Module: kamailio Branch: master Commit: b918e09e9c3e06bddfd7a205f64abb603d589f1c URL: https://github.com/kamailio/kamailio/commit/b918e09e9c3e06bddfd7a205f64abb60...
Author: Alexander Bakker ab@alexbakker.me Committer: Daniel-Constantin Mierla miconda@gmail.com Date: 2025-01-29T08:19:45+01:00
outbound: encode bind address into flow token as destination
This is an attempt to fix the combination of the outbound/rr modules and ``tcp_accept_haproxy=yes``. This combination is currently broken, as previously reported on the mailing list: https://www.mail-archive.com/sr-users@lists.kamailio.org/msg21854.html
The issue is that the destination address/port combo of the haproxy side is encoded into the flow token. When the rr module decodes the flow token and tries to look up the listening socket using ``find_si``, it cannot be found, because it is given the destination address/port combo of the connection of the haproxy side, not the address/port combo that Kamailio is actually listening on.
This patch fixes the issue by encoding the ``bind_address`` of the socket the connection was received on into the flow token as the destination address. The source address remains unchanged, as it *can* be used to look up the TCP connection (with a minor patch to ``_tcpconn_find`` in ``tcp_main.c``)
---
Modified: src/modules/outbound/outbound_mod.c
---
Diff: https://github.com/kamailio/kamailio/commit/b918e09e9c3e06bddfd7a205f64abb60... Patch: https://github.com/kamailio/kamailio/commit/b918e09e9c3e06bddfd7a205f64abb60...
---
diff --git a/src/modules/outbound/outbound_mod.c b/src/modules/outbound/outbound_mod.c index f2e0c7dbc3d..a5f17e4ef99 100644 --- a/src/modules/outbound/outbound_mod.c +++ b/src/modules/outbound/outbound_mod.c @@ -180,15 +180,25 @@ int encode_flow_token(str *flow_token, struct receive_info *rcv) return -1; }
+ /* By encoding the bind address into the flow token as the destination + address, we make sure that we'll still be able to find the socket when + decoding it even if there's an haproxy in front */ + struct ip_addr dst_ip = rcv->dst_ip; + unsigned short dst_port = rcv->dst_port; + if(rcv->bind_address) { + dst_ip = rcv->bind_address->address; + dst_port = rcv->bind_address->port_no; + } + /* Encode protocol information */ unenc_flow_token[pos++] = - (rcv->dst_ip.af == AF_INET6 ? 0x80 : 0x00) | rcv->proto; + (dst_ip.af == AF_INET6 ? 0x80 : 0x00) | rcv->proto;
/* Encode destination address */ - for(i = 0; i < (rcv->dst_ip.af == AF_INET6 ? 16 : 4); i++) - unenc_flow_token[pos++] = rcv->dst_ip.u.addr[i]; - unenc_flow_token[pos++] = (rcv->dst_port >> 8) & 0xff; - unenc_flow_token[pos++] = rcv->dst_port & 0xff; + for(i = 0; i < (dst_ip.af == AF_INET6 ? 16 : 4); i++) + unenc_flow_token[pos++] = dst_ip.u.addr[i]; + unenc_flow_token[pos++] = (dst_port >> 8) & 0xff; + unenc_flow_token[pos++] = dst_port & 0xff;
/* Encode source address */ for(i = 0; i < (rcv->src_ip.af == AF_INET6 ? 16 : 4); i++)