Unverified Commit 12e564ca authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

parse_proxy: use the IPv6 zone id if given

If the proxy string is given as an IPv6 numerical address with a zone
id, make sure to use that for the connect to the proxy.

Reported-by: Edmond Yu

Fixes #3482
Closes #3918
parent 885ce314
Loading
Loading
Loading
Loading
+36 −25
Original line number Original line Diff line number Diff line
@@ -1883,6 +1883,40 @@ CURLcode Curl_uc_to_curlcode(CURLUcode uc)
  }
  }
}
}


/*
 * If the URL was set with an IPv6 numerical address with a zone id part, set
 * the scope_id based on that!
 */

static void zonefrom_url(CURLU *uh, struct connectdata *conn)
{
  char *zoneid;
  CURLUcode uc;

  uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0);

  if(!uc && zoneid) {
    char *endp;
    unsigned long scope = strtoul(zoneid, &endp, 10);
    if(!*endp && (scope < UINT_MAX))
      /* A plain number, use it direcly as a scope id. */
      conn->scope_id = (unsigned int)scope;
#ifdef HAVE_IF_NAMETOINDEX
    else {
      /* Zone identifier is not numeric */
      unsigned int scopeidx = 0;
      scopeidx = if_nametoindex(zoneid);
      if(!scopeidx)
        infof(conn->data, "Invalid zoneid: %s; %s\n", zoneid,
              strerror(errno));
      else
        conn->scope_id = scopeidx;
    }
#endif /* HAVE_IF_NAMETOINDEX */
    free(zoneid);
  }
}

/*
/*
 * Parse URL and fill in the relevant members of the connection struct.
 * Parse URL and fill in the relevant members of the connection struct.
 */
 */
@@ -2004,38 +2038,14 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
  if(hostname[0] == '[') {
  if(hostname[0] == '[') {
    /* This looks like an IPv6 address literal. See if there is an address
    /* This looks like an IPv6 address literal. See if there is an address
       scope. */
       scope. */
    char *zoneid;
    size_t hlen;
    size_t hlen;
    uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0);
    conn->bits.ipv6_ip = TRUE;
    conn->bits.ipv6_ip = TRUE;

    /* cut off the brackets! */
    /* cut off the brackets! */
    hostname++;
    hostname++;
    hlen = strlen(hostname);
    hlen = strlen(hostname);
    hostname[hlen - 1] = 0;
    hostname[hlen - 1] = 0;
    if(!uc && zoneid) {
      char *endp;
      unsigned long scope;
      scope = strtoul(zoneid, &endp, 10);
      if(!*endp && (scope < UINT_MAX)) {
        /* A plain number, use it direcly as a scope id. */
        conn->scope_id = (unsigned int)scope;
      }
#ifdef HAVE_IF_NAMETOINDEX
      else {
        /* Zone identifier is not numeric */
        unsigned int scopeidx = 0;
        scopeidx = if_nametoindex(zoneid);
        if(!scopeidx)
          infof(data, "Invalid zoneid id: %s; %s\n", zoneid,
                strerror(errno));
        else
          conn->scope_id = scopeidx;


      }
    zonefrom_url(uh, conn);
#endif /* HAVE_IF_NAMETOINDEX */
      free(zoneid);
    }
  }
  }


  /* make sure the connect struct gets its own copy of the host name */
  /* make sure the connect struct gets its own copy of the host name */
@@ -2422,6 +2432,7 @@ static CURLcode parse_proxy(struct Curl_easy *data,
    size_t len = strlen(host);
    size_t len = strlen(host);
    host[len-1] = 0; /* clear the trailing bracket */
    host[len-1] = 0; /* clear the trailing bracket */
    host++;
    host++;
    zonefrom_url(uhp, conn);
  }
  }
  proxyinfo->host.name = host;
  proxyinfo->host.name = host;