summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-08-24 15:57:16 (GMT)
committerThomas Haller <thaller@redhat.com>2015-08-24 16:01:42 (GMT)
commiteaa75b7c7d3e6a4df1a2e7591ae295acfae3f73e (patch)
treed51183750257a529143d6ef89d2fd55641f6e56c
parentfa380b409a02fe17b2d5cfc9074a8913523dbb68 (diff)
downloadlibnl-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.h2
-rw-r--r--lib/nl.c4
-rw-r--r--lib/socket.c7
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);
diff --git a/lib/nl.c b/lib/nl.c
index 737ebaa..c93b6a5 100644
--- a/lib/nl.c
+++ b/lib/nl.c
@@ -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