summaryrefslogtreecommitdiff
path: root/tunnel.c
diff options
context:
space:
mode:
authorMikhail Osipov <mike.osipov@gmail.com>2019-10-18 20:46:58 +0300
committerMikhail Osipov <mike.osipov@gmail.com>2019-10-18 21:14:24 +0300
commit8142854950bc510b8c21a210538d14a301dbcf63 (patch)
treedb4ecc964090218f50f1e9c4a8797544f9d45879 /tunnel.c
parent3b00c7be0e8834402ed93eb42b3a93302076c5ff (diff)
skel update
Diffstat (limited to 'tunnel.c')
-rw-r--r--tunnel.c120
1 files changed, 73 insertions, 47 deletions
diff --git a/tunnel.c b/tunnel.c
index 56bdcdd..2e0718e 100644
--- a/tunnel.c
+++ b/tunnel.c
@@ -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);
}