unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] getaddrinfo spaghetti cleanups
@ 2021-08-03 21:29 Siddhesh Poyarekar via Libc-alpha
  2021-08-03 21:29 ` [PATCH 1/5] gaiconf_init: Refactor some bits for readability Siddhesh Poyarekar via Libc-alpha
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-08-03 21:29 UTC (permalink / raw)
  To: libc-alpha

This series cleans up a bunch of confusing gotos in various functions in
getaddrinfo.  The gotos jump from one condition to another and in
various directions, making code quite hard to read.

Siddhesh Poyarekar (5):
  gaiconf_init: Refactor some bits for readability
  gai_init: Avoid jumping from if condition to its else counterpart
  getaddrinfo: Refactor code for readability
  gaih_inet: Consolidate got_port code
  gaih_inet: Make process_list label into a function

 sysdeps/posix/getaddrinfo.c | 1067 ++++++++++++++++++-----------------
 1 file changed, 542 insertions(+), 525 deletions(-)

-- 
2.31.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] gaiconf_init: Refactor some bits for readability
  2021-08-03 21:29 [PATCH 0/5] getaddrinfo spaghetti cleanups Siddhesh Poyarekar via Libc-alpha
@ 2021-08-03 21:29 ` Siddhesh Poyarekar via Libc-alpha
  2021-08-03 21:29 ` [PATCH 2/5] gai_init: Avoid jumping from if condition to its else counterpart Siddhesh Poyarekar via Libc-alpha
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-08-03 21:29 UTC (permalink / raw)
  To: libc-alpha

Split out line processing for `label`, `precedence` and `scopev4` into
separate functions instead of the gotos.
---
 sysdeps/posix/getaddrinfo.c | 149 ++++++++++++++++++++----------------
 1 file changed, 84 insertions(+), 65 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 9f1cde27b5..f222c2a62f 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -1761,6 +1761,66 @@ scopecmp (const void *p1, const void *p2)
   return 1;
 }
 
+static bool
+add_prefixlist (struct prefixlist **listp, size_t *lenp, bool *nullbitsp,
+		char *val1, char *val2, char **pos)
+{
+  struct in6_addr prefix;
+  unsigned long int bits;
+  unsigned long int val;
+  char *endp;
+
+  bits = 128;
+  __set_errno (0);
+  char *cp = strchr (val1, '/');
+  if (cp != NULL)
+    *cp++ = '\0';
+  *pos = cp;
+  if (inet_pton (AF_INET6, val1, &prefix)
+      && (cp == NULL
+	  || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
+	  || errno != ERANGE)
+      && *endp == '\0'
+      && bits <= 128
+      && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
+	  || errno != ERANGE)
+      && *endp == '\0'
+      && val <= INT_MAX)
+    {
+      struct prefixlist *newp = malloc (sizeof (*newp));
+      if (newp == NULL)
+	return false;
+
+      memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
+      newp->entry.bits = bits;
+      newp->entry.val = val;
+      newp->next = *listp;
+      *listp = newp;
+      ++*lenp;
+      *nullbitsp |= bits == 0;
+    }
+  return true;
+}
+
+static bool
+add_scopelist (struct scopelist **listp, size_t *lenp, bool *nullbitsp,
+	       const struct in6_addr *prefixp, unsigned long int bits,
+	       unsigned long int val)
+{
+  struct scopelist *newp = malloc (sizeof (*newp));
+  if (newp == NULL)
+    return false;
+
+  newp->entry.netmask = htonl (bits != 96 ? (0xffffffff << (128 - bits)) : 0);
+  newp->entry.addr32 = (prefixp->s6_addr32[3] & newp->entry.netmask);
+  newp->entry.scope = val;
+  newp->next = *listp;
+  *listp = newp;
+  ++*lenp;
+  *nullbitsp |= bits == 96;
+
+  return true;
+}
 
 static void
 gaiconf_init (void)
@@ -1836,55 +1896,17 @@ gaiconf_init (void)
 	  /*  Ignore the rest of the line.  */
 	  *cp = '\0';
 
-	  struct prefixlist **listp;
-	  size_t *lenp;
-	  bool *nullbitsp;
 	  switch (cmdlen)
 	    {
 	    case 5:
 	      if (strcmp (cmd, "label") == 0)
 		{
-		  struct in6_addr prefix;
-		  unsigned long int bits;
-		  unsigned long int val;
-		  char *endp;
-
-		  listp = &labellist;
-		  lenp = &nlabellist;
-		  nullbitsp = &labellist_nullbits;
-
-		new_elem:
-		  bits = 128;
-		  __set_errno (0);
-		  cp = strchr (val1, '/');
-		  if (cp != NULL)
-		    *cp++ = '\0';
-		  if (inet_pton (AF_INET6, val1, &prefix)
-		      && (cp == NULL
-			  || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
-			  || errno != ERANGE)
-		      && *endp == '\0'
-		      && bits <= 128
-		      && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
-			  || errno != ERANGE)
-		      && *endp == '\0'
-		      && val <= INT_MAX)
+		  if (!add_prefixlist (&labellist, &nlabellist,
+				       &labellist_nullbits, val1, val2, &cp))
 		    {
-		      struct prefixlist *newp = malloc (sizeof (*newp));
-		      if (newp == NULL)
-			{
-			  free (line);
-			  fclose (fp);
-			  goto no_file;
-			}
-
-		      memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
-		      newp->entry.bits = bits;
-		      newp->entry.val = val;
-		      newp->next = *listp;
-		      *listp = newp;
-		      ++*lenp;
-		      *nullbitsp |= bits == 0;
+		      free (line);
+		      fclose (fp);
+		      goto no_file;
 		    }
 		}
 	      break;
@@ -1926,27 +1948,14 @@ gaiconf_init (void)
 			  && *endp == '\0'
 			  && val <= INT_MAX)
 			{
-			  struct scopelist *newp;
-			new_scope:
-			  newp = malloc (sizeof (*newp));
-			  if (newp == NULL)
+			  if (!add_scopelist (&scopelist, &nscopelist,
+					      &scopelist_nullbits, &prefix,
+					      bits, val))
 			    {
 			      free (line);
 			      fclose (fp);
 			      goto no_file;
 			    }
-
-			  newp->entry.netmask = htonl (bits != 96
-						       ? (0xffffffff
-							  << (128 - bits))
-						       : 0);
-			  newp->entry.addr32 = (prefix.s6_addr32[3]
-						& newp->entry.netmask);
-			  newp->entry.scope = val;
-			  newp->next = scopelist;
-			  scopelist = newp;
-			  ++nscopelist;
-			  scopelist_nullbits |= bits == 96;
 			}
 		    }
 		  else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
@@ -1960,8 +1969,14 @@ gaiconf_init (void)
 			   && *endp == '\0'
 			   && val <= INT_MAX)
 		    {
-		      bits += 96;
-		      goto new_scope;
+		      if (!add_scopelist (&scopelist, &nscopelist,
+					  &scopelist_nullbits, &prefix,
+					  bits + 96, val))
+			{
+			  free (line);
+			  fclose (fp);
+			  goto no_file;
+			}
 		    }
 		}
 	      break;
@@ -1969,10 +1984,14 @@ gaiconf_init (void)
 	    case 10:
 	      if (strcmp (cmd, "precedence") == 0)
 		{
-		  listp = &precedencelist;
-		  lenp = &nprecedencelist;
-		  nullbitsp = &precedencelist_nullbits;
-		  goto new_elem;
+		  if (!add_prefixlist (&precedencelist, &nprecedencelist,
+				       &precedencelist_nullbits, val1, val2,
+				       &cp))
+		    {
+		      free (line);
+		      fclose (fp);
+		      goto no_file;
+		    }
 		}
 	      break;
 	    }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] gai_init: Avoid jumping from if condition to its else counterpart
  2021-08-03 21:29 [PATCH 0/5] getaddrinfo spaghetti cleanups Siddhesh Poyarekar via Libc-alpha
  2021-08-03 21:29 ` [PATCH 1/5] gaiconf_init: Refactor some bits for readability Siddhesh Poyarekar via Libc-alpha
