summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-11-01 12:14:32 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-11-01 12:14:32 +0100
commit42e44a0b5c85b890810e398f86b7ec3a06a02d12 (patch)
treede9d7cde40efadaf0e6e912f3a41c3f515ad578d /src
parent80cbd0c9bd83fd0501b505f54ec8e29028894af5 (diff)
downloadfastd-42e44a0b5c85b890810e398f86b7ec3a06a02d12.tar
fastd-42e44a0b5c85b890810e398f86b7ec3a06a02d12.zip
Handle socket errors
Diffstat (limited to 'src')
-rw-r--r--src/fastd.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/src/fastd.c b/src/fastd.c
index a117b1e..b93ee75 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -217,7 +217,7 @@ static int bind_socket(fastd_context *ctx, const fastd_bind_address *addr, bool
if (bind(fd, (struct sockaddr*)&bind_address, af == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) {
if (warn)
- pr_warn(ctx, "bind");
+ pr_warn_errno(ctx, "bind");
goto error;
}
@@ -310,12 +310,19 @@ static void close_tuntap(fastd_context *ctx) {
free(ctx->ifname);
}
+static void close_socket(fastd_context *ctx, fastd_socket *sock) {
+ if (sock->fd >= 0) {
+ if(close(sock->fd))
+ pr_error_errno(ctx, "closing socket: close");
+
+ sock->fd = -2;
+ }
+}
+
static void close_sockets(fastd_context *ctx) {
unsigned i;
- for (i = 0; i < ctx->n_socks; i++) {
- if(close(ctx->socks[i].fd))
- pr_warn_errno(ctx, "closing IPv4 socket: close");
- }
+ for (i = 0; i < ctx->n_socks; i++)
+ close_socket(ctx, &ctx->socks[i]);
free(ctx->socks);
}
@@ -769,6 +776,15 @@ static void handle_resolv_returns(fastd_context *ctx) {
free(resolve_return.hostname);
}
+static inline void handle_socket_error(fastd_context *ctx, fastd_socket *sock) {
+ if (sock->addr->bindtodev)
+ pr_warn(ctx, "socket bind %I on `%s' lost", &sock->addr->addr, sock->addr->bindtodev);
+ else
+ pr_warn(ctx, "socket bind %I lost", &sock->addr->addr);
+
+ close_socket(ctx, sock);
+}
+
static void handle_input(fastd_context *ctx) {
struct pollfd fds[ctx->n_socks + 2];
fds[0].fd = ctx->tunfd;
@@ -803,6 +819,11 @@ static void handle_input(fastd_context *ctx) {
handle_resolv_returns(ctx);
for (i = 0; i < ctx->n_socks; i++) {
+ if (fds[i+2].revents & (POLLERR|POLLHUP|POLLNVAL)) {
+ handle_socket_error(ctx, &ctx->socks[i]);
+ continue;
+ }
+
if (fds[i+2].revents & POLLIN)
handle_socket(ctx, &ctx->socks[i]);
}
@@ -823,8 +844,9 @@ static void cleanup_peers(fastd_context *ctx) {
static void maintenance(fastd_context *ctx) {
cleanup_peers(ctx);
-
fastd_peer_eth_addr_cleanup(ctx);
+
+ bind_sockets(ctx);
}
@@ -931,7 +953,6 @@ int main(int argc, char *argv[]) {
while (!terminate) {
handle_tasks(&ctx);
- bind_sockets(&ctx);
handle_input(&ctx);
maintenance(&ctx);