From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from brown.elm.relay.mailchannels.net (brown.elm.relay.mailchannels.net [23.83.212.23]) by sourceware.org (Postfix) with ESMTPS id 56C06394FC3D for ; Thu, 17 Mar 2022 08:12:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 56C06394FC3D X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 3A41B120847; Thu, 17 Mar 2022 08:12:20 +0000 (UTC) Received: from pdx1-sub0-mail-a307.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 3EEE2120951; Thu, 17 Mar 2022 08:12:09 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1647504729; a=rsa-sha256; cv=none; b=Csxyhqj+EISALVSe2gzx8eAzMOdQBe8mHgqXUZdmUZYueRLqAqouIoyNp6mVCjHD4bdQPN cDjOXJo7DWkJuUlrYoJIyWyfh3y5AkbUnLblm0Ppf8luvDkfpRkJ4bv6EzhrcEhMvE7nsb dxFTl4Af7g7/FGVqTGqAzKtwYVMrsh3yR6B4GF3cNvK8ExVJ9XsWNjrOTeY1ArdE68oOJ6 YfmQ7ft3UbT5/DMWTZssGjZORQuG9VQNAw8DL9exVGaWdvkD0N3ofc8TIjJ7fdulW/ldZa d0dnUyTiKfDsb5N9yo35d+NlqWvN88fxWebPm5C217wajoAqIWLxn2HPbEtVrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1647504729; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=R+opd4772gqjyYMToQ0sfIRD/BX9SYOBnRHNOjKY9Eg=; b=ir1IpFLefMhLFWLcfqP/3BTgZ16eK4Zb1dXNArZEl9wGd4RflypO0DpGzkqGIEe6fHNh0S NOHRhJlTQiYNRdUflMF4a6IrkNbeBjGy2W72sX8kYBX8gw/i+U1jL+2QOXE3rBzmjmTfGg 2TXEk+xv5DGH0SyO+QvTEzj0TxRPpKcflWo0oJjk86hG9gfgmpEtaC+mRtK7RlLgku+NyB LwkvBHr8wRDpggTlY5u2gMheRAovcxfK3hqPiifhP4I3jUAiY6jXJGFLF0su6jzcXvM97T DEOeemmaZhY9QoZLVBwSL68lHchdkzaT0hTJHvibGfXKFw1SOpZU9T7z53Yc1g== ARC-Authentication-Results: i=1; rspamd-74bfb75fc6-s9pd7; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a307.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.120.38.157 (trex/6.5.3); Thu, 17 Mar 2022 08:12:20 +0000 X-MC-Relay: Junk X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Obese-Shade: 2c8b9bab08a1a1cb_1647504729816_565995004 X-MC-Loop-Signature: 1647504729816:663544828 X-MC-Ingress-Time: 1647504729815 Received: from rhbox.intra.reserved-bit.com (unknown [1.186.123.88]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a307.dreamhost.com (Postfix) with ESMTPSA id 4KK0HC3lFfz1Q; Thu, 17 Mar 2022 01:12:06 -0700 (PDT) From: Siddhesh Poyarekar To: libc-alpha@sourceware.org Subject: [PATCH v3 04/12] gaih_inet: Simplify service resolution Date: Thu, 17 Mar 2022 13:41:32 +0530 Message-Id: <20220317081140.3098156-5-siddhesh@sourceware.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220317081140.3098156-1-siddhesh@sourceware.org> References: <20220308100717.1006126-1-siddhesh@sourceware.org> <20220317081140.3098156-1-siddhesh@sourceware.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3493.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL, SPF_HELO_NONE, SPF_NEUTRAL, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Mar 2022 08:12:23 -0000 Refactor the code to split out the service resolution code into a separate function. Allocate the service tuples array just once to the size of the typeproto array, thus avoiding the unnecessary pointer chasing and stack allocations. Signed-off-by: Siddhesh Poyarekar Reviewed-by: DJ Delorie --- sysdeps/posix/getaddrinfo.c | 178 ++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 100 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index e9deb2da6a..dae5e9f55f 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -100,14 +100,12 @@ struct gaih_service struct gaih_servtuple { - struct gaih_servtuple *next; int socktype; int protocol; int port; + bool set; }; -static const struct gaih_servtuple nullserv; - struct gaih_typeproto { @@ -180,11 +178,11 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, } while (r); - st->next = NULL; st->socktype = tp->socktype; st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) ? req->ai_protocol : tp->protocol); st->port = s->s_port; + st->set = true; return 0; } @@ -375,20 +373,11 @@ process_canonname (const struct addrinfo *req, const char *orig_name, } static int -gaih_inet (const char *name, const struct gaih_service *service, - const struct addrinfo *req, struct addrinfo **pai, - unsigned int *naddrs, struct scratch_buffer *tmpbuf) +get_servtuples (const struct gaih_service *service, const struct addrinfo *req, + struct gaih_servtuple *st, struct scratch_buffer *tmpbuf) { + int i; const struct gaih_typeproto *tp = gaih_inet_typeproto; - struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv; - struct gaih_addrtuple *at = NULL; - bool got_ipv6 = false; - char *canon = NULL; - const char *orig_name = name; - - /* Reserve stack memory for the scratch buffer in the getaddrinfo - function. */ - size_t alloca_used = sizeof (struct scratch_buffer); if (req->ai_protocol || req->ai_socktype) { @@ -410,98 +399,88 @@ gaih_inet (const char *name, const struct gaih_service *service, } } - int port = 0; - if (service != NULL) + if (service != NULL && (tp->protoflag & GAI_PROTO_NOSERVICE) != 0) + return -EAI_SERVICE; + + if (service == NULL || service->num >= 0) { - if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) - return -EAI_SERVICE; + int port = service != NULL ? htons (service->num) : 0; - if (service->num < 0) + if (req->ai_socktype || req->ai_protocol) { - if (tp->name[0]) - { - st = (struct gaih_servtuple *) - alloca_account (sizeof (struct gaih_servtuple), alloca_used); - - int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf); - if (__glibc_unlikely (rc != 0)) - return rc; - } - else - { - struct gaih_servtuple **pst = &st; - for (tp++; tp->name[0]; tp++) - { - struct gaih_servtuple *newp; + st[0].socktype = tp->socktype; + st[0].protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) + ? req->ai_protocol : tp->protocol); + st[0].port = port; + st[0].set = true; - if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) - continue; + return 0; + } - if (req->ai_socktype != 0 - && req->ai_socktype != tp->socktype) - continue; - if (req->ai_protocol != 0 - && !(tp->protoflag & GAI_PROTO_PROTOANY) - && req->ai_protocol != tp->protocol) - continue; + /* Neither socket type nor protocol is set. Return all socket types + we know about. */ + for (i = 0, ++tp; tp->name[0]; ++tp) + if (tp->defaultflag) + { + st[i].socktype = tp->socktype; + st[i].protocol = tp->protocol; + st[i].port = port; + st[i++].set = true; + } - newp = (struct gaih_servtuple *) - alloca_account (sizeof (struct gaih_servtuple), - alloca_used); + return 0; + } - if (gaih_inet_serv (service->name, - tp, req, newp, tmpbuf) != 0) - continue; + if (tp->name[0]) + return gaih_inet_serv (service->name, tp, req, st, tmpbuf); - *pst = newp; - pst = &(newp->next); - } - if (st == (struct gaih_servtuple *) &nullserv) - return -EAI_SERVICE; - } - } - else - { - port = htons (service->num); - goto got_port; - } - } - else + for (i = 0, tp++; tp->name[0]; tp++) { - got_port: + if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) + continue; - if (req->ai_socktype || req->ai_protocol) - { - st = alloca_account (sizeof (struct gaih_servtuple), alloca_used); - st->next = NULL; - st->socktype = tp->socktype; - st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) - ? req->ai_protocol : tp->protocol); - st->port = port; - } - else - { - /* Neither socket type nor protocol is set. Return all socket types - we know about. */ - struct gaih_servtuple **lastp = &st; - for (++tp; tp->name[0]; ++tp) - if (tp->defaultflag) - { - struct gaih_servtuple *newp; + if (req->ai_socktype != 0 + && req->ai_socktype != tp->socktype) + continue; + if (req->ai_protocol != 0 + && !(tp->protoflag & GAI_PROTO_PROTOANY) + && req->ai_protocol != tp->protocol) + continue; - newp = alloca_account (sizeof (struct gaih_servtuple), - alloca_used); - newp->next = NULL; - newp->socktype = tp->socktype; - newp->protocol = tp->protocol; - newp->port = port; + if (gaih_inet_serv (service->name, + tp, req, &st[i], tmpbuf) != 0) + continue; - *lastp = newp; - lastp = &newp->next; - } - } + i++; } + if (!st[0].set) + return -EAI_SERVICE; + + return 0; +} + +static int +gaih_inet (const char *name, const struct gaih_service *service, + const struct addrinfo *req, struct addrinfo **pai, + unsigned int *naddrs, struct scratch_buffer *tmpbuf) +{ + struct gaih_servtuple st[sizeof (gaih_inet_typeproto) + / sizeof (struct gaih_typeproto)] = {0}; + + struct gaih_addrtuple *at = NULL; + bool got_ipv6 = false; + char *canon = NULL; + const char *orig_name = name; + + /* Reserve stack memory for the scratch buffer in the getaddrinfo + function. */ + size_t alloca_used = sizeof (struct scratch_buffer); + + int rc; + if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0) + return rc; + bool malloc_name = false; struct gaih_addrtuple *addrmem = NULL; int result = 0; @@ -1083,7 +1062,6 @@ gaih_inet (const char *name, const struct gaih_service *service, if ((result = process_canonname (req, orig_name, &canon)) != 0) goto free_and_return; - struct gaih_servtuple *st2; struct gaih_addrtuple *at2 = at; size_t socklen; sa_family_t family; @@ -1109,7 +1087,7 @@ gaih_inet (const char *name, const struct gaih_service *service, else socklen = sizeof (struct sockaddr_in); - for (st2 = st; st2 != NULL; st2 = st2->next) + for (int i = 0; st[i].set; i++) { struct addrinfo *ai; ai = *pai = malloc (sizeof (struct addrinfo) + socklen); @@ -1121,8 +1099,8 @@ gaih_inet (const char *name, const struct gaih_service *service, ai->ai_flags = req->ai_flags; ai->ai_family = family; - ai->ai_socktype = st2->socktype; - ai->ai_protocol = st2->protocol; + ai->ai_socktype = st[i].socktype; + ai->ai_protocol = st[i].protocol; ai->ai_addrlen = socklen; ai->ai_addr = (void *) (ai + 1); @@ -1144,7 +1122,7 @@ gaih_inet (const char *name, const struct gaih_service *service, struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) ai->ai_addr; - sin6p->sin6_port = st2->port; + sin6p->sin6_port = st[i].port; sin6p->sin6_flowinfo = 0; memcpy (&sin6p->sin6_addr, at2->addr, sizeof (struct in6_addr)); @@ -1154,7 +1132,7 @@ gaih_inet (const char *name, const struct gaih_service *service, { struct sockaddr_in *sinp = (struct sockaddr_in *) ai->ai_addr; - sinp->sin_port = st2->port; + sinp->sin_port = st[i].port; memcpy (&sinp->sin_addr, at2->addr, sizeof (struct in_addr)); memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero)); -- 2.35.1