<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-mgw/+/19969">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">mgw: Initial IPv6 support<br><br>This commit contains the bulky work of moving all address parsing to<br>support IPv6 together with IPv4.<br>Some specific patches required for full IPv6+IPv4 support requiring<br>behavioral changes come after this one.<br><br>Full Osmux IPv6 support is left out of the scope of this patch.<br><br>Depends: libosmocore.git Ie07a38b05b7888885dba4ae795e9f3d9a561543d (> 1.4.0)<br>Depends: libosmocore.git I59bf4b4b3ed14766a5a5285923d1ffa9fc8b2294 (> 1.4.0)<br>Change-Id: I504ca776d88fd852bbaef07060c125980db3fdd7<br>---<br>M include/osmocom/mgcp/mgcp.h<br>M include/osmocom/mgcp/mgcp_endp.h<br>M include/osmocom/mgcp/mgcp_network.h<br>M include/osmocom/mgcp/osmux.h<br>M src/libosmo-mgcp/mgcp_conn.c<br>M src/libosmo-mgcp/mgcp_network.c<br>M src/libosmo-mgcp/mgcp_osmux.c<br>M src/libosmo-mgcp/mgcp_protocol.c<br>M src/libosmo-mgcp/mgcp_sdp.c<br>M src/libosmo-mgcp/mgcp_vty.c<br>M src/osmo-mgw/mgw_main.c<br>M tests/mgcp/mgcp_test.c<br>12 files changed, 281 insertions(+), 117 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/69/19969/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/mgcp/mgcp.h b/include/osmocom/mgcp/mgcp.h</span><br><span>index 33bfe71..75e531b 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp.h</span><br><span>@@ -23,6 +23,7 @@</span><br><span> #pragma once</span><br><span> </span><br><span> #include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span> #include <osmocom/core/write_queue.h></span><br><span> #include <osmocom/core/timer.h></span><br><span> #include <osmocom/core/logging.h></span><br><span>@@ -207,4 +208,4 @@</span><br><span> </span><br><span> </span><br><span> int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port);</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len);</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_udp_send(int fd, struct osmo_sockaddr *addr, int port, char *buf, int len);</span><br><span>diff --git a/include/osmocom/mgcp/mgcp_endp.h b/include/osmocom/mgcp/mgcp_endp.h</span><br><span>index 065494f..14cae25 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp_endp.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp_endp.h</span><br><span>@@ -26,7 +26,7 @@</span><br><span> #include <osmocom/core/msgb.h></span><br><span> #include <osmocom/gsm/i460_mux.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct sockaddr_in;</span><br><span style="color: hsl(120, 100%, 40%);">+struct sockaddr;</span><br><span> struct mgcp_conn;</span><br><span> struct mgcp_conn_rtp;</span><br><span> struct mgcp_endpoint;</span><br><span>@@ -42,7 +42,7 @@</span><br><span> struct osmo_rtp_msg_ctx {</span><br><span>         int proto;</span><br><span>   struct mgcp_conn_rtp *conn_src;</span><br><span style="color: hsl(0, 100%, 40%);">- struct sockaddr_in *from_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_sockaddr *from_addr;</span><br><span> };</span><br><span> </span><br><span> #define OSMO_RTP_MSG_CTX(MSGB) ((struct osmo_rtp_msg_ctx*)(MSGB)->cb)</span><br><span>diff --git a/include/osmocom/mgcp/mgcp_network.h b/include/osmocom/mgcp/mgcp_network.h</span><br><span>index c4967eb..9674445 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp_network.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp_network.h</span><br><span>@@ -2,6 +2,9 @@</span><br><span> </span><br><span> #include <inttypes.h></span><br><span> #include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/mgcp/mgcp.h></span><br><span> </span><br><span> #define MGCP_DUMMY_LOAD 0x23</span><br><span>@@ -79,7 +82,7 @@</span><br><span> /* 'mgcp_rtp_end': basically a wrapper around the RTP+RTCP ports */</span><br><span> struct mgcp_rtp_end {</span><br><span>       /* remote IP address of the RTP socket */</span><br><span style="color: hsl(0, 100%, 40%);">-       struct in_addr addr;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_sockaddr addr;</span><br><span> </span><br><span>       /* in network byte order */</span><br><span>  int rtp_port, rtcp_port;</span><br><span>@@ -121,12 +124,12 @@</span><br><span>     /* is this tap active (1) or not (0) */</span><br><span>      int enabled;</span><br><span>         /* IP/port to which we're forwarding the tapped data */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct sockaddr_in forward;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_sockaddr forward;</span><br><span> };</span><br><span> </span><br><span> struct mgcp_conn;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr,</span><br><span>         struct msgb *msg, struct mgcp_conn_rtp *conn_src,</span><br><span>            struct mgcp_conn_rtp *conn_dst);</span><br><span> int mgcp_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn);</span><br><span>@@ -140,7 +143,7 @@</span><br><span> void mgcp_patch_and_count(struct mgcp_endpoint *endp,</span><br><span>                          struct mgcp_rtp_state *state,</span><br><span>                        struct mgcp_rtp_end *rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct sockaddr_in *addr, struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+                          struct osmo_sockaddr *addr, struct msgb *msg);</span><br><span> void mgcp_get_local_addr(char *addr, struct mgcp_conn_rtp *conn);</span><br><span> int mgcp_set_ip_tos(int fd, int tos);</span><br><span> </span><br><span>diff --git a/include/osmocom/mgcp/osmux.h b/include/osmocom/mgcp/osmux.h</span><br><span>index 69ba3d0..99b44d1 100644</span><br><span>--- a/include/osmocom/mgcp/osmux.h</span><br><span>+++ b/include/osmocom/mgcp/osmux.h</span><br><span>@@ -1,5 +1,6 @@</span><br><span> #pragma once</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span> </span><br><span> #include <osmocom/netif/osmux.h></span><br><span> struct mgcp_conn_rtp;</span><br><span>@@ -13,7 +14,7 @@</span><br><span> </span><br><span> int osmux_init(int role, struct mgcp_config *cfg);</span><br><span> int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct in_addr *addr, uint16_t port);</span><br><span style="color: hsl(120, 100%, 40%);">+                 struct osmo_sockaddr *addr, uint16_t port);</span><br><span> void conn_osmux_disable(struct mgcp_conn_rtp *conn);</span><br><span> int conn_osmux_allocate_cid(struct mgcp_conn_rtp *conn, int osmux_cid);</span><br><span> void conn_osmux_release_cid(struct mgcp_conn_rtp *conn);</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_conn.c b/src/libosmo-mgcp/mgcp_conn.c</span><br><span>index d52fa64..328e580 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_conn.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_conn.c</span><br><span>@@ -349,6 +349,7 @@</span><br><span> char *mgcp_conn_dump(struct mgcp_conn *conn)</span><br><span> {</span><br><span>     static char str[sizeof(conn->name)+sizeof(conn->id)+256];</span><br><span style="color: hsl(120, 100%, 40%);">+       char ipbuf[INET6_ADDRSTRLEN];</span><br><span> </span><br><span>    if (!conn) {</span><br><span>                 snprintf(str, sizeof(str), "(null connection)");</span><br><span>@@ -362,7 +363,7 @@</span><br><span>                      "rtp:%u rtcp:%u)",</span><br><span>                         conn->name,</span><br><span>                       conn->id,</span><br><span style="color: hsl(0, 100%, 40%);">-                    inet_ntoa(conn->u.rtp.end.addr),</span><br><span style="color: hsl(120, 100%, 40%);">+                   osmo_sockaddr_ntop(&conn->u.rtp.end.addr.u.sa, ipbuf),</span><br><span>                        ntohs(conn->u.rtp.end.rtp_port),</span><br><span>                          ntohs(conn->u.rtp.end.rtcp_port));</span><br><span>               break;</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_network.c b/src/libosmo-mgcp/mgcp_network.c</span><br><span>index 712c706..756ae2a 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_network.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_network.c</span><br><span>@@ -77,6 +77,16 @@</span><br><span> </span><br><span> static int rx_rtp(struct msgb *msg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static bool addr_is_any(struct osmo_sockaddr *osa) {</span><br><span style="color: hsl(120, 100%, 40%);">+    if (osa->u.sa.sa_family == AF_INET6) {</span><br><span style="color: hsl(120, 100%, 40%);">+             struct in6_addr ip6_any = IN6ADDR_ANY_INIT;</span><br><span style="color: hsl(120, 100%, 40%);">+           return memcmp(&osa->u.sin6.sin6_addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                             &ip6_any, sizeof(ip6_any)) == 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              return osa->u.sin.sin_addr.s_addr == 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Determine the local rtp bind IP-address.</span><br><span>  *  \param[out] addr caller provided memory to store the resulting IP-Address.</span><br><span>  *  \param[in] endp mgcp endpoint, that holds a copy of the VTY parameters.</span><br><span>@@ -89,19 +99,20 @@</span><br><span> {</span><br><span> </span><br><span>       struct mgcp_endpoint *endp;</span><br><span style="color: hsl(120, 100%, 40%);">+   char ipbuf[INET6_ADDRSTRLEN];</span><br><span>        int rc;</span><br><span>      endp = conn->conn->endp;</span><br><span> </span><br><span>   /* Try probing the local IP-Address */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (endp->cfg->net_ports.bind_addr_probe && conn->end.addr.s_addr != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-              rc = osmo_sock_local_ip(addr, inet_ntoa(conn->end.addr));</span><br><span style="color: hsl(120, 100%, 40%);">+  if (endp->cfg->net_ports.bind_addr_probe && !addr_is_any(&conn->end.addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = osmo_sock_local_ip(addr, osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf));</span><br><span>               if (rc < 0)</span><br><span>                       LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span>                             "local interface auto detection failed, using configured addresses...\n");</span><br><span>                else {</span><br><span>                       LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,</span><br><span>                             "selected local rtp bind ip %s by probing using remote ip %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                              addr, inet_ntoa(conn->end.addr));</span><br><span style="color: hsl(120, 100%, 40%);">+                          addr, osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf));</span><br><span>                      return;</span><br><span>              }</span><br><span>    }</span><br><span>@@ -110,7 +121,7 @@</span><br><span>      if (endp->cfg->net_ports.bind_addr) {</span><br><span>          /* Check there is a bind IP for the RTP traffic configured,</span><br><span>           * if so, use that IP-Address */</span><br><span style="color: hsl(0, 100%, 40%);">-                osmo_strlcpy(addr, endp->cfg->net_ports.bind_addr, INET_ADDRSTRLEN);</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_strlcpy(addr, endp->cfg->net_ports.bind_addr, INET6_ADDRSTRLEN);</span><br><span>          LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,</span><br><span>                     "using configured rtp bind ip as local bind ip %s\n",</span><br><span>                      addr);</span><br><span>@@ -118,7 +129,7 @@</span><br><span>                /* No specific bind IP is configured for the RTP traffic, so</span><br><span>                  * assume the IP where we listen for incoming MGCP messages</span><br><span>           * as bind IP */</span><br><span style="color: hsl(0, 100%, 40%);">-                osmo_strlcpy(addr, endp->cfg->source_addr, INET_ADDRSTRLEN);</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_strlcpy(addr, endp->cfg->source_addr, INET6_ADDRSTRLEN);</span><br><span>          LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,</span><br><span>                    "using mgcp bind ip as local rtp bind ip: %s\n", addr);</span><br><span>    }</span><br><span>@@ -154,19 +165,26 @@</span><br><span>  *  \param[in] buf buffer that holds the data to be send.</span><br><span>  *  \param[in] len length of the data to be sent.</span><br><span>  *  \returns bytes sent, -1 on error. */</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_udp_send(int fd, struct osmo_sockaddr *addr, int port, char *buf, int len)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct sockaddr_in out;</span><br><span style="color: hsl(120, 100%, 40%);">+       char ipbuf[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t addr_len;</span><br><span style="color: hsl(120, 100%, 40%);">+      bool is_ipv6 =  addr->u.sa.sa_family == AF_INET6;</span><br><span> </span><br><span>     LOGP(DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-       "sending %i bytes length packet to %s:%u ...\n",</span><br><span style="color: hsl(0, 100%, 40%);">-      len, inet_ntoa(*addr), ntohs(port));</span><br><span style="color: hsl(120, 100%, 40%);">+          "sending %i bytes length packet to %s:%u ...\n", len,</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+        ntohs(port));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  out.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-       out.sin_port = port;</span><br><span style="color: hsl(0, 100%, 40%);">-    memcpy(&out.sin_addr, addr, sizeof(*addr));</span><br><span style="color: hsl(120, 100%, 40%);">+       if (is_ipv6) {</span><br><span style="color: hsl(120, 100%, 40%);">+                addr->u.sin6.sin6_port = port;</span><br><span style="color: hsl(120, 100%, 40%);">+             addr_len = sizeof(addr->u.sin6);</span><br><span style="color: hsl(120, 100%, 40%);">+   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              addr->u.sin.sin_port = port;</span><br><span style="color: hsl(120, 100%, 40%);">+               addr_len = sizeof(addr->u.sin);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return sendto(fd, buf, len, 0, (struct sockaddr *)&out, sizeof(out));</span><br><span style="color: hsl(120, 100%, 40%);">+     return sendto(fd, buf, len, 0, &addr->u.sa, addr_len);</span><br><span> }</span><br><span> </span><br><span> /*! send RTP dummy packet (to keep NAT connection open).</span><br><span>@@ -229,12 +247,13 @@</span><br><span>                          struct mgcp_rtp_state *state,</span><br><span>                                struct mgcp_rtp_stream_state *sstate,</span><br><span>                                struct mgcp_rtp_end *rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                           struct sockaddr_in *addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                             struct osmo_sockaddr *addr,</span><br><span>                          uint16_t seq, uint32_t timestamp,</span><br><span>                            const char *text, int32_t * tsdelta_out)</span><br><span> {</span><br><span>         int32_t tsdelta;</span><br><span>     int32_t timestamp_error;</span><br><span style="color: hsl(120, 100%, 40%);">+      char ipbuf[INET6_ADDRSTRLEN];</span><br><span> </span><br><span>    /* Not fully intialized, skip */</span><br><span>     if (sstate->last_tsdelta == 0 && timestamp == sstate->last_timestamp)</span><br><span>@@ -251,8 +270,9 @@</span><br><span>                             "from %s:%d\n",</span><br><span>                            text, seq,</span><br><span>                           state->patch.timestamp_offset, state->patch.seq_offset,</span><br><span style="color: hsl(0, 100%, 40%);">-                           sstate->ssrc, timestamp, inet_ntoa(addr->sin_addr),</span><br><span style="color: hsl(0, 100%, 40%);">-                               ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                            sstate->ssrc, timestamp,</span><br><span style="color: hsl(120, 100%, 40%);">+                           osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                                osmo_sockaddr_port(&addr->u.sa));</span><br><span>            }</span><br><span>            return 0;</span><br><span>    }</span><br><span>@@ -267,9 +287,9 @@</span><br><span>                       "The %s timestamp delta is %d "</span><br><span>                    "on SSRC: %u timestamp: %u "</span><br><span>                       "from %s:%d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       text, tsdelta,</span><br><span style="color: hsl(0, 100%, 40%);">-                  sstate->ssrc, timestamp,</span><br><span style="color: hsl(0, 100%, 40%);">-                     inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                      text, tsdelta, sstate->ssrc, timestamp,</span><br><span style="color: hsl(120, 100%, 40%);">+                    osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_sockaddr_port(&addr->u.sa));</span><br><span> </span><br><span>                return 0;</span><br><span>    }</span><br><span>@@ -281,7 +301,8 @@</span><br><span>                               "on SSRC: %u timestamp: %u from %s:%d\n",</span><br><span>                                  text, sstate->last_tsdelta, tsdelta,</span><br><span>                              sstate->ssrc, timestamp,</span><br><span style="color: hsl(0, 100%, 40%);">-                             inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                              osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                                osmo_sockaddr_port(&addr->u.sa));</span><br><span>            }</span><br><span>    }</span><br><span> </span><br><span>@@ -303,7 +324,8 @@</span><br><span>                   (int16_t)(seq - sstate->last_seq),</span><br><span>                        (int32_t)(timestamp - sstate->last_timestamp),</span><br><span>                    tsdelta,</span><br><span style="color: hsl(0, 100%, 40%);">-                        inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_sockaddr_port(&addr->u.sa),</span><br><span>                      state->packet_duration);</span><br><span>         }</span><br><span>    return 1;</span><br><span>@@ -313,12 +335,13 @@</span><br><span> static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp,</span><br><span>                                     struct mgcp_rtp_state *state,</span><br><span>                                        struct mgcp_rtp_end *rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   struct sockaddr_in *addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     struct osmo_sockaddr *addr,</span><br><span>                                  int16_t delta_seq, uint32_t in_timestamp)</span><br><span> {</span><br><span>        int32_t tsdelta = state->packet_duration;</span><br><span>         int timestamp_offset;</span><br><span>        uint32_t out_timestamp;</span><br><span style="color: hsl(120, 100%, 40%);">+       char ipbuf[INET6_ADDRSTRLEN];</span><br><span> </span><br><span>    if (tsdelta == 0) {</span><br><span>          tsdelta = state->out_stream.last_tsdelta;</span><br><span>@@ -327,7 +350,8 @@</span><br><span>                            "A fixed packet duration is not available, "</span><br><span>                               "using last output timestamp delta instead: %d "</span><br><span>                           "from %s:%d\n", tsdelta,</span><br><span style="color: hsl(0, 100%, 40%);">-                              inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                              osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                                osmo_sockaddr_port(&addr->u.sa));</span><br><span>            } else {</span><br><span>                     tsdelta = rtp_end->codec->rate * 20 / 1000;</span><br><span>                    LOGPENDP(endp, DRTP, LOGL_NOTICE,</span><br><span>@@ -335,7 +359,8 @@</span><br><span>                               "are not available, "</span><br><span>                              "using fixed 20ms instead: %d "</span><br><span>                            "from %s:%d\n", tsdelta,</span><br><span style="color: hsl(0, 100%, 40%);">-                              inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                              osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                                osmo_sockaddr_port(&addr->u.sa));</span><br><span>            }</span><br><span>    }</span><br><span> </span><br><span>@@ -344,13 +369,13 @@</span><br><span> </span><br><span>    if (state->patch.timestamp_offset != timestamp_offset) {</span><br><span>          state->patch.timestamp_offset = timestamp_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>                 LOGPENDP(endp, DRTP, LOGL_NOTICE,</span><br><span>                     "Timestamp offset change on SSRC: %u "</span><br><span>                     "SeqNo delta: %d, TS offset: %d, "</span><br><span>                         "from %s:%d\n", state->in_stream.ssrc,</span><br><span>                          delta_seq, state->patch.timestamp_offset,</span><br><span style="color: hsl(0, 100%, 40%);">-                    inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                      osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_sockaddr_port(&addr->u.sa));</span><br><span>    }</span><br><span> </span><br><span>        return timestamp_offset;</span><br><span>@@ -360,9 +385,10 @@</span><br><span> static int align_rtp_timestamp_offset(struct mgcp_endpoint *endp,</span><br><span>                                       struct mgcp_rtp_state *state,</span><br><span>                                struct mgcp_rtp_end *rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   struct sockaddr_in *addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     struct osmo_sockaddr *addr,</span><br><span>                                  uint32_t timestamp)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        char ipbuf[INET6_ADDRSTRLEN];</span><br><span>        int ts_error = 0;</span><br><span>    int ts_check = 0;</span><br><span>    int ptime = state->packet_duration;</span><br><span>@@ -375,14 +401,14 @@</span><br><span>       /* If there is an alignment error, we have to compensate it */</span><br><span>       if (ts_error) {</span><br><span>              state->patch.timestamp_offset += ptime - ts_error;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>                LOGPENDP(endp, DRTP, LOGL_NOTICE,</span><br><span>                     "Corrected timestamp alignment error of %d on SSRC: %u "</span><br><span>                   "new TS offset: %d, "</span><br><span>                      "from %s:%d\n",</span><br><span>                    ts_error, state->in_stream.ssrc,</span><br><span style="color: hsl(0, 100%, 40%);">-                     state->patch.timestamp_offset, inet_ntoa(addr->sin_addr),</span><br><span style="color: hsl(0, 100%, 40%);">-                         ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                    state->patch.timestamp_offset,</span><br><span style="color: hsl(120, 100%, 40%);">+                     osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_sockaddr_port(&addr->u.sa));</span><br><span>    }</span><br><span> </span><br><span>        /* Check we really managed to compensate the timestamp</span><br><span>@@ -521,8 +547,9 @@</span><br><span> void mgcp_patch_and_count(struct mgcp_endpoint *endp,</span><br><span>                          struct mgcp_rtp_state *state,</span><br><span>                        struct mgcp_rtp_end *rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct sockaddr_in *addr, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+                   struct osmo_sockaddr *addr, struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+  char ipbuf[INET6_ADDRSTRLEN];</span><br><span>        uint32_t arrival_time;</span><br><span>       int32_t transit;</span><br><span>     uint16_t seq;</span><br><span>@@ -560,7 +587,8 @@</span><br><span>                   "pkt-duration: %d, from %s:%d\n",</span><br><span>                          state->in_stream.ssrc,</span><br><span>                    state->patch.seq_offset, state->packet_duration,</span><br><span style="color: hsl(0, 100%, 40%);">-                  inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                      osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_sockaddr_port(&addr->u.sa));</span><br><span>            if (state->packet_duration == 0) {</span><br><span>                        state->packet_duration =</span><br><span>                      rtp_end->codec->rate * 20 / 1000;</span><br><span>@@ -568,14 +596,16 @@</span><br><span>                           "fixed packet duration is not available, "</span><br><span>                                 "using fixed 20ms instead: %d from %s:%d\n",</span><br><span>                               state->packet_duration,</span><br><span style="color: hsl(0, 100%, 40%);">-                              inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                              osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                                osmo_sockaddr_port(&addr->u.sa));</span><br><span>            }</span><br><span>    } else if (state->in_stream.ssrc != ssrc) {</span><br><span>               LOGPENDP(endp, DRTP, LOGL_NOTICE,</span><br><span>                     "SSRC changed: %u -> %u  "</span><br><span>                      "from %s:%d\n",</span><br><span>                    state->in_stream.ssrc, rtp_hdr->ssrc,</span><br><span style="color: hsl(0, 100%, 40%);">-                     inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                      osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_sockaddr_port(&addr->u.sa));</span><br><span> </span><br><span>                state->in_stream.ssrc = ssrc;</span><br><span>             if (rtp_end->force_constant_ssrc) {</span><br><span>@@ -604,7 +634,8 @@</span><br><span>                                  "SeqNo offset: %d, TS offset: %d "</span><br><span>                                 "from %s:%d\n", state->in_stream.ssrc,</span><br><span>                                  state->patch.seq_offset, state->patch.timestamp_offset,</span><br><span style="color: hsl(0, 100%, 40%);">-                           inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                              osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                                osmo_sockaddr_port(&addr->u.sa));</span><br><span>            }</span><br><span> </span><br><span>                state->in_stream.last_tsdelta = 0;</span><br><span>@@ -825,7 +856,7 @@</span><br><span>  *  \param[in] conn_src associated source connection.</span><br><span>  *  \param[in] conn_dst associated destination connection.</span><br><span>  *  \returns 0 on success, -1 on ERROR. */</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr,</span><br><span>         struct msgb *msg, struct mgcp_conn_rtp *conn_src,</span><br><span>            struct mgcp_conn_rtp *conn_dst)</span><br><span> {</span><br><span>@@ -836,6 +867,7 @@</span><br><span>     struct mgcp_trunk *trunk = endp->trunk;</span><br><span>   struct mgcp_rtp_end *rtp_end;</span><br><span>        struct mgcp_rtp_state *rtp_state;</span><br><span style="color: hsl(120, 100%, 40%);">+     char ipbuf[INET6_ADDRSTRLEN];</span><br><span>        char *dest_name;</span><br><span>     int rc;</span><br><span>      int len;</span><br><span>@@ -886,7 +918,7 @@</span><br><span>                        "output disabled, drop to %s %s "</span><br><span>                          "rtp_port:%u rtcp_port:%u\n",</span><br><span>                      dest_name,</span><br><span style="color: hsl(0, 100%, 40%);">-                      inet_ntoa(rtp_end->addr),</span><br><span style="color: hsl(120, 100%, 40%);">+                  osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),</span><br><span>                       ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)</span><br><span>               );</span><br><span>       } else if (is_rtp) {</span><br><span>@@ -932,7 +964,8 @@</span><br><span>                   LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span>                              "process/send to %s %s "</span><br><span>                           "rtp_port:%u rtcp_port:%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                 dest_name, inet_ntoa(rtp_end->addr),</span><br><span style="color: hsl(120, 100%, 40%);">+                               dest_name,</span><br><span style="color: hsl(120, 100%, 40%);">+                            osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),</span><br><span>                               ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)</span><br><span>                           );</span><br><span> </span><br><span>@@ -975,7 +1008,7 @@</span><br><span>        } else if (!trunk->omit_rtcp) {</span><br><span>           LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span>                      "send to %s %s rtp_port:%u rtcp_port:%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   dest_name, inet_ntoa(rtp_end->addr),</span><br><span style="color: hsl(120, 100%, 40%);">+                       dest_name, osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),</span><br><span>                    ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)</span><br><span>                   );</span><br><span> </span><br><span>@@ -995,10 +1028,11 @@</span><br><span> </span><br><span> /* Check if the origin (addr) matches the address/port data of the RTP</span><br><span>  * connections. */</span><br><span style="color: hsl(0, 100%, 40%);">-static int check_rtp_origin(struct mgcp_conn_rtp *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                          struct sockaddr_in *addr)</span><br><span style="color: hsl(120, 100%, 40%);">+static int check_rtp_origin(struct mgcp_conn_rtp *conn, struct osmo_sockaddr *addr)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- if (conn->end.addr.s_addr == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+  char ipbuf[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (addr_is_any(&conn->end.addr)) {</span><br><span>           switch (conn->conn->mode) {</span><br><span>            case MGCP_CONN_LOOPBACK:</span><br><span>                     /* HACK: for IuUP, we want to reply with an IuUP Initialization ACK upon the first RTP</span><br><span>@@ -1010,7 +1044,8 @@</span><br><span>                        * MGCP port is in loopback mode, allow looping back the packet to any source. */</span><br><span>                    LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span>                             "In loopback mode and remote address not set:"</span><br><span style="color: hsl(0, 100%, 40%);">-                                " allowing data from address: %s\n", inet_ntoa(addr->sin_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+                                 " allowing data from address: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                osmo_sockaddr_ntop(&addr->u.sa, ipbuf));</span><br><span>                     return 0;</span><br><span> </span><br><span>                default:</span><br><span>@@ -1019,18 +1054,25 @@</span><br><span>                    * confuse humans with expected errors. */</span><br><span>                   LOGPCONN(conn->conn, DRTP, LOGL_INFO,</span><br><span>                              "Rx RTP from %s, but remote address not set:"</span><br><span style="color: hsl(0, 100%, 40%);">-                                 " dropping early media\n", inet_ntoa(addr->sin_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+                           " dropping early media\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                          osmo_sockaddr_ntop(&addr->u.sa, ipbuf));</span><br><span>                     return -1;</span><br><span>           }</span><br><span>    }</span><br><span> </span><br><span>        /* Note: Check if the inbound RTP data comes from the same host to</span><br><span>    * which we send our outgoing RTP traffic. */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (conn->end.addr.s_addr != addr->sin_addr.s_addr) {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (conn->end.addr.u.sa.sa_family != addr->u.sa.sa_family ||</span><br><span style="color: hsl(120, 100%, 40%);">+        (conn->end.addr.u.sa.sa_family == AF_INET &&</span><br><span style="color: hsl(120, 100%, 40%);">+        conn->end.addr.u.sin.sin_addr.s_addr != addr->u.sin.sin_addr.s_addr) ||</span><br><span style="color: hsl(120, 100%, 40%);">+        (conn->end.addr.u.sa.sa_family == AF_INET6 &&</span><br><span style="color: hsl(120, 100%, 40%);">+       memcmp(&conn->end.addr.u.sin6.sin6_addr, &addr->u.sin6.sin6_addr,</span><br><span style="color: hsl(120, 100%, 40%);">+              sizeof(struct in6_addr)) == 0)) {</span><br><span>                LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                        "data from wrong address: %s, ", inet_ntoa(addr->sin_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+                     "data from wrong address: %s, ",</span><br><span style="color: hsl(120, 100%, 40%);">+                    osmo_sockaddr_ntop(&addr->u.sa, ipbuf));</span><br><span>             LOGPC(DRTP, LOGL_ERROR, "expected: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   inet_ntoa(conn->end.addr));</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf));</span><br><span>               LOGPCONN(conn->conn, DRTP, LOGL_ERROR, "packet tossed\n");</span><br><span>              return -1;</span><br><span>   }</span><br><span>@@ -1039,10 +1081,11 @@</span><br><span>   * the same as the remote port where we transmit outgoing RTP traffic</span><br><span>         * to (set by MDCX). We use this to check the origin of the data for</span><br><span>          * plausibility. */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (conn->end.rtp_port != addr->sin_port &&</span><br><span style="color: hsl(0, 100%, 40%);">-           conn->end.rtcp_port != addr->sin_port) {</span><br><span style="color: hsl(120, 100%, 40%);">+    if (conn->end.rtp_port != osmo_sockaddr_port(&addr->u.sa) &&</span><br><span style="color: hsl(120, 100%, 40%);">+            conn->end.rtcp_port != osmo_sockaddr_port(&addr->u.sa)) {</span><br><span>              LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                        "data from wrong source port: %d, ", ntohs(addr->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                     "data from wrong source port: %d, ",</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_sockaddr_port(&addr->u.sa));</span><br><span>            LOGPC(DRTP, LOGL_ERROR,</span><br><span>                    "expected: %d for RTP or %d for RTCP\n",</span><br><span>                   ntohs(conn->end.rtp_port), ntohs(conn->end.rtcp_port));</span><br><span>@@ -1057,26 +1100,29 @@</span><br><span>  * makes sense */</span><br><span> static int check_rtp_destin(struct mgcp_conn_rtp *conn)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+    char ipbuf[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+ bool ip_is_any = addr_is_any(&conn->end.addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      /* Note: it is legal to create a connection but never setting a port</span><br><span>          * and IP-address for outgoing data. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (strcmp(inet_ntoa(conn->end.addr), "0.0.0.0") == 0 && conn->end.rtp_port == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ip_is_any && conn->end.rtp_port == 0) {</span><br><span>               LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,</span><br><span>                     "destination IP-address and rtp port is (not yet) known (%s:%u)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   inet_ntoa(conn->end.addr), conn->end.rtp_port);</span><br><span style="color: hsl(120, 100%, 40%);">+                         osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf), conn->end.rtp_port);</span><br><span>             return -1;</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (strcmp(inet_ntoa(conn->end.addr), "0.0.0.0") == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ip_is_any) {</span><br><span>             LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span>                     "destination IP-address is invalid (%s:%u)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                        inet_ntoa(conn->end.addr), conn->end.rtp_port);</span><br><span style="color: hsl(120, 100%, 40%);">+                         osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf), conn->end.rtp_port);</span><br><span>             return -1;</span><br><span>   }</span><br><span> </span><br><span>        if (conn->end.rtp_port == 0) {</span><br><span>            LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span>                     "destination rtp port is invalid (%s:%u)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                  inet_ntoa(conn->end.addr), conn->end.rtp_port);</span><br><span style="color: hsl(120, 100%, 40%);">+                         osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf), conn->end.rtp_port);</span><br><span>             return -1;</span><br><span>   }</span><br><span> </span><br><span>@@ -1147,7 +1193,6 @@</span><br><span>        struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);</span><br><span>         enum rtp_proto proto = mc->proto;</span><br><span>         struct mgcp_conn_rtp *conn_src = mc->conn_src;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct sockaddr_in *from_addr = mc->from_addr;</span><br><span>    struct mgcp_endpoint *endp = conn_src->conn->endp;</span><br><span> </span><br><span>         LOGPENDP(endp, DRTP, LOGL_DEBUG, "destin conn:%s\n",</span><br><span>@@ -1167,7 +1212,7 @@</span><br><span>                        "endpoint type is MGCP_RTP_DEFAULT, "</span><br><span>                      "using mgcp_send() to forward data directly\n");</span><br><span>          return mgcp_send(endp, proto == MGCP_PROTO_RTP,</span><br><span style="color: hsl(0, 100%, 40%);">-                          from_addr, msg, conn_src, conn_dst);</span><br><span style="color: hsl(120, 100%, 40%);">+                          mc->from_addr, msg, conn_src, conn_dst);</span><br><span>         case MGCP_OSMUX_BSC_NAT:</span><br><span>     case MGCP_OSMUX_BSC:</span><br><span>                 LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span>@@ -1197,7 +1242,7 @@</span><br><span>     struct mgcp_conn_rtp *conn_src = mc->conn_src;</span><br><span>    struct mgcp_conn *conn = conn_src->conn;</span><br><span>  struct mgcp_conn *conn_dst;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct sockaddr_in *from_addr = mc->from_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_sockaddr *from_addr = mc->from_addr;</span><br><span> </span><br><span>      /*! NOTE: This callback function implements the endpoint specific</span><br><span>     *  dispatch behaviour of an rtp bridge/proxy endpoint. It is assumed</span><br><span>@@ -1216,8 +1261,19 @@</span><br><span>                * address data from the UDP packet header to patch the</span><br><span>               * outgoing address in connection on the fly */</span><br><span>              if (conn->u.rtp.end.rtp_port == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 conn->u.rtp.end.addr = from_addr->sin_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-                       conn->u.rtp.end.rtp_port = from_addr->sin_port;</span><br><span style="color: hsl(120, 100%, 40%);">+                 OSMO_ASSERT(conn->u.rtp.end.addr.u.sa.sa_family == from_addr->u.sa.sa_family);</span><br><span style="color: hsl(120, 100%, 40%);">+                  switch (from_addr->u.sa.sa_family) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+                         conn->u.rtp.end.addr.u.sin.sin_addr = from_addr->u.sin.sin_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+                                conn->u.rtp.end.rtp_port = from_addr->u.sin.sin_port;</span><br><span style="color: hsl(120, 100%, 40%);">+                           break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+                                conn->u.rtp.end.addr.u.sin6.sin6_addr = from_addr->u.sin6.sin6_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+                            conn->u.rtp.end.rtp_port = from_addr->u.sin6.sin6_port;</span><br><span style="color: hsl(120, 100%, 40%);">+                         break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        default:</span><br><span style="color: hsl(120, 100%, 40%);">+                              OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+                   }</span><br><span>            }</span><br><span>            return mgcp_send_rtp(conn_src, msg);</span><br><span>         }</span><br><span>@@ -1266,7 +1322,7 @@</span><br><span>    struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);</span><br><span>         struct mgcp_conn_rtp *conn_src = mc->conn_src;</span><br><span>    struct mgcp_conn *conn = conn_src->conn;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct sockaddr_in *from_addr = mc->from_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_sockaddr *from_addr = mc->from_addr;</span><br><span> </span><br><span>      /* Check if the connection is in loopback mode, if yes, just send the</span><br><span>         * incoming data back to the origin */</span><br><span>@@ -1276,8 +1332,19 @@</span><br><span>               * address data from the UDP packet header to patch the</span><br><span>               * outgoing address in connection on the fly */</span><br><span>              if (conn->u.rtp.end.rtp_port == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 conn->u.rtp.end.addr = from_addr->sin_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-                       conn->u.rtp.end.rtp_port = from_addr->sin_port;</span><br><span style="color: hsl(120, 100%, 40%);">+                 OSMO_ASSERT(conn->u.rtp.end.addr.u.sa.sa_family == from_addr->u.sa.sa_family);</span><br><span style="color: hsl(120, 100%, 40%);">+                  switch (from_addr->u.sa.sa_family) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+                         conn->u.rtp.end.addr.u.sin.sin_addr = from_addr->u.sin.sin_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+                                conn->u.rtp.end.rtp_port = from_addr->u.sin.sin_port;</span><br><span style="color: hsl(120, 100%, 40%);">+                           break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+                                conn->u.rtp.end.addr.u.sin6.sin6_addr = from_addr->u.sin6.sin6_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+                            conn->u.rtp.end.rtp_port = from_addr->u.sin6.sin6_port;</span><br><span style="color: hsl(120, 100%, 40%);">+                         break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        default:</span><br><span style="color: hsl(120, 100%, 40%);">+                              OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+                   }</span><br><span>            }</span><br><span>            return mgcp_send_rtp(conn_src, msg);</span><br><span>         }</span><br><span>@@ -1331,8 +1398,9 @@</span><br><span> </span><br><span>        struct mgcp_conn_rtp *conn_src;</span><br><span>      struct mgcp_endpoint *endp;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct sockaddr_in addr;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_sockaddr addr;</span><br><span>   socklen_t slen = sizeof(addr);</span><br><span style="color: hsl(120, 100%, 40%);">+        char ipbuf[INET6_ADDRSTRLEN];</span><br><span>        int ret;</span><br><span>     enum rtp_proto proto;</span><br><span>        struct osmo_rtp_msg_ctx *mc;</span><br><span>@@ -1346,7 +1414,7 @@</span><br><span> </span><br><span>     proto = (fd == &conn_src->end.rtp)? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        ret = recvfrom(fd->fd, msgb_data(msg), msg->data_len, 0, (struct sockaddr *)&addr, &slen);</span><br><span style="color: hsl(120, 100%, 40%);">+      ret = recvfrom(fd->fd, msgb_data(msg), msg->data_len, 0, (struct sockaddr *)&addr.u.sa, &slen);</span><br><span> </span><br><span>    if (ret <= 0) {</span><br><span>           LOG_CONN_RTP(conn_src, LOGL_ERROR, "recvfrom error: %s\n", strerror(errno));</span><br><span>@@ -1358,7 +1426,8 @@</span><br><span> </span><br><span>   LOG_CONN_RTP(conn_src, LOGL_DEBUG, "%s: rx %u bytes from %s:%u\n",</span><br><span>                      proto == MGCP_PROTO_RTP ? "RTP" : "RTPC",</span><br><span style="color: hsl(0, 100%, 40%);">-                   msgb_length(msg), inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                    msgb_length(msg), osmo_sockaddr_ntop(&addr.u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+                  osmo_sockaddr_port(&addr.u.sa));</span><br><span> </span><br><span>        if ((proto == MGCP_PROTO_RTP && check_rtp(conn_src, msg))</span><br><span>        || (proto == MGCP_PROTO_RTCP && check_rtcp(conn_src, msg))) {</span><br><span>@@ -1383,7 +1452,10 @@</span><br><span>   };</span><br><span>   LOG_CONN_RTP(conn_src, LOGL_DEBUG, "msg ctx: %d %p %s\n",</span><br><span>               mc->proto, mc->conn_src,</span><br><span style="color: hsl(0, 100%, 40%);">-                  osmo_hexdump((void*)mc->from_addr, sizeof(struct sockaddr_in)));</span><br><span style="color: hsl(120, 100%, 40%);">+                   osmo_hexdump((void*)mc->from_addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                              mc->from_addr->u.sa.sa_family == AF_INET6 ?</span><br><span style="color: hsl(120, 100%, 40%);">+                                   sizeof(struct sockaddr_in6) :</span><br><span style="color: hsl(120, 100%, 40%);">+                                 sizeof(struct sockaddr_in)));</span><br><span> </span><br><span>    /* Increment RX statistics */</span><br><span>        rate_ctr_inc(&conn_src->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR]);</span><br><span>@@ -1404,7 +1476,7 @@</span><br><span> {</span><br><span>     struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);</span><br><span>         struct mgcp_conn_rtp *conn_src = mc->conn_src;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct sockaddr_in *from_addr = mc->from_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_sockaddr *from_addr = mc->from_addr;</span><br><span>  struct mgcp_conn *conn = conn_src->conn;</span><br><span>  struct mgcp_trunk *trunk = conn->endp->trunk;</span><br><span> </span><br><span>@@ -1456,7 +1528,7 @@</span><br><span> {</span><br><span>         int rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     rc = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, source_addr, port,</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, source_addr, port,</span><br><span>                       NULL, 0, OSMO_SOCK_F_BIND);</span><br><span>     if (rc < 0) {</span><br><span>             LOGP(DRTP, LOGL_ERROR, "failed to bind UDP port (%s:%i).\n",</span><br><span>@@ -1536,7 +1608,7 @@</span><br><span> {</span><br><span>  char name[512];</span><br><span>      struct mgcp_rtp_end *end;</span><br><span style="color: hsl(0, 100%, 40%);">-       char local_ip_addr[INET_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+  char local_ip_addr[INET6_ADDRSTRLEN];</span><br><span> </span><br><span>    snprintf(name, sizeof(name), "%s-%s", conn->conn->name, conn->conn->id);</span><br><span>       end = &conn->end;</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_osmux.c b/src/libosmo-mgcp/mgcp_osmux.c</span><br><span>index 93c922d..5864c95 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_osmux.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_osmux.c</span><br><span>@@ -148,15 +148,20 @@</span><br><span> /* Lookup existing handle for a specified address, if the handle can not be</span><br><span>  * found, the function will automatically allocate one */</span><br><span> static struct osmux_in_handle *</span><br><span style="color: hsl(0, 100%, 40%);">-osmux_handle_lookup(struct mgcp_config *cfg, struct in_addr *addr, int rem_port)</span><br><span style="color: hsl(120, 100%, 40%);">+osmux_handle_lookup(struct mgcp_config *cfg, struct osmo_sockaddr *addr, int rem_port)</span><br><span> {</span><br><span>        struct osmux_handle *h;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     h = osmux_handle_find_get(addr, rem_port);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (addr->u.sa.sa_family != AF_INET) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DLMGCP, LOGL_DEBUG, "IPv6 not supported in osmux yet!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   h = osmux_handle_find_get(&addr->u.sin.sin_addr, rem_port);</span><br><span>   if (h != NULL)</span><br><span>               return h->in;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    h = osmux_handle_alloc(cfg, addr, rem_port);</span><br><span style="color: hsl(120, 100%, 40%);">+  h = osmux_handle_alloc(cfg, &addr->u.sin.sin_addr, rem_port);</span><br><span>         if (h == NULL)</span><br><span>               return NULL;</span><br><span> </span><br><span>@@ -236,7 +241,7 @@</span><br><span> {</span><br><span>  struct mgcp_conn_rtp *conn = data;</span><br><span>   struct mgcp_endpoint *endp = conn->conn->endp;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct sockaddr_in addr = { /* FIXME: do we know the source address?? */ };</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_sockaddr addr = { /* FIXME: do we know the source address?? */ };</span><br><span>        struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);</span><br><span>         *mc = (struct osmo_rtp_msg_ctx){</span><br><span>             .proto = MGCP_PROTO_RTP,</span><br><span>@@ -275,6 +280,8 @@</span><br><span> static int endp_osmux_state_check(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,</span><br><span>                            bool sending)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+  char ipbuf[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      switch(conn->osmux.state) {</span><br><span>       case OSMUX_STATE_ACTIVATING:</span><br><span>         if (osmux_enable_conn(endp, conn, &conn->end.addr, conn->end.rtp_port) < 0) {</span><br><span>@@ -287,7 +294,8 @@</span><br><span>             LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR,</span><br><span>                   "Osmux %s CID %u towards %s:%u is now enabled\n",</span><br><span>                          sending ? "sent" : "received",</span><br><span style="color: hsl(0, 100%, 40%);">-                      conn->osmux.cid, inet_ntoa(conn->end.addr),</span><br><span style="color: hsl(120, 100%, 40%);">+                     conn->osmux.cid,</span><br><span style="color: hsl(120, 100%, 40%);">+                   osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf),</span><br><span>                      ntohs(conn->end.rtp_port));</span><br><span>              return 0;</span><br><span>    case OSMUX_STATE_ENABLED:</span><br><span>@@ -433,7 +441,7 @@</span><br><span>  *  \param[in] port portnumber of the remote OSMUX endpoint (in network byte order)</span><br><span>  *  \returns 0 on success, -1 on ERROR */</span><br><span> int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                  struct in_addr *addr, uint16_t port)</span><br><span style="color: hsl(120, 100%, 40%);">+                  struct osmo_sockaddr *addr, uint16_t port)</span><br><span> {</span><br><span>        /*! If osmux is enabled, initialize the output handler. This handler is</span><br><span>       *  used to reconstruct the RTP flow from osmux. The RTP SSRC is</span><br><span>@@ -444,7 +452,7 @@</span><br><span>        *  overlapping RTP SSRC traveling to the BTSes behind the BSC,</span><br><span>       *  similarly, for flows traveling to the MSC.</span><br><span>        */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct in_addr addr_unset = {};</span><br><span style="color: hsl(120, 100%, 40%);">+       struct in6_addr addr_unset = {};</span><br><span>     static const uint32_t rtp_ssrc_winlen = UINT32_MAX / (OSMUX_CID_MAX + 1);</span><br><span>    uint16_t osmux_dummy = endp->cfg->osmux_dummy;</span><br><span> </span><br><span>@@ -457,7 +465,10 @@</span><br><span>      }</span><br><span> </span><br><span>        /* Wait until we have the connection information from MDCX */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (memcmp(&conn->end.addr, &addr_unset, sizeof(addr_unset)) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+       if (memcmp(&conn->end.addr, &addr_unset,</span><br><span style="color: hsl(120, 100%, 40%);">+              conn->end.addr.u.sa.sa_family == AF_INET6 ?</span><br><span style="color: hsl(120, 100%, 40%);">+                     sizeof(struct in6_addr) :</span><br><span style="color: hsl(120, 100%, 40%);">+                     sizeof(struct in_addr)) == 0) {</span><br><span>              LOGPCONN(conn->conn, DLMGCP, LOGL_INFO,</span><br><span>                   "Osmux remote address/port still unknown\n");</span><br><span>              return -1;</span><br><span>@@ -559,6 +570,7 @@</span><br><span>  *  \returns bytes sent, -1 on error */</span><br><span> int osmux_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+      char ipbuf[INET6_ADDRSTRLEN];</span><br><span>        struct osmux_hdr *osmuxh;</span><br><span>    int buf_len;</span><br><span>         struct in_addr addr_unset = {};</span><br><span>@@ -588,7 +600,8 @@</span><br><span> </span><br><span>    LOGPCONN(conn->conn, DLMGCP, LOGL_DEBUG,</span><br><span>           "sending OSMUX dummy load to %s:%u CID %u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                 inet_ntoa(conn->end.addr), ntohs(conn->end.rtp_port), conn->osmux.cid);</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+               ntohs(conn->end.rtp_port), conn->osmux.cid);</span><br><span> </span><br><span>      return mgcp_udp_send(osmux_fd.fd, &conn->end.addr,</span><br><span>                         conn->end.rtp_port, (char*)osmuxh, buf_len);</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>index 9ec4aee..1269524 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>@@ -230,7 +230,7 @@</span><br><span>      struct msgb *sdp;</span><br><span>    int rc;</span><br><span>      struct msgb *result;</span><br><span style="color: hsl(0, 100%, 40%);">-    char local_ip_addr[INET_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+  char local_ip_addr[INET6_ADDRSTRLEN];</span><br><span> </span><br><span>    sdp = msgb_alloc_headroom(4096, 128, "sdp record");</span><br><span>        if (!sdp)</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_sdp.c b/src/libosmo-mgcp/mgcp_sdp.c</span><br><span>index 1c3c89a..e98ca94 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_sdp.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_sdp.c</span><br><span>@@ -21,6 +21,9 @@</span><br><span>  */</span><br><span> </span><br><span> #include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/sockaddr_str.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/mgcp/mgcp.h></span><br><span> #include <osmocom/mgcp/osmux.h></span><br><span> #include <osmocom/mgcp/mgcp_conn.h></span><br><span>@@ -259,6 +262,42 @@</span><br><span>       return -EINVAL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int audio_ip_from_sdp(struct osmo_sockaddr *dst_addr, char *sdp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        bool is_ipv6;</span><br><span style="color: hsl(120, 100%, 40%);">+ char ipbuf[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strncmp("c=IN IP", sdp, 7) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    sdp += 7;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (*sdp == '6')</span><br><span style="color: hsl(120, 100%, 40%);">+             is_ipv6 = true;</span><br><span style="color: hsl(120, 100%, 40%);">+        else if (*sdp == '4')</span><br><span style="color: hsl(120, 100%, 40%);">+        is_ipv6 = false;</span><br><span style="color: hsl(120, 100%, 40%);">+       else</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+     sdp++;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (*sdp != ' ')</span><br><span style="color: hsl(120, 100%, 40%);">+              return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    sdp++;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (is_ipv6) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* 45 = INET6_ADDRSTRLEN -1 */</span><br><span style="color: hsl(120, 100%, 40%);">+                if (sscanf(sdp, "%45s", ipbuf) != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                        return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            if (inet_pton(AF_INET6, ipbuf, &dst_addr->u.sin6.sin6_addr) != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                      return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            dst_addr->u.sa.sa_family = AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* 15 = INET_ADDRSTRLEN -1 */</span><br><span style="color: hsl(120, 100%, 40%);">+         if (sscanf(sdp, "%15s", ipbuf) != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                        return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            if (inet_pton(AF_INET, ipbuf, &dst_addr->u.sin.sin_addr) != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                 return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            dst_addr->u.sa.sa_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Pick optional fmtp parameters by payload type, if there are no fmtp</span><br><span>  * parameters, a nullpointer is returned */</span><br><span> static struct mgcp_codec_param *param_by_pt(int pt, struct sdp_fmtp_param *fmtp_params, unsigned int fmtp_params_len)</span><br><span>@@ -289,6 +328,7 @@</span><br><span>       struct sdp_fmtp_param fmtp_params[MGCP_MAX_CODECS];</span><br><span>  unsigned int fmtp_used = 0;</span><br><span>  struct mgcp_codec_param *codec_param;</span><br><span style="color: hsl(120, 100%, 40%);">+ char ipbuf[INET6_ADDRSTRLEN];</span><br><span>        char *line;</span><br><span>  unsigned int i;</span><br><span>      void *tmp_ctx = talloc_new(NULL);</span><br><span>@@ -298,7 +338,6 @@</span><br><span>      int ptime, ptime2 = 0;</span><br><span>       char audio_name[64];</span><br><span>         int port, rc;</span><br><span style="color: hsl(0, 100%, 40%);">-   char ipv4[16];</span><br><span> </span><br><span>   OSMO_ASSERT(endp);</span><br><span>   OSMO_ASSERT(conn);</span><br><span>@@ -355,10 +394,8 @@</span><br><span>                            codecs_used = rc;</span><br><span>                    break;</span><br><span>               case 'c':</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (sscanf(line, "c=IN IP4 %15s", ipv4) == 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               inet_aton(ipv4, &rtp->addr);</span><br><span style="color: hsl(0, 100%, 40%);">-                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (audio_ip_from_sdp(&rtp->addr, line) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                                return -1;</span><br><span>                   break;</span><br><span>               default:</span><br><span>                     if (p->endp)</span><br><span>@@ -393,7 +430,7 @@</span><br><span> </span><br><span>    LOGPCONN(conn->conn, DLMGCP, LOGL_NOTICE,</span><br><span>              "Got media info via SDP: port:%d, addr:%s, duration:%d, payload-types:",</span><br><span style="color: hsl(0, 100%, 40%);">-      ntohs(rtp->rtp_port), inet_ntoa(rtp->addr),</span><br><span style="color: hsl(120, 100%, 40%);">+             ntohs(rtp->rtp_port), osmo_sockaddr_ntop(&rtp->addr.u.sa, ipbuf),</span><br><span>          rtp->packet_duration_ms);</span><br><span>    if (codecs_used == 0)</span><br><span>                LOGPC(DLMGCP, LOGL_NOTICE, "none");</span><br><span>@@ -529,6 +566,7 @@</span><br><span>  int local_port;</span><br><span>      struct sdp_fmtp_param fmtp_params[1];</span><br><span>         unsigned int fmtp_params_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    bool addr_is_v6;</span><br><span> </span><br><span>         OSMO_ASSERT(endp);</span><br><span>   OSMO_ASSERT(conn);</span><br><span>@@ -543,12 +581,16 @@</span><br><span>   audio_name = codec->audio_name;</span><br><span>   payload_type = codec->payload_type;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    addr_is_v6 = osmo_ip_str_type(addr) == AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   rc = msgb_printf(sdp,</span><br><span>                         "v=0\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-                     "o=- %s 23 IN IP4 %s\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                   "o=- %s 23 IN IP%c %s\r\n"</span><br><span>                         "s=-\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-                     "c=IN IP4 %s\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-                     "t=0 0\r\n", conn->conn->id, addr, addr);</span><br><span style="color: hsl(120, 100%, 40%);">+                     "c=IN IP%c %s\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                  "t=0 0\r\n", conn->conn->id,</span><br><span style="color: hsl(120, 100%, 40%);">+                  addr_is_v6 ? '6' : '4', addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                         addr_is_v6 ? '6' : '4', addr);</span><br><span> </span><br><span>  if (rc < 0)</span><br><span>               goto buffer_too_small;</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_vty.c b/src/libosmo-mgcp/mgcp_vty.c</span><br><span>index 22863c7..8ea1cdd 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_vty.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_vty.c</span><br><span>@@ -22,6 +22,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/sockaddr_str.h></span><br><span> #include <osmocom/vty/misc.h></span><br><span> #include <osmocom/mgcp/mgcp.h></span><br><span> #include <osmocom/mgcp/mgcp_common.h></span><br><span>@@ -407,9 +408,11 @@</span><br><span> </span><br><span> DEFUN(cfg_mgcp_local_ip,</span><br><span>       cfg_mgcp_local_ip_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "local ip A.B.C.D",</span><br><span style="color: hsl(120, 100%, 40%);">+      "local ip " VTY_IPV46_CMD,</span><br><span>       "Local options for the SDP record\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      IP_STR "IPv4 Address to use in SDP record\n")</span><br><span style="color: hsl(120, 100%, 40%);">+      IP_STR</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv4 Address to use in SDP record\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv6 Address to use in SDP record\n")</span><br><span> {</span><br><span>    osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);</span><br><span>         return CMD_SUCCESS;</span><br><span>@@ -418,7 +421,10 @@</span><br><span> #define BIND_STR "Listen/Bind related socket option\n"</span><br><span> DEFUN(cfg_mgcp_bind_ip,</span><br><span>       cfg_mgcp_bind_ip_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")</span><br><span style="color: hsl(120, 100%, 40%);">+      "bind ip " VTY_IPV46_CMD,</span><br><span style="color: hsl(120, 100%, 40%);">+      BIND_STR IP_STR</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv4 Address to bind to\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv6 Address to bind to\n")</span><br><span> {</span><br><span>  osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);</span><br><span>      return CMD_SUCCESS;</span><br><span>@@ -494,8 +500,10 @@</span><br><span> </span><br><span> DEFUN(cfg_mgcp_rtp_bind_ip,</span><br><span>       cfg_mgcp_rtp_bind_ip_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "rtp bind-ip A.B.C.D",</span><br><span style="color: hsl(0, 100%, 40%);">-      RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")</span><br><span style="color: hsl(120, 100%, 40%);">+      "rtp bind-ip " VTY_IPV46_CMD,</span><br><span style="color: hsl(120, 100%, 40%);">+      RTP_STR "Bind endpoints facing the Network\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv4 Address to bind to\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv6 Address to bind to\n")</span><br><span> {</span><br><span>  osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);</span><br><span>      return CMD_SUCCESS;</span><br><span>@@ -850,11 +858,13 @@</span><br><span>  return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define CALL_AGENT_STR "Callagent information\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define CALL_AGENT_STR "Call agent information\n"</span><br><span> DEFUN(cfg_mgcp_agent_addr,</span><br><span>       cfg_mgcp_agent_addr_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "call-agent ip A.B.C.D",</span><br><span style="color: hsl(0, 100%, 40%);">-      CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")</span><br><span style="color: hsl(120, 100%, 40%);">+      "call-agent ip " VTY_IPV46_CMD,</span><br><span style="color: hsl(120, 100%, 40%);">+      CALL_AGENT_STR IP_STR</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv4 Address of the call agent\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv6 Address of the call agent\n")</span><br><span> {</span><br><span>      osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);</span><br><span>  return CMD_SUCCESS;</span><br><span>@@ -1236,13 +1246,15 @@</span><br><span> </span><br><span> DEFUN(tap_rtp,</span><br><span>       tap_rtp_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",</span><br><span style="color: hsl(120, 100%, 40%);">+      "tap-rtp <0-64> ENDPOINT CONN (in|out) " VTY_IPV46_CMD " <0-65534>",</span><br><span>       "Forward data on endpoint to a different system\n" "Trunk number\n"</span><br><span>       "The endpoint in hex\n"</span><br><span>       "The connection id in hex\n"</span><br><span>       "Forward incoming data\n"</span><br><span>       "Forward leaving data\n"</span><br><span style="color: hsl(0, 100%, 40%);">-      "destination IP of the data\n" "destination port\n")</span><br><span style="color: hsl(120, 100%, 40%);">+      "Destination IPv4 of the data\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "Destination IPv6 of the data\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "Destination port\n")</span><br><span> {</span><br><span>       struct mgcp_rtp_tap *tap;</span><br><span>    struct mgcp_trunk *trunk;</span><br><span>@@ -1290,8 +1302,22 @@</span><br><span>   }</span><br><span> </span><br><span>        memset(&tap->forward, 0, sizeof(tap->forward));</span><br><span style="color: hsl(0, 100%, 40%);">-       inet_aton(argv[4], &tap->forward.sin_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-      tap->forward.sin_port = htons(atoi(argv[5]));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    tap->forward.u.sa.sa_family = osmo_ip_str_type(argv[4]);</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (tap->forward.u.sa.sa_family) {</span><br><span style="color: hsl(120, 100%, 40%);">+     case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+         if (inet_pton(AF_INET, argv[4], &tap->forward.u.sin.sin_addr) != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                    return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           tap->forward.u.sin.sin_port = htons(atoi(argv[5]));</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+                if (inet_pton(AF_INET6, argv[4], &tap->forward.u.sin6.sin6_addr) != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                 return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           tap->forward.u.sin6.sin6_port = htons(atoi(argv[5]));</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span>    tap->enabled = 1;</span><br><span>         return CMD_SUCCESS;</span><br><span> }</span><br><span>@@ -1407,7 +1433,10 @@</span><br><span> </span><br><span> DEFUN(cfg_mgcp_osmux_ip,</span><br><span>       cfg_mgcp_osmux_ip_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")</span><br><span style="color: hsl(120, 100%, 40%);">+      "osmux bind-ip " VTY_IPV46_CMD,</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMUX_STR IP_STR</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv4 Address to bind to\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      "IPv6 Address to bind to\n")</span><br><span> {</span><br><span>   osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);</span><br><span>       return CMD_SUCCESS;</span><br><span>diff --git a/src/osmo-mgw/mgw_main.c b/src/osmo-mgw/mgw_main.c</span><br><span>index 7f4df2e..37357a0 100644</span><br><span>--- a/src/osmo-mgw/mgw_main.c</span><br><span>+++ b/src/osmo-mgw/mgw_main.c</span><br><span>@@ -179,7 +179,7 @@</span><br><span> </span><br><span> static int read_call_agent(struct osmo_fd *fd, unsigned int what)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct sockaddr_in addr;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_sockaddr addr;</span><br><span>   socklen_t slen = sizeof(addr);</span><br><span>       struct msgb *msg;</span><br><span>    struct msgb *resp;</span><br><span>@@ -205,7 +205,7 @@</span><br><span>     msgb_reset(msg);</span><br><span> </span><br><span>         if (resp) {</span><br><span style="color: hsl(0, 100%, 40%);">-             sendto(cfg->gw_fd.bfd.fd, resp->l2h, msgb_l2len(resp), 0, (struct sockaddr *) &addr, sizeof(addr));</span><br><span style="color: hsl(120, 100%, 40%);">+         sendto(cfg->gw_fd.bfd.fd, resp->l2h, msgb_l2len(resp), 0, &addr.u.sa, sizeof(addr));</span><br><span>               msgb_free(resp);</span><br><span>     }</span><br><span> </span><br><span>@@ -345,7 +345,7 @@</span><br><span>  if (cfg->call_agent_addr)</span><br><span>                 flags |= OSMO_SOCK_F_CONNECT;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       rc = osmo_sock_init2_ofd(&cfg->gw_fd.bfd, AF_INET, SOCK_DGRAM, IPPROTO_UDP,</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = osmo_sock_init2_ofd(&cfg->gw_fd.bfd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,</span><br><span>                                 cfg->source_addr, cfg->source_port,</span><br><span>                            cfg->call_agent_addr, cfg->call_agent_addr ? 2727 : 0, flags);</span><br><span>         if (rc < 0) {</span><br><span>diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c</span><br><span>index c5b6d17..620b0d1 100644</span><br><span>--- a/tests/mgcp/mgcp_test.c</span><br><span>+++ b/tests/mgcp/mgcp_test.c</span><br><span>@@ -34,6 +34,7 @@</span><br><span> #include <osmocom/core/application.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span> #include <string.h></span><br><span> #include <limits.h></span><br><span> #include <dlfcn.h></span><br><span>@@ -1262,7 +1263,7 @@</span><br><span> void mgcp_patch_and_count(struct mgcp_endpoint *endp,</span><br><span>                     struct mgcp_rtp_state *state,</span><br><span>                        struct mgcp_rtp_end *rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct sockaddr_in *addr, struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+                          struct osmo_sockaddr *addr, struct msgb *msg);</span><br><span> </span><br><span> static void test_packet_error_detection(int patch_ssrc, int patch_ts)</span><br><span> {</span><br><span>@@ -1274,7 +1275,7 @@</span><br><span>   struct mgcp_config cfg = {0};</span><br><span>        struct mgcp_rtp_state state;</span><br><span>         struct mgcp_rtp_end *rtp;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct sockaddr_in addr = { 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_sockaddr addr = { 0 };</span><br><span>   uint32_t last_ssrc = 0;</span><br><span>      uint32_t last_timestamp = 0;</span><br><span>         uint32_t last_seqno = 0;</span><br><span>@@ -1486,7 +1487,8 @@</span><br><span>     OSMO_ASSERT(conn->end.rtp_port == htons(16434));</span><br><span>  memset(&addr, 0, sizeof(addr));</span><br><span>  inet_aton("8.8.8.8", &addr);</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_ASSERT(conn->end.addr.s_addr == addr.s_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(conn->end.addr.u.sa.sa_family == AF_INET);</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(conn->end.addr.u.sin.sin_addr.s_addr == addr.s_addr);</span><br><span> </span><br><span>     /* Check what happens without that flag */</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-mgw/+/19969">change 19969</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-mgw/+/19969"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-mgw </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I504ca776d88fd852bbaef07060c125980db3fdd7 </div>
<div style="display:none"> Gerrit-Change-Number: 19969 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>