summaryrefslogtreecommitdiff
path: root/lib/nl.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-03-05 10:50:04 +0100
committerThomas Haller <thaller@redhat.com>2015-03-05 11:26:22 +0100
commit9614acf4c4354892b5b734cace4778acfc019999 (patch)
treea5f951654c089a097be94c9ae5f91ed0d6b03eac /lib/nl.c
parent15824e42730980132a9e52d0c9d6929808e5ae78 (diff)
downloadlibnl-9614acf4c4354892b5b734cace4778acfc019999.tar.gz
lib/nl: preserve s_local if nl_connect() fails
s_local.nl_pid is used to track the generated port unless NL_OWN_PORT is set. Ensure that getsockname() doesn't overwrite the value and possibly reset the local port manually to release the generated port. Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'lib/nl.c')
-rw-r--r--lib/nl.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/nl.c b/lib/nl.c
index bb11d2c7..8e4c4552 100644
--- a/lib/nl.c
+++ b/lib/nl.c
@@ -98,6 +98,7 @@ int nl_connect(struct nl_sock *sk, int protocol)
int err, flags = 0;
int errsv;
socklen_t addrlen;
+ struct sockaddr_nl local = { 0 };
char buf[64];
#ifdef SOCK_CLOEXEC
@@ -163,8 +164,8 @@ int nl_connect(struct nl_sock *sk, int protocol)
}
}
- addrlen = sizeof(sk->s_local);
- err = getsockname(sk->s_fd, (struct sockaddr *) &sk->s_local,
+ addrlen = sizeof(local);
+ err = getsockname(sk->s_fd, (struct sockaddr *) &local,
&addrlen);
if (err < 0) {
NL_DBG(4, "nl_connect(%p): getsockname() failed with %d (%s)\n",
@@ -173,24 +174,31 @@ int nl_connect(struct nl_sock *sk, int protocol)
goto errout;
}
- if (addrlen != sizeof(sk->s_local)) {
+ if (addrlen != sizeof(local)) {
err = -NLE_NOADDR;
goto errout;
}
- if (sk->s_local.nl_family != AF_NETLINK) {
+ if (local.nl_family != AF_NETLINK) {
err = -NLE_AF_NOSUPPORT;
goto errout;
}
+ if (sk->s_local.nl_pid != local.nl_pid) {
+ /* strange, the port id is not as expected. Set the local
+ * port id to release a possibly generated port and un-own
+ * it. */
+ nl_socket_set_local_port (sk, local.nl_pid);
+ }
+ sk->s_local = local;
sk->s_proto = protocol;
return 0;
errout:
- if (sk->s_fd != -1) {
- close(sk->s_fd);
- sk->s_fd = -1;
- }
+ if (sk->s_fd != -1) {
+ close(sk->s_fd);
+ sk->s_fd = -1;
+ }
return err;
}