curl_osslq.c 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 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. #if defined(USE_OPENSSL_QUIC) && defined(USE_NGHTTP3)
  26. #include <openssl/ssl.h>
  27. #include <openssl/bio.h>
  28. #include <openssl/err.h>
  29. #include <nghttp3/nghttp3.h>
  30. #include "urldata.h"
  31. #include "sendf.h"
  32. #include "strdup.h"
  33. #include "rand.h"
  34. #include "multiif.h"
  35. #include "strcase.h"
  36. #include "cfilters.h"
  37. #include "cf-socket.h"
  38. #include "connect.h"
  39. #include "progress.h"
  40. #include "strerror.h"
  41. #include "dynbuf.h"
  42. #include "http1.h"
  43. #include "select.h"
  44. #include "inet_pton.h"
  45. #include "vquic.h"
  46. #include "vquic_int.h"
  47. #include "vquic-tls.h"
  48. #include "vtls/keylog.h"
  49. #include "vtls/vtls.h"
  50. #include "vtls/openssl.h"
  51. #include "curl_osslq.h"
  52. #include "warnless.h"
  53. /* The last 3 #include files should be in this order */
  54. #include "curl_printf.h"
  55. #include "curl_memory.h"
  56. #include "memdebug.h"
  57. /* A stream window is the maximum amount we need to buffer for
  58. * each active transfer. We use HTTP/3 flow control and only ACK
  59. * when we take things out of the buffer.
  60. * Chunk size is large enough to take a full DATA frame */
  61. #define H3_STREAM_WINDOW_SIZE (128 * 1024)
  62. #define H3_STREAM_CHUNK_SIZE (16 * 1024)
  63. /* The pool keeps spares around and half of a full stream window
  64. * seems good. More does not seem to improve performance.
  65. * The benefit of the pool is that stream buffer to not keep
  66. * spares. So memory consumption goes down when streams run empty,
  67. * have a large upload done, etc. */
  68. #define H3_STREAM_POOL_SPARES \
  69. (H3_STREAM_WINDOW_SIZE / H3_STREAM_CHUNK_SIZE ) / 2
  70. /* Receive and Send max number of chunks just follows from the
  71. * chunk size and window size */
  72. #define H3_STREAM_RECV_CHUNKS \
  73. (H3_STREAM_WINDOW_SIZE / H3_STREAM_CHUNK_SIZE)
  74. #define H3_STREAM_SEND_CHUNKS \
  75. (H3_STREAM_WINDOW_SIZE / H3_STREAM_CHUNK_SIZE)
  76. #ifndef ARRAYSIZE
  77. #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
  78. #endif
  79. #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
  80. typedef uint32_t sslerr_t;
  81. #else
  82. typedef unsigned long sslerr_t;
  83. #endif
  84. /* How to access `call_data` from a cf_osslq filter */
  85. #undef CF_CTX_CALL_DATA
  86. #define CF_CTX_CALL_DATA(cf) \
  87. ((struct cf_osslq_ctx *)(cf)->ctx)->call_data
  88. static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
  89. struct Curl_easy *data);
  90. static const char *osslq_SSL_ERROR_to_str(int err)
  91. {
  92. switch(err) {
  93. case SSL_ERROR_NONE:
  94. return "SSL_ERROR_NONE";
  95. case SSL_ERROR_SSL:
  96. return "SSL_ERROR_SSL";
  97. case SSL_ERROR_WANT_READ:
  98. return "SSL_ERROR_WANT_READ";
  99. case SSL_ERROR_WANT_WRITE:
  100. return "SSL_ERROR_WANT_WRITE";
  101. case SSL_ERROR_WANT_X509_LOOKUP:
  102. return "SSL_ERROR_WANT_X509_LOOKUP";
  103. case SSL_ERROR_SYSCALL:
  104. return "SSL_ERROR_SYSCALL";
  105. case SSL_ERROR_ZERO_RETURN:
  106. return "SSL_ERROR_ZERO_RETURN";
  107. case SSL_ERROR_WANT_CONNECT:
  108. return "SSL_ERROR_WANT_CONNECT";
  109. case SSL_ERROR_WANT_ACCEPT:
  110. return "SSL_ERROR_WANT_ACCEPT";
  111. #if defined(SSL_ERROR_WANT_ASYNC)
  112. case SSL_ERROR_WANT_ASYNC:
  113. return "SSL_ERROR_WANT_ASYNC";
  114. #endif
  115. #if defined(SSL_ERROR_WANT_ASYNC_JOB)
  116. case SSL_ERROR_WANT_ASYNC_JOB:
  117. return "SSL_ERROR_WANT_ASYNC_JOB";
  118. #endif
  119. #if defined(SSL_ERROR_WANT_EARLY)
  120. case SSL_ERROR_WANT_EARLY:
  121. return "SSL_ERROR_WANT_EARLY";
  122. #endif
  123. default:
  124. return "SSL_ERROR unknown";
  125. }
  126. }
  127. /* Return error string for last OpenSSL error */
  128. static char *osslq_strerror(unsigned long error, char *buf, size_t size)
  129. {
  130. DEBUGASSERT(size);
  131. *buf = '\0';
  132. #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
  133. ERR_error_string_n((uint32_t)error, buf, size);
  134. #else
  135. ERR_error_string_n(error, buf, size);
  136. #endif
  137. if(!*buf) {
  138. const char *msg = error ? "Unknown error" : "No error";
  139. if(strlen(msg) < size)
  140. strcpy(buf, msg);
  141. }
  142. return buf;
  143. }
  144. static CURLcode make_bio_addr(BIO_ADDR **pbio_addr,
  145. const struct Curl_sockaddr_ex *addr)
  146. {
  147. BIO_ADDR *ba;
  148. CURLcode result = CURLE_FAILED_INIT;
  149. ba = BIO_ADDR_new();
  150. if(!ba) {
  151. result = CURLE_OUT_OF_MEMORY;
  152. goto out;
  153. }
  154. switch(addr->family) {
  155. case AF_INET: {
  156. struct sockaddr_in * const sin =
  157. (struct sockaddr_in * const)(void *)&addr->sa_addr;
  158. if(!BIO_ADDR_rawmake(ba, AF_INET, &sin->sin_addr,
  159. sizeof(sin->sin_addr), sin->sin_port)) {
  160. goto out;
  161. }
  162. result = CURLE_OK;
  163. break;
  164. }
  165. #ifdef ENABLE_IPV6
  166. case AF_INET6: {
  167. struct sockaddr_in6 * const sin =
  168. (struct sockaddr_in6 * const)(void *)&addr->sa_addr;
  169. if(!BIO_ADDR_rawmake(ba, AF_INET6, &sin->sin6_addr,
  170. sizeof(sin->sin6_addr), sin->sin6_port)) {
  171. }
  172. result = CURLE_OK;
  173. break;
  174. }
  175. #endif /* ENABLE_IPV6 */
  176. default:
  177. /* sunsupported */
  178. DEBUGASSERT(0);
  179. break;
  180. }
  181. out:
  182. if(result && ba) {
  183. BIO_ADDR_free(ba);
  184. ba = NULL;
  185. }
  186. *pbio_addr = ba;
  187. return result;
  188. }
  189. /* QUIC stream (not necessarily H3) */
  190. struct cf_osslq_stream {
  191. int64_t id;
  192. SSL *ssl;
  193. struct bufq recvbuf; /* QUIC war data recv buffer */
  194. BIT(recvd_eos);
  195. BIT(closed);
  196. BIT(reset);
  197. BIT(send_blocked);
  198. };
  199. static CURLcode cf_osslq_stream_open(struct cf_osslq_stream *s,
  200. SSL *conn,
  201. uint64_t flags,
  202. struct bufc_pool *bufcp,
  203. void *user_data)
  204. {
  205. DEBUGASSERT(!s->ssl);
  206. Curl_bufq_initp(&s->recvbuf, bufcp, 1, BUFQ_OPT_NONE);
  207. s->ssl = SSL_new_stream(conn, flags);
  208. if(!s->ssl) {
  209. return CURLE_FAILED_INIT;
  210. }
  211. s->id = SSL_get_stream_id(s->ssl);
  212. SSL_set_app_data(s->ssl, user_data);
  213. return CURLE_OK;
  214. }
  215. static void cf_osslq_stream_cleanup(struct cf_osslq_stream *s)
  216. {
  217. if(s->ssl) {
  218. SSL_set_app_data(s->ssl, NULL);
  219. SSL_free(s->ssl);
  220. }
  221. Curl_bufq_free(&s->recvbuf);
  222. memset(s, 0, sizeof(*s));
  223. }
  224. static void cf_osslq_stream_close(struct cf_osslq_stream *s)
  225. {
  226. if(s->ssl) {
  227. SSL_free(s->ssl);
  228. s->ssl = NULL;
  229. }
  230. }
  231. struct cf_osslq_h3conn {
  232. nghttp3_conn *conn;
  233. nghttp3_settings settings;
  234. struct cf_osslq_stream s_ctrl;
  235. struct cf_osslq_stream s_qpack_enc;
  236. struct cf_osslq_stream s_qpack_dec;
  237. struct cf_osslq_stream remote_ctrl[3]; /* uni streams opened by the peer */
  238. size_t remote_ctrl_n; /* number of peer streams opened */
  239. };
  240. static void cf_osslq_h3conn_cleanup(struct cf_osslq_h3conn *h3)
  241. {
  242. size_t i;
  243. if(h3->conn)
  244. nghttp3_conn_del(h3->conn);
  245. cf_osslq_stream_cleanup(&h3->s_ctrl);
  246. cf_osslq_stream_cleanup(&h3->s_qpack_enc);
  247. cf_osslq_stream_cleanup(&h3->s_qpack_dec);
  248. for(i = 0; i < h3->remote_ctrl_n; ++i) {
  249. cf_osslq_stream_cleanup(&h3->remote_ctrl[i]);
  250. }
  251. }
  252. struct cf_osslq_ctx {
  253. struct cf_quic_ctx q;
  254. struct ssl_peer peer;
  255. struct quic_tls_ctx tls;
  256. struct cf_call_data call_data;
  257. struct cf_osslq_h3conn h3;
  258. struct curltime started_at; /* time the current attempt started */
  259. struct curltime handshake_at; /* time connect handshake finished */
  260. struct curltime first_byte_at; /* when first byte was recvd */
  261. struct curltime reconnect_at; /* time the next attempt should start */
  262. struct bufc_pool stream_bufcp; /* chunk pool for streams */
  263. size_t max_stream_window; /* max flow window for one stream */
  264. uint64_t max_idle_ms; /* max idle time for QUIC connection */
  265. BIT(got_first_byte); /* if first byte was received */
  266. #ifdef USE_OPENSSL
  267. BIT(x509_store_setup); /* if x509 store has been set up */
  268. BIT(protocol_shutdown); /* QUIC connection is shut down */
  269. #endif
  270. };
  271. static void cf_osslq_ctx_clear(struct cf_osslq_ctx *ctx)
  272. {
  273. struct cf_call_data save = ctx->call_data;
  274. cf_osslq_h3conn_cleanup(&ctx->h3);
  275. Curl_vquic_tls_cleanup(&ctx->tls);
  276. vquic_ctx_free(&ctx->q);
  277. Curl_bufcp_free(&ctx->stream_bufcp);
  278. Curl_ssl_peer_cleanup(&ctx->peer);
  279. memset(ctx, 0, sizeof(*ctx));
  280. ctx->call_data = save;
  281. }
  282. static void cf_osslq_close(struct Curl_cfilter *cf, struct Curl_easy *data)
  283. {
  284. struct cf_osslq_ctx *ctx = cf->ctx;
  285. struct cf_call_data save;
  286. CF_DATA_SAVE(save, cf, data);
  287. if(ctx && ctx->tls.ssl) {
  288. /* TODO: send connection close */
  289. CURL_TRC_CF(data, cf, "cf_osslq_close()");
  290. cf_osslq_ctx_clear(ctx);
  291. }
  292. cf->connected = FALSE;
  293. CF_DATA_RESTORE(cf, save);
  294. }
  295. static void cf_osslq_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
  296. {
  297. struct cf_osslq_ctx *ctx = cf->ctx;
  298. struct cf_call_data save;
  299. CF_DATA_SAVE(save, cf, data);
  300. CURL_TRC_CF(data, cf, "destroy");
  301. if(ctx) {
  302. CURL_TRC_CF(data, cf, "cf_osslq_destroy()");
  303. cf_osslq_ctx_clear(ctx);
  304. free(ctx);
  305. }
  306. cf->ctx = NULL;
  307. /* No CF_DATA_RESTORE(cf, save) possible */
  308. (void)save;
  309. }
  310. static CURLcode cf_osslq_h3conn_add_stream(struct cf_osslq_h3conn *h3,
  311. SSL *stream_ssl,
  312. struct Curl_cfilter *cf,
  313. struct Curl_easy *data)
  314. {
  315. struct cf_osslq_ctx *ctx = cf->ctx;
  316. int64_t stream_id = SSL_get_stream_id(stream_ssl);
  317. if(h3->remote_ctrl_n >= ARRAYSIZE(h3->remote_ctrl)) {
  318. /* rejected, we are full */
  319. CURL_TRC_CF(data, cf, "[%" PRId64 "] rejecting additional remote stream",
  320. stream_id);
  321. SSL_free(stream_ssl);
  322. return CURLE_FAILED_INIT;
  323. }
  324. switch(SSL_get_stream_type(stream_ssl)) {
  325. case SSL_STREAM_TYPE_READ: {
  326. struct cf_osslq_stream *nstream = &h3->remote_ctrl[h3->remote_ctrl_n++];
  327. nstream->id = stream_id;
  328. nstream->ssl = stream_ssl;
  329. Curl_bufq_initp(&nstream->recvbuf, &ctx->stream_bufcp, 1, BUFQ_OPT_NONE);
  330. CURL_TRC_CF(data, cf, "[%" PRId64 "] accepted new remote uni stream",
  331. stream_id);
  332. break;
  333. }
  334. default:
  335. CURL_TRC_CF(data, cf, "[%" PRId64 "] rejecting remote non-uni-read"
  336. " stream", stream_id);
  337. SSL_free(stream_ssl);
  338. return CURLE_FAILED_INIT;
  339. }
  340. return CURLE_OK;
  341. }
  342. static CURLcode cf_osslq_ssl_err(struct Curl_cfilter *cf,
  343. struct Curl_easy *data,
  344. int detail, CURLcode def_result)
  345. {
  346. struct cf_osslq_ctx *ctx = cf->ctx;
  347. CURLcode result = def_result;
  348. sslerr_t errdetail;
  349. char ebuf[256] = "unknown";
  350. const char *err_descr = ebuf;
  351. long lerr;
  352. int lib;
  353. int reason;
  354. struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
  355. errdetail = ERR_get_error();
  356. lib = ERR_GET_LIB(errdetail);
  357. reason = ERR_GET_REASON(errdetail);
  358. if((lib == ERR_LIB_SSL) &&
  359. ((reason == SSL_R_CERTIFICATE_VERIFY_FAILED) ||
  360. (reason == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED))) {
  361. result = CURLE_PEER_FAILED_VERIFICATION;
  362. lerr = SSL_get_verify_result(ctx->tls.ssl);
  363. if(lerr != X509_V_OK) {
  364. ssl_config->certverifyresult = lerr;
  365. msnprintf(ebuf, sizeof(ebuf),
  366. "SSL certificate problem: %s",
  367. X509_verify_cert_error_string(lerr));
  368. }
  369. else
  370. err_descr = "SSL certificate verification failed";
  371. }
  372. #if defined(SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)
  373. /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on
  374. OpenSSL version above v1.1.1, not LibreSSL, BoringSSL, or AWS-LC */
  375. else if((lib == ERR_LIB_SSL) &&
  376. (reason == SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)) {
  377. /* If client certificate is required, communicate the
  378. error to client */
  379. result = CURLE_SSL_CLIENTCERT;
  380. osslq_strerror(errdetail, ebuf, sizeof(ebuf));
  381. }
  382. #endif
  383. else if((lib == ERR_LIB_SSL) && (reason == SSL_R_PROTOCOL_IS_SHUTDOWN)) {
  384. ctx->protocol_shutdown = TRUE;
  385. err_descr = "QUIC connection has been shut down";
  386. result = def_result;
  387. }
  388. else {
  389. result = def_result;
  390. osslq_strerror(errdetail, ebuf, sizeof(ebuf));
  391. }
  392. /* detail is already set to the SSL error above */
  393. /* If we e.g. use SSLv2 request-method and the server doesn't like us
  394. * (RST connection, etc.), OpenSSL gives no explanation whatsoever and
  395. * the SO_ERROR is also lost.
  396. */
  397. if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
  398. char extramsg[80]="";
  399. int sockerr = SOCKERRNO;
  400. struct ip_quadruple ip;
  401. Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip);
  402. if(sockerr && detail == SSL_ERROR_SYSCALL)
  403. Curl_strerror(sockerr, extramsg, sizeof(extramsg));
  404. failf(data, "QUIC connect: %s in connection to %s:%d (%s)",
  405. extramsg[0] ? extramsg : osslq_SSL_ERROR_to_str(detail),
  406. ctx->peer.dispname, ip.remote_port, ip.remote_ip);
  407. }
  408. else {
  409. /* Could be a CERT problem */
  410. failf(data, "%s", err_descr);
  411. }
  412. return result;
  413. }
  414. static CURLcode cf_osslq_verify_peer(struct Curl_cfilter *cf,
  415. struct Curl_easy *data)
  416. {
  417. struct cf_osslq_ctx *ctx = cf->ctx;
  418. cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
  419. cf->conn->httpversion = 30;
  420. cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX;
  421. return Curl_vquic_tls_verify_peer(&ctx->tls, cf, data, &ctx->peer);
  422. }
  423. /**
  424. * All about the H3 internals of a stream
  425. */
  426. struct h3_stream_ctx {
  427. struct cf_osslq_stream s;
  428. struct bufq sendbuf; /* h3 request body */
  429. struct bufq recvbuf; /* h3 response body */
  430. struct h1_req_parser h1; /* h1 request parsing */
  431. size_t sendbuf_len_in_flight; /* sendbuf amount "in flight" */
  432. size_t upload_blocked_len; /* the amount written last and EGAINed */
  433. size_t recv_buf_nonflow; /* buffered bytes, not counting for flow control */
  434. uint64_t error3; /* HTTP/3 stream error code */
  435. curl_off_t upload_left; /* number of request bytes left to upload */
  436. curl_off_t download_recvd; /* number of response DATA bytes received */
  437. int status_code; /* HTTP status code */
  438. bool resp_hds_complete; /* we have a complete, final response */
  439. bool closed; /* TRUE on stream close */
  440. bool reset; /* TRUE on stream reset */
  441. bool send_closed; /* stream is local closed */
  442. BIT(quic_flow_blocked); /* stream is blocked by QUIC flow control */
  443. };
  444. #define H3_STREAM_CTX(d) ((struct h3_stream_ctx *)(((d) && (d)->req.p.http)? \
  445. ((struct HTTP *)(d)->req.p.http)->h3_ctx \
  446. : NULL))
  447. #define H3_STREAM_LCTX(d) ((struct HTTP *)(d)->req.p.http)->h3_ctx
  448. #define H3_STREAM_ID(d) (H3_STREAM_CTX(d)? \
  449. H3_STREAM_CTX(d)->s.id : -2)
  450. static CURLcode h3_data_setup(struct Curl_cfilter *cf,
  451. struct Curl_easy *data)
  452. {
  453. struct cf_osslq_ctx *ctx = cf->ctx;
  454. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  455. if(!data || !data->req.p.http) {
  456. failf(data, "initialization failure, transfer not http initialized");
  457. return CURLE_FAILED_INIT;
  458. }
  459. if(stream)
  460. return CURLE_OK;
  461. stream = calloc(1, sizeof(*stream));
  462. if(!stream)
  463. return CURLE_OUT_OF_MEMORY;
  464. stream->s.id = -1;
  465. /* on send, we control how much we put into the buffer */
  466. Curl_bufq_initp(&stream->sendbuf, &ctx->stream_bufcp,
  467. H3_STREAM_SEND_CHUNKS, BUFQ_OPT_NONE);
  468. stream->sendbuf_len_in_flight = 0;
  469. /* on recv, we need a flexible buffer limit since we also write
  470. * headers to it that are not counted against the nghttp3 flow limits. */
  471. Curl_bufq_initp(&stream->recvbuf, &ctx->stream_bufcp,
  472. H3_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT);
  473. stream->recv_buf_nonflow = 0;
  474. Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN);
  475. H3_STREAM_LCTX(data) = stream;
  476. return CURLE_OK;
  477. }
  478. static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
  479. {
  480. struct cf_osslq_ctx *ctx = cf->ctx;
  481. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  482. (void)cf;
  483. if(stream) {
  484. CURL_TRC_CF(data, cf, "[%"PRId64"] easy handle is done", stream->s.id);
  485. if(ctx->h3.conn && !stream->closed) {
  486. nghttp3_conn_shutdown_stream_read(ctx->h3.conn, stream->s.id);
  487. nghttp3_conn_close_stream(ctx->h3.conn, stream->s.id,
  488. NGHTTP3_H3_REQUEST_CANCELLED);
  489. nghttp3_conn_set_stream_user_data(ctx->h3.conn, stream->s.id, NULL);
  490. stream->closed = TRUE;
  491. }
  492. cf_osslq_stream_cleanup(&stream->s);
  493. Curl_bufq_free(&stream->sendbuf);
  494. Curl_bufq_free(&stream->recvbuf);
  495. Curl_h1_req_parse_free(&stream->h1);
  496. free(stream);
  497. H3_STREAM_LCTX(data) = NULL;
  498. }
  499. }
  500. static struct cf_osslq_stream *cf_osslq_get_qstream(struct Curl_cfilter *cf,
  501. struct Curl_easy *data,
  502. int64_t stream_id)
  503. {
  504. struct cf_osslq_ctx *ctx = cf->ctx;
  505. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  506. struct Curl_easy *sdata;
  507. if(stream && stream->s.id == stream_id) {
  508. return &stream->s;
  509. }
  510. else if(ctx->h3.s_ctrl.id == stream_id) {
  511. return &ctx->h3.s_ctrl;
  512. }
  513. else if(ctx->h3.s_qpack_enc.id == stream_id) {
  514. return &ctx->h3.s_qpack_enc;
  515. }
  516. else if(ctx->h3.s_qpack_dec.id == stream_id) {
  517. return &ctx->h3.s_qpack_dec;
  518. }
  519. else {
  520. DEBUGASSERT(data->multi);
  521. for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
  522. if((sdata->conn == data->conn) && H3_STREAM_ID(sdata) == stream_id) {
  523. stream = H3_STREAM_CTX(sdata);
  524. return stream? &stream->s : NULL;
  525. }
  526. }
  527. }
  528. return NULL;
  529. }
  530. static void h3_drain_stream(struct Curl_cfilter *cf,
  531. struct Curl_easy *data)
  532. {
  533. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  534. unsigned char bits;
  535. (void)cf;
  536. bits = CURL_CSELECT_IN;
  537. if(stream && stream->upload_left && !stream->send_closed)
  538. bits |= CURL_CSELECT_OUT;
  539. if(data->state.select_bits != bits) {
  540. data->state.select_bits = bits;
  541. Curl_expire(data, 0, EXPIRE_RUN_NOW);
  542. }
  543. }
  544. static CURLcode h3_data_pause(struct Curl_cfilter *cf,
  545. struct Curl_easy *data,
  546. bool pause)
  547. {
  548. if(!pause) {
  549. /* unpaused. make it run again right away */
  550. h3_drain_stream(cf, data);
  551. Curl_expire(data, 0, EXPIRE_RUN_NOW);
  552. }
  553. return CURLE_OK;
  554. }
  555. static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
  556. uint64_t app_error_code, void *user_data,
  557. void *stream_user_data)
  558. {
  559. struct Curl_cfilter *cf = user_data;
  560. struct Curl_easy *data = stream_user_data;
  561. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  562. (void)conn;
  563. (void)stream_id;
  564. /* we might be called by nghttp3 after we already cleaned up */
  565. if(!stream)
  566. return 0;
  567. stream->closed = TRUE;
  568. stream->error3 = app_error_code;
  569. if(stream->error3 != NGHTTP3_H3_NO_ERROR) {
  570. stream->reset = TRUE;
  571. stream->send_closed = TRUE;
  572. CURL_TRC_CF(data, cf, "[%" PRId64 "] RESET: error %" PRId64,
  573. stream->s.id, stream->error3);
  574. }
  575. else {
  576. CURL_TRC_CF(data, cf, "[%" PRId64 "] CLOSED", stream->s.id);
  577. }
  578. h3_drain_stream(cf, data);
  579. return 0;
  580. }
  581. /*
  582. * write_resp_raw() copies response data in raw format to the `data`'s
  583. * receive buffer. If not enough space is available, it appends to the
  584. * `data`'s overflow buffer.
  585. */
  586. static CURLcode write_resp_raw(struct Curl_cfilter *cf,
  587. struct Curl_easy *data,
  588. const void *mem, size_t memlen,
  589. bool flow)
  590. {
  591. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  592. CURLcode result = CURLE_OK;
  593. ssize_t nwritten;
  594. (void)cf;
  595. if(!stream) {
  596. return CURLE_RECV_ERROR;
  597. }
  598. nwritten = Curl_bufq_write(&stream->recvbuf, mem, memlen, &result);
  599. if(nwritten < 0) {
  600. return result;
  601. }
  602. if(!flow)
  603. stream->recv_buf_nonflow += (size_t)nwritten;
  604. if((size_t)nwritten < memlen) {
  605. /* This MUST not happen. Our recbuf is dimensioned to hold the
  606. * full max_stream_window and then some for this very reason. */
  607. DEBUGASSERT(0);
  608. return CURLE_RECV_ERROR;
  609. }
  610. return result;
  611. }
  612. static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
  613. const uint8_t *buf, size_t buflen,
  614. void *user_data, void *stream_user_data)
  615. {
  616. struct Curl_cfilter *cf = user_data;
  617. struct Curl_easy *data = stream_user_data;
  618. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  619. CURLcode result;
  620. (void)conn;
  621. (void)stream3_id;
  622. if(!stream)
  623. return NGHTTP3_ERR_CALLBACK_FAILURE;
  624. result = write_resp_raw(cf, data, buf, buflen, TRUE);
  625. if(result) {
  626. CURL_TRC_CF(data, cf, "[%" PRId64 "] DATA len=%zu, ERROR receiving %d",
  627. stream->s.id, buflen, result);
  628. return NGHTTP3_ERR_CALLBACK_FAILURE;
  629. }
  630. stream->download_recvd += (curl_off_t)buflen;
  631. CURL_TRC_CF(data, cf, "[%" PRId64 "] DATA len=%zu, total=%zd",
  632. stream->s.id, buflen, stream->download_recvd);
  633. h3_drain_stream(cf, data);
  634. return 0;
  635. }
  636. static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream_id,
  637. size_t consumed, void *user_data,
  638. void *stream_user_data)
  639. {
  640. struct Curl_cfilter *cf = user_data;
  641. struct Curl_easy *data = stream_user_data;
  642. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  643. (void)conn;
  644. (void)stream_id;
  645. if(stream)
  646. CURL_TRC_CF(data, cf, "[%" PRId64 "] deferred consume %zu bytes",
  647. stream->s.id, consumed);
  648. return 0;
  649. }
  650. static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
  651. int32_t token, nghttp3_rcbuf *name,
  652. nghttp3_rcbuf *value, uint8_t flags,
  653. void *user_data, void *stream_user_data)
  654. {
  655. struct Curl_cfilter *cf = user_data;
  656. nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
  657. nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
  658. struct Curl_easy *data = stream_user_data;
  659. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  660. CURLcode result = CURLE_OK;
  661. (void)conn;
  662. (void)stream_id;
  663. (void)token;
  664. (void)flags;
  665. (void)cf;
  666. /* we might have cleaned up this transfer already */
  667. if(!stream)
  668. return 0;
  669. if(token == NGHTTP3_QPACK_TOKEN__STATUS) {
  670. char line[14]; /* status line is always 13 characters long */
  671. size_t ncopy;
  672. result = Curl_http_decode_status(&stream->status_code,
  673. (const char *)h3val.base, h3val.len);
  674. if(result)
  675. return -1;
  676. ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n",
  677. stream->status_code);
  678. CURL_TRC_CF(data, cf, "[%" PRId64 "] status: %s", stream_id, line);
  679. result = write_resp_raw(cf, data, line, ncopy, FALSE);
  680. if(result) {
  681. return -1;
  682. }
  683. }
  684. else {
  685. /* store as an HTTP1-style header */
  686. CURL_TRC_CF(data, cf, "[%" PRId64 "] header: %.*s: %.*s",
  687. stream_id, (int)h3name.len, h3name.base,
  688. (int)h3val.len, h3val.base);
  689. result = write_resp_raw(cf, data, h3name.base, h3name.len, FALSE);
  690. if(result) {
  691. return -1;
  692. }
  693. result = write_resp_raw(cf, data, ": ", 2, FALSE);
  694. if(result) {
  695. return -1;
  696. }
  697. result = write_resp_raw(cf, data, h3val.base, h3val.len, FALSE);
  698. if(result) {
  699. return -1;
  700. }
  701. result = write_resp_raw(cf, data, "\r\n", 2, FALSE);
  702. if(result) {
  703. return -1;
  704. }
  705. }
  706. return 0;
  707. }
  708. static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
  709. int fin, void *user_data, void *stream_user_data)
  710. {
  711. struct Curl_cfilter *cf = user_data;
  712. struct Curl_easy *data = stream_user_data;
  713. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  714. CURLcode result = CURLE_OK;
  715. (void)conn;
  716. (void)stream_id;
  717. (void)fin;
  718. (void)cf;
  719. if(!stream)
  720. return 0;
  721. /* add a CRLF only if we've received some headers */
  722. result = write_resp_raw(cf, data, "\r\n", 2, FALSE);
  723. if(result) {
  724. return -1;
  725. }
  726. CURL_TRC_CF(data, cf, "[%" PRId64 "] end_headers, status=%d",
  727. stream_id, stream->status_code);
  728. if(stream->status_code / 100 != 1) {
  729. stream->resp_hds_complete = TRUE;
  730. }
  731. h3_drain_stream(cf, data);
  732. return 0;
  733. }
  734. static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id,
  735. uint64_t app_error_code, void *user_data,
  736. void *stream_user_data)
  737. {
  738. struct Curl_cfilter *cf = user_data;
  739. struct Curl_easy *data = stream_user_data;
  740. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  741. (void)conn;
  742. (void)app_error_code;
  743. if(!stream || !stream->s.ssl)
  744. return 0;
  745. CURL_TRC_CF(data, cf, "[%" PRId64 "] stop_sending", stream_id);
  746. cf_osslq_stream_close(&stream->s);
  747. return 0;
  748. }
  749. static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t stream_id,
  750. uint64_t app_error_code, void *user_data,
  751. void *stream_user_data) {
  752. struct Curl_cfilter *cf = user_data;
  753. struct Curl_easy *data = stream_user_data;
  754. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  755. int rv;
  756. (void)conn;
  757. if(stream && stream->s.ssl) {
  758. SSL_STREAM_RESET_ARGS args = {0};
  759. args.quic_error_code = app_error_code;
  760. rv = !SSL_stream_reset(stream->s.ssl, &args, sizeof(args));
  761. CURL_TRC_CF(data, cf, "[%" PRId64 "] reset -> %d", stream_id, rv);
  762. if(!rv) {
  763. return NGHTTP3_ERR_CALLBACK_FAILURE;
  764. }
  765. }
  766. return 0;
  767. }
  768. static nghttp3_ssize
  769. cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id,
  770. nghttp3_vec *vec, size_t veccnt,
  771. uint32_t *pflags, void *user_data,
  772. void *stream_user_data)
  773. {
  774. struct Curl_cfilter *cf = user_data;
  775. struct Curl_easy *data = stream_user_data;
  776. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  777. ssize_t nwritten = 0;
  778. size_t nvecs = 0;
  779. (void)cf;
  780. (void)conn;
  781. (void)stream_id;
  782. (void)user_data;
  783. (void)veccnt;
  784. if(!stream)
  785. return NGHTTP3_ERR_CALLBACK_FAILURE;
  786. /* nghttp3 keeps references to the sendbuf data until it is ACKed
  787. * by the server (see `cb_h3_acked_req_body()` for updates).
  788. * `sendbuf_len_in_flight` is the amount of bytes in `sendbuf`
  789. * that we have already passed to nghttp3, but which have not been
  790. * ACKed yet.
  791. * Any amount beyond `sendbuf_len_in_flight` we need still to pass
  792. * to nghttp3. Do that now, if we can. */
  793. if(stream->sendbuf_len_in_flight < Curl_bufq_len(&stream->sendbuf)) {
  794. nvecs = 0;
  795. while(nvecs < veccnt &&
  796. Curl_bufq_peek_at(&stream->sendbuf,
  797. stream->sendbuf_len_in_flight,
  798. (const unsigned char **)&vec[nvecs].base,
  799. &vec[nvecs].len)) {
  800. stream->sendbuf_len_in_flight += vec[nvecs].len;
  801. nwritten += vec[nvecs].len;
  802. ++nvecs;
  803. }
  804. DEBUGASSERT(nvecs > 0); /* we SHOULD have been be able to peek */
  805. }
  806. if(nwritten > 0 && stream->upload_left != -1)
  807. stream->upload_left -= nwritten;
  808. /* When we stopped sending and everything in `sendbuf` is "in flight",
  809. * we are at the end of the request body. */
  810. if(stream->upload_left == 0) {
  811. *pflags = NGHTTP3_DATA_FLAG_EOF;
  812. stream->send_closed = TRUE;
  813. }
  814. else if(!nwritten) {
  815. /* Not EOF, and nothing to give, we signal WOULDBLOCK. */
  816. CURL_TRC_CF(data, cf, "[%" PRId64 "] read req body -> AGAIN",
  817. stream->s.id);
  818. return NGHTTP3_ERR_WOULDBLOCK;
  819. }
  820. CURL_TRC_CF(data, cf, "[%" PRId64 "] read req body -> "
  821. "%d vecs%s with %zu (buffered=%zu, left=%"
  822. CURL_FORMAT_CURL_OFF_T ")",
  823. stream->s.id, (int)nvecs,
  824. *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"",
  825. nwritten, Curl_bufq_len(&stream->sendbuf),
  826. stream->upload_left);
  827. return (nghttp3_ssize)nvecs;
  828. }
  829. static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
  830. uint64_t datalen, void *user_data,
  831. void *stream_user_data)
  832. {
  833. struct Curl_cfilter *cf = user_data;
  834. struct Curl_easy *data = stream_user_data;
  835. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  836. size_t skiplen;
  837. (void)cf;
  838. if(!stream)
  839. return 0;
  840. /* The server acknowledged `datalen` of bytes from our request body.
  841. * This is a delta. We have kept this data in `sendbuf` for
  842. * re-transmissions and can free it now. */
  843. if(datalen >= (uint64_t)stream->sendbuf_len_in_flight)
  844. skiplen = stream->sendbuf_len_in_flight;
  845. else
  846. skiplen = (size_t)datalen;
  847. Curl_bufq_skip(&stream->sendbuf, skiplen);
  848. stream->sendbuf_len_in_flight -= skiplen;
  849. /* Everything ACKed, we resume upload processing */
  850. if(!stream->sendbuf_len_in_flight) {
  851. int rv = nghttp3_conn_resume_stream(conn, stream_id);
  852. if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  853. return NGHTTP3_ERR_CALLBACK_FAILURE;
  854. }
  855. }
  856. return 0;
  857. }
  858. static nghttp3_callbacks ngh3_callbacks = {
  859. cb_h3_acked_stream_data,
  860. cb_h3_stream_close,
  861. cb_h3_recv_data,
  862. cb_h3_deferred_consume,
  863. NULL, /* begin_headers */
  864. cb_h3_recv_header,
  865. cb_h3_end_headers,
  866. NULL, /* begin_trailers */
  867. cb_h3_recv_header,
  868. NULL, /* end_trailers */
  869. cb_h3_stop_sending,
  870. NULL, /* end_stream */
  871. cb_h3_reset_stream,
  872. NULL, /* shutdown */
  873. NULL /* recv_settings */
  874. };
  875. static CURLcode cf_osslq_h3conn_init(struct cf_osslq_ctx *ctx, SSL *conn,
  876. void *user_data)
  877. {
  878. struct cf_osslq_h3conn *h3 = &ctx->h3;
  879. CURLcode result;
  880. int rc;
  881. nghttp3_settings_default(&h3->settings);
  882. rc = nghttp3_conn_client_new(&h3->conn,
  883. &ngh3_callbacks,
  884. &h3->settings,
  885. nghttp3_mem_default(),
  886. user_data);
  887. if(rc) {
  888. result = CURLE_OUT_OF_MEMORY;
  889. goto out;
  890. }
  891. result = cf_osslq_stream_open(&h3->s_ctrl, conn,
  892. SSL_STREAM_FLAG_ADVANCE|SSL_STREAM_FLAG_UNI,
  893. &ctx->stream_bufcp, NULL);
  894. if(result) {
  895. result = CURLE_QUIC_CONNECT_ERROR;
  896. goto out;
  897. }
  898. result = cf_osslq_stream_open(&h3->s_qpack_enc, conn,
  899. SSL_STREAM_FLAG_ADVANCE|SSL_STREAM_FLAG_UNI,
  900. &ctx->stream_bufcp, NULL);
  901. if(result) {
  902. result = CURLE_QUIC_CONNECT_ERROR;
  903. goto out;
  904. }
  905. result = cf_osslq_stream_open(&h3->s_qpack_dec, conn,
  906. SSL_STREAM_FLAG_ADVANCE|SSL_STREAM_FLAG_UNI,
  907. &ctx->stream_bufcp, NULL);
  908. if(result) {
  909. result = CURLE_QUIC_CONNECT_ERROR;
  910. goto out;
  911. }
  912. rc = nghttp3_conn_bind_control_stream(h3->conn, h3->s_ctrl.id);
  913. if(rc) {
  914. result = CURLE_QUIC_CONNECT_ERROR;
  915. goto out;
  916. }
  917. rc = nghttp3_conn_bind_qpack_streams(h3->conn, h3->s_qpack_enc.id,
  918. h3->s_qpack_dec.id);
  919. if(rc) {
  920. result = CURLE_QUIC_CONNECT_ERROR;
  921. goto out;
  922. }
  923. result = CURLE_OK;
  924. out:
  925. return result;
  926. }
  927. static CURLcode cf_osslq_ctx_start(struct Curl_cfilter *cf,
  928. struct Curl_easy *data)
  929. {
  930. struct cf_osslq_ctx *ctx = cf->ctx;
  931. CURLcode result;
  932. int rv;
  933. const struct Curl_sockaddr_ex *peer_addr = NULL;
  934. BIO *bio = NULL;
  935. BIO_ADDR *baddr = NULL;
  936. Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE,
  937. H3_STREAM_POOL_SPARES);
  938. result = Curl_ssl_peer_init(&ctx->peer, cf);
  939. if(result)
  940. goto out;
  941. #define H3_ALPN "\x2h3"
  942. result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer,
  943. H3_ALPN, sizeof(H3_ALPN) - 1,
  944. NULL, NULL);
  945. if(result)
  946. goto out;
  947. result = vquic_ctx_init(&ctx->q);
  948. if(result)
  949. goto out;
  950. result = CURLE_QUIC_CONNECT_ERROR;
  951. Curl_cf_socket_peek(cf->next, data, &ctx->q.sockfd, &peer_addr, NULL);
  952. if(!peer_addr)
  953. goto out;
  954. ctx->q.local_addrlen = sizeof(ctx->q.local_addr);
  955. rv = getsockname(ctx->q.sockfd, (struct sockaddr *)&ctx->q.local_addr,
  956. &ctx->q.local_addrlen);
  957. if(rv == -1)
  958. goto out;
  959. result = make_bio_addr(&baddr, peer_addr);
  960. if(result) {
  961. failf(data, "error creating BIO_ADDR from sockaddr");
  962. goto out;
  963. }
  964. /* Type conversions, see #12861: OpenSSL wants an `int`, but on 64-bit
  965. * Win32 systems, Microsoft defines SOCKET as `unsigned long long`.
  966. */
  967. #if defined(_WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
  968. if(ctx->q.sockfd > INT_MAX) {
  969. failf(data, "Windows socket identifier larger than MAX_INT, "
  970. "unable to set in OpenSSL dgram API.");
  971. result = CURLE_QUIC_CONNECT_ERROR;
  972. goto out;
  973. }
  974. bio = BIO_new_dgram((int)ctx->q.sockfd, BIO_NOCLOSE);
  975. #else
  976. bio = BIO_new_dgram(ctx->q.sockfd, BIO_NOCLOSE);
  977. #endif
  978. if(!bio) {
  979. result = CURLE_OUT_OF_MEMORY;
  980. goto out;
  981. }
  982. if(!SSL_set1_initial_peer_addr(ctx->tls.ssl, baddr)) {
  983. failf(data, "failed to set the initial peer address");
  984. result = CURLE_FAILED_INIT;
  985. goto out;
  986. }
  987. if(!SSL_set_blocking_mode(ctx->tls.ssl, 0)) {
  988. failf(data, "failed to turn off blocking mode");
  989. result = CURLE_FAILED_INIT;
  990. goto out;
  991. }
  992. #ifdef SSL_VALUE_QUIC_IDLE_TIMEOUT
  993. /* Added in OpenSSL v3.3.x */
  994. if(!SSL_set_feature_request_uint(ctx->tls.ssl, SSL_VALUE_QUIC_IDLE_TIMEOUT,
  995. CURL_QUIC_MAX_IDLE_MS)) {
  996. CURL_TRC_CF(data, cf, "error setting idle timeout, ");
  997. result = CURLE_FAILED_INIT;
  998. goto out;
  999. }
  1000. #endif
  1001. SSL_set_bio(ctx->tls.ssl, bio, bio);
  1002. bio = NULL;
  1003. SSL_set_connect_state(ctx->tls.ssl);
  1004. SSL_set_incoming_stream_policy(ctx->tls.ssl,
  1005. SSL_INCOMING_STREAM_POLICY_ACCEPT, 0);
  1006. /* setup the H3 things on top of the QUIC connection */
  1007. result = cf_osslq_h3conn_init(ctx, ctx->tls.ssl, cf);
  1008. out:
  1009. if(bio)
  1010. BIO_free(bio);
  1011. if(baddr)
  1012. BIO_ADDR_free(baddr);
  1013. CURL_TRC_CF(data, cf, "QUIC tls init -> %d", result);
  1014. return result;
  1015. }
  1016. struct h3_quic_recv_ctx {
  1017. struct Curl_cfilter *cf;
  1018. struct Curl_easy *data;
  1019. struct cf_osslq_stream *s;
  1020. };
  1021. static ssize_t h3_quic_recv(void *reader_ctx,
  1022. unsigned char *buf, size_t len,
  1023. CURLcode *err)
  1024. {
  1025. struct h3_quic_recv_ctx *x = reader_ctx;
  1026. size_t nread;
  1027. int rv;
  1028. *err = CURLE_OK;
  1029. rv = SSL_read_ex(x->s->ssl, buf, len, &nread);
  1030. if(rv <= 0) {
  1031. int detail = SSL_get_error(x->s->ssl, rv);
  1032. if(detail == SSL_ERROR_WANT_READ || detail == SSL_ERROR_WANT_WRITE) {
  1033. *err = CURLE_AGAIN;
  1034. return -1;
  1035. }
  1036. else if(detail == SSL_ERROR_ZERO_RETURN) {
  1037. CURL_TRC_CF(x->data, x->cf, "[%" PRId64 "] h3_quic_recv -> EOS",
  1038. x->s->id);
  1039. x->s->recvd_eos = TRUE;
  1040. return 0;
  1041. }
  1042. else if(SSL_get_stream_read_state(x->s->ssl) ==
  1043. SSL_STREAM_STATE_RESET_REMOTE) {
  1044. uint64_t app_error_code = NGHTTP3_H3_NO_ERROR;
  1045. SSL_get_stream_read_error_code(x->s->ssl, &app_error_code);
  1046. CURL_TRC_CF(x->data, x->cf, "[%" PRId64 "] h3_quic_recv -> RESET, "
  1047. "rv=%d, app_err=%" PRIu64,
  1048. x->s->id, rv, app_error_code);
  1049. if(app_error_code != NGHTTP3_H3_NO_ERROR) {
  1050. x->s->reset = TRUE;
  1051. }
  1052. x->s->recvd_eos = TRUE;
  1053. return 0;
  1054. }
  1055. else {
  1056. *err = cf_osslq_ssl_err(x->cf, x->data, detail, CURLE_RECV_ERROR);
  1057. return -1;
  1058. }
  1059. }
  1060. else {
  1061. /* CURL_TRC_CF(x->data, x->cf, "[%" PRId64 "] h3_quic_recv -> %zu bytes",
  1062. x->s->id, nread); */
  1063. }
  1064. return (ssize_t)nread;
  1065. }
  1066. static CURLcode cf_osslq_stream_recv(struct cf_osslq_stream *s,
  1067. struct Curl_cfilter *cf,
  1068. struct Curl_easy *data)
  1069. {
  1070. struct cf_osslq_ctx *ctx = cf->ctx;
  1071. CURLcode result = CURLE_OK;
  1072. ssize_t nread;
  1073. struct h3_quic_recv_ctx x;
  1074. int rv, eagain = FALSE;
  1075. size_t total_recv_len = 0;
  1076. DEBUGASSERT(s);
  1077. if(s->closed)
  1078. return CURLE_OK;
  1079. x.cf = cf;
  1080. x.data = data;
  1081. x.s = s;
  1082. while(s->ssl && !s->closed && !eagain &&
  1083. (total_recv_len < H3_STREAM_CHUNK_SIZE)) {
  1084. if(Curl_bufq_is_empty(&s->recvbuf) && !s->recvd_eos) {
  1085. while(!eagain && !s->recvd_eos && !Curl_bufq_is_full(&s->recvbuf)) {
  1086. nread = Curl_bufq_sipn(&s->recvbuf, 0, h3_quic_recv, &x, &result);
  1087. if(nread < 0) {
  1088. if(result != CURLE_AGAIN)
  1089. goto out;
  1090. result = CURLE_OK;
  1091. eagain = TRUE;
  1092. }
  1093. }
  1094. }
  1095. /* Forward what we have to nghttp3 */
  1096. if(!Curl_bufq_is_empty(&s->recvbuf)) {
  1097. const unsigned char *buf;
  1098. size_t blen;
  1099. while(Curl_bufq_peek(&s->recvbuf, &buf, &blen)) {
  1100. nread = nghttp3_conn_read_stream(ctx->h3.conn, s->id,
  1101. buf, blen, 0);
  1102. CURL_TRC_CF(data, cf, "[%" PRId64 "] forward %zu bytes "
  1103. "to nghttp3 -> %zd", s->id, blen, nread);
  1104. if(nread < 0) {
  1105. failf(data, "nghttp3_conn_read_stream(len=%zu) error: %s",
  1106. blen, nghttp3_strerror((int)nread));
  1107. result = CURLE_RECV_ERROR;
  1108. goto out;
  1109. }
  1110. /* success, `nread` is the flow for QUIC to count as "consumed",
  1111. * not sure how that will work with OpenSSL. Anyways, without error,
  1112. * all data that we passed is not owned by nghttp3. */
  1113. Curl_bufq_skip(&s->recvbuf, blen);
  1114. total_recv_len += blen;
  1115. }
  1116. }
  1117. /* When we forwarded everything, handle RESET/EOS */
  1118. if(Curl_bufq_is_empty(&s->recvbuf) && !s->closed) {
  1119. result = CURLE_OK;
  1120. if(s->reset) {
  1121. uint64_t app_error;
  1122. if(!SSL_get_stream_read_error_code(s->ssl, &app_error)) {
  1123. failf(data, "SSL_get_stream_read_error_code returned error");
  1124. result = CURLE_RECV_ERROR;
  1125. goto out;
  1126. }
  1127. rv = nghttp3_conn_close_stream(ctx->h3.conn, s->id, app_error);
  1128. s->closed = TRUE;
  1129. if(rv < 0 && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  1130. failf(data, "nghttp3_conn_close_stream returned error: %s",
  1131. nghttp3_strerror(rv));
  1132. result = CURLE_RECV_ERROR;
  1133. goto out;
  1134. }
  1135. }
  1136. else if(s->recvd_eos) {
  1137. rv = nghttp3_conn_close_stream(ctx->h3.conn, s->id,
  1138. NGHTTP3_H3_NO_ERROR);
  1139. s->closed = TRUE;
  1140. CURL_TRC_CF(data, cf, "[%" PRId64 "] close nghttp3 stream -> %d",
  1141. s->id, rv);
  1142. if(rv < 0 && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  1143. failf(data, "nghttp3_conn_close_stream returned error: %s",
  1144. nghttp3_strerror(rv));
  1145. result = CURLE_RECV_ERROR;
  1146. goto out;
  1147. }
  1148. }
  1149. }
  1150. }
  1151. out:
  1152. if(result)
  1153. CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_osslq_stream_recv -> %d",
  1154. s->id, result);
  1155. return result;
  1156. }
  1157. static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
  1158. struct Curl_easy *data)
  1159. {
  1160. struct cf_osslq_ctx *ctx = cf->ctx;
  1161. CURLcode result = CURLE_OK;
  1162. if(!ctx->tls.ssl)
  1163. goto out;
  1164. ERR_clear_error();
  1165. /* 1. Check for new incoming streams */
  1166. while(1) {
  1167. SSL *snew = SSL_accept_stream(ctx->tls.ssl, SSL_ACCEPT_STREAM_NO_BLOCK);
  1168. if(!snew)
  1169. break;
  1170. (void)cf_osslq_h3conn_add_stream(&ctx->h3, snew, cf, data);
  1171. }
  1172. if(!SSL_handle_events(ctx->tls.ssl)) {
  1173. int detail = SSL_get_error(ctx->tls.ssl, 0);
  1174. result = cf_osslq_ssl_err(cf, data, detail, CURLE_RECV_ERROR);
  1175. }
  1176. if(ctx->h3.conn) {
  1177. size_t i;
  1178. for(i = 0; i < ctx->h3.remote_ctrl_n; ++i) {
  1179. result = cf_osslq_stream_recv(&ctx->h3.remote_ctrl[i], cf, data);
  1180. if(result)
  1181. goto out;
  1182. }
  1183. }
  1184. if(ctx->h3.conn) {
  1185. struct Curl_easy *sdata;
  1186. struct h3_stream_ctx *stream;
  1187. /* PULL all open streams */
  1188. DEBUGASSERT(data->multi);
  1189. for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
  1190. if(sdata->conn == data->conn && CURL_WANT_RECV(sdata)) {
  1191. stream = H3_STREAM_CTX(sdata);
  1192. if(stream && !stream->closed &&
  1193. !Curl_bufq_is_full(&stream->recvbuf)) {
  1194. result = cf_osslq_stream_recv(&stream->s, cf, sdata);
  1195. if(result)
  1196. goto out;
  1197. }
  1198. }
  1199. }
  1200. }
  1201. out:
  1202. CURL_TRC_CF(data, cf, "progress_ingress -> %d", result);
  1203. return result;
  1204. }
  1205. /* Iterate over all streams and check if blocked can be unblocked */
  1206. static CURLcode cf_osslq_check_and_unblock(struct Curl_cfilter *cf,
  1207. struct Curl_easy *data)
  1208. {
  1209. struct cf_osslq_ctx *ctx = cf->ctx;
  1210. struct Curl_easy *sdata;
  1211. struct h3_stream_ctx *stream;
  1212. if(ctx->h3.conn) {
  1213. for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
  1214. if(sdata->conn == data->conn) {
  1215. stream = H3_STREAM_CTX(sdata);
  1216. if(stream && stream->s.ssl && stream->s.send_blocked &&
  1217. !SSL_want_write(stream->s.ssl)) {
  1218. nghttp3_conn_unblock_stream(ctx->h3.conn, stream->s.id);
  1219. stream->s.send_blocked = FALSE;
  1220. h3_drain_stream(cf, sdata);
  1221. CURL_TRC_CF(sdata, cf, "unblocked");
  1222. }
  1223. }
  1224. }
  1225. }
  1226. return CURLE_OK;
  1227. }
  1228. static CURLcode h3_send_streams(struct Curl_cfilter *cf,
  1229. struct Curl_easy *data)
  1230. {
  1231. struct cf_osslq_ctx *ctx = cf->ctx;
  1232. CURLcode result = CURLE_OK;
  1233. if(!ctx->tls.ssl || !ctx->h3.conn)
  1234. goto out;
  1235. for(;;) {
  1236. struct cf_osslq_stream *s = NULL;
  1237. nghttp3_vec vec[16];
  1238. nghttp3_ssize n, i;
  1239. int64_t stream_id;
  1240. size_t written;
  1241. int eos, ok, rv;
  1242. size_t total_len, acked_len = 0;
  1243. bool blocked = FALSE, eos_written = FALSE;
  1244. n = nghttp3_conn_writev_stream(ctx->h3.conn, &stream_id, &eos,
  1245. vec, ARRAYSIZE(vec));
  1246. if(n < 0) {
  1247. failf(data, "nghttp3_conn_writev_stream returned error: %s",
  1248. nghttp3_strerror((int)n));
  1249. result = CURLE_SEND_ERROR;
  1250. goto out;
  1251. }
  1252. if(stream_id < 0) {
  1253. result = CURLE_OK;
  1254. goto out;
  1255. }
  1256. /* Get the stream for this data */
  1257. s = cf_osslq_get_qstream(cf, data, stream_id);
  1258. if(!s) {
  1259. failf(data, "nghttp3_conn_writev_stream gave unknown stream %" PRId64,
  1260. stream_id);
  1261. result = CURLE_SEND_ERROR;
  1262. goto out;
  1263. }
  1264. /* Now write the data to the stream's SSL*, it may not all fit! */
  1265. DEBUGASSERT(s->id == stream_id);
  1266. for(i = 0, total_len = 0; i < n; ++i) {
  1267. total_len += vec[i].len;
  1268. }
  1269. for(i = 0; (i < n) && !blocked; ++i) {
  1270. /* Without stream->s.ssl, we closed that already, so
  1271. * pretend the write did succeed. */
  1272. #ifdef SSL_WRITE_FLAG_CONCLUDE
  1273. /* Since OpenSSL v3.3.x, on last chunk set EOS if needed */
  1274. uint64_t flags = (eos && ((i + 1) == n))? SSL_WRITE_FLAG_CONCLUDE : 0;
  1275. written = vec[i].len;
  1276. ok = !s->ssl || SSL_write_ex2(s->ssl, vec[i].base, vec[i].len, flags,
  1277. &written);
  1278. if(ok && flags & SSL_WRITE_FLAG_CONCLUDE)
  1279. eos_written = TRUE;
  1280. #else
  1281. written = vec[i].len;
  1282. ok = !s->ssl || SSL_write_ex(s->ssl, vec[i].base, vec[i].len,
  1283. &written);
  1284. #endif
  1285. if(ok) {
  1286. /* As OpenSSL buffers the data, we count this as acknowledged
  1287. * from nghttp3's point of view */
  1288. CURL_TRC_CF(data, cf, "[%"PRId64"] send %zu bytes to QUIC ok",
  1289. s->id, vec[i].len);
  1290. acked_len += vec[i].len;
  1291. }
  1292. else {
  1293. int detail = SSL_get_error(s->ssl, 0);
  1294. switch(detail) {
  1295. case SSL_ERROR_WANT_WRITE:
  1296. case SSL_ERROR_WANT_READ:
  1297. /* QUIC blocked us from writing more */
  1298. CURL_TRC_CF(data, cf, "[%"PRId64"] send %zu bytes to QUIC blocked",
  1299. s->id, vec[i].len);
  1300. written = 0;
  1301. nghttp3_conn_block_stream(ctx->h3.conn, s->id);
  1302. s->send_blocked = blocked = TRUE;
  1303. break;
  1304. default:
  1305. failf(data, "[%"PRId64"] send %zu bytes to QUIC, SSL error %d",
  1306. s->id, vec[i].len, detail);
  1307. result = cf_osslq_ssl_err(cf, data, detail, CURLE_SEND_ERROR);
  1308. goto out;
  1309. }
  1310. }
  1311. }
  1312. if(acked_len > 0 || (eos && !s->send_blocked)) {
  1313. /* Since QUIC buffers the data written internally, we can tell
  1314. * nghttp3 that it can move forward on it */
  1315. ctx->q.last_io = Curl_now();
  1316. rv = nghttp3_conn_add_write_offset(ctx->h3.conn, s->id, acked_len);
  1317. if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  1318. failf(data, "nghttp3_conn_add_write_offset returned error: %s\n",
  1319. nghttp3_strerror(rv));
  1320. result = CURLE_SEND_ERROR;
  1321. goto out;
  1322. }
  1323. rv = nghttp3_conn_add_ack_offset(ctx->h3.conn, s->id, acked_len);
  1324. if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  1325. failf(data, "nghttp3_conn_add_ack_offset returned error: %s\n",
  1326. nghttp3_strerror(rv));
  1327. result = CURLE_SEND_ERROR;
  1328. goto out;
  1329. }
  1330. CURL_TRC_CF(data, cf, "[%" PRId64 "] forwarded %zu/%zu h3 bytes "
  1331. "to QUIC, eos=%d", s->id, acked_len, total_len, eos);
  1332. }
  1333. if(eos && !s->send_blocked && !eos_written) {
  1334. /* wrote everything and H3 indicates end of stream */
  1335. CURL_TRC_CF(data, cf, "[%" PRId64 "] closing QUIC stream", s->id);
  1336. SSL_stream_conclude(s->ssl, 0);
  1337. }
  1338. }
  1339. out:
  1340. CURL_TRC_CF(data, cf, "h3_send_streams -> %d", result);
  1341. return result;
  1342. }
  1343. static CURLcode cf_progress_egress(struct Curl_cfilter *cf,
  1344. struct Curl_easy *data)
  1345. {
  1346. struct cf_osslq_ctx *ctx = cf->ctx;
  1347. CURLcode result = CURLE_OK;
  1348. if(!ctx->tls.ssl)
  1349. goto out;
  1350. ERR_clear_error();
  1351. result = h3_send_streams(cf, data);
  1352. if(result)
  1353. goto out;
  1354. if(!SSL_handle_events(ctx->tls.ssl)) {
  1355. int detail = SSL_get_error(ctx->tls.ssl, 0);
  1356. result = cf_osslq_ssl_err(cf, data, detail, CURLE_SEND_ERROR);
  1357. }
  1358. result = cf_osslq_check_and_unblock(cf, data);
  1359. out:
  1360. CURL_TRC_CF(data, cf, "progress_egress -> %d", result);
  1361. return result;
  1362. }
  1363. static CURLcode check_and_set_expiry(struct Curl_cfilter *cf,
  1364. struct Curl_easy *data)
  1365. {
  1366. struct cf_osslq_ctx *ctx = cf->ctx;
  1367. CURLcode result = CURLE_OK;
  1368. struct timeval tv;
  1369. timediff_t timeoutms;
  1370. int is_infinite = TRUE;
  1371. if(ctx->tls.ssl &&
  1372. SSL_get_event_timeout(ctx->tls.ssl, &tv, &is_infinite) &&
  1373. !is_infinite) {
  1374. timeoutms = curlx_tvtoms(&tv);
  1375. /* QUIC want to be called again latest at the returned timeout */
  1376. if(timeoutms <= 0) {
  1377. result = cf_progress_ingress(cf, data);
  1378. if(result)
  1379. goto out;
  1380. result = cf_progress_egress(cf, data);
  1381. if(result)
  1382. goto out;
  1383. if(SSL_get_event_timeout(ctx->tls.ssl, &tv, &is_infinite)) {
  1384. timeoutms = curlx_tvtoms(&tv);
  1385. }
  1386. }
  1387. if(!is_infinite) {
  1388. Curl_expire(data, timeoutms, EXPIRE_QUIC);
  1389. CURL_TRC_CF(data, cf, "QUIC expiry in %ldms", (long)timeoutms);
  1390. }
  1391. }
  1392. out:
  1393. return result;
  1394. }
  1395. static CURLcode cf_osslq_connect(struct Curl_cfilter *cf,
  1396. struct Curl_easy *data,
  1397. bool blocking, bool *done)
  1398. {
  1399. struct cf_osslq_ctx *ctx = cf->ctx;
  1400. CURLcode result = CURLE_OK;
  1401. struct cf_call_data save;
  1402. struct curltime now;
  1403. int err;
  1404. if(cf->connected) {
  1405. *done = TRUE;
  1406. return CURLE_OK;
  1407. }
  1408. /* Connect the UDP filter first */
  1409. if(!cf->next->connected) {
  1410. result = Curl_conn_cf_connect(cf->next, data, blocking, done);
  1411. if(result || !*done)
  1412. return result;
  1413. }
  1414. *done = FALSE;
  1415. now = Curl_now();
  1416. CF_DATA_SAVE(save, cf, data);
  1417. if(ctx->reconnect_at.tv_sec && Curl_timediff(now, ctx->reconnect_at) < 0) {
  1418. /* Not time yet to attempt the next connect */
  1419. CURL_TRC_CF(data, cf, "waiting for reconnect time");
  1420. goto out;
  1421. }
  1422. if(!ctx->tls.ssl) {
  1423. ctx->started_at = now;
  1424. result = cf_osslq_ctx_start(cf, data);
  1425. if(result)
  1426. goto out;
  1427. }
  1428. if(!ctx->got_first_byte) {
  1429. int readable = SOCKET_READABLE(ctx->q.sockfd, 0);
  1430. if(readable > 0 && (readable & CURL_CSELECT_IN)) {
  1431. ctx->got_first_byte = TRUE;
  1432. ctx->first_byte_at = Curl_now();
  1433. }
  1434. }
  1435. ERR_clear_error();
  1436. err = SSL_do_handshake(ctx->tls.ssl);
  1437. if(err == 1) {
  1438. /* connected */
  1439. ctx->handshake_at = now;
  1440. ctx->q.last_io = now;
  1441. CURL_TRC_CF(data, cf, "handshake complete after %dms",
  1442. (int)Curl_timediff(now, ctx->started_at));
  1443. result = cf_osslq_verify_peer(cf, data);
  1444. if(!result) {
  1445. CURL_TRC_CF(data, cf, "peer verified");
  1446. cf->connected = TRUE;
  1447. cf->conn->alpn = CURL_HTTP_VERSION_3;
  1448. *done = TRUE;
  1449. connkeep(cf->conn, "HTTP/3 default");
  1450. }
  1451. }
  1452. else {
  1453. int detail = SSL_get_error(ctx->tls.ssl, err);
  1454. switch(detail) {
  1455. case SSL_ERROR_WANT_READ:
  1456. ctx->q.last_io = now;
  1457. CURL_TRC_CF(data, cf, "QUIC SSL_connect() -> WANT_RECV");
  1458. result = Curl_vquic_tls_before_recv(&ctx->tls, cf, data);
  1459. goto out;
  1460. case SSL_ERROR_WANT_WRITE:
  1461. ctx->q.last_io = now;
  1462. CURL_TRC_CF(data, cf, "QUIC SSL_connect() -> WANT_SEND");
  1463. result = CURLE_OK;
  1464. goto out;
  1465. #ifdef SSL_ERROR_WANT_ASYNC
  1466. case SSL_ERROR_WANT_ASYNC:
  1467. ctx->q.last_io = now;
  1468. CURL_TRC_CF(data, cf, "QUIC SSL_connect() -> WANT_ASYNC");
  1469. result = CURLE_OK;
  1470. goto out;
  1471. #endif
  1472. #ifdef SSL_ERROR_WANT_RETRY_VERIFY
  1473. case SSL_ERROR_WANT_RETRY_VERIFY:
  1474. result = CURLE_OK;
  1475. goto out;
  1476. #endif
  1477. default:
  1478. result = cf_osslq_ssl_err(cf, data, detail, CURLE_COULDNT_CONNECT);
  1479. goto out;
  1480. }
  1481. }
  1482. out:
  1483. if(result == CURLE_RECV_ERROR && ctx->tls.ssl && ctx->protocol_shutdown) {
  1484. /* When a QUIC server instance is shutting down, it may send us a
  1485. * CONNECTION_CLOSE right away. Our connection then enters the DRAINING
  1486. * state. The CONNECT may work in the near future again. Indicate
  1487. * that as a "weird" reply. */
  1488. result = CURLE_WEIRD_SERVER_REPLY;
  1489. }
  1490. #ifndef CURL_DISABLE_VERBOSE_STRINGS
  1491. if(result) {
  1492. struct ip_quadruple ip;
  1493. Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip);
  1494. infof(data, "QUIC connect to %s port %u failed: %s",
  1495. ip.remote_ip, ip.remote_port, curl_easy_strerror(result));
  1496. }
  1497. #endif
  1498. if(!result)
  1499. result = check_and_set_expiry(cf, data);
  1500. if(result || *done)
  1501. CURL_TRC_CF(data, cf, "connect -> %d, done=%d", result, *done);
  1502. CF_DATA_RESTORE(cf, save);
  1503. return result;
  1504. }
  1505. static ssize_t h3_stream_open(struct Curl_cfilter *cf,
  1506. struct Curl_easy *data,
  1507. const void *buf, size_t len,
  1508. CURLcode *err)
  1509. {
  1510. struct cf_osslq_ctx *ctx = cf->ctx;
  1511. struct h3_stream_ctx *stream = NULL;
  1512. struct dynhds h2_headers;
  1513. size_t nheader;
  1514. nghttp3_nv *nva = NULL;
  1515. int rc = 0;
  1516. unsigned int i;
  1517. ssize_t nwritten = -1;
  1518. nghttp3_data_reader reader;
  1519. nghttp3_data_reader *preader = NULL;
  1520. Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST);
  1521. *err = h3_data_setup(cf, data);
  1522. if(*err)
  1523. goto out;
  1524. stream = H3_STREAM_CTX(data);
  1525. DEBUGASSERT(stream);
  1526. if(!stream) {
  1527. *err = CURLE_FAILED_INIT;
  1528. goto out;
  1529. }
  1530. nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, err);
  1531. if(nwritten < 0)
  1532. goto out;
  1533. if(!stream->h1.done) {
  1534. /* need more data */
  1535. goto out;
  1536. }
  1537. DEBUGASSERT(stream->h1.req);
  1538. *err = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data);
  1539. if(*err) {
  1540. nwritten = -1;
  1541. goto out;
  1542. }
  1543. /* no longer needed */
  1544. Curl_h1_req_parse_free(&stream->h1);
  1545. nheader = Curl_dynhds_count(&h2_headers);
  1546. nva = malloc(sizeof(nghttp3_nv) * nheader);
  1547. if(!nva) {
  1548. *err = CURLE_OUT_OF_MEMORY;
  1549. nwritten = -1;
  1550. goto out;
  1551. }
  1552. for(i = 0; i < nheader; ++i) {
  1553. struct dynhds_entry *e = Curl_dynhds_getn(&h2_headers, i);
  1554. nva[i].name = (unsigned char *)e->name;
  1555. nva[i].namelen = e->namelen;
  1556. nva[i].value = (unsigned char *)e->value;
  1557. nva[i].valuelen = e->valuelen;
  1558. nva[i].flags = NGHTTP3_NV_FLAG_NONE;
  1559. }
  1560. DEBUGASSERT(stream->s.id == -1);
  1561. *err = cf_osslq_stream_open(&stream->s, ctx->tls.ssl, 0,
  1562. &ctx->stream_bufcp, data);
  1563. if(*err) {
  1564. failf(data, "can't get bidi streams");
  1565. *err = CURLE_SEND_ERROR;
  1566. goto out;
  1567. }
  1568. switch(data->state.httpreq) {
  1569. case HTTPREQ_POST:
  1570. case HTTPREQ_POST_FORM:
  1571. case HTTPREQ_POST_MIME:
  1572. case HTTPREQ_PUT:
  1573. /* known request body size or -1 */
  1574. if(data->state.infilesize != -1)
  1575. stream->upload_left = data->state.infilesize;
  1576. else
  1577. /* data sending without specifying the data amount up front */
  1578. stream->upload_left = -1; /* unknown */
  1579. break;
  1580. default:
  1581. /* there is not request body */
  1582. stream->upload_left = 0; /* no request body */
  1583. break;
  1584. }
  1585. stream->send_closed = (stream->upload_left == 0);
  1586. if(!stream->send_closed) {
  1587. reader.read_data = cb_h3_read_req_body;
  1588. preader = &reader;
  1589. }
  1590. rc = nghttp3_conn_submit_request(ctx->h3.conn, stream->s.id,
  1591. nva, nheader, preader, data);
  1592. if(rc) {
  1593. switch(rc) {
  1594. case NGHTTP3_ERR_CONN_CLOSING:
  1595. CURL_TRC_CF(data, cf, "h3sid[%"PRId64"] failed to send, "
  1596. "connection is closing", stream->s.id);
  1597. break;
  1598. default:
  1599. CURL_TRC_CF(data, cf, "h3sid[%"PRId64"] failed to send -> %d (%s)",
  1600. stream->s.id, rc, nghttp3_strerror(rc));
  1601. break;
  1602. }
  1603. *err = CURLE_SEND_ERROR;
  1604. nwritten = -1;
  1605. goto out;
  1606. }
  1607. if(Curl_trc_is_verbose(data)) {
  1608. infof(data, "[HTTP/3] [%" PRId64 "] OPENED stream for %s",
  1609. stream->s.id, data->state.url);
  1610. for(i = 0; i < nheader; ++i) {
  1611. infof(data, "[HTTP/3] [%" PRId64 "] [%.*s: %.*s]", stream->s.id,
  1612. (int)nva[i].namelen, nva[i].name,
  1613. (int)nva[i].valuelen, nva[i].value);
  1614. }
  1615. }
  1616. out:
  1617. free(nva);
  1618. Curl_dynhds_free(&h2_headers);
  1619. return nwritten;
  1620. }
  1621. static ssize_t cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  1622. const void *buf, size_t len, CURLcode *err)
  1623. {
  1624. struct cf_osslq_ctx *ctx = cf->ctx;
  1625. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  1626. struct cf_call_data save;
  1627. ssize_t nwritten;
  1628. CURLcode result;
  1629. CF_DATA_SAVE(save, cf, data);
  1630. DEBUGASSERT(cf->connected);
  1631. DEBUGASSERT(ctx->tls.ssl);
  1632. DEBUGASSERT(ctx->h3.conn);
  1633. *err = CURLE_OK;
  1634. result = cf_progress_ingress(cf, data);
  1635. if(result) {
  1636. *err = result;
  1637. nwritten = -1;
  1638. goto out;
  1639. }
  1640. result = cf_progress_egress(cf, data);
  1641. if(result) {
  1642. *err = result;
  1643. nwritten = -1;
  1644. goto out;
  1645. }
  1646. if(!stream || stream->s.id < 0) {
  1647. nwritten = h3_stream_open(cf, data, buf, len, err);
  1648. if(nwritten < 0) {
  1649. CURL_TRC_CF(data, cf, "failed to open stream -> %d", *err);
  1650. goto out;
  1651. }
  1652. stream = H3_STREAM_CTX(data);
  1653. }
  1654. else if(stream->upload_blocked_len) {
  1655. /* the data in `buf` has already been submitted or added to the
  1656. * buffers, but have been EAGAINed on the last invocation. */
  1657. DEBUGASSERT(len >= stream->upload_blocked_len);
  1658. if(len < stream->upload_blocked_len) {
  1659. /* Did we get called again with a smaller `len`? This should not
  1660. * happen. We are not prepared to handle that. */
  1661. failf(data, "HTTP/3 send again with decreased length");
  1662. *err = CURLE_HTTP3;
  1663. nwritten = -1;
  1664. goto out;
  1665. }
  1666. nwritten = (ssize_t)stream->upload_blocked_len;
  1667. stream->upload_blocked_len = 0;
  1668. }
  1669. else if(stream->closed) {
  1670. if(stream->resp_hds_complete) {
  1671. /* Server decided to close the stream after having sent us a final
  1672. * response. This is valid if it is not interested in the request
  1673. * body. This happens on 30x or 40x responses.
  1674. * We silently discard the data sent, since this is not a transport
  1675. * error situation. */
  1676. CURL_TRC_CF(data, cf, "[%" PRId64 "] discarding data"
  1677. "on closed stream with response", stream->s.id);
  1678. *err = CURLE_OK;
  1679. nwritten = (ssize_t)len;
  1680. goto out;
  1681. }
  1682. CURL_TRC_CF(data, cf, "[%" PRId64 "] send_body(len=%zu) "
  1683. "-> stream closed", stream->s.id, len);
  1684. *err = CURLE_HTTP3;
  1685. nwritten = -1;
  1686. goto out;
  1687. }
  1688. else {
  1689. nwritten = Curl_bufq_write(&stream->sendbuf, buf, len, err);
  1690. CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_send, add to "
  1691. "sendbuf(len=%zu) -> %zd, %d",
  1692. stream->s.id, len, nwritten, *err);
  1693. if(nwritten < 0) {
  1694. goto out;
  1695. }
  1696. (void)nghttp3_conn_resume_stream(ctx->h3.conn, stream->s.id);
  1697. }
  1698. result = cf_progress_egress(cf, data);
  1699. if(result) {
  1700. *err = result;
  1701. nwritten = -1;
  1702. }
  1703. if(stream && nwritten > 0 && stream->sendbuf_len_in_flight) {
  1704. /* We have unacknowledged DATA and cannot report success to our
  1705. * caller. Instead we EAGAIN and remember how much we have already
  1706. * "written" into our various internal connection buffers. */
  1707. stream->upload_blocked_len = nwritten;
  1708. CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_send(len=%zu), "
  1709. "%zu bytes in flight -> EGAIN", stream->s.id, len,
  1710. stream->sendbuf_len_in_flight);
  1711. *err = CURLE_AGAIN;
  1712. nwritten = -1;
  1713. }
  1714. out:
  1715. result = check_and_set_expiry(cf, data);
  1716. CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_send(len=%zu) -> %zd, %d",
  1717. stream? stream->s.id : -1, len, nwritten, *err);
  1718. CF_DATA_RESTORE(cf, save);
  1719. return nwritten;
  1720. }
  1721. static ssize_t recv_closed_stream(struct Curl_cfilter *cf,
  1722. struct Curl_easy *data,
  1723. struct h3_stream_ctx *stream,
  1724. CURLcode *err)
  1725. {
  1726. ssize_t nread = -1;
  1727. (void)cf;
  1728. if(stream->reset) {
  1729. failf(data,
  1730. "HTTP/3 stream %" PRId64 " reset by server", stream->s.id);
  1731. *err = stream->resp_hds_complete? CURLE_PARTIAL_FILE : CURLE_HTTP3;
  1732. goto out;
  1733. }
  1734. else if(!stream->resp_hds_complete) {
  1735. failf(data,
  1736. "HTTP/3 stream %" PRId64 " was closed cleanly, but before getting"
  1737. " all response header fields, treated as error",
  1738. stream->s.id);
  1739. *err = CURLE_HTTP3;
  1740. goto out;
  1741. }
  1742. *err = CURLE_OK;
  1743. nread = 0;
  1744. out:
  1745. return nread;
  1746. }
  1747. static ssize_t cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  1748. char *buf, size_t len, CURLcode *err)
  1749. {
  1750. struct cf_osslq_ctx *ctx = cf->ctx;
  1751. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  1752. ssize_t nread = -1;
  1753. struct cf_call_data save;
  1754. CURLcode result;
  1755. (void)ctx;
  1756. CF_DATA_SAVE(save, cf, data);
  1757. DEBUGASSERT(cf->connected);
  1758. DEBUGASSERT(ctx);
  1759. DEBUGASSERT(ctx->tls.ssl);
  1760. DEBUGASSERT(ctx->h3.conn);
  1761. *err = CURLE_OK;
  1762. if(!stream) {
  1763. *err = CURLE_RECV_ERROR;
  1764. goto out;
  1765. }
  1766. if(!Curl_bufq_is_empty(&stream->recvbuf)) {
  1767. nread = Curl_bufq_read(&stream->recvbuf,
  1768. (unsigned char *)buf, len, err);
  1769. if(nread < 0) {
  1770. CURL_TRC_CF(data, cf, "[%" PRId64 "] read recvbuf(len=%zu) "
  1771. "-> %zd, %d", stream->s.id, len, nread, *err);
  1772. goto out;
  1773. }
  1774. }
  1775. result = cf_progress_ingress(cf, data);
  1776. if(result) {
  1777. *err = result;
  1778. nread = -1;
  1779. goto out;
  1780. }
  1781. /* recvbuf had nothing before, maybe after progressing ingress? */
  1782. if(nread < 0 && !Curl_bufq_is_empty(&stream->recvbuf)) {
  1783. nread = Curl_bufq_read(&stream->recvbuf,
  1784. (unsigned char *)buf, len, err);
  1785. if(nread < 0) {
  1786. CURL_TRC_CF(data, cf, "[%" PRId64 "] read recvbuf(len=%zu) "
  1787. "-> %zd, %d", stream->s.id, len, nread, *err);
  1788. goto out;
  1789. }
  1790. }
  1791. if(nread > 0) {
  1792. h3_drain_stream(cf, data);
  1793. }
  1794. else {
  1795. if(stream->closed) {
  1796. nread = recv_closed_stream(cf, data, stream, err);
  1797. goto out;
  1798. }
  1799. *err = CURLE_AGAIN;
  1800. nread = -1;
  1801. }
  1802. out:
  1803. if(cf_progress_egress(cf, data)) {
  1804. *err = CURLE_SEND_ERROR;
  1805. nread = -1;
  1806. }
  1807. else {
  1808. CURLcode result2 = check_and_set_expiry(cf, data);
  1809. if(result2) {
  1810. *err = result2;
  1811. nread = -1;
  1812. }
  1813. }
  1814. CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_recv(len=%zu) -> %zd, %d",
  1815. stream? stream->s.id : -1, len, nread, *err);
  1816. CF_DATA_RESTORE(cf, save);
  1817. return nread;
  1818. }
  1819. /*
  1820. * Called from transfer.c:data_pending to know if we should keep looping
  1821. * to receive more data from the connection.
  1822. */
  1823. static bool cf_osslq_data_pending(struct Curl_cfilter *cf,
  1824. const struct Curl_easy *data)
  1825. {
  1826. const struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  1827. (void)cf;
  1828. return stream && !Curl_bufq_is_empty(&stream->recvbuf);
  1829. }
  1830. static CURLcode cf_osslq_data_event(struct Curl_cfilter *cf,
  1831. struct Curl_easy *data,
  1832. int event, int arg1, void *arg2)
  1833. {
  1834. struct cf_osslq_ctx *ctx = cf->ctx;
  1835. CURLcode result = CURLE_OK;
  1836. struct cf_call_data save;
  1837. CF_DATA_SAVE(save, cf, data);
  1838. (void)arg1;
  1839. (void)arg2;
  1840. switch(event) {
  1841. case CF_CTRL_DATA_SETUP:
  1842. break;
  1843. case CF_CTRL_DATA_PAUSE:
  1844. result = h3_data_pause(cf, data, (arg1 != 0));
  1845. break;
  1846. case CF_CTRL_DATA_DETACH:
  1847. h3_data_done(cf, data);
  1848. break;
  1849. case CF_CTRL_DATA_DONE:
  1850. h3_data_done(cf, data);
  1851. break;
  1852. case CF_CTRL_DATA_DONE_SEND: {
  1853. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  1854. if(stream && !stream->send_closed) {
  1855. stream->send_closed = TRUE;
  1856. stream->upload_left = Curl_bufq_len(&stream->sendbuf);
  1857. (void)nghttp3_conn_resume_stream(ctx->h3.conn, stream->s.id);
  1858. }
  1859. break;
  1860. }
  1861. case CF_CTRL_DATA_IDLE: {
  1862. struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
  1863. CURL_TRC_CF(data, cf, "data idle");
  1864. if(stream && !stream->closed) {
  1865. result = check_and_set_expiry(cf, data);
  1866. }
  1867. break;
  1868. }
  1869. default:
  1870. break;
  1871. }
  1872. CF_DATA_RESTORE(cf, save);
  1873. return result;
  1874. }
  1875. static bool cf_osslq_conn_is_alive(struct Curl_cfilter *cf,
  1876. struct Curl_easy *data,
  1877. bool *input_pending)
  1878. {
  1879. struct cf_osslq_ctx *ctx = cf->ctx;
  1880. bool alive = FALSE;
  1881. struct cf_call_data save;
  1882. CF_DATA_SAVE(save, cf, data);
  1883. *input_pending = FALSE;
  1884. if(!ctx->tls.ssl)
  1885. goto out;
  1886. #ifdef SSL_VALUE_QUIC_IDLE_TIMEOUT
  1887. /* Added in OpenSSL v3.3.x */
  1888. {
  1889. timediff_t idletime;
  1890. uint64_t idle_ms = ctx->max_idle_ms;
  1891. if(!SSL_get_value_uint(ctx->tls.ssl, SSL_VALUE_CLASS_FEATURE_NEGOTIATED,
  1892. SSL_VALUE_QUIC_IDLE_TIMEOUT, &idle_ms)) {
  1893. CURL_TRC_CF(data, cf, "error getting negotiated idle timeout, "
  1894. "assume connection is dead.");
  1895. goto out;
  1896. }
  1897. CURL_TRC_CF(data, cf, "negotiated idle timeout: %zums", (size_t)idle_ms);
  1898. idletime = Curl_timediff(Curl_now(), ctx->q.last_io);
  1899. if(idletime > 0 && (uint64_t)idletime > idle_ms)
  1900. goto out;
  1901. }
  1902. #endif
  1903. if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending))
  1904. goto out;
  1905. alive = TRUE;
  1906. if(*input_pending) {
  1907. CURLcode result;
  1908. /* This happens before we've sent off a request and the connection is
  1909. not in use by any other transfer, there shouldn't be any data here,
  1910. only "protocol frames" */
  1911. *input_pending = FALSE;
  1912. result = cf_progress_ingress(cf, data);
  1913. CURL_TRC_CF(data, cf, "is_alive, progress ingress -> %d", result);
  1914. alive = result? FALSE : TRUE;
  1915. }
  1916. out:
  1917. CF_DATA_RESTORE(cf, save);
  1918. return alive;
  1919. }
  1920. static void cf_osslq_adjust_pollset(struct Curl_cfilter *cf,
  1921. struct Curl_easy *data,
  1922. struct easy_pollset *ps)
  1923. {
  1924. struct cf_osslq_ctx *ctx = cf->ctx;
  1925. if(!ctx->tls.ssl) {
  1926. /* NOP */
  1927. }
  1928. else if(!cf->connected) {
  1929. /* during handshake, transfer has not started yet. we always
  1930. * add our socket for polling if SSL wants to send/recv */
  1931. Curl_pollset_set(data, ps, ctx->q.sockfd,
  1932. SSL_net_read_desired(ctx->tls.ssl),
  1933. SSL_net_write_desired(ctx->tls.ssl));
  1934. }
  1935. else {
  1936. /* once connected, we only modify the socket if it is present.
  1937. * this avoids adding it for paused transfers. */
  1938. bool want_recv, want_send;
  1939. Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send);
  1940. if(want_recv || want_send) {
  1941. Curl_pollset_set(data, ps, ctx->q.sockfd,
  1942. SSL_net_read_desired(ctx->tls.ssl),
  1943. SSL_net_write_desired(ctx->tls.ssl));
  1944. }
  1945. }
  1946. }
  1947. static CURLcode cf_osslq_query(struct Curl_cfilter *cf,
  1948. struct Curl_easy *data,
  1949. int query, int *pres1, void *pres2)
  1950. {
  1951. struct cf_osslq_ctx *ctx = cf->ctx;
  1952. switch(query) {
  1953. case CF_QUERY_MAX_CONCURRENT: {
  1954. #ifdef SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL
  1955. /* Added in OpenSSL v3.3.x */
  1956. uint64_t v;
  1957. if(!SSL_get_value_uint(ctx->tls.ssl, SSL_VALUE_CLASS_GENERIC,
  1958. SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL, &v)) {
  1959. CURL_TRC_CF(data, cf, "error getting available local bidi streams");
  1960. return CURLE_HTTP3;
  1961. }
  1962. /* we report avail + in_use */
  1963. v += CONN_INUSE(cf->conn);
  1964. *pres1 = (v > INT_MAX)? INT_MAX : (int)v;
  1965. #else
  1966. *pres1 = 100;
  1967. #endif
  1968. CURL_TRC_CF(data, cf, "query max_conncurrent -> %d", *pres1);
  1969. return CURLE_OK;
  1970. }
  1971. case CF_QUERY_CONNECT_REPLY_MS:
  1972. if(ctx->got_first_byte) {
  1973. timediff_t ms = Curl_timediff(ctx->first_byte_at, ctx->started_at);
  1974. *pres1 = (ms < INT_MAX)? (int)ms : INT_MAX;
  1975. }
  1976. else
  1977. *pres1 = -1;
  1978. return CURLE_OK;
  1979. case CF_QUERY_TIMER_CONNECT: {
  1980. struct curltime *when = pres2;
  1981. if(ctx->got_first_byte)
  1982. *when = ctx->first_byte_at;
  1983. return CURLE_OK;
  1984. }
  1985. case CF_QUERY_TIMER_APPCONNECT: {
  1986. struct curltime *when = pres2;
  1987. if(cf->connected)
  1988. *when = ctx->handshake_at;
  1989. return CURLE_OK;
  1990. }
  1991. default:
  1992. break;
  1993. }
  1994. return cf->next?
  1995. cf->next->cft->query(cf->next, data, query, pres1, pres2) :
  1996. CURLE_UNKNOWN_OPTION;
  1997. }
  1998. struct Curl_cftype Curl_cft_http3 = {
  1999. "HTTP/3",
  2000. CF_TYPE_IP_CONNECT | CF_TYPE_SSL | CF_TYPE_MULTIPLEX,
  2001. 0,
  2002. cf_osslq_destroy,
  2003. cf_osslq_connect,
  2004. cf_osslq_close,
  2005. Curl_cf_def_get_host,
  2006. cf_osslq_adjust_pollset,
  2007. cf_osslq_data_pending,
  2008. cf_osslq_send,
  2009. cf_osslq_recv,
  2010. cf_osslq_data_event,
  2011. cf_osslq_conn_is_alive,
  2012. Curl_cf_def_conn_keep_alive,
  2013. cf_osslq_query,
  2014. };
  2015. CURLcode Curl_cf_osslq_create(struct Curl_cfilter **pcf,
  2016. struct Curl_easy *data,
  2017. struct connectdata *conn,
  2018. const struct Curl_addrinfo *ai)
  2019. {
  2020. struct cf_osslq_ctx *ctx = NULL;
  2021. struct Curl_cfilter *cf = NULL, *udp_cf = NULL;
  2022. CURLcode result;
  2023. (void)data;
  2024. ctx = calloc(1, sizeof(*ctx));
  2025. if(!ctx) {
  2026. result = CURLE_OUT_OF_MEMORY;
  2027. goto out;
  2028. }
  2029. cf_osslq_ctx_clear(ctx);
  2030. result = Curl_cf_create(&cf, &Curl_cft_http3, ctx);
  2031. if(result)
  2032. goto out;
  2033. result = Curl_cf_udp_create(&udp_cf, data, conn, ai, TRNSPRT_QUIC);
  2034. if(result)
  2035. goto out;
  2036. cf->conn = conn;
  2037. udp_cf->conn = cf->conn;
  2038. udp_cf->sockindex = cf->sockindex;
  2039. cf->next = udp_cf;
  2040. out:
  2041. *pcf = (!result)? cf : NULL;
  2042. if(result) {
  2043. if(udp_cf)
  2044. Curl_conn_cf_discard_sub(cf, udp_cf, data, TRUE);
  2045. Curl_safefree(cf);
  2046. Curl_safefree(ctx);
  2047. }
  2048. return result;
  2049. }
  2050. bool Curl_conn_is_osslq(const struct Curl_easy *data,
  2051. const struct connectdata *conn,
  2052. int sockindex)
  2053. {
  2054. struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
  2055. (void)data;
  2056. for(; cf; cf = cf->next) {
  2057. if(cf->cft == &Curl_cft_http3)
  2058. return TRUE;
  2059. if(cf->cft->flags & CF_TYPE_IP_CONNECT)
  2060. return FALSE;
  2061. }
  2062. return FALSE;
  2063. }
  2064. /*
  2065. * Store ngtcp2 version info in this buffer.
  2066. */
  2067. void Curl_osslq_ver(char *p, size_t len)
  2068. {
  2069. const nghttp3_info *ht3 = nghttp3_version(0);
  2070. (void)msnprintf(p, len, "nghttp3/%s", ht3->version_str);
  2071. }
  2072. #endif /* USE_OPENSSL_QUIC && USE_NGHTTP3 */