@ 2021-08-03 21:29 ` Siddhesh Poyarekar via Libc-alpha
  2021-08-03 21:29 ` [PATCH 3/5] getaddrinfo: Refactor code for readability Siddhesh Poyarekar via Libc-alpha
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-08-03 21:29 UTC (permalink / raw)
  To: libc-alpha

Clean up another antipattern where code flows from an if condition to
its else counterpart with a goto.

Most of the change in this patch is whitespace-only; a `git diff -b`
ought to show the actual logic changes.
---
 sysdeps/posix/getaddrinfo.c | 516 ++++++++++++++++++------------------
 1 file changed, 257 insertions(+), 259 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index f222c2a62f..180048eec2 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -1836,142 +1836,122 @@ gaiconf_init (void)
   bool scopelist_nullbits = false;
 
   FILE *fp = fopen (GAICONF_FNAME, "rce");
-  if (fp != NULL)
+  if (fp == NULL)
+    goto no_file;
+
+  struct __stat64_t64 st;
+  if (__fstat64_time64 (fileno (fp), &st) != 0)
     {
-      struct __stat64_t64 st;
-      if (__fstat64_time64 (fileno (fp), &st) != 0)
-	{
-	  fclose (fp);
-	  goto no_file;
-	}
+      fclose (fp);
+      goto no_file;
+    }
 
-      char *line = NULL;
-      size_t linelen = 0;
+  char *line = NULL;
+  size_t linelen = 0;
 
-      __fsetlocking (fp, FSETLOCKING_BYCALLER);
+  __fsetlocking (fp, FSETLOCKING_BYCALLER);
 
-      while (!feof_unlocked (fp))
+  while (!feof_unlocked (fp))
+    {
+      ssize_t n = __getline (&line, &linelen, fp);
+      if (n <= 0)
+	break;
+
+      /* Handle comments.  No escaping possible so this is easy.  */
+      char *cp = strchr (line, '#');
+      if (cp != NULL)
+	*cp = '\0';
+
+      cp = line;
+      while (isspace (*cp))
+	++cp;
+
+      char *cmd = cp;
+      while (*cp != '\0' && !isspace (*cp))
+	++cp;
+      size_t cmdlen = cp - cmd;
+
+      if (*cp != '\0')
+	*cp++ = '\0';
+      while (isspace (*cp))
+	++cp;
+
+      char *val1 = cp;
+      while (*cp != '\0' && !isspace (*cp))
+	++cp;
+      size_t val1len = cp - cmd;
+
+      /* We always need at least two values.  */
+      if (val1len == 0)
+	continue;
+
+      if (*cp != '\0')
+	*cp++ = '\0';
+      while (isspace (*cp))
+	++cp;
+
+      char *val2 = cp;
+      while (*cp != '\0' && !isspace (*cp))
+	++cp;
+
+      /*  Ignore the rest of the line.  */
+      *cp = '\0';
+
+      switch (cmdlen)
 	{
-	  ssize_t n = __getline (&line, &linelen, fp);
-	  if (n <= 0)
-	    break;
-
-	  /* Handle comments.  No escaping possible so this is easy.  */
-	  char *cp = strchr (line, '#');
-	  if (cp != NULL)
-	    *cp = '\0';
-
-	  cp = line;
-	  while (isspace (*cp))
-	    ++cp;
-
-	  char *cmd = cp;
-	  while (*cp != '\0' && !isspace (*cp))
-	    ++cp;
-	  size_t cmdlen = cp - cmd;
-
-	  if (*cp != '\0')
-	    *cp++ = '\0';
-	  while (isspace (*cp))
-	    ++cp;
-
-	  char *val1 = cp;
-	  while (*cp != '\0' && !isspace (*cp))
-	    ++cp;
-	  size_t val1len = cp - cmd;
-
-	  /* We always need at least two values.  */
-	  if (val1len == 0)
-	    continue;
-
-	  if (*cp != '\0')
-	    *cp++ = '\0';
-	  while (isspace (*cp))
-	    ++cp;
-
-	  char *val2 = cp;
-	  while (*cp != '\0' && !isspace (*cp))
-	    ++cp;
-
-	  /*  Ignore the rest of the line.  */
-	  *cp = '\0';
-
-	  switch (cmdlen)
+	case 5:
+	  if (strcmp (cmd, "label") == 0)
 	    {
-	    case 5:
-	      if (strcmp (cmd, "label") == 0)
+	      if (!add_prefixlist (&labellist, &nlabellist,
+				   &labellist_nullbits, val1, val2, &cp))
 		{
-		  if (!add_prefixlist (&labellist, &nlabellist,
-				       &labellist_nullbits, val1, val2, &cp))
-		    {
-		      free (line);
-		      fclose (fp);
-		      goto no_file;
-		    }
+		  free (line);
+		  fclose (fp);
+		  goto no_file;
 		}
-	      break;
+	    }
+	  break;
 
-	    case 6:
-	      if (strcmp (cmd, "reload") == 0)
-		{
-		  gaiconf_reload_flag = strcmp (val1, "yes") == 0;
-		  if (gaiconf_reload_flag)
-		    gaiconf_reload_flag_ever_set = 1;
-		}
-	      break;
+	case 6:
+	  if (strcmp (cmd, "reload") == 0)
+	    {
+	      gaiconf_reload_flag = strcmp (val1, "yes") == 0;
+	      if (gaiconf_reload_flag)
+		gaiconf_reload_flag_ever_set = 1;
+	    }
+	  break;
 
-	    case 7:
-	      if (strcmp (cmd, "scopev4") == 0)
+	case 7:
+	  if (strcmp (cmd, "scopev4") == 0)
+	    {
+	      struct in6_addr prefix;
+	      unsigned long int bits;
+	      unsigned long int val;
+	      char *endp;
+
+	      bits = 32;
+	      __set_errno (0);
+	      cp = strchr (val1, '/');
+	      if (cp != NULL)
+		*cp++ = '\0';
+	      if (inet_pton (AF_INET6, val1, &prefix))
 		{
-		  struct in6_addr prefix;
-		  unsigned long int bits;
-		  unsigned long int val;
-		  char *endp;
-
-		  bits = 32;
-		  __set_errno (0);
-		  cp = strchr (val1, '/');
-		  if (cp != NULL)
-		    *cp++ = '\0';
-		  if (inet_pton (AF_INET6, val1, &prefix))
-		    {
-		      bits = 128;
-		      if (IN6_IS_ADDR_V4MAPPED (&prefix)
-			  && (cp == NULL
-			      || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
-			      || errno != ERANGE)
-			  && *endp == '\0'
-			  && bits >= 96
-			  && bits <= 128
-			  && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
-			      || errno != ERANGE)
-			  && *endp == '\0'
-			  && val <= INT_MAX)
-			{
-			  if (!add_scopelist (&scopelist, &nscopelist,
-					      &scopelist_nullbits, &prefix,
-					      bits, val))
-			    {
-			      free (line);
-			      fclose (fp);
-			      goto no_file;
-			    }
-			}
-		    }
-		  else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
-			   && (cp == NULL
-			       || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
-			       || errno != ERANGE)
-			   && *endp == '\0'
-			   && bits <= 32
-			   && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
-			       || errno != ERANGE)
-			   && *endp == '\0'
-			   && val <= INT_MAX)
+		  bits = 128;
+		  if (IN6_IS_ADDR_V4MAPPED (&prefix)
+		      && (cp == NULL
+			  || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
+			  || errno != ERANGE)
+		      && *endp == '\0'
+		      && bits >= 96
+		      && bits <= 128
+		      && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
+			  || errno != ERANGE)
+		      && *endp == '\0'
+		      && val <= INT_MAX)
 		    {
 		      if (!add_scopelist (&scopelist, &nscopelist,
 					  &scopelist_nullbits, &prefix,
-					  bits + 96, val))
+					  bits, val))
 			{
 			  free (line);
 			  fclose (fp);
@@ -1979,173 +1959,191 @@ gaiconf_init (void)
 			}
 		    }
 		}
-	      break;
-
-	    case 10:
-	      if (strcmp (cmd, "precedence") == 0)
+	      else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
+		       && (cp == NULL
+			   || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
+			   || errno != ERANGE)
+		       && *endp == '\0'
+		       && bits <= 32
+		       && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
+			   || errno != ERANGE)
+		       && *endp == '\0'
+		       && val <= INT_MAX)
 		{
-		  if (!add_prefixlist (&precedencelist, &nprecedencelist,
-				       &precedencelist_nullbits, val1, val2,
-				       &cp))
+		  if (!add_scopelist (&scopelist, &nscopelist,
+				      &scopelist_nullbits, &prefix,
+				      bits + 96, val))
 		    {
 		      free (line);
 		      fclose (fp);
 		      goto no_file;
 		    }
 		}
-	      break;
-	    }
-	}
-
-      free (line);
-
-      fclose (fp);
-
-      /* Create the array for the labels.  */
-      struct prefixentry *new_labels;
-      if (nlabellist > 0)
-	{
-	  if (!labellist_nullbits)
-	    ++nlabellist;
-	  new_labels = malloc (nlabellist * sizeof (*new_labels));
-	  if (new_labels == NULL)
-	    goto no_file;
-
-	  int i = nlabellist;
-	  if (!labellist_nullbits)
-	    {
-	      --i;
-	      memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
-	      new_labels[i].bits = 0;
-	      new_labels[i].val = 1;
 	    }
+	  break;
 
-	  struct prefixlist *l = labellist;
-	  while (i-- > 0)
+	case 10:
+	  if (strcmp (cmd, "precedence") == 0)
 	    {
-	      new_labels[i] = l->entry;
-	      l = l->next;
+	      if (!add_prefixlist (&precedencelist, &nprecedencelist,
+				   &precedencelist_nullbits, val1, val2,
+				   &cp))
+		{
+		  free (line);
+		  fclose (fp);
+		  goto no_file;
+		}
 	    }
-	  free_prefixlist (labellist);
-	  labellist = NULL;
-
-	  /* Sort the entries so that the most specific ones are at
-	     the beginning.  */
-	  qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
+	  break;
 	}
