mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 16:18:48 -05:00
allow binding the local end of a connection even when using IPv6, thus we
now have --interface working properly
This commit is contained in:
parent
192606bc4b
commit
36e35b6f60
@ -185,7 +185,6 @@ int waitconnect(int sockfd, /* socket */
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ENABLE_IPV6
|
|
||||||
static CURLcode bindlocal(struct connectdata *conn,
|
static CURLcode bindlocal(struct connectdata *conn,
|
||||||
int sockfd)
|
int sockfd)
|
||||||
{
|
{
|
||||||
@ -207,24 +206,31 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
*************************************************************/
|
*************************************************************/
|
||||||
if (strlen(data->set.device)<255) {
|
if (strlen(data->set.device)<255) {
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
struct hostent *h=NULL;
|
Curl_addrinfo *h=NULL;
|
||||||
char *hostdataptr=NULL;
|
char *hostdataptr=NULL;
|
||||||
size_t size;
|
size_t size;
|
||||||
char myhost[256] = "";
|
char myhost[256] = "";
|
||||||
in_addr_t in;
|
in_addr_t in;
|
||||||
|
|
||||||
if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) {
|
if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) {
|
||||||
|
/*
|
||||||
|
* We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer
|
||||||
|
*/
|
||||||
h = Curl_resolv(data, myhost, 0, &hostdataptr);
|
h = Curl_resolv(data, myhost, 0, &hostdataptr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(strlen(data->set.device)>1) {
|
if(strlen(data->set.device)>1) {
|
||||||
|
/*
|
||||||
|
* This was not an interface, resolve the name as a host name
|
||||||
|
* or IP number
|
||||||
|
*/
|
||||||
h = Curl_resolv(data, data->set.device, 0, &hostdataptr);
|
h = Curl_resolv(data, data->set.device, 0, &hostdataptr);
|
||||||
}
|
|
||||||
if(h) {
|
if(h) {
|
||||||
/* we know data->set.device is shorter than the myhost array */
|
/* we know data->set.device is shorter than the myhost array */
|
||||||
strcpy(myhost, data->set.device);
|
strcpy(myhost, data->set.device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(! *myhost) {
|
if(! *myhost) {
|
||||||
/* need to fix this
|
/* need to fix this
|
||||||
@ -243,10 +249,13 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
|
|
||||||
if ( h ) {
|
if ( h ) {
|
||||||
memset((char *)&sa, 0, sizeof(sa));
|
memset((char *)&sa, 0, sizeof(sa));
|
||||||
memcpy((char *)&sa.sin_addr,
|
#ifdef ENABLE_IPV6
|
||||||
h->h_addr,
|
memcpy((char *)&sa.sin_addr, h->ai_addr, h->ai_addrlen);
|
||||||
h->h_length);
|
sa.sin_family = h->ai_family;
|
||||||
|
#else
|
||||||
|
memcpy((char *)&sa.sin_addr, h->h_addr, h->h_length);
|
||||||
sa.sin_family = AF_INET;
|
sa.sin_family = AF_INET;
|
||||||
|
#endif
|
||||||
sa.sin_addr.s_addr = in;
|
sa.sin_addr.s_addr = in;
|
||||||
sa.sin_port = 0; /* get any port */
|
sa.sin_port = 0; /* get any port */
|
||||||
|
|
||||||
@ -314,7 +323,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
|
|
||||||
return CURLE_HTTP_PORT_FAILED;
|
return CURLE_HTTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
#endif /* end of ipv4-specific section */
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int socketerror(int sockfd)
|
int socketerror(int sockfd)
|
||||||
@ -401,6 +410,14 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(conn->data->set.device) {
|
||||||
|
/* user selected to bind the outgoing socket to a specified "device"
|
||||||
|
before doing connect */
|
||||||
|
CURLcode res = bindlocal(conn, sockfd);
|
||||||
|
if(res)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/* set socket non-blocking */
|
/* set socket non-blocking */
|
||||||
Curl_nonblock(sockfd, TRUE);
|
Curl_nonblock(sockfd, TRUE);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user