From 5aed78e183e843a6935679d3ebdafd0c10b41114 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 30 Jul 2008 21:55:26 +0000 Subject: - 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]/" --- lib/connect.c | 7 +++++++ lib/url.c | 27 +++++++++++++++++++++++++++ lib/urldata.h | 3 +++ 3 files changed, 37 insertions(+) (limited to 'lib') 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) diff --git a/lib/url.c b/lib/url.c index 9baa4b368..170310beb 100644 --- a/lib/url.c +++ b/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 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=) 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 { -- cgit v1.2.3