diff options
author | Thomas Haller <thaller@redhat.com> | 2015-08-24 15:57:16 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-08-24 16:01:42 (GMT) |
commit | eaa75b7c7d3e6a4df1a2e7591ae295acfae3f73e (patch) | |
tree | d51183750257a529143d6ef89d2fd55641f6e56c | |
parent | fa380b409a02fe17b2d5cfc9074a8913523dbb68 (diff) | |
download | libnl-eaa75b7c7d3e6a4df1a2e7591ae295acfae3f73e.zip libnl-eaa75b7c7d3e6a4df1a2e7591ae295acfae3f73e.tar.gz libnl-eaa75b7c7d3e6a4df1a2e7591ae295acfae3f73e.tar.bz2 |
socket: fix assertion in nl_connect() when all ports are already in use
When generating a port fails a few times (because they are already in used
outside of libnl's knowledge), we would back off generating a local
port and instead let kernel decide.
There was however a bug in nl_connect() that caused an assertion:
BUG at file position socket.c:147:_nl_socket_used_ports_release_all
app: socket.c:147: _nl_socket_used_ports_release_all: Assertion `0' failed.
Fixes: 96e1e5bdc2e803700055395cc3c428fa2525d1ca
-rw-r--r-- | include/netlink-private/socket.h | 2 | ||||
-rw-r--r-- | lib/nl.c | 4 | ||||
-rw-r--r-- | lib/socket.c | 7 |
3 files changed, 8 insertions, 5 deletions
diff --git a/include/netlink-private/socket.h b/include/netlink-private/socket.h index 86a440c..9ceecfd 100644 --- a/include/netlink-private/socket.h +++ b/include/netlink-private/socket.h @@ -19,7 +19,7 @@ extern "C" { #endif int _nl_socket_is_local_port_unspecified (struct nl_sock *sk); -uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk); +uint32_t _nl_socket_set_local_port_no_release(struct nl_sock *sk, int generate_other); void _nl_socket_used_ports_release_all(const uint32_t *used_ports); void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port); @@ -137,11 +137,11 @@ int nl_connect(struct nl_sock *sk, int protocol) if (ntries++ > 5) { /* try only a few times. We hit this only if many ports are already in * use but allocated *outside* libnl/generate_local_port(). */ - nl_socket_set_local_port (sk, 0); + _nl_socket_set_local_port_no_release (sk, 0); break; } - port = _nl_socket_generate_local_port_no_release(sk); + port = _nl_socket_set_local_port_no_release(sk, 1); if (port == 0) break; diff --git a/lib/socket.c b/lib/socket.c index 55bdc96..109c416 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -333,14 +333,17 @@ int _nl_socket_is_local_port_unspecified(struct nl_sock *sk) return (sk->s_local.nl_pid == 0); } -uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk) +uint32_t _nl_socket_set_local_port_no_release(struct nl_sock *sk, int generate_other) { uint32_t port; /* reset the port to generate_local_port(), but do not release * the previously generated port. */ - port = generate_local_port(); + if (generate_other) + port = generate_local_port(); + else + port = 0; sk->s_local.nl_pid = port; if (port == 0) { /* failed to find an unsed port. Restore the socket to have an |