summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryasuoka <yasuoka@openbsd.org>2015-10-27 04:27:01 +0000
committeryasuoka <yasuoka@openbsd.org>2015-10-27 04:27:01 +0000
commit51da3916b4f1243b82c8dfb6992895b17755706e (patch)
tree856454b14c3b41a13582db4ba2a1657ad529fdbc
parentFix radiusd module to set O_NONBLOCK properly. (diff)
downloadwireguard-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.c16
-rw-r--r--usr.sbin/radiusd/radiusd_radius.c19
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)));