diff options
author | Daniel Stenberg <daniel@haxx.se> | 2008-07-30 21:55:26 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2008-07-30 21:55:26 +0000 |
commit | 5aed78e183e843a6935679d3ebdafd0c10b41114 (patch) | |
tree | 5f9426759bda1e85565fd5dce82d6a60be8f6892 /lib | |
parent | 011e5dd86447ffc8eb2e491020cbe5a3f4cd071b (diff) |
- 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]/"
Diffstat (limited to 'lib')
-rw-r--r-- | lib/connect.c | 7 | ||||
-rw-r--r-- | lib/url.c | 27 | ||||
-rw-r--r-- | lib/urldata.h | 3 |
3 files changed, 37 insertions, 0 deletions
diff --git a/lib/connect.c b/lib/connect.c index 6c736a42c..4018eb042 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -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) @@ -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 diff --git a/lib/urldata.h b/lib/urldata.h index 7cdc7342a..c2fd36825 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -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 { |