-      else
-	new_labels = (struct prefixentry *) default_labels;
-
-      struct prefixentry *new_precedence;
-      if (nprecedencelist > 0)
-	{
-	  if (!precedencelist_nullbits)
-	    ++nprecedencelist;
-	  new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
-	  if (new_precedence == NULL)
-	    {
-	      if (new_labels != default_labels)
-		free (new_labels);
-	      goto no_file;
-	    }
+    }
 
-	  int i = nprecedencelist;
-	  if (!precedencelist_nullbits)
-	    {
-	      --i;
-	      memset (&new_precedence[i].prefix, '\0',
-		      sizeof (struct in6_addr));
-	      new_precedence[i].bits = 0;
-	      new_precedence[i].val = 40;
-	    }
+  free (line);
 
-	  struct prefixlist *l = precedencelist;
-	  while (i-- > 0)
-	    {
-	      new_precedence[i] = l->entry;
-	      l = l->next;
-	    }
-	  free_prefixlist (precedencelist);
-	  precedencelist = NULL;
+  fclose (fp);
 
-	  /* Sort the entries so that the most specific ones are at
-	     the beginning.  */
-	  qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
-		 prefixcmp);
+  /* Create the array for the labels.  */
+  struct prefixentry *new_labels;
+  if (nlabellist > 0)
+    {
+      if (!labellist_nullbits)
+	++nlabellist;
+      new_labels = malloc (nlabellist * sizeof (*new_labels));
+      if (new_labels == NULL)
+	goto no_file;
+
+      int i = nlabellist;
+      if (!labellist_nullbits)
+	{
+	  --i;
+	  memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
+	  new_labels[i].bits = 0;
+	  new_labels[i].val = 1;
 	}
-      else
-	new_precedence = (struct prefixentry *) default_precedence;
 
-      struct scopeentry *new_scopes;
-      if (nscopelist > 0)
+      struct prefixlist *l = labellist;
+      while (i-- > 0)
 	{
-	  if (!scopelist_nullbits)
-	    ++nscopelist;
-	  new_scopes = malloc (nscopelist * sizeof (*new_scopes));
-	  if (new_scopes == NULL)
-	    {
-	      if (new_labels != default_labels)
-		free (new_labels);
-	      if (new_precedence != default_precedence)
-		free (new_precedence);
-	      goto no_file;
-	    }
-
-	  int i = nscopelist;
-	  if (!scopelist_nullbits)
-	    {
-	      --i;
-	      new_scopes[i].addr32 = 0;
-	      new_scopes[i].netmask = 0;
-	      new_scopes[i].scope = 14;
-	    }
+	  new_labels[i] = l->entry;
+	  l = l->next;
+	}
+      free_prefixlist (labellist);
+      labellist = NULL;
 
-	  struct scopelist *l = scopelist;
-	  while (i-- > 0)
-	    {
-	      new_scopes[i] = l->entry;
-	      l = l->next;
-	    }
-	  free_scopelist (scopelist);
+      /* Sort the entries so that the most specific ones are at
+	 the beginning.  */
+      qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
+    }
+  else
+    new_labels = (struct prefixentry *) default_labels;
 
-	  /* Sort the entries so that the most specific ones are at
-	     the beginning.  */
-	  qsort (new_scopes, nscopelist, sizeof (*new_scopes),
-		 scopecmp);
+  struct prefixentry *new_precedence;
+  if (nprecedencelist > 0)
+    {
+      if (!precedencelist_nullbits)
+	++nprecedencelist;
+      new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
+      if (new_precedence == NULL)
+	{
+	  if (new_labels != default_labels)
+	    free (new_labels);
+	  goto no_file;
 	}
-      else
-	new_scopes = (struct scopeentry *) default_scopes;
-
-      /* Now we are ready to replace the values.  */
-      const struct prefixentry *old = labels;
-      labels = new_labels;
-      if (old != default_labels)
-	free ((void *) old);
 
-      old = precedence;
-      precedence = new_precedence;
-      if (old != default_precedence)
-	free ((void *) old);
+      int i = nprecedencelist;
+      if (!precedencelist_nullbits)
+	{
+	  --i;
+	  memset (&new_precedence[i].prefix, '\0',
+		  sizeof (struct in6_addr));
+	  new_precedence[i].bits = 0;
+	  new_precedence[i].val = 40;
+	}
 
-      const struct scopeentry *oldscope = scopes;
-      scopes = new_scopes;
-      if (oldscope != default_scopes)
-	free ((void *) oldscope);
+      struct prefixlist *l = precedencelist;
+      while (i-- > 0)
+	{
+	  new_precedence[i] = l->entry;
+	  l = l->next;
+	}
+      free_prefixlist (precedencelist);
+      precedencelist = NULL;
 
-      save_gaiconf_mtime (&st);
+      /* Sort the entries so that the most specific ones are at
+	 the beginning.  */
+      qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
+	     prefixcmp);
     }
   else
+    new_precedence = (struct prefixentry *) default_precedence;
+
+  struct scopeentry *new_scopes;
+  if (nscopelist > 0)
     {
-    no_file:
-      free_prefixlist (labellist);
-      free_prefixlist (precedencelist);
+      if (!scopelist_nullbits)
+	++nscopelist;
+      new_scopes = malloc (nscopelist * sizeof (*new_scopes));
+      if (new_scopes == NULL)
+	{
+	  if (new_labels != default_labels)
+	    free (new_labels);
+	  if (new_precedence != default_precedence)
+	    free (new_precedence);
+	  goto no_file;
+	}
+
+      int i = nscopelist;
+      if (!scopelist_nullbits)
+	{
+	  --i;
+	  new_scopes[i].addr32 = 0;
+	  new_scopes[i].netmask = 0;
+	  new_scopes[i].scope = 14;
+	}
+
+      struct scopelist *l = scopelist;
+      while (i-- > 0)
+	{
+	  new_scopes[i] = l->entry;
+	  l = l->next;
+	}
       free_scopelist (scopelist);
 
-      /* If we previously read the file but it is gone now, free the
-	 old data and use the builtin one.  Leave the reload flag
-	 alone.  */
-      fini ();
+      /* Sort the entries so that the most specific ones are at
+	 the beginning.  */
+      qsort (new_scopes, nscopelist, sizeof (*new_scopes),
+	     scopecmp);
     }
+  else
+    new_scopes = (struct scopeentry *) default_scopes;
+
+  /* Now we are ready to replace the values.  */
+  const struct prefixentry *old = labels;
+  labels = new_labels;
+  if (old != default_labels)
+    free ((void *) old);
+
+  old = precedence;
+  precedence = new_precedence;
+  if (old != default_precedence)
+    free ((void *) old);
+
+  const struct scopeentry *oldscope = scopes;
+  scopes = new_scopes;
+  if (oldscope != default_scopes)
+    free ((void *) oldscope);
+
+  save_gaiconf_mtime (&st);
+  return;
+
+no_file:
+  free_prefixlist (labellist);
+  free_prefixlist (precedencelist);
+  free_scopelist (scopelist);
+
+  /* If we previously read the file but it is gone now, free the old data and
+     use the builtin one.  Leave the reload flag alone.  */
+  fini ();
 }
 
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] getaddrinfo: Refactor code for readability
  2021-08-03 21:29 [PATCH 0/5] getaddrinfo spaghetti cleanups Siddhesh Poyarekar via Libc-alpha
  2021-08-03 21:29 ` [PATCH 1/5] gaiconf_init: Refactor some bits for readability Siddhesh Poyarekar via Libc-alpha
  2021-08-03 21:29 ` [PATCH 2/5] gai_init: Avoid jumping from if condition to its else counterpart Siddhesh Poyarekar via Libc-alpha
@ 2021-08-03 21:29 ` Siddhesh Poyarekar via Libc-alpha
  2021-08-03 21:29 ` [PATCH 4/5] gaih_inet: Consolidate got_port code Siddhesh Poyarekar via Libc-alpha
  2021-08-03 21:29 ` [PATCH 5/5] gaih_inet: Make process_list label into a function Siddhesh Poyarekar via Libc-alpha
  4 siblings, 0 replies; 6+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-08-03 21:29 UTC (permalink / raw)
  To: libc-alpha

The close_retry goto jump is confusing and clumsy to read, so refactor
the code a bit to make it easier to follow.
---
 sysdeps/posix/getaddrinfo.c | 46 +++++++++++++++++++++++++++----------
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 180048eec2..fd05d53c1a 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -2156,6 +2156,37 @@ gaiconf_reload (void)
     gaiconf_init ();
 }
 
+static bool
+try_connect (int *fdp, int *afp, struct sockaddr_in6 *source_addrp,
+	     const struct sockaddr *addr, socklen_t addrlen, int family)
+{
+  int fd = *fdp;
+  int af = *afp;
+  socklen_t sl = sizeof (*source_addrp);
+  bool retry = false;
+
+  do
+    {
+      if (fd != -1 && __connect (fd, addr, addrlen) == 0
+	  && __getsockname (fd, (struct sockaddr *) source_addrp, &sl) == 0)
+	return true;
+      else if (errno == EAFNOSUPPORT && af == AF_INET6 && family == AF_INET)
+	{
+	  /* This could mean IPv6 sockets are IPv6-only.  */
+	  if (fd != -1)
+	    __close_nocancel_nostatus (fd);
+	  *afp = af = AF_INET;
+	  *fdp = fd = __socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC,
+				IPPROTO_IP);
+	  retry = true;
+	}
+      else
+	return false;
+    }
+  while (retry);
+
+  __builtin_unreachable ();
+}
 
 int
 getaddrinfo (const char *name, const char *service,
@@ -2346,7 +2377,6 @@ getaddrinfo (const char *name, const char *service,
 	      if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
 		{
 		  if (fd != -1)
-		  close_retry:
 		    __close_nocancel_nostatus (fd);
 		  af = q->ai_family;
 		  fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
@@ -2358,14 +2388,10 @@ getaddrinfo (const char *name, const char *service,
 		  __connect (fd, &sa, sizeof (sa));
 		}
 
-	      socklen_t sl = sizeof (results[i].source_addr);
-	      if (fd != -1
-		  && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
-		  && __getsockname (fd,
-				    (struct sockaddr *) &results[i].source_addr,
-				    &sl) == 0)
+	      if (try_connect (&fd, &af, &results[i].source_addr, q->ai_addr,
+			       q->ai_addrlen, q->ai_family))
 		{
-		  results[i].source_addr_len = sl;
+		  results[i].source_addr_len = sizeof (results[i].source_addr);
 		  results[i].got_source_addr = true;
 
 		  if (in6ai != NULL)
@@ -2430,10 +2456,6 @@ getaddrinfo (const char *name, const char *service,
 		      results[i].source_addr_len = sizeof (struct sockaddr_in);
 		    }
 		}
-	      else if (errno == EAFNOSUPPORT && af == AF_INET6
-		       && q->ai_family == AF_INET)
-		/* This could mean IPv6 sockets are IPv6-only.  */
-		goto close_retry;
 	      else
 		/* Just make sure that if we have to process the same
 		   address again we do not copy any memory.  */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] gaih_inet: Consolidate got_port code
  2021-08-03 21:29 [PATCH 0/5] getaddrinfo spaghetti cleanups Siddhesh Poyarekar via Libc-alpha
                   ` (2 preceding siblings ...)
  2021-08-03 21:29 ` [PATCH 3/5] getaddrinfo: Refactor code for readability Siddhesh Poyarekar via Libc-alpha
@ 2021-08-03 21:29 ` Siddhesh Poyarekar via Libc-alpha
  2021-08-03 21:29 ` [PATCH 5/5] gaih_inet: Make process_list label into a function Siddhesh Poyarekar via Libc-alpha
  4 siblings, 0 replies; 6+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-08-03 21:29 UTC (permalink / raw)
  To: libc-alpha

Refactor the code to remove the unnecessary got_port goto across
conditional branches.
---
 sysdeps/posix/getaddrinfo.c | 105 +++++++++++++++++-------------------
 1 file changed, 48 insertions(+), 57 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index fd05d53c1a..220cd41cde 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -359,65 +359,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	}
     }
 
-  int port = 0;
-  if (service != NULL)
-    {
-      if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
-	return -EAI_SERVICE;
-
-      if (service->num < 0)
-	{
-	  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;
-
-		  if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
-		    continue;
+  if (service != NULL && (tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
+    return -EAI_SERVICE;
 
-		  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 = (struct gaih_servtuple *)
-		    alloca_account (sizeof (struct gaih_servtuple),
-				    alloca_used);
-
-		  if (gaih_inet_serv (service->name,
-				      tp, req, newp, tmpbuf) != 0)
-		    continue;
-
-		  *pst = newp;
-		  pst = &(newp->next);
-		}
-	      if (st == (struct gaih_servtuple *) &nullserv)
-		return -EAI_SERVICE;
-	    }
-	}
-      else
-	{
-	  port = htons (service->num);
-	  goto got_port;
-	}
-    }
-  else
+  if (service == NULL || service->num >= 0)
     {
-    got_port:
+      int port = service != NULL ? htons (service->num) : 0;
 
       if (req->ai_socktype || req->ai_protocol)
 	{
@@ -450,6 +397,50 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	      }
 	}
     }
+  else
+    {
+      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;
+
+	      if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
+		continue;
+
+	      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 = (struct gaih_servtuple *)
+		alloca_account (sizeof (struct gaih_servtuple),
+				alloca_used);
+
+	      if (gaih_inet_serv (service->name,
+				  tp, req, newp, tmpbuf) != 0)
+		continue;
+
+	      *pst = newp;
+	      pst = &(newp->next);
+	    }
+	  if (st == (struct gaih_servtuple *) &nullserv)
+	    return -EAI_SERVICE;
+	}
+    }
 
   bool malloc_name = false;
   struct gaih_addrtuple *addrmem = NULL;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] gaih_inet: Make process_list label into a function
  2021-08-03 21:29 [PATCH 0/5] getaddrinfo spaghetti cleanups Siddhesh Poyarekar via Libc-alpha
                   ` (3 preceding siblings ...)
  2021-08-03 21:29 ` [PATCH 4/5] gaih_inet: Consolidate got_port code Siddhesh Poyarekar via Libc-alpha
@ 2021-08-03 21:29 ` Siddhesh Poyarekar via Libc-alpha
  4 siblings, 0 replies; 6+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2021-08-03 21:29 UTC (permalink / raw)
  To: libc-alpha

