From: yasuoka Date: Tue, 27 Oct 2015 04:27:01 +0000 (+0000) Subject: Set O_NONBLOCK for UDP sockets not to block on recv(). Actually X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=51da3916b4f1243b82c8dfb6992895b17755706e;p=openbsd 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. --- 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 #include +#include #include +#include #include #include #include @@ -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)));