~ubuntu-branches/ubuntu/saucy/curl/saucy-201307251546

« back to all changes in this revision

Viewing changes to lib/connect.c

  • Committer: Bazaar Package Importer
  • Author(s): Ramakrishnan Muthukrishnan
  • Date: 2011-02-28 19:35:36 UTC
  • mto: (3.6.1 experimental) (1.3.1)
  • mto: This revision was merged to the branch mainline in revision 47.
  • Revision ID: james.westby@ubuntu.com-20110228193536-p3a9jawxxofcsz7o
Tags: upstream-7.21.4
ImportĀ upstreamĀ versionĀ 7.21.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
9
9
 *
10
10
 * This software is licensed as described in the file COPYING, which
11
11
 * you should have received as part of this distribution. The terms
124
124
 * transfer/connection. If the value is negative, the timeout time has already
125
125
 * elapsed.
126
126
 *
 
127
 * The start time is stored in progress.t_startsingle - as set with
 
128
 * Curl_pgrsTime(..., TIMER_STARTSINGLE);
 
129
 *
127
130
 * If 'nowp' is non-NULL, it points to the current time.
128
131
 * 'duringconnect' is FALSE if not during a connect, as then of course the
129
132
 * connect timeout is not taken into account!
130
133
 */
131
 
long Curl_timeleft(struct connectdata *conn,
 
134
long Curl_timeleft(struct SessionHandle *data,
132
135
                   struct timeval *nowp,
133
136
                   bool duringconnect)
134
137
{
135
 
  struct SessionHandle *data = conn->data;
136
138
  int timeout_set = 0;
137
139
  long timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
138
140
  struct timeval now;
658
660
  curl_socket_t sockfd = conn->sock[sockindex];
659
661
  long allow = DEFAULT_CONNECT_TIMEOUT;
660
662
  int error = 0;
 
663
  struct timeval now;
661
664
 
662
665
  DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
663
666
 
669
672
    return CURLE_OK;
670
673
  }
671
674
 
 
675
  now = Curl_tvnow();
 
676
 
672
677
  /* figure out how long time we have left to connect */
673
 
  allow = Curl_timeleft(conn, NULL, TRUE);
 
678
  allow = Curl_timeleft(data, &now, TRUE);
674
679
 
675
680
  if(allow < 0) {
676
681
    /* time-out, bail out, go home */
680
685
 
681
686
  /* check for connect without timeout as we want to return immediately */
682
687
  rc = waitconnect(conn, sockfd, 0);
683
 
  if(WAITCONN_TIMEOUT == rc)
 
688
  if(WAITCONN_TIMEOUT == rc) {
 
689
    if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
 
690
      infof(data, "After %ldms connect time, move on!\n",
 
691
            conn->timeoutms_per_addr);
 
692
      goto next;
 
693
    }
 
694
 
684
695
    /* not an error, but also no connection yet */
685
696
    return code;
 
697
  }
686
698
 
687
699
  if(WAITCONN_CONNECTED == rc) {
688
700
    if(verifyconnect(sockfd, &error)) {
715
727
    data->state.os_errno = error;
716
728
    SET_SOCKERRNO(error);
717
729
  }
 
730
  next:
718
731
 
719
732
  code = trynextip(conn, sockindex, connected);
720
733
 
844
857
 
845
858
  addr.family = ai->ai_family;
846
859
  addr.socktype = conn->socktype;
847
 
  addr.protocol = ai->ai_protocol;
 
860
  addr.protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
848
861
  addr.addrlen = ai->ai_addrlen;
849
862
 
850
863
  if(addr.addrlen > sizeof(struct Curl_sockaddr_storage))
913
926
                               CURLSOCKTYPE_IPCXN);
914
927
    if(error) {
915
928
      sclose(sockfd); /* close the socket and bail out */
916
 
      return res;
 
929
      return CURLE_ABORTED_BY_CALLBACK;
917
930
    }
918
931
  }
919
932
 
928
941
  curlx_nonblock(sockfd, TRUE);
929
942
 
930
943
  /* Connect TCP sockets, bind UDP */
931
 
  if(conn->socktype == SOCK_STREAM)
 
944
  if(conn->socktype == SOCK_STREAM) {
932
945
    rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
 
946
    conn->connecttime = Curl_tvnow();
 
947
    if(conn->num_addr > 1)
 
948
      Curl_expire(data, conn->timeoutms_per_addr);
 
949
  }
933
950
  else
934
951
    rc = 0;
935
952
 
1010
1027
  struct SessionHandle *data = conn->data;
1011
1028
  curl_socket_t sockfd = CURL_SOCKET_BAD;
1012
1029
  int aliasindex;
1013
 
  int num_addr;
1014
1030
  Curl_addrinfo *ai;
1015
1031
  Curl_addrinfo *curr_addr;
1016
1032
 
1021
1037
   * Figure out what maximum time we have left
1022
1038
   *************************************************************/
1023
1039
  long timeout_ms;
1024
 
  long timeout_per_addr;
1025
1040
 
1026
1041
  DEBUGASSERT(sockconn);
1027
1042
  *connected = FALSE; /* default to not connected */
1028
1043
 
1029
1044
  /* get the timeout left */
1030
 
  timeout_ms = Curl_timeleft(conn, &before, TRUE);
 
1045
  timeout_ms = Curl_timeleft(data, &before, TRUE);
1031
1046
 
1032
1047
  if(timeout_ms < 0) {
1033
1048
    /* a precaution, no need to continue if time already is up */
1036
1051
  }
1037
1052
 
1038
1053
  /* Max time for each address */
1039
 
  num_addr = Curl_num_addresses(remotehost->addr);
1040
 
  timeout_per_addr = timeout_ms / num_addr;
 
1054
  conn->num_addr = Curl_num_addresses(remotehost->addr);
 
1055
  conn->timeoutms_per_addr = timeout_ms / conn->num_addr;
1041
1056
 
1042
1057
  ai = remotehost->addr;
1043
1058
 
1045
1060
   * know for the given host. One by one until one IP succeeds.
1046
1061
   */
1047
1062
 
1048
 
  if(data->state.used_interface == Curl_if_multi)
1049
 
    /* don't hang when doing multi */
1050
 
    timeout_per_addr = 0;
1051
 
 
1052
1063
  /*
1053
1064
   * Connecting with a Curl_addrinfo chain
1054
1065
   */
1057
1068
 
1058
1069
    /* start connecting to the IP curr_addr points to */
1059
1070
    CURLcode res =
1060
 
      singleipconnect(conn, curr_addr, timeout_per_addr, &sockfd, connected);
 
1071
      singleipconnect(conn, curr_addr,
 
1072
                      /* don't hang when doing multi */
 
1073
                      (data->state.used_interface == Curl_if_multi)?0:
 
1074
                      conn->timeoutms_per_addr, &sockfd, connected);
1061
1075
 
1062
1076
    if(res)
1063
1077
      return res;