process_list is the final operation in gaih_inet where the result is
written out.  Factor it out into a separate function and call it at
the end if there have been no errors.  Rename the free_and_return
label to done and use it to jump to the end of gaih_inet, where
process_list is called if return is non-zero.

This change makes the code more linear and slightly clearer to follow.
This needs still more rework to make the function simpler to
understand.
---
 sysdeps/posix/getaddrinfo.c | 311 +++++++++++++++++-------------------
 1 file changed, 149 insertions(+), 162 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 220cd41cde..3afac87fa2 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -256,7 +256,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
 	{								      \
 	  __resolv_context_put (res_ctx);				      \
 	  result = -EAI_MEMORY;						      \
-	  goto free_and_return;						      \
+	  goto done;							      \
 	}								      \
     }									      \
   if (status == NSS_STATUS_NOTFOUND					      \
@@ -266,7 +266,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
 	{								      \
 	  __resolv_context_put (res_ctx);				      \
 	  result = -EAI_SYSTEM;						      \
-	  goto free_and_return;						      \
+	  goto done;							      \
 	}								      \
       if (h_errno == TRY_AGAIN)						      \
 	no_data = EAI_AGAIN;						      \
@@ -279,7 +279,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
 	{								      \
 	  __resolv_context_put (res_ctx);				      \
 	  result = -EAI_SYSTEM;						      \
-	  goto free_and_return;						      \
+	  goto done;							      \
 	}								      \
       *pat = addrmem;							      \
 									      \
@@ -290,7 +290,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
 	    {								      \
 	      __resolv_context_put (res_ctx);				      \
 	      result = -EAI_SYSTEM;					      \
-	      goto free_and_return;					      \
+	      goto done;						      \
 	    }								      \
 	  canon = canonbuf;						      \
 	}								      \
@@ -323,6 +323,123 @@ getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
   return __strdup (name);
 }
 
