diff --git a/doc/configuration.txt b/doc/configuration.txt index b9d520fe2..d90c39e66 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -17995,16 +17995,17 @@ cur_tunnel_timeout : integer "set-timeout" rule has been applied. See also "be_tunnel_timeout". dst : ip - This is the destination IPv4 address of the connection on the client side, - which is the address the client connected to. It can be useful when running - in transparent mode. It is of type IP and works on both IPv4 and IPv6 tables. - On IPv6 tables, IPv4 address is mapped to its IPv6 equivalent, according to - RFC 4291. When the incoming connection passed through address translation or - redirection involving connection tracking, the original destination address - before the redirection will be reported. On Linux systems, the source and - destination may seldom appear reversed if the nf_conntrack_tcp_loose sysctl - is set, because a late response may reopen a timed out connection and switch - what is believed to be the source and the destination. + This is the destination IP address of the connection on the client side, + which is the address the client connected to. Any tcp/http rules may alter + this address. It can be useful when running in transparent mode. It is of + type IP and works on both IPv4 and IPv6 tables. On IPv6 tables, IPv4 address + is mapped to its IPv6 equivalent, according to RFC 4291. When the incoming + connection passed through address translation or redirection involving + connection tracking, the original destination address before the redirection + will be reported. On Linux systems, the source and destination may seldom + appear reversed if the nf_conntrack_tcp_loose sysctl is set, because a late + response may reopen a timed out connection and switch what is believed to be + the source and the destination. dst_conn : integer Returns an integer value corresponding to the number of currently established @@ -18029,10 +18030,10 @@ dst_is_local : boolean dst_port : integer Returns an integer value corresponding to the destination TCP port of the connection on the client side, which is the port the client connected to. - This might be used when running in transparent mode, when assigning dynamic - ports to some clients for a whole application session, to stick all users to - a same server, or to pass the destination port information to a server using - an HTTP header. + Any tcp/http rules may alter this address. This might be used when running in + transparent mode, when assigning dynamic ports to some clients for a whole + application session, to stick all users to a same server, or to pass the + destination port information to a server using an HTTP header. fc_conn_err : integer Returns the ID of the error that might have occurred on the current @@ -18096,6 +18097,21 @@ fc_conn_err_str : string | 43 | "SSL fatal error" | +----+---------------------------------------------------------------------------+ +fc_dst : ip + This is the original destination IP address of the connection on the client + side. Only "tcp-request connection" rules may alter this address. See "dst" + for details. + +fc_dst_is_local : boolean + Returns true if the original destination address of the incoming connection + is local to the system, or false if the address doesn't exist on the + system. See "dst_is_local" for details. + +fc_dst_port : integer + Returns an integer value corresponding to the original destination TCP port + of the connection on the client side. Only "tcp-request connection" rules may + alter this address. See "dst-port" for details. + fc_fackets : integer Returns the fack counter measured by the kernel for the client connection. If the server connection is not established, if the connection is @@ -18159,6 +18175,22 @@ fc_sacked : integer if the operating system does not support TCP_INFO, for example Linux kernels before 2.4, the sample fetch fails. +fc_src : ip + This is the original destination IP address of the connection on the client + side. Only "tcp-request connection" rules may alter this address. See "src" + for details. + +fc_src_is_local : boolean + Returns true if the source address of incoming connection is local to the + system, or false if the address doesn't exist on the system. See + "src_is_local" for details. + +fc_src_port : integer + + Returns an integer value corresponding to the TCP source port of the + connection on the client side. Only "tcp-request connection" rules may alter + this address. See "src-port" for details. + fc_unacked : integer Returns the unacked counter measured by the kernel for the client connection. @@ -18495,20 +18527,21 @@ so_name : string strings instead of integers. src : ip - This is the source IPv4 address of the client of the session. It is of type - IP and works on both IPv4 and IPv6 tables. On IPv6 tables, IPv4 addresses are - mapped to their IPv6 equivalent, according to RFC 4291. Note that it is the - TCP-level source address which is used, and not the address of a client - behind a proxy. However if the "accept-proxy" or "accept-netscaler-cip" bind - directive is used, it can be the address of a client behind another - PROXY-protocol compatible component for all rule sets except - "tcp-request connection" which sees the real address. When the incoming - connection passed through address translation or redirection involving - connection tracking, the original destination address before the redirection - will be reported. On Linux systems, the source and destination may seldom - appear reversed if the nf_conntrack_tcp_loose sysctl is set, because a late - response may reopen a timed out connection and switch what is believed to be - the source and the destination. + This is the source IP address of the client of the session. Any tcp/http + rules may alter this address. It is of type IP and works on both IPv4 and + IPv6 tables. On IPv6 tables, IPv4 addresses are mapped to their IPv6 + equivalent, according to RFC 4291. Note that it is the TCP-level source + address which is used, and not the address of a client behind a + proxy. However if the "accept-proxy" or "accept-netscaler-cip" bind directive + is used, it can be the address of a client behind another PROXY-protocol + compatible component for all rule sets except "tcp-request connection" which + sees the real address. When the incoming connection passed through address + translation or redirection involving connection tracking, the original + destination address before the redirection will be reported. On Linux + systems, the source and destination may seldom appear reversed if the + nf_conntrack_tcp_loose sysctl is set, because a late response may reopen a + timed out connection and switch what is believed to be the source and the + destination. Example: # add an HTTP header in requests with the originating address' country @@ -18744,9 +18777,10 @@ src_kbytes_out([]) : integer src_port : integer Returns an integer value corresponding to the TCP source port of the - connection on the client side, which is the port the client connected from. - Usage of this function is very limited as modern protocols do not care much - about source ports nowadays. + connection on the client side, which is the port the client connected + from. Any tcp/http rules may alter this address. Usage of this function is + very limited as modern protocols do not care much about source ports + nowadays. src_sess_cnt([
]) : integer Returns the cumulative number of connections initiated from the incoming diff --git a/src/tcp_sample.c b/src/tcp_sample.c index d167bde86..19edcd243 100644 --- a/src/tcp_sample.c +++ b/src/tcp_sample.c @@ -51,14 +51,20 @@ smp_fetch_src(const struct arg *args, struct sample *smp, const char *kw, void * { const struct sockaddr_storage *src = NULL; - if (kw[0] == 'b') { + if (kw[0] == 'b') { /* bc_src */ struct connection *conn = ((obj_type(smp->sess->origin) == OBJ_TYPE_CHECK) ? cs_conn(__objt_check(smp->sess->origin)->cs) : (smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)): NULL)); if (conn && conn_get_src(conn)) src = conn_src(conn); } - else + else if (kw[0] == 'f') { /* fc_src */ + struct connection *conn = objt_conn(smp->sess->origin); + + if (conn && conn_get_src(conn)) + src = conn_src(conn); + } + else /* src */ src = (smp->strm ? si_src(&smp->strm->si[0]) : sess_src(smp->sess)); if (!src) @@ -89,14 +95,20 @@ smp_fetch_sport(const struct arg *args, struct sample *smp, const char *kw, void { const struct sockaddr_storage *src = NULL; - if (kw[0] == 'b') { + if (kw[0] == 'b') { /* bc_src_port */ struct connection *conn = ((obj_type(smp->sess->origin) == OBJ_TYPE_CHECK) ? cs_conn(__objt_check(smp->sess->origin)->cs) : (smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)): NULL)); if (conn && conn_get_src(conn)) src = conn_src(conn); } - else + else if (kw[0] == 'f') { /* fc_src_port */ + struct connection *conn = objt_conn(smp->sess->origin); + + if (conn && conn_get_src(conn)) + src = conn_src(conn); + } + else /* src_port */ src = (smp->strm ? si_src(&smp->strm->si[0]) : sess_src(smp->sess)); if (!src) @@ -118,14 +130,20 @@ smp_fetch_dst(const struct arg *args, struct sample *smp, const char *kw, void * { const struct sockaddr_storage *dst = NULL; - if (kw[0] == 'b') { + if (kw[0] == 'b') { /* bc_dst */ struct connection *conn = ((obj_type(smp->sess->origin) == OBJ_TYPE_CHECK) ? cs_conn(__objt_check(smp->sess->origin)->cs) : (smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)): NULL)); if (conn && conn_get_dst(conn)) dst = conn_dst(conn); } - else + else if (kw[0] == 'f') { /* fc_dst */ + struct connection *conn = objt_conn(smp->sess->origin); + + if (conn && conn_get_dst(conn)) + dst = conn_dst(conn); + } + else /* dst */ dst = (smp->strm ? si_dst(&smp->strm->si[0]) : sess_dst(smp->sess)); if (!dst) @@ -154,7 +172,16 @@ smp_fetch_dst(const struct arg *args, struct sample *smp, const char *kw, void * int smp_fetch_dst_is_local(const struct arg *args, struct sample *smp, const char *kw, void *private) { struct listener *li = smp->sess->listener; - const struct sockaddr_storage *dst = (smp->strm ? si_dst(&smp->strm->si[0]) : sess_dst(smp->sess)); + const struct sockaddr_storage *dst = NULL; + + if (kw[0] == 'f') { /* fc_dst_is_local */ + struct connection *conn = objt_conn(smp->sess->origin); + + if (conn && conn_get_src(conn)) + dst = conn_dst(conn); + } + else /* dst_is_local */ + dst = (smp->strm ? si_dst(&smp->strm->si[0]) : sess_dst(smp->sess)); if (!dst) return 0; @@ -171,7 +198,16 @@ int smp_fetch_dst_is_local(const struct arg *args, struct sample *smp, const cha int smp_fetch_src_is_local(const struct arg *args, struct sample *smp, const char *kw, void *private) { struct listener *li = smp->sess->listener; - const struct sockaddr_storage *src = (smp->strm ? si_src(&smp->strm->si[0]) : sess_src(smp->sess)); + const struct sockaddr_storage *src = NULL; + + if (kw[0] == 'f') { /* fc_src_is_local */ + struct connection *conn = objt_conn(smp->sess->origin); + + if (conn && conn_get_src(conn)) + src = conn_src(conn); + } + else /* src_is_local */ + src = (smp->strm ? si_src(&smp->strm->si[0]) : sess_src(smp->sess)); if (!src) return 0; @@ -190,14 +226,20 @@ smp_fetch_dport(const struct arg *args, struct sample *smp, const char *kw, void { const struct sockaddr_storage *dst = NULL; - if (kw[0] == 'b') { + if (kw[0] == 'b') { /* bc_dst_port */ struct connection *conn = ((obj_type(smp->sess->origin) == OBJ_TYPE_CHECK) ? cs_conn(__objt_check(smp->sess->origin)->cs) : (smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)): NULL)); if (conn && conn_get_dst(conn)) dst = conn_dst(conn); } - else + else if (kw[0] == 'f') { /* fc_dst_post */ + struct connection *conn = objt_conn(smp->sess->origin); + + if (conn && conn_get_src(conn)) + dst = conn_dst(conn); + } + else /* dst_port */ dst = (smp->strm ? si_dst(&smp->strm->si[0]) : sess_dst(smp->sess)); if (!dst) @@ -421,6 +463,15 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, { { "dst", smp_fetch_dst, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI }, { "dst_is_local", smp_fetch_dst_is_local, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI }, { "dst_port", smp_fetch_dport, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI }, + + { "fc_dst", smp_fetch_dst, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI }, + { "fc_dst_is_local", smp_fetch_dst_is_local, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI }, + { "fc_dst_port", smp_fetch_dport, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI }, + + { "fc_src", smp_fetch_src, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI }, + { "fc_src_is_local", smp_fetch_src_is_local, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI }, + { "fc_src_port", smp_fetch_sport, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI }, + { "src", smp_fetch_src, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI }, { "src_is_local", smp_fetch_src_is_local, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI }, { "src_port", smp_fetch_sport, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI },