diff options
| -rw-r--r-- | conf.c | 7 | ||||
| -rw-r--r-- | repair.c | 4 | ||||
| -rw-r--r-- | tap.c | 5 |
3 files changed, 16 insertions, 0 deletions
@@ -2084,6 +2084,13 @@ static void conf_accept(struct ctx *c) int fd, rc; retry: + /* Currently we perform the configuration transaction more-or-less + * synchronously, so we want the accepted socket to be blocking. + * + * FIXME: We should make the configuration update asynchronous, like + * most of our operation, so a misbehaving configuration client can't + * block the main forwarding loop. + */ fd = accept4(c->fd_control_listen, NULL, NULL, SOCK_CLOEXEC); if (fd < 0) { if (errno != EAGAIN) @@ -99,6 +99,10 @@ int repair_listen_handler(struct ctx *c, uint32_t events) return EEXIST; } + /* We want the accepted socket to be blocking; we use it during + * migration which is a synchronous interruption to our normal + * non-blocking behaviour. + */ if ((c->fd_repair = accept4(c->fd_repair_listen, NULL, NULL, SOCK_CLOEXEC)) < 0) { rc = errno; @@ -1492,6 +1492,11 @@ void tap_listen_handler(struct ctx *c, uint32_t events) return; } + /* Because we generally only access the accepted socket from epoll + * events, it usually doesn't matter if it's blocking or non-blocking. + * However, in rare cases when the socket buffer fills we need (briefly, + * we hope) blocking writes (write_remainder() in send_frames_passt()). + */ c->fd_tap = accept4(c->fd_tap_listen, NULL, NULL, SOCK_CLOEXEC); if (c->fd_tap < 0) { warn_perror("Error accepting tap client"); |
