From ad395da749b85d20b465581b8699a726c68418f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Sun, 18 Oct 2020 02:53:40 +0200 Subject: json-rpc-test-server: try to fetch a name for us AI_CANONNAME might not be the best thing but most of the code will stay even if we go for a better method. --- json-rpc-test-server.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/json-rpc-test-server.c b/json-rpc-test-server.c index 801fb88..0ce8a10 100644 --- a/json-rpc-test-server.c +++ b/json-rpc-test-server.c @@ -2364,8 +2364,9 @@ static struct client_vtable client_fcgi_vtable = }; static struct client * -client_fcgi_create (EV_P_ int sock_fd) +client_fcgi_create (EV_P_ const char *host, int sock_fd) { + (void) host; struct client_fcgi *self = client_new (EV_A_ sizeof *self, sock_fd); self->client.vtable = &client_fcgi_vtable; @@ -2468,8 +2469,9 @@ static struct client_vtable client_scgi_vtable = }; static struct client * -client_scgi_create (EV_P_ int sock_fd) +client_scgi_create (EV_P_ const char *host, int sock_fd) { + (void) host; struct client_scgi *self = client_new (EV_A_ sizeof *self, sock_fd); self->client.vtable = &client_scgi_vtable; @@ -2564,8 +2566,9 @@ static struct client_vtable client_ws_vtable = }; static struct client * -client_ws_create (EV_P_ int sock_fd) +client_ws_create (EV_P_ const char *host, int sock_fd) { + (void) host; struct client_ws *self = client_new (EV_A_ sizeof *self, sock_fd); self->client.vtable = &client_ws_vtable; @@ -2742,13 +2745,15 @@ client_co_run (struct server_context *ctx) // --- Basic server stuff ------------------------------------------------------ -typedef struct client *(*client_create_fn) (EV_P_ int sock_fd); +typedef struct client * + (*client_create_fn) (EV_P_ const char *host, int sock_fd); struct listener { int fd; ///< Listening socket FD ev_io watcher; ///< New connection available client_create_fn create; ///< Client constructor + char *host; ///< Hostname, IP or empty for any }; static void @@ -2763,6 +2768,8 @@ close_listeners (struct server_context *self) ev_io_stop (EV_DEFAULT_ &listener->watcher); xclose (listener->fd); listener->fd = -1; + + cstr_set (&listener->host, NULL); } } @@ -2812,7 +2819,7 @@ on_client_available (EV_P_ ev_io *watcher, int revents) { int sock_fd = accept (watcher->fd, NULL, NULL); if (sock_fd != -1) - listener->create (EV_A_ sock_fd); + listener->create (EV_A_ listener->host, sock_fd); else if (errno == EAGAIN) return; else if (errno != EINTR && errno != EMFILE @@ -2842,7 +2849,8 @@ parse_config (struct server_context *ctx, struct error **e) } static int -listener_bind (struct addrinfo *gai_iter) +listener_bind (struct addrinfo *gai_iter, + char *host, size_t host_len, char *port, size_t port_len) { int fd = socket (gai_iter->ai_family, gai_iter->ai_socktype, gai_iter->ai_protocol); @@ -2856,15 +2864,17 @@ listener_bind (struct addrinfo *gai_iter) soft_assert (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) != -1); - char host[NI_MAXHOST], port[NI_MAXSERV]; - host[0] = port[0] = '\0'; + *host = *port = 0; int err = getnameinfo (gai_iter->ai_addr, gai_iter->ai_addrlen, - host, sizeof host, port, sizeof port, - NI_NUMERICHOST | NI_NUMERICSERV); + host, host_len, port, port_len, NI_NUMERICHOST | NI_NUMERICSERV); if (err) print_debug ("%s: %s", "getnameinfo", gai_strerror (err)); + // We're binding to a port but our caller prefers a hostname char *address = format_host_port_pair (host, port); + if (gai_iter->ai_canonname) + snprintf (host, host_len, "%s", gai_iter->ai_canonname); + if (bind (fd, gai_iter->ai_addr, gai_iter->ai_addrlen)) print_error ("bind to %s failed: %s", address, strerror (errno)); else if (listen (fd, 16 /* arbitrary number */)) @@ -2897,9 +2907,11 @@ listener_add (struct server_context *ctx, const char *host, const char *port, } int fd; + char host_buf[NI_MAXHOST] = "", port_buf[NI_MAXSERV] = ""; for (gai_iter = gai_result; gai_iter; gai_iter = gai_iter->ai_next) { - if ((fd = listener_bind (gai_iter)) == -1) + if ((fd = listener_bind (gai_iter, + host_buf, sizeof host_buf, port_buf, sizeof port_buf)) == -1) continue; set_blocking (fd, false); @@ -2909,6 +2921,8 @@ listener_add (struct server_context *ctx, const char *host, const char *port, listener->watcher.data = listener; listener->create = create; listener->fd = fd; + listener->host = xstrdup (host); + // The client will query the obtained socket for the port anyway break; } freeaddrinfo (gai_result); @@ -2926,7 +2940,7 @@ get_ports_from_config (struct server_context *ctx, static bool setup_listen_fds (struct server_context *ctx, struct error **e) { - static const struct addrinfo gai_hints = + static struct addrinfo gai_hints = { .ai_socktype = SOCK_STREAM, .ai_flags = AI_PASSIVE, @@ -2944,6 +2958,9 @@ setup_listen_fds (struct server_context *ctx, struct error **e) size_t n_ports = ports_fcgi.len + ports_scgi.len + ports_ws.len; ctx->listeners = xcalloc (n_ports, sizeof *ctx->listeners); + if (bind_host) + gai_hints.ai_flags |= AI_CANONNAME; + for (size_t i = 0; i < ports_fcgi.len; i++) listener_add (ctx, bind_host, ports_fcgi.vector[i], &gai_hints, client_fcgi_create); -- cgit v1.2.3