Loading lib/connect.c +203 −30 Original line number Diff line number Diff line Loading @@ -41,10 +41,14 @@ #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif #ifdef HAVE_ARPA_INET_H #include <arpa/inet.h> #endif #endif #include <stdio.h> #include <errno.h> #include <string.h> #ifndef TRUE #define TRUE 1 Loading @@ -61,6 +65,7 @@ #include "urldata.h" #include "sendf.h" #include "if2ip.h" /* The last #include file should be: */ #ifdef MALLOCDEBUG Loading Loading @@ -152,25 +157,189 @@ int waitconnect(int sockfd, /* socket */ return 0; } static CURLcode bindlocal(struct connectdata *conn, int sockfd) { #if !defined(WIN32)||defined(__CYGWIN32__) /* We don't generally like checking for OS-versions, we should make this HAVE_XXXX based, although at the moment I don't have a decent test for this! */ #ifdef HAVE_INET_NTOA #ifndef INADDR_NONE #define INADDR_NONE (unsigned long) ~0 #endif #ifndef ENABLE_IPV6 struct SessionHandle *data = conn->data; /************************************************************* * Select device to bind socket to *************************************************************/ if (strlen(data->set.device)<255) { struct sockaddr_in sa; struct hostent *h=NULL; char *hostdataptr=NULL; size_t size; char myhost[256] = ""; unsigned long in; if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { h = Curl_getaddrinfo(data, myhost, 0, &hostdataptr); } else { if(strlen(data->set.device)>1) { h = Curl_getaddrinfo(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(! *myhost) { /* need to fix this h=Curl_gethost(data, getmyhost(*myhost,sizeof(myhost)), hostent_buf, sizeof(hostent_buf)); */ if(hostdataptr) free(hostdataptr); /* allocated by Curl_getaddrinfo() */ return CURLE_HTTP_PORT_FAILED; } infof(data, "We bind local end to %s\n", myhost); if ( (in=inet_addr(myhost)) != INADDR_NONE ) { if ( h ) { memset((char *)&sa, 0, sizeof(sa)); memcpy((char *)&sa.sin_addr, h->h_addr, h->h_length); sa.sin_family = AF_INET; sa.sin_addr.s_addr = in; sa.sin_port = 0; /* get any port */ if( bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) >= 0) { /* we succeeded to bind */ struct sockaddr_in add; size = sizeof(add); if(getsockname(sockfd, (struct sockaddr *) &add, (socklen_t *)&size)<0) { failf(data, "getsockname() failed"); return CURLE_HTTP_PORT_FAILED; } } else { switch(errno) { case EBADF: failf(data, "Invalid descriptor: %d", errno); break; case EINVAL: failf(data, "Invalid request: %d", errno); break; case EACCES: failf(data, "Address is protected, user not superuser: %d", errno); break; case ENOTSOCK: failf(data, "Argument is a descriptor for a file, not a socket: %d", errno); break; case EFAULT: failf(data, "Inaccessable memory error: %d", errno); break; case ENAMETOOLONG: failf(data, "Address too long: %d", errno); break; case ENOMEM: failf(data, "Insufficient kernel memory was available: %d", errno); break; default: failf(data,"errno %d\n"); } /* end of switch */ return CURLE_HTTP_PORT_FAILED; } /* end of else */ } /* end of if h */ else { failf(data,"could't find my own IP address (%s)", myhost); return CURLE_HTTP_PORT_FAILED; } } /* end of inet_addr */ else { failf(data, "could't find my own IP address (%s)", myhost); return CURLE_HTTP_PORT_FAILED; } if(hostdataptr) free(hostdataptr); /* allocated by Curl_getaddrinfo() */ return CURLE_OK; } /* end of device selection support */ #endif /* end of HAVE_INET_NTOA */ #endif /* end of not WIN32 */ #endif /*ENABLE_IPV6*/ return CURLE_HTTP_PORT_FAILED; } /* * TCP connect to the given host with timeout, proxy or remote doesn't matter. * There might be more than one IP address to try out. Fill in the passed * pointer with the connected socket. */ CURLcode Curl_connecthost(struct connectdata *conn, long timeout_ms, Curl_addrinfo *remotehost, int port, int sockfd, /* input socket, or -1 if none */ int *socket) CURLcode Curl_connecthost(struct connectdata *conn, /* context */ Curl_addrinfo *remotehost, /* use one in here */ int port, /* connect to this */ int *socket, /* the connected socket */ Curl_ipconnect **addr) /* the one we used */ { struct SessionHandle *data = conn->data; int rc; int sockfd; int aliasindex=0; struct timeval after; struct timeval before = Curl_tvnow(); /************************************************************* * Figure out what maximum time we have left *************************************************************/ long timeout_ms=300000; /* milliseconds, default to five minutes */ if(data->set.timeout || data->set.connecttimeout) { double has_passed; /* Evaluate how much that that has passed */ has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start); #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif /* get the most strict timeout of the ones converted to milliseconds */ if(data->set.timeout && (data->set.timeout>data->set.connecttimeout)) timeout_ms = data->set.timeout*1000; else timeout_ms = data->set.connecttimeout*1000; /* subtract the passed time */ timeout_ms -= (long)(has_passed * 1000); if(timeout_ms < 0) /* a precaution, no need to continue if time already is up */ return CURLE_OPERATION_TIMEOUTED; } #ifdef ENABLE_IPV6 struct addrinfo *ai; /* Loading @@ -178,11 +347,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, */ port =0; /* we already have port in the 'remotehost' struct */ if(sockfd != -1) /* don't use any previous one, it might be of wrong type */ sclose(sockfd); sockfd = -1; /* none! */ for (ai = remotehost; ai; ai = ai->ai_next) { for (ai = remotehost; ai; ai = ai->ai_next, aliasindex++) { sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sockfd < 0) continue; Loading Loading @@ -216,26 +381,33 @@ CURLcode Curl_connecthost(struct connectdata *conn, nonblock(sockfd, FALSE); break; } conn->ai = ai; if (sockfd < 0) { failf(data, strerror(errno)); return CURLE_COULDNT_CONNECT; } if(addr) *addr = ai; /* the address we ended up connected to */ #else /* * Connecting with IPv4-only support */ int aliasindex; struct sockaddr_in serv_addr; if(-1 == sockfd) /* create an ordinary socket if none was provided */ /* create an IPv4 TCP socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == sockfd) return CURLE_COULDNT_CONNECT; /* big time error */ /* non-block socket */ 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; } /* Convert socket to non-blocking type */ nonblock(sockfd, TRUE); /* This is the loop that attempts to connect to all IP-addresses we Loading @@ -243,9 +415,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, for(rc=-1, aliasindex=0; rc && (struct in_addr *)remotehost->h_addr_list[aliasindex]; aliasindex++) { struct sockaddr_in serv_addr; /* copy this particular name info to the conn struct as it might be used later in the krb4 "system" */ /* do this nasty work to do the connect */ memset((char *) &serv_addr, '\0', sizeof(serv_addr)); memcpy((char *)&(serv_addr.sin_addr), (struct in_addr *)remotehost->h_addr_list[aliasindex], Loading Loading @@ -279,6 +451,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, break; default: /* unknown error, fallthrough and try another address! */ failf(data, "Failed to connect to IP number %d", aliasindex+1); break; } } Loading @@ -287,33 +460,33 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* get a new timeout for next attempt */ after = Curl_tvnow(); timeout_ms -= (long)(Curl_tvdiff(after, before)*1000); if(timeout_ms < 0) if(timeout_ms < 0) { failf(data, "Connect timeout on IP number %d", aliasindex+1); break; } before = after; continue; /* try next address */ } else { /* copy this particular name info to the conn struct as it might be used later in the krb4 "system" */ memcpy((char *) &conn->serv_addr, &serv_addr, sizeof(conn->serv_addr)); } break; } if(-1 == rc) { /* no good connect was made */ sclose(sockfd); *socket = -1; failf(data, "Couldn't connect to (any) IP address"); return CURLE_COULDNT_CONNECT; } /* now disable the non-blocking mode again */ nonblock(sockfd, FALSE); if(addr) /* this is the address we've connected to */ *addr = (struct in_addr *)remotehost->h_addr_list[aliasindex]; #endif *socket = sockfd; /* pass this to our parent */ /* allow NULL-pointers to get passed in */ if(socket) *socket = sockfd; /* the socket descriptor we've connected */ return CURLE_OK; } Loading lib/connect.h +3 −3 Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ *****************************************************************************/ CURLcode Curl_connecthost(struct connectdata *conn, long timeout, /* milliseconds */ Curl_addrinfo *host, /* connect to this */ long port, /* connect to this port number */ int sockfd, /* input socket, or -1 if none */ int *socket); /* not set if error is returned */ int *socket, /* not set if error is returned */ Curl_ipconnect **addr /* the one we used */ ); /* index we used */ #endif lib/ftp.c +16 −70 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ #include "strequal.h" #include "ssluse.h" #include "connect.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> Loading Loading @@ -739,7 +740,7 @@ CURLcode ftp_getsize(struct connectdata *conn, char *file, */ static void ftp_pasv_verbose(struct connectdata *conn, Curl_addrinfo *addr, Curl_ipconnect *addr, char *newhost, /* ascii version */ int port) { Loading Loading @@ -805,7 +806,7 @@ ftp_pasv_verbose(struct connectdata *conn, #else answer = NULL; #endif (void) memcpy(&in.s_addr, *addr->h_addr_list, sizeof (in.s_addr)); (void) memcpy(&in.s_addr, addr, sizeof (Curl_ipconnect)); infof(conn->data, "Connecting to %s (%s) port %u\n", answer?answer->h_name:newhost, #if defined(HAVE_INET_NTOA_R) Loading Loading @@ -1223,12 +1224,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn) Curl_addrinfo *addr; char *hostdataptr=NULL; #ifdef ENABLE_IPV6 struct addrinfo *ai; #else struct sockaddr_in serv_addr; #endif Curl_ipconnect *conninfo; char *str=buf; /* Loading Loading @@ -1277,72 +1273,22 @@ CURLcode ftp_use_pasv(struct connectdata *conn) connectport = newport; /* we connect to the remote port */ } #ifdef ENABLE_IPV6 conn->secondarysocket = -1; for (ai = addr; ai; ai = ai->ai_next) { /* XXX for now, we can do IPv4 only */ if (ai->ai_family != AF_INET) continue; conn->secondarysocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (conn->secondarysocket < 0) continue; if (connect(conn->secondarysocket, ai->ai_addr, ai->ai_addrlen) < 0) { close(conn->secondarysocket); conn->secondarysocket = -1; continue; } result = Curl_connecthost(conn, addr, connectport, &conn->secondarysocket, &conninfo); if(data->set.verbose) if((CURLE_OK == result) && data->set.verbose) /* this just dumps information about this second connection */ ftp_pasv_verbose(conn, ai, newhost, 0 /* port not really known */); break; } if (conn->secondarysocket < 0) { failf(data, strerror(errno)); return CURLE_FTP_CANT_RECONNECT; } #else /* IPv4 code */ conn->secondarysocket = socket(AF_INET, SOCK_STREAM, 0); memset((char *) &serv_addr, '\0', sizeof(serv_addr)); memcpy((char *)&(serv_addr.sin_addr), addr->h_addr, addr->h_length); serv_addr.sin_family = addr->h_addrtype; serv_addr.sin_port = htons(connectport); if(data->set.verbose) /* this just dumps information about this second connection */ ftp_pasv_verbose(conn, addr, newhost, connectport); ftp_pasv_verbose(conn, conninfo, newhost, connectport); if(hostdataptr) free(hostdataptr); if (connect(conn->secondarysocket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { switch(errno) { #ifdef ECONNREFUSED /* this should be made nicer */ case ECONNREFUSED: failf(data, "Connection refused by ftp server"); break; #endif #ifdef EINTR case EINTR: failf(data, "Connection timed out to ftp server"); break; #endif default: failf(data, "Can't connect to ftp server"); break; } return CURLE_FTP_CANT_RECONNECT; } #endif /* end of IPv4-specific code*/ if(CURLE_OK != result) return result; if (data->set.tunnel_thru_httpproxy) { /* We want "seamless" FTP operations through HTTP proxy tunnel */ Loading lib/hostip.h +0 −6 Original line number Diff line number Diff line Loading @@ -27,12 +27,6 @@ struct addrinfo; struct hostent; struct SessionHandle; #ifdef ENABLE_IPV6 typedef struct addrinfo Curl_addrinfo; #else typedef struct hostent Curl_addrinfo; #endif Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, char *hostname, int port, Loading lib/setup.h +15 −0 Original line number Diff line number Diff line Loading @@ -144,4 +144,19 @@ int fileno( FILE *stream); #endif /* * Curl_addrinfo MUST be used for name resolving information. * Information regarding a single IP witin a Curl_addrinfo MUST be stored in * a Curl_ipconnect struct. */ #ifdef ENABLE_IPV6 typedef struct addrinfo Curl_addrinfo; typedef struct addrinfo Curl_ipconnect; #else typedef struct hostent Curl_addrinfo; typedef struct in_addr Curl_ipconnect; #endif #endif /* __CONFIG_H */ Loading
lib/connect.c +203 −30 Original line number Diff line number Diff line Loading @@ -41,10 +41,14 @@ #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif #ifdef HAVE_ARPA_INET_H #include <arpa/inet.h> #endif #endif #include <stdio.h> #include <errno.h> #include <string.h> #ifndef TRUE #define TRUE 1 Loading @@ -61,6 +65,7 @@ #include "urldata.h" #include "sendf.h" #include "if2ip.h" /* The last #include file should be: */ #ifdef MALLOCDEBUG Loading Loading @@ -152,25 +157,189 @@ int waitconnect(int sockfd, /* socket */ return 0; } static CURLcode bindlocal(struct connectdata *conn, int sockfd) { #if !defined(WIN32)||defined(__CYGWIN32__) /* We don't generally like checking for OS-versions, we should make this HAVE_XXXX based, although at the moment I don't have a decent test for this! */ #ifdef HAVE_INET_NTOA #ifndef INADDR_NONE #define INADDR_NONE (unsigned long) ~0 #endif #ifndef ENABLE_IPV6 struct SessionHandle *data = conn->data; /************************************************************* * Select device to bind socket to *************************************************************/ if (strlen(data->set.device)<255) { struct sockaddr_in sa; struct hostent *h=NULL; char *hostdataptr=NULL; size_t size; char myhost[256] = ""; unsigned long in; if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { h = Curl_getaddrinfo(data, myhost, 0, &hostdataptr); } else { if(strlen(data->set.device)>1) { h = Curl_getaddrinfo(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(! *myhost) { /* need to fix this h=Curl_gethost(data, getmyhost(*myhost,sizeof(myhost)), hostent_buf, sizeof(hostent_buf)); */ if(hostdataptr) free(hostdataptr); /* allocated by Curl_getaddrinfo() */ return CURLE_HTTP_PORT_FAILED; } infof(data, "We bind local end to %s\n", myhost); if ( (in=inet_addr(myhost)) != INADDR_NONE ) { if ( h ) { memset((char *)&sa, 0, sizeof(sa)); memcpy((char *)&sa.sin_addr, h->h_addr, h->h_length); sa.sin_family = AF_INET; sa.sin_addr.s_addr = in; sa.sin_port = 0; /* get any port */ if( bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) >= 0) { /* we succeeded to bind */ struct sockaddr_in add; size = sizeof(add); if(getsockname(sockfd, (struct sockaddr *) &add, (socklen_t *)&size)<0) { failf(data, "getsockname() failed"); return CURLE_HTTP_PORT_FAILED; } } else { switch(errno) { case EBADF: failf(data, "Invalid descriptor: %d", errno); break; case EINVAL: failf(data, "Invalid request: %d", errno); break; case EACCES: failf(data, "Address is protected, user not superuser: %d", errno); break; case ENOTSOCK: failf(data, "Argument is a descriptor for a file, not a socket: %d", errno); break; case EFAULT: failf(data, "Inaccessable memory error: %d", errno); break; case ENAMETOOLONG: failf(data, "Address too long: %d", errno); break; case ENOMEM: failf(data, "Insufficient kernel memory was available: %d", errno); break; default: failf(data,"errno %d\n"); } /* end of switch */ return CURLE_HTTP_PORT_FAILED; } /* end of else */ } /* end of if h */ else { failf(data,"could't find my own IP address (%s)", myhost); return CURLE_HTTP_PORT_FAILED; } } /* end of inet_addr */ else { failf(data, "could't find my own IP address (%s)", myhost); return CURLE_HTTP_PORT_FAILED; } if(hostdataptr) free(hostdataptr); /* allocated by Curl_getaddrinfo() */ return CURLE_OK; } /* end of device selection support */ #endif /* end of HAVE_INET_NTOA */ #endif /* end of not WIN32 */ #endif /*ENABLE_IPV6*/ return CURLE_HTTP_PORT_FAILED; } /* * TCP connect to the given host with timeout, proxy or remote doesn't matter. * There might be more than one IP address to try out. Fill in the passed * pointer with the connected socket. */ CURLcode Curl_connecthost(struct connectdata *conn, long timeout_ms, Curl_addrinfo *remotehost, int port, int sockfd, /* input socket, or -1 if none */ int *socket) CURLcode Curl_connecthost(struct connectdata *conn, /* context */ Curl_addrinfo *remotehost, /* use one in here */ int port, /* connect to this */ int *socket, /* the connected socket */ Curl_ipconnect **addr) /* the one we used */ { struct SessionHandle *data = conn->data; int rc; int sockfd; int aliasindex=0; struct timeval after; struct timeval before = Curl_tvnow(); /************************************************************* * Figure out what maximum time we have left *************************************************************/ long timeout_ms=300000; /* milliseconds, default to five minutes */ if(data->set.timeout || data->set.connecttimeout) { double has_passed; /* Evaluate how much that that has passed */ has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start); #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif /* get the most strict timeout of the ones converted to milliseconds */ if(data->set.timeout && (data->set.timeout>data->set.connecttimeout)) timeout_ms = data->set.timeout*1000; else timeout_ms = data->set.connecttimeout*1000; /* subtract the passed time */ timeout_ms -= (long)(has_passed * 1000); if(timeout_ms < 0) /* a precaution, no need to continue if time already is up */ return CURLE_OPERATION_TIMEOUTED; } #ifdef ENABLE_IPV6 struct addrinfo *ai; /* Loading @@ -178,11 +347,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, */ port =0; /* we already have port in the 'remotehost' struct */ if(sockfd != -1) /* don't use any previous one, it might be of wrong type */ sclose(sockfd); sockfd = -1; /* none! */ for (ai = remotehost; ai; ai = ai->ai_next) { for (ai = remotehost; ai; ai = ai->ai_next, aliasindex++) { sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sockfd < 0) continue; Loading Loading @@ -216,26 +381,33 @@ CURLcode Curl_connecthost(struct connectdata *conn, nonblock(sockfd, FALSE); break; } conn->ai = ai; if (sockfd < 0) { failf(data, strerror(errno)); return CURLE_COULDNT_CONNECT; } if(addr) *addr = ai; /* the address we ended up connected to */ #else /* * Connecting with IPv4-only support */ int aliasindex; struct sockaddr_in serv_addr; if(-1 == sockfd) /* create an ordinary socket if none was provided */ /* create an IPv4 TCP socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == sockfd) return CURLE_COULDNT_CONNECT; /* big time error */ /* non-block socket */ 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; } /* Convert socket to non-blocking type */ nonblock(sockfd, TRUE); /* This is the loop that attempts to connect to all IP-addresses we Loading @@ -243,9 +415,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, for(rc=-1, aliasindex=0; rc && (struct in_addr *)remotehost->h_addr_list[aliasindex]; aliasindex++) { struct sockaddr_in serv_addr; /* copy this particular name info to the conn struct as it might be used later in the krb4 "system" */ /* do this nasty work to do the connect */ memset((char *) &serv_addr, '\0', sizeof(serv_addr)); memcpy((char *)&(serv_addr.sin_addr), (struct in_addr *)remotehost->h_addr_list[aliasindex], Loading Loading @@ -279,6 +451,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, break; default: /* unknown error, fallthrough and try another address! */ failf(data, "Failed to connect to IP number %d", aliasindex+1); break; } } Loading @@ -287,33 +460,33 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* get a new timeout for next attempt */ after = Curl_tvnow(); timeout_ms -= (long)(Curl_tvdiff(after, before)*1000); if(timeout_ms < 0) if(timeout_ms < 0) { failf(data, "Connect timeout on IP number %d", aliasindex+1); break; } before = after; continue; /* try next address */ } else { /* copy this particular name info to the conn struct as it might be used later in the krb4 "system" */ memcpy((char *) &conn->serv_addr, &serv_addr, sizeof(conn->serv_addr)); } break; } if(-1 == rc) { /* no good connect was made */ sclose(sockfd); *socket = -1; failf(data, "Couldn't connect to (any) IP address"); return CURLE_COULDNT_CONNECT; } /* now disable the non-blocking mode again */ nonblock(sockfd, FALSE); if(addr) /* this is the address we've connected to */ *addr = (struct in_addr *)remotehost->h_addr_list[aliasindex]; #endif *socket = sockfd; /* pass this to our parent */ /* allow NULL-pointers to get passed in */ if(socket) *socket = sockfd; /* the socket descriptor we've connected */ return CURLE_OK; } Loading
lib/connect.h +3 −3 Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ *****************************************************************************/ CURLcode Curl_connecthost(struct connectdata *conn, long timeout, /* milliseconds */ Curl_addrinfo *host, /* connect to this */ long port, /* connect to this port number */ int sockfd, /* input socket, or -1 if none */ int *socket); /* not set if error is returned */ int *socket, /* not set if error is returned */ Curl_ipconnect **addr /* the one we used */ ); /* index we used */ #endif
lib/ftp.c +16 −70 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ #include "strequal.h" #include "ssluse.h" #include "connect.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> Loading Loading @@ -739,7 +740,7 @@ CURLcode ftp_getsize(struct connectdata *conn, char *file, */ static void ftp_pasv_verbose(struct connectdata *conn, Curl_addrinfo *addr, Curl_ipconnect *addr, char *newhost, /* ascii version */ int port) { Loading Loading @@ -805,7 +806,7 @@ ftp_pasv_verbose(struct connectdata *conn, #else answer = NULL; #endif (void) memcpy(&in.s_addr, *addr->h_addr_list, sizeof (in.s_addr)); (void) memcpy(&in.s_addr, addr, sizeof (Curl_ipconnect)); infof(conn->data, "Connecting to %s (%s) port %u\n", answer?answer->h_name:newhost, #if defined(HAVE_INET_NTOA_R) Loading Loading @@ -1223,12 +1224,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn) Curl_addrinfo *addr; char *hostdataptr=NULL; #ifdef ENABLE_IPV6 struct addrinfo *ai; #else struct sockaddr_in serv_addr; #endif Curl_ipconnect *conninfo; char *str=buf; /* Loading Loading @@ -1277,72 +1273,22 @@ CURLcode ftp_use_pasv(struct connectdata *conn) connectport = newport; /* we connect to the remote port */ } #ifdef ENABLE_IPV6 conn->secondarysocket = -1; for (ai = addr; ai; ai = ai->ai_next) { /* XXX for now, we can do IPv4 only */ if (ai->ai_family != AF_INET) continue; conn->secondarysocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (conn->secondarysocket < 0) continue; if (connect(conn->secondarysocket, ai->ai_addr, ai->ai_addrlen) < 0) { close(conn->secondarysocket); conn->secondarysocket = -1; continue; } result = Curl_connecthost(conn, addr, connectport, &conn->secondarysocket, &conninfo); if(data->set.verbose) if((CURLE_OK == result) && data->set.verbose) /* this just dumps information about this second connection */ ftp_pasv_verbose(conn, ai, newhost, 0 /* port not really known */); break; } if (conn->secondarysocket < 0) { failf(data, strerror(errno)); return CURLE_FTP_CANT_RECONNECT; } #else /* IPv4 code */ conn->secondarysocket = socket(AF_INET, SOCK_STREAM, 0); memset((char *) &serv_addr, '\0', sizeof(serv_addr)); memcpy((char *)&(serv_addr.sin_addr), addr->h_addr, addr->h_length); serv_addr.sin_family = addr->h_addrtype; serv_addr.sin_port = htons(connectport); if(data->set.verbose) /* this just dumps information about this second connection */ ftp_pasv_verbose(conn, addr, newhost, connectport); ftp_pasv_verbose(conn, conninfo, newhost, connectport); if(hostdataptr) free(hostdataptr); if (connect(conn->secondarysocket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { switch(errno) { #ifdef ECONNREFUSED /* this should be made nicer */ case ECONNREFUSED: failf(data, "Connection refused by ftp server"); break; #endif #ifdef EINTR case EINTR: failf(data, "Connection timed out to ftp server"); break; #endif default: failf(data, "Can't connect to ftp server"); break; } return CURLE_FTP_CANT_RECONNECT; } #endif /* end of IPv4-specific code*/ if(CURLE_OK != result) return result; if (data->set.tunnel_thru_httpproxy) { /* We want "seamless" FTP operations through HTTP proxy tunnel */ Loading
lib/hostip.h +0 −6 Original line number Diff line number Diff line Loading @@ -27,12 +27,6 @@ struct addrinfo; struct hostent; struct SessionHandle; #ifdef ENABLE_IPV6 typedef struct addrinfo Curl_addrinfo; #else typedef struct hostent Curl_addrinfo; #endif Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, char *hostname, int port, Loading
lib/setup.h +15 −0 Original line number Diff line number Diff line Loading @@ -144,4 +144,19 @@ int fileno( FILE *stream); #endif /* * Curl_addrinfo MUST be used for name resolving information. * Information regarding a single IP witin a Curl_addrinfo MUST be stored in * a Curl_ipconnect struct. */ #ifdef ENABLE_IPV6 typedef struct addrinfo Curl_addrinfo; typedef struct addrinfo Curl_ipconnect; #else typedef struct hostent Curl_addrinfo; typedef struct in_addr Curl_ipconnect; #endif #endif /* __CONFIG_H */