-
Notifications
You must be signed in to change notification settings - Fork 265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parse proxy protocol #337
base: master
Are you sure you want to change the base?
Parse proxy protocol #337
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -198,11 +198,22 @@ ranch_init({Ref, Transport, {Callback, Opts}}) -> | |
-spec init(Args :: list()) -> {'ok', #state{}, ?TIMEOUT} | {'stop', any()} | 'ignore'. | ||
init([Ref, Transport, Socket, Module, Options]) -> | ||
Protocol = proplists:get_value(protocol, Options, smtp), | ||
PeerName = | ||
case Transport:peername(Socket) of | ||
{ok, {IPaddr, _Port}} -> IPaddr; | ||
{error, _} -> error | ||
end, | ||
|
||
PeerName = case proplists:get_value(proxy_protocol, Options, false) of | ||
false -> | ||
case Transport:peername(Socket) of | ||
{ok, {IPaddr, _Port}} -> IPaddr; | ||
{error, _} -> error | ||
end; | ||
_ -> | ||
case read_proxy_protocol(Transport, Socket) of | ||
{ok, IpAddr} -> | ||
IpAddr; | ||
_ -> | ||
error | ||
end | ||
end, | ||
|
||
case | ||
PeerName =/= error andalso | ||
Module:init( | ||
|
@@ -1405,6 +1416,32 @@ report_recipient(multiple, [{ResponseType, Value} | Rest], State) -> | |
report_recipient(ResponseType, Value, State), | ||
report_recipient(multiple, Rest, State). | ||
|
||
% parse proxy protocol | ||
% http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt | ||
|
||
read_proxy_protocol(Transport, Socket) -> | ||
ok = Transport:setopts(Socket, [{packet, line}, binary]), | ||
case Transport:recv(Socket, 0, 5000) of | ||
{ok, Data} -> | ||
case Data of | ||
<<"PROXY ", _/binary>> -> | ||
case binary:split(Data, <<" ">>, [global]) of | ||
[<<"PROXY">>, InetFamily, SrcIp, _DstIp, _SrcPort, _DstPort] when InetFamily == <<"TCP4">> orelse InetFamily == <<"TCP6">> -> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should probably use the right, address specific parser for v4 or v6, so if the proxy sends TCP4 with a v6 address, things fail. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Huh... can you be more explicit ? |
||
inet:parse_address(binary_to_list(SrcIp)); | ||
_ -> | ||
?LOG_ERROR("unexpected proxy protocol found: ~p.", [Data]), | ||
{error, invalid_proxy_protocol} | ||
end; | ||
_ -> | ||
% misconfiguration. | ||
?LOG_ERROR("unexpected proxy protocol found: ~p.", [Data]), | ||
{error, invalid_proxy_protocol} | ||
end; | ||
Error -> | ||
?LOG_ERROR("read_proxy_protocol receiving proxy data failed with ~p.", [Error]), | ||
Error | ||
end. | ||
|
||
-ifdef(TEST). | ||
parse_encoded_address_test_() -> | ||
[ | ||
|
@@ -3709,3 +3746,4 @@ smtp_session_nomaxsize_test_() -> | |
]}. | ||
|
||
-endif. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also a binary form of this protocol (version 2), were you planning on supporting this as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can support if you think it makes sense. Idea is that you have control in what version you want to use:
send-proxy
is v1 (current implementation)send-proxy-v2
- is v2