From 3db1f095b2b2620e25e75cf66f7bdd88b2bc83de Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Fri, 28 May 2021 11:08:48 +0200 Subject: [PATCH 1/2] sip: copy the IPv6 scope ID from laddr to dst --- src/sip/transp.c | 50 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/src/sip/transp.c b/src/sip/transp.c index cccbf4d02..ac0ccabb3 100644 --- a/src/sip/transp.c +++ b/src/sip/transp.c @@ -26,6 +26,11 @@ #include "sip.h" +#define DEBUG_MODULE "transp" +#define DEBUG_LEVEL 5 +#include + + enum { TCP_ACCEPT_TIMEOUT = 32, TCP_IDLE_TIMEOUT = 900, @@ -157,6 +162,9 @@ static const struct sip_transport *transp_find(struct sip *sip, if (af != AF_UNSPEC && sa_af(&transp->laddr) != af) continue; + if (sa_is_linklocal(&transp->laddr) != sa_is_linklocal(dst)) + continue; + return transp; } @@ -390,6 +398,7 @@ static void udp_recv_handler(const struct sa *src, struct mbuf *mb, void *arg) msg->src = *src; msg->dst = transp->laddr; msg->tp = SIP_TRANSP_UDP; + sa_set_scopeid(&msg->src, sa_scopeid(&transp->laddr)); sip_recv(transp->sip, msg, 0); @@ -1029,6 +1038,25 @@ static int ws_conn_send(struct sip_connqent **qentp, struct sip *sip, } +#if HAVE_INET6 +static int dst_set_scopeid(struct sip *sip, struct sa *dst, enum sip_transp tp) +{ + struct sa laddr; + int err; + + if (sa_af(dst) != AF_INET6 || !sa_is_linklocal(dst)) + return 0; + + err = sip_transp_laddr(sip, &laddr, tp, dst); + if (err) + return err; + + sa_set_scopeid(dst, sa_scopeid(&laddr)); + return 0; +} +#endif + + int sip_transp_init(struct sip *sip, uint32_t sz) { return hash_alloc(&sip->ht_conn, sz); @@ -1343,25 +1371,33 @@ int sip_transp_send(struct sip_connqent **qentp, struct sip *sip, void *sock, const struct sip_transport *transp; struct sip_conn *conn; bool secure = false; + struct sa dsttmp; int err; if (!sip || !dst || !mb) return EINVAL; + sa_cpy(&dsttmp, dst); +#if HAVE_INET6 + err = dst_set_scopeid(sip, &dsttmp, tp); + if (err) + return err; +#endif + switch (tp) { case SIP_TRANSP_UDP: if (!sock) { - transp = transp_find(sip, tp, sa_af(dst), dst); + transp = transp_find(sip, tp, sa_af(&dsttmp), &dsttmp); if (!transp) return EPROTONOSUPPORT; sock = transp->sock; } - trace_send(sip, tp, sock, dst, mb); + trace_send(sip, tp, sock, &dsttmp, mb); - err = udp_send(sock, dst, mb); + err = udp_send(sock, &dsttmp, mb); break; case SIP_TRANSP_TLS: @@ -1373,12 +1409,12 @@ int sip_transp_send(struct sip_connqent **qentp, struct sip *sip, void *sock, if (conn && conn->tc) { - trace_send(sip, tp, conn, dst, mb); + trace_send(sip, tp, conn, &dsttmp, mb); err = tcp_send(conn->tc, mb); } else - err = conn_send(qentp, sip, secure, dst, host, mb, + err = conn_send(qentp, sip, secure, &dsttmp, host, mb, transph, arg); break; @@ -1390,7 +1426,7 @@ int sip_transp_send(struct sip_connqent **qentp, struct sip *sip, void *sock, conn = sock; if (conn && conn->websock_conn) { - trace_send(sip, tp, conn, dst, mb); + trace_send(sip, tp, conn, &dsttmp, mb); err = websock_send(conn->websock_conn, WEBSOCK_BIN, "%b", @@ -1401,7 +1437,7 @@ int sip_transp_send(struct sip_connqent **qentp, struct sip *sip, void *sock, } } else { - err = ws_conn_send(qentp, sip, secure, dst, mb, + err = ws_conn_send(qentp, sip, secure, &dsttmp, mb, transph, arg); if (err) { re_fprintf(stderr, "ws_conn_send failed" From c13309c487622f0b0b0f97e54292699a05a8affc Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Mon, 7 Jun 2021 11:58:57 +0200 Subject: [PATCH 2/2] net,sip: check if destination is reachable when selecting transport --- src/sip/transp.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/sip/transp.c b/src/sip/transp.c index ac0ccabb3..8e49aae3c 100644 --- a/src/sip/transp.c +++ b/src/sip/transp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "sip.h" @@ -150,19 +151,33 @@ static const struct sip_transport *transp_find(struct sip *sip, int af, const struct sa *dst) { struct le *le; - (void)dst; + struct sa dsttmp; for (le = sip->transpl.head; le; le = le->next) { const struct sip_transport *transp = le->data; + const struct sa *laddr = &transp->laddr; + struct sa src; if (transp->tp != tp) continue; - if (af != AF_UNSPEC && sa_af(&transp->laddr) != af) + if (af != AF_UNSPEC && sa_af(laddr) != af) + continue; + + if (!sa_isset(dst, SA_ADDR)) + return transp; + + if (sa_is_linklocal(laddr) != sa_is_linklocal(dst)) + continue; + + sa_cpy(&dsttmp, dst); + sa_set_scopeid(&dsttmp, sa_scopeid(laddr)); + + if (net_dst_source_addr_get(&dsttmp, &src)) continue; - if (sa_is_linklocal(&transp->laddr) != sa_is_linklocal(dst)) + if (!sa_cmp(&src, laddr, SA_ADDR)) continue; return transp;