diff options
| author | Mikhail Osipov <mike.osipov@gmail.com> | 2019-10-18 20:46:58 +0300 |
|---|---|---|
| committer | Mikhail Osipov <mike.osipov@gmail.com> | 2019-10-18 21:14:24 +0300 |
| commit | 8142854950bc510b8c21a210538d14a301dbcf63 (patch) | |
| tree | db4ecc964090218f50f1e9c4a8797544f9d45879 /tunnel.c | |
| parent | 3b00c7be0e8834402ed93eb42b3a93302076c5ff (diff) | |
skel update
Diffstat (limited to 'tunnel.c')
| -rw-r--r-- | tunnel.c | 120 |
1 files changed, 73 insertions, 47 deletions
@@ -2,6 +2,7 @@ #include <sys/stat.h> #include <sys/un.h> +#include <stdbool.h> #include <stddef.h> #include <unistd.h> #include <errno.h> @@ -12,12 +13,45 @@ #include "tunnel.h" #include "macro.h" -int tunnel_socket(struct sockaddr **sa, socklen_t *salen) +struct socket { + int fd; + struct sockaddr *sa; + socklen_t salen; +}; + +static bool socket_connect(struct socket *sock) +{ + if (connect(sock->fd, sock->sa, sock->salen) < 0) + return false; + + return true; +} + +static void socket_free(struct socket *sock) +{ + if (sock) { + if (sock->fd >= 0) + close(sock->fd); + free(sock->sa); + free(sock); + } +} + +static int socket_detach_fd(struct socket *sock) +{ + int fd = sock->fd; + + sock->fd = -1; + + return fd; +} + +struct socket *tunnel_socket(void) { - int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0); - if (sock < 0) { + int fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); + if (fd < 0) { warn("socket"); - return -1; + return NULL; } struct sockaddr_un sun = { @@ -31,86 +65,78 @@ int tunnel_socket(struct sockaddr **sa, socklen_t *salen) if (len > sizeof(sun)) { warnx("too large unix path"); - close(sock); - return -1; + close(fd); + return NULL; } - *sa = _copy(&sun, len); - *salen = len; + struct socket *sock = _new(struct socket, + .fd = fd, + .salen = len, + .sa = _copy(&sun, len), + ); return sock; } -int tunnel_listen(int sock, struct sockaddr *sa, socklen_t salen) +bool tunnel_listen(struct socket *sock) { - if (bind(sock, sa, salen) < 0) { + if (bind(sock->fd, sock->sa, sock->salen) < 0) { warn("bind"); - return -1; + return false; } - if (listen(sock, 0) < 0) { + if (listen(sock->fd, 0) < 0) { warn("listen"); - return -1; + return false; } - return 0; + return true; } -int tunnel_server(void) +bool tunnel_server(void) { - struct sockaddr *sa = NULL; - socklen_t salen = 0; + struct socket *sock = tunnel_socket(); + if (!sock) + return false; - int sock = tunnel_socket(&sa, &salen); - if (sock < 0) - return -1; + defer { socket_free(sock); } - defer { - close(sock); - free(sa); - } + if (! tunnel_listen(sock)) + return false; - if (tunnel_listen(sock, sa, salen) < 0) - return -1; - - if (tunnel_daemon(sock) < 0) - return -1; + if (! tunnel_daemon(sock->fd)) + return false; - return 0; + return true; } -int tunnel_connect(int sock, struct sockaddr *sa, socklen_t salen) +bool tunnel_connect(struct socket *sock) { - if (connect(sock, sa, salen) < 0) { + if (! socket_connect(sock)) { if (errno == ENOENT) { - if (tunnel_server() < 0) - return -1; + if (! tunnel_server()) + return false; } - if (errno != ENOENT || connect(sock, sa, salen) < 0) { + if (errno != ENOENT || ! socket_connect(sock)) { warn("connect"); - return -1; + return false; } } - return 0; + return true; } int tunnel_client(void) { - struct sockaddr *sa = NULL; - socklen_t salen = 0; - - int sock = tunnel_socket(&sa, &salen); - if (sock < 0) + struct socket *sock = tunnel_socket(); + if (! sock) return -1; - defer { free(sa); } + defer { socket_free(sock); } - if (tunnel_connect(sock, sa, salen) < 0) { - close(sock); + if (! tunnel_connect(sock)) return -1; - } - return sock; + return socket_detach_fd(sock); } |
