Skip to content

Commit

Permalink
Add support for the UNIQUE_ID proxy protocol header TLV
Browse files Browse the repository at this point in the history
  • Loading branch information
essen committed Dec 5, 2023
1 parent be7a7f4 commit cb75e10
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
6 changes: 6 additions & 0 deletions doc/src/manual/ranch_proxy_header.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ proxy_info() = #{
%% Extra TLV-encoded data.
alpn => binary(), %% US-ASCII.
authority => binary(), %% UTF-8.
unique_id => binary(), %% Opaque byte sequence of up to 128 bytes.
netns => binary(), %% US-ASCII.
ssl => #{
client := [ssl | cert_conn | cert_sess],
Expand Down Expand Up @@ -105,6 +106,10 @@ authority::
The host name serving as authority for the connection.
This is typically passed using the SNI extension for TLS.

unique_id::
An opaque byte sequence of up to 128 bytes generated
by the upstream proxy that uniquely identifies the connection.

netns::

The namespace's name for the original connection.
Expand Down Expand Up @@ -158,6 +163,7 @@ The non-standard TLVs that Ranch was not able to parse.

== Changelog

* *2.2*: The `unique_id` TLV was added.
* *1.7*: Module introduced.

== See also
Expand Down
10 changes: 10 additions & 0 deletions src/ranch_proxy_header.erl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
%% Extra TLV-encoded data.
alpn => binary(), %% US-ASCII.
authority => binary(), %% UTF-8.
unique_id => binary(), %% Opaque byte sequence of up to 128 bytes.
ssl => #{
client := [ssl | cert_conn | cert_sess],
verified := boolean(),
Expand Down Expand Up @@ -520,6 +521,12 @@ parse_tlv(<<16#3, TLVLen:16, CRC32C:32, Rest/bits>>, Len0, Info, Header) when TL
%% PP2_TYPE_NOOP.
parse_tlv(<<16#4, TLVLen:16, _:TLVLen/binary, Rest/bits>>, Len, Info, Header) ->
parse_tlv(Rest, Len - TLVLen - 3, Info, Header);
%% PP2_TYPE_UNIQUE_ID.
parse_tlv(<<16#5, TLVLen:16, UniqueID:TLVLen/binary, Rest/bits>>, Len, Info, Header)
when TLVLen =< 128 ->
parse_tlv(Rest, Len - TLVLen - 3, Info#{unique_id => UniqueID}, Header);
parse_tlv(<<16#5, _/bits>>, _, _, _) ->
{error, 'Invalid TLV length in the PROXY protocol binary header. (PP 2.2, PP 2.2.5)'};
%% PP2_TYPE_SSL.
parse_tlv(<<16#20, TLVLen:16, Client, Verify:32, Rest0/bits>>, Len, Info, Header) ->
SubsLen = TLVLen - 5,
Expand Down Expand Up @@ -682,6 +689,7 @@ tlvs(ProxyInfo, Opts) ->
[
binary_tlv(ProxyInfo, alpn, 16#1),
binary_tlv(ProxyInfo, authority, 16#2),
binary_tlv(ProxyInfo, unique_id, 16#5),
ssl_tlv(ProxyInfo),
binary_tlv(ProxyInfo, netns, 16#30),
raw_tlvs(ProxyInfo),
Expand Down Expand Up @@ -849,6 +857,8 @@ v2_tlvs_test() ->
]},
Test5Out = Test5In#{raw_tlvs => lists:reverse(RawTLVs)},
{ok, Test5Out, <<>>} = parse(iolist_to_binary(header(Test5In))),
Test6 = Common#{unique_id => rand:bytes(rand:uniform(128))},
{ok, Test6, <<>>} = parse(iolist_to_binary(header(Test6))),
ok.

v2_checksum_test() ->
Expand Down

0 comments on commit cb75e10

Please sign in to comment.