+static int
+process_list (const struct addrinfo *req, struct gaih_addrtuple *at,
+	      struct gaih_servtuple *st, const char *canon, bool canon_alloc,
+	      bool got_ipv6, struct addrinfo **pai, unsigned int *naddrs)
+{
+  struct gaih_servtuple *st2;
+  struct gaih_addrtuple *at2 = at;
+  size_t socklen;
+  sa_family_t family;
+
+  /*
+     buffer is the size of an unformatted IPv6 address in printable format.
+     */
+  for (at2 = at; at2 != NULL; at2 = at2->next)
+    {
+      /* Only the first entry gets the canonical name.  */
+      if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
+	{
+	  bool do_idn = req->ai_flags & AI_CANONIDN;
+	  if (do_idn)
+	    {
+	      char *out;
+	      int rc = __idna_from_dns_encoding (canon, &out);
+	      if (rc == 0)
+		canon = out;
+	      else if (rc == EAI_IDN_ENCODE)
+		/* Use the punycode name as a fallback.  */
+		do_idn = false;
+	      else
+		return -rc;
+	    }
+	  if (!do_idn)
+	    {
+	      if (!canon_alloc)
+		{
+		  canon = __strdup (canon);
+		  if (canon == NULL)
+		    return -EAI_MEMORY;
+		}
+	    }
+	}
+
+      family = at2->family;
+      if (family == AF_INET6)
+	{
+	  socklen = sizeof (struct sockaddr_in6);
+
+	  /* If we looked up IPv4 mapped address discard them here if
+	     the caller isn't interested in all address and we have
+	     found at least one IPv6 address.  */
+	  if (got_ipv6
+	      && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
+	      && IN6_IS_ADDR_V4MAPPED (at2->addr))
+	    continue;
+	}
+      else
+	socklen = sizeof (struct sockaddr_in);
+
+      for (st2 = st; st2 != NULL; st2 = st2->next)
+	{
+	  struct addrinfo *ai;
+	  ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
+	  if (ai == NULL)
+	    {
+	      free ((char *) canon);
+	      return -EAI_MEMORY;
+	    }
+
+	  ai->ai_flags = req->ai_flags;
+	  ai->ai_family = family;
+	  ai->ai_socktype = st2->socktype;
+	  ai->ai_protocol = st2->protocol;
+	  ai->ai_addrlen = socklen;
+	  ai->ai_addr = (void *) (ai + 1);
+
+	  /* We only add the canonical name once.  */
+	  ai->ai_canonname = (char *) canon;
+	  canon = NULL;
+
+#ifdef _HAVE_SA_LEN
+	  ai->ai_addr->sa_len = socklen;
+#endif /* _HAVE_SA_LEN */
+	  ai->ai_addr->sa_family = family;
+
+	  /* In case of an allocation error the list must be NULL
+	     terminated.  */
+	  ai->ai_next = NULL;
+
+	  if (family == AF_INET6)
+	    {
+	      struct sockaddr_in6 *sin6p =
+		(struct sockaddr_in6 *) ai->ai_addr;
+
+	      sin6p->sin6_port = st2->port;
+	      sin6p->sin6_flowinfo = 0;
+	      memcpy (&sin6p->sin6_addr,
+		      at2->addr, sizeof (struct in6_addr));
+	      sin6p->sin6_scope_id = at2->scopeid;
+	    }
+	  else
+	    {
+	      struct sockaddr_in *sinp =
+		(struct sockaddr_in *) ai->ai_addr;
+	      sinp->sin_port = st2->port;
+	      memcpy (&sinp->sin_addr,
+		      at2->addr, sizeof (struct in_addr));
+	      memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
+	    }
+
+	  pai = &(ai->ai_next);
+	}
+
+      ++*naddrs;
+    }
+  return 0;
+}
+
 static int
 gaih_inet (const char *name, const struct gaih_service *service,
 	   const struct addrinfo *req, struct addrinfo **pai,
@@ -479,7 +596,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	  else
 	    {
 	      result = -EAI_ADDRFAMILY;
-	      goto free_and_return;
+	      goto done;
 	    }
 
 	  if (req->ai_flags & AI_CANONNAME)
@@ -507,7 +624,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	      else
 		{
 		  result = -EAI_ADDRFAMILY;
-		  goto free_and_return;
+		  goto done;
 		}
 
 	      if (scope_delim != NULL
@@ -516,7 +633,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 					   &at->scopeid) != 0)
 		{
 		  result = -EAI_NONAME;
-		  goto free_and_return;
+		  goto done;
 		}
 
 	      if (req->ai_flags & AI_CANONNAME)
@@ -555,7 +672,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		  if (!scratch_buffer_grow (tmpbuf))
 		    {
 		      result = -EAI_MEMORY;
-		      goto free_and_return;
+		      goto done;
 		    }
 		}
 
@@ -568,7 +685,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 			  (req, AF_INET, h, &addrmem))
 			{
 			  result = -EAI_MEMORY;
-			  goto free_and_return;
+			  goto done;
 			}
 		      *pat = addrmem;
 		    }
@@ -578,7 +695,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 			result = -EAI_NODATA;
 		      else
 			result = -EAI_NONAME;
-		      goto free_and_return;
+		      goto done;
 		    }
 		}
 	      else
@@ -592,10 +709,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		       The name is known, though.  */
 		    result = -EAI_NODATA;
 
-		  goto free_and_return;
+		  goto done;
 		}
 
-	      goto process_list;
+	      if (at->family == AF_UNSPEC)
+		result = -EAI_NONAME;
+
+	      goto done;
 	    }
 
 #ifdef USE_NSCD
@@ -619,7 +739,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		  if (addrmem == NULL)
 		    {
 		      result = -EAI_MEMORY;
-		      goto free_and_return;
+		      goto done;
 		    }
 
 		  struct gaih_addrtuple *addrfree = addrmem;
@@ -654,7 +774,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 			  if (canonbuf == NULL)
 			    {
 			      result = -EAI_MEMORY;
-			      goto free_and_return;
+			      goto done;
 			    }
 			  canon = (*pat)->name = canonbuf;
 			}
@@ -687,16 +807,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		  free (air);
 
 		  if (at->family == AF_UNSPEC)
-		    {
-		      result = -EAI_NONAME;
-		      goto free_and_return;
-		    }
+		    result = -EAI_NONAME;
 
-		  goto process_list;
+		  goto done;
 		}
 	      else if (err == 0)
 		/* The database contains a negative entry.  */
-		goto free_and_return;
+		goto done;
 	      else if (__nss_not_use_nscd_hosts == 0)
 		{
 		  if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
@@ -706,7 +823,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		  else
 		    result = -EAI_SYSTEM;
 
-		  goto free_and_return;
+		  goto done;
 		}
 	    }
 #endif
@@ -755,7 +872,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 			{
 			  __resolv_context_put (res_ctx);
 			  result = -EAI_MEMORY;
-			  goto free_and_return;
+			  goto done;
 			}
 		    }
 
@@ -854,7 +971,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 				{
 				  __resolv_context_put (res_ctx);
 				  result = -EAI_MEMORY;
-				  goto free_and_return;
+				  goto done;
 				}
 			      canon = canonbuf;
 			    }
@@ -903,7 +1020,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	      && h_errno == NETDB_INTERNAL)
 	    {
 	      result = -EAI_SYSTEM;
-	      goto free_and_return;
+	      goto done;
 	    }
 
 	  if (no_data != 0 && no_inet6_data != 0)
@@ -916,16 +1033,12 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		   is known, though.  */
 		result = -EAI_NODATA;
 
-	      goto free_and_return;
+	      goto done;
 	    }
 	}
 
-    process_list:
       if (at->family == AF_UNSPEC)
-	{
-	  result = -EAI_NONAME;
-	  goto free_and_return;
-	}
+	result = -EAI_NONAME;
     }
   else
     {
@@ -955,142 +1068,16 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	}
     }
 
-  {
-    struct gaih_servtuple *st2;
-    struct gaih_addrtuple *at2 = at;
-    size_t socklen;
-    sa_family_t family;
-
-    /*
-      buffer is the size of an unformatted IPv6 address in printable format.
-     */
-    while (at2 != NULL)
-      {
-	/* Only the first entry gets the canonical name.  */
-	if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
-	  {
-	    if (canon == NULL)
-	      /* If the canonical name cannot be determined, use
-		 the passed in string.  */
-	      canon = orig_name;
-
-	    bool do_idn = req->ai_flags & AI_CANONIDN;
-	    if (do_idn)
-	      {
-		char *out;
-		int rc = __idna_from_dns_encoding (canon, &out);
-		if (rc == 0)
-		  canon = out;
-		else if (rc == EAI_IDN_ENCODE)
-		  /* Use the punycode name as a fallback.  */
-		  do_idn = false;
-		else
-		  {
-		    result = -rc;
-		    goto free_and_return;
-		  }
-	      }
-	    if (!do_idn)
-	      {
-		if (canonbuf != NULL)
-		  /* We already allocated the string using malloc, but
-		     the buffer is now owned by canon.  */
-		  canonbuf = NULL;
-		else
-		  {
-		    canon = __strdup (canon);
-		    if (canon == NULL)
-		      {
-			result = -EAI_MEMORY;
-			goto free_and_return;
-		      }
-		  }
-	      }
-	  }
-
-	family = at2->family;
-	if (family == AF_INET6)
-	  {
-	    socklen = sizeof (struct sockaddr_in6);
-
-	    /* If we looked up IPv4 mapped address discard them here if
-	       the caller isn't interested in all address and we have
-	       found at least one IPv6 address.  */
-	    if (got_ipv6
-		&& (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
-		&& IN6_IS_ADDR_V4MAPPED (at2->addr))
-	      goto ignore;
-	  }
-	else
-	  socklen = sizeof (struct sockaddr_in);
-
-	for (st2 = st; st2 != NULL; st2 = st2->next)
-	  {
-	    struct addrinfo *ai;
-	    ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
-	    if (ai == NULL)
-	      {
-		free ((char *) canon);
-		result = -EAI_MEMORY;
-		goto free_and_return;
-	      }
-
-	    ai->ai_flags = req->ai_flags;
-	    ai->ai_family = family;
-	    ai->ai_socktype = st2->socktype;
-	    ai->ai_protocol = st2->protocol;
-	    ai->ai_addrlen = socklen;
-	    ai->ai_addr = (void *) (ai + 1);
-
-	    /* We only add the canonical name once.  */
-	    ai->ai_canonname = (char *) canon;
-	    canon = NULL;
-
-#ifdef _HAVE_SA_LEN
-	    ai->ai_addr->sa_len = socklen;
-#endif /* _HAVE_SA_LEN */
-	    ai->ai_addr->sa_family = family;
-
-	    /* In case of an allocation error the list must be NULL
-	       terminated.  */
-	    ai->ai_next = NULL;
-
-	    if (family == AF_INET6)
-	      {
-		struct sockaddr_in6 *sin6p =
-		  (struct sockaddr_in6 *) ai->ai_addr;
-
-		sin6p->sin6_port = st2->port;
-		sin6p->sin6_flowinfo = 0;
-		memcpy (&sin6p->sin6_addr,
-			at2->addr, sizeof (struct in6_addr));
-		sin6p->sin6_scope_id = at2->scopeid;
-	      }
-	    else
-	      {
-		struct sockaddr_in *sinp =
-		  (struct sockaddr_in *) ai->ai_addr;
-		sinp->sin_port = st2->port;
-		memcpy (&sinp->sin_addr,
-			at2->addr, sizeof (struct in_addr));
-		memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
-	      }
-
-	    pai = &(ai->ai_next);
-	  }
-
-	++*naddrs;
-
-      ignore:
-	at2 = at2->next;
-      }
-  }
+done:
+  if (result == 0)
+    result = process_list (req, at, st, canon ?: orig_name, canonbuf != NULL,
+			   got_ipv6, pai, naddrs);
 
- free_and_return:
   if (malloc_name)
     free ((char *) name);
   free (addrmem);
-  free (canonbuf);
+  if (result != 0)
+    free (canonbuf);
 
   return result;
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-08-03 21:33 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-03 21:29 [PATCH 0/5] getaddrinfo spaghetti cleanups Siddhesh Poyarekar via Libc-alpha
2021-08-03 21:29 ` [PATCH 1/5] gaiconf_init: Refactor some bits for readability Siddhesh Poyarekar via Libc-alpha
2021-08-03 21:29 ` [PATCH 2/5] gai_init: Avoid jumping from if condition to its else counterpart Siddhesh Poyarekar via Libc-alpha
2021-08-03 21:29 ` [PATCH 3/5] getaddrinfo: Refactor code for readability Siddhesh Poyarekar via Libc-alpha
2021-08-03 21:29 ` [PATCH 4/5] gaih_inet: Consolidate got_port code Siddhesh Poyarekar via Libc-alpha
2021-08-03 21:29 ` [PATCH 5/5] gaih_inet: Make process_list label into a function Siddhesh Poyarekar via Libc-alpha

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).