From: Aurelien DARRAGON Date: Fri, 30 Dec 2022 15:56:08 +0000 (+0100) Subject: MINOR: http_ext: add rfc7239_n2np converter X-Git-Tag: v2.8-dev3~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9a273b4069875565b36e0ab58ddd29ff4736d3a8;p=thirdparty%2Fhaproxy.git MINOR: http_ext: add rfc7239_n2np converter Adding new http converter: rfc7239_n2np. Takes a string representing 7239 forwarded header node (extracted from either 'for' or 'by' 7239 header fields) as input and translates it to either unsigned integer or ('_' prefixed obfuscated identifier), according to 7239RFC. Example: # extract 'by' field from forwarded header, extract node port from # resulting node identifier and store the result in req.fnp http-request set-var(req.fnp) req.hdr(forwarded),rfc7239_field(by),rfc7239_n2np #input: "by=\"127.0.0.1:9999\"" # output: 9999 #input: "by=\"_name:_port\"" # output: "_port" Depends on: - "MINOR: http_ext: introduce http ext converters" --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 37c2d331d5..b01b30aec7 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -17268,6 +17268,21 @@ rfc7239_n2nn #input: "for=\"_name:_port\"" # output: "_name" +rfc7239_n2np + Converts RFC7239 node (provided by 'for' or 'by' 7239 header fields) + into its corresponding nodeport final form: + - unsigned integer + - '_obfs' identifier + + Example: + # extract 'by' field from forwarded header, extract node port from + # resulting node identifier and store the result in req.fnp + http-request set-var(req.fnp) req.hdr(forwarded),rfc7239_field(by),rfc7239_n2np + #input: "by=\"127.0.0.1:9999\"" + # output: 9999 + #input: "by=\"_name:_port\"" + # output: "_port" + add() Adds to the input value of type signed integer, and returns the result as a signed integer. can be a numeric value or a variable diff --git a/src/http_ext.c b/src/http_ext.c index 3681bd0791..62aa55dd47 100644 --- a/src/http_ext.c +++ b/src/http_ext.c @@ -1480,11 +1480,47 @@ static int sample_conv_7239_n2nn(const struct arg *args, struct sample *smp, voi return 1; } +/* input: substring representing 7239 forwarded header node + * output: forwarded header nodeport translated to either + * integer or str for obfuscated ('_' prefix) + */ +static int sample_conv_7239_n2np(const struct arg *args, struct sample *smp, void *private) +{ + struct ist input = ist2(smp->data.u.str.area, smp->data.u.str.data); + struct forwarded_header_node ctx; + struct buffer *output; + + if (http_7239_extract_node(&input, &ctx, 1) == 0) + return 0; /* could not extract node */ + + switch (ctx.nodeport.type) { + case FORWARDED_HEADER_UNK: + return 0; /* not provided */ + case FORWARDED_HEADER_OBFS: + output = get_trash_chunk(); + chunk_appendf(output, "_"); /* append obfs prefix */ + chunk_istcat(output, ctx.nodeport.obfs); + smp->flags &= ~SMP_F_CONST; + smp->data.type = SMP_T_STR; + smp->data.u.str = *output; + break; + case FORWARDED_HEADER_PORT: + smp->data.type = SMP_T_SINT; + smp->data.u.sint = ctx.nodeport.port; + break; + default: + return 0; /* unsupported */ + } + + return 1; +} + /* Note: must not be declared as its list will be overwritten */ static struct sample_conv_kw_list sample_conv_kws = {ILH, { { "rfc7239_is_valid", sample_conv_7239_valid, 0, NULL, SMP_T_STR, SMP_T_BOOL}, { "rfc7239_field", sample_conv_7239_field, ARG1(1,STR), NULL, SMP_T_STR, SMP_T_STR}, { "rfc7239_n2nn", sample_conv_7239_n2nn, 0, NULL, SMP_T_STR, SMP_T_ANY}, + { "rfc7239_n2np", sample_conv_7239_n2np, 0, NULL, SMP_T_STR, SMP_T_ANY}, { NULL, NULL, 0, 0, 0 }, }};