int uv__udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int addrlen, unsigned int flags) { int err; int yes; int fd; /* Check for bad flags. */ if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR)) return -EINVAL; /* Cannot set IPv6-only mode on non-IPv6 socket. */ if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) return -EINVAL; fd = handle->io_watcher.fd; if (fd == -1) { err = uv__socket(addr->sa_family, SOCK_DGRAM, 0); if (err < 0) return err; fd = err; handle->io_watcher.fd = fd; } if (flags & UV_UDP_REUSEADDR) { err = uv__set_reuse(fd); if (err) goto out; } if (flags & UV_UDP_IPV6ONLY) { #ifdef IPV6_V6ONLY yes = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) { err = -errno; goto out; } #else err = -ENOTSUP; goto out; #endif } if (bind(fd, addr, addrlen)) { err = -errno; goto out; } if (addr->sa_family == AF_INET6) handle->flags |= UV_HANDLE_IPV6; return 0; out: uv__close(handle->io_watcher.fd); handle->io_watcher.fd = -1; return err; }
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { int err; /* Check for already active socket. */ if (handle->io_watcher.fd != -1) return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */ err = uv__set_reuse(sock); if (err) return err; handle->io_watcher.fd = sock; return 0; }
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { int err; /* Check for already active socket. */ if (handle->io_watcher.fd != -1) return -EBUSY; err = uv__nonblock(sock, 1); if (err) return err; err = uv__set_reuse(sock); if (err) return err; handle->io_watcher.fd = sock; return 0; }