From 019136712de0ca37f7b5f324819b6ed2aa37685e Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Fri, 28 May 2021 11:08:48 +0200 Subject: [PATCH] sip: copy the IPv6 scope ID from laddr to dst --- src/sip/transp.c | 55 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/sip/transp.c b/src/sip/transp.c index cc7d88daf..b1cc1c14d 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; } @@ -371,6 +379,12 @@ 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)); + + if (err) { + DEBUG_WARNING("could not copy IPv6 scope id from %j to %j\n", + &transp->laddr, &msg->src); + } sip_recv(transp->sip, msg, 0); @@ -1009,6 +1023,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); @@ -1323,25 +1356,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: @@ -1353,12 +1394,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; @@ -1370,7 +1411,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", @@ -1381,7 +1422,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"