summaryrefslogtreecommitdiffstats
path: root/src/unix/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/unix/udp.c')
-rw-r--r--src/unix/udp.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/src/unix/udp.c b/src/unix/udp.c
index 1cd4925..c556325 100644
--- a/src/unix/udp.c
+++ b/src/unix/udp.c
@@ -307,7 +307,7 @@ int uv__udp_bind(uv_udp_t* handle,
if (flags & UV_UDP_REUSEADDR) {
err = uv__set_reuse(fd);
if (err)
- goto out;
+ return err;
}
if (flags & UV_UDP_IPV6ONLY) {
@@ -315,11 +315,11 @@ int uv__udp_bind(uv_udp_t* handle,
yes = 1;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
err = -errno;
- goto out;
+ return err;
}
#else
err = -ENOTSUP;
- goto out;
+ return err;
#endif
}
@@ -329,27 +329,25 @@ int uv__udp_bind(uv_udp_t* handle,
/* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
* socket created with AF_INET to an AF_INET6 address or vice versa. */
err = -EINVAL;
- goto out;
+ return err;
}
if (addr->sa_family == AF_INET6)
handle->flags |= UV_HANDLE_IPV6;
handle->flags |= UV_HANDLE_BOUND;
-
return 0;
-
-out:
- uv__close(handle->io_watcher.fd);
- handle->io_watcher.fd = -1;
- return err;
}
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
int domain,
unsigned int flags) {
- unsigned char taddr[sizeof(struct sockaddr_in6)];
+ union {
+ struct sockaddr_in6 in6;
+ struct sockaddr_in in;
+ struct sockaddr addr;
+ } taddr;
socklen_t addrlen;
if (handle->io_watcher.fd != -1)
@@ -358,7 +356,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
switch (domain) {
case AF_INET:
{
- struct sockaddr_in* addr = (void*)&taddr;
+ struct sockaddr_in* addr = &taddr.in;
memset(addr, 0, sizeof *addr);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = INADDR_ANY;
@@ -367,7 +365,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
}
case AF_INET6:
{
- struct sockaddr_in6* addr = (void*)&taddr;
+ struct sockaddr_in6* addr = &taddr.in6;
memset(addr, 0, sizeof *addr);
addr->sin6_family = AF_INET6;
addr->sin6_addr = in6addr_any;
@@ -379,7 +377,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
abort();
}
- return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, flags);
+ return uv__udp_bind(handle, &taddr.addr, addrlen, flags);
}
@@ -429,6 +427,13 @@ int uv__udp_send(uv_udp_send_t* req,
if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) {
uv__udp_sendmsg(handle);
+
+ /* `uv__udp_sendmsg` may not be able to do non-blocking write straight
+ * away. In such cases the `io_watcher` has to be queued for asynchronous
+ * write.
+ */
+ if (!QUEUE_EMPTY(&handle->write_queue))
+ uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
} else {
uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
}