diff options
| author | Roy Marples <roy@marples.name> | 2014-02-13 12:58:58 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2014-02-13 12:58:58 +0000 |
| commit | e8c8e9b9b2967f9d56498061baec523b5238c1ce (patch) | |
| tree | c1d60ccbfe06a398538a16088102abbfe766e155 /ipv6nd.c | |
| parent | 298c01136e8c73b410f75c2dfad996487b7f414f (diff) | |
| download | dhcpcd-e8c8e9b9b2967f9d56498061baec523b5238c1ce.tar.xz | |
Work without SOCK_CLOEXEC again.
Diffstat (limited to 'ipv6nd.c')
| -rw-r--r-- | ipv6nd.c | 46 |
1 files changed, 44 insertions, 2 deletions
@@ -39,6 +39,7 @@ #endif #include <errno.h> +#include <fcntl.h> #include <stddef.h> #include <stdlib.h> #include <string.h> @@ -178,10 +179,29 @@ ipv6nd_open(struct dhcpcd_ctx *dctx) ctx = dctx->ipv6; if (ctx->nd_fd != -1) goto unspec; +#ifdef SOCK_CLOEXEC ctx->nd_fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_ICMPV6); if (ctx->nd_fd == -1) return -1; +#else + if ((ctx->nd_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1) + return -1; + if ((on = fcntl(ctx->nd_fd, F_GETFD, 0)) == -1 || + fcntl(ctx->nd_fd, F_SETFD, on | FD_CLOEXEC) == -1) + { + close(ctx->nd_fd); + ctx->nd_fd = -1; + return -1; + } + if ((on = fcntl(ctx->nd_fd, F_GETFL, 0)) == -1 || + fcntl(ctx->nd_fd, F_SETFL, on | O_NONBLOCK) == -1) + { + close(ctx->nd_fd); + ctx->nd_fd = -1; + return -1; + } +#endif on = 1; if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, @@ -210,9 +230,31 @@ unspec: ICMP6_FILTER_SETBLOCKALL(&filt); /* We send DAD requests from the unspecified address. */ - ctx->unspec_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); +#ifdef SOCK_CLOEXEC + ctx->unspec_fd = socket(AF_INET6, + SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, + IPPROTO_ICMPV6); if (ctx->unspec_fd == -1) - goto eexit; + return -1; +#else + if ((ctx->unspec_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1) + return -1; + if ((on = fcntl(ctx->unspec_fd, F_GETFD, 0)) == -1 || + fcntl(ctx->unspec_fd, F_SETFD, on | FD_CLOEXEC) == -1) + { + close(ctx->unspec_fd); + ctx->unspec_fd = -1; + return -1; + } + if ((on = fcntl(ctx->unspec_fd, F_GETFL, 0)) == -1 || + fcntl(ctx->unspec_fd, F_SETFL, on | O_NONBLOCK) == -1) + { + close(ctx->unspec_fd); + ctx->unspec_fd = -1; + return -1; + } +#endif + if (setsockopt(ctx->unspec_fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)) == -1) goto eexit; |
