aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2020-10-18 02:53:40 +0200
committerPřemysl Eric Janouch <p@janouch.name>2023-08-01 03:14:49 +0200
commit50b345aad0dee3006bab2740cb03bae2fb1228eb (patch)
tree075a918b223af871df9be60876d218f9f95fa1dc
parent693455006830f29f79cc94b277060dfe39a8b66f (diff)
downloadjson-rpc-shell-50b345aad0dee3006bab2740cb03bae2fb1228eb.tar.gz
json-rpc-shell-50b345aad0dee3006bab2740cb03bae2fb1228eb.tar.xz
json-rpc-shell-50b345aad0dee3006bab2740cb03bae2fb1228eb.zip
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.
-rw-r--r--json-rpc-test-server.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/json-rpc-test-server.c b/json-rpc-test-server.c
index 99842f5..df4a1f3 100644
--- a/json-rpc-test-server.c
+++ b/json-rpc-test-server.c
@@ -2376,8 +2376,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;
@@ -2480,8 +2481,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;
@@ -2576,8 +2578,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;
@@ -2754,13 +2757,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
@@ -2775,6 +2780,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);
}
}
@@ -2824,7 +2831,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
@@ -2854,7 +2861,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);
@@ -2868,15 +2876,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 */))
@@ -2909,9 +2919,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);
@@ -2921,6 +2933,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);
@@ -2938,7 +2952,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,
@@ -2956,6 +2970,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);