From ad8ada98b2339ede07cad25523c184e01168eca8 Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Wed, 5 Oct 2016 13:01:29 +1000 Subject: [PATCH] * source/portknock: implement start() --- src/sources/portknock.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/sources/portknock.c b/src/sources/portknock.c index 3554711..2b85f0b 100644 --- a/src/sources/portknock.c +++ b/src/sources/portknock.c @@ -10,6 +10,7 @@ #include #include #include +#include #define HOST_MAX 48 #define PORT_MAX 6 @@ -18,7 +19,7 @@ typedef struct f2b_port_t { struct f2b_port_t *next; char host[HOST_MAX]; char port[PORT_MAX]; - int fd; + int sock; } f2b_port_t; struct _config { @@ -131,9 +132,41 @@ errcb(cfg_t *cfg, void (*cb)(char *errstr)) { bool start(cfg_t *cfg) { + struct addrinfo hints; + struct addrinfo *result; assert(cfg != NULL); - /* TODO */ + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + + for (f2b_port_t *port = cfg->ports; port != 0; port = port->next) { + port->sock = -1; + int ret = getaddrinfo(port->host, port->port, &hints, &result); + if (ret != 0) { + snprintf(cfg->error, sizeof(cfg->error), "getaddrinfo: %s", gai_strerror(ret)); + cfg->errcb(cfg->error); + continue; + } + for (struct addrinfo *rp = result; rp != NULL; rp = rp->ai_next) { + port->sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (port->sock == -1) + continue; + if (bind(port->sock, rp->ai_addr, rp->ai_addrlen) == 0) { + if (listen(port->sock, 5) == 0) /* TODO: hardcoded */ + break; /* success */ + close(port->sock); + port->sock = -1; + } + } + freeaddrinfo(result); + if (port->sock < 0) { + snprintf(cfg->error, sizeof(cfg->error), "can't bind/listen on %s:%s", port->host, port->port); + cfg->errcb(cfg->error); + } + } + return true; }