Mercurial > gftp.yaz
diff lib/socket-connect.c @ 952:a490d94a5b8e
2008-03-28 Brian Masney <masneyb@gftp.org>
* lib/Makefile.am lib/misc.c lib/socket-connect.c
lib/socket-connect-getaddrinfo.c lib/socket-connect-gethostbyname.c
lib/sockutils.c lib/gftp.h - cleaned up more of the socket functions
and split them up into their own files. Cleanups and bug fixes to the
DNS lookup code.
| author | masneyb |
|---|---|
| date | Fri, 28 Mar 2008 11:44:36 +0000 |
| parents | c7d7a081cd9c |
| children |
line wrap: on
line diff
--- a/lib/socket-connect.c Sat Mar 08 11:36:14 2008 +0000 +++ b/lib/socket-connect.c Fri Mar 28 11:44:36 2008 +0000 @@ -20,26 +20,21 @@ #include "gftp.h" static const char cvsid[] = "$Id: protocols.c 952 2008-01-24 23:31:26Z masneyb $"; -/* FIXME - clean up this function */ static int gftp_need_proxy (gftp_request * request, char *service, char *proxy_hostname, - unsigned int proxy_port) + unsigned int proxy_port, void **connect_data) { gftp_config_list_vars * proxy_hosts; gftp_proxy_hosts * hostname; size_t hostlen, domlen; unsigned char addy[4]; - struct sockaddr *addr; GList * templist; gint32 netaddr; char *pos; -#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) - struct addrinfo hints, *hostp; - unsigned int port; - int errnum; - char serv[8]; -#else - struct hostent host, *hostp; + +#if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR) + struct hostent host; + int ret; #endif gftp_lookup_global_option ("dont_use_proxy", &proxy_hosts); @@ -50,48 +45,22 @@ return (proxy_hostname != NULL && *proxy_hostname != '\0'); - hostp = NULL; #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) - memset (&hints, 0, sizeof (hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - port = request->use_proxy ? proxy_port : request->port; - if (port == 0) - strcpy (serv, service); - else - snprintf (serv, sizeof (serv), "%d", port); - request->logging_function (gftp_logging_misc, request, - _("Looking up %s\n"), request->hostname); - - if ((errnum = getaddrinfo (request->hostname, serv, &hints, - &hostp)) != 0) - { - request->logging_function (gftp_logging_error, request, - _("Cannot look up hostname %s: %s\n"), - request->hostname, gai_strerror (errnum)); - return (GFTP_ERETRYABLE); - } - - addr = hostp->ai_addr; + *connect_data = lookup_host_with_getaddrinfo (request, service, + proxy_hostname, proxy_port); + if (*connect_data == NULL) + return (GFTP_ERETRYABLE); #else /* !HAVE_GETADDRINFO */ - request->logging_function (gftp_logging_misc, request, - _("Looking up %s\n"), request->hostname); - if (!(hostp = r_gethostbyname (request->hostname, &host, NULL))) - { - request->logging_function (gftp_logging_error, request, - _("Cannot look up hostname %s: %s\n"), - request->hostname, g_strerror (errno)); - return (GFTP_ERETRYABLE); - } + ret = lookup_host_with_gethostbyname (request, proxy_hostname, &host); + if (ret != 0) + return (ret); - addr = (struct sockaddr *) host.h_addr_list[0]; + connect_data = NULL; /* FIXME */ -#endif /* HAVE_GETADDRINFO */ +#endif templist = proxy_hosts->list; while (templist != NULL) @@ -111,7 +80,7 @@ if (hostname->ipv4_network_address != 0) { - memcpy (addy, addr, sizeof (*addy)); + memcpy (addy, request->remote_addr, sizeof (*addy)); netaddr = (((addy[0] & 0xff) << 24) | ((addy[1] & 0xff) << 16) | ((addy[2] & 0xff) << 8) | (addy[3] & 0xff)) & @@ -126,248 +95,23 @@ } -#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) -static int -get_port (struct addrinfo *addr) -{ - struct sockaddr_in * saddr; - int port; - - if (addr->ai_family == AF_INET) - { - saddr = (struct sockaddr_in *) addr->ai_addr; - port = ntohs (saddr->sin_port); - } - else - port = 0; - - return (port); -} - - -static int -gftp_connect_server_with_getaddr (gftp_request * request, char *service, - char *proxy_hostname, unsigned int proxy_port) -{ - struct addrinfo *hostp, *current_hostp; - char *connect_host, *disphost; - struct addrinfo hints, *res; - intptr_t enable_ipv6; - unsigned int port; - int ret, sock = -1; - char serv[8]; - - if ((ret = gftp_need_proxy (request, service, proxy_hostname, - proxy_port)) < 0) - return (ret); - else - request->use_proxy = ret; - - gftp_lookup_request_option (request, "enable_ipv6", &enable_ipv6); - - memset (&hints, 0, sizeof (hints)); - hints.ai_flags = AI_CANONNAME; - - hints.ai_family = enable_ipv6 ? PF_UNSPEC : AF_INET; - hints.ai_socktype = SOCK_STREAM; - - if (request->use_proxy) - { - connect_host = proxy_hostname; - port = proxy_port; - } - else - { - connect_host = request->hostname; - port = request->port; - } - - if (port == 0) - strcpy (serv, service); - else - snprintf (serv, sizeof (serv), "%d", port); - - request->logging_function (gftp_logging_misc, request, - _("Looking up %s\n"), connect_host); - if ((ret = getaddrinfo (connect_host, serv, &hints, - &hostp)) != 0) - { - request->logging_function (gftp_logging_error, request, - _("Cannot look up hostname %s: %s\n"), - connect_host, gai_strerror (ret)); - return (GFTP_ERETRYABLE); - } - - disphost = connect_host; - for (res = hostp; res != NULL; res = res->ai_next) - { - disphost = res->ai_canonname ? res->ai_canonname : connect_host; - port = get_port (res); - if (!request->use_proxy) - request->port = port; - - if ((sock = socket (res->ai_family, res->ai_socktype, - res->ai_protocol)) < 0) - { - request->logging_function (gftp_logging_error, request, - _("Failed to create a socket: %s\n"), - g_strerror (errno)); - continue; - } - - request->logging_function (gftp_logging_misc, request, - _("Trying %s:%d\n"), disphost, port); - - if (connect (sock, res->ai_addr, res->ai_addrlen) == -1) - { - request->logging_function (gftp_logging_error, request, - _("Cannot connect to %s: %s\n"), - disphost, g_strerror (errno)); - close (sock); - continue; - } - - current_hostp = res; - request->ai_family = res->ai_family; - break; - } - - if (res == NULL) - { - if (hostp != NULL) - freeaddrinfo (hostp); - - return (GFTP_ERETRYABLE); - } - - request->remote_addr_len = current_hostp->ai_addrlen; - request->remote_addr = g_malloc0 (request->remote_addr_len); - memcpy (request->remote_addr, &((struct sockaddr_in *) current_hostp->ai_addr)->sin_addr, - request->remote_addr_len); - - request->logging_function (gftp_logging_misc, request, - _("Connected to %s:%d\n"), connect_host, port); - - return (sock); -} -#endif - - -static int -gftp_connect_server_legacy (gftp_request * request, char *service, - char *proxy_hostname, unsigned int proxy_port) -{ - struct sockaddr_in remote_address; - char *connect_host, *disphost; - struct hostent host, *hostp; - struct servent serv_struct; - int ret, sock, curhost; - unsigned int port; - - if ((ret = gftp_need_proxy (request, service, proxy_hostname, - proxy_port)) < 0) - return (ret); - - request->use_proxy = ret; - if (request->use_proxy == 1) - hostp = NULL; - - request->ai_family = AF_INET; - if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) - { - request->logging_function (gftp_logging_error, request, - _("Failed to create a IPv4 socket: %s\n"), - g_strerror (errno)); - return (GFTP_ERETRYABLE); - } - - memset (&remote_address, 0, sizeof (remote_address)); - remote_address.sin_family = AF_INET; - - if (request->use_proxy) - { - connect_host = proxy_hostname; - port = proxy_port; - } - else - { - connect_host = request->hostname; - port = request->port; - } - - if (port == 0) - { - if (!r_getservbyname (service, "tcp", &serv_struct, NULL)) - { - request->logging_function (gftp_logging_error, request, - _("Cannot look up service name %s/tcp. Please check your services file\n"), - service); - close (sock); - return (GFTP_EFATAL); - } - - port = ntohs (serv_struct.s_port); - - if (!request->use_proxy) - request->port = port; - } - - remote_address.sin_port = htons (port); - - request->logging_function (gftp_logging_misc, request, - _("Looking up %s\n"), connect_host); - - if (!(hostp = r_gethostbyname (connect_host, &host, NULL))) - { - request->logging_function (gftp_logging_error, request, - _("Cannot look up hostname %s: %s\n"), - connect_host, g_strerror (errno)); - close (sock); - return (GFTP_ERETRYABLE); - } - - disphost = NULL; - for (curhost = 0; - host.h_addr_list[curhost] != NULL; - curhost++) - { - disphost = host.h_name; - memcpy (&remote_address.sin_addr, - host.h_addr_list[curhost], - host.h_length); - request->logging_function (gftp_logging_misc, request, - _("Trying %s:%d\n"), - host.h_name, port); - - if (connect (sock, (struct sockaddr *) &remote_address, - sizeof (remote_address)) == -1) - { - request->logging_function (gftp_logging_error, request, - _("Cannot connect to %s: %s\n"), - connect_host, g_strerror (errno)); - } - break; - } - - if (host.h_addr_list[curhost] == NULL) - { - close (sock); - return (GFTP_ERETRYABLE); - } - - return (sock); -} - - int gftp_connect_server (gftp_request * request, char *service, char *proxy_hostname, unsigned int proxy_port) { - int sock; + void *connect_data; + int sock, ret; + if ((ret = gftp_need_proxy (request, service, proxy_hostname, + proxy_port, &connect_data)) < 0) + return (ret); + request->use_proxy = ret; + + /* FIXME - pass connect_data to these functions. This is to bypass a + second DNS lookup */ #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) - sock = gftp_connect_server_with_getaddr (request, service, proxy_hostname, - proxy_port); + sock = gftp_connect_server_with_getaddrinfo (request, service, proxy_hostname, + proxy_port); #else sock = gftp_connect_server_legacy (request, service, proxy_hostname, proxy_port);
