Project

General

Profile

Actions

Bug #5499

open

octoi client binds to specific IP even if 0.0.0.0 is specified

Added by laforge almost 2 years ago. Updated 9 months ago.

Status:
New
Priority:
Low
Assignee:
-
Category:
octoi
Target version:
-
Start date:
03/28/2022
Due date:
% Done:

0%

Spec Reference:

Description

Even if the config file specifies 0.0.0.0 as the local address for the client, the socket apparently still gets bound to a specifid address at the time of the bind/connect.

udp        0      0 192.168.2.6:3333        90.187.70.153:10010     VERBUNDEN

This means that the OCTOI connection breaks as soon as the client gets a different IP address (e.g. by DHCP).

The odd part is that this doesn't happen on the server side. My socket looks like this:

udp        0      0 0.0.0.0:10010           0.0.0.0:*                          

Actions #1

Updated by laforge almost 2 years ago

  • Category set to octoi
Actions #2

Updated by laforge over 1 year ago

strangely, looking at the various IPs reported by stats.retronetworking.org, I have the feeling that osmo-e1d octoi-client mode does work correctly for users behind dynamic IPs.

Any feedback from other users?

Actions #3

Updated by manawyrm over 1 year ago

Yup. This problem doesn't occur when the external dynamic IP (after NAT) changes. I've seen that happening multiple times without issue.

There is a problem however, when the internal IPv4 address (192.168.2.6) in this case changes. Easy fix: Don't do that/use a static IP.

I think the main problem here is the error handling: When this bug occurs, there's a send error for each packet, but osmo-e1d stays alive. Just exit/aborting the program would be OK here and result in better (overall) uptime.

Actions #4

Updated by roox over 1 year ago

strangely, looking at the various IPs reported by stats.retronetworking.org, I have the feeling that osmo-e1d octoi-client mode does work correctly for users behind dynamic IPs.

Any feedback from other users?

I haven't seen this issue with osmo-e1d in client mode.
[T-DSL]<->[Fritzbox with NAT]<->[Linux-router]<->[Linux-box with icE1usb/osmo-e1d]
The frequent dis-/reconnects since some time from my side are caused by other issues in my setup at the moment.

Actions #5

Updated by laforge 9 months ago

So octoi_sock_create_client() just calls the normal libosmocore socket API functions:

                rc = osmo_sock_init_osa_ofd(&sock->ofd, SOCK_DGRAM, IPPROTO_UDP,
                                            NULL, (struct osmo_sockaddr *) &sa_remote,
                                            OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_NONBLOCK);

This calls down into osmo_sock_init_osa() which in absence of OSMO_SOCK_F_BIND does not perform a local bind of the socket.

The "problem" might be related to the fact that local-bind 0.0.0.0 10013 actually makes the code go through the _F_BIND case and hence call bind() in order to bind to the port number, which inadvertently might also bind the local IP?

Actions #6

Updated by laforge 9 months ago

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).

Actions #7

Updated by laforge 9 months ago

  • Assignee deleted (laforge)
Actions

Also available in: Atom PDF

Add picture from clipboard (Maximum size: 48.8 MB)