cfilters.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #ifndef HEADER_CURL_CFILTERS_H
  2. #define HEADER_CURL_CFILTERS_H
  3. /***************************************************************************
  4. * _ _ ____ _
  5. * Project ___| | | | _ \| |
  6. * / __| | | | |_) | |
  7. * | (__| |_| | _ <| |___
  8. * \___|\___/|_| \_\_____|
  9. *
  10. * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
  11. *
  12. * This software is licensed as described in the file COPYING, which
  13. * you should have received as part of this distribution. The terms
  14. * are also available at https://curl.se/docs/copyright.html.
  15. *
  16. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  17. * copies of the Software, and permit persons to whom the Software is
  18. * furnished to do so, under the terms of the COPYING file.
  19. *
  20. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  21. * KIND, either express or implied.
  22. *
  23. * SPDX-License-Identifier: curl
  24. *
  25. ***************************************************************************/
  26. struct Curl_cfilter;
  27. struct Curl_easy;
  28. struct Curl_dns_entry;
  29. struct connectdata;
  30. /* Callback to destroy resources held by this filter instance.
  31. * Implementations MUST NOT chain calls to cf->next.
  32. */
  33. typedef void Curl_cft_destroy_this(struct Curl_cfilter *cf,
  34. struct Curl_easy *data);
  35. /* Setup the connection for `data`, using destination `remotehost`.
  36. */
  37. typedef CURLcode Curl_cft_setup(struct Curl_cfilter *cf,
  38. struct Curl_easy *data,
  39. const struct Curl_dns_entry *remotehost);
  40. typedef void Curl_cft_close(struct Curl_cfilter *cf,
  41. struct Curl_easy *data);
  42. typedef CURLcode Curl_cft_connect(struct Curl_cfilter *cf,
  43. struct Curl_easy *data,
  44. bool blocking, bool *done);
  45. /* Return the hostname and port the connection goes to.
  46. * This may change with the connection state of filters when tunneling
  47. * is involved.
  48. * @param cf the filter to ask
  49. * @param data the easy handle currently active
  50. * @param phost on return, points to the relevant, real hostname.
  51. * this is owned by the connection.
  52. * @param pdisplay_host on return, points to the printable hostname.
  53. * this is owned by the connection.
  54. * @param pport on return, contains the port number
  55. */
  56. typedef void Curl_cft_get_host(struct Curl_cfilter *cf,
  57. struct Curl_easy *data,
  58. const char **phost,
  59. const char **pdisplay_host,
  60. int *pport);
  61. /* Filters may return sockets and fdset flags they are waiting for.
  62. * The passes array has room for up to MAX_SOCKSPEREASYHANDLE sockets.
  63. * @return read/write fdset for index in socks
  64. * or GETSOCK_BLANK when nothing to wait on
  65. */
  66. typedef int Curl_cft_get_select_socks(struct Curl_cfilter *cf,
  67. struct Curl_easy *data,
  68. curl_socket_t *socks);
  69. typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf,
  70. const struct Curl_easy *data);
  71. typedef ssize_t Curl_cft_send(struct Curl_cfilter *cf,
  72. struct Curl_easy *data, /* transfer */
  73. const void *buf, /* data to write */
  74. size_t len, /* amount to write */
  75. CURLcode *err); /* error to return */
  76. typedef ssize_t Curl_cft_recv(struct Curl_cfilter *cf,
  77. struct Curl_easy *data, /* transfer */
  78. char *buf, /* store data here */
  79. size_t len, /* amount to read */
  80. CURLcode *err); /* error to return */
  81. typedef void Curl_cft_attach_data(struct Curl_cfilter *cf,
  82. struct Curl_easy *data);
  83. typedef void Curl_cft_detach_data(struct Curl_cfilter *cf,
  84. struct Curl_easy *data);
  85. /**
  86. * The easy handle `data` is being detached (no longer served)
  87. * by connection `conn`. All filters are informed to release any resources
  88. * related to `data`.
  89. * Note: there may be several `data` attached to a connection at the same
  90. * time.
  91. */
  92. void Curl_conn_detach(struct connectdata *conn, struct Curl_easy *data);
  93. #define CF_TYPE_IP_CONNECT (1 << 0)
  94. #define CF_TYPE_SSL (1 << 1)
  95. /* A connection filter type, e.g. specific implementation. */
  96. struct Curl_cftype {
  97. const char *name; /* name of the filter type */
  98. long flags; /* flags of filter type */
  99. Curl_cft_destroy_this *destroy; /* destroy resources of this cf */
  100. Curl_cft_setup *setup; /* setup for a connection */
  101. Curl_cft_connect *connect; /* establish connection */
  102. Curl_cft_close *close; /* close conn */
  103. Curl_cft_get_host *get_host; /* host filter talks to */
  104. Curl_cft_get_select_socks *get_select_socks;/* sockets to select on */
  105. Curl_cft_data_pending *has_data_pending;/* conn has data pending */
  106. Curl_cft_send *do_send; /* send data */
  107. Curl_cft_recv *do_recv; /* receive data */
  108. Curl_cft_attach_data *attach_data; /* data is being handled here */
  109. Curl_cft_detach_data *detach_data; /* data is no longer handled here */
  110. };
  111. /* A connection filter instance, e.g. registered at a connection */
  112. struct Curl_cfilter {
  113. const struct Curl_cftype *cft; /* the type providing implementation */
  114. struct Curl_cfilter *next; /* next filter in chain */
  115. void *ctx; /* filter type specific settings */
  116. struct connectdata *conn; /* the connection this filter belongs to */
  117. int sockindex; /* TODO: like to get rid off this */
  118. BIT(connected); /* != 0 iff this filter is connected */
  119. };
  120. /* Default implementations for the type functions, implementing nop. */
  121. void Curl_cf_def_destroy_this(struct Curl_cfilter *cf,
  122. struct Curl_easy *data);
  123. /* Default implementations for the type functions, implementing pass-through
  124. * the filter chain. */
  125. CURLcode Curl_cf_def_setup(struct Curl_cfilter *cf,
  126. struct Curl_easy *data,
  127. const struct Curl_dns_entry *remotehost);
  128. void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data);
  129. CURLcode Curl_cf_def_connect(struct Curl_cfilter *cf,
  130. struct Curl_easy *data,
  131. bool blocking, bool *done);
  132. void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
  133. const char **phost, const char **pdisplay_host,
  134. int *pport);
  135. int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
  136. struct Curl_easy *data,
  137. curl_socket_t *socks);
  138. bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
  139. const struct Curl_easy *data);
  140. ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  141. const void *buf, size_t len, CURLcode *err);
  142. ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  143. char *buf, size_t len, CURLcode *err);
  144. void Curl_cf_def_attach_data(struct Curl_cfilter *cf,
  145. struct Curl_easy *data);
  146. void Curl_cf_def_detach_data(struct Curl_cfilter *cf,
  147. struct Curl_easy *data);
  148. /**
  149. * Create a new filter instance, unattached to the filter chain.
  150. * Use Curl_conn_cf_add() to add it to the chain.
  151. * @param pcf on success holds the created instance
  152. * @parm cft the filter type
  153. * @param ctx the type specific context to use
  154. */
  155. CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
  156. const struct Curl_cftype *cft,
  157. void *ctx);
  158. /**
  159. * Add a filter instance to the `sockindex` filter chain at connection
  160. * `data->conn`. The filter must not already be attached. It is inserted at
  161. * the start of the chain (top).
  162. */
  163. void Curl_conn_cf_add(struct Curl_easy *data,
  164. struct connectdata *conn,
  165. int sockindex,
  166. struct Curl_cfilter *cf);
  167. /**
  168. * Remove and destroy all filters at chain `sockindex` on connection `conn`.
  169. */
  170. void Curl_conn_cf_discard_all(struct Curl_easy *data,
  171. struct connectdata *conn,
  172. int sockindex);
  173. /**
  174. * Discard, e.g. remove and destroy a specific filter instance.
  175. * If the filter is attached to a connection, it will be removed before
  176. * it is destroyed.
  177. */
  178. void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data);
  179. ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  180. const void *buf, size_t len, CURLcode *err);
  181. ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  182. char *buf, size_t len, CURLcode *err);
  183. #define CURL_CF_SSL_DEFAULT -1
  184. #define CURL_CF_SSL_DISABLE 0
  185. #define CURL_CF_SSL_ENABLE 1
  186. /**
  187. * Setup the filter chain at `sockindex` in connection `conn`, invoking
  188. * the instance `setup(remotehost)` methods. If no filter chain is
  189. * installed yet, inspects the configuration in `data` to install a
  190. * suitable filter chain.
  191. */
  192. CURLcode Curl_conn_setup(struct Curl_easy *data,
  193. struct connectdata *conn,
  194. int sockindex,
  195. const struct Curl_dns_entry *remotehost,
  196. int ssl_mode);
  197. /**
  198. * Bring the filter chain at `sockindex` for connection `data->conn` into
  199. * connected state. Which will set `*done` to TRUE.
  200. * This can be called on an already connected chain with no side effects.
  201. * When not `blocking`, calls may return without error and `*done != TRUE`,
  202. * while the individual filters negotiated the connection.
  203. */
  204. CURLcode Curl_conn_connect(struct Curl_easy *data, int sockindex,
  205. bool blocking, bool *done);
  206. /**
  207. * Check if the filter chain at `sockindex` for connection `conn` is
  208. * completely connected.
  209. */
  210. bool Curl_conn_is_connected(struct connectdata *conn, int sockindex);
  211. /**
  212. * Determine if we have reached the remote host on IP level, e.g.
  213. * have a TCP connection. This turns TRUE before a possible SSL
  214. * handshake has been started/done.
  215. */
  216. bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex);
  217. /**
  218. * Determine if the connection is using SSL to the remote host
  219. * (or will be once connected). This will return FALSE, if SSL
  220. * is only used in proxying and not for the tunnel itself.
  221. */
  222. bool Curl_conn_is_ssl(struct Curl_easy *data, int sockindex);
  223. /**
  224. * Close the filter chain at `sockindex` for connection `data->conn`.
  225. * Filters remain in place and may be connected again afterwards.
  226. */
  227. void Curl_conn_close(struct Curl_easy *data, int sockindex);
  228. /**
  229. * Return if data is pending in some connection filter at chain
  230. * `sockindex` for connection `data->conn`.
  231. */
  232. bool Curl_conn_data_pending(struct Curl_easy *data,
  233. int sockindex);
  234. /**
  235. * Get any select fd flags and the socket filters at chain `sockindex`
  236. * at connection `conn` might be waiting for.
  237. */
  238. int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
  239. curl_socket_t *socks);
  240. /**
  241. * Receive data through the filter chain at `sockindex` for connection
  242. * `data->conn`. Copy at most `len` bytes into `buf`. Return the
  243. * actuel number of bytes copied or a negative value on error.
  244. * The error code is placed into `*code`.
  245. */
  246. ssize_t Curl_conn_recv(struct Curl_easy *data, int sockindex, char *buf,
  247. size_t len, CURLcode *code);
  248. /**
  249. * Send `len` bytes of data from `buf` through the filter chain `sockindex`
  250. * at connection `data->conn`. Return the actual number of bytes written
  251. * or a negative value on error.
  252. * The error code is placed into `*code`.
  253. */
  254. ssize_t Curl_conn_send(struct Curl_easy *data, int sockindex,
  255. const void *buf, size_t len, CURLcode *code);
  256. /**
  257. * The easy handle `data` is being attached (served) by connection `conn`.
  258. * All filters are informed to adapt to handling `data`.
  259. * Note: there may be several `data` attached to a connection at the same
  260. * time.
  261. */
  262. void Curl_conn_attach_data(struct connectdata *conn,
  263. struct Curl_easy *data);
  264. /**
  265. * The easy handle `data` is being detached (no longer served)
  266. * by connection `conn`. All filters are informed to release any resources
  267. * related to `data`.
  268. * Note: there may be several `data` attached to a connection at the same
  269. * time.
  270. */
  271. void Curl_conn_detach_data(struct connectdata *conn,
  272. struct Curl_easy *data);
  273. void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
  274. const char **phost, const char **pdisplay_host,
  275. int *pport);
  276. #endif /* HEADER_CURL_CFILTERS_H */