diff options
| -rw-r--r-- | json-rpc-test-server.c | 41 | 
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); | 
