diff options
| author | Drew DeVault <sir@cmpwn.com> | 2020-09-23 12:40:28 -0400 |
|---|---|---|
| committer | Drew DeVault <sir@cmpwn.com> | 2020-09-23 12:43:05 -0400 |
| commit | 65c2a56c6d62e3c24d52da8c63f306b70becdb45 (patch) | |
| tree | 3fab5e106777ddaeb2d9b2b35e9c5adfd5f634b2 /src | |
| parent | 9adc6f34c7497cf2fde21cd1dfdf87ba3296b559 (diff) | |
| download | gmnisrv-65c2a56c6d62e3c24d52da8c63f306b70becdb45.tar.gz gmnisrv-65c2a56c6d62e3c24d52da8c63f306b70becdb45.tar.xz gmnisrv-65c2a56c6d62e3c24d52da8c63f306b70becdb45.zip | |
Initialize sockets
Diffstat (limited to 'src')
| -rw-r--r-- | src/config.c | 26 | ||||
| -rw-r--r-- | src/main.c | 14 | ||||
| -rw-r--r-- | src/server.c | 92 |
3 files changed, 131 insertions, 1 deletions
diff --git a/src/config.c b/src/config.c index 9bc251c..f3172d2 100644 --- a/src/config.c +++ b/src/config.c @@ -31,7 +31,9 @@ parse_listen(struct gmnisrv_config *conf, const char *value) char *port = tok; struct gmnisrv_bind *bind = calloc(1, sizeof(struct gmnisrv_bind)); + assert(bind); bind->port = 1965; + bind->name = strdup(tok); if (tok[0] == '[') { bind->family = AF_INET6; @@ -133,6 +135,7 @@ conf_ini_handler(void *user, const char *section, struct gmnisrv_host *host = gmnisrv_config_get_host(conf, section); if (!host) { host = calloc(1, sizeof(struct gmnisrv_host)); + assert(host); host->hostname = strdup(section); host->next = conf->hosts; conf->hosts = host; @@ -194,3 +197,26 @@ load_config(struct gmnisrv_config *conf, const char *path) return validate_config(conf); } + +void +config_finish(struct gmnisrv_config *conf) +{ + free(conf->tls.store); + free(conf->tls.organization); + free(conf->tls.email); + struct gmnisrv_bind *bind = conf->binds; + while (bind) { + struct gmnisrv_bind *next = bind->next; + free(bind->name); + free(bind); + bind = next; + } + struct gmnisrv_host *host = conf->hosts; + while (host) { + struct gmnisrv_host *next = host->next; + free(host->hostname); + free(host->root); + free(host); + host = next; + } +} @@ -1,6 +1,7 @@ #include <getopt.h> #include <stdio.h> #include "config.h" +#include "server.h" static void usage(const char *argv_0) @@ -36,8 +37,19 @@ main(int argc, char **argv) int r = load_config(&conf, confpath); if (r != 0) { - return r; + goto exit_conf; } + struct gmnisrv_server server = {0}; + r = server_init(&server, &conf); + if (r != 0) { + goto exit; + } + server_run(&server); + +exit: + server_finish(&server); +exit_conf: + config_finish(&conf); return 0; } diff --git a/src/server.c b/src/server.c new file mode 100644 index 0000000..39c2c07 --- /dev/null +++ b/src/server.c @@ -0,0 +1,92 @@ +#include <arpa/inet.h> +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include "config.h" +#include "server.h" + +int +server_init(struct gmnisrv_server *server, struct gmnisrv_config *conf) +{ + server->conf = conf; + for (struct gmnisrv_bind *b = conf->binds; b; b = b->next) { + ++server->nlisten; + } + + assert(server->nlisten < 1024); + server->nfds = server->nlisten; + server->fds = calloc(server->nfds, sizeof(struct pollfd)); + assert(server->fds); + + server->clientsz = 1024 - server->nlisten; + server->clients = calloc(server->clientsz, sizeof(struct gmnisrv_client)); + + size_t i = 0; + for (struct gmnisrv_bind *b = conf->binds; b; b = b->next) { + int sockfd = socket(b->family, SOCK_STREAM, 0); + if (sockfd < 0) { + fprintf(stderr, + "Failed to establish socket %s: %s\n", + b->name, strerror(errno)); + return 1; + } + + struct sockaddr *addr; + size_t addrsz; + if (b->family == AF_INET) { + struct sockaddr_in in = {0}; + in.sin_family = AF_INET; + memcpy(&in.sin_addr, b->addr, sizeof(b->addr)); + in.sin_port = htons(b->port); + addr = (struct sockaddr *)∈ + addrsz = sizeof(in); + } else if (b->family == AF_INET6) { + struct sockaddr_in6 in = {0}; + in.sin6_family = AF_INET6; + memcpy(&in.sin6_addr, b->addr, sizeof(b->addr)); + in.sin6_port = htons(b->port); + addr = (struct sockaddr *)∈ + addrsz = sizeof(in); +#ifdef LINUX + static int t = 1; + setsockopt(sockfd, IPPROTO_IPV6, + IPV6_V6ONLY, &t, sizeof(t)); +#endif + } else { + assert(0); + } + + int r = bind(sockfd, addr, addrsz); + if (r == -1) { + fprintf(stderr, + "Failed to bind socket %s: %s\n", + b->name, strerror(errno)); + return 1; + } + + r = listen(sockfd, 16); + + server->fds[i].fd = sockfd; + server->fds[i].events = POLLIN; + ++i; + } + + return 0; +} + +void +server_run(struct gmnisrv_server *server) +{ + // TODO + (void)server; +} + +void +server_finish(struct gmnisrv_server *server) +{ + // TODO + (void)server; +} |
