diff --git a/CHANGES b/CHANGES index 16eb857adf..55f6a3d921 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,12 @@ Changelog Daniel Stenberg (30 Jul 2008) +- 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]/" + - PHP's bug report #43158 (http://bugs.php.net/bug.php?id=43158) identifies a true bug in libcurl built with OpenSSL. It made curl_easy_getinfo() more or less always return 0 for CURLINFO_SSL_VERIFYRESULT because the function that diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 9ea04d39cb..52c834e846 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -19,6 +19,7 @@ This release includes the following changes: o Added CURLINFO_APPCONNECT_TIME o Added test selection by key word in runtests.pl o the curl tool's -w option support the %{ssl_verify_result} variable + o Added CURLOPT_SCOPE and scope parsing of the URL according to RFC4007 This release includes the following bugfixes: diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 index d8f7d82683..6191469d6c 100644 --- a/docs/libcurl/curl_easy_setopt.3 +++ b/docs/libcurl/curl_easy_setopt.3 @@ -21,7 +21,7 @@ .\" * $Id$ .\" ************************************************************************** .\" -.TH curl_easy_setopt 3 "5 Jan 2008" "libcurl 7.19.0" "libcurl Manual" +.TH curl_easy_setopt 3 "30 Jul 2008" "libcurl 7.19.0" "libcurl Manual" .SH NAME curl_easy_setopt \- set options for a curl easy handle .SH SYNOPSIS @@ -547,6 +547,9 @@ notably telnet or rlogin) small segments may need to be sent without delay. This is less efficient than sending larger amounts of data at a time, and can contribute to congestion on the network if overdone. +.IP CURLOPT_ADDRESS_SCOPE +Pass a long specifying the scope_id value to use when connecting to IPv6 +link-local or site-local addresses. .SH NAMES and PASSWORDS OPTIONS (Authentication) .IP CURLOPT_NETRC This parameter controls the preference of libcurl between using user names and diff --git a/include/curl/curl.h b/include/curl/curl.h index af3a0d8a90..da7cc0793d 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -1211,6 +1211,9 @@ typedef enum { /* Issuer certificate */ CINIT(ISSUERCERT, OBJECTPOINT, 170), + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; diff --git a/lib/connect.c b/lib/connect.c index 6c736a42c1..4018eb0427 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 9baa4b3687..170310beb5 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 7cdc7342ab..c2fd36825a 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 {