so the following snippet does what we want (socket bound to 0.0.0.0:10013):
int rc;
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
assert(fd >= 0);
struct sockaddr_in sin = {
.sin_addr = INADDR_ANY,
.sin_port = htons(10013),
};
rc = bind(fd, (struct sockaddr *) &sin, sizeof(sin));
assert(rc >= 0);
which renders:
udp 0 0 0.0.0.0:10013 0.0.0.0:*
but once we connect()
with code like this:
int rc;
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
assert(fd >= 0);
struct sockaddr_in sin = {
.sin_family = AF_INET,
.sin_addr = INADDR_ANY,
.sin_port = htons(10013),
};
rc = bind(fd, (struct sockaddr *) &sin, sizeof(sin));
assert(rc >= 0);
struct sockaddr_in remote = {
.sin_family = AF_INET,
.sin_addr = 0x04030201,
.sin_port = htons(3333),
};
rc = connect(fd, (struct sockaddr *) &remote, sizeof(remote));
assert(rc >= 0);
it becomes
udp 0 0 192.168.100.149:10013 1.2.3.4:3333 ESTABLISHED
so it seems like the connect()
forces the socket to choose a local address.
This likely means that we'd have to make sure we call connect()
on every re-connect, to make sure to consider whatever the [new?] local address might be at the time we connect. In libosmocore-api-user-language this means calling osmo_sock_init_osa()
or anything that goes through osmo_sock_init()
or osmo_sock_init2()
.
As far as I read the OCTOI code in osmo-e1d, osmo_sock_init_osa_ofd
is only called via octoi_sock_create_client
, which is only called when the vty/config file of local-bind
is parsed. The subsequent reconnect are merely at logical OCTOIP protocol level (sending E1OIP_MSGT_SERVICE_REQ over the already-connected UDP socket).