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; return 0;
} }
#ifndef ENABLE_IPV6
static CURLcode bindlocal(struct connectdata *conn, static CURLcode bindlocal(struct connectdata *conn,
int sockfd) int sockfd)
{ {
@ -207,22 +206,29 @@ 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); }
} }
} }
@ -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);