cfilters.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at https://curl.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. * SPDX-License-Identifier: curl
  22. *
  23. ***************************************************************************/
  24. #include "curl_setup.h"
  25. #include "urldata.h"
  26. #include "strerror.h"
  27. #include "cfilters.h"
  28. #include "connect.h"
  29. #include "url.h"
  30. #include "sendf.h"
  31. #include "sockaddr.h" /* required for Curl_sockaddr_storage */
  32. #include "multiif.h"
  33. #include "progress.h"
  34. #include "select.h"
  35. #include "curlx/warnless.h"
  36. #include "curlx/strparse.h"
  37. /* The last 3 #include files should be in this order */
  38. #include "curl_printf.h"
  39. #include "curl_memory.h"
  40. #include "memdebug.h"
  41. static void cf_cntrl_update_info(struct Curl_easy *data,
  42. struct connectdata *conn);
  43. #ifdef UNITTESTS
  44. /* used by unit2600.c */
  45. void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data)
  46. {
  47. cf->connected = FALSE;
  48. if(cf->next)
  49. cf->next->cft->do_close(cf->next, data);
  50. }
  51. #endif
  52. CURLcode Curl_cf_def_shutdown(struct Curl_cfilter *cf,
  53. struct Curl_easy *data, bool *done)
  54. {
  55. (void)cf;
  56. (void)data;
  57. *done = TRUE;
  58. return CURLE_OK;
  59. }
  60. static void conn_report_connect_stats(struct Curl_easy *data,
  61. struct connectdata *conn);
  62. void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
  63. struct Curl_easy *data,
  64. struct easy_pollset *ps)
  65. {
  66. /* NOP */
  67. (void)cf;
  68. (void)data;
  69. (void)ps;
  70. }
  71. bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
  72. const struct Curl_easy *data)
  73. {
  74. return cf->next ?
  75. cf->next->cft->has_data_pending(cf->next, data) : FALSE;
  76. }
  77. CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  78. const void *buf, size_t len, bool eos,
  79. size_t *pnwritten)
  80. {
  81. if(cf->next)
  82. return cf->next->cft->do_send(cf->next, data, buf, len, eos, pnwritten);
  83. *pnwritten = 0;
  84. return CURLE_RECV_ERROR;
  85. }
  86. CURLcode Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  87. char *buf, size_t len, size_t *pnread)
  88. {
  89. if(cf->next)
  90. return cf->next->cft->do_recv(cf->next, data, buf, len, pnread);
  91. *pnread = 0;
  92. return CURLE_SEND_ERROR;
  93. }
  94. bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
  95. struct Curl_easy *data,
  96. bool *input_pending)
  97. {
  98. return cf->next ?
  99. cf->next->cft->is_alive(cf->next, data, input_pending) :
  100. FALSE; /* pessimistic in absence of data */
  101. }
  102. CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
  103. struct Curl_easy *data)
  104. {
  105. return cf->next ?
  106. cf->next->cft->keep_alive(cf->next, data) :
  107. CURLE_OK;
  108. }
  109. CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
  110. struct Curl_easy *data,
  111. int query, int *pres1, void *pres2)
  112. {
  113. return cf->next ?
  114. cf->next->cft->query(cf->next, data, query, pres1, pres2) :
  115. CURLE_UNKNOWN_OPTION;
  116. }
  117. void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
  118. struct Curl_easy *data)
  119. {
  120. struct Curl_cfilter *cfn, *cf = *pcf;
  121. if(cf) {
  122. *pcf = NULL;
  123. while(cf) {
  124. cfn = cf->next;
  125. /* prevent destroying filter to mess with its sub-chain, since
  126. * we have the reference now and will call destroy on it.
  127. */
  128. cf->next = NULL;
  129. cf->cft->destroy(cf, data);
  130. free(cf);
  131. cf = cfn;
  132. }
  133. }
  134. }
  135. void Curl_conn_cf_discard_all(struct Curl_easy *data,
  136. struct connectdata *conn, int index)
  137. {
  138. Curl_conn_cf_discard_chain(&conn->cfilter[index], data);
  139. }
  140. void Curl_conn_close(struct Curl_easy *data, int index)
  141. {
  142. struct Curl_cfilter *cf;
  143. DEBUGASSERT(data->conn);
  144. /* it is valid to call that without filters being present */
  145. cf = data->conn->cfilter[index];
  146. if(cf) {
  147. cf->cft->do_close(cf, data);
  148. }
  149. Curl_shutdown_clear(data, index);
  150. }
  151. CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done)
  152. {
  153. struct Curl_cfilter *cf;
  154. CURLcode result = CURLE_OK;
  155. timediff_t timeout_ms;
  156. struct curltime now;
  157. DEBUGASSERT(data->conn);
  158. /* Get the first connected filter that is not shut down already. */
  159. cf = data->conn->cfilter[sockindex];
  160. while(cf && (!cf->connected || cf->shutdown))
  161. cf = cf->next;
  162. if(!cf) {
  163. *done = TRUE;
  164. return CURLE_OK;
  165. }
  166. *done = FALSE;
  167. now = curlx_now();
  168. if(!Curl_shutdown_started(data, sockindex)) {
  169. CURL_TRC_M(data, "shutdown start on%s connection",
  170. sockindex ? " secondary" : "");
  171. Curl_shutdown_start(data, sockindex, 0, &now);
  172. }
  173. else {
  174. timeout_ms = Curl_shutdown_timeleft(data->conn, sockindex, &now);
  175. if(timeout_ms < 0) {
  176. /* info message, since this might be regarded as acceptable */
  177. infof(data, "shutdown timeout");
  178. return CURLE_OPERATION_TIMEDOUT;
  179. }
  180. }
  181. while(cf) {
  182. if(!cf->shutdown) {
  183. bool cfdone = FALSE;
  184. result = cf->cft->do_shutdown(cf, data, &cfdone);
  185. if(result) {
  186. CURL_TRC_CF(data, cf, "shut down failed with %d", result);
  187. return result;
  188. }
  189. else if(!cfdone) {
  190. CURL_TRC_CF(data, cf, "shut down not done yet");
  191. return CURLE_OK;
  192. }
  193. CURL_TRC_CF(data, cf, "shut down successfully");
  194. cf->shutdown = TRUE;
  195. }
  196. cf = cf->next;
  197. }
  198. *done = (!result);
  199. return result;
  200. }
  201. CURLcode Curl_cf_recv(struct Curl_easy *data, int num, char *buf,
  202. size_t len, size_t *pnread)
  203. {
  204. struct Curl_cfilter *cf;
  205. DEBUGASSERT(data);
  206. DEBUGASSERT(data->conn);
  207. cf = data->conn->cfilter[num];
  208. while(cf && !cf->connected)
  209. cf = cf->next;
  210. if(cf)
  211. return cf->cft->do_recv(cf, data, buf, len, pnread);
  212. failf(data, "recv: no filter connected");
  213. DEBUGASSERT(0);
  214. *pnread = 0;
  215. return CURLE_FAILED_INIT;
  216. }
  217. CURLcode Curl_cf_send(struct Curl_easy *data, int num,
  218. const void *mem, size_t len, bool eos,
  219. size_t *pnwritten)
  220. {
  221. struct Curl_cfilter *cf;
  222. DEBUGASSERT(data);
  223. DEBUGASSERT(data->conn);
  224. cf = data->conn->cfilter[num];
  225. while(cf && !cf->connected)
  226. cf = cf->next;
  227. if(cf) {
  228. return cf->cft->do_send(cf, data, mem, len, eos, pnwritten);
  229. }
  230. failf(data, "send: no filter connected");
  231. DEBUGASSERT(0);
  232. *pnwritten = 0;
  233. return CURLE_FAILED_INIT;
  234. }
  235. struct cf_io_ctx {
  236. struct Curl_easy *data;
  237. struct Curl_cfilter *cf;
  238. };
  239. static CURLcode cf_bufq_reader(void *writer_ctx,
  240. unsigned char *buf, size_t blen,
  241. size_t *pnread)
  242. {
  243. struct cf_io_ctx *io = writer_ctx;
  244. return Curl_conn_cf_recv(io->cf, io->data, (char *)buf, blen, pnread);
  245. }
  246. CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf,
  247. struct Curl_easy *data,
  248. struct bufq *bufq,
  249. size_t maxlen,
  250. size_t *pnread)
  251. {
  252. struct cf_io_ctx io;
  253. if(!cf || !data) {
  254. *pnread = 0;
  255. return CURLE_BAD_FUNCTION_ARGUMENT;
  256. }
  257. io.data = data;
  258. io.cf = cf;
  259. return Curl_bufq_sipn(bufq, maxlen, cf_bufq_reader, &io, pnread);
  260. }
  261. static CURLcode cf_bufq_writer(void *writer_ctx,
  262. const unsigned char *buf, size_t buflen,
  263. size_t *pnwritten)
  264. {
  265. struct cf_io_ctx *io = writer_ctx;
  266. return Curl_conn_cf_send(io->cf, io->data, (const char *)buf,
  267. buflen, FALSE, pnwritten);
  268. }
  269. CURLcode Curl_cf_send_bufq(struct Curl_cfilter *cf,
  270. struct Curl_easy *data,
  271. struct bufq *bufq,
  272. const unsigned char *buf, size_t blen,
  273. size_t *pnwritten)
  274. {
  275. struct cf_io_ctx io;
  276. if(!cf || !data) {
  277. *pnwritten = 0;
  278. return CURLE_BAD_FUNCTION_ARGUMENT;
  279. }
  280. io.data = data;
  281. io.cf = cf;
  282. if(buf && blen)
  283. return Curl_bufq_write_pass(bufq, buf, blen, cf_bufq_writer, &io,
  284. pnwritten);
  285. else
  286. return Curl_bufq_pass(bufq, cf_bufq_writer, &io, pnwritten);
  287. }
  288. CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
  289. const struct Curl_cftype *cft,
  290. void *ctx)
  291. {
  292. struct Curl_cfilter *cf;
  293. CURLcode result = CURLE_OUT_OF_MEMORY;
  294. DEBUGASSERT(cft);
  295. cf = calloc(1, sizeof(*cf));
  296. if(!cf)
  297. goto out;
  298. cf->cft = cft;
  299. cf->ctx = ctx;
  300. result = CURLE_OK;
  301. out:
  302. *pcf = cf;
  303. return result;
  304. }
  305. void Curl_conn_cf_add(struct Curl_easy *data,
  306. struct connectdata *conn,
  307. int index,
  308. struct Curl_cfilter *cf)
  309. {
  310. (void)data;
  311. DEBUGASSERT(conn);
  312. DEBUGASSERT(!cf->conn);
  313. DEBUGASSERT(!cf->next);
  314. cf->next = conn->cfilter[index];
  315. cf->conn = conn;
  316. cf->sockindex = index;
  317. conn->cfilter[index] = cf;
  318. CURL_TRC_CF(data, cf, "added");
  319. }
  320. void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
  321. struct Curl_cfilter *cf_new)
  322. {
  323. struct Curl_cfilter *tail, **pnext;
  324. DEBUGASSERT(cf_at);
  325. DEBUGASSERT(cf_new);
  326. DEBUGASSERT(!cf_new->conn);
  327. tail = cf_at->next;
  328. cf_at->next = cf_new;
  329. do {
  330. cf_new->conn = cf_at->conn;
  331. cf_new->sockindex = cf_at->sockindex;
  332. pnext = &cf_new->next;
  333. cf_new = cf_new->next;
  334. } while(cf_new);
  335. *pnext = tail;
  336. }
  337. bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf,
  338. struct Curl_cfilter *discard,
  339. struct Curl_easy *data,
  340. bool destroy_always)
  341. {
  342. struct Curl_cfilter **pprev = &cf->next;
  343. bool found = FALSE;
  344. /* remove from sub-chain and destroy */
  345. DEBUGASSERT(cf);
  346. while(*pprev) {
  347. if(*pprev == cf) {
  348. *pprev = discard->next;
  349. discard->next = NULL;
  350. found = TRUE;
  351. break;
  352. }
  353. pprev = &((*pprev)->next);
  354. }
  355. if(found || destroy_always) {
  356. discard->next = NULL;
  357. discard->cft->destroy(discard, data);
  358. free(discard);
  359. }
  360. return found;
  361. }
  362. CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
  363. struct Curl_easy *data,
  364. bool *done)
  365. {
  366. if(cf)
  367. return cf->cft->do_connect(cf, data, done);
  368. return CURLE_FAILED_INIT;
  369. }
  370. void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data)
  371. {
  372. if(cf)
  373. cf->cft->do_close(cf, data);
  374. }
  375. CURLcode Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  376. const void *buf, size_t len, bool eos,
  377. size_t *pnwritten)
  378. {
  379. if(cf)
  380. return cf->cft->do_send(cf, data, buf, len, eos, pnwritten);
  381. *pnwritten = 0;
  382. return CURLE_SEND_ERROR;
  383. }
  384. CURLcode Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  385. char *buf, size_t len, size_t *pnread)
  386. {
  387. if(cf)
  388. return cf->cft->do_recv(cf, data, buf, len, pnread);
  389. *pnread = 0;
  390. return CURLE_RECV_ERROR;
  391. }
  392. CURLcode Curl_conn_connect(struct Curl_easy *data,
  393. int sockindex,
  394. bool blocking,
  395. bool *done)
  396. {
  397. #define CF_CONN_NUM_POLLS_ON_STACK 5
  398. struct pollfd a_few_on_stack[CF_CONN_NUM_POLLS_ON_STACK];
  399. struct curl_pollfds cpfds;
  400. struct Curl_cfilter *cf;
  401. CURLcode result = CURLE_OK;
  402. DEBUGASSERT(data);
  403. DEBUGASSERT(data->conn);
  404. cf = data->conn->cfilter[sockindex];
  405. if(!cf) {
  406. *done = FALSE;
  407. return CURLE_FAILED_INIT;
  408. }
  409. *done = cf->connected;
  410. if(*done)
  411. return CURLE_OK;
  412. Curl_pollfds_init(&cpfds, a_few_on_stack, CF_CONN_NUM_POLLS_ON_STACK);
  413. while(!*done) {
  414. if(Curl_conn_needs_flush(data, sockindex)) {
  415. DEBUGF(infof(data, "Curl_conn_connect(index=%d), flush", sockindex));
  416. result = Curl_conn_flush(data, sockindex);
  417. if(result && (result != CURLE_AGAIN))
  418. return result;
  419. }
  420. result = cf->cft->do_connect(cf, data, done);
  421. CURL_TRC_CF(data, cf, "Curl_conn_connect(block=%d) -> %d, done=%d",
  422. blocking, result, *done);
  423. if(!result && *done) {
  424. /* Now that the complete filter chain is connected, let all filters
  425. * persist information at the connection. E.g. cf-socket sets the
  426. * socket and ip related information. */
  427. cf_cntrl_update_info(data, data->conn);
  428. conn_report_connect_stats(data, data->conn);
  429. data->conn->keepalive = curlx_now();
  430. Curl_verboseconnect(data, data->conn, sockindex);
  431. goto out;
  432. }
  433. else if(result) {
  434. CURL_TRC_CF(data, cf, "Curl_conn_connect(), filter returned %d",
  435. result);
  436. conn_report_connect_stats(data, data->conn);
  437. goto out;
  438. }
  439. if(!blocking)
  440. goto out;
  441. else {
  442. /* check allowed time left */
  443. const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
  444. curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
  445. struct easy_pollset ps;
  446. int rc;
  447. if(timeout_ms < 0) {
  448. /* no need to continue if time already is up */
  449. failf(data, "connect timeout");
  450. result = CURLE_OPERATION_TIMEDOUT;
  451. goto out;
  452. }
  453. CURL_TRC_CF(data, cf, "Curl_conn_connect(block=1), do poll");
  454. Curl_pollfds_reset(&cpfds);
  455. memset(&ps, 0, sizeof(ps));
  456. /* In general, we want to send after connect, wait on that. */
  457. if(sockfd != CURL_SOCKET_BAD)
  458. Curl_pollset_set_out_only(data, &ps, sockfd);
  459. Curl_conn_adjust_pollset(data, data->conn, &ps);
  460. result = Curl_pollfds_add_ps(&cpfds, &ps);
  461. if(result)
  462. goto out;
  463. rc = Curl_poll(cpfds.pfds, cpfds.n,
  464. CURLMIN(timeout_ms, (cpfds.n ? 1000 : 10)));
  465. CURL_TRC_CF(data, cf, "Curl_conn_connect(block=1), Curl_poll() -> %d",
  466. rc);
  467. if(rc < 0) {
  468. result = CURLE_COULDNT_CONNECT;
  469. goto out;
  470. }
  471. /* continue iterating */
  472. }
  473. }
  474. out:
  475. Curl_pollfds_cleanup(&cpfds);
  476. return result;
  477. }
  478. bool Curl_conn_is_setup(struct connectdata *conn, int sockindex)
  479. {
  480. return (conn->cfilter[sockindex] != NULL);
  481. }
  482. bool Curl_conn_is_connected(struct connectdata *conn, int sockindex)
  483. {
  484. struct Curl_cfilter *cf;
  485. cf = conn->cfilter[sockindex];
  486. return cf && cf->connected;
  487. }
  488. bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex)
  489. {
  490. struct Curl_cfilter *cf;
  491. cf = data->conn->cfilter[sockindex];
  492. while(cf) {
  493. if(cf->connected)
  494. return TRUE;
  495. if(cf->cft->flags & CF_TYPE_IP_CONNECT)
  496. return FALSE;
  497. cf = cf->next;
  498. }
  499. return FALSE;
  500. }
  501. bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf)
  502. {
  503. for(; cf; cf = cf->next) {
  504. if(cf->cft->flags & CF_TYPE_SSL)
  505. return TRUE;
  506. if(cf->cft->flags & CF_TYPE_IP_CONNECT)
  507. return FALSE;
  508. }
  509. return FALSE;
  510. }
  511. bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex)
  512. {
  513. return conn ? Curl_conn_cf_is_ssl(conn->cfilter[sockindex]) : FALSE;
  514. }
  515. bool Curl_conn_get_ssl_info(struct Curl_easy *data,
  516. struct connectdata *conn, int sockindex,
  517. struct curl_tlssessioninfo *info)
  518. {
  519. if(Curl_conn_is_ssl(conn, sockindex)) {
  520. struct Curl_cfilter *cf = conn->cfilter[sockindex];
  521. CURLcode result = cf ? cf->cft->query(cf, data, CF_QUERY_SSL_INFO,
  522. NULL, (void *)info) : CURLE_UNKNOWN_OPTION;
  523. return !result;
  524. }
  525. return FALSE;
  526. }
  527. bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex)
  528. {
  529. struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL;
  530. for(; cf; cf = cf->next) {
  531. if(cf->cft->flags & CF_TYPE_MULTIPLEX)
  532. return TRUE;
  533. if(cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_SSL))
  534. return FALSE;
  535. }
  536. return FALSE;
  537. }
  538. unsigned char Curl_conn_get_transport(struct Curl_easy *data,
  539. struct connectdata *conn)
  540. {
  541. struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
  542. return Curl_conn_cf_get_transport(cf, data);
  543. }
  544. unsigned char Curl_conn_http_version(struct Curl_easy *data,
  545. struct connectdata *conn)
  546. {
  547. struct Curl_cfilter *cf;
  548. CURLcode result = CURLE_UNKNOWN_OPTION;
  549. unsigned char v = 0;
  550. cf = conn->cfilter[FIRSTSOCKET];
  551. for(; cf; cf = cf->next) {
  552. if(cf->cft->flags & CF_TYPE_HTTP) {
  553. int value = 0;
  554. result = cf->cft->query(cf, data, CF_QUERY_HTTP_VERSION, &value, NULL);
  555. if(!result && ((value < 0) || (value > 255)))
  556. result = CURLE_FAILED_INIT;
  557. else
  558. v = (unsigned char)value;
  559. break;
  560. }
  561. if(cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_SSL))
  562. break;
  563. }
  564. return (unsigned char)(result ? 0 : v);
  565. }
  566. bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
  567. {
  568. struct Curl_cfilter *cf;
  569. (void)data;
  570. DEBUGASSERT(data);
  571. DEBUGASSERT(data->conn);
  572. cf = data->conn->cfilter[sockindex];
  573. while(cf && !cf->connected) {
  574. cf = cf->next;
  575. }
  576. if(cf) {
  577. return cf->cft->has_data_pending(cf, data);
  578. }
  579. return FALSE;
  580. }
  581. bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf,
  582. struct Curl_easy *data)
  583. {
  584. CURLcode result;
  585. int pending = 0;
  586. result = cf ? cf->cft->query(cf, data, CF_QUERY_NEED_FLUSH,
  587. &pending, NULL) : CURLE_UNKNOWN_OPTION;
  588. return (result || !pending) ? FALSE : TRUE;
  589. }
  590. bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex)
  591. {
  592. return Curl_conn_cf_needs_flush(data->conn->cfilter[sockindex], data);
  593. }
  594. void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
  595. struct Curl_easy *data,
  596. struct easy_pollset *ps)
  597. {
  598. /* Get the lowest not-connected filter, if there are any */
  599. while(cf && !cf->connected && cf->next && !cf->next->connected)
  600. cf = cf->next;
  601. /* Skip all filters that have already shut down */
  602. while(cf && cf->shutdown)
  603. cf = cf->next;
  604. /* From there on, give all filters a chance to adjust the pollset.
  605. * Lower filters are called later, so they may override */
  606. while(cf) {
  607. cf->cft->adjust_pollset(cf, data, ps);
  608. cf = cf->next;
  609. }
  610. }
  611. void Curl_conn_adjust_pollset(struct Curl_easy *data,
  612. struct connectdata *conn,
  613. struct easy_pollset *ps)
  614. {
  615. int i;
  616. DEBUGASSERT(data);
  617. DEBUGASSERT(conn);
  618. for(i = 0; i < 2; ++i) {
  619. Curl_conn_cf_adjust_pollset(conn->cfilter[i], data, ps);
  620. }
  621. }
  622. int Curl_conn_cf_poll(struct Curl_cfilter *cf,
  623. struct Curl_easy *data,
  624. timediff_t timeout_ms)
  625. {
  626. struct easy_pollset ps;
  627. struct pollfd pfds[MAX_SOCKSPEREASYHANDLE];
  628. unsigned int i, npfds = 0;
  629. DEBUGASSERT(cf);
  630. DEBUGASSERT(data);
  631. DEBUGASSERT(data->conn);
  632. memset(&ps, 0, sizeof(ps));
  633. memset(pfds, 0, sizeof(pfds));
  634. Curl_conn_cf_adjust_pollset(cf, data, &ps);
  635. DEBUGASSERT(ps.num <= MAX_SOCKSPEREASYHANDLE);
  636. for(i = 0; i < ps.num; ++i) {
  637. short events = 0;
  638. if(ps.actions[i] & CURL_POLL_IN) {
  639. events |= POLLIN;
  640. }
  641. if(ps.actions[i] & CURL_POLL_OUT) {
  642. events |= POLLOUT;
  643. }
  644. if(events) {
  645. pfds[npfds].fd = ps.sockets[i];
  646. pfds[npfds].events = events;
  647. ++npfds;
  648. }
  649. }
  650. if(!npfds)
  651. DEBUGF(infof(data, "no sockets to poll!"));
  652. return Curl_poll(pfds, npfds, timeout_ms);
  653. }
  654. void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex,
  655. const char **phost, int *pport)
  656. {
  657. struct Curl_cfilter *cf, *cf_proxy = NULL;
  658. DEBUGASSERT(data->conn);
  659. cf = data->conn->cfilter[sockindex];
  660. /* Find the "lowest" tunneling proxy filter that has not connected yet. */
  661. while(cf && !cf->connected) {
  662. if((cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_PROXY)) ==
  663. (CF_TYPE_IP_CONNECT|CF_TYPE_PROXY))
  664. cf_proxy = cf;
  665. cf = cf->next;
  666. }
  667. /* cf_proxy (!= NULL) is not connected yet. It is talking
  668. * to an interim host and any authentication or other things apply
  669. * to this interim host and port. */
  670. if(!cf_proxy || cf_proxy->cft->query(cf_proxy, data, CF_QUERY_HOST_PORT,
  671. pport, CURL_UNCONST(phost))) {
  672. /* Everything connected or query unsuccessful, the overall
  673. * connection's destination is the answer */
  674. *phost = data->conn->host.name;
  675. *pport = data->conn->remote_port;
  676. }
  677. }
  678. CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf,
  679. struct Curl_easy *data,
  680. int event, int arg1, void *arg2)
  681. {
  682. (void)cf;
  683. (void)data;
  684. (void)event;
  685. (void)arg1;
  686. (void)arg2;
  687. return CURLE_OK;
  688. }
  689. CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf,
  690. struct Curl_easy *data,
  691. bool ignore_result,
  692. int event, int arg1, void *arg2)
  693. {
  694. CURLcode result = CURLE_OK;
  695. for(; cf; cf = cf->next) {
  696. if(Curl_cf_def_cntrl == cf->cft->cntrl)
  697. continue;
  698. result = cf->cft->cntrl(cf, data, event, arg1, arg2);
  699. if(!ignore_result && result)
  700. break;
  701. }
  702. return result;
  703. }
  704. curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf,
  705. struct Curl_easy *data)
  706. {
  707. curl_socket_t sock;
  708. if(cf && !cf->cft->query(cf, data, CF_QUERY_SOCKET, NULL, &sock))
  709. return sock;
  710. return CURL_SOCKET_BAD;
  711. }
  712. unsigned char Curl_conn_cf_get_transport(struct Curl_cfilter *cf,
  713. struct Curl_easy *data)
  714. {
  715. int transport = 0;
  716. if(cf && !cf->cft->query(cf, data, CF_QUERY_TRANSPORT, &transport, NULL))
  717. return (unsigned char)transport;
  718. return (unsigned char)(data->conn ? data->conn->transport_wanted : 0);
  719. }
  720. static const struct Curl_sockaddr_ex *
  721. cf_get_remote_addr(struct Curl_cfilter *cf, struct Curl_easy *data)
  722. {
  723. const struct Curl_sockaddr_ex *remote_addr = NULL;
  724. if(cf &&
  725. !cf->cft->query(cf, data, CF_QUERY_REMOTE_ADDR, NULL,
  726. CURL_UNCONST(&remote_addr)))
  727. return remote_addr;
  728. return NULL;
  729. }
  730. CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf,
  731. struct Curl_easy *data,
  732. int *is_ipv6, struct ip_quadruple *ipquad)
  733. {
  734. if(cf)
  735. return cf->cft->query(cf, data, CF_QUERY_IP_INFO, is_ipv6, ipquad);
  736. return CURLE_UNKNOWN_OPTION;
  737. }
  738. curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex)
  739. {
  740. struct Curl_cfilter *cf;
  741. cf = data->conn ? data->conn->cfilter[sockindex] : NULL;
  742. /* if the top filter has not connected, ask it (and its sub-filters)
  743. * for the socket. Otherwise conn->sock[sockindex] should have it.
  744. */
  745. if(cf && !cf->connected)
  746. return Curl_conn_cf_get_socket(cf, data);
  747. return data->conn ? data->conn->sock[sockindex] : CURL_SOCKET_BAD;
  748. }
  749. const struct Curl_sockaddr_ex *
  750. Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex)
  751. {
  752. struct Curl_cfilter *cf = data->conn ? data->conn->cfilter[sockindex] : NULL;
  753. return cf ? cf_get_remote_addr(cf, data) : NULL;
  754. }
  755. void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex)
  756. {
  757. if(data->conn) {
  758. struct Curl_cfilter *cf = data->conn->cfilter[sockindex];
  759. if(cf)
  760. (void)Curl_conn_cf_cntrl(cf, data, TRUE,
  761. CF_CTRL_FORGET_SOCKET, 0, NULL);
  762. fake_sclose(data->conn->sock[sockindex]);
  763. data->conn->sock[sockindex] = CURL_SOCKET_BAD;
  764. }
  765. }
  766. static CURLcode cf_cntrl_all(struct connectdata *conn,
  767. struct Curl_easy *data,
  768. bool ignore_result,
  769. int event, int arg1, void *arg2)
  770. {
  771. CURLcode result = CURLE_OK;
  772. size_t i;
  773. for(i = 0; i < CURL_ARRAYSIZE(conn->cfilter); ++i) {
  774. result = Curl_conn_cf_cntrl(conn->cfilter[i], data, ignore_result,
  775. event, arg1, arg2);
  776. if(!ignore_result && result)
  777. break;
  778. }
  779. return result;
  780. }
  781. CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data)
  782. {
  783. return cf_cntrl_all(data->conn, data, FALSE,
  784. CF_CTRL_DATA_SETUP, 0, NULL);
  785. }
  786. CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data)
  787. {
  788. return cf_cntrl_all(data->conn, data, FALSE,
  789. CF_CTRL_DATA_IDLE, 0, NULL);
  790. }
  791. CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex)
  792. {
  793. return Curl_conn_cf_cntrl(data->conn->cfilter[sockindex], data, FALSE,
  794. CF_CTRL_FLUSH, 0, NULL);
  795. }
  796. /**
  797. * Notify connection filters that the transfer represented by `data`
  798. * is done with sending data (e.g. has uploaded everything).
  799. */
  800. void Curl_conn_ev_data_done_send(struct Curl_easy *data)
  801. {
  802. cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE_SEND, 0, NULL);
  803. }
  804. /**
  805. * Notify connection filters that the transfer represented by `data`
  806. * is finished - eventually premature, e.g. before being complete.
  807. */
  808. void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature)
  809. {
  810. cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE, premature, NULL);
  811. }
  812. CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause)
  813. {
  814. return cf_cntrl_all(data->conn, data, FALSE,
  815. CF_CTRL_DATA_PAUSE, do_pause, NULL);
  816. }
  817. static void cf_cntrl_update_info(struct Curl_easy *data,
  818. struct connectdata *conn)
  819. {
  820. cf_cntrl_all(conn, data, TRUE, CF_CTRL_CONN_INFO_UPDATE, 0, NULL);
  821. }
  822. /**
  823. * Update connection statistics
  824. */
  825. static void conn_report_connect_stats(struct Curl_easy *data,
  826. struct connectdata *conn)
  827. {
  828. struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
  829. if(cf) {
  830. struct curltime connected;
  831. struct curltime appconnected;
  832. memset(&connected, 0, sizeof(connected));
  833. cf->cft->query(cf, data, CF_QUERY_TIMER_CONNECT, NULL, &connected);
  834. if(connected.tv_sec || connected.tv_usec)
  835. Curl_pgrsTimeWas(data, TIMER_CONNECT, connected);
  836. memset(&appconnected, 0, sizeof(appconnected));
  837. cf->cft->query(cf, data, CF_QUERY_TIMER_APPCONNECT, NULL, &appconnected);
  838. if(appconnected.tv_sec || appconnected.tv_usec)
  839. Curl_pgrsTimeWas(data, TIMER_APPCONNECT, appconnected);
  840. }
  841. }
  842. bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn,
  843. bool *input_pending)
  844. {
  845. struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
  846. return cf && !cf->conn->bits.close &&
  847. cf->cft->is_alive(cf, data, input_pending);
  848. }
  849. CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
  850. struct connectdata *conn,
  851. int sockindex)
  852. {
  853. struct Curl_cfilter *cf = conn->cfilter[sockindex];
  854. return cf ? cf->cft->keep_alive(cf, data) : CURLE_OK;
  855. }
  856. size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
  857. struct connectdata *conn,
  858. int sockindex)
  859. {
  860. CURLcode result;
  861. int n = 0;
  862. struct Curl_cfilter *cf = conn->cfilter[sockindex];
  863. result = cf ? cf->cft->query(cf, data, CF_QUERY_MAX_CONCURRENT,
  864. &n, NULL) : CURLE_UNKNOWN_OPTION;
  865. return (result || n <= 0) ? 1 : (size_t)n;
  866. }
  867. int Curl_conn_get_stream_error(struct Curl_easy *data,
  868. struct connectdata *conn,
  869. int sockindex)
  870. {
  871. CURLcode result;
  872. int n = 0;
  873. struct Curl_cfilter *cf = conn->cfilter[sockindex];
  874. result = cf ? cf->cft->query(cf, data, CF_QUERY_STREAM_ERROR,
  875. &n, NULL) : CURLE_UNKNOWN_OPTION;
  876. return (result || n < 0) ? 0 : n;
  877. }
  878. int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd)
  879. {
  880. if(data && data->conn &&
  881. sockfd != CURL_SOCKET_BAD && sockfd == data->conn->sock[SECONDARYSOCKET])
  882. return SECONDARYSOCKET;
  883. return FIRSTSOCKET;
  884. }
  885. CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex,
  886. char *buf, size_t blen, size_t *pnread)
  887. {
  888. DEBUGASSERT(data);
  889. DEBUGASSERT(data->conn);
  890. if(data && data->conn && data->conn->recv[sockindex])
  891. return data->conn->recv[sockindex](data, sockindex, buf, blen, pnread);
  892. *pnread = 0;
  893. return CURLE_FAILED_INIT;
  894. }
  895. CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
  896. const void *buf, size_t blen, bool eos,
  897. size_t *pnwritten)
  898. {
  899. size_t write_len = blen;
  900. DEBUGASSERT(data);
  901. DEBUGASSERT(data->conn);
  902. DEBUGASSERT(sockindex >= 0 && sockindex < 2);
  903. #ifdef DEBUGBUILD
  904. if(write_len) {
  905. /* Allow debug builds to override this logic to force short sends
  906. */
  907. const char *p = getenv("CURL_SMALLSENDS");
  908. if(p) {
  909. curl_off_t altsize;
  910. if(!curlx_str_number(&p, &altsize, write_len))
  911. write_len = (size_t)altsize;
  912. }
  913. }
  914. #endif
  915. if(write_len != blen)
  916. eos = FALSE;
  917. if(data && data->conn && data->conn->send[sockindex])
  918. return data->conn->send[sockindex](data, sockindex, buf, write_len, eos,
  919. pnwritten);
  920. *pnwritten = 0;
  921. return CURLE_FAILED_INIT;
  922. }
  923. void Curl_pollset_reset(struct Curl_easy *data,
  924. struct easy_pollset *ps)
  925. {
  926. size_t i;
  927. (void)data;
  928. memset(ps, 0, sizeof(*ps));
  929. for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++)
  930. ps->sockets[i] = CURL_SOCKET_BAD;
  931. }
  932. /**
  933. *
  934. */
  935. void Curl_pollset_change(struct Curl_easy *data,
  936. struct easy_pollset *ps, curl_socket_t sock,
  937. int add_flags, int remove_flags)
  938. {
  939. unsigned int i;
  940. (void)data;
  941. DEBUGASSERT(VALID_SOCK(sock));
  942. if(!VALID_SOCK(sock))
  943. return;
  944. DEBUGASSERT(add_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
  945. DEBUGASSERT(remove_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
  946. DEBUGASSERT((add_flags&remove_flags) == 0); /* no overlap */
  947. for(i = 0; i < ps->num; ++i) {
  948. if(ps->sockets[i] == sock) {
  949. ps->actions[i] &= (unsigned char)(~remove_flags);
  950. ps->actions[i] |= (unsigned char)add_flags;
  951. /* all gone? remove socket */
  952. if(!ps->actions[i]) {
  953. if((i + 1) < ps->num) {
  954. memmove(&ps->sockets[i], &ps->sockets[i + 1],
  955. (ps->num - (i + 1)) * sizeof(ps->sockets[0]));
  956. memmove(&ps->actions[i], &ps->actions[i + 1],
  957. (ps->num - (i + 1)) * sizeof(ps->actions[0]));
  958. }
  959. --ps->num;
  960. }
  961. return;
  962. }
  963. }
  964. /* not present */
  965. if(add_flags) {
  966. /* Having more SOCKETS per easy handle than what is defined
  967. * is a programming error. This indicates that we need
  968. * to raise this limit, making easy_pollset larger.
  969. * Since we use this in tight loops, we do not want to make
  970. * the pollset dynamic unnecessarily.
  971. * The current maximum in practise is HTTP/3 eyeballing where
  972. * we have up to 4 sockets involved in connection setup.
  973. */
  974. DEBUGASSERT(i < MAX_SOCKSPEREASYHANDLE);
  975. if(i < MAX_SOCKSPEREASYHANDLE) {
  976. ps->sockets[i] = sock;
  977. ps->actions[i] = (unsigned char)add_flags;
  978. ps->num = i + 1;
  979. }
  980. }
  981. }
  982. void Curl_pollset_set(struct Curl_easy *data,
  983. struct easy_pollset *ps, curl_socket_t sock,
  984. bool do_in, bool do_out)
  985. {
  986. Curl_pollset_change(data, ps, sock,
  987. (do_in ? CURL_POLL_IN : 0)|
  988. (do_out ? CURL_POLL_OUT : 0),
  989. (!do_in ? CURL_POLL_IN : 0)|
  990. (!do_out ? CURL_POLL_OUT : 0));
  991. }
  992. static void ps_add(struct Curl_easy *data, struct easy_pollset *ps,
  993. int bitmap, curl_socket_t *socks)
  994. {
  995. if(bitmap) {
  996. int i;
  997. for(i = 0; i < MAX_SOCKSPEREASYHANDLE; ++i) {
  998. if(!(bitmap & GETSOCK_MASK_RW(i)) || !VALID_SOCK((socks[i]))) {
  999. break;
  1000. }
  1001. if(bitmap & GETSOCK_READSOCK(i)) {
  1002. if(bitmap & GETSOCK_WRITESOCK(i))
  1003. Curl_pollset_add_inout(data, ps, socks[i]);
  1004. else
  1005. /* is READ, since we checked MASK_RW above */
  1006. Curl_pollset_add_in(data, ps, socks[i]);
  1007. }
  1008. else
  1009. Curl_pollset_add_out(data, ps, socks[i]);
  1010. }
  1011. }
  1012. }
  1013. void Curl_pollset_add_socks(struct Curl_easy *data,
  1014. struct easy_pollset *ps,
  1015. int (*get_socks_cb)(struct Curl_easy *data,
  1016. curl_socket_t *socks))
  1017. {
  1018. curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
  1019. int bitmap;
  1020. bitmap = get_socks_cb(data, socks);
  1021. ps_add(data, ps, bitmap, socks);
  1022. }
  1023. void Curl_pollset_check(struct Curl_easy *data,
  1024. struct easy_pollset *ps, curl_socket_t sock,
  1025. bool *pwant_read, bool *pwant_write)
  1026. {
  1027. unsigned int i;
  1028. (void)data;
  1029. DEBUGASSERT(VALID_SOCK(sock));
  1030. for(i = 0; i < ps->num; ++i) {
  1031. if(ps->sockets[i] == sock) {
  1032. *pwant_read = !!(ps->actions[i] & CURL_POLL_IN);
  1033. *pwant_write = !!(ps->actions[i] & CURL_POLL_OUT);
  1034. return;
  1035. }
  1036. }
  1037. *pwant_read = *pwant_write = FALSE;
  1038. }
  1039. bool Curl_pollset_want_read(struct Curl_easy *data,
  1040. struct easy_pollset *ps,
  1041. curl_socket_t sock)
  1042. {
  1043. unsigned int i;
  1044. (void)data;
  1045. for(i = 0; i < ps->num; ++i) {
  1046. if((ps->sockets[i] == sock) && (ps->actions[i] & CURL_POLL_IN))
  1047. return TRUE;
  1048. }
  1049. return FALSE;
  1050. }