summaryrefslogtreecommitdiffstats
path: root/lib/socket.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-07-10 12:58:51 (GMT)
committerThomas Haller <thaller@redhat.com>2015-08-14 14:04:15 (GMT)
commit96e1e5bdc2e803700055395cc3c428fa2525d1ca (patch)
tree111aa8b0c81418a8c8c6f8dfd4ea49cbe24f46ca /lib/socket.c
parentf78c3e82398a505ccf7e297b4021f23559ad8977 (diff)
downloadlibnl-96e1e5bdc2e803700055395cc3c428fa2525d1ca.zip
libnl-96e1e5bdc2e803700055395cc3c428fa2525d1ca.tar.gz
libnl-96e1e5bdc2e803700055395cc3c428fa2525d1ca.tar.bz2
socket: add fallback for nl_connect() by trying to bind to unspecified local port
libnl allows the user to explicitly set the local port before connecting the socket. A more convenient way is to leave the local port unspecified and let libnl generate a port id. As it is, generate_local_port() would try at most 1024 ports, that means if a user tries to connect more sockets, the automatism will fail. Kernel also supports choosing the local port itself (via netlink_autobind()). So, this could be fixed by always leaving the port unspecified and let kernel decide on the port. For that we could entirely drop generate_local_port(). There are however problems with that: - it is unclear why generate_local_port() was even introduced in the first place instead of always relying kernel. This code already appeared in libnl-1, so maybe there was a good reason for it or it is necessary on some kernel versions. - The deprecated libnl-1 library also uses a form of generate_local_port(). Its first guess would always be getpid(), but the problem is that it would not retry on EADDRINUSE. Currently libnl-3 generates ports in a different sequence and will not generate a conflicting port (until it already exhausted 1016 other ports). Hence, currently if your application uses libnl1 and libnl3 together, the automatism might just work without conflicts (commit 1f734a8f892abcd3f81637df4a089155aca1b66a). Accidently, kernel/netlink_autobind() also first tries the process id as port. That means, if we change libnl-3 to leave the decision to kernel, and - the application connects sockets both via libnl-1 and libnl-3 - and the libnl-3 socket happens to connect first then the libnl-1 socket would fail to connect without retrying another port. - Removing generate_local_port() entirely changes behavior in the following case: sk = nl_socket_alloc(); /* accessing local port before connecting the socket used to * freeze the local port to the generated value. */ port = nl_socket_get_local_port(sk); nl_connect(sk, NETLINK_...); Maybe the issues are minor and it would simplify the code just to get rid of the cruft. But instead fix the issue without changing behavior. Just keep trying with generate_local_port() first, before fallback to kernel. Reported-by: Julien Courtat <julien.courtat@6wind.com> Signed-off-by: Thomas Haller <thaller@redhat.com> http://lists.infradead.org/pipermail/libnl/2015-June/001889.html
Diffstat (limited to 'lib/socket.c')
-rw-r--r--lib/socket.c3
1 files changed, 0 insertions, 3 deletions
diff --git a/lib/socket.c b/lib/socket.c
index a1e0873..eef07f0 100644
--- a/lib/socket.c
+++ b/lib/socket.c
@@ -115,9 +115,6 @@ static uint32_t generate_local_port(void)
}
nl_write_unlock(&port_map_lock);
-
- /* Out of sockets in our own PID namespace, what to do? FIXME */
- NL_DBG(1, "Warning: Ran out of unique local port namespace\n");
return 0;
}