~ubuntu-branches/ubuntu/natty/curl/natty-security

« back to all changes in this revision

Viewing changes to lib/multi.c

  • Committer: Bazaar Package Importer
  • Author(s): Bhavani Shankar
  • Date: 2010-06-20 13:56:28 UTC
  • mfrom: (3.4.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100620135628-e30tp9jldq6hq985
Tags: 7.21.0-1ubuntu1
* Merge from debian unstable.  Remaining changes: LP: #596334
  - Keep build deps in main:
    - Drop build dependencies: stunnel, libssh2-1-dev
    - Add build-dependency on openssh-server
    - Drop libssh2-1-dev from libcurl4-openssl-dev's Depends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2010, 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
18
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
 * KIND, either express or implied.
20
20
 *
21
 
 * $Id: multi.c,v 1.204 2009-08-24 08:41:17 bagder Exp $
22
21
 ***************************************************************************/
23
22
 
24
23
#include "setup.h"
181
180
                                    previous callback */
182
181
};
183
182
 
184
 
static bool multi_conn_using(struct Curl_multi *multi,
 
183
static void multi_connc_remove_handle(struct Curl_multi *multi,
 
184
                                      struct SessionHandle *data);
 
185
static void singlesocket(struct Curl_multi *multi,
 
186
                         struct Curl_one_easy *easy);
 
187
static CURLMcode add_closure(struct Curl_multi *multi,
185
188
                             struct SessionHandle *data);
186
 
static void singlesocket(struct Curl_multi *multi,
187
 
                         struct Curl_one_easy *easy);
188
 
static void add_closure(struct Curl_multi *multi,
189
 
                        struct SessionHandle *data);
190
189
static int update_timer(struct Curl_multi *multi);
191
190
 
192
191
static CURLcode addHandleToSendOrPendPipeline(struct SessionHandle *handle,
258
257
struct Curl_sh_entry {
259
258
  struct SessionHandle *easy;
260
259
  time_t timestamp;
261
 
  long inuse;
262
260
  int action;  /* what action READ/WRITE this socket waits for */
263
261
  curl_socket_t socket; /* mainly to ease debugging */
264
262
  void *socketp; /* settable by users with curl_multi_assign() */
282
280
    return there;
283
281
 
284
282
  /* not present, add it */
285
 
  check = calloc(sizeof(struct Curl_sh_entry), 1);
 
283
  check = calloc(1, sizeof(struct Curl_sh_entry));
286
284
  if(!check)
287
285
    return NULL; /* major failure */
288
286
  check->easy = data;
364
362
 
365
363
CURLM *curl_multi_init(void)
366
364
{
367
 
  struct Curl_multi *multi = calloc(sizeof(struct Curl_multi), 1);
 
365
  struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
368
366
 
369
367
  if(!multi)
370
368
    return NULL;
425
423
    return CURLM_BAD_EASY_HANDLE;
426
424
 
427
425
  /* Now, time to add an easy handle to the multi stack */
428
 
  easy = calloc(sizeof(struct Curl_one_easy), 1);
 
426
  easy = calloc(1, sizeof(struct Curl_one_easy));
429
427
  if(!easy)
430
428
    return CURLM_OUT_OF_MEMORY;
431
429
 
568
566
  struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
569
567
 
570
568
  fprintf(stderr, " [easy %p/magic %x/socket %d]",
571
 
          (void *)sh->easy, sh->easy->magic, sh->socket);
 
569
          (void *)sh->easy, sh->easy->magic, (int)sh->socket);
572
570
}
573
571
#endif
574
572
 
649
647
        Curl_getoff_all_pipelines(easy->easy_handle, easy->easy_conn);
650
648
    }
651
649
 
652
 
    /* If this easy_handle was the last one in charge for one or more
653
 
       connections in the shared connection cache, we might need to keep this
654
 
       handle around until either A) the connection is closed and killed
655
 
       properly, or B) another easy_handle uses the connection.
656
 
 
657
 
       The reason why we need to have a easy_handle associated with a live
658
 
       connection is simply that some connections will need a handle to get
659
 
       closed down properly. Currently, the only connections that need to keep
660
 
       a easy_handle handle around are using FTP(S). Such connections have
661
 
       the PROT_CLOSEACTION bit set.
662
 
 
663
 
       Thus, we need to check for all connections in the shared cache that
664
 
       points to this handle and are using PROT_CLOSEACTION. If there's any,
665
 
       we need to add this handle to the list of "easy handles kept around for
666
 
       nice connection closures".
667
 
    */
668
 
    if(multi_conn_using(multi, easy->easy_handle)) {
669
 
      /* There's at least one connection using this handle so we must keep
670
 
         this handle around. We also keep the connection cache pointer
671
 
         pointing to the shared one since that will be used on close as
672
 
         well. */
673
 
      easy->easy_handle->state.shared_conn = multi;
674
 
 
675
 
      /* this handle is still being used by a shared connection cache and
676
 
         thus we leave it around for now */
677
 
      add_closure(multi, easy->easy_handle);
678
 
    }
 
650
    /* figure out if the easy handle is used by one or more connections in the
 
651
       cache */
 
652
    multi_connc_remove_handle(multi, easy->easy_handle);
679
653
 
680
654
    if(easy->easy_handle->state.connc->type == CONNCACHE_MULTI) {
681
655
      /* if this was using the shared connection cache we clear the pointer
914
888
    /* Handle the case when the pipe breaks, i.e., the connection
915
889
       we're using gets cleaned up and we're left with nothing. */
916
890
    if(easy->easy_handle->state.pipe_broke) {
917
 
      infof(easy->easy_handle, "Pipe broke: handle 0x%x, url = %s\n",
 
891
      infof(easy->easy_handle, "Pipe broke: handle 0x%p, url = %s\n",
918
892
            easy, easy->easy_handle->state.path);
919
893
 
920
894
      if(easy->state != CURLM_STATE_COMPLETED) {
1090
1064
          else
1091
1065
#endif
1092
1066
            multistate(easy, CURLM_STATE_PROTOCONNECT);
 
1067
 
1093
1068
        }
1094
 
        else {
 
1069
        else
1095
1070
          /* after the connect has completed, go WAITDO or DO */
1096
1071
          multistate(easy, multi->pipelining_enabled?
1097
1072
                     CURLM_STATE_WAITDO:CURLM_STATE_DO);
1098
1073
 
1099
 
          result = CURLM_CALL_MULTI_PERFORM;
1100
 
        }
 
1074
        result = CURLM_CALL_MULTI_PERFORM;
1101
1075
      }
1102
1076
      break;
1103
1077
 
1122
1096
    case CURLM_STATE_WAITDO:
1123
1097
      /* Wait for our turn to DO when we're pipelining requests */
1124
1098
#ifdef DEBUGBUILD
1125
 
      infof(easy->easy_handle, "Conn %d send pipe %d inuse %d athead %d\n",
 
1099
      infof(easy->easy_handle, "Conn %ld send pipe %zu inuse %d athead %d\n",
1126
1100
            easy->easy_conn->connectindex,
1127
1101
            easy->easy_conn->send_pipe->size,
1128
 
            easy->easy_conn->writechannel_inuse,
 
1102
            easy->easy_conn->writechannel_inuse?1:0,
1129
1103
            isHandleAtHead(easy->easy_handle,
1130
 
                           easy->easy_conn->send_pipe));
 
1104
                           easy->easy_conn->send_pipe)?1:0);
1131
1105
#endif
1132
1106
      if(!easy->easy_conn->writechannel_inuse &&
1133
1107
         isHandleAtHead(easy->easy_handle,
1154
1128
 
1155
1129
        if(CURLE_OK == easy->result) {
1156
1130
          if(!dophase_done) {
 
1131
            /* some steps needed for wildcard matching */
 
1132
            if(easy->easy_handle->set.wildcardmatch) {
 
1133
              struct WildcardData *wc = &easy->easy_handle->wildcard;
 
1134
              if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
 
1135
                /* skip some states if it is important */
 
1136
                Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
 
1137
                multistate(easy, CURLM_STATE_DONE);
 
1138
                result = CURLM_CALL_MULTI_PERFORM;
 
1139
                break;
 
1140
              }
 
1141
            }
1157
1142
            /* DO was not completed in one function call, we must continue
1158
1143
               DOING... */
1159
1144
            multistate(easy, CURLM_STATE_DOING);
1192
1177
            disconnect_conn = TRUE;
1193
1178
          }
1194
1179
          else
1195
 
            retry = newurl?TRUE:FALSE;
 
1180
            retry = (bool)(newurl?TRUE:FALSE);
1196
1181
 
1197
1182
          Curl_posttransfer(easy->easy_handle);
1198
1183
          drc = Curl_done(&easy->easy_conn, easy->result, FALSE);
1310
1295
      }
1311
1296
#ifdef DEBUGBUILD
1312
1297
      else {
1313
 
        infof(easy->easy_handle, "Conn %d recv pipe %d inuse %d athead %d\n",
 
1298
        infof(easy->easy_handle, "Conn %ld recv pipe %zu inuse %d athead %d\n",
1314
1299
              easy->easy_conn->connectindex,
1315
1300
              easy->easy_conn->recv_pipe->size,
1316
 
              easy->easy_conn->readchannel_inuse,
 
1301
              easy->easy_conn->readchannel_inuse?1:0,
1317
1302
              isHandleAtHead(easy->easy_handle,
1318
 
                             easy->easy_conn->recv_pipe));
 
1303
                             easy->easy_conn->recv_pipe)?1:0);
1319
1304
      }
1320
1305
#endif
1321
1306
      break;
1364
1349
        easy->easy_conn->writechannel_inuse = FALSE;
1365
1350
      }
1366
1351
 
1367
 
      if(easy->result)  {
 
1352
      if(easy->result) {
1368
1353
        /* The transfer phase returned error, we mark the connection to get
1369
1354
         * closed to prevent being re-used. This is because we can't possibly
1370
1355
         * know if the connection is in a good shape or not now.  Unless it is
1384
1369
 
1385
1370
        easy->result = Curl_retry_request(easy->easy_conn, &newurl);
1386
1371
        if(!easy->result)
1387
 
          retry = newurl?TRUE:FALSE;
 
1372
          retry = (bool)(newurl?TRUE:FALSE);
1388
1373
 
1389
1374
        /* call this even if the readwrite function returned error */
1390
1375
        Curl_posttransfer(easy->easy_handle);
1475
1460
          easy->easy_conn = NULL;
1476
1461
      }
1477
1462
 
 
1463
      if(easy->easy_handle->set.wildcardmatch) {
 
1464
        if(easy->easy_handle->wildcard.state != CURLWC_DONE) {
 
1465
          /* if a wildcard is set and we are not ending -> lets start again
 
1466
             with CURLM_STATE_INIT */
 
1467
          result = CURLM_CALL_MULTI_PERFORM;
 
1468
          multistate(easy, CURLM_STATE_INIT);
 
1469
          break;
 
1470
        }
 
1471
      }
 
1472
 
1478
1473
      /* after we have DONE what we're supposed to do, go COMPLETED, and
1479
1474
         it doesn't matter what the Curl_done() returned! */
1480
1475
      multistate(easy, CURLM_STATE_COMPLETED);
1559
1554
    multi->num_msgs++; /* increase message counter */
1560
1555
  }
1561
1556
 
1562
 
  if(CURLM_CALL_MULTI_PERFORM == result)
1563
 
    /* Set the timeout for this handle to expire really soon so that it will
1564
 
       be taken care of even when this handle is added in the midst of
1565
 
       operation when only the curl_multi_socket() API is used. During that
1566
 
       flow, only sockets that time-out or have actions will be dealt
1567
 
       with. Since this handle has no action yet, we make sure it times out to
1568
 
       get things to happen. Also, this makes it less important for callers of
1569
 
       the curl_multi_* functions to bother about the CURLM_CALL_MULTI_PERFORM
1570
 
       return code, as long as they deal with the timeouts properly. */
1571
 
    Curl_expire(easy->easy_handle, 1);
1572
 
 
1573
1557
  return result;
1574
1558
}
1575
1559
 
1587
1571
  easy=multi->easy.next;
1588
1572
  while(easy != &multi->easy) {
1589
1573
    CURLMcode result;
1590
 
 
1591
 
    result = multi_runsingle(multi, easy);
 
1574
    struct WildcardData *wc = &easy->easy_handle->wildcard;
 
1575
 
 
1576
    if(easy->easy_handle->set.wildcardmatch) {
 
1577
      if(!wc->filelist) {
 
1578
        CURLcode ret = Curl_wildcard_init(wc); /* init wildcard structures */
 
1579
        if(ret)
 
1580
          return CURLM_OUT_OF_MEMORY;
 
1581
      }
 
1582
    }
 
1583
 
 
1584
    do
 
1585
      result = multi_runsingle(multi, easy);
 
1586
    while (CURLM_CALL_MULTI_PERFORM == result);
 
1587
 
 
1588
    if(easy->easy_handle->set.wildcardmatch) {
 
1589
      /* destruct wildcard structures if it is needed */
 
1590
      if(wc->state == CURLWC_DONE || result)
 
1591
        Curl_wildcard_dtor(wc);
 
1592
    }
 
1593
 
1592
1594
    if(result)
1593
1595
      returncode = result;
1594
1596
 
1750
1752
  struct Curl_one_easy *easy_by_hash;
1751
1753
  bool remove_sock_from_hash;
1752
1754
 
1753
 
  memset(&socks, 0, sizeof(socks));
1754
1755
  for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++)
1755
1756
    socks[i] = CURL_SOCKET_BAD;
1756
1757
 
1792
1793
        return;
1793
1794
    }
1794
1795
 
 
1796
    /* we know (entry != NULL) at this point, see the logic above */
1795
1797
    multi->socket_cb(easy->easy_handle,
1796
1798
                     s,
1797
1799
                     action,
1798
1800
                     multi->socket_userp,
1799
 
                     entry ? entry->socketp : NULL);
 
1801
                     entry->socketp);
1800
1802
 
1801
1803
    entry->action = action; /* store the current action state */
1802
1804
  }
1948
1950
      if(data->set.one_easy->easy_conn)  /* set socket event bitmask */
1949
1951
        data->set.one_easy->easy_conn->cselect_bits = ev_bitmask;
1950
1952
 
1951
 
      result = multi_runsingle(multi, data->set.one_easy);
 
1953
      do
 
1954
        result = multi_runsingle(multi, data->set.one_easy);
 
1955
      while (CURLM_CALL_MULTI_PERFORM == result);
1952
1956
 
1953
1957
      if(data->set.one_easy->easy_conn)
1954
1958
        data->set.one_easy->easy_conn->cselect_bits = 0;
1977
1981
 
1978
1982
    /* the first loop lap 'data' can be NULL */
1979
1983
    if(data) {
1980
 
      result = multi_runsingle(multi, data->set.one_easy);
 
1984
      do
 
1985
        result = multi_runsingle(multi, data->set.one_easy);
 
1986
      while (CURLM_CALL_MULTI_PERFORM == result);
1981
1987
 
1982
1988
      if(CURLM_OK >= result)
1983
1989
        /* get the socket(s) and check if the state has been changed since
1989
1995
       extracts a matching node if there is one */
1990
1996
 
1991
1997
    now = Curl_tvnow();
1992
 
    now.tv_usec += 1000; /* to compensate for the truncating of 999us to 0ms,
1993
 
                            we always add time here to make the comparison
1994
 
                            below better */
 
1998
    now.tv_usec += 40000; /* compensate for bad precision timers */
 
1999
    if(now.tv_usec > 1000000) {
 
2000
      now.tv_sec++;
 
2001
      now.tv_usec -= 1000000;
 
2002
    }
1995
2003
 
1996
2004
    multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
1997
2005
    if(t) {
2369
2377
  return CURLM_OK;
2370
2378
}
2371
2379
 
2372
 
static bool multi_conn_using(struct Curl_multi *multi,
2373
 
                             struct SessionHandle *data)
 
2380
static void multi_connc_remove_handle(struct Curl_multi *multi,
 
2381
                                      struct SessionHandle *data)
2374
2382
{
2375
 
  /* any live CLOSEACTION-connections pointing to the give 'data' ? */
 
2383
  /* a connection in the connection cache pointing to the given 'data' ? */
2376
2384
  int i;
2377
2385
 
2378
2386
  for(i=0; i< multi->connc->num; i++) {
2379
 
    if(multi->connc->connects[i] &&
2380
 
       (multi->connc->connects[i]->data == data) &&
2381
 
       multi->connc->connects[i]->protocol & PROT_CLOSEACTION)
2382
 
      return TRUE;
 
2387
    struct connectdata * conn = multi->connc->connects[i];
 
2388
 
 
2389
    if(conn && conn->data == data) {
 
2390
      /* If this easy_handle was the last one in charge for one or more
 
2391
         connections in the shared connection cache, we might need to keep
 
2392
         this handle around until either A) the connection is closed and
 
2393
         killed properly, or B) another easy_handle uses the connection.
 
2394
 
 
2395
         The reason why we need to have a easy_handle associated with a live
 
2396
         connection is simply that some connections will need a handle to get
 
2397
         closed down properly. Currently, the only connections that need to
 
2398
         keep a easy_handle handle around are using FTP(S). Such connections
 
2399
         have the PROT_CLOSEACTION bit set.
 
2400
 
 
2401
         Thus, we need to check for all connections in the shared cache that
 
2402
         points to this handle and are using PROT_CLOSEACTION. If there's any,
 
2403
         we need to add this handle to the list of "easy handles kept around
 
2404
         for nice connection closures".
 
2405
      */
 
2406
 
 
2407
      if(conn->protocol & PROT_CLOSEACTION) {
 
2408
        /* this handle is still being used by a shared connection and
 
2409
           thus we leave it around for now */
 
2410
        if(add_closure(multi, data) == CURLM_OK)
 
2411
          data->state.shared_conn = multi;
 
2412
        else {
 
2413
          /* out of memory - so much for graceful shutdown */
 
2414
          Curl_disconnect(conn);
 
2415
          multi->connc->connects[i] = NULL;
 
2416
        }
 
2417
      }
 
2418
      else
 
2419
        /* disconect the easy handle from the connection since the connection
 
2420
           will now remain but this easy handle is going */
 
2421
        conn->data = NULL;
 
2422
    }
2383
2423
  }
2384
 
 
2385
 
  return FALSE;
2386
2424
}
2387
2425
 
2388
2426
/* Add the given data pointer to the list of 'closure handles' that are kept
2389
2427
   around only to be able to close some connections nicely - just make sure
2390
2428
   that this handle isn't already added, like for the cases when an easy
2391
2429
   handle is removed, added and removed again... */
2392
 
static void add_closure(struct Curl_multi *multi,
2393
 
                        struct SessionHandle *data)
 
2430
static CURLMcode add_closure(struct Curl_multi *multi,
 
2431
                             struct SessionHandle *data)
2394
2432
{
2395
 
  int i;
2396
 
  struct closure *cl = calloc(sizeof(struct closure), 1);
2397
 
  struct closure *p=NULL;
2398
 
  struct closure *n;
2399
 
  if(cl) {
2400
 
    cl->easy_handle = data;
2401
 
    cl->next = multi->closure;
2402
 
    multi->closure = cl;
2403
 
  }
2404
 
 
2405
 
  p = multi->closure;
2406
 
  cl = p->next; /* start immediately on the second since the first is the one
2407
 
                   we just added and it is _very_ likely to actually exist
2408
 
                   used in the cache since that's the whole purpose of adding
2409
 
                   it to this list! */
2410
 
 
2411
 
  /* When adding, scan through all the other currently kept handles and see if
2412
 
     there are any connections still referring to them and kill them if not. */
 
2433
  struct closure *cl = multi->closure;
 
2434
  struct closure *p = NULL;
 
2435
  bool add = TRUE;
 
2436
 
 
2437
  /* Before adding, scan through all the other currently kept handles and see
 
2438
     if there are any connections still referring to them and kill them if
 
2439
     not. */
2413
2440
  while(cl) {
 
2441
    struct closure *n;
2414
2442
    bool inuse = FALSE;
 
2443
    int i;
 
2444
 
2415
2445
    for(i=0; i< multi->connc->num; i++) {
2416
2446
      if(multi->connc->connects[i] &&
2417
2447
         (multi->connc->connects[i]->data == cl->easy_handle)) {
2424
2454
 
2425
2455
    if(!inuse) {
2426
2456
      /* cl->easy_handle is now killable */
2427
 
      infof(data, "Delayed kill of easy handle %p\n", cl->easy_handle);
 
2457
 
2428
2458
      /* unmark it as not having a connection around that uses it anymore */
2429
2459
      cl->easy_handle->state.shared_conn= NULL;
2430
 
      Curl_close(cl->easy_handle);
 
2460
 
 
2461
      if(cl->easy_handle->state.closed) {
 
2462
        infof(data, "Delayed kill of easy handle %p\n", cl->easy_handle);
 
2463
        /* close handle only if curl_easy_cleanup() already has been called
 
2464
           for this easy handle */
 
2465
        Curl_close(cl->easy_handle);
 
2466
      }
2431
2467
      if(p)
2432
2468
        p->next = n;
2433
2469
      else
2434
2470
        multi->closure = n;
2435
2471
      free(cl);
2436
 
    }
2437
 
    else
 
2472
    } else {
 
2473
      if(cl->easy_handle == data)
 
2474
        add = FALSE;
 
2475
 
2438
2476
      p = cl;
 
2477
    }
2439
2478
 
2440
2479
    cl = n;
2441
2480
  }
2442
2481
 
 
2482
  if (add) {
 
2483
    cl = calloc(1, sizeof(struct closure));
 
2484
    if(!cl)
 
2485
      return CURLM_OUT_OF_MEMORY;
 
2486
 
 
2487
    cl->easy_handle = data;
 
2488
    cl->next = multi->closure;
 
2489
    multi->closure = cl;
 
2490
  }
 
2491
 
 
2492
  return CURLM_OK;
2443
2493
}
2444
2494
 
2445
2495
#ifdef DEBUGBUILD