summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-03-22 00:57:16 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-03-22 00:57:16 +0100
commitdf387f268f8d30d0a21731406bf6031cd6ba9588 (patch)
tree1f1465524c01826a61f7c5f7631c43cce41e6b62
parent5266f01d3295e7ac79cf25674167382b86817019 (diff)
downloadfastd-df387f268f8d30d0a21731406bf6031cd6ba9588.tar
fastd-df387f268f8d30d0a21731406bf6031cd6ba9588.zip
Refactor poll API
-rw-r--r--src/async.c8
-rw-r--r--src/fastd.c8
-rw-r--r--src/fastd.h10
-rw-r--r--src/peer.c12
-rw-r--r--src/poll.c260
-rw-r--r--src/poll.h25
-rw-r--r--src/receive.c2
-rw-r--r--src/send.c4
-rw-r--r--src/socket.c24
-rw-r--r--src/status.c16
-rw-r--r--src/tuntap.c46
-rw-r--r--src/types.h10
12 files changed, 185 insertions, 240 deletions
diff --git a/src/async.c b/src/async.c
index d05b8c5..50efeac 100644
--- a/src/async.c
+++ b/src/async.c
@@ -56,8 +56,10 @@ void fastd_async_init(void) {
fastd_setnonblock(fds[1]);
#endif
- ctx.async_rfd = fds[0];
+ ctx.async_rfd = FASTD_POLL_FD(POLL_TYPE_ASYNC, fds[0]);
ctx.async_wfd = fds[1];
+
+ fastd_poll_fd_register(&ctx.async_rfd);
}
/** Handles a DNS resolver response */
@@ -104,7 +106,7 @@ void fastd_async_handle(void) {
.msg_iovlen = 1,
};
- if (recvmsg(ctx.async_rfd, &msg, MSG_PEEK) < 0)
+ if (recvmsg(ctx.async_rfd.fd, &msg, MSG_PEEK) < 0)
exit_errno("fastd_async_handle: recvmsg");
uint8_t buf[header.len] __attribute__((aligned(8)));
@@ -112,7 +114,7 @@ void fastd_async_handle(void) {
vec[1].iov_len = sizeof(buf);
msg.msg_iovlen = 2;
- if (recvmsg(ctx.async_rfd, &msg, 0) < 0)
+ if (recvmsg(ctx.async_rfd.fd, &msg, 0) < 0)
exit_errno("fastd_async_handle: recvmsg");
switch (header.type) {
diff --git a/src/fastd.c b/src/fastd.c
index 4ac0e8e..52bbf9c 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -178,7 +178,7 @@ static void init_sockets(void) {
fastd_bind_address_t *addr = conf.bind_addrs;
for (i = 0; i < conf.n_bind_addrs; i++) {
if (get_bind_port(addr)) {
- ctx.socks[i] = (fastd_socket_t){ .fd = -2, .addr = addr };
+ ctx.socks[i] = (fastd_socket_t){ .fd = FASTD_POLL_FD(POLL_TYPE_SOCKET, -2), .addr = addr };
if (addr == conf.bind_addr_default_v4)
ctx.sock_default_v4 = &ctx.socks[i];
@@ -187,7 +187,7 @@ static void init_sockets(void) {
ctx.sock_default_v6 = &ctx.socks[i];
}
else {
- ctx.socks[i] = (fastd_socket_t){ .fd = -1, .addr = NULL };
+ ctx.socks[i] = (fastd_socket_t){ .fd = FASTD_POLL_FD(POLL_TYPE_SOCKET, -1), .addr = NULL };
}
addr = addr->next;
@@ -508,10 +508,12 @@ static inline void init(int argc, char *argv[]) {
fastd_cap_init();
+ fastd_poll_init();
+
init_sockets();
+
fastd_status_init();
fastd_async_init();
- fastd_poll_init();
if (!fastd_socket_handle_binds())
exit_error("unable to bind default socket");
diff --git a/src/fastd.h b/src/fastd.h
index f1b2f93..ba6acfb 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -39,6 +39,7 @@
#include "dlist.h"
#include "buffer.h"
#include "log.h"
+#include "poll.h"
#include "sem.h"
#include "shell.h"
#include "util.h"
@@ -147,7 +148,7 @@ struct fastd_bind_address {
/** A socket descriptor */
struct fastd_socket {
- int fd; /**< The file descriptor for the socket */
+ fastd_poll_fd_t fd; /**< The file descriptor for the socket */
const fastd_bind_address_t *addr; /**< The address this socket is supposed to be bound to (or NULL) */
fastd_peer_address_t *bound_addr; /**< The actual address that was bound to (may differ from addr when addr has a random port) */
fastd_peer_t *peer; /**< If the socket belongs to a single peer (as it was create dynamically when sending a handshake), contains that peer */
@@ -280,11 +281,12 @@ struct fastd_context {
#ifdef USE_EPOLL
int epoll_fd; /**< The file descriptor for the epoll facility */
#else
+ VECTOR(fastd_poll_fd_t *) fds; /**< Vector of file descriptors to poll on, indexed by the FD itself */
VECTOR(struct pollfd) pollfds; /**< The vector of pollfds for all file descriptors */
#endif
#ifdef WITH_STATUS_SOCKET
- int status_fd; /**< The file descriptor of the status socket */
+ fastd_poll_fd_t status_fd; /**< The file descriptor of the status socket */
#endif
bool has_floating; /**< Specifies if any of the configured peers have floating remotes */
@@ -298,12 +300,12 @@ struct fastd_context {
fastd_timeout_t next_maintenance; /**< The time of the next maintenance call */
VECTOR(pid_t) async_pids; /**< PIDs of asynchronously executed commands which still have to be reaped */
- int async_rfd; /**< The read side of the pipe used to send data from other threads to the main thread */
+ fastd_poll_fd_t async_rfd; /**< The read side of the pipe used to send data from other threads to the main thread */
int async_wfd; /**< The write side of the pipe used to send data from other threads to the main thread */
pthread_attr_t detached_thread; /**< pthread_attr_t for creating detached threads */
- int tunfd; /**< The file descriptor of the tunnel interface */
+ fastd_poll_fd_t tunfd; /**< The file descriptor of the tunnel interface */
#ifdef __ANDROID__
int android_ctrl_sock_fd; /**< The unix domain socket for communicating with Android GUI */
diff --git a/src/peer.c b/src/peer.c
index 9ce5ca2..efe554d 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -183,13 +183,9 @@ static void free_socket_by_id(size_t i) {
fastd_socket_close(peer->sock);
free(peer->sock);
-
- peer->sock = NULL;
- fastd_poll_set_fd_peer(i);
- }
- else {
- peer->sock = NULL;
}
+
+ peer->sock = NULL;
}
/** Closes and frees a peer's dynamic socket */
@@ -245,8 +241,6 @@ void fastd_peer_reset_socket(fastd_peer_t *peer) {
if (!peer->sock || !fastd_peer_is_socket_dynamic(peer))
return;
-
- fastd_poll_set_fd_peer(i);
}
/**
@@ -446,7 +440,6 @@ static void delete_peer(fastd_peer_t *peer) {
size_t i = peer_index(peer);
VECTOR_DELETE(ctx.peers, i);
- fastd_poll_delete_peer(i);
conf.protocol->free_peer_state(peer);
@@ -741,7 +734,6 @@ bool fastd_peer_add(fastd_peer_t *peer) {
peer->id = ctx.next_peer_id++;
VECTOR_ADD(ctx.peers, peer);
- fastd_poll_add_peer();
conf.protocol->init_peer_state(peer);
diff --git a/src/poll.c b/src/poll.c
index 499a339..6c83f97 100644
--- a/src/poll.c
+++ b/src/poll.c
@@ -66,6 +66,47 @@ static inline int handshake_timeout(void) {
}
+/** Handles a file descriptor that was selected on */
+static inline void handle_fd(fastd_poll_fd_t *fd, bool input, bool error) {
+ switch (fd->type) {
+ case POLL_TYPE_ASYNC:
+ if (input)
+ fastd_async_handle();
+ break;
+
+#ifdef WITH_STATUS_SOCKET
+ case POLL_TYPE_STATUS:
+ if (input)
+ fastd_status_handle();
+ break;
+#endif
+
+ case POLL_TYPE_IFACE:
+ if (input)
+ fastd_tuntap_handle();
+ break;
+
+ case POLL_TYPE_SOCKET:
+ {
+ fastd_socket_t *sock = container_of(fd, fastd_socket_t, fd);
+ if (error) {
+ if (sock->peer)
+ fastd_peer_reset_socket(sock->peer);
+ else
+ fastd_socket_error(sock);
+ }
+ else if (input) {
+ fastd_receive(sock);
+ }
+ }
+ break;
+
+ default:
+ exit_bug("unknown FD type");
+ }
+}
+
+
#ifdef USE_EPOLL
@@ -84,25 +125,6 @@ void fastd_poll_init(void) {
ctx.epoll_fd = epoll_create(1);
if (ctx.epoll_fd < 0)
exit_errno("epoll_create1");
-
- struct epoll_event event_async = {
- .events = EPOLLIN,
- .data.ptr = &ctx.async_rfd,
- };
- if (epoll_ctl(ctx.epoll_fd, EPOLL_CTL_ADD, ctx.async_rfd, &event_async) < 0)
- exit_errno("epoll_ctl");
-
-#ifdef WITH_STATUS_SOCKET
- if (ctx.status_fd >= 0) {
- struct epoll_event event_status = {
- .events = EPOLLIN,
- .data.ptr = &ctx.status_fd,
- };
-
- if (epoll_ctl(ctx.epoll_fd, EPOLL_CTL_ADD, ctx.status_fd, &event_status) < 0)
- exit_errno("epoll_ctl");
- }
-#endif
}
void fastd_poll_free(void) {
@@ -110,42 +132,25 @@ void fastd_poll_free(void) {
pr_warn_errno("closing EPOLL: close");
}
-void fastd_poll_set_fd_tuntap(void) {
- struct epoll_event event = {
- .events = EPOLLIN,
- .data.ptr = &ctx.tunfd,
- };
- if (epoll_ctl(ctx.epoll_fd, EPOLL_CTL_ADD, ctx.tunfd, &event) < 0)
- exit_errno("epoll_ctl");
-}
-
-void fastd_poll_set_fd_sock(size_t i) {
- struct epoll_event event = {
- .events = EPOLLIN,
- .data.ptr = &ctx.socks[i],
- };
- if (epoll_ctl(ctx.epoll_fd, EPOLL_CTL_ADD, ctx.socks[i].fd, &event) < 0)
- exit_errno("epoll_ctl");
-}
-
-void fastd_poll_set_fd_peer(size_t i) {
- fastd_peer_t *peer = VECTOR_INDEX(ctx.peers, i);
- if (!peer->sock || !fastd_peer_is_socket_dynamic(peer))
- return;
+void fastd_poll_fd_register(fastd_poll_fd_t *fd) {
+ if (fd->fd < 0)
+ exit_bug("fastd_poll_fd_register: invalid FD");
struct epoll_event event = {
.events = EPOLLIN,
- .data.ptr = peer->sock,
+ .data.ptr = fd,
};
- if (epoll_ctl(ctx.epoll_fd, EPOLL_CTL_ADD, peer->sock->fd, &event) < 0)
+
+ if (epoll_ctl(ctx.epoll_fd, EPOLL_CTL_ADD, fd->fd, &event) < 0)
exit_errno("epoll_ctl");
}
-void fastd_poll_add_peer(void) {
-}
+bool fastd_poll_fd_close(fastd_poll_fd_t *fd) {
+ if (epoll_ctl(ctx.epoll_fd, EPOLL_CTL_DEL, fd->fd, NULL) < 0)
+ exit_errno("epoll_ctl");
-void fastd_poll_delete_peer(UNUSED size_t i) {
+ return (close(fd->fd) == 0);
}
@@ -170,115 +175,44 @@ void fastd_poll_handle(void) {
return;
size_t i;
- for (i = 0; i < (size_t)ret; i++) {
- if (events[i].data.ptr == &ctx.tunfd) {
- if (events[i].events & EPOLLIN)
- fastd_tuntap_handle();
- }
- else if (events[i].data.ptr == &ctx.async_rfd) {
- if (events[i].events & EPOLLIN)
- fastd_async_handle();
- }
-#ifdef WITH_STATUS_SOCKET
- else if (events[i].data.ptr == &ctx.status_fd) {
- if (events[i].events & EPOLLIN)
- fastd_status_handle();
- }
-#endif
- else {
- fastd_socket_t *sock = events[i].data.ptr;
-
- if (events[i].events & (EPOLLERR|EPOLLHUP)) {
- if (sock->peer)
- fastd_peer_reset_socket(sock->peer);
- else
- fastd_socket_error(sock);
- }
- else if (events[i].events & EPOLLIN) {
- fastd_receive(sock);
- }
- }
- }
+ for (i = 0; i < (size_t)ret; i++)
+ handle_fd(events[i].data.ptr,
+ events[i].events & EPOLLIN,
+ events[i].events & (EPOLLERR|EPOLLHUP));
}
#else
void fastd_poll_init(void) {
- VECTOR_RESIZE(ctx.pollfds, 3 + ctx.n_socks + VECTOR_LEN(ctx.peers));
-
- VECTOR_INDEX(ctx.pollfds, 0) = (struct pollfd) {
- .fd = -1,
- .events = POLLIN,
- .revents = 0,
- };
-
- VECTOR_INDEX(ctx.pollfds, 1) = (struct pollfd) {
- .fd = ctx.async_rfd,
- .events = POLLIN,
- .revents = 0,
- };
-
- VECTOR_INDEX(ctx.pollfds, 2) = (struct pollfd) {
-#ifdef WITH_STATUS_SOCKET
- .fd = ctx.status_fd,
-#else
- .fd = -1,
-#endif
- .events = POLLIN,
- .revents = 0,
- };
-
- size_t i;
- for (i = 0; i < ctx.n_socks + VECTOR_LEN(ctx.peers); i++) {
- VECTOR_INDEX(ctx.pollfds, 3+i) = (struct pollfd) {
- .fd = -1,
- .events = POLLIN,
- .revents = 0,
- };
- }
}
void fastd_poll_free(void) {
+ VECTOR_FREE(ctx.fds);
VECTOR_FREE(ctx.pollfds);
}
-void fastd_poll_set_fd_tuntap(void) {
- VECTOR_INDEX(ctx.pollfds, 0).fd = ctx.tunfd;
-}
-
-void fastd_poll_set_fd_sock(size_t i) {
- VECTOR_INDEX(ctx.pollfds, 3+i).fd = ctx.socks[i].fd;
-}
+void fastd_poll_fd_register(fastd_poll_fd_t *fd) {
+ if (fd->fd < 0)
+ exit_bug("fastd_poll_fd_register: invalid FD");
-void fastd_poll_set_fd_peer(size_t i) {
- if (!VECTOR_LEN(ctx.pollfds))
- exit_bug("fastd_poll_set_fd_peer: polling not initialized yet");
+ while (VECTOR_LEN(ctx.fds) <= (size_t)fd->fd)
+ VECTOR_ADD(ctx.fds, NULL);
- fastd_peer_t *peer = VECTOR_INDEX(ctx.peers, i);
+ VECTOR_INDEX(ctx.fds, fd->fd) = fd;
- if (!peer->sock || !fastd_peer_is_socket_dynamic(peer))
- VECTOR_INDEX(ctx.pollfds, 3+ctx.n_socks+i).fd = -1;
- else
- VECTOR_INDEX(ctx.pollfds, 3+ctx.n_socks+i).fd = peer->sock->fd;
+ VECTOR_RESIZE(ctx.pollfds, 0);
}
-void fastd_poll_add_peer(void) {
- if (!VECTOR_LEN(ctx.pollfds))
- /* Polling is not initialized yet */
- return;
+bool fastd_poll_fd_close(fastd_poll_fd_t *fd) {
+ if (fd->fd < 0 || (size_t)fd->fd >= VECTOR_LEN(ctx.fds))
+ exit_bug("fastd_poll_fd_close: invalid FD");
- struct pollfd pollfd = {
- .fd = -1,
- .events = POLLIN,
- .revents = 0,
- };
+ VECTOR_INDEX(ctx.fds, fd->fd) = NULL;
- VECTOR_ADD(ctx.pollfds, pollfd);
-}
+ VECTOR_RESIZE(ctx.pollfds, 0);
-void fastd_poll_delete_peer(size_t i) {
- VECTOR_DELETE(ctx.pollfds, 3+ctx.n_socks+i);
+ return (close(fd->fd) == 0);
}
@@ -294,8 +228,20 @@ void fastd_poll_handle(void) {
if (timeout < 0 || timeout > maintenance_timeout)
timeout = maintenance_timeout;
- if (VECTOR_LEN(ctx.pollfds) != 3 + ctx.n_socks + VECTOR_LEN(ctx.peers))
- exit_bug("fd count mismatch");
+ if (!VECTOR_LEN(ctx.pollfds)) {
+ for (i = 0; i < VECTOR_LEN(ctx.fds); i++) {
+ fastd_poll_fd_t *fd = VECTOR_INDEX(ctx.fds, i);
+ if (!fd)
+ continue;
+
+ struct pollfd pollfd = {
+ .fd = fd->fd,
+ .events = POLLIN,
+ .revents = 0,
+ };
+ VECTOR_ADD(ctx.pollfds, pollfd);
+ }
+ }
sigset_t set, oldset;
sigemptyset(&set);
@@ -334,6 +280,8 @@ void fastd_poll_handle(void) {
}
if (ret > 0) {
+ ret = 0;
+
for (i = 0; i < VECTOR_LEN(ctx.pollfds); i++) {
struct pollfd *pollfd = &VECTOR_INDEX(ctx.pollfds, i);
pollfd->revents = 0;
@@ -345,6 +293,9 @@ void fastd_poll_handle(void) {
pollfd->revents |= POLLIN;
if (FD_ISSET(pollfd->fd, &errfds))
pollfd->revents |= POLLERR;
+
+ if (pollfd->revents)
+ ret++;
}
}
@@ -360,39 +311,14 @@ void fastd_poll_handle(void) {
if (ret <= 0)
return;
- if (VECTOR_INDEX(ctx.pollfds, 0).revents & POLLIN)
- fastd_tuntap_handle();
- if (VECTOR_INDEX(ctx.pollfds, 1).revents & POLLIN)
- fastd_async_handle();
-
-#ifdef WITH_STATUS_SOCKET
- if (VECTOR_INDEX(ctx.pollfds, 2).revents & POLLIN)
- fastd_status_handle();
-#endif
-
- for (i = 0; i < ctx.n_socks; i++) {
- if (VECTOR_INDEX(ctx.pollfds, 3+i).revents & (POLLERR|POLLHUP|POLLNVAL)) {
- fastd_socket_error(&ctx.socks[i]);
- VECTOR_INDEX(ctx.pollfds, 3+i).fd = -1;
- }
- else if (VECTOR_INDEX(ctx.pollfds, 3+i).revents & POLLIN) {
- fastd_receive(&ctx.socks[i]);
- }
- }
+ for (i = 0; i < VECTOR_LEN(ctx.pollfds) && ret > 0; i++) {
+ struct pollfd *pollfd = &VECTOR_INDEX(ctx.pollfds, i);
- for (i = 0; i < VECTOR_LEN(ctx.peers); i++) {
- fastd_peer_t *peer = VECTOR_INDEX(ctx.peers, i);
+ if (pollfd->revents)
+ ret--;
- if (VECTOR_INDEX(ctx.pollfds, 3+ctx.n_socks+i).revents & (POLLERR|POLLHUP|POLLNVAL)) {
- fastd_peer_reset_socket(peer);
- }
- else if (VECTOR_INDEX(ctx.pollfds, 3+ctx.n_socks+i).revents & POLLIN) {
- fastd_receive(peer->sock);
- }
+ handle_fd(VECTOR_INDEX(ctx.fds, pollfd->fd), pollfd->revents & POLLIN, pollfd->revents & (POLLERR|POLLHUP|POLLNVAL));
}
-
- if (VECTOR_LEN(ctx.pollfds) != 3 + ctx.n_socks + VECTOR_LEN(ctx.peers))
- exit_bug("fd count mismatch");
}
#endif
diff --git a/src/poll.h b/src/poll.h
index 823bcc8..fa870a9 100644
--- a/src/poll.h
+++ b/src/poll.h
@@ -36,22 +36,25 @@
#include "types.h"
+/** A file descriptor to poll on */
+struct fastd_poll_fd {
+ fastd_poll_type_t type; /**< What the file descriptor is used for */
+ int fd; /**< The file descriptor itself */
+};
+
+
/** Initializes the poll interface */
void fastd_poll_init(void);
/** Frees the poll interface */
void fastd_poll_free(void);
-/** Updates the file descriptor of the TUN/TAP interface from \e ctx.tunfd */
-void fastd_poll_set_fd_tuntap(void);
-/** Updates the file descriptor of the socket \e ctx.socks[i] */
-void fastd_poll_set_fd_sock(size_t i);
-/** Updates the file descriptor of the dynamic socket for the peer with index \e i in \e ctx.peers */
-void fastd_poll_set_fd_peer(size_t i);
-
-/** Must be called when a peer is added at the end of the peer list */
-void fastd_poll_add_peer(void);
-/** Must be called then the peer with the index \e i is deleted */
-void fastd_poll_delete_peer(size_t i);
+/** Returns a fastd_poll_fd_t structure */
+#define FASTD_POLL_FD(type, fd) ((fastd_poll_fd_t){type, fd})
+
+/** Registers a new file descriptor to poll on */
+void fastd_poll_fd_register(fastd_poll_fd_t *fd);
+/** Unregisters and closes a file descriptor */
+bool fastd_poll_fd_close(fastd_poll_fd_t *fd);
/** Waits for the next input event */
void fastd_poll_handle(void);
diff --git a/src/receive.c b/src/receive.c
index 2ee402a..8bb926c 100644
--- a/src/receive.c
+++ b/src/receive.c
@@ -260,7 +260,7 @@ void fastd_receive(fastd_socket_t *sock) {
.msg_controllen = sizeof(cbuf),
};
- ssize_t len = recvmsg(sock->fd, &message, 0);
+ ssize_t len = recvmsg(sock->fd.fd, &message, 0);
if (len <= 0) {
if (len < 0)
pr_warn_errno("recvmsg");
diff --git a/src/send.c b/src/send.c
index caa7312..c340daf 100644
--- a/src/send.c
+++ b/src/send.c
@@ -131,7 +131,7 @@ static void send_type(const fastd_socket_t *sock, const fastd_peer_address_t *lo
if (!msg.msg_controllen)
msg.msg_control = NULL;
- int ret = sendmsg(sock->fd, &msg, 0);
+ int ret = sendmsg(sock->fd.fd, &msg, 0);
if (ret < 0 && errno == EINVAL && msg.msg_controllen) {
pr_debug2("sendmsg failed, trying again without pktinfo");
@@ -142,7 +142,7 @@ static void send_type(const fastd_socket_t *sock, const fastd_peer_address_t *lo
msg.msg_control = NULL;
msg.msg_controllen = 0;
- ret = sendmsg(sock->fd, &msg, 0);
+ ret = sendmsg(sock->fd.fd, &msg, 0);
}
if (ret < 0) {
diff --git a/src/socket.c b/src/socket.c
index e932148..325ff30 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -180,7 +180,7 @@ static bool set_bound_address(fastd_socket_t *sock) {
fastd_peer_address_t addr = {};
socklen_t len = sizeof(addr);
- if (getsockname(sock->fd, &addr.sa, &len) < 0) {
+ if (getsockname(sock->fd.fd, &addr.sa, &len) < 0) {
pr_error_errno("getsockname");
return false;
}
@@ -201,22 +201,20 @@ bool fastd_socket_handle_binds(void) {
size_t i;
for (i = 0; i < ctx.n_socks; i++) {
- if (ctx.socks[i].fd >= 0)
+ if (ctx.socks[i].fd.fd >= 0)
continue;
if (!ctx.socks[i].addr)
continue;
- ctx.socks[i].fd = bind_socket(ctx.socks[i].addr, ctx.socks[i].fd < -1);
+ ctx.socks[i].fd = FASTD_POLL_FD(POLL_TYPE_SOCKET, bind_socket(ctx.socks[i].addr, ctx.socks[i].fd.fd < -1));
- if (ctx.socks[i].fd >= 0) {
+ if (ctx.socks[i].fd.fd >= 0) {
if (!set_bound_address(&ctx.socks[i])) {
fastd_socket_close(&ctx.socks[i]);
continue;
}
- fastd_poll_set_fd_sock(i);
-
fastd_peer_address_t bound_addr = *ctx.socks[i].bound_addr;
if (!ctx.socks[i].addr->addr.sa.sa_family)
bound_addr.sa.sa_family = AF_UNSPEC;
@@ -225,10 +223,12 @@ bool fastd_socket_handle_binds(void) {
pr_info("successfully bound to %B on `%s'", &bound_addr, ctx.socks[i].addr->bindtodev);
else
pr_info("successfully bound to %B", &bound_addr);
+
+ fastd_poll_fd_register(&ctx.socks[i].fd);
}
}
- if ((ctx.sock_default_v4 && ctx.sock_default_v4->fd < 0) || (ctx.sock_default_v6 && ctx.sock_default_v6->fd < 0))
+ if ((ctx.sock_default_v4 && ctx.sock_default_v4->fd.fd < 0) || (ctx.sock_default_v6 && ctx.sock_default_v6->fd.fd < 0))
return false;
return true;
@@ -260,7 +260,7 @@ fastd_socket_t * fastd_socket_open(fastd_peer_t *peer, int af) {
fastd_socket_t *sock = fastd_new(fastd_socket_t);
- sock->fd = fd;
+ sock->fd = FASTD_POLL_FD(POLL_TYPE_SOCKET, fd);
sock->addr = NULL;
sock->bound_addr = NULL;
sock->peer = peer;
@@ -271,16 +271,18 @@ fastd_socket_t * fastd_socket_open(fastd_peer_t *peer, int af) {
return NULL;
}
+ fastd_poll_fd_register(&sock->fd);
+
return sock;
}
/** Closes a socket */
void fastd_socket_close(fastd_socket_t *sock) {
- if (sock->fd >= 0) {
- if(close(sock->fd))
+ if (sock->fd.fd >= 0) {
+ if (!fastd_poll_fd_close(&sock->fd))
pr_error_errno("closing socket: close");
- sock->fd = -2;
+ sock->fd.fd = -2;
}
if (sock->bound_addr) {
diff --git a/src/status.c b/src/status.c
index f079938..181ab11 100644
--- a/src/status.c
+++ b/src/status.c
@@ -199,7 +199,7 @@ static void dump_status(int fd) {
/** Initialized the status socket */
void fastd_status_init(void) {
if (!conf.status_socket) {
- ctx.status_fd = -1;
+ ctx.status_fd.fd = -1;
return;
}
@@ -215,8 +215,8 @@ void fastd_status_init(void) {
}
#endif
- ctx.status_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (ctx.status_fd < 0)
+ ctx.status_fd = FASTD_POLL_FD(POLL_TYPE_STATUS, socket(AF_UNIX, SOCK_STREAM, 0));
+ if (ctx.status_fd.fd < 0)
exit_errno("fastd_status_init: socket");
@@ -230,7 +230,7 @@ void fastd_status_init(void) {
sa->sun_family = AF_UNIX;
memcpy(sa->sun_path, conf.status_socket, status_socket_len+1);
- if (bind(ctx.status_fd, (struct sockaddr*)sa, len)) {
+ if (bind(ctx.status_fd.fd, (struct sockaddr*)sa, len)) {
switch (errno) {
case EADDRINUSE:
exit_error("unable to create status socket: the path `%s' already exists", conf.status_socket);
@@ -240,7 +240,7 @@ void fastd_status_init(void) {
}
}
- if (listen(ctx.status_fd, 4))
+ if (listen(ctx.status_fd.fd, 4))
exit_errno("fastd_status_init: listen");
@@ -250,6 +250,8 @@ void fastd_status_init(void) {
if (setegid(gid) < 0)
pr_debug_errno("setegid");
#endif
+
+ fastd_poll_fd_register(&ctx.status_fd);
}
/** Closes the status socket */
@@ -257,7 +259,7 @@ void fastd_status_close(void) {
if (!conf.status_socket)
return;
- if (close(ctx.status_fd))
+ if (!fastd_poll_fd_close(&ctx.status_fd))
pr_warn_errno("fastd_status_cleanup: close");
if (unlink(conf.status_socket))
@@ -266,7 +268,7 @@ void fastd_status_close(void) {
/** Handles a single connection on the status socket */
void fastd_status_handle(void) {
- int fd = accept(ctx.status_fd, NULL, NULL);
+ int fd = accept(ctx.status_fd.fd, NULL, NULL);
if (fd < 0) {
pr_warn_errno("fastd_status_handle: accept");
diff --git a/src/tuntap.c b/src/tuntap.c
index 98a0983..e9e0cb4 100644
--- a/src/tuntap.c
+++ b/src/tuntap.c
@@ -71,7 +71,8 @@ static void tuntap_open_linux(const char * dev_name) {
struct ifreq ifr = {};
- if ((ctx.tunfd = open(dev_name, O_RDWR|O_NONBLOCK)) < 0)
+ ctx.tunfd = FASTD_POLL_FD(POLL_TYPE_IFACE, open(dev_name, O_RDWR|O_NONBLOCK));
+ if (ctx.tunfd.fd < 0)
exit_errno("could not open tun/tap device file");
if (conf.ifname)
@@ -91,7 +92,7 @@ static void tuntap_open_linux(const char * dev_name) {
}
ifr.ifr_flags |= IFF_NO_PI;
- if (ioctl(ctx.tunfd, TUNSETIFF, &ifr) < 0)
+ if (ioctl(ctx.tunfd.fd, TUNSETIFF, &ifr) < 0)
exit_errno("TUNSETIFF ioctl failed");
ctx.ifname = fastd_strndup(ifr.ifr_name, IFNAMSIZ-1);
@@ -112,7 +113,7 @@ static void tuntap_open_linux(const char * dev_name) {
if (close(ctl_sock))
pr_error_errno("close");
- fastd_poll_set_fd_tuntap();
+ fastd_poll_fd_register(&ctx.tunfd);
pr_debug("tun/tap device initialized.");
}
@@ -131,11 +132,11 @@ void fastd_tuntap_open(void) {
}
pr_debug("using android TUN fd");
- ctx.tunfd = fastd_android_receive_tunfd();
+ ctx.tunfd = FASTD_POLL_FD(POLL_TYPE_IFACE(fastd_android_receive_tunfd()));
fastd_android_send_pid();
- fastd_poll_set_fd_tuntap();
+ fastd_poll_fd_register(&ctx.tunfd);
pr_debug("tun device initialized.");
} else {
@@ -157,12 +158,12 @@ void fastd_tuntap_open(void) {
static void set_tun_mtu(void) {
struct tuninfo tuninfo;
- if (ioctl(ctx.tunfd, TUNGIFINFO, &tuninfo) < 0)
+ if (ioctl(ctx.tunfd.fd, TUNGIFINFO, &tuninfo) < 0)
exit_errno("TUNGIFINFO ioctl failed");
tuninfo.mtu = conf.mtu;
- if (ioctl(ctx.tunfd, TUNSIFINFO, &tuninfo) < 0)
+ if (ioctl(ctx.tunfd.fd, TUNSIFINFO, &tuninfo) < 0)
exit_errno("TUNSIFINFO ioctl failed");
}
@@ -173,19 +174,19 @@ static void set_tun_mtu(void) {
static void set_tap_mtu(void) {
struct tapinfo tapinfo;
- if (ioctl(ctx.tunfd, TAPGIFINFO, &tapinfo) < 0)
+ if (ioctl(ctx.tunfd.fd, TAPGIFINFO, &tapinfo) < 0)
exit_errno("TAPGIFINFO ioctl failed");
tapinfo.mtu = conf.mtu;
- if (ioctl(ctx.tunfd, TAPSIFINFO, &tapinfo) < 0)
+ if (ioctl(ctx.tunfd.fd, TAPSIFINFO, &tapinfo) < 0)
exit_errno("TAPSIFINFO ioctl failed");
}
/** Sets up the TUN device */
static void setup_tun(void) {
int one = 1;
- if (ioctl(ctx.tunfd, TUNSIFHEAD, &one) < 0)
+ if (ioctl(ctx.tunfd.fd, TUNSIFHEAD, &one) < 0)
exit_errno("TUNSIFHEAD ioctl failed");
set_tun_mtu();
@@ -195,7 +196,7 @@ static void setup_tun(void) {
static void setup_tap(void) {
struct ifreq ifr = {};
- if (ioctl(ctx.tunfd, TAPGIFNAME, &ifr) < 0)
+ if (ioctl(ctx.tunfd.fd, TAPGIFNAME, &ifr) < 0)
exit_errno("TAPGIFNAME ioctl failed");
free(ctx.ifname);
@@ -234,10 +235,11 @@ void fastd_tuntap_open(void) {
strncat(ifname, type, IFNAMSIZ-1);
}
- if ((ctx.tunfd = open(ifname, O_RDWR|O_NONBLOCK)) < 0)
+ ctx.tunfd = FASTD_POLL_FD(POLL_TYPE_IFACE, open(ifname, O_RDWR|O_NONBLOCK));
+ if (ctx.tunfd.fd < 0)
exit_errno("could not open tun/tap device file");
- if (!(ctx.ifname = fdevname_r(ctx.tunfd, fastd_alloc(IFNAMSIZ), IFNAMSIZ)))
+ if (!(ctx.ifname = fdevname_r(ctx.tunfd.fd, fastd_alloc(IFNAMSIZ), IFNAMSIZ)))
exit_errno("could not get tun/tap interface name");
switch (conf.mode) {
@@ -253,7 +255,7 @@ void fastd_tuntap_open(void) {
exit_bug("invalid mode");
}
- fastd_poll_set_fd_tuntap();
+ fastd_poll_fd_register(&ctx.tunfd);
pr_debug("tun/tap device initialized.");
}
@@ -307,7 +309,8 @@ void fastd_tuntap_open(void) {
pr_debug("initializing tun device...");
- if ((ctx.tunfd = open(ifname, O_RDWR|O_NONBLOCK)) < 0)
+ ctx.tunfd = FASTD_POLL_FD(POLL_TYPE_IFACE, open(ifname, O_RDWR|O_NONBLOCK));
+ if (ctx.tunfd.fd < 0)
exit_errno("could not open tun device file");
ctx.ifname = fastd_strndup(conf.ifname, IFNAMSIZ-1);
@@ -325,7 +328,7 @@ void fastd_tuntap_open(void) {
exit_bug("invalid mode");
}
- fastd_poll_set_fd_tuntap();
+ fastd_poll_fd_register(&ctx.tunfd);
pr_debug("tun device initialized.");
}
@@ -360,7 +363,8 @@ void fastd_tuntap_open(void) {
pr_debug("initializing tun device...");
- if ((ctx.tunfd = open(ifname, O_RDWR|O_NONBLOCK)) < 0)
+ ctx.tunfd = FASTD_POLL_FD(POLL_TYPE_IFACE, open(ifname, O_RDWR|O_NONBLOCK));
+ if (ctx.tunfd.fd < 0)
exit_errno("could not open tun device file");
ctx.ifname = fastd_strndup(conf.ifname, IFNAMSIZ-1);
@@ -378,7 +382,7 @@ void fastd_tuntap_open(void) {
if (close(ctl_sock))
pr_error_errno("close");
- fastd_poll_set_fd_tuntap();
+ fastd_poll_fd_register(&ctx.tunfd);
pr_debug("tun device initialized.");
}
@@ -400,7 +404,7 @@ void fastd_tuntap_handle(void) {
else
buffer = fastd_buffer_alloc(max_len, conf.min_encrypt_head_space, conf.min_encrypt_tail_space);
- ssize_t len = read(ctx.tunfd, buffer.data, max_len);
+ ssize_t len = read(ctx.tunfd.fd, buffer.data, max_len);
if (len < 0)
exit_errno("read");
@@ -436,12 +440,12 @@ void fastd_tuntap_write(fastd_buffer_t buffer) {
memcpy(buffer.data, &af, 4);
}
- if (write(ctx.tunfd, buffer.data, buffer.len) < 0)
+ if (write(ctx.tunfd.fd, buffer.data, buffer.len) < 0)
pr_debug2_errno("write");
}
/** Closes the TUN/TAP device */
void fastd_tuntap_close(void) {
- if (close(ctx.tunfd))
+ if (!fastd_poll_fd_close(&ctx.tunfd))
pr_warn_errno("closing tun/tap: close");
}
diff --git a/src/types.h b/src/types.h
index f380541..2a854c2 100644
--- a/src/types.h
+++ b/src/types.h
@@ -75,12 +75,22 @@ typedef enum fastd_drop_caps {
DROP_CAPS_EARLY, /**< The capabilities are dropped before executing the on-up command */
} fastd_drop_caps_t;
+/** Types of file descriptors to poll on */
+typedef enum fastd_poll_type {
+ POLL_TYPE_UNSPEC = 0,
+ POLL_TYPE_ASYNC,
+ POLL_TYPE_STATUS,
+ POLL_TYPE_IFACE,
+ POLL_TYPE_SOCKET,
+} fastd_poll_type_t;
+
/** A timestamp used as a timeout */
typedef int64_t fastd_timeout_t;
typedef struct fastd_buffer fastd_buffer_t;
+typedef struct fastd_poll_fd fastd_poll_fd_t;
typedef union fastd_peer_address fastd_peer_address_t;
typedef struct fastd_bind_address fastd_bind_address_t;