From 069b0b29fe9f951cb4411d541dab22d6d8c0ac4b Mon Sep 17 00:00:00 2001 From: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:23:56 +0000 Subject: [PATCH 1/5] tcp_main: Add protocol argument for searching tcp/tls connections --- src/core/forward.h | 3 ++- src/core/tcp_conn.h | 3 ++- src/core/tcp_main.c | 32 ++++++++++++++++++-------------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/core/forward.h b/src/core/forward.h index a810dc0b1f1..46bd3a36171 100644 --- a/src/core/forward.h +++ b/src/core/forward.h @@ -188,7 +188,8 @@ static inline int msg_send_buffer( su2ip_addr(&ip, &dst->to); if(tcp_connection_match == TCPCONN_MATCH_STRICT) { con = tcpconn_lookup(dst->id, &ip, port, from, - (dst->send_sock) ? dst->send_sock->port_no : 0, 0); + (dst->send_sock) ? dst->send_sock->port_no : 0, 0, + PROTO_NONE); } else { con = tcpconn_get(dst->id, &ip, port, from, 0); } diff --git a/src/core/tcp_conn.h b/src/core/tcp_conn.h index 4534439f6b2..13301563945 100644 --- a/src/core/tcp_conn.h +++ b/src/core/tcp_conn.h @@ -407,7 +407,8 @@ struct tcp_connection *tcpconn_get(int id, struct ip_addr *ip, int port, union sockaddr_union *local_addr, ticks_t timeout); struct tcp_connection *tcpconn_lookup(int id, struct ip_addr *ip, int port, - union sockaddr_union *local_addr, int try_local_port, ticks_t timeout); + union sockaddr_union *local_addr, int try_local_port, ticks_t timeout, + sip_protos_t proto); typedef struct tcp_event_info { diff --git a/src/core/tcp_main.c b/src/core/tcp_main.c index 757329a8543..73e2ef6163d 100644 --- a/src/core/tcp_main.c +++ b/src/core/tcp_main.c @@ -1701,8 +1701,8 @@ void tcpconn_rm(struct tcp_connection *c) * ip address and/or a 0 local port). * WARNING: unprotected (locks) use tcpconn_get unless you really * know what you are doing */ -struct tcp_connection *_tcpconn_find( - int id, struct ip_addr *ip, int port, struct ip_addr *l_ip, int l_port) +struct tcp_connection *_tcpconn_find(int id, struct ip_addr *ip, int port, + struct ip_addr *l_ip, int l_port, sip_protos_t proto) { struct tcp_connection *c; @@ -1741,7 +1741,8 @@ struct tcp_connection *_tcpconn_find( && (ip_addr_cmp(ip, &a->parent->rcv.src_ip)) && (is_local_ip_any || ip_addr_cmp(l_ip, &a->parent->rcv.dst_ip) - || ip_addr_cmp(l_ip, &a->parent->cinfo.dst_ip))) { + || ip_addr_cmp(l_ip, &a->parent->cinfo.dst_ip)) + && (proto == PROTO_NONE || a->parent->rcv.proto == proto)) { LM_DBG("found connection by peer address (id: %d)\n", a->parent->id); return a->parent; @@ -1762,7 +1763,8 @@ int tcpconn_exists(int conn_id, ip_addr_t *peer_ip, int peer_port, tcp_connection_t *c; TCPCONN_LOCK; - c = _tcpconn_find(conn_id, peer_ip, peer_port, local_ip, local_port); + c = _tcpconn_find( + conn_id, peer_ip, peer_port, local_ip, local_port, PROTO_NONE); TCPCONN_UNLOCK; if(c) { return 1; @@ -1778,7 +1780,8 @@ int tcpconn_exists(int conn_id, ip_addr_t *peer_ip, int peer_port, * want to decrement it after use. */ struct tcp_connection *tcpconn_lookup(int id, struct ip_addr *ip, int port, - union sockaddr_union *local_addr, int try_local_port, ticks_t timeout) + union sockaddr_union *local_addr, int try_local_port, ticks_t timeout, + sip_protos_t proto) { struct tcp_connection *c; struct ip_addr local_ip; @@ -1797,10 +1800,10 @@ struct tcp_connection *tcpconn_lookup(int id, struct ip_addr *ip, int port, } TCPCONN_LOCK; if(likely(try_local_port != 0) && likely(local_port == 0)) { - c = _tcpconn_find(id, ip, port, &local_ip, try_local_port); + c = _tcpconn_find(id, ip, port, &local_ip, try_local_port, proto); } if(unlikely(c == NULL)) { - c = _tcpconn_find(id, ip, port, &local_ip, local_port); + c = _tcpconn_find(id, ip, port, &local_ip, local_port, proto); } if(likely(c)) { atomic_inc(&c->refcnt); @@ -1825,7 +1828,7 @@ struct tcp_connection *tcpconn_lookup(int id, struct ip_addr *ip, int port, struct tcp_connection *tcpconn_get(int id, struct ip_addr *ip, int port, union sockaddr_union *local_addr, ticks_t timeout) { - return tcpconn_lookup(id, ip, port, local_addr, 0, timeout); + return tcpconn_lookup(id, ip, port, local_addr, 0, timeout, PROTO_NONE); } @@ -1951,7 +1954,7 @@ int tcpconn_add_alias(int id, int port, int proto) port = port ? port : ((proto == PROTO_TLS) ? SIPS_PORT : SIP_PORT); TCPCONN_LOCK; /* check if alias already exists */ - c = _tcpconn_find(id, 0, 0, 0, 0); + c = _tcpconn_find(id, 0, 0, 0, 0, PROTO_NONE); if(likely(c)) { ip_addr_mk_any(c->rcv.src_ip.af, &zero_ip); alias_flags = cfg_get(tcp, tcp_cfg, alias_flags); @@ -2092,8 +2095,8 @@ int tcp_send(struct dest_info *dst, union sockaddr_union *from, const char *buf, if(likely(port)) { su2ip_addr(&ip, &dst->to); if(tcp_connection_match == TCPCONN_MATCH_STRICT) { - c = tcpconn_lookup( - dst->id, &ip, port, from, try_local_port, con_lifetime); + c = tcpconn_lookup(dst->id, &ip, port, from, try_local_port, + con_lifetime, dst->proto); } else { c = tcpconn_get(dst->id, &ip, port, from, con_lifetime); } @@ -2109,8 +2112,8 @@ int tcp_send(struct dest_info *dst, union sockaddr_union *from, const char *buf, if(likely(port)) { /* try again w/o id */ if(tcp_connection_match == TCPCONN_MATCH_STRICT) { - c = tcpconn_lookup( - 0, &ip, port, from, try_local_port, con_lifetime); + c = tcpconn_lookup(0, &ip, port, from, try_local_port, + con_lifetime, dst->proto); } else { c = tcpconn_get(0, &ip, port, from, con_lifetime); } @@ -5430,7 +5433,8 @@ int wss_send(dest_info_t *dst, const char *buf, unsigned len) su2ip_addr(&ip, &dst->to); if(tcp_connection_match == TCPCONN_MATCH_STRICT) { con = tcpconn_lookup(dst->id, &ip, port, from, - (dst->send_sock) ? dst->send_sock->port_no : 0, 0); + (dst->send_sock) ? dst->send_sock->port_no : 0, 0, + PROTO_NONE); } else { con = tcpconn_get(dst->id, &ip, port, from, 0); } From aba184b2fa83fc852815eb711415920ff64de201 Mon Sep 17 00:00:00 2001 From: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:29:57 +0000 Subject: [PATCH 2/5] tcp_main: Add proto argument to tcpconn_exists function --- src/core/tcp_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/tcp_main.c b/src/core/tcp_main.c index 73e2ef6163d..0ea1b541ea6 100644 --- a/src/core/tcp_main.c +++ b/src/core/tcp_main.c @@ -1758,13 +1758,12 @@ struct tcp_connection *_tcpconn_find(int id, struct ip_addr *ip, int port, * - return: 1 if found; 0 if not found */ int tcpconn_exists(int conn_id, ip_addr_t *peer_ip, int peer_port, - ip_addr_t *local_ip, int local_port) + ip_addr_t *local_ip, int local_port, sip_protos_t proto) { tcp_connection_t *c; TCPCONN_LOCK; - c = _tcpconn_find( - conn_id, peer_ip, peer_port, local_ip, local_port, PROTO_NONE); + c = _tcpconn_find(conn_id, peer_ip, peer_port, local_ip, local_port, proto); TCPCONN_UNLOCK; if(c) { return 1; @@ -4497,7 +4496,8 @@ static inline int handle_new_connect(struct socket_info *si) if(likely(tcpconn)) { if(tcp_accept_unique) { if(tcpconn_exists(0, &tcpconn->rcv.dst_ip, tcpconn->rcv.dst_port, - &tcpconn->rcv.src_ip, tcpconn->rcv.src_port)) { + &tcpconn->rcv.src_ip, tcpconn->rcv.src_port, + si->proto)) { LM_ERR("duplicated connection by local and remote addresses\n"); _tcpconn_free(tcpconn); tcp_safe_close(new_sock); From 6626cbd45b7003ae388dbc5b5938f94e506621b0 Mon Sep 17 00:00:00 2001 From: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:42:49 +0000 Subject: [PATCH 3/5] tcp_main: Update comment docs --- src/core/tcp_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/tcp_main.c b/src/core/tcp_main.c index 0ea1b541ea6..e3323736cc0 100644 --- a/src/core/tcp_main.c +++ b/src/core/tcp_main.c @@ -1697,8 +1697,8 @@ void tcpconn_rm(struct tcp_connection *c) /* finds a connection, if id=0 uses the ip addr, port, local_ip and local port * (host byte order) and tries to find the connection that matches all of - * them. Wild cards can be used for local_ip and local_port (a 0 filled - * ip address and/or a 0 local port). + * them. Wild cards can be used for local_ip, local_port and proto (a 0 filled + * ip address and/or a 0 local port and/or PROTO_NONE). * WARNING: unprotected (locks) use tcpconn_get unless you really * know what you are doing */ struct tcp_connection *_tcpconn_find(int id, struct ip_addr *ip, int port, @@ -1754,7 +1754,7 @@ struct tcp_connection *_tcpconn_find(int id, struct ip_addr *ip, int port, /** - * find if a tcp connection exits by id or remote+local address/port + * find if a tcp connection exits by id or remote+local address/port and protocol * - return: 1 if found; 0 if not found */ int tcpconn_exists(int conn_id, ip_addr_t *peer_ip, int peer_port, @@ -1774,6 +1774,7 @@ int tcpconn_exists(int conn_id, ip_addr_t *peer_ip, int peer_port, /* TCP connection find with locks and timeout * - local_addr contains the desired local ip:port. If null any local address * will be used. IN*ADDR_ANY or 0 port are wild cards. + * - proto is the protocol to match (PROTO_NONE for any) * - try_local_port makes the search use it first, instead of port from local_addr * If found, the connection's reference counter will be incremented, you might * want to decrement it after use. From 8edeac3be8870bdd4f8d17066172bf2b0182198d Mon Sep 17 00:00:00 2001 From: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> Date: Wed, 10 Apr 2024 11:13:32 +0000 Subject: [PATCH 4/5] core/forward: Match protocol when forwarding --- src/core/forward.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/forward.h b/src/core/forward.h index 46bd3a36171..7b51e1a5559 100644 --- a/src/core/forward.h +++ b/src/core/forward.h @@ -189,7 +189,7 @@ static inline int msg_send_buffer( if(tcp_connection_match == TCPCONN_MATCH_STRICT) { con = tcpconn_lookup(dst->id, &ip, port, from, (dst->send_sock) ? dst->send_sock->port_no : 0, 0, - PROTO_NONE); + dst->proto); } else { con = tcpconn_get(dst->id, &ip, port, from, 0); } From a3f7525e2f774c0e1ada62312bae2b0d29c65b35 Mon Sep 17 00:00:00 2001 From: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> Date: Wed, 10 Apr 2024 11:14:45 +0000 Subject: [PATCH 5/5] tcp_main: Match wss protocol --- src/core/tcp_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/tcp_main.c b/src/core/tcp_main.c index e3323736cc0..b71e7ad37f2 100644 --- a/src/core/tcp_main.c +++ b/src/core/tcp_main.c @@ -5435,7 +5435,7 @@ int wss_send(dest_info_t *dst, const char *buf, unsigned len) if(tcp_connection_match == TCPCONN_MATCH_STRICT) { con = tcpconn_lookup(dst->id, &ip, port, from, (dst->send_sock) ? dst->send_sock->port_no : 0, 0, - PROTO_NONE); + dst->proto); } else { con = tcpconn_get(dst->id, &ip, port, from, 0); }