allow binding the local end of a connection even when using IPv6, thus we

now have --interface working properly
This commit is contained in:
Daniel Stenberg 2002-04-22 23:56:13 +00:00
parent 192606bc4b
commit 36e35b6f60
1 changed files with 27 additions and 10 deletions

View File

@ -185,7 +185,6 @@ int waitconnect(int sockfd, /* socket */
return 0;
}
#ifndef ENABLE_IPV6
static CURLcode bindlocal(struct connectdata *conn,
int sockfd)
{
@ -207,22 +206,29 @@ static CURLcode bindlocal(struct connectdata *conn,
*************************************************************/
if (strlen(data->set.device)<255) {
struct sockaddr_in sa;
struct hostent *h=NULL;
Curl_addrinfo *h=NULL;
char *hostdataptr=NULL;
size_t size;
char myhost[256] = "";
in_addr_t in;
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);
}
else {
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);
}
if(h) {
/* we know data->set.device is shorter than the myhost array */
strcpy(myhost, data->set.device);
if(h) {
/* we know data->set.device is shorter than the myhost array */
strcpy(myhost, data->set.device);
}
}
}
@ -243,10 +249,13 @@ static CURLcode bindlocal(struct connectdata *conn,
if ( h ) {
memset((char *)&sa, 0, sizeof(sa));
memcpy((char *)&sa.sin_addr,
h->h_addr,
h->h_length);
#ifdef ENABLE_IPV6
memcpy((char *)&sa.sin_addr, h->ai_addr, h->ai_addrlen);
sa.sin_family = h->ai_family;
#else
memcpy((char *)&sa.sin_addr, h->h_addr, h->h_length);
sa.sin_family = AF_INET;
#endif
sa.sin_addr.s_addr = in;
sa.sin_port = 0; /* get any port */
@ -314,7 +323,7 @@ static CURLcode bindlocal(struct connectdata *conn,
return CURLE_HTTP_PORT_FAILED;
}
#endif /* end of ipv4-specific section */
static
int socketerror(int sockfd)
@ -401,6 +410,14 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
if (sockfd < 0)
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 */
Curl_nonblock(sockfd, TRUE);