1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/***************************************************************************
2e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *                                  _   _ ____  _
3e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *  Project                     ___| | | |  _ \| |
4e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *                             / __| | | | |_) | |
5e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *                            | (__| |_| |  _ <| |___
6e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *                             \___|\___/|_| \_\_____|
7e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
9e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is licensed as described in the file COPYING, which
12e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you should have received as part of this distribution. The terms
13d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html.
14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * copies of the Software, and permit persons to whom the Software is
17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * furnished to do so, under the terms of the COPYING file.
18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * KIND, either express or implied.
21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
22e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/
23e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
24e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_setup.h"
25e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
26e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include <curl/curl.h>
27e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
28e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "urldata.h"
29e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "url.h"
30e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "progress.h"
31e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "multiif.h"
32e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "pipeline.h"
33e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "sendf.h"
34e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "rawstr.h"
35e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
36e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_memory.h"
37e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* The last #include file should be: */
38e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "memdebug.h"
39e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
40e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstruct site_blacklist_entry {
41e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  char *hostname;
42e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  unsigned short port;
43e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET};
44e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
45e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void site_blacklist_llist_dtor(void *user, void *element)
46e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
47e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct site_blacklist_entry *entry = element;
48e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  (void)user;
49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
50e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  Curl_safefree(entry->hostname);
51e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  free(entry);
52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
53e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
54e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void server_blacklist_llist_dtor(void *user, void *element)
55e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
56e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  (void)user;
57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  free(element);
58e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
59e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
60e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymobool Curl_pipeline_penalized(struct Curl_easy *data,
61e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                             struct connectdata *conn)
62e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
63e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(data) {
64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    bool penalized = FALSE;
65e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    curl_off_t penalty_size =
66e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      Curl_multi_content_length_penalty_size(data->multi);
67e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    curl_off_t chunk_penalty_size =
68e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      Curl_multi_chunk_length_penalty_size(data->multi);
69e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    curl_off_t recv_size = -2; /* Make it easy to spot in the log */
70e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
71e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* Find the head of the recv pipe, if any */
72e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(conn->recv_pipe && conn->recv_pipe->head) {
73e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      struct Curl_easy *recv_handle = conn->recv_pipe->head->ptr;
74e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
75e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      recv_size = recv_handle->req.size;
76e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
77e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      if(penalty_size > 0 && recv_size > penalty_size)
78e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        penalized = TRUE;
79e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
80e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
81e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(chunk_penalty_size > 0 &&
82e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET       (curl_off_t)conn->chunk.datasize > chunk_penalty_size)
83e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      penalized = TRUE;
84e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
85e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
86e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n",
87e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          conn->connection_id, (void *)conn, recv_size,
88e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          conn->chunk.datasize, penalized?"TRUE":"FALSE");
89e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return penalized;
90e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
91e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return FALSE;
92e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
93e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
94e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymostatic CURLcode addHandleToPipeline(struct Curl_easy *data,
95e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                                    struct curl_llist *pipeline)
96e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
97e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
98e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return CURLE_OUT_OF_MEMORY;
99e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return CURLE_OK;
100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
101e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
102e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
103e3149cc1cf501b46caba8d47652ac90b95c78eacAlex DeymoCURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
104e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                                     struct connectdata *conn)
105e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
106e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct curl_llist_element *sendhead = conn->send_pipe->head;
107e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct curl_llist *pipeline;
108e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  CURLcode result;
109e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
110e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  pipeline = conn->send_pipe;
111e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
112e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  result = addHandleToPipeline(handle, pipeline);
113e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
114e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
115e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* this is a new one as head, expire it */
116e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    Curl_pipeline_leave_write(conn); /* not in use yet */
117e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    Curl_expire(conn->send_pipe->head->ptr, 1);
118e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
119e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
120e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#if 0 /* enable for pipeline debugging */
121e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  print_pipeline(conn);
122e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
123e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
124e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return result;
125e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
126e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
127e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* Move this transfer from the sending list to the receiving list.
128e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
129e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET   Pay special attention to the new sending list "leader" as it needs to get
130e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET   checked to update what sockets it acts on.
131e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
132e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET*/
133e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymovoid Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
134e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                                             struct connectdata *conn)
135e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
136e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct curl_llist_element *curr;
137e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
138e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  curr = conn->send_pipe->head;
139e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  while(curr) {
140e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(curr->ptr == handle) {
141e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      Curl_llist_move(conn->send_pipe, curr,
142e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                      conn->recv_pipe, conn->recv_pipe->tail);
143e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
144e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      if(conn->send_pipe->head) {
145e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        /* Since there's a new easy handle at the start of the send pipeline,
146e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET           set its timeout value to 1ms to make it trigger instantly */
147e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        Curl_pipeline_leave_write(conn); /* not used now */
148e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef DEBUGBUILD
149e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        infof(conn->data, "%p is at send pipe head B!\n",
150e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET              (void *)conn->send_pipe->head->ptr);
151e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
152e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        Curl_expire(conn->send_pipe->head->ptr, 1);
153e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
154e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
155e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      /* The receiver's list is not really interesting here since either this
156e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET         handle is now first in the list and we'll deal with it soon, or
157e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET         another handle is already first and thus is already taken care of */
158e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
159e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      break; /* we're done! */
160e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
161e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    curr = curr->next;
162e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
163e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
164e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
165e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymobool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
166e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                                    struct connectdata *conn)
167e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
168e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(handle->multi) {
169e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    struct curl_llist *blacklist =
170e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      Curl_multi_pipelining_site_bl(handle->multi);
171e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
172e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(blacklist) {
173e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      struct curl_llist_element *curr;
174e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
175e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      curr = blacklist->head;
176e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      while(curr) {
177e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        struct site_blacklist_entry *site;
178e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
179e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        site = curr->ptr;
180e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if(Curl_raw_equal(site->hostname, conn->host.name) &&
181e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET           site->port == conn->remote_port) {
182e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          infof(handle, "Site %s:%d is pipeline blacklisted\n",
183e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                conn->host.name, conn->remote_port);
184e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          return TRUE;
185e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
186e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        curr = curr->next;
187e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
188e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
189e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
190e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return FALSE;
191e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
192e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
193e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETCURLMcode Curl_pipeline_set_site_blacklist(char **sites,
194e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                                           struct curl_llist **list_ptr)
195e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
196e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct curl_llist *old_list = *list_ptr;
197e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct curl_llist *new_list = NULL;
198e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
199e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(sites) {
200e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor);
201e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(!new_list)
202e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      return CURLM_OUT_OF_MEMORY;
203e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
204e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* Parse the URLs and populate the list */
205e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    while(*sites) {
206e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      char *hostname;
207e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      char *port;
208e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      struct site_blacklist_entry *entry;
209e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
210e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      hostname = strdup(*sites);
211e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      if(!hostname) {
212e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        Curl_llist_destroy(new_list, NULL);
213e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        return CURLM_OUT_OF_MEMORY;
214e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
215e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
216e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      entry = malloc(sizeof(struct site_blacklist_entry));
217e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      if(!entry) {
218e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        free(hostname);
219e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        Curl_llist_destroy(new_list, NULL);
220e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        return CURLM_OUT_OF_MEMORY;
221e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
222e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
223e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      port = strchr(hostname, ':');
224e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      if(port) {
225e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        *port = '\0';
226e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        port++;
227e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        entry->port = (unsigned short)strtol(port, NULL, 10);
228e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
229e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      else {
230e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        /* Default port number for HTTP */
231e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        entry->port = 80;
232e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
233e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
234e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      entry->hostname = hostname;
235e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
236e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      if(!Curl_llist_insert_next(new_list, new_list->tail, entry)) {
237e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        site_blacklist_llist_dtor(NULL, entry);
238e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        Curl_llist_destroy(new_list, NULL);
239e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        return CURLM_OUT_OF_MEMORY;
240e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
241e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
242e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      sites++;
243e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
244e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
245e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
246e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  /* Free the old list */
247e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(old_list) {
248e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    Curl_llist_destroy(old_list, NULL);
249e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
250e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
251e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
252e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  *list_ptr = new_list;
253e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
254e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return CURLM_OK;
255e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
256e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
257e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymobool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
258e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                                      char *server_name)
259e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
260e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(handle->multi && server_name) {
261e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    struct curl_llist *blacklist =
262e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      Curl_multi_pipelining_server_bl(handle->multi);
263e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
264e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(blacklist) {
265e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      struct curl_llist_element *curr;
266e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
267e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      curr = blacklist->head;
268e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      while(curr) {
269e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        char *bl_server_name;
270e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
271e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        bl_server_name = curr->ptr;
272e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if(Curl_raw_nequal(bl_server_name, server_name,
273e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                           strlen(bl_server_name))) {
274e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          infof(handle, "Server %s is blacklisted\n", server_name);
275e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET          return TRUE;
276e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
277e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        curr = curr->next;
278e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      }
279e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
280e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
281e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name));
282e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
283e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return FALSE;
284e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
285e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
286e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETCURLMcode Curl_pipeline_set_server_blacklist(char **servers,
287e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                                             struct curl_llist **list_ptr)
288e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
289e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct curl_llist *old_list = *list_ptr;
290e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct curl_llist *new_list = NULL;
291e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
292e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(servers) {
293e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor);
294e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(!new_list)
295e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      return CURLM_OUT_OF_MEMORY;
296e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
297e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* Parse the URLs and populate the list */
298e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    while(*servers) {
299e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      char *server_name;
300e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
301e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      server_name = strdup(*servers);
302e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      if(!server_name) {
303e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo        Curl_llist_destroy(new_list, NULL);
304e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        return CURLM_OUT_OF_MEMORY;
305e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      }
306e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
307e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      if(!Curl_llist_insert_next(new_list, new_list->tail, server_name)) {
308e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo        Curl_llist_destroy(new_list, NULL);
309e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo        Curl_safefree(server_name);
310e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        return CURLM_OUT_OF_MEMORY;
311e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      }
312e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
313e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      servers++;
314e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
315e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
316e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
317e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  /* Free the old list */
318e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(old_list) {
319e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    Curl_llist_destroy(old_list, NULL);
320e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
321e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
322e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
323e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  *list_ptr = new_list;
324e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
325e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return CURLM_OK;
326e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
327e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
328e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymostatic bool pipe_head(struct Curl_easy *data,
329e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                      struct curl_llist *pipeline)
330e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
331d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo  if(pipeline) {
332d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo    struct curl_llist_element *curr = pipeline->head;
333d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo    if(curr)
334d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo      return (curr->ptr == data) ? TRUE : FALSE;
335d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo  }
336e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return FALSE;
337e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
338e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
339e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* returns TRUE if the given handle is head of the recv pipe */
340e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymobool Curl_recvpipe_head(struct Curl_easy *data,
341e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                        struct connectdata *conn)
342e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
343e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return pipe_head(data, conn->recv_pipe);
344e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
345e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
346e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* returns TRUE if the given handle is head of the send pipe */
347e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymobool Curl_sendpipe_head(struct Curl_easy *data,
348e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                        struct connectdata *conn)
349e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
350e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return pipe_head(data, conn->send_pipe);
351e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
352e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
353e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
354e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*
355e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Check if the write channel is available and this handle as at the head,
356e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * then grab the channel and return TRUE.
357e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
358e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * If not available, return FALSE.
359e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */
360e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
361e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymobool Curl_pipeline_checkget_write(struct Curl_easy *data,
362e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                                  struct connectdata *conn)
363e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
364e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(conn->bits.multiplex)
365e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* when multiplexing, we can use it at once */
366e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return TRUE;
367e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
368e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) {
369e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* Grab the channel */
370e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    conn->writechannel_inuse = TRUE;
371e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return TRUE;
372e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
373e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return FALSE;
374e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
375e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
376e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
377e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*
378e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Check if the read channel is available and this handle as at the head, then
379e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * grab the channel and return TRUE.
380e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
381e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * If not available, return FALSE.
382e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */
383e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
384e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymobool Curl_pipeline_checkget_read(struct Curl_easy *data,
385e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                                 struct connectdata *conn)
386e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
387e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(conn->bits.multiplex)
388e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* when multiplexing, we can use it at once */
389e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return TRUE;
390e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
391e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) {
392e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* Grab the channel */
393e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    conn->readchannel_inuse = TRUE;
394e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return TRUE;
395e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
396e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return FALSE;
397e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
398e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
399e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*
400e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * The current user of the pipeline write channel gives it up.
401e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */
402e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETvoid Curl_pipeline_leave_write(struct connectdata *conn)
403e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
404e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  conn->writechannel_inuse = FALSE;
405e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
406e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
407e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*
408e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * The current user of the pipeline read channel gives it up.
409e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */
410e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETvoid Curl_pipeline_leave_read(struct connectdata *conn)
411e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
412e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  conn->readchannel_inuse = FALSE;
413e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
414e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
415e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
416e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#if 0
417e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETvoid print_pipeline(struct connectdata *conn)
418e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
419e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct curl_llist_element *curr;
420e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct connectbundle *cb_ptr;
421e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo  struct Curl_easy *data = conn->data;
422e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
423e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  cb_ptr = conn->bundle;
424e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
425e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(cb_ptr) {
426e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    curr = cb_ptr->conn_list->head;
427e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    while(curr) {
428e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      conn = curr->ptr;
429e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n",
430e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            conn->connection_id,
431e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            (void *)conn,
432e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            conn->send_pipe->size,
433e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            conn->recv_pipe->size);
434e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      curr = curr->next;
435e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
436e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
437e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
438e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
439e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
440