From: Omar Polo Subject: gotwebd: amke get_addrs() take the service name directly To: gameoftrees@openbsd.org Date: Wed, 15 Nov 2023 14:01:29 +0100 This changes how we handle the port number: bubbles up the local portstr added in previous commit and lets getaddrinfo() deals with port numbers and services name. getservice() then can be gc. while here add the missing free() in parse.y diff /home/op/w/gotwebd commit - dfd77022fc31b33c39f1e800698a2d43644666fa path + /home/op/w/gotwebd blob - ba2956ed0ff1a6e634c10f00b922c87daba91fc7 file + gotwebd/parse.y --- gotwebd/parse.y +++ gotwebd/parse.y @@ -95,7 +95,7 @@ static struct server *conf_new_server(const char *); int getservice(const char *); int n; -int get_addrs(const char *, struct server *, in_port_t); +int get_addrs(const char *, const char *, struct server *); int addr_dup_check(struct addresslist *, struct address *, const char *, const char *); int add_addr(struct server *, struct address *); @@ -104,7 +104,6 @@ typedef struct { union { long long number; char *string; - in_port_t port; } v; int lineno; } YYSTYPE; @@ -118,7 +117,6 @@ typedef struct { %token UNIX_SOCKET UNIX_SOCKET_NAME SERVER CHROOT CUSTOM_CSS SOCKET %token STRING -%type fcgiport %token NUMBER %type boolean %type listen_addr @@ -179,27 +177,6 @@ listen_addr : '*' { $$ = NULL; } | STRING ; -fcgiport : PORT NUMBER { - if ($2 <= 0 || $2 > (int)USHRT_MAX) { - yyerror("invalid port: %lld", $2); - YYERROR; - } - $$ = $2; - } - | PORT STRING { - int val; - - if ((val = getservice($2)) == -1) { - yyerror("invalid port: %s", $2); - free($2); - YYERROR; - } - free($2); - - $$ = val; - } - ; - main : PREFORK NUMBER { if ($2 <= 0 || $2 > PROC_MAX_INSTANCES) { yyerror("prefork is %s: %lld", @@ -345,13 +322,32 @@ serveropts1 : REPOS_PATH STRING { } free($2); } - | LISTEN ON listen_addr fcgiport { - if (get_addrs($3, new_srv, $4) == -1) { + | LISTEN ON listen_addr PORT STRING { + if (get_addrs($3, $5, new_srv) == -1) { yyerror("could not get addrs"); YYERROR; } + free($3); + free($5); new_srv->fcgi_socket = 1; } + | LISTEN ON listen_addr PORT NUMBER { + char portno[32]; + int n; + + n = snprintf(portno, sizeof(portno), "%lld", + (long long)$5); + if (n < 0 || (size_t)n >= sizeof(portno)) + fatalx("port number too long: %lld", + (long long)$5); + + if (get_addrs($3, portno, new_srv) == -1) { + yyerror("could not get addrs"); + YYERROR; + } + free($3); + new_srv->fcgi_socket = 1; + } | LISTEN ON SOCKET STRING { if (strcasecmp($4, "off") == 0) { new_srv->unix_socket = 0; @@ -1003,47 +999,22 @@ symget(const char *nam) } int -getservice(const char *n) +get_addrs(const char *hostname, const char *servname, struct server *new_srv) { - struct servent *s; - const char *errstr; - long long llval; - - llval = strtonum(n, 0, UINT16_MAX, &errstr); - if (errstr) { - s = getservbyname(n, "tcp"); - if (s == NULL) - s = getservbyname(n, "udp"); - if (s == NULL) - return (-1); - return ntohs(s->s_port); - } - - return (unsigned short)llval; -} - -int -get_addrs(const char *s, struct server *new_srv, in_port_t port) -{ struct addrinfo hints, *res0, *res; - int n, error; - struct sockaddr_in *sain; - struct sockaddr_in6 *sin6; + int error; + struct sockaddr_in *sain, *ra; + struct sockaddr_in6 *sin6, *ra6; struct address *h; - char portstr[32]; - n = snprintf(portstr, sizeof(portstr), "%d", port); - if (n < 0 || (size_t)n >= sizeof(portstr)) - fatalx("snprintf: port number too long: %d", port); - memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; /* DUMMY */ + hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; - error = getaddrinfo(s, portstr, &hints, &res0); + error = getaddrinfo(hostname, servname, &hints, &res0); if (error) { - log_warnx("%s: could not parse \"%s\": %s", __func__, s, - gai_strerror(error)); + log_warnx("%s: could not parse \"%s:%s\": %s", __func__, + hostname, servname, gai_strerror(error)); return (-1); } @@ -1051,12 +1022,10 @@ get_addrs(const char *s, struct server *new_srv, in_po if ((h = calloc(1, sizeof(*h))) == NULL) fatal(__func__); - if (port) - h->port = port; - if (s == NULL) { + if (hostname == NULL) { strlcpy(h->ifname, "*", sizeof(h->ifname)); } else { - if (strlcpy(h->ifname, s, sizeof(h->ifname)) >= + if (strlcpy(h->ifname, hostname, sizeof(h->ifname)) >= sizeof(h->ifname)) { log_warnx("%s: address truncated", __func__); freeaddrinfo(res0); @@ -1066,16 +1035,21 @@ get_addrs(const char *s, struct server *new_srv, in_po } h->ss.ss_family = res->ai_family; - if (res->ai_family == AF_INET) { - struct sockaddr_in *ra; + switch (res->ai_family) { + case AF_INET: sain = (struct sockaddr_in *)&h->ss; ra = (struct sockaddr_in *)res->ai_addr; + h->port = ntohs(ra->sin_port); got_sockaddr_inet_init(sain, &ra->sin_addr); - } else { - struct sockaddr_in6 *ra; + break; + case AF_INET6: sin6 = (struct sockaddr_in6 *)&h->ss; - ra = (struct sockaddr_in6 *)res->ai_addr; - got_sockaddr_inet6_init(sin6, &ra->sin6_addr, 0); + ra6 = (struct sockaddr_in6 *)res->ai_addr; + h->port = ntohs(ra6->sin6_port); + got_sockaddr_inet6_init(sin6, &ra6->sin6_addr, 0); + break; + default: + fatalx("unknown address family %d", res->ai_family); } if (add_addr(new_srv, h))