aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2002-04-22 23:56:13 +0000
committerDaniel Stenberg <daniel@haxx.se>2002-04-22 23:56:13 +0000
commit36e35b6f6003d061d125318bb547bed1c9a74bbe (patch)
treecb1fb8ad1d57f4898e793b9a829856ce77c326b4
parent192606bc4b4f8ab45aff24b33f01b7af1e4d4704 (diff)
allow binding the local end of a connection even when using IPv6, thus we
now have --interface working properly
-rw-r--r--lib/connect.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/lib/connect.c b/lib/connect.c
index ee52b6764..3fe0e0eb0 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -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);