Remove duplicate socket connect code from gnutls.c
authorDavid Woodhouse <David.Woodhouse@intel.com>
Thu, 31 May 2012 21:03:08 +0000 (22:03 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Thu, 31 May 2012 21:37:07 +0000 (22:37 +0100)
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
gnutls.c

index ac0d0c4..17b3e02 100644 (file)
--- a/gnutls.c
+++ b/gnutls.c
 
 #include "openconnect-internal.h"
 
-/* OSX < 1.6 doesn't have AI_NUMERICSERV */
-#ifndef AI_NUMERICSERV
-#define AI_NUMERICSERV 0
-#endif
-
 /* Helper functions for reading/writing lines over SSL.
    We could use cURL for the HTTP stuff, but it's overkill */
 
@@ -885,41 +880,6 @@ static int verify_peer(gnutls_session_t session)
        return err;
 }
 
-static int cancellable_connect(struct openconnect_info *vpninfo, int sockfd,
-                              const struct sockaddr *addr, socklen_t addrlen)
-{
-       struct sockaddr_storage peer;
-       socklen_t peerlen = sizeof(peer);
-       fd_set wr_set, rd_set;
-       int maxfd = sockfd;
-
-       fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK);
-
-       if (connect(sockfd, addr, addrlen) < 0 && errno != EINPROGRESS)
-               return -1;
-
-       FD_ZERO(&wr_set);
-       FD_ZERO(&rd_set);
-       FD_SET(sockfd, &wr_set);
-       if (vpninfo->cancel_fd != -1) {
-               FD_SET(vpninfo->cancel_fd, &rd_set);
-               if (vpninfo->cancel_fd > sockfd)
-                       maxfd = vpninfo->cancel_fd;
-       }
-       
-       /* Later we'll render this whole exercise non-pointless by
-          including a 'cancelfd' here too. */
-       select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
-       if (vpninfo->cancel_fd != -1 && FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
-               vpn_progress(vpninfo, PRG_ERR, _("Socket connect cancelled\n"));
-               errno = EINTR;
-               return -1;
-       }
-               
-       /* Check whether connect() succeeded or failed by using
-          getpeername(). See http://cr.yp.to/docs/connect.html */
-       return getpeername(sockfd, (void *)&peer, &peerlen);
-}
 
 int openconnect_open_https(struct openconnect_info *vpninfo)
 {
@@ -929,176 +889,9 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
        if (vpninfo->https_sess)
                return 0;
 
-       if (!vpninfo->port)
-               vpninfo->port = 443;
-
-       if (vpninfo->peer_addr) {
-#ifdef SOCK_CLOEXEC
-               ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_IP);
-               if (ssl_sock < 0)
-#endif
-               {
-                       ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM, IPPROTO_IP);
-                       if (ssl_sock < 0)
-                               goto reconn_err;
-                       fcntl(ssl_sock, F_SETFD, fcntl(ssl_sock, F_GETFD) | FD_CLOEXEC);
-               }
-               if (cancellable_connect(vpninfo, ssl_sock, vpninfo->peer_addr, vpninfo->peer_addrlen)) {
-               reconn_err:
-                       if (vpninfo->proxy) {
-                               vpn_progress(vpninfo, PRG_ERR, 
-                                            _("Failed to reconnect to proxy %s\n"),
-                                            vpninfo->proxy);
-                       } else {
-                               vpn_progress(vpninfo, PRG_ERR, 
-                                            _("Failed to reconnect to host %s\n"),
-                                            vpninfo->hostname);
-                       }
-                       return -EINVAL;
-               }
-               
-       } else {
-               struct addrinfo hints, *result, *rp;
-               char *hostname;
-               char port[6];
-
-               memset(&hints, 0, sizeof(struct addrinfo));
-               hints.ai_family = AF_UNSPEC;
-               hints.ai_socktype = SOCK_STREAM;
-               hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
-               hints.ai_protocol = 0;
-               hints.ai_canonname = NULL;
-               hints.ai_addr = NULL;
-               hints.ai_next = NULL;
-
-               /* The 'port' variable is a string because it's easier
-                  this way than if we pass NULL to getaddrinfo() and
-                  then try to fill in the numeric value into
-                  different types of returned sockaddr_in{6,}. */
-#ifdef LIBPROXY_HDR
-               if (vpninfo->proxy_factory) {
-                       char *url;
-                       char **proxies;
-                       int i = 0;
-
-                       free(vpninfo->proxy_type);
-                       vpninfo->proxy_type = NULL;
-                       free(vpninfo->proxy);
-                       vpninfo->proxy = NULL;
-
-                       if (vpninfo->port == 443)
-                               i = asprintf(&url, "https://%s/%s", vpninfo->hostname,
-                                            vpninfo->urlpath?:"");
-                       else
-                               i = asprintf(&url, "https://%s:%d/%s", vpninfo->hostname,
-                                            vpninfo->port, vpninfo->urlpath?:"");
-                       if (i == -1)
-                               return -ENOMEM;
-
-                       proxies = px_proxy_factory_get_proxies(vpninfo->proxy_factory,
-                                                              url);
-
-                       i = 0;
-                       while (proxies && proxies[i]) {
-                               if (!vpninfo->proxy &&
-                                   (!strncmp(proxies[i], "http://", 7) ||
-                                    !strncmp(proxies[i], "socks://", 8) ||
-                                    !strncmp(proxies[i], "socks5://", 9)))
-                                       internal_parse_url(proxies[i], &vpninfo->proxy_type,
-                                                 &vpninfo->proxy, &vpninfo->proxy_port,
-                                                 NULL, 0);
-                               i++;
-                       }
-                       free(url);
-                       free(proxies);
-                       if (vpninfo->proxy)
-                               vpn_progress(vpninfo, PRG_TRACE,
-                                            _("Proxy from libproxy: %s://%s:%d/\n"),
-                                            vpninfo->proxy_type, vpninfo->proxy, vpninfo->port);
-               }
-#endif
-               if (vpninfo->proxy) {
-                       hostname = vpninfo->proxy;
-                       snprintf(port, 6, "%d", vpninfo->proxy_port);
-               } else {
-                       hostname = vpninfo->hostname;
-                       snprintf(port, 6, "%d", vpninfo->port);
-               }
-
-               if (hostname[0] == '[' && hostname[strlen(hostname)-1] == ']') {
-                       /* Solaris has no strndup(). */
-                       int len = strlen(hostname) - 2;
-                       char *new_hostname = malloc(len + 1);
-                       if (!new_hostname)
-                               return -ENOMEM;
-                       memcpy(new_hostname, hostname + 1, len);
-                       new_hostname[len] = 0;
-
-                       hostname = new_hostname;
-                       hints.ai_flags |= AI_NUMERICHOST;
-               }
-
-               err = getaddrinfo(hostname, port, &hints, &result);
-               if (hints.ai_flags & AI_NUMERICHOST)
-                       free(hostname);
-
-               if (err) {
-                       vpn_progress(vpninfo, PRG_ERR,
-                                    _("getaddrinfo failed for host '%s': %s\n"),
-                                    hostname, gai_strerror(err));
-                       return -EINVAL;
-               }
-
-               for (rp = result; rp ; rp = rp->ai_next) {
-                       char host[80];
-
-                       if (!getnameinfo(rp->ai_addr, rp->ai_addrlen, host,
-                                        sizeof(host), NULL, 0, NI_NUMERICHOST))
-                               vpn_progress(vpninfo, PRG_INFO,
-                                            _("Attempting to connect to %s%s%s:%s\n"),
-                                            rp->ai_family == AF_INET6?"[":"",
-                                            host,
-                                            rp->ai_family == AF_INET6?"]":"",
-                                            port);
-                       
-                       ssl_sock = socket(rp->ai_family, rp->ai_socktype,
-                                         rp->ai_protocol);
-                       if (ssl_sock < 0)
-                               continue;
-                       if (cancellable_connect(vpninfo, ssl_sock, rp->ai_addr, rp->ai_addrlen) >= 0) {
-                               /* Store the peer address we actually used, so that DTLS can
-                                  use it again later */
-                               vpninfo->peer_addr = malloc(rp->ai_addrlen);
-                               if (!vpninfo->peer_addr) {
-                                       vpn_progress(vpninfo, PRG_ERR,
-                                                    _("Failed to allocate sockaddr storage\n"));
-                                       close(ssl_sock);
-                                       return -ENOMEM;
-                               }
-                               vpninfo->peer_addrlen = rp->ai_addrlen;
-                               memcpy(vpninfo->peer_addr, rp->ai_addr, rp->ai_addrlen);
-                               break;
-                       }
-                       close(ssl_sock);
-                       ssl_sock = -1;
-               }
-               freeaddrinfo(result);
-               
-               if (ssl_sock < 0) {
-                       vpn_progress(vpninfo, PRG_ERR,
-                                    _("Failed to connect to host %s\n"),
-                                    vpninfo->proxy?:vpninfo->hostname);
-                       return -EINVAL;
-               }
-       }
-
-       if (vpninfo->proxy) {
-               err = process_proxy(vpninfo, ssl_sock);
-               if (err) {
-                       close(ssl_sock);
-                       return err;
-               }
-       }
+       ssl_sock = connect_https_socket(vpninfo);
+       if (ssl_sock < 0)
+               return ssl_sock;
 
        if (!vpninfo->https_cred) {
                gnutls_certificate_allocate_credentials(&vpninfo->https_cred);