- Phil Blundell added the CURLOPT_SCOPE option, as well as adjusted the URL
parser to allow numerical IPv6-addresses to be specified with the scope given, as per RFC4007 - with a percent letter that itself needs to be URL escaped. For example, for an address of fe80::1234%1 the HTTP URL is: "http://[fe80::1234%251]/"
This commit is contained in:
@@ -773,6 +773,13 @@ singleipconnect(struct connectdata *conn,
|
||||
|
||||
*connected = FALSE; /* default is not connected */
|
||||
|
||||
#ifdef CURLRES_IPV6
|
||||
if (conn->scope && (addr->family == AF_INET6)) {
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr->addr;
|
||||
in6->sin6_scope_id = conn->scope;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FIXME: do we have Curl_printable_address-like with struct sockaddr* as
|
||||
argument? */
|
||||
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
|
||||
|
||||
27
lib/url.c
27
lib/url.c
@@ -2091,6 +2091,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLOPT_ADDRESS_SCOPE:
|
||||
/*
|
||||
* We always get longs when passed plain numericals, but for this value we
|
||||
* know that an unsigned int will always hold the value so we blindly
|
||||
* typecast to this type
|
||||
*/
|
||||
data->set.scope = (unsigned int) va_arg(param, long);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* unknown tag and its companion, just ignore: */
|
||||
result = CURLE_FAILED_INIT; /* correct this */
|
||||
@@ -3080,6 +3089,24 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data,
|
||||
path[0] = '/';
|
||||
}
|
||||
|
||||
if (conn->host.name[0] == '[' && !data->state.this_is_a_follow) {
|
||||
/* This looks like an IPv6 address literal. See if there is an address
|
||||
scope. */
|
||||
char *percent = strstr (conn->host.name, "%25");
|
||||
if (percent) {
|
||||
char *endp;
|
||||
conn->scope = strtoul (percent + 3, &endp, 10);
|
||||
if (*endp == ']') {
|
||||
/* The address scope was well formed. Knock it out of the hostname. */
|
||||
strcpy (percent, "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data->set.scope)
|
||||
/* Override any scope that was set above. */
|
||||
conn->scope = data->set.scope;
|
||||
|
||||
/*
|
||||
* So if the URL was A://B/C,
|
||||
* conn->protostr is A
|
||||
|
||||
@@ -903,6 +903,8 @@ struct connectdata {
|
||||
set. */
|
||||
char *ip_addr_str;
|
||||
|
||||
unsigned int scope; /* address scope for IPv6 */
|
||||
|
||||
char protostr[16]; /* store the protocol string in this buffer */
|
||||
int socktype; /* SOCK_STREAM or SOCK_DGRAM */
|
||||
|
||||
@@ -1478,6 +1480,7 @@ struct UserDefined {
|
||||
bool proxy_transfer_mode; /* set transfer mode (;type=<a|i>) when doing FTP
|
||||
via an HTTP proxy */
|
||||
char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
|
||||
unsigned int scope; /* address scope for IPv6 */
|
||||
};
|
||||
|
||||
struct Names {
|
||||
|
||||
Reference in New Issue
Block a user