Andrei G has uploaded this change for review.

View Change

core/socket: local_ip: connect to discard port

osmo_sock_local_ip() finds the source address for a remote by connecting a
dummy UDP socket to that remote and reading the local side back with
getsockname(). It connects to port 0. Linux accepts that and returns the
source address. Darwin rejects it with EADDRNOTAVAIL (errno 49), so the
function returns -EINVAL for every remote. The BSDs behave like Darwin
here.

Two consumers break on Darwin as a result. libosmo-mgcp-client cannot
determine its local address at mgcp_client.c:1347 and fails to build any
MGCP message carrying SDP ("Could not determine local IP-Address!"); the
mgcp_client test then dereferences the message it did not get. In osmo-mgw,
mgcp_network.c:137 uses the same call to pick the local RTP address when
none is configured.

No packet is ever sent on the dummy socket, so the remote port has no
effect on the answer: the socket is connected, read with getsockname() and
closed. Use 9 (discard, IANA reserved), which every kernel accepts.
Behaviour on Linux is unchanged.

Change-Id: I597874d5b2a81dd34c6a2b274fcf8d9bfc14c301
Signed-off-by: Andrei Gosman <andrei.gosman@gmail.com>
---
M src/core/socket.c
1 file changed, 4 insertions(+), 2 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/73/43573/1
diff --git a/src/core/socket.c b/src/core/socket.c
index 3a2d7b7..cf737fe 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2466,8 +2466,10 @@

/* Connect a dummy socket to trick the kernel into determining the
* ip-address of the interface that would be used if we would send
- * out an actual packet */
- sfd = osmo_sock_init2(family, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, remote_ip, 0, OSMO_SOCK_F_CONNECT);
+ * out an actual packet. No packet is sent, so the remote port does
+ * not matter, but it must not be 0: Linux accepts a UDP connect() to
+ * port 0, while Darwin and the BSDs reject it with EADDRNOTAVAIL. */
+ sfd = osmo_sock_init2(family, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, remote_ip, 9, OSMO_SOCK_F_CONNECT);
if (sfd < 0)
return -EINVAL;


To view, visit change 43573. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I597874d5b2a81dd34c6a2b274fcf8d9bfc14c301
Gerrit-Change-Number: 43573
Gerrit-PatchSet: 1
Gerrit-Owner: Andrei G <andrei.gosman@gmail.com>