From cb75e10c99af8c5654d94b9dcae2f8c7879b4f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 5 Dec 2023 12:33:13 +0100 Subject: Add support for the UNIQUE_ID proxy protocol header TLV --- doc/src/manual/ranch_proxy_header.asciidoc | 6 ++++++ src/ranch_proxy_header.erl | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/doc/src/manual/ranch_proxy_header.asciidoc b/doc/src/manual/ranch_proxy_header.asciidoc index c194d98..c4ef150 100644 --- a/doc/src/manual/ranch_proxy_header.asciidoc +++ b/doc/src/manual/ranch_proxy_header.asciidoc @@ -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], @@ -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. @@ -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 diff --git a/src/ranch_proxy_header.erl b/src/ranch_proxy_header.erl index 254a969..3f282d2 100644 --- a/src/ranch_proxy_header.erl +++ b/src/ranch_proxy_header.erl @@ -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(), @@ -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, @@ -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), @@ -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() -> -- cgit v1.2.3