diff options
author | 2015-10-27 04:27:01 +0000 | |
---|---|---|
committer | 2015-10-27 04:27:01 +0000 | |
commit | 51da3916b4f1243b82c8dfb6992895b17755706e (patch) | |
tree | 856454b14c3b41a13582db4ba2a1657ad529fdbc | |
parent | Fix radiusd module to set O_NONBLOCK properly. (diff) | |
download | wireguard-openbsd-51da3916b4f1243b82c8dfb6992895b17755706e.tar.xz wireguard-openbsd-51da3916b4f1243b82c8dfb6992895b17755706e.zip |
Set O_NONBLOCK for UDP sockets not to block on recv(). Actually
block had happened if an error of the socket is handled by send().
diff from Yuuichi Someya.
-rw-r--r-- | usr.sbin/radiusd/radiusd.c | 16 | ||||
-rw-r--r-- | usr.sbin/radiusd/radiusd_radius.c | 19 |
2 files changed, 31 insertions, 4 deletions
diff --git a/usr.sbin/radiusd/radiusd.c b/usr.sbin/radiusd/radiusd.c index 0c1a2ff62e5..6a85c0b8131 100644 --- a/usr.sbin/radiusd/radiusd.c +++ b/usr.sbin/radiusd/radiusd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radiusd.c,v 1.10 2015/10/27 04:18:36 yasuoka Exp $ */ +/* $OpenBSD: radiusd.c,v 1.11 2015/10/27 04:27:01 yasuoka Exp $ */ /* * Copyright (c) 2013 Internet Initiative Japan Inc. @@ -197,7 +197,7 @@ radiusd_start(struct radiusd *radiusd) { struct radiusd_listen *l; struct radiusd_module *module; - int s; + int s, ival; char hbuf[NI_MAXHOST]; TAILQ_FOREACH(l, &radiusd->listen, next) { @@ -220,6 +220,16 @@ radiusd_start(struct radiusd *radiusd) close(s); goto on_error; } + if ((ival = fcntl(s, F_GETFL, 0)) < 0) { + log_warn("fcntl(F_GETFL) failed at %s()", __func__); + close(s); + goto on_error; + } + if (fcntl(s, F_SETFL, ival | O_NONBLOCK) < 0) { + log_warn("fcntl(F_SETFL,O_NONBLOCK) failed at %s()", __func__); + close(s); + goto on_error; + } if (l->addr.ipv4.sin_family == AF_INET) log_info("Start listening on %s:%d/udp", hbuf, (int)ntohs(l->addr.ipv4.sin_port)); @@ -368,6 +378,8 @@ radiusd_listen_on_event(int fd, short evmask, void *ctx) peersz = sizeof(peer); if ((sz = recvfrom(listn->sock, buf, sizeof(buf), 0, (struct sockaddr *)&peer, &peersz)) < 0) { + if (errno == EAGAIN) + return; log_warn("%s: recvfrom() failed", __func__); goto on_error; } diff --git a/usr.sbin/radiusd/radiusd_radius.c b/usr.sbin/radiusd/radiusd_radius.c index 88590ff08a3..80153846389 100644 --- a/usr.sbin/radiusd/radiusd_radius.c +++ b/usr.sbin/radiusd/radiusd_radius.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radiusd_radius.c,v 1.8 2015/10/19 22:07:37 yasuoka Exp $ */ +/* $OpenBSD: radiusd_radius.c,v 1.9 2015/10/27 04:27:01 yasuoka Exp $ */ /* * Copyright (c) 2013 Internet Initiative Japan Inc. @@ -22,7 +22,9 @@ #include <netinet/in.h> #include <err.h> +#include <errno.h> #include <event.h> +#include <fcntl.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -326,6 +328,7 @@ on_fail: static int radius_server_start(struct radius_server *server) { + int ival; socklen_t locallen; char buf0[NI_MAXHOST + NI_MAXSERV + 32]; char buf1[NI_MAXHOST + NI_MAXSERV + 32]; @@ -343,6 +346,16 @@ radius_server_start(struct radius_server *server) server->addr.sin4.sin_len, buf1, sizeof(buf1))); goto on_error; } + if ((ival = fcntl(server->sock, F_GETFL, 0)) < 0) { + module_radius_log(server->module, LOG_WARNING, + "%s: fcntl(F_GETFL) failed", __func__); + goto on_error; + } + if (fcntl(server->sock, F_SETFL, ival | O_NONBLOCK) < 0) { + module_radius_log(server->module, LOG_WARNING, + "%s: fcntl(F_SETFL) failed", __func__); + goto on_error; + } locallen = sizeof(server->local); if (getsockname(server->sock, (struct sockaddr *)&server->local, &locallen) != 0) { @@ -394,7 +407,9 @@ radius_server_on_event(int fd, short evmask, void *ctx) struct sockaddr *peer; peer = (struct sockaddr *)&server->addr; - if ((sz = recv(server->sock, pkt, sizeof(pkt), 0)) <= 0) { + if ((sz = recv(server->sock, pkt, sizeof(pkt), 0)) == -1) { + if (errno == EAGAIN) + return; module_radius_log(server->module, LOG_WARNING, "server=%s recv() failed: %m", addrport_tostring(peer, peer->sa_len, buf, sizeof(buf))); |