cfilters.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, 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" /* for Curl_safefree() */
  30. #include "sendf.h"
  31. #include "sockaddr.h" /* required for Curl_sockaddr_storage */
  32. #include "multiif.h"
  33. #include "progress.h"
  34. #include "warnless.h"
  35. #include "http_proxy.h"
  36. #include "socks.h"
  37. #include "vtls/vtls.h"
  38. /* The last 3 #include files should be in this order */
  39. #include "curl_printf.h"
  40. #include "curl_memory.h"
  41. #include "memdebug.h"
  42. #ifndef ARRAYSIZE
  43. #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
  44. #endif
  45. void Curl_cf_def_destroy_this(struct Curl_cfilter *cf, struct Curl_easy *data)
  46. {
  47. (void)cf;
  48. (void)data;
  49. }
  50. CURLcode Curl_cf_def_setup(struct Curl_cfilter *cf,
  51. struct Curl_easy *data,
  52. const struct Curl_dns_entry *remotehost)
  53. {
  54. DEBUGASSERT(cf->next);
  55. return cf->next->cft->setup(cf->next, data, remotehost);
  56. }
  57. void Curl_cf_def_attach_data(struct Curl_cfilter *cf,
  58. struct Curl_easy *data)
  59. {
  60. (void)cf;
  61. (void)data;
  62. }
  63. void Curl_cf_def_detach_data(struct Curl_cfilter *cf,
  64. struct Curl_easy *data)
  65. {
  66. (void)cf;
  67. (void)data;
  68. }
  69. void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data)
  70. {
  71. DEBUGASSERT(cf->next);
  72. cf->connected = FALSE;
  73. cf->next->cft->close(cf->next, data);
  74. }
  75. CURLcode Curl_cf_def_connect(struct Curl_cfilter *cf,
  76. struct Curl_easy *data,
  77. bool blocking, bool *done)
  78. {
  79. DEBUGASSERT(cf->next);
  80. return cf->next->cft->connect(cf->next, data, blocking, done);
  81. }
  82. void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
  83. const char **phost, const char **pdisplay_host,
  84. int *pport)
  85. {
  86. DEBUGASSERT(cf->next);
  87. cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
  88. }
  89. int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
  90. struct Curl_easy *data,
  91. curl_socket_t *socks)
  92. {
  93. DEBUGASSERT(cf->next);
  94. return cf->next->cft->get_select_socks(cf->next, data, socks);
  95. }
  96. bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
  97. const struct Curl_easy *data)
  98. {
  99. DEBUGASSERT(cf->next);
  100. return cf->next->cft->has_data_pending(cf->next, data);
  101. }
  102. ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  103. const void *buf, size_t len, CURLcode *err)
  104. {
  105. DEBUGASSERT(cf->next);
  106. return cf->next->cft->do_send(cf->next, data, buf, len, err);
  107. }
  108. ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  109. char *buf, size_t len, CURLcode *err)
  110. {
  111. DEBUGASSERT(cf->next);
  112. return cf->next->cft->do_recv(cf->next, data, buf, len, err);
  113. }
  114. void Curl_conn_cf_discard_all(struct Curl_easy *data,
  115. struct connectdata *conn, int index)
  116. {
  117. struct Curl_cfilter *cfn, *cf = conn->cfilter[index];
  118. if(cf) {
  119. conn->cfilter[index] = NULL;
  120. while(cf) {
  121. cfn = cf->next;
  122. cf->cft->destroy(cf, data);
  123. free(cf);
  124. cf = cfn;
  125. }
  126. }
  127. }
  128. void Curl_conn_close(struct Curl_easy *data, int index)
  129. {
  130. struct Curl_cfilter *cf;
  131. DEBUGASSERT(data->conn);
  132. /* it is valid to call that without filters being present */
  133. cf = data->conn->cfilter[index];
  134. if(cf) {
  135. cf->cft->close(cf, data);
  136. }
  137. }
  138. ssize_t Curl_conn_recv(struct Curl_easy *data, int num, char *buf,
  139. size_t len, CURLcode *code)
  140. {
  141. struct Curl_cfilter *cf;
  142. ssize_t nread;
  143. DEBUGASSERT(data);
  144. DEBUGASSERT(data->conn);
  145. cf = data->conn->cfilter[num];
  146. while(cf && !cf->connected) {
  147. cf = cf->next;
  148. }
  149. if(cf) {
  150. nread = cf->cft->do_recv(cf, data, buf, len, code);
  151. /* DEBUGF(infof(data, "Curl_conn_recv(handle=%p, index=%d)"
  152. "-> %ld, err=%d", data, num, nread, *code));*/
  153. return nread;
  154. }
  155. failf(data, "no filter connected, conn=%ld, sockindex=%d",
  156. data->conn->connection_id, num);
  157. *code = CURLE_FAILED_INIT;
  158. return -1;
  159. }
  160. ssize_t Curl_conn_send(struct Curl_easy *data, int num,
  161. const void *mem, size_t len, CURLcode *code)
  162. {
  163. struct Curl_cfilter *cf;
  164. ssize_t nwritten;
  165. DEBUGASSERT(data);
  166. DEBUGASSERT(data->conn);
  167. cf = data->conn->cfilter[num];
  168. while(cf && !cf->connected) {
  169. cf = cf->next;
  170. }
  171. if(cf) {
  172. nwritten = cf->cft->do_send(cf, data, mem, len, code);
  173. /* DEBUGF(infof(data, "Curl_conn_send(handle=%p, index=%d, len=%ld)"
  174. " -> %ld, err=%d", data, num, len, nwritten, *code));*/
  175. return nwritten;
  176. }
  177. failf(data, "no filter connected, conn=%ld, sockindex=%d",
  178. data->conn->connection_id, num);
  179. *code = CURLE_FAILED_INIT;
  180. return -1;
  181. }
  182. CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
  183. const struct Curl_cftype *cft,
  184. void *ctx)
  185. {
  186. struct Curl_cfilter *cf;
  187. CURLcode result = CURLE_OUT_OF_MEMORY;
  188. DEBUGASSERT(cft);
  189. cf = calloc(sizeof(*cf), 1);
  190. if(!cf)
  191. goto out;
  192. cf->cft = cft;
  193. cf->ctx = ctx;
  194. result = CURLE_OK;
  195. out:
  196. *pcf = cf;
  197. return result;
  198. }
  199. void Curl_conn_cf_add(struct Curl_easy *data,
  200. struct connectdata *conn,
  201. int index,
  202. struct Curl_cfilter *cf)
  203. {
  204. (void)data;
  205. DEBUGASSERT(conn);
  206. DEBUGASSERT(!cf->conn);
  207. DEBUGASSERT(!cf->next);
  208. DEBUGF(infof(data, CMSGI(conn, index, "cf_add(filter=%s)"),
  209. cf->cft->name));
  210. cf->next = conn->cfilter[index];
  211. cf->conn = conn;
  212. cf->sockindex = index;
  213. conn->cfilter[index] = cf;
  214. }
  215. void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data)
  216. {
  217. struct Curl_cfilter **pprev = &cf->conn->cfilter[cf->sockindex];
  218. /* remove from chain if still in there */
  219. DEBUGASSERT(cf);
  220. while (*pprev) {
  221. if (*pprev == cf) {
  222. *pprev = cf->next;
  223. break;
  224. }
  225. pprev = &((*pprev)->next);
  226. }
  227. cf->cft->destroy(cf, data);
  228. free(cf);
  229. }
  230. ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  231. const void *buf, size_t len, CURLcode *err)
  232. {
  233. return cf->cft->do_send(cf, data, buf, len, err);
  234. }
  235. ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  236. char *buf, size_t len, CURLcode *err)
  237. {
  238. return cf->cft->do_recv(cf, data, buf, len, err);
  239. }
  240. CURLcode Curl_conn_setup(struct Curl_easy *data,
  241. struct connectdata *conn,
  242. int sockindex,
  243. const struct Curl_dns_entry *remotehost,
  244. int ssl_mode)
  245. {
  246. struct Curl_cfilter *cf;
  247. CURLcode result;
  248. DEBUGASSERT(data);
  249. /* If no filter is set, we have the "default" setup of connection filters.
  250. * The filter chain from botton to top will be:
  251. * - SOCKET socket filter for outgoing connection to remotehost
  252. * if http_proxy tunneling is engaged:
  253. * - SSL if proxytype is CURLPROXY_HTTPS
  254. * - HTTP_PROXY_TUNNEL
  255. * otherwise, if socks_proxy is engaged:
  256. * - SOCKS_PROXY_TUNNEL
  257. * - SSL if conn->handler has PROTOPT_SSL
  258. */
  259. if(!conn->cfilter[sockindex]) {
  260. DEBUGF(infof(data, DMSGI(data, sockindex, "setup, init filter chain")));
  261. result = Curl_conn_socket_set(data, conn, sockindex);
  262. if(result)
  263. goto out;
  264. #ifndef CURL_DISABLE_PROXY
  265. if(conn->bits.socksproxy) {
  266. result = Curl_conn_socks_proxy_add(data, conn, sockindex);
  267. if(result)
  268. goto out;
  269. }
  270. if(conn->bits.httpproxy) {
  271. #ifdef USE_SSL
  272. if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
  273. result = Curl_ssl_cfilter_proxy_add(data, conn, sockindex);
  274. if(result)
  275. goto out;
  276. }
  277. #endif /* USE_SSL */
  278. #if !defined(CURL_DISABLE_HTTP)
  279. if(conn->bits.tunnel_proxy) {
  280. result = Curl_conn_http_proxy_add(data, conn, sockindex);
  281. if(result)
  282. goto out;
  283. }
  284. #endif /* !CURL_DISABLE_HTTP */
  285. }
  286. #endif /* !CURL_DISABLE_PROXY */
  287. #ifdef USE_SSL
  288. if(ssl_mode == CURL_CF_SSL_ENABLE
  289. || (ssl_mode != CURL_CF_SSL_DISABLE
  290. && conn->handler->flags & PROTOPT_SSL)) {
  291. result = Curl_ssl_cfilter_add(data, conn, sockindex);
  292. if(result)
  293. goto out;
  294. }
  295. #else
  296. (void)ssl_mode;
  297. #endif /* USE_SSL */
  298. #if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
  299. if(data->set.haproxyprotocol) {
  300. result = Curl_conn_haproxy_add(data, conn, sockindex);
  301. if(result)
  302. goto out;
  303. }
  304. #endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */
  305. }
  306. DEBUGASSERT(conn->cfilter[sockindex]);
  307. cf = data->conn->cfilter[sockindex];
  308. result = cf->cft->setup(cf, data, remotehost);
  309. out:
  310. return result;
  311. }
  312. CURLcode Curl_conn_connect(struct Curl_easy *data,
  313. int sockindex,
  314. bool blocking,
  315. bool *done)
  316. {
  317. struct Curl_cfilter *cf;
  318. CURLcode result;
  319. DEBUGASSERT(data);
  320. cf = data->conn->cfilter[sockindex];
  321. DEBUGASSERT(cf);
  322. result = cf->cft->connect(cf, data, blocking, done);
  323. DEBUGF(infof(data, DMSGI(data, sockindex, "connect(block=%d)-> %d, done=%d"),
  324. blocking, result, *done));
  325. return result;
  326. }
  327. bool Curl_conn_is_connected(struct connectdata *conn, int sockindex)
  328. {
  329. struct Curl_cfilter *cf;
  330. cf = conn->cfilter[sockindex];
  331. return cf && cf->connected;
  332. }
  333. bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex)
  334. {
  335. struct Curl_cfilter *cf;
  336. cf = data->conn->cfilter[sockindex];
  337. while(cf) {
  338. if(cf->connected)
  339. return TRUE;
  340. if(cf->cft->flags & CF_TYPE_IP_CONNECT)
  341. return FALSE;
  342. cf = cf->next;
  343. }
  344. return FALSE;
  345. }
  346. bool Curl_conn_is_ssl(struct Curl_easy *data, int sockindex)
  347. {
  348. struct Curl_cfilter *cf = data->conn? data->conn->cfilter[sockindex] : NULL;
  349. (void)data;
  350. for(; cf; cf = cf->next) {
  351. if(cf->cft->flags & CF_TYPE_SSL)
  352. return TRUE;
  353. if(cf->cft->flags & CF_TYPE_IP_CONNECT)
  354. return FALSE;
  355. }
  356. return FALSE;
  357. }
  358. bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
  359. {
  360. struct Curl_cfilter *cf;
  361. (void)data;
  362. DEBUGASSERT(data);
  363. DEBUGASSERT(data->conn);
  364. if(Curl_recv_has_postponed_data(data->conn, sockindex))
  365. return TRUE;
  366. cf = data->conn->cfilter[sockindex];
  367. while(cf && !cf->connected) {
  368. cf = cf->next;
  369. }
  370. if(cf) {
  371. return cf->cft->has_data_pending(cf, data);
  372. }
  373. return FALSE;
  374. }
  375. int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
  376. curl_socket_t *socks)
  377. {
  378. struct Curl_cfilter *cf;
  379. DEBUGASSERT(data);
  380. DEBUGASSERT(data->conn);
  381. cf = data->conn->cfilter[sockindex];
  382. if(cf) {
  383. return cf->cft->get_select_socks(cf, data, socks);
  384. }
  385. return GETSOCK_BLANK;
  386. }
  387. void Curl_conn_attach_data(struct connectdata *conn,
  388. struct Curl_easy *data)
  389. {
  390. size_t i;
  391. struct Curl_cfilter *cf;
  392. for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
  393. cf = conn->cfilter[i];
  394. if(cf) {
  395. while(cf) {
  396. cf->cft->attach_data(cf, data);
  397. cf = cf->next;
  398. }
  399. }
  400. }
  401. }
  402. void Curl_conn_detach_data(struct connectdata *conn,
  403. struct Curl_easy *data)
  404. {
  405. size_t i;
  406. struct Curl_cfilter *cf;
  407. for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
  408. cf = conn->cfilter[i];
  409. if(cf) {
  410. while(cf) {
  411. cf->cft->detach_data(cf, data);
  412. cf = cf->next;
  413. }
  414. }
  415. }
  416. }
  417. void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
  418. const char **phost, const char **pdisplay_host,
  419. int *pport)
  420. {
  421. struct Curl_cfilter *cf;
  422. DEBUGASSERT(data->conn);
  423. cf = data->conn->cfilter[sockindex];
  424. if(cf) {
  425. cf->cft->get_host(cf, data, phost, pdisplay_host, pport);
  426. }
  427. else {
  428. /* Some filter ask during shutdown for this, mainly for debugging
  429. * purposes. We hand out the defaults, however this is not always
  430. * accurate, as the connction might be tunneled, etc. But all that
  431. * state is already gone here. */
  432. *phost = data->conn->host.name;
  433. *pdisplay_host = data->conn->host.dispname;
  434. *pport = data->conn->remote_port;
  435. }
  436. }