summaryrefslogtreecommitdiffstats
path: root/lib/socket.c
Commit message (Collapse)AuthorAgeFilesLines
* socket: fix assertion in nl_connect() when all ports are already in useThomas Haller2015-08-241-2/+5
| | | | | | | | | | | | | 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
* lib/socket: in nl_socket_set_fd() always reset the local portThomas Haller2015-08-141-6/+1
| | | | | | | | | Even if the local port of @sk already equals to the port of the file descriptor @fd, we want to release a possibly generated port and set NL_OWN_PORT. Fixes: 2d61e890379888907a93ddd0a04187b130629f6f Signed-off-by: Thomas Haller <thaller@redhat.com>
* socket: add fallback for nl_connect() by trying to bind to unspecified local ↵Thomas Haller2015-08-141-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* socket: clear port when unable to generate local portThomas Haller2015-08-141-8/+22
| | | | | | | | | | | | | | | | | | | | When running out of local ports, _nl_socket_generate_local_port_no_release() would leave the socket with port UINT32_MAX. That means if nl_connect() fails due to out-of-ports, it would leave the port id assigned to an invalid port and the socket instance was not re-usable until the user called nl_socket_set_local_port(). Fix that by resetting the local port to zero. Thereby, also change generate_local_port() to return zero when running out of ports. zero is a more natural value for ~no port found~. It also matches the port that _nl_socket_generate_local_port_no_release() uses when failing to generate a port. Also ensure that zero cannot be returned as valid port by generate_local_port(). Arguably, that would only be possible if (getpid() & 0x3FFFFF) returns zero. Just be extra cautious. Signed-off-by: Thomas Haller <thaller@redhat.com>
* lib/socket: detect protocol in nl_socket_set_fd()Thomas Haller2015-03-061-9/+63
| | | | | | | | | | | | | | | With support for socket option SO_PROTOCOL we don't need the protocol argument to nl_socket_set_fd(). Maybe we should drop the protocol argument and just not support nl_socket_set_fd() on older systems. But instead keep the argument and allow passing -1 to autodetect it. If the user sets a protocol option, we check via getsockopt() that the value is correct and error out otherwise. On older kernels, the user must set the value. Otherwise nl_socket_set_fd() will fail. Signed-off-by: Thomas Haller <thaller@redhat.com>
* lib/socket: add nl_socket_set_fd() functionThomas Haller2015-03-051-0/+62
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is based on the patch by sagil@infinidat.com, but heavily modified. Add a function nl_socket_set_fd(), I renamed it from nl_connect_fd(). Now nl_connect() and nl_socket_set_fd() are implemented independently as they share little code. But they have similar functionality: to initialize a libnl socket and set it's file descriptor. A user who wants libnl to setup the socket can continue to use nl_connect(). A user with special requirements should setup the socket entirely. That includes calling socket() (with or without SOCK_CLOEXEC), bind(), setting buffer size. For the same reason I dropped nl_create_fd(). It didn't do much more then calling socket() -- which the user can do directly. https://github.com/thom311/libnl/pull/68 Signed-off-by: Thomas Haller <thaller@redhat.com>
| * add socket nl_connect_fd() & nl_create_fd()Sagi Lowenhardt2015-03-051-0/+6
|/ | | | | | | | | | | | - Added option to create socket (fd) without bind. It is now possible to forward the socket fd to another child process... ...later use nl_connect_fd() to connect to socket from the child process. - Added option to disable CLOEXEC even if defined (in socket.h) 'nl_socket_enable_cloexec' & 'nl_socket_disable_cloexec' No change to current default behavior. Signed-off-by: Sagi Lowenhardt <sagil@infinidat.com>
* lib/socket: remove NL_SOCK_BUFSIZE_SET socket flagThomas Haller2015-03-051-2/+0
| | | | | | | | | | | | | | | | The flag was not actually used. NL_SOCK_BUFSIZE_SET was only set by nl_socket_set_buffer_size(). Note that you can only call nl_socket_set_buffer_size() on a socket that is already connected via nl_connect(). On first call, nl_connect() would always see NL_SOCK_BUFSIZE_SET unset, and call nl_socket_set_buffer_size(). Since the flag was never unset, when trying to connect a socket a second time, we would not set the buffer size again. Which was a bug. Signed-off-by: Thomas Haller <thaller@redhat.com>
* lib: log errors from platformLubomir Rintel2015-02-171-5/+35
| | | | | | | | | | | | nl_syserr2nlerr() reduces a lot of platform errors to NLE_FAILURE -- "Unspecific failure" which makes it somehow hard to track down the real reason behind a failure. Logging them with level of 4 makes it a little less painful. https://github.com/thom311/libnl/pull/65 Signed-off-by: Thomas Haller <thaller@redhat.com>
* socket: Be correct, time(2) takes a pointer, not an integerThomas Graf2014-07-271-1/+1
| | | | | Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: Thomas Haller <thaller@redhat.com>
* lib/socket: randomize the generated local portThomas Haller2014-05-061-3/+26
| | | | | | | | | | | | | | Instead of always trying the same order of ports when looking for an unused port, randomize the order (naively). As libnl-1 uses the same function, it is likely that two applications that are using both libraries generate the same ports. By chosing a different order how to select the local port, the chances are smaller for this to happen (however, it cannot avoid it entirely. The user and/or libnl3 still has to cope with the situation, that somebody else might already use the port). Signed-off-by: Thomas Haller <thaller@redhat.com>
* lib/socket: retry generate local port in nl_connect on ADDRINUSEThomas Haller2014-05-061-21/+89
| | | | | | | | | | | | | | | | | | | | | It can easily happen that the generated local netlink port is alrady in use. In that case bind will fail with ADDRINUSE. Users of libnl3 could workaround this, by managing the local ports themselves, but sometimes these users are libraries too and they also don't know which ports might be used by other components. This patch changes that nl_socket_alloc() no longer initilizes the local port id immediately. Instead it will be initialized when the user calls nl_socket_get_local_port() the first time and thereby shows interest in the value. If bind() fails with ADDRINUSE, check if the user ever cared about the local port, i.e. whether the local port is still unset. If it is still unset, assume that libnl should choose a suitable port and retry until an unused port can be found. Signed-off-by: Thomas Haller <thaller@redhat.com>
* lib/socket: don't fail if no more local ports can be assigned in nl_socket_allocThomas Haller2014-05-061-4/+0
| | | | | | | | | | | | | | | By failing inside of nl_socket_alloc(), the user can not even work around when running out of local ports. This patch changes that if there are no more local ports, we set the port to UINT32_MAX. This is a consistent behavior to calling nl_socket_set_local_port(sk, 0). In general, since nl_socket_set_local_port() does not restict the generated ports in any way we cannot assume to have a valid port. So the check in the constructor was harmful and users who ever encountered it (because they created 1024 libnl3 sockets) could not even work around it. Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: Thomas Haller <thaller@redhat.com>
* lib/socket: use proper typed constant UINT32_MAX for uint32_t typed portThomas Haller2014-05-061-4/+4
| | | | | | | This was a bug on architectures with native int type less then 32 bit. Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: Thomas Haller <thaller@redhat.com>
* socket: Warn via debug message if local port namespace is exhaustedThomas Graf2013-06-281-0/+1
| | | | Signed-off-by: Thomas Graf <tgraf@suug.ch>
* Fix leak of cb if nl_socket_alloc_cb() failed to allocate socketКоренберг Марк (дома)2013-04-271-4/+13
| | | | | - each *_get() should have corresponding *_put(). That rule was broken in nl_socket_alloc() - Also, check if cb is NULL in nl_socket_set_cb (calls BUG())
* Move private header files to <netlink-private/*>Thomas Graf2013-01-241-1/+1
| | | | | | | This clarifies the seperation between public and private header files. Signed-off-by: Thomas Graf <tgraf@suug.ch>
* lock abstraction layerThomas Graf2012-11-151-22/+6
| | | | | | Hide pthread availability and enablement behind internal API Signed-off-by: Thomas Graf <tgraf@suug.ch>
* socket: document nl_socket_get_fd()Thomas Graf2012-11-061-0/+9
|
* Add missing va_end() callsMichele Baldessari2012-10-291-4/+12
| | | | Add missing va_end() calls on all error paths
* Add configure option to disable pthreads supportRich Fought2012-10-261-0/+16
|
* nl: Provide API to specify the default buffer size when receiving netlink ↵Thomas Graf2012-10-091-0/+30
| | | | | | | | | | | | messages New functions: nl_socket_set_msg_buf_size(sk, size) nl_socket_get_msg_buf_size(sk) Default remains getpagesize() Signed-off-by: Thomas Graf <tgraf@redhat.com>
* doc: documentation restructuringThomas Graf2012-05-101-2/+14
| | | | | | | | | | - changes the modules hierarchy to better represent the set of libaries - list the header file that needs to be included - remove examples/doc from api ref that is included in the guide - add references to the guide - fix doxygen api linking for version 1.8.0 - readd doxygen mainpage to config file - fix a couple of doxygen doc bugs
* socket: fix two typosJiri Pirko2011-08-311-2/+2
| | | | Signed-off-by: Jiri Pirko <jpirko@redhat.com>
* socket: introduce nl_socket_modify_err_cbJiri Pirko2011-08-311-0/+15
| | | | | | | This function does the same as nl_socket_modify_cb except for error callback Signed-off-by: Jiri Pirko <jpirko@redhat.com>
* Local port leak on nl_socket_alloc/nl_socket_set_local_port(, 0)Andrew Rybchenko2011-08-301-1/+8
| | | | | | | | | | | | | | | | | | I've found a bug in the following scenario (fragment of code): while (1) { struct nl_sock *sk = nl_socket_alloc(); if (sk == NULL) { fprintf(stderr, "Failed to allocate nl socket\n"); break; } nl_socket_set_local_port(sk, 0); nl_socket_free(sk); } The problem is that nl_socket_set_local_port(, 0) does not release local port if it is allocated before.
* make port map thread safeThomas Graf2011-08-111-2/+14
| | | | | | | | This patch has been in Fedora and RHEL for a while. It adds a mutex to protect the port map from concurrent thread accesses. Original patch from Stefan Berger <stefanb@us.ibm.com>. Modified to use configure.in to check for libpthread
* socket: constify interfaceThomas Graf2010-11-181-6/+6
|
* Generic Netlink multicast groups supportdima2010-10-141-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | I have a patch against commit d378220c96c3c8b6f27dca33e7d8ba03318f9c2d extending libnl with a facility to receive generic netlink messages sent to multicast groups. Essentially it add one new function genl_ctrl_resolve_grp which prototype looks like this int genl_ctrl_resolve_grp(struct nl_sock *sk, const char *family_name, const char *grp_name) It resolves the family name and the group name to group id. Then the returned id can be used in nl_socket_add_membership to subscribe to multicast messages. Besides that it adds two more functions uint32_t nl_socket_get_peer_groups(struct nl_sock *sk) void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups) allowing to modify the socket peer groups field. So it's possible to multicast messages from the user space using the legacy interface. Looks like there is no way (or I was not able to find one?) to modify the netlink socket destination group from the user space, when the group id is greater then 32.
* release_local_port: properly compute the bitmap positionInaky Perez-Gonzalez2009-05-041-1/+1
| | | | | | | | Current calculation is always off, not reflecting the right position in the bitmap, which results in failures due to conflicts (detected at the kernel level) when trying to open a new handle. Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
* restructure module documentation orderThomas Graf2008-12-101-1/+1
| | | | split hiearchy into one top level module per library
* Consistent naming of socket functionsThomas Graf2008-12-101-3/+14
|
* Documentation updateThomas Graf2008-12-031-71/+0
|
* Allow to pass multiple group values to membership functionsHolger Eitzenberger2008-12-031-16/+42
| | | | | | | | | | | | | | | Instead of calling the membership functions several times it is helpfull to extend the API and make the single group functions a special case. The value 0 (NFNLGRP_NONE) terminates this list. Example use: nl_socket_add_memberships(sock, group_1, group_2, 0); nl_socket_drop_memberships(sock, group_1, group_2, 0); Signed-off-by: Holger Eitzenberger <holger@eitzenberger.org>
* Add socket flag NL_NO_AUTO_ACK to allow disabling auto ACKSThomas Graf2008-10-201-0/+27
|
* Rename struct nl_handle to struct nl_sockThomas Graf2008-05-151-118/+115
| | | | | | | | The idea of a common handle is long revised and only misleading, nl_handle really represents a socket with some additional action handlers assigned to it. Alias for nl_handle is kept for backwards compatibility.
* Thread-safe error handlingThomas Graf2008-05-141-23/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In order for the interface to become more thread safe, the error handling was revised to no longer depend on a static errno and error string buffer. This patch converts all error paths to return a libnl specific error code which can be translated to a error message using nl_geterror(int error). The functions nl_error() and nl_get_errno() are therefore obsolete. This change required various sets of function prototypes to be changed in order to return an error code, the most prominent are: struct nl_cache *foo_alloc_cache(...); changed to: int foo_alloc_cache(..., struct nl_cache **); struct nl_msg *foo_build_request(...); changed to: int foo_build_request(..., struct nl_msg **); struct foo *foo_parse(...); changed to: int foo_parse(..., struct foo **); This pretty much only leaves trivial allocation functions to still return a pointer object which can still return NULL to signal out of memory. This change is a serious API and ABI breaker, sorry!
* Support defining the default callback handler with an environment variableThomas Graf2007-12-181-1/+21
|
* Fix memory leak when parsing netlink messages into cachesThomas Graf2007-12-171-1/+1
| | | | The reference created by the parsers was never given back.
* Fix creation and destruction of socketsThomas Graf2007-12-171-3/+34
| | | | | | | | Fixes an off-by-one when releasing local ports. Fixes nl_connect() to properly close the socket upon failure. Return EBADFD if operations are performed on unconnected sockets where appropriate. Makes nl_handle_alloc() return an error if all local ports are used up.
* Initial importThomas Graf2007-09-141-0/+548