2
0

curl_ngtcp2.c 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613
  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_NGTCP2) && defined(USE_NGHTTP3)
  26. #include <ngtcp2/ngtcp2.h>
  27. #include <nghttp3/nghttp3.h>
  28. #ifdef USE_OPENSSL
  29. #include <openssl/err.h>
  30. #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
  31. #include <ngtcp2/ngtcp2_crypto_boringssl.h>
  32. #else
  33. #include <ngtcp2/ngtcp2_crypto_quictls.h>
  34. #endif
  35. #include "vtls/openssl.h"
  36. #elif defined(USE_GNUTLS)
  37. #include <ngtcp2/ngtcp2_crypto_gnutls.h>
  38. #include "vtls/gtls.h"
  39. #elif defined(USE_WOLFSSL)
  40. #include <ngtcp2/ngtcp2_crypto_wolfssl.h>
  41. #include "vtls/wolfssl.h"
  42. #endif
  43. #include "urldata.h"
  44. #include "hash.h"
  45. #include "sendf.h"
  46. #include "strdup.h"
  47. #include "rand.h"
  48. #include "multiif.h"
  49. #include "strcase.h"
  50. #include "cfilters.h"
  51. #include "cf-socket.h"
  52. #include "connect.h"
  53. #include "progress.h"
  54. #include "strerror.h"
  55. #include "dynbuf.h"
  56. #include "http1.h"
  57. #include "select.h"
  58. #include "inet_pton.h"
  59. #include "transfer.h"
  60. #include "vquic.h"
  61. #include "vquic_int.h"
  62. #include "vquic-tls.h"
  63. #include "vtls/keylog.h"
  64. #include "vtls/vtls.h"
  65. #include "curl_ngtcp2.h"
  66. #include "warnless.h"
  67. /* The last 3 #include files should be in this order */
  68. #include "curl_printf.h"
  69. #include "curl_memory.h"
  70. #include "memdebug.h"
  71. #define QUIC_MAX_STREAMS (256*1024)
  72. #define QUIC_MAX_DATA (1*1024*1024)
  73. #define QUIC_HANDSHAKE_TIMEOUT (10*NGTCP2_SECONDS)
  74. /* A stream window is the maximum amount we need to buffer for
  75. * each active transfer. We use HTTP/3 flow control and only ACK
  76. * when we take things out of the buffer.
  77. * Chunk size is large enough to take a full DATA frame */
  78. #define H3_STREAM_WINDOW_SIZE (128 * 1024)
  79. #define H3_STREAM_CHUNK_SIZE (16 * 1024)
  80. /* The pool keeps spares around and half of a full stream windows
  81. * seems good. More does not seem to improve performance.
  82. * The benefit of the pool is that stream buffer to not keep
  83. * spares. Memory consumption goes down when streams run empty,
  84. * have a large upload done, etc. */
  85. #define H3_STREAM_POOL_SPARES \
  86. (H3_STREAM_WINDOW_SIZE / H3_STREAM_CHUNK_SIZE ) / 2
  87. /* Receive and Send max number of chunks just follows from the
  88. * chunk size and window size */
  89. #define H3_STREAM_RECV_CHUNKS \
  90. (H3_STREAM_WINDOW_SIZE / H3_STREAM_CHUNK_SIZE)
  91. #define H3_STREAM_SEND_CHUNKS \
  92. (H3_STREAM_WINDOW_SIZE / H3_STREAM_CHUNK_SIZE)
  93. /*
  94. * Store ngtcp2 version info in this buffer.
  95. */
  96. void Curl_ngtcp2_ver(char *p, size_t len)
  97. {
  98. const ngtcp2_info *ng2 = ngtcp2_version(0);
  99. const nghttp3_info *ht3 = nghttp3_version(0);
  100. (void)msnprintf(p, len, "ngtcp2/%s nghttp3/%s",
  101. ng2->version_str, ht3->version_str);
  102. }
  103. struct cf_ngtcp2_ctx {
  104. struct cf_quic_ctx q;
  105. struct ssl_peer peer;
  106. struct curl_tls_ctx tls;
  107. ngtcp2_path connected_path;
  108. ngtcp2_conn *qconn;
  109. ngtcp2_cid dcid;
  110. ngtcp2_cid scid;
  111. uint32_t version;
  112. ngtcp2_settings settings;
  113. ngtcp2_transport_params transport_params;
  114. ngtcp2_ccerr last_error;
  115. ngtcp2_crypto_conn_ref conn_ref;
  116. struct cf_call_data call_data;
  117. nghttp3_conn *h3conn;
  118. nghttp3_settings h3settings;
  119. struct curltime started_at; /* time the current attempt started */
  120. struct curltime handshake_at; /* time connect handshake finished */
  121. struct bufc_pool stream_bufcp; /* chunk pool for streams */
  122. struct dynbuf scratch; /* temp buffer for header construction */
  123. struct Curl_hash streams; /* hash `data->mid` to `h3_stream_ctx` */
  124. size_t max_stream_window; /* max flow window for one stream */
  125. uint64_t max_idle_ms; /* max idle time for QUIC connection */
  126. uint64_t used_bidi_streams; /* bidi streams we have opened */
  127. uint64_t max_bidi_streams; /* max bidi streams we can open */
  128. int qlogfd;
  129. BIT(initialized);
  130. BIT(shutdown_started); /* queued shutdown packets */
  131. };
  132. /* How to access `call_data` from a cf_ngtcp2 filter */
  133. #undef CF_CTX_CALL_DATA
  134. #define CF_CTX_CALL_DATA(cf) \
  135. ((struct cf_ngtcp2_ctx *)(cf)->ctx)->call_data
  136. static void h3_stream_hash_free(void *stream);
  137. static void cf_ngtcp2_ctx_init(struct cf_ngtcp2_ctx *ctx)
  138. {
  139. DEBUGASSERT(!ctx->initialized);
  140. ctx->qlogfd = -1;
  141. ctx->version = NGTCP2_PROTO_VER_MAX;
  142. ctx->max_stream_window = H3_STREAM_WINDOW_SIZE;
  143. ctx->max_idle_ms = CURL_QUIC_MAX_IDLE_MS;
  144. Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE,
  145. H3_STREAM_POOL_SPARES);
  146. Curl_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER);
  147. Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free);
  148. ctx->initialized = TRUE;
  149. }
  150. static void cf_ngtcp2_ctx_free(struct cf_ngtcp2_ctx *ctx)
  151. {
  152. if(ctx && ctx->initialized) {
  153. Curl_bufcp_free(&ctx->stream_bufcp);
  154. Curl_dyn_free(&ctx->scratch);
  155. Curl_hash_clean(&ctx->streams);
  156. Curl_hash_destroy(&ctx->streams);
  157. Curl_ssl_peer_cleanup(&ctx->peer);
  158. }
  159. free(ctx);
  160. }
  161. struct pkt_io_ctx;
  162. static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
  163. struct Curl_easy *data,
  164. struct pkt_io_ctx *pktx);
  165. static CURLcode cf_progress_egress(struct Curl_cfilter *cf,
  166. struct Curl_easy *data,
  167. struct pkt_io_ctx *pktx);
  168. /**
  169. * All about the H3 internals of a stream
  170. */
  171. struct h3_stream_ctx {
  172. curl_int64_t id; /* HTTP/3 protocol identifier */
  173. struct bufq sendbuf; /* h3 request body */
  174. struct h1_req_parser h1; /* h1 request parsing */
  175. size_t sendbuf_len_in_flight; /* sendbuf amount "in flight" */
  176. curl_uint64_t error3; /* HTTP/3 stream error code */
  177. curl_off_t upload_left; /* number of request bytes left to upload */
  178. int status_code; /* HTTP status code */
  179. CURLcode xfer_result; /* result from xfer_resp_write(_hd) */
  180. bool resp_hds_complete; /* we have a complete, final response */
  181. bool closed; /* TRUE on stream close */
  182. bool reset; /* TRUE on stream reset */
  183. bool send_closed; /* stream is local closed */
  184. BIT(quic_flow_blocked); /* stream is blocked by QUIC flow control */
  185. };
  186. #define H3_STREAM_CTX(ctx,data) ((struct h3_stream_ctx *)(\
  187. data? Curl_hash_offt_get(&(ctx)->streams, (data)->mid) : NULL))
  188. #define H3_STREAM_CTX_ID(ctx,id) ((struct h3_stream_ctx *)(\
  189. Curl_hash_offt_get(&(ctx)->streams, (id))))
  190. static void h3_stream_ctx_free(struct h3_stream_ctx *stream)
  191. {
  192. Curl_bufq_free(&stream->sendbuf);
  193. Curl_h1_req_parse_free(&stream->h1);
  194. free(stream);
  195. }
  196. static void h3_stream_hash_free(void *stream)
  197. {
  198. DEBUGASSERT(stream);
  199. h3_stream_ctx_free((struct h3_stream_ctx *)stream);
  200. }
  201. static CURLcode h3_data_setup(struct Curl_cfilter *cf,
  202. struct Curl_easy *data)
  203. {
  204. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  205. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  206. if(!data)
  207. return CURLE_FAILED_INIT;
  208. if(stream)
  209. return CURLE_OK;
  210. stream = calloc(1, sizeof(*stream));
  211. if(!stream)
  212. return CURLE_OUT_OF_MEMORY;
  213. stream->id = -1;
  214. /* on send, we control how much we put into the buffer */
  215. Curl_bufq_initp(&stream->sendbuf, &ctx->stream_bufcp,
  216. H3_STREAM_SEND_CHUNKS, BUFQ_OPT_NONE);
  217. stream->sendbuf_len_in_flight = 0;
  218. Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN);
  219. if(!Curl_hash_offt_set(&ctx->streams, data->mid, stream)) {
  220. h3_stream_ctx_free(stream);
  221. return CURLE_OUT_OF_MEMORY;
  222. }
  223. return CURLE_OK;
  224. }
  225. static void cf_ngtcp2_stream_close(struct Curl_cfilter *cf,
  226. struct Curl_easy *data,
  227. struct h3_stream_ctx *stream)
  228. {
  229. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  230. DEBUGASSERT(data);
  231. DEBUGASSERT(stream);
  232. if(!stream->closed && ctx->qconn && ctx->h3conn) {
  233. CURLcode result;
  234. nghttp3_conn_set_stream_user_data(ctx->h3conn, stream->id, NULL);
  235. ngtcp2_conn_set_stream_user_data(ctx->qconn, stream->id, NULL);
  236. stream->closed = TRUE;
  237. (void)ngtcp2_conn_shutdown_stream(ctx->qconn, 0, stream->id,
  238. NGHTTP3_H3_REQUEST_CANCELLED);
  239. result = cf_progress_egress(cf, data, NULL);
  240. if(result)
  241. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cancel stream -> %d",
  242. stream->id, result);
  243. }
  244. }
  245. static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
  246. {
  247. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  248. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  249. (void)cf;
  250. if(stream) {
  251. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] easy handle is done",
  252. stream->id);
  253. cf_ngtcp2_stream_close(cf, data, stream);
  254. Curl_hash_offt_remove(&ctx->streams, data->mid);
  255. }
  256. }
  257. static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf,
  258. struct Curl_easy *data,
  259. int64_t stream_id,
  260. struct h3_stream_ctx **pstream)
  261. {
  262. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  263. struct h3_stream_ctx *stream;
  264. (void)cf;
  265. stream = H3_STREAM_CTX(ctx, data);
  266. if(stream && stream->id == stream_id) {
  267. *pstream = stream;
  268. return data;
  269. }
  270. else {
  271. struct Curl_llist_node *e;
  272. DEBUGASSERT(data->multi);
  273. for(e = Curl_llist_head(&data->multi->process); e; e = Curl_node_next(e)) {
  274. struct Curl_easy *sdata = Curl_node_elem(e);
  275. if(sdata->conn != data->conn)
  276. continue;
  277. stream = H3_STREAM_CTX(ctx, sdata);
  278. if(stream && stream->id == stream_id) {
  279. *pstream = stream;
  280. return sdata;
  281. }
  282. }
  283. }
  284. *pstream = NULL;
  285. return NULL;
  286. }
  287. static void h3_drain_stream(struct Curl_cfilter *cf,
  288. struct Curl_easy *data)
  289. {
  290. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  291. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  292. unsigned char bits;
  293. (void)cf;
  294. bits = CURL_CSELECT_IN;
  295. if(stream && stream->upload_left && !stream->send_closed)
  296. bits |= CURL_CSELECT_OUT;
  297. if(data->state.select_bits != bits) {
  298. data->state.select_bits = bits;
  299. Curl_expire(data, 0, EXPIRE_RUN_NOW);
  300. }
  301. }
  302. /* ngtcp2 default congestion controller does not perform pacing. Limit
  303. the maximum packet burst to MAX_PKT_BURST packets. */
  304. #define MAX_PKT_BURST 10
  305. struct pkt_io_ctx {
  306. struct Curl_cfilter *cf;
  307. struct Curl_easy *data;
  308. ngtcp2_tstamp ts;
  309. ngtcp2_path_storage ps;
  310. };
  311. static void pktx_update_time(struct pkt_io_ctx *pktx,
  312. struct Curl_cfilter *cf)
  313. {
  314. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  315. vquic_ctx_update_time(&ctx->q);
  316. pktx->ts = (ngtcp2_tstamp)ctx->q.last_op.tv_sec * NGTCP2_SECONDS +
  317. (ngtcp2_tstamp)ctx->q.last_op.tv_usec * NGTCP2_MICROSECONDS;
  318. }
  319. static void pktx_init(struct pkt_io_ctx *pktx,
  320. struct Curl_cfilter *cf,
  321. struct Curl_easy *data)
  322. {
  323. pktx->cf = cf;
  324. pktx->data = data;
  325. ngtcp2_path_storage_zero(&pktx->ps);
  326. pktx_update_time(pktx, cf);
  327. }
  328. static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
  329. uint64_t datalen, void *user_data,
  330. void *stream_user_data);
  331. static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref)
  332. {
  333. struct Curl_cfilter *cf = conn_ref->user_data;
  334. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  335. return ctx->qconn;
  336. }
  337. #ifdef DEBUG_NGTCP2
  338. static void quic_printf(void *user_data, const char *fmt, ...)
  339. {
  340. struct Curl_cfilter *cf = user_data;
  341. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  342. (void)ctx; /* TODO: need an easy handle to infof() message */
  343. va_list ap;
  344. va_start(ap, fmt);
  345. vfprintf(stderr, fmt, ap);
  346. va_end(ap);
  347. fprintf(stderr, "\n");
  348. }
  349. #endif
  350. static void qlog_callback(void *user_data, uint32_t flags,
  351. const void *data, size_t datalen)
  352. {
  353. struct Curl_cfilter *cf = user_data;
  354. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  355. (void)flags;
  356. if(ctx->qlogfd != -1) {
  357. ssize_t rc = write(ctx->qlogfd, data, datalen);
  358. if(rc == -1) {
  359. /* on write error, stop further write attempts */
  360. close(ctx->qlogfd);
  361. ctx->qlogfd = -1;
  362. }
  363. }
  364. }
  365. static void quic_settings(struct cf_ngtcp2_ctx *ctx,
  366. struct Curl_easy *data,
  367. struct pkt_io_ctx *pktx)
  368. {
  369. ngtcp2_settings *s = &ctx->settings;
  370. ngtcp2_transport_params *t = &ctx->transport_params;
  371. ngtcp2_settings_default(s);
  372. ngtcp2_transport_params_default(t);
  373. #ifdef DEBUG_NGTCP2
  374. s->log_printf = quic_printf;
  375. #else
  376. s->log_printf = NULL;
  377. #endif
  378. (void)data;
  379. s->initial_ts = pktx->ts;
  380. s->handshake_timeout = QUIC_HANDSHAKE_TIMEOUT;
  381. s->max_window = 100 * ctx->max_stream_window;
  382. s->max_stream_window = 10 * ctx->max_stream_window;
  383. t->initial_max_data = 10 * ctx->max_stream_window;
  384. t->initial_max_stream_data_bidi_local = ctx->max_stream_window;
  385. t->initial_max_stream_data_bidi_remote = ctx->max_stream_window;
  386. t->initial_max_stream_data_uni = ctx->max_stream_window;
  387. t->initial_max_streams_bidi = QUIC_MAX_STREAMS;
  388. t->initial_max_streams_uni = QUIC_MAX_STREAMS;
  389. t->max_idle_timeout = (ctx->max_idle_ms * NGTCP2_MILLISECONDS);
  390. if(ctx->qlogfd != -1) {
  391. s->qlog_write = qlog_callback;
  392. }
  393. }
  394. static CURLcode init_ngh3_conn(struct Curl_cfilter *cf);
  395. static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data)
  396. {
  397. (void)user_data;
  398. (void)tconn;
  399. return 0;
  400. }
  401. static void cf_ngtcp2_conn_close(struct Curl_cfilter *cf,
  402. struct Curl_easy *data);
  403. static bool cf_ngtcp2_err_is_fatal(int code)
  404. {
  405. return (NGTCP2_ERR_FATAL >= code) ||
  406. (NGTCP2_ERR_DROP_CONN == code) ||
  407. (NGTCP2_ERR_IDLE_CLOSE == code);
  408. }
  409. static void cf_ngtcp2_err_set(struct Curl_cfilter *cf,
  410. struct Curl_easy *data, int code)
  411. {
  412. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  413. if(!ctx->last_error.error_code) {
  414. if(NGTCP2_ERR_CRYPTO == code) {
  415. ngtcp2_ccerr_set_tls_alert(&ctx->last_error,
  416. ngtcp2_conn_get_tls_alert(ctx->qconn),
  417. NULL, 0);
  418. }
  419. else {
  420. ngtcp2_ccerr_set_liberr(&ctx->last_error, code, NULL, 0);
  421. }
  422. }
  423. if(cf_ngtcp2_err_is_fatal(code))
  424. cf_ngtcp2_conn_close(cf, data);
  425. }
  426. static bool cf_ngtcp2_h3_err_is_fatal(int code)
  427. {
  428. return (NGHTTP3_ERR_FATAL >= code) ||
  429. (NGHTTP3_ERR_H3_CLOSED_CRITICAL_STREAM == code);
  430. }
  431. static void cf_ngtcp2_h3_err_set(struct Curl_cfilter *cf,
  432. struct Curl_easy *data, int code)
  433. {
  434. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  435. if(!ctx->last_error.error_code) {
  436. ngtcp2_ccerr_set_application_error(&ctx->last_error,
  437. nghttp3_err_infer_quic_app_error_code(code), NULL, 0);
  438. }
  439. if(cf_ngtcp2_h3_err_is_fatal(code))
  440. cf_ngtcp2_conn_close(cf, data);
  441. }
  442. static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
  443. int64_t sid, uint64_t offset,
  444. const uint8_t *buf, size_t buflen,
  445. void *user_data, void *stream_user_data)
  446. {
  447. struct Curl_cfilter *cf = user_data;
  448. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  449. curl_int64_t stream_id = (curl_int64_t)sid;
  450. nghttp3_ssize nconsumed;
  451. int fin = (flags & NGTCP2_STREAM_DATA_FLAG_FIN) ? 1 : 0;
  452. struct Curl_easy *data = stream_user_data;
  453. (void)offset;
  454. (void)data;
  455. nconsumed =
  456. nghttp3_conn_read_stream(ctx->h3conn, stream_id, buf, buflen, fin);
  457. if(!data)
  458. data = CF_DATA_CURRENT(cf);
  459. if(data)
  460. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read_stream(len=%zu) -> %zd",
  461. stream_id, buflen, nconsumed);
  462. if(nconsumed < 0) {
  463. struct h3_stream_ctx *stream = H3_STREAM_CTX_ID(ctx, stream_id);
  464. if(data && stream) {
  465. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] error on known stream, "
  466. "reset=%d, closed=%d",
  467. stream_id, stream->reset, stream->closed);
  468. }
  469. return NGTCP2_ERR_CALLBACK_FAILURE;
  470. }
  471. /* number of bytes inside buflen which consists of framing overhead
  472. * including QPACK HEADERS. In other words, it does not consume payload of
  473. * DATA frame. */
  474. ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, (uint64_t)nconsumed);
  475. ngtcp2_conn_extend_max_offset(tconn, (uint64_t)nconsumed);
  476. return 0;
  477. }
  478. static int
  479. cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id,
  480. uint64_t offset, uint64_t datalen, void *user_data,
  481. void *stream_user_data)
  482. {
  483. struct Curl_cfilter *cf = user_data;
  484. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  485. int rv;
  486. (void)stream_id;
  487. (void)tconn;
  488. (void)offset;
  489. (void)datalen;
  490. (void)stream_user_data;
  491. rv = nghttp3_conn_add_ack_offset(ctx->h3conn, stream_id, datalen);
  492. if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  493. return NGTCP2_ERR_CALLBACK_FAILURE;
  494. }
  495. return 0;
  496. }
  497. static int cb_stream_close(ngtcp2_conn *tconn, uint32_t flags,
  498. int64_t sid, uint64_t app_error_code,
  499. void *user_data, void *stream_user_data)
  500. {
  501. struct Curl_cfilter *cf = user_data;
  502. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  503. struct Curl_easy *data = stream_user_data;
  504. curl_int64_t stream_id = (curl_int64_t)sid;
  505. int rv;
  506. (void)tconn;
  507. /* stream is closed... */
  508. if(!data)
  509. data = CF_DATA_CURRENT(cf);
  510. if(!data)
  511. return NGTCP2_ERR_CALLBACK_FAILURE;
  512. if(!(flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET)) {
  513. app_error_code = NGHTTP3_H3_NO_ERROR;
  514. }
  515. rv = nghttp3_conn_close_stream(ctx->h3conn, stream_id, app_error_code);
  516. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] quic close(app_error=%"
  517. FMT_PRIu64 ") -> %d", stream_id, (curl_uint64_t)app_error_code,
  518. rv);
  519. if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  520. cf_ngtcp2_h3_err_set(cf, data, rv);
  521. return NGTCP2_ERR_CALLBACK_FAILURE;
  522. }
  523. return 0;
  524. }
  525. static int cb_stream_reset(ngtcp2_conn *tconn, int64_t sid,
  526. uint64_t final_size, uint64_t app_error_code,
  527. void *user_data, void *stream_user_data)
  528. {
  529. struct Curl_cfilter *cf = user_data;
  530. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  531. curl_int64_t stream_id = (curl_int64_t)sid;
  532. struct Curl_easy *data = stream_user_data;
  533. int rv;
  534. (void)tconn;
  535. (void)final_size;
  536. (void)app_error_code;
  537. (void)data;
  538. rv = nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream_id);
  539. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] reset -> %d", stream_id, rv);
  540. if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  541. return NGTCP2_ERR_CALLBACK_FAILURE;
  542. }
  543. return 0;
  544. }
  545. static int cb_stream_stop_sending(ngtcp2_conn *tconn, int64_t stream_id,
  546. uint64_t app_error_code, void *user_data,
  547. void *stream_user_data)
  548. {
  549. struct Curl_cfilter *cf = user_data;
  550. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  551. int rv;
  552. (void)tconn;
  553. (void)app_error_code;
  554. (void)stream_user_data;
  555. rv = nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream_id);
  556. if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  557. return NGTCP2_ERR_CALLBACK_FAILURE;
  558. }
  559. return 0;
  560. }
  561. static int cb_extend_max_local_streams_bidi(ngtcp2_conn *tconn,
  562. uint64_t max_streams,
  563. void *user_data)
  564. {
  565. struct Curl_cfilter *cf = user_data;
  566. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  567. struct Curl_easy *data = CF_DATA_CURRENT(cf);
  568. (void)tconn;
  569. ctx->max_bidi_streams = max_streams;
  570. if(data)
  571. CURL_TRC_CF(data, cf, "max bidi streams now %" FMT_PRIu64
  572. ", used %" FMT_PRIu64, (curl_uint64_t)ctx->max_bidi_streams,
  573. (curl_uint64_t)ctx->used_bidi_streams);
  574. return 0;
  575. }
  576. static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t sid,
  577. uint64_t max_data, void *user_data,
  578. void *stream_user_data)
  579. {
  580. struct Curl_cfilter *cf = user_data;
  581. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  582. curl_int64_t stream_id = (curl_int64_t)sid;
  583. struct Curl_easy *data = CF_DATA_CURRENT(cf);
  584. struct Curl_easy *s_data;
  585. struct h3_stream_ctx *stream;
  586. int rv;
  587. (void)tconn;
  588. (void)max_data;
  589. (void)stream_user_data;
  590. rv = nghttp3_conn_unblock_stream(ctx->h3conn, stream_id);
  591. if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  592. return NGTCP2_ERR_CALLBACK_FAILURE;
  593. }
  594. s_data = get_stream_easy(cf, data, stream_id, &stream);
  595. if(s_data && stream && stream->quic_flow_blocked) {
  596. CURL_TRC_CF(s_data, cf, "[%" FMT_PRId64 "] unblock quic flow", stream_id);
  597. stream->quic_flow_blocked = FALSE;
  598. h3_drain_stream(cf, s_data);
  599. }
  600. return 0;
  601. }
  602. static void cb_rand(uint8_t *dest, size_t destlen,
  603. const ngtcp2_rand_ctx *rand_ctx)
  604. {
  605. CURLcode result;
  606. (void)rand_ctx;
  607. result = Curl_rand(NULL, dest, destlen);
  608. if(result) {
  609. /* cb_rand is only used for non-cryptographic context. If Curl_rand
  610. failed, just fill 0 and call it *random*. */
  611. memset(dest, 0, destlen);
  612. }
  613. }
  614. static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
  615. uint8_t *token, size_t cidlen,
  616. void *user_data)
  617. {
  618. CURLcode result;
  619. (void)tconn;
  620. (void)user_data;
  621. result = Curl_rand(NULL, cid->data, cidlen);
  622. if(result)
  623. return NGTCP2_ERR_CALLBACK_FAILURE;
  624. cid->datalen = cidlen;
  625. result = Curl_rand(NULL, token, NGTCP2_STATELESS_RESET_TOKENLEN);
  626. if(result)
  627. return NGTCP2_ERR_CALLBACK_FAILURE;
  628. return 0;
  629. }
  630. static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_encryption_level level,
  631. void *user_data)
  632. {
  633. struct Curl_cfilter *cf = user_data;
  634. (void)tconn;
  635. if(level != NGTCP2_ENCRYPTION_LEVEL_1RTT) {
  636. return 0;
  637. }
  638. if(init_ngh3_conn(cf) != CURLE_OK) {
  639. return NGTCP2_ERR_CALLBACK_FAILURE;
  640. }
  641. return 0;
  642. }
  643. #if defined(_MSC_VER) && defined(_DLL)
  644. # pragma warning(push)
  645. # pragma warning(disable:4232) /* MSVC extension, dllimport identity */
  646. #endif
  647. static ngtcp2_callbacks ng_callbacks = {
  648. ngtcp2_crypto_client_initial_cb,
  649. NULL, /* recv_client_initial */
  650. ngtcp2_crypto_recv_crypto_data_cb,
  651. cb_handshake_completed,
  652. NULL, /* recv_version_negotiation */
  653. ngtcp2_crypto_encrypt_cb,
  654. ngtcp2_crypto_decrypt_cb,
  655. ngtcp2_crypto_hp_mask_cb,
  656. cb_recv_stream_data,
  657. cb_acked_stream_data_offset,
  658. NULL, /* stream_open */
  659. cb_stream_close,
  660. NULL, /* recv_stateless_reset */
  661. ngtcp2_crypto_recv_retry_cb,
  662. cb_extend_max_local_streams_bidi,
  663. NULL, /* extend_max_local_streams_uni */
  664. cb_rand,
  665. cb_get_new_connection_id,
  666. NULL, /* remove_connection_id */
  667. ngtcp2_crypto_update_key_cb, /* update_key */
  668. NULL, /* path_validation */
  669. NULL, /* select_preferred_addr */
  670. cb_stream_reset,
  671. NULL, /* extend_max_remote_streams_bidi */
  672. NULL, /* extend_max_remote_streams_uni */
  673. cb_extend_max_stream_data,
  674. NULL, /* dcid_status */
  675. NULL, /* handshake_confirmed */
  676. NULL, /* recv_new_token */
  677. ngtcp2_crypto_delete_crypto_aead_ctx_cb,
  678. ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
  679. NULL, /* recv_datagram */
  680. NULL, /* ack_datagram */
  681. NULL, /* lost_datagram */
  682. ngtcp2_crypto_get_path_challenge_data_cb,
  683. cb_stream_stop_sending,
  684. NULL, /* version_negotiation */
  685. cb_recv_rx_key,
  686. NULL, /* recv_tx_key */
  687. NULL, /* early_data_rejected */
  688. };
  689. #if defined(_MSC_VER) && defined(_DLL)
  690. # pragma warning(pop)
  691. #endif
  692. /**
  693. * Connection maintenance like timeouts on packet ACKs etc. are done by us, not
  694. * the OS like for TCP. POLL events on the socket therefore are not
  695. * sufficient.
  696. * ngtcp2 tells us when it wants to be invoked again. We handle that via
  697. * the `Curl_expire()` mechanisms.
  698. */
  699. static CURLcode check_and_set_expiry(struct Curl_cfilter *cf,
  700. struct Curl_easy *data,
  701. struct pkt_io_ctx *pktx)
  702. {
  703. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  704. struct pkt_io_ctx local_pktx;
  705. ngtcp2_tstamp expiry;
  706. if(!pktx) {
  707. pktx_init(&local_pktx, cf, data);
  708. pktx = &local_pktx;
  709. }
  710. else {
  711. pktx_update_time(pktx, cf);
  712. }
  713. expiry = ngtcp2_conn_get_expiry(ctx->qconn);
  714. if(expiry != UINT64_MAX) {
  715. if(expiry <= pktx->ts) {
  716. CURLcode result;
  717. int rv = ngtcp2_conn_handle_expiry(ctx->qconn, pktx->ts);
  718. if(rv) {
  719. failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
  720. ngtcp2_strerror(rv));
  721. cf_ngtcp2_err_set(cf, data, rv);
  722. return CURLE_SEND_ERROR;
  723. }
  724. result = cf_progress_ingress(cf, data, pktx);
  725. if(result)
  726. return result;
  727. result = cf_progress_egress(cf, data, pktx);
  728. if(result)
  729. return result;
  730. /* ask again, things might have changed */
  731. expiry = ngtcp2_conn_get_expiry(ctx->qconn);
  732. }
  733. if(expiry > pktx->ts) {
  734. ngtcp2_duration timeout = expiry - pktx->ts;
  735. if(timeout % NGTCP2_MILLISECONDS) {
  736. timeout += NGTCP2_MILLISECONDS;
  737. }
  738. Curl_expire(data, (timediff_t)(timeout / NGTCP2_MILLISECONDS),
  739. EXPIRE_QUIC);
  740. }
  741. }
  742. return CURLE_OK;
  743. }
  744. static void cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf,
  745. struct Curl_easy *data,
  746. struct easy_pollset *ps)
  747. {
  748. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  749. bool want_recv, want_send;
  750. if(!ctx->qconn)
  751. return;
  752. Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send);
  753. if(!want_send && !Curl_bufq_is_empty(&ctx->q.sendbuf))
  754. want_send = TRUE;
  755. if(want_recv || want_send) {
  756. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  757. struct cf_call_data save;
  758. bool c_exhaust, s_exhaust;
  759. CF_DATA_SAVE(save, cf, data);
  760. c_exhaust = want_send && (!ngtcp2_conn_get_cwnd_left(ctx->qconn) ||
  761. !ngtcp2_conn_get_max_data_left(ctx->qconn));
  762. s_exhaust = want_send && stream && stream->id >= 0 &&
  763. stream->quic_flow_blocked;
  764. want_recv = (want_recv || c_exhaust || s_exhaust);
  765. want_send = (!s_exhaust && want_send) ||
  766. !Curl_bufq_is_empty(&ctx->q.sendbuf);
  767. Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send);
  768. CF_DATA_RESTORE(cf, save);
  769. }
  770. }
  771. static int cb_h3_stream_close(nghttp3_conn *conn, int64_t sid,
  772. uint64_t app_error_code, void *user_data,
  773. void *stream_user_data)
  774. {
  775. struct Curl_cfilter *cf = user_data;
  776. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  777. struct Curl_easy *data = stream_user_data;
  778. curl_int64_t stream_id = (curl_int64_t)sid;
  779. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  780. (void)conn;
  781. (void)stream_id;
  782. /* we might be called by nghttp3 after we already cleaned up */
  783. if(!stream)
  784. return 0;
  785. stream->closed = TRUE;
  786. stream->error3 = (curl_uint64_t)app_error_code;
  787. if(stream->error3 != NGHTTP3_H3_NO_ERROR) {
  788. stream->reset = TRUE;
  789. stream->send_closed = TRUE;
  790. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] RESET: error %" FMT_PRIu64,
  791. stream->id, stream->error3);
  792. }
  793. else {
  794. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] CLOSED", stream->id);
  795. }
  796. h3_drain_stream(cf, data);
  797. return 0;
  798. }
  799. static void h3_xfer_write_resp_hd(struct Curl_cfilter *cf,
  800. struct Curl_easy *data,
  801. struct h3_stream_ctx *stream,
  802. const char *buf, size_t blen, bool eos)
  803. {
  804. /* If we already encountered an error, skip further writes */
  805. if(!stream->xfer_result) {
  806. stream->xfer_result = Curl_xfer_write_resp_hd(data, buf, blen, eos);
  807. if(stream->xfer_result)
  808. CURL_TRC_CF(data, cf, "[%"FMT_PRId64"] error %d writing %zu "
  809. "bytes of headers", stream->id, stream->xfer_result, blen);
  810. }
  811. }
  812. static void h3_xfer_write_resp(struct Curl_cfilter *cf,
  813. struct Curl_easy *data,
  814. struct h3_stream_ctx *stream,
  815. const char *buf, size_t blen, bool eos)
  816. {
  817. /* If we already encountered an error, skip further writes */
  818. if(!stream->xfer_result) {
  819. stream->xfer_result = Curl_xfer_write_resp(data, buf, blen, eos);
  820. /* If the transfer write is errored, we do not want any more data */
  821. if(stream->xfer_result) {
  822. CURL_TRC_CF(data, cf, "[%"FMT_PRId64"] error %d writing %zu bytes "
  823. "of data", stream->id, stream->xfer_result, blen);
  824. }
  825. }
  826. }
  827. static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
  828. const uint8_t *buf, size_t blen,
  829. void *user_data, void *stream_user_data)
  830. {
  831. struct Curl_cfilter *cf = user_data;
  832. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  833. struct Curl_easy *data = stream_user_data;
  834. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  835. (void)conn;
  836. (void)stream3_id;
  837. if(!stream)
  838. return NGHTTP3_ERR_CALLBACK_FAILURE;
  839. h3_xfer_write_resp(cf, data, stream, (char *)buf, blen, FALSE);
  840. if(blen) {
  841. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] ACK %zu bytes of DATA",
  842. stream->id, blen);
  843. ngtcp2_conn_extend_max_stream_offset(ctx->qconn, stream->id, blen);
  844. ngtcp2_conn_extend_max_offset(ctx->qconn, blen);
  845. }
  846. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] DATA len=%zu", stream->id, blen);
  847. return 0;
  848. }
  849. static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream3_id,
  850. size_t consumed, void *user_data,
  851. void *stream_user_data)
  852. {
  853. struct Curl_cfilter *cf = user_data;
  854. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  855. (void)conn;
  856. (void)stream_user_data;
  857. /* nghttp3 has consumed bytes on the QUIC stream and we need to
  858. * tell the QUIC connection to increase its flow control */
  859. ngtcp2_conn_extend_max_stream_offset(ctx->qconn, stream3_id, consumed);
  860. ngtcp2_conn_extend_max_offset(ctx->qconn, consumed);
  861. return 0;
  862. }
  863. static int cb_h3_end_headers(nghttp3_conn *conn, int64_t sid,
  864. int fin, void *user_data, void *stream_user_data)
  865. {
  866. struct Curl_cfilter *cf = user_data;
  867. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  868. struct Curl_easy *data = stream_user_data;
  869. curl_int64_t stream_id = (curl_int64_t)sid;
  870. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  871. (void)conn;
  872. (void)stream_id;
  873. (void)fin;
  874. (void)cf;
  875. if(!stream)
  876. return 0;
  877. /* add a CRLF only if we have received some headers */
  878. h3_xfer_write_resp_hd(cf, data, stream, STRCONST("\r\n"), stream->closed);
  879. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] end_headers, status=%d",
  880. stream_id, stream->status_code);
  881. if(stream->status_code / 100 != 1) {
  882. stream->resp_hds_complete = TRUE;
  883. }
  884. h3_drain_stream(cf, data);
  885. return 0;
  886. }
  887. static int cb_h3_recv_header(nghttp3_conn *conn, int64_t sid,
  888. int32_t token, nghttp3_rcbuf *name,
  889. nghttp3_rcbuf *value, uint8_t flags,
  890. void *user_data, void *stream_user_data)
  891. {
  892. struct Curl_cfilter *cf = user_data;
  893. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  894. curl_int64_t stream_id = (curl_int64_t)sid;
  895. nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
  896. nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
  897. struct Curl_easy *data = stream_user_data;
  898. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  899. CURLcode result = CURLE_OK;
  900. (void)conn;
  901. (void)stream_id;
  902. (void)token;
  903. (void)flags;
  904. (void)cf;
  905. /* we might have cleaned up this transfer already */
  906. if(!stream)
  907. return 0;
  908. if(token == NGHTTP3_QPACK_TOKEN__STATUS) {
  909. result = Curl_http_decode_status(&stream->status_code,
  910. (const char *)h3val.base, h3val.len);
  911. if(result)
  912. return -1;
  913. Curl_dyn_reset(&ctx->scratch);
  914. result = Curl_dyn_addn(&ctx->scratch, STRCONST("HTTP/3 "));
  915. if(!result)
  916. result = Curl_dyn_addn(&ctx->scratch,
  917. (const char *)h3val.base, h3val.len);
  918. if(!result)
  919. result = Curl_dyn_addn(&ctx->scratch, STRCONST(" \r\n"));
  920. if(!result)
  921. h3_xfer_write_resp_hd(cf, data, stream, Curl_dyn_ptr(&ctx->scratch),
  922. Curl_dyn_len(&ctx->scratch), FALSE);
  923. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] status: %s",
  924. stream_id, Curl_dyn_ptr(&ctx->scratch));
  925. if(result) {
  926. return -1;
  927. }
  928. }
  929. else {
  930. /* store as an HTTP1-style header */
  931. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] header: %.*s: %.*s",
  932. stream_id, (int)h3name.len, h3name.base,
  933. (int)h3val.len, h3val.base);
  934. Curl_dyn_reset(&ctx->scratch);
  935. result = Curl_dyn_addn(&ctx->scratch,
  936. (const char *)h3name.base, h3name.len);
  937. if(!result)
  938. result = Curl_dyn_addn(&ctx->scratch, STRCONST(": "));
  939. if(!result)
  940. result = Curl_dyn_addn(&ctx->scratch,
  941. (const char *)h3val.base, h3val.len);
  942. if(!result)
  943. result = Curl_dyn_addn(&ctx->scratch, STRCONST("\r\n"));
  944. if(!result)
  945. h3_xfer_write_resp_hd(cf, data, stream, Curl_dyn_ptr(&ctx->scratch),
  946. Curl_dyn_len(&ctx->scratch), FALSE);
  947. }
  948. return 0;
  949. }
  950. static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id,
  951. uint64_t app_error_code, void *user_data,
  952. void *stream_user_data)
  953. {
  954. struct Curl_cfilter *cf = user_data;
  955. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  956. int rv;
  957. (void)conn;
  958. (void)stream_user_data;
  959. rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, 0, stream_id,
  960. app_error_code);
  961. if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
  962. return NGHTTP3_ERR_CALLBACK_FAILURE;
  963. }
  964. return 0;
  965. }
  966. static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t sid,
  967. uint64_t app_error_code, void *user_data,
  968. void *stream_user_data) {
  969. struct Curl_cfilter *cf = user_data;
  970. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  971. curl_int64_t stream_id = (curl_int64_t)sid;
  972. struct Curl_easy *data = stream_user_data;
  973. int rv;
  974. (void)conn;
  975. (void)data;
  976. rv = ngtcp2_conn_shutdown_stream_write(ctx->qconn, 0, stream_id,
  977. app_error_code);
  978. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] reset -> %d", stream_id, rv);
  979. if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
  980. return NGHTTP3_ERR_CALLBACK_FAILURE;
  981. }
  982. return 0;
  983. }
  984. static nghttp3_callbacks ngh3_callbacks = {
  985. cb_h3_acked_req_body, /* acked_stream_data */
  986. cb_h3_stream_close,
  987. cb_h3_recv_data,
  988. cb_h3_deferred_consume,
  989. NULL, /* begin_headers */
  990. cb_h3_recv_header,
  991. cb_h3_end_headers,
  992. NULL, /* begin_trailers */
  993. cb_h3_recv_header,
  994. NULL, /* end_trailers */
  995. cb_h3_stop_sending,
  996. NULL, /* end_stream */
  997. cb_h3_reset_stream,
  998. NULL, /* shutdown */
  999. NULL /* recv_settings */
  1000. };
  1001. static CURLcode init_ngh3_conn(struct Curl_cfilter *cf)
  1002. {
  1003. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1004. CURLcode result;
  1005. int rc;
  1006. int64_t ctrl_stream_id, qpack_enc_stream_id, qpack_dec_stream_id;
  1007. if(ngtcp2_conn_get_streams_uni_left(ctx->qconn) < 3) {
  1008. return CURLE_QUIC_CONNECT_ERROR;
  1009. }
  1010. nghttp3_settings_default(&ctx->h3settings);
  1011. rc = nghttp3_conn_client_new(&ctx->h3conn,
  1012. &ngh3_callbacks,
  1013. &ctx->h3settings,
  1014. nghttp3_mem_default(),
  1015. cf);
  1016. if(rc) {
  1017. result = CURLE_OUT_OF_MEMORY;
  1018. goto fail;
  1019. }
  1020. rc = ngtcp2_conn_open_uni_stream(ctx->qconn, &ctrl_stream_id, NULL);
  1021. if(rc) {
  1022. result = CURLE_QUIC_CONNECT_ERROR;
  1023. goto fail;
  1024. }
  1025. rc = nghttp3_conn_bind_control_stream(ctx->h3conn, ctrl_stream_id);
  1026. if(rc) {
  1027. result = CURLE_QUIC_CONNECT_ERROR;
  1028. goto fail;
  1029. }
  1030. rc = ngtcp2_conn_open_uni_stream(ctx->qconn, &qpack_enc_stream_id, NULL);
  1031. if(rc) {
  1032. result = CURLE_QUIC_CONNECT_ERROR;
  1033. goto fail;
  1034. }
  1035. rc = ngtcp2_conn_open_uni_stream(ctx->qconn, &qpack_dec_stream_id, NULL);
  1036. if(rc) {
  1037. result = CURLE_QUIC_CONNECT_ERROR;
  1038. goto fail;
  1039. }
  1040. rc = nghttp3_conn_bind_qpack_streams(ctx->h3conn, qpack_enc_stream_id,
  1041. qpack_dec_stream_id);
  1042. if(rc) {
  1043. result = CURLE_QUIC_CONNECT_ERROR;
  1044. goto fail;
  1045. }
  1046. return CURLE_OK;
  1047. fail:
  1048. return result;
  1049. }
  1050. static ssize_t recv_closed_stream(struct Curl_cfilter *cf,
  1051. struct Curl_easy *data,
  1052. struct h3_stream_ctx *stream,
  1053. CURLcode *err)
  1054. {
  1055. ssize_t nread = -1;
  1056. (void)cf;
  1057. if(stream->reset) {
  1058. failf(data, "HTTP/3 stream %" FMT_PRId64 " reset by server", stream->id);
  1059. *err = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
  1060. goto out;
  1061. }
  1062. else if(!stream->resp_hds_complete) {
  1063. failf(data,
  1064. "HTTP/3 stream %" FMT_PRId64 " was closed cleanly, but before "
  1065. "getting all response header fields, treated as error",
  1066. stream->id);
  1067. *err = CURLE_HTTP3;
  1068. goto out;
  1069. }
  1070. *err = CURLE_OK;
  1071. nread = 0;
  1072. out:
  1073. return nread;
  1074. }
  1075. /* incoming data frames on the h3 stream */
  1076. static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  1077. char *buf, size_t blen, CURLcode *err)
  1078. {
  1079. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1080. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  1081. ssize_t nread = -1;
  1082. struct cf_call_data save;
  1083. struct pkt_io_ctx pktx;
  1084. (void)ctx;
  1085. (void)buf;
  1086. CF_DATA_SAVE(save, cf, data);
  1087. DEBUGASSERT(cf->connected);
  1088. DEBUGASSERT(ctx);
  1089. DEBUGASSERT(ctx->qconn);
  1090. DEBUGASSERT(ctx->h3conn);
  1091. *err = CURLE_OK;
  1092. pktx_init(&pktx, cf, data);
  1093. if(!stream || ctx->shutdown_started) {
  1094. *err = CURLE_RECV_ERROR;
  1095. goto out;
  1096. }
  1097. if(cf_progress_ingress(cf, data, &pktx)) {
  1098. *err = CURLE_RECV_ERROR;
  1099. nread = -1;
  1100. goto out;
  1101. }
  1102. if(stream->xfer_result) {
  1103. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] xfer write failed", stream->id);
  1104. cf_ngtcp2_stream_close(cf, data, stream);
  1105. *err = stream->xfer_result;
  1106. nread = -1;
  1107. goto out;
  1108. }
  1109. else if(stream->closed) {
  1110. nread = recv_closed_stream(cf, data, stream, err);
  1111. goto out;
  1112. }
  1113. *err = CURLE_AGAIN;
  1114. nread = -1;
  1115. out:
  1116. if(cf_progress_egress(cf, data, &pktx)) {
  1117. *err = CURLE_SEND_ERROR;
  1118. nread = -1;
  1119. }
  1120. else {
  1121. CURLcode result2 = check_and_set_expiry(cf, data, &pktx);
  1122. if(result2) {
  1123. *err = result2;
  1124. nread = -1;
  1125. }
  1126. }
  1127. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(blen=%zu) -> %zd, %d",
  1128. stream ? stream->id : -1, blen, nread, *err);
  1129. CF_DATA_RESTORE(cf, save);
  1130. return nread;
  1131. }
  1132. static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
  1133. uint64_t datalen, void *user_data,
  1134. void *stream_user_data)
  1135. {
  1136. struct Curl_cfilter *cf = user_data;
  1137. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1138. struct Curl_easy *data = stream_user_data;
  1139. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  1140. size_t skiplen;
  1141. (void)cf;
  1142. if(!stream)
  1143. return 0;
  1144. /* The server acknowledged `datalen` of bytes from our request body.
  1145. * This is a delta. We have kept this data in `sendbuf` for
  1146. * re-transmissions and can free it now. */
  1147. if(datalen >= (uint64_t)stream->sendbuf_len_in_flight)
  1148. skiplen = stream->sendbuf_len_in_flight;
  1149. else
  1150. skiplen = (size_t)datalen;
  1151. Curl_bufq_skip(&stream->sendbuf, skiplen);
  1152. stream->sendbuf_len_in_flight -= skiplen;
  1153. /* Resume upload processing if we have more data to send */
  1154. if(stream->sendbuf_len_in_flight < Curl_bufq_len(&stream->sendbuf)) {
  1155. int rv = nghttp3_conn_resume_stream(conn, stream_id);
  1156. if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
  1157. return NGHTTP3_ERR_CALLBACK_FAILURE;
  1158. }
  1159. }
  1160. return 0;
  1161. }
  1162. static nghttp3_ssize
  1163. cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id,
  1164. nghttp3_vec *vec, size_t veccnt,
  1165. uint32_t *pflags, void *user_data,
  1166. void *stream_user_data)
  1167. {
  1168. struct Curl_cfilter *cf = user_data;
  1169. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1170. struct Curl_easy *data = stream_user_data;
  1171. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  1172. ssize_t nwritten = 0;
  1173. size_t nvecs = 0;
  1174. (void)cf;
  1175. (void)conn;
  1176. (void)stream_id;
  1177. (void)user_data;
  1178. (void)veccnt;
  1179. if(!stream)
  1180. return NGHTTP3_ERR_CALLBACK_FAILURE;
  1181. /* nghttp3 keeps references to the sendbuf data until it is ACKed
  1182. * by the server (see `cb_h3_acked_req_body()` for updates).
  1183. * `sendbuf_len_in_flight` is the amount of bytes in `sendbuf`
  1184. * that we have already passed to nghttp3, but which have not been
  1185. * ACKed yet.
  1186. * Any amount beyond `sendbuf_len_in_flight` we need still to pass
  1187. * to nghttp3. Do that now, if we can. */
  1188. if(stream->sendbuf_len_in_flight < Curl_bufq_len(&stream->sendbuf)) {
  1189. nvecs = 0;
  1190. while(nvecs < veccnt &&
  1191. Curl_bufq_peek_at(&stream->sendbuf,
  1192. stream->sendbuf_len_in_flight,
  1193. (const unsigned char **)&vec[nvecs].base,
  1194. &vec[nvecs].len)) {
  1195. stream->sendbuf_len_in_flight += vec[nvecs].len;
  1196. nwritten += vec[nvecs].len;
  1197. ++nvecs;
  1198. }
  1199. DEBUGASSERT(nvecs > 0); /* we SHOULD have been be able to peek */
  1200. }
  1201. if(nwritten > 0 && stream->upload_left != -1)
  1202. stream->upload_left -= nwritten;
  1203. /* When we stopped sending and everything in `sendbuf` is "in flight",
  1204. * we are at the end of the request body. */
  1205. if(stream->upload_left == 0) {
  1206. *pflags = NGHTTP3_DATA_FLAG_EOF;
  1207. stream->send_closed = TRUE;
  1208. }
  1209. else if(!nwritten) {
  1210. /* Not EOF, and nothing to give, we signal WOULDBLOCK. */
  1211. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read req body -> AGAIN",
  1212. stream->id);
  1213. return NGHTTP3_ERR_WOULDBLOCK;
  1214. }
  1215. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read req body -> "
  1216. "%d vecs%s with %zu (buffered=%zu, left=%" FMT_OFF_T ")",
  1217. stream->id, (int)nvecs,
  1218. *pflags == NGHTTP3_DATA_FLAG_EOF ? " EOF" : "",
  1219. nwritten, Curl_bufq_len(&stream->sendbuf),
  1220. stream->upload_left);
  1221. return (nghttp3_ssize)nvecs;
  1222. }
  1223. /* Index where :authority header field will appear in request header
  1224. field list. */
  1225. #define AUTHORITY_DST_IDX 3
  1226. static ssize_t h3_stream_open(struct Curl_cfilter *cf,
  1227. struct Curl_easy *data,
  1228. const void *buf, size_t len,
  1229. CURLcode *err)
  1230. {
  1231. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1232. struct h3_stream_ctx *stream = NULL;
  1233. int64_t sid;
  1234. struct dynhds h2_headers;
  1235. size_t nheader;
  1236. nghttp3_nv *nva = NULL;
  1237. int rc = 0;
  1238. unsigned int i;
  1239. ssize_t nwritten = -1;
  1240. nghttp3_data_reader reader;
  1241. nghttp3_data_reader *preader = NULL;
  1242. Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST);
  1243. *err = h3_data_setup(cf, data);
  1244. if(*err)
  1245. goto out;
  1246. stream = H3_STREAM_CTX(ctx, data);
  1247. DEBUGASSERT(stream);
  1248. if(!stream) {
  1249. *err = CURLE_FAILED_INIT;
  1250. goto out;
  1251. }
  1252. nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, err);
  1253. if(nwritten < 0)
  1254. goto out;
  1255. if(!stream->h1.done) {
  1256. /* need more data */
  1257. goto out;
  1258. }
  1259. DEBUGASSERT(stream->h1.req);
  1260. *err = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data);
  1261. if(*err) {
  1262. nwritten = -1;
  1263. goto out;
  1264. }
  1265. /* no longer needed */
  1266. Curl_h1_req_parse_free(&stream->h1);
  1267. nheader = Curl_dynhds_count(&h2_headers);
  1268. nva = malloc(sizeof(nghttp3_nv) * nheader);
  1269. if(!nva) {
  1270. *err = CURLE_OUT_OF_MEMORY;
  1271. nwritten = -1;
  1272. goto out;
  1273. }
  1274. for(i = 0; i < nheader; ++i) {
  1275. struct dynhds_entry *e = Curl_dynhds_getn(&h2_headers, i);
  1276. nva[i].name = (unsigned char *)e->name;
  1277. nva[i].namelen = e->namelen;
  1278. nva[i].value = (unsigned char *)e->value;
  1279. nva[i].valuelen = e->valuelen;
  1280. nva[i].flags = NGHTTP3_NV_FLAG_NONE;
  1281. }
  1282. rc = ngtcp2_conn_open_bidi_stream(ctx->qconn, &sid, data);
  1283. if(rc) {
  1284. failf(data, "can get bidi streams");
  1285. *err = CURLE_SEND_ERROR;
  1286. nwritten = -1;
  1287. goto out;
  1288. }
  1289. stream->id = (curl_int64_t)sid;
  1290. ++ctx->used_bidi_streams;
  1291. switch(data->state.httpreq) {
  1292. case HTTPREQ_POST:
  1293. case HTTPREQ_POST_FORM:
  1294. case HTTPREQ_POST_MIME:
  1295. case HTTPREQ_PUT:
  1296. /* known request body size or -1 */
  1297. if(data->state.infilesize != -1)
  1298. stream->upload_left = data->state.infilesize;
  1299. else
  1300. /* data sending without specifying the data amount up front */
  1301. stream->upload_left = -1; /* unknown */
  1302. break;
  1303. default:
  1304. /* there is not request body */
  1305. stream->upload_left = 0; /* no request body */
  1306. break;
  1307. }
  1308. stream->send_closed = (stream->upload_left == 0);
  1309. if(!stream->send_closed) {
  1310. reader.read_data = cb_h3_read_req_body;
  1311. preader = &reader;
  1312. }
  1313. rc = nghttp3_conn_submit_request(ctx->h3conn, stream->id,
  1314. nva, nheader, preader, data);
  1315. if(rc) {
  1316. switch(rc) {
  1317. case NGHTTP3_ERR_CONN_CLOSING:
  1318. CURL_TRC_CF(data, cf, "h3sid[%" FMT_PRId64 "] failed to send, "
  1319. "connection is closing", stream->id);
  1320. break;
  1321. default:
  1322. CURL_TRC_CF(data, cf, "h3sid[%" FMT_PRId64 "] failed to send -> "
  1323. "%d (%s)", stream->id, rc, nghttp3_strerror(rc));
  1324. break;
  1325. }
  1326. *err = CURLE_SEND_ERROR;
  1327. nwritten = -1;
  1328. goto out;
  1329. }
  1330. if(Curl_trc_is_verbose(data)) {
  1331. infof(data, "[HTTP/3] [%" FMT_PRId64 "] OPENED stream for %s",
  1332. stream->id, data->state.url);
  1333. for(i = 0; i < nheader; ++i) {
  1334. infof(data, "[HTTP/3] [%" FMT_PRId64 "] [%.*s: %.*s]", stream->id,
  1335. (int)nva[i].namelen, nva[i].name,
  1336. (int)nva[i].valuelen, nva[i].value);
  1337. }
  1338. }
  1339. out:
  1340. free(nva);
  1341. Curl_dynhds_free(&h2_headers);
  1342. return nwritten;
  1343. }
  1344. static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  1345. const void *buf, size_t len, bool eos,
  1346. CURLcode *err)
  1347. {
  1348. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1349. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  1350. ssize_t sent = 0;
  1351. struct cf_call_data save;
  1352. struct pkt_io_ctx pktx;
  1353. CURLcode result;
  1354. CF_DATA_SAVE(save, cf, data);
  1355. DEBUGASSERT(cf->connected);
  1356. DEBUGASSERT(ctx->qconn);
  1357. DEBUGASSERT(ctx->h3conn);
  1358. pktx_init(&pktx, cf, data);
  1359. *err = CURLE_OK;
  1360. (void)eos; /* TODO: use for stream EOF and block handling */
  1361. result = cf_progress_ingress(cf, data, &pktx);
  1362. if(result) {
  1363. *err = result;
  1364. sent = -1;
  1365. }
  1366. if(!stream || stream->id < 0) {
  1367. if(ctx->shutdown_started) {
  1368. CURL_TRC_CF(data, cf, "cannot open stream on closed connection");
  1369. *err = CURLE_SEND_ERROR;
  1370. sent = -1;
  1371. goto out;
  1372. }
  1373. sent = h3_stream_open(cf, data, buf, len, err);
  1374. if(sent < 0) {
  1375. CURL_TRC_CF(data, cf, "failed to open stream -> %d", *err);
  1376. goto out;
  1377. }
  1378. stream = H3_STREAM_CTX(ctx, data);
  1379. }
  1380. else if(stream->xfer_result) {
  1381. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] xfer write failed", stream->id);
  1382. cf_ngtcp2_stream_close(cf, data, stream);
  1383. *err = stream->xfer_result;
  1384. sent = -1;
  1385. goto out;
  1386. }
  1387. else if(stream->closed) {
  1388. if(stream->resp_hds_complete) {
  1389. /* Server decided to close the stream after having sent us a final
  1390. * response. This is valid if it is not interested in the request
  1391. * body. This happens on 30x or 40x responses.
  1392. * We silently discard the data sent, since this is not a transport
  1393. * error situation. */
  1394. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] discarding data"
  1395. "on closed stream with response", stream->id);
  1396. *err = CURLE_OK;
  1397. sent = (ssize_t)len;
  1398. goto out;
  1399. }
  1400. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] send_body(len=%zu) "
  1401. "-> stream closed", stream->id, len);
  1402. *err = CURLE_HTTP3;
  1403. sent = -1;
  1404. goto out;
  1405. }
  1406. else if(ctx->shutdown_started) {
  1407. CURL_TRC_CF(data, cf, "cannot send on closed connection");
  1408. *err = CURLE_SEND_ERROR;
  1409. sent = -1;
  1410. goto out;
  1411. }
  1412. else {
  1413. sent = Curl_bufq_write(&stream->sendbuf, buf, len, err);
  1414. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send, add to "
  1415. "sendbuf(len=%zu) -> %zd, %d",
  1416. stream->id, len, sent, *err);
  1417. if(sent < 0) {
  1418. goto out;
  1419. }
  1420. (void)nghttp3_conn_resume_stream(ctx->h3conn, stream->id);
  1421. }
  1422. result = cf_progress_egress(cf, data, &pktx);
  1423. if(result) {
  1424. *err = result;
  1425. sent = -1;
  1426. }
  1427. out:
  1428. result = check_and_set_expiry(cf, data, &pktx);
  1429. if(result) {
  1430. *err = result;
  1431. sent = -1;
  1432. }
  1433. CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %zd, %d",
  1434. stream ? stream->id : -1, len, sent, *err);
  1435. CF_DATA_RESTORE(cf, save);
  1436. return sent;
  1437. }
  1438. static CURLcode qng_verify_peer(struct Curl_cfilter *cf,
  1439. struct Curl_easy *data)
  1440. {
  1441. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1442. cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
  1443. cf->conn->httpversion = 30;
  1444. return Curl_vquic_tls_verify_peer(&ctx->tls, cf, data, &ctx->peer);
  1445. }
  1446. static CURLcode recv_pkt(const unsigned char *pkt, size_t pktlen,
  1447. struct sockaddr_storage *remote_addr,
  1448. socklen_t remote_addrlen, int ecn,
  1449. void *userp)
  1450. {
  1451. struct pkt_io_ctx *pktx = userp;
  1452. struct cf_ngtcp2_ctx *ctx = pktx->cf->ctx;
  1453. ngtcp2_pkt_info pi;
  1454. ngtcp2_path path;
  1455. int rv;
  1456. ngtcp2_addr_init(&path.local, (struct sockaddr *)&ctx->q.local_addr,
  1457. (socklen_t)ctx->q.local_addrlen);
  1458. ngtcp2_addr_init(&path.remote, (struct sockaddr *)remote_addr,
  1459. remote_addrlen);
  1460. pi.ecn = (uint8_t)ecn;
  1461. rv = ngtcp2_conn_read_pkt(ctx->qconn, &path, &pi, pkt, pktlen, pktx->ts);
  1462. if(rv) {
  1463. CURL_TRC_CF(pktx->data, pktx->cf, "ingress, read_pkt -> %s (%d)",
  1464. ngtcp2_strerror(rv), rv);
  1465. cf_ngtcp2_err_set(pktx->cf, pktx->data, rv);
  1466. if(rv == NGTCP2_ERR_CRYPTO)
  1467. /* this is a "TLS problem", but a failed certificate verification
  1468. is a common reason for this */
  1469. return CURLE_PEER_FAILED_VERIFICATION;
  1470. return CURLE_RECV_ERROR;
  1471. }
  1472. return CURLE_OK;
  1473. }
  1474. static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
  1475. struct Curl_easy *data,
  1476. struct pkt_io_ctx *pktx)
  1477. {
  1478. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1479. struct pkt_io_ctx local_pktx;
  1480. CURLcode result = CURLE_OK;
  1481. if(!pktx) {
  1482. pktx_init(&local_pktx, cf, data);
  1483. pktx = &local_pktx;
  1484. }
  1485. result = Curl_vquic_tls_before_recv(&ctx->tls, cf, data);
  1486. if(result)
  1487. return result;
  1488. return vquic_recv_packets(cf, data, &ctx->q, 1000, recv_pkt, pktx);
  1489. }
  1490. /**
  1491. * Read a network packet to send from ngtcp2 into `buf`.
  1492. * Return number of bytes written or -1 with *err set.
  1493. */
  1494. static ssize_t read_pkt_to_send(void *userp,
  1495. unsigned char *buf, size_t buflen,
  1496. CURLcode *err)
  1497. {
  1498. struct pkt_io_ctx *x = userp;
  1499. struct cf_ngtcp2_ctx *ctx = x->cf->ctx;
  1500. nghttp3_vec vec[16];
  1501. nghttp3_ssize veccnt;
  1502. ngtcp2_ssize ndatalen;
  1503. uint32_t flags;
  1504. int64_t stream_id;
  1505. int fin;
  1506. ssize_t nwritten, n;
  1507. veccnt = 0;
  1508. stream_id = -1;
  1509. fin = 0;
  1510. /* ngtcp2 may want to put several frames from different streams into
  1511. * this packet. `NGTCP2_WRITE_STREAM_FLAG_MORE` tells it to do so.
  1512. * When `NGTCP2_ERR_WRITE_MORE` is returned, we *need* to make
  1513. * another iteration.
  1514. * When ngtcp2 is happy (because it has no other frame that would fit
  1515. * or it has nothing more to send), it returns the total length
  1516. * of the assembled packet. This may be 0 if there was nothing to send. */
  1517. nwritten = 0;
  1518. *err = CURLE_OK;
  1519. for(;;) {
  1520. if(ctx->h3conn && ngtcp2_conn_get_max_data_left(ctx->qconn)) {
  1521. veccnt = nghttp3_conn_writev_stream(ctx->h3conn, &stream_id, &fin, vec,
  1522. sizeof(vec) / sizeof(vec[0]));
  1523. if(veccnt < 0) {
  1524. failf(x->data, "nghttp3_conn_writev_stream returned error: %s",
  1525. nghttp3_strerror((int)veccnt));
  1526. cf_ngtcp2_h3_err_set(x->cf, x->data, (int)veccnt);
  1527. *err = CURLE_SEND_ERROR;
  1528. return -1;
  1529. }
  1530. }
  1531. flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
  1532. (fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
  1533. n = ngtcp2_conn_writev_stream(ctx->qconn, &x->ps.path,
  1534. NULL, buf, buflen,
  1535. &ndatalen, flags, stream_id,
  1536. (const ngtcp2_vec *)vec, veccnt, x->ts);
  1537. if(n == 0) {
  1538. /* nothing to send */
  1539. *err = CURLE_AGAIN;
  1540. nwritten = -1;
  1541. goto out;
  1542. }
  1543. else if(n < 0) {
  1544. switch(n) {
  1545. case NGTCP2_ERR_STREAM_DATA_BLOCKED: {
  1546. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, x->data);
  1547. DEBUGASSERT(ndatalen == -1);
  1548. nghttp3_conn_block_stream(ctx->h3conn, stream_id);
  1549. CURL_TRC_CF(x->data, x->cf, "[%" FMT_PRId64 "] block quic flow",
  1550. (curl_int64_t)stream_id);
  1551. DEBUGASSERT(stream);
  1552. if(stream)
  1553. stream->quic_flow_blocked = TRUE;
  1554. n = 0;
  1555. break;
  1556. }
  1557. case NGTCP2_ERR_STREAM_SHUT_WR:
  1558. DEBUGASSERT(ndatalen == -1);
  1559. nghttp3_conn_shutdown_stream_write(ctx->h3conn, stream_id);
  1560. n = 0;
  1561. break;
  1562. case NGTCP2_ERR_WRITE_MORE:
  1563. /* ngtcp2 wants to send more. update the flow of the stream whose data
  1564. * is in the buffer and continue */
  1565. DEBUGASSERT(ndatalen >= 0);
  1566. n = 0;
  1567. break;
  1568. default:
  1569. DEBUGASSERT(ndatalen == -1);
  1570. failf(x->data, "ngtcp2_conn_writev_stream returned error: %s",
  1571. ngtcp2_strerror((int)n));
  1572. cf_ngtcp2_err_set(x->cf, x->data, (int)n);
  1573. *err = CURLE_SEND_ERROR;
  1574. nwritten = -1;
  1575. goto out;
  1576. }
  1577. }
  1578. if(ndatalen >= 0) {
  1579. /* we add the amount of data bytes to the flow windows */
  1580. int rv = nghttp3_conn_add_write_offset(ctx->h3conn, stream_id, ndatalen);
  1581. if(rv) {
  1582. failf(x->data, "nghttp3_conn_add_write_offset returned error: %s\n",
  1583. nghttp3_strerror(rv));
  1584. return CURLE_SEND_ERROR;
  1585. }
  1586. }
  1587. if(n > 0) {
  1588. /* packet assembled, leave */
  1589. nwritten = n;
  1590. goto out;
  1591. }
  1592. }
  1593. out:
  1594. return nwritten;
  1595. }
  1596. static CURLcode cf_progress_egress(struct Curl_cfilter *cf,
  1597. struct Curl_easy *data,
  1598. struct pkt_io_ctx *pktx)
  1599. {
  1600. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1601. ssize_t nread;
  1602. size_t max_payload_size, path_max_payload_size, max_pktcnt;
  1603. size_t pktcnt = 0;
  1604. size_t gsolen = 0; /* this disables gso until we have a clue */
  1605. CURLcode curlcode;
  1606. struct pkt_io_ctx local_pktx;
  1607. if(!pktx) {
  1608. pktx_init(&local_pktx, cf, data);
  1609. pktx = &local_pktx;
  1610. }
  1611. else {
  1612. pktx_update_time(pktx, cf);
  1613. ngtcp2_path_storage_zero(&pktx->ps);
  1614. }
  1615. curlcode = vquic_flush(cf, data, &ctx->q);
  1616. if(curlcode) {
  1617. if(curlcode == CURLE_AGAIN) {
  1618. Curl_expire(data, 1, EXPIRE_QUIC);
  1619. return CURLE_OK;
  1620. }
  1621. return curlcode;
  1622. }
  1623. /* In UDP, there is a maximum theoretical packet paload length and
  1624. * a minimum payload length that is "guaranteed" to work.
  1625. * To detect if this minimum payload can be increased, ngtcp2 sends
  1626. * now and then a packet payload larger than the minimum. It that
  1627. * is ACKed by the peer, both parties know that it works and
  1628. * the subsequent packets can use a larger one.
  1629. * This is called PMTUD (Path Maximum Transmission Unit Discovery).
  1630. * Since a PMTUD might be rejected right on send, we do not want it
  1631. * be followed by other packets of lesser size. Because those would
  1632. * also fail then. So, if we detect a PMTUD while buffering, we flush.
  1633. */
  1634. max_payload_size = ngtcp2_conn_get_max_tx_udp_payload_size(ctx->qconn);
  1635. path_max_payload_size =
  1636. ngtcp2_conn_get_path_max_tx_udp_payload_size(ctx->qconn);
  1637. /* maximum number of packets buffered before we flush to the socket */
  1638. max_pktcnt = CURLMIN(MAX_PKT_BURST,
  1639. ctx->q.sendbuf.chunk_size / max_payload_size);
  1640. for(;;) {
  1641. /* add the next packet to send, if any, to our buffer */
  1642. nread = Curl_bufq_sipn(&ctx->q.sendbuf, max_payload_size,
  1643. read_pkt_to_send, pktx, &curlcode);
  1644. if(nread < 0) {
  1645. if(curlcode != CURLE_AGAIN)
  1646. return curlcode;
  1647. /* Nothing more to add, flush and leave */
  1648. curlcode = vquic_send(cf, data, &ctx->q, gsolen);
  1649. if(curlcode) {
  1650. if(curlcode == CURLE_AGAIN) {
  1651. Curl_expire(data, 1, EXPIRE_QUIC);
  1652. return CURLE_OK;
  1653. }
  1654. return curlcode;
  1655. }
  1656. goto out;
  1657. }
  1658. DEBUGASSERT(nread > 0);
  1659. if(pktcnt == 0) {
  1660. /* first packet in buffer. This is either of a known, "good"
  1661. * payload size or it is a PMTUD. We will see. */
  1662. gsolen = (size_t)nread;
  1663. }
  1664. else if((size_t)nread > gsolen ||
  1665. (gsolen > path_max_payload_size && (size_t)nread != gsolen)) {
  1666. /* The just added packet is a PMTUD *or* the one(s) before the
  1667. * just added were PMTUD and the last one is smaller.
  1668. * Flush the buffer before the last add. */
  1669. curlcode = vquic_send_tail_split(cf, data, &ctx->q,
  1670. gsolen, nread, nread);
  1671. if(curlcode) {
  1672. if(curlcode == CURLE_AGAIN) {
  1673. Curl_expire(data, 1, EXPIRE_QUIC);
  1674. return CURLE_OK;
  1675. }
  1676. return curlcode;
  1677. }
  1678. pktcnt = 0;
  1679. continue;
  1680. }
  1681. if(++pktcnt >= max_pktcnt || (size_t)nread < gsolen) {
  1682. /* Reached MAX_PKT_BURST *or*
  1683. * the capacity of our buffer *or*
  1684. * last add was shorter than the previous ones, flush */
  1685. curlcode = vquic_send(cf, data, &ctx->q, gsolen);
  1686. if(curlcode) {
  1687. if(curlcode == CURLE_AGAIN) {
  1688. Curl_expire(data, 1, EXPIRE_QUIC);
  1689. return CURLE_OK;
  1690. }
  1691. return curlcode;
  1692. }
  1693. /* pktbuf has been completely sent */
  1694. pktcnt = 0;
  1695. }
  1696. }
  1697. out:
  1698. return CURLE_OK;
  1699. }
  1700. /*
  1701. * Called from transfer.c:data_pending to know if we should keep looping
  1702. * to receive more data from the connection.
  1703. */
  1704. static bool cf_ngtcp2_data_pending(struct Curl_cfilter *cf,
  1705. const struct Curl_easy *data)
  1706. {
  1707. (void)cf;
  1708. (void)data;
  1709. return FALSE;
  1710. }
  1711. static CURLcode h3_data_pause(struct Curl_cfilter *cf,
  1712. struct Curl_easy *data,
  1713. bool pause)
  1714. {
  1715. /* TODO: there seems right now no API in ngtcp2 to shrink/enlarge
  1716. * the streams windows. As we do in HTTP/2. */
  1717. if(!pause) {
  1718. h3_drain_stream(cf, data);
  1719. Curl_expire(data, 0, EXPIRE_RUN_NOW);
  1720. }
  1721. return CURLE_OK;
  1722. }
  1723. static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
  1724. struct Curl_easy *data,
  1725. int event, int arg1, void *arg2)
  1726. {
  1727. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1728. CURLcode result = CURLE_OK;
  1729. struct cf_call_data save;
  1730. CF_DATA_SAVE(save, cf, data);
  1731. (void)arg1;
  1732. (void)arg2;
  1733. switch(event) {
  1734. case CF_CTRL_DATA_SETUP:
  1735. break;
  1736. case CF_CTRL_DATA_PAUSE:
  1737. result = h3_data_pause(cf, data, (arg1 != 0));
  1738. break;
  1739. case CF_CTRL_DATA_DETACH:
  1740. h3_data_done(cf, data);
  1741. break;
  1742. case CF_CTRL_DATA_DONE:
  1743. h3_data_done(cf, data);
  1744. break;
  1745. case CF_CTRL_DATA_DONE_SEND: {
  1746. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  1747. if(stream && !stream->send_closed) {
  1748. stream->send_closed = TRUE;
  1749. stream->upload_left = Curl_bufq_len(&stream->sendbuf) -
  1750. stream->sendbuf_len_in_flight;
  1751. (void)nghttp3_conn_resume_stream(ctx->h3conn, stream->id);
  1752. }
  1753. break;
  1754. }
  1755. case CF_CTRL_DATA_IDLE: {
  1756. struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
  1757. CURL_TRC_CF(data, cf, "data idle");
  1758. if(stream && !stream->closed) {
  1759. result = check_and_set_expiry(cf, data, NULL);
  1760. if(result)
  1761. CURL_TRC_CF(data, cf, "data idle, check_and_set_expiry -> %d", result);
  1762. }
  1763. break;
  1764. }
  1765. default:
  1766. break;
  1767. }
  1768. CF_DATA_RESTORE(cf, save);
  1769. return result;
  1770. }
  1771. static void cf_ngtcp2_ctx_close(struct cf_ngtcp2_ctx *ctx)
  1772. {
  1773. struct cf_call_data save = ctx->call_data;
  1774. if(!ctx->initialized)
  1775. return;
  1776. if(ctx->qlogfd != -1) {
  1777. close(ctx->qlogfd);
  1778. }
  1779. ctx->qlogfd = -1;
  1780. Curl_vquic_tls_cleanup(&ctx->tls);
  1781. vquic_ctx_free(&ctx->q);
  1782. if(ctx->h3conn)
  1783. nghttp3_conn_del(ctx->h3conn);
  1784. if(ctx->qconn)
  1785. ngtcp2_conn_del(ctx->qconn);
  1786. ctx->call_data = save;
  1787. }
  1788. static CURLcode cf_ngtcp2_shutdown(struct Curl_cfilter *cf,
  1789. struct Curl_easy *data, bool *done)
  1790. {
  1791. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1792. struct cf_call_data save;
  1793. struct pkt_io_ctx pktx;
  1794. CURLcode result = CURLE_OK;
  1795. if(cf->shutdown || !ctx->qconn) {
  1796. *done = TRUE;
  1797. return CURLE_OK;
  1798. }
  1799. CF_DATA_SAVE(save, cf, data);
  1800. *done = FALSE;
  1801. pktx_init(&pktx, cf, data);
  1802. if(!ctx->shutdown_started) {
  1803. char buffer[NGTCP2_MAX_UDP_PAYLOAD_SIZE];
  1804. ngtcp2_ssize nwritten;
  1805. if(!Curl_bufq_is_empty(&ctx->q.sendbuf)) {
  1806. CURL_TRC_CF(data, cf, "shutdown, flushing sendbuf");
  1807. result = cf_progress_egress(cf, data, &pktx);
  1808. if(!Curl_bufq_is_empty(&ctx->q.sendbuf)) {
  1809. CURL_TRC_CF(data, cf, "sending shutdown packets blocked");
  1810. result = CURLE_OK;
  1811. goto out;
  1812. }
  1813. else if(result) {
  1814. CURL_TRC_CF(data, cf, "shutdown, error %d flushing sendbuf", result);
  1815. *done = TRUE;
  1816. goto out;
  1817. }
  1818. }
  1819. ctx->shutdown_started = TRUE;
  1820. nwritten = ngtcp2_conn_write_connection_close(
  1821. ctx->qconn, NULL, /* path */
  1822. NULL, /* pkt_info */
  1823. (uint8_t *)buffer, sizeof(buffer),
  1824. &ctx->last_error, pktx.ts);
  1825. CURL_TRC_CF(data, cf, "start shutdown(err_type=%d, err_code=%"
  1826. FMT_PRIu64 ") -> %d", ctx->last_error.type,
  1827. (curl_uint64_t)ctx->last_error.error_code, (int)nwritten);
  1828. if(nwritten > 0) {
  1829. Curl_bufq_write(&ctx->q.sendbuf, (const unsigned char *)buffer,
  1830. (size_t)nwritten, &result);
  1831. if(result) {
  1832. CURL_TRC_CF(data, cf, "error %d adding shutdown packets to sendbuf, "
  1833. "aborting shutdown", result);
  1834. goto out;
  1835. }
  1836. ctx->q.no_gso = TRUE;
  1837. ctx->q.gsolen = (size_t)nwritten;
  1838. ctx->q.split_len = 0;
  1839. }
  1840. }
  1841. if(!Curl_bufq_is_empty(&ctx->q.sendbuf)) {
  1842. CURL_TRC_CF(data, cf, "shutdown, flushing egress");
  1843. result = vquic_flush(cf, data, &ctx->q);
  1844. if(result == CURLE_AGAIN) {
  1845. CURL_TRC_CF(data, cf, "sending shutdown packets blocked");
  1846. result = CURLE_OK;
  1847. goto out;
  1848. }
  1849. else if(result) {
  1850. CURL_TRC_CF(data, cf, "shutdown, error %d flushing sendbuf", result);
  1851. *done = TRUE;
  1852. goto out;
  1853. }
  1854. }
  1855. if(Curl_bufq_is_empty(&ctx->q.sendbuf)) {
  1856. /* Sent everything off. ngtcp2 seems to have no support for graceful
  1857. * shutdowns. So, we are done. */
  1858. CURL_TRC_CF(data, cf, "shutdown completely sent off, done");
  1859. *done = TRUE;
  1860. result = CURLE_OK;
  1861. }
  1862. out:
  1863. CF_DATA_RESTORE(cf, save);
  1864. return result;
  1865. }
  1866. static void cf_ngtcp2_conn_close(struct Curl_cfilter *cf,
  1867. struct Curl_easy *data)
  1868. {
  1869. bool done;
  1870. cf_ngtcp2_shutdown(cf, data, &done);
  1871. }
  1872. static void cf_ngtcp2_close(struct Curl_cfilter *cf, struct Curl_easy *data)
  1873. {
  1874. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1875. struct cf_call_data save;
  1876. CF_DATA_SAVE(save, cf, data);
  1877. if(ctx && ctx->qconn) {
  1878. cf_ngtcp2_conn_close(cf, data);
  1879. cf_ngtcp2_ctx_close(ctx);
  1880. CURL_TRC_CF(data, cf, "close");
  1881. }
  1882. cf->connected = FALSE;
  1883. CF_DATA_RESTORE(cf, save);
  1884. }
  1885. static void cf_ngtcp2_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
  1886. {
  1887. CURL_TRC_CF(data, cf, "destroy");
  1888. if(cf->ctx) {
  1889. cf_ngtcp2_ctx_free(cf->ctx);
  1890. cf->ctx = NULL;
  1891. }
  1892. }
  1893. #ifdef USE_OPENSSL
  1894. /* The "new session" callback must return zero if the session can be removed
  1895. * or non-zero if the session has been put into the session cache.
  1896. */
  1897. static int quic_ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
  1898. {
  1899. struct Curl_cfilter *cf;
  1900. struct cf_ngtcp2_ctx *ctx;
  1901. struct Curl_easy *data;
  1902. ngtcp2_crypto_conn_ref *cref;
  1903. cref = (ngtcp2_crypto_conn_ref *)SSL_get_app_data(ssl);
  1904. cf = cref ? cref->user_data : NULL;
  1905. ctx = cf ? cf->ctx : NULL;
  1906. data = cf ? CF_DATA_CURRENT(cf) : NULL;
  1907. if(cf && data && ctx) {
  1908. Curl_ossl_add_session(cf, data, &ctx->peer, ssl_sessionid);
  1909. return 1;
  1910. }
  1911. return 0;
  1912. }
  1913. #endif /* USE_OPENSSL */
  1914. #ifdef USE_GNUTLS
  1915. static int quic_gtls_handshake_cb(gnutls_session_t session, unsigned int htype,
  1916. unsigned when, unsigned int incoming,
  1917. const gnutls_datum_t *msg)
  1918. {
  1919. ngtcp2_crypto_conn_ref *conn_ref = gnutls_session_get_ptr(session);
  1920. struct Curl_cfilter *cf = conn_ref ? conn_ref->user_data : NULL;
  1921. struct cf_ngtcp2_ctx *ctx = cf ? cf->ctx : NULL;
  1922. (void)msg;
  1923. (void)incoming;
  1924. if(when && cf && ctx) { /* after message has been processed */
  1925. struct Curl_easy *data = CF_DATA_CURRENT(cf);
  1926. DEBUGASSERT(data);
  1927. if(data) {
  1928. CURL_TRC_CF(data, cf, "handshake: %s message type %d",
  1929. incoming ? "incoming" : "outgoing", htype);
  1930. }
  1931. switch(htype) {
  1932. case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: {
  1933. (void)Curl_gtls_update_session_id(cf, data, session, &ctx->peer, "h3");
  1934. break;
  1935. }
  1936. default:
  1937. break;
  1938. }
  1939. }
  1940. return 0;
  1941. }
  1942. #endif /* USE_GNUTLS */
  1943. #ifdef USE_WOLFSSL
  1944. static int wssl_quic_new_session_cb(WOLFSSL *ssl, WOLFSSL_SESSION *session)
  1945. {
  1946. ngtcp2_crypto_conn_ref *conn_ref = wolfSSL_get_app_data(ssl);
  1947. struct Curl_cfilter *cf = conn_ref ? conn_ref->user_data : NULL;
  1948. DEBUGASSERT(cf != NULL);
  1949. if(cf && session) {
  1950. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1951. struct Curl_easy *data = CF_DATA_CURRENT(cf);
  1952. DEBUGASSERT(data);
  1953. if(data && ctx) {
  1954. (void)wssl_cache_session(cf, data, &ctx->peer, session);
  1955. }
  1956. }
  1957. return 0;
  1958. }
  1959. #endif /* USE_WOLFSSL */
  1960. static CURLcode tls_ctx_setup(struct Curl_cfilter *cf,
  1961. struct Curl_easy *data,
  1962. void *user_data)
  1963. {
  1964. struct curl_tls_ctx *ctx = user_data;
  1965. struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
  1966. #ifdef USE_OPENSSL
  1967. #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
  1968. if(ngtcp2_crypto_boringssl_configure_client_context(ctx->ossl.ssl_ctx)
  1969. != 0) {
  1970. failf(data, "ngtcp2_crypto_boringssl_configure_client_context failed");
  1971. return CURLE_FAILED_INIT;
  1972. }
  1973. #else
  1974. if(ngtcp2_crypto_quictls_configure_client_context(ctx->ossl.ssl_ctx) != 0) {
  1975. failf(data, "ngtcp2_crypto_quictls_configure_client_context failed");
  1976. return CURLE_FAILED_INIT;
  1977. }
  1978. #endif /* !OPENSSL_IS_BORINGSSL && !OPENSSL_IS_AWSLC */
  1979. if(ssl_config->primary.cache_session) {
  1980. /* Enable the session cache because it is a prerequisite for the
  1981. * "new session" callback. Use the "external storage" mode to prevent
  1982. * OpenSSL from creating an internal session cache.
  1983. */
  1984. SSL_CTX_set_session_cache_mode(ctx->ossl.ssl_ctx,
  1985. SSL_SESS_CACHE_CLIENT |
  1986. SSL_SESS_CACHE_NO_INTERNAL);
  1987. SSL_CTX_sess_set_new_cb(ctx->ossl.ssl_ctx, quic_ossl_new_session_cb);
  1988. }
  1989. #elif defined(USE_GNUTLS)
  1990. if(ngtcp2_crypto_gnutls_configure_client_session(ctx->gtls.session) != 0) {
  1991. failf(data, "ngtcp2_crypto_gnutls_configure_client_session failed");
  1992. return CURLE_FAILED_INIT;
  1993. }
  1994. if(ssl_config->primary.cache_session) {
  1995. gnutls_handshake_set_hook_function(ctx->gtls.session,
  1996. GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST,
  1997. quic_gtls_handshake_cb);
  1998. }
  1999. #elif defined(USE_WOLFSSL)
  2000. if(ngtcp2_crypto_wolfssl_configure_client_context(ctx->wssl.ctx) != 0) {
  2001. failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed");
  2002. return CURLE_FAILED_INIT;
  2003. }
  2004. if(ssl_config->primary.cache_session) {
  2005. /* Register to get notified when a new session is received */
  2006. wolfSSL_CTX_sess_set_new_cb(ctx->wssl.ctx, wssl_quic_new_session_cb);
  2007. }
  2008. #endif
  2009. return CURLE_OK;
  2010. }
  2011. /*
  2012. * Might be called twice for happy eyeballs.
  2013. */
  2014. static CURLcode cf_connect_start(struct Curl_cfilter *cf,
  2015. struct Curl_easy *data,
  2016. struct pkt_io_ctx *pktx)
  2017. {
  2018. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  2019. int rc;
  2020. int rv;
  2021. CURLcode result;
  2022. const struct Curl_sockaddr_ex *sockaddr = NULL;
  2023. int qfd;
  2024. DEBUGASSERT(ctx->initialized);
  2025. result = Curl_ssl_peer_init(&ctx->peer, cf, TRNSPRT_QUIC);
  2026. if(result)
  2027. return result;
  2028. #define H3_ALPN "\x2h3\x5h3-29"
  2029. result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer,
  2030. H3_ALPN, sizeof(H3_ALPN) - 1,
  2031. tls_ctx_setup, &ctx->tls, &ctx->conn_ref);
  2032. if(result)
  2033. return result;
  2034. #ifdef USE_OPENSSL
  2035. SSL_set_quic_use_legacy_codepoint(ctx->tls.ossl.ssl, 0);
  2036. #endif
  2037. ctx->dcid.datalen = NGTCP2_MAX_CIDLEN;
  2038. result = Curl_rand(data, ctx->dcid.data, NGTCP2_MAX_CIDLEN);
  2039. if(result)
  2040. return result;
  2041. ctx->scid.datalen = NGTCP2_MAX_CIDLEN;
  2042. result = Curl_rand(data, ctx->scid.data, NGTCP2_MAX_CIDLEN);
  2043. if(result)
  2044. return result;
  2045. (void)Curl_qlogdir(data, ctx->scid.data, NGTCP2_MAX_CIDLEN, &qfd);
  2046. ctx->qlogfd = qfd; /* -1 if failure above */
  2047. quic_settings(ctx, data, pktx);
  2048. result = vquic_ctx_init(&ctx->q);
  2049. if(result)
  2050. return result;
  2051. Curl_cf_socket_peek(cf->next, data, &ctx->q.sockfd, &sockaddr, NULL);
  2052. if(!sockaddr)
  2053. return CURLE_QUIC_CONNECT_ERROR;
  2054. ctx->q.local_addrlen = sizeof(ctx->q.local_addr);
  2055. rv = getsockname(ctx->q.sockfd, (struct sockaddr *)&ctx->q.local_addr,
  2056. &ctx->q.local_addrlen);
  2057. if(rv == -1)
  2058. return CURLE_QUIC_CONNECT_ERROR;
  2059. ngtcp2_addr_init(&ctx->connected_path.local,
  2060. (struct sockaddr *)&ctx->q.local_addr,
  2061. ctx->q.local_addrlen);
  2062. ngtcp2_addr_init(&ctx->connected_path.remote,
  2063. &sockaddr->curl_sa_addr, (socklen_t)sockaddr->addrlen);
  2064. rc = ngtcp2_conn_client_new(&ctx->qconn, &ctx->dcid, &ctx->scid,
  2065. &ctx->connected_path,
  2066. NGTCP2_PROTO_VER_V1, &ng_callbacks,
  2067. &ctx->settings, &ctx->transport_params,
  2068. NULL, cf);
  2069. if(rc)
  2070. return CURLE_QUIC_CONNECT_ERROR;
  2071. #ifdef USE_OPENSSL
  2072. ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->tls.ossl.ssl);
  2073. #elif defined(USE_GNUTLS)
  2074. ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->tls.gtls.session);
  2075. #elif defined(USE_WOLFSSL)
  2076. ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->tls.wssl.handle);
  2077. #else
  2078. #error "ngtcp2 TLS backend not defined"
  2079. #endif
  2080. ngtcp2_ccerr_default(&ctx->last_error);
  2081. ctx->conn_ref.get_conn = get_conn;
  2082. ctx->conn_ref.user_data = cf;
  2083. return CURLE_OK;
  2084. }
  2085. static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
  2086. struct Curl_easy *data,
  2087. bool blocking, bool *done)
  2088. {
  2089. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  2090. CURLcode result = CURLE_OK;
  2091. struct cf_call_data save;
  2092. struct curltime now;
  2093. struct pkt_io_ctx pktx;
  2094. if(cf->connected) {
  2095. *done = TRUE;
  2096. return CURLE_OK;
  2097. }
  2098. /* Connect the UDP filter first */
  2099. if(!cf->next->connected) {
  2100. result = Curl_conn_cf_connect(cf->next, data, blocking, done);
  2101. if(result || !*done)
  2102. return result;
  2103. }
  2104. *done = FALSE;
  2105. now = Curl_now();
  2106. pktx_init(&pktx, cf, data);
  2107. CF_DATA_SAVE(save, cf, data);
  2108. if(!ctx->qconn) {
  2109. ctx->started_at = now;
  2110. result = cf_connect_start(cf, data, &pktx);
  2111. if(result)
  2112. goto out;
  2113. result = cf_progress_egress(cf, data, &pktx);
  2114. /* we do not expect to be able to recv anything yet */
  2115. goto out;
  2116. }
  2117. result = cf_progress_ingress(cf, data, &pktx);
  2118. if(result)
  2119. goto out;
  2120. result = cf_progress_egress(cf, data, &pktx);
  2121. if(result)
  2122. goto out;
  2123. if(ngtcp2_conn_get_handshake_completed(ctx->qconn)) {
  2124. ctx->handshake_at = now;
  2125. CURL_TRC_CF(data, cf, "handshake complete after %dms",
  2126. (int)Curl_timediff(now, ctx->started_at));
  2127. result = qng_verify_peer(cf, data);
  2128. if(!result) {
  2129. CURL_TRC_CF(data, cf, "peer verified");
  2130. cf->connected = TRUE;
  2131. cf->conn->alpn = CURL_HTTP_VERSION_3;
  2132. *done = TRUE;
  2133. connkeep(cf->conn, "HTTP/3 default");
  2134. }
  2135. }
  2136. out:
  2137. if(result == CURLE_RECV_ERROR && ctx->qconn &&
  2138. ngtcp2_conn_in_draining_period(ctx->qconn)) {
  2139. /* When a QUIC server instance is shutting down, it may send us a
  2140. * CONNECTION_CLOSE right away. Our connection then enters the DRAINING
  2141. * state. The CONNECT may work in the near future again. Indicate
  2142. * that as a "weird" reply. */
  2143. result = CURLE_WEIRD_SERVER_REPLY;
  2144. }
  2145. #ifndef CURL_DISABLE_VERBOSE_STRINGS
  2146. if(result) {
  2147. struct ip_quadruple ip;
  2148. Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip);
  2149. infof(data, "QUIC connect to %s port %u failed: %s",
  2150. ip.remote_ip, ip.remote_port, curl_easy_strerror(result));
  2151. }
  2152. #endif
  2153. if(!result && ctx->qconn) {
  2154. result = check_and_set_expiry(cf, data, &pktx);
  2155. }
  2156. if(result || *done)
  2157. CURL_TRC_CF(data, cf, "connect -> %d, done=%d", result, *done);
  2158. CF_DATA_RESTORE(cf, save);
  2159. return result;
  2160. }
  2161. static CURLcode cf_ngtcp2_query(struct Curl_cfilter *cf,
  2162. struct Curl_easy *data,
  2163. int query, int *pres1, void *pres2)
  2164. {
  2165. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  2166. struct cf_call_data save;
  2167. switch(query) {
  2168. case CF_QUERY_MAX_CONCURRENT: {
  2169. DEBUGASSERT(pres1);
  2170. CF_DATA_SAVE(save, cf, data);
  2171. /* Set after transport params arrived and continually updated
  2172. * by callback. QUIC counts the number over the lifetime of the
  2173. * connection, ever increasing.
  2174. * We count the *open* transfers plus the budget for new ones. */
  2175. if(!ctx->qconn || ctx->shutdown_started) {
  2176. *pres1 = 0;
  2177. }
  2178. else if(ctx->max_bidi_streams) {
  2179. uint64_t avail_bidi_streams = 0;
  2180. uint64_t max_streams = CONN_INUSE(cf->conn);
  2181. if(ctx->max_bidi_streams > ctx->used_bidi_streams)
  2182. avail_bidi_streams = ctx->max_bidi_streams - ctx->used_bidi_streams;
  2183. max_streams += avail_bidi_streams;
  2184. *pres1 = (max_streams > INT_MAX) ? INT_MAX : (int)max_streams;
  2185. }
  2186. else /* transport params not arrived yet? take our default. */
  2187. *pres1 = (int)Curl_multi_max_concurrent_streams(data->multi);
  2188. CURL_TRC_CF(data, cf, "query conn[%" FMT_OFF_T "]: "
  2189. "MAX_CONCURRENT -> %d (%zu in use)",
  2190. cf->conn->connection_id, *pres1, CONN_INUSE(cf->conn));
  2191. CF_DATA_RESTORE(cf, save);
  2192. return CURLE_OK;
  2193. }
  2194. case CF_QUERY_CONNECT_REPLY_MS:
  2195. if(ctx->q.got_first_byte) {
  2196. timediff_t ms = Curl_timediff(ctx->q.first_byte_at, ctx->started_at);
  2197. *pres1 = (ms < INT_MAX) ? (int)ms : INT_MAX;
  2198. }
  2199. else
  2200. *pres1 = -1;
  2201. return CURLE_OK;
  2202. case CF_QUERY_TIMER_CONNECT: {
  2203. struct curltime *when = pres2;
  2204. if(ctx->q.got_first_byte)
  2205. *when = ctx->q.first_byte_at;
  2206. return CURLE_OK;
  2207. }
  2208. case CF_QUERY_TIMER_APPCONNECT: {
  2209. struct curltime *when = pres2;
  2210. if(cf->connected)
  2211. *when = ctx->handshake_at;
  2212. return CURLE_OK;
  2213. }
  2214. default:
  2215. break;
  2216. }
  2217. return cf->next ?
  2218. cf->next->cft->query(cf->next, data, query, pres1, pres2) :
  2219. CURLE_UNKNOWN_OPTION;
  2220. }
  2221. static bool cf_ngtcp2_conn_is_alive(struct Curl_cfilter *cf,
  2222. struct Curl_easy *data,
  2223. bool *input_pending)
  2224. {
  2225. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  2226. bool alive = FALSE;
  2227. const ngtcp2_transport_params *rp;
  2228. struct cf_call_data save;
  2229. CF_DATA_SAVE(save, cf, data);
  2230. *input_pending = FALSE;
  2231. if(!ctx->qconn || ctx->shutdown_started)
  2232. goto out;
  2233. /* Both sides of the QUIC connection announce they max idle times in
  2234. * the transport parameters. Look at the minimum of both and if
  2235. * we exceed this, regard the connection as dead. The other side
  2236. * may have completely purged it and will no longer respond
  2237. * to any packets from us. */
  2238. rp = ngtcp2_conn_get_remote_transport_params(ctx->qconn);
  2239. if(rp) {
  2240. timediff_t idletime;
  2241. uint64_t idle_ms = ctx->max_idle_ms;
  2242. if(rp->max_idle_timeout &&
  2243. (rp->max_idle_timeout / NGTCP2_MILLISECONDS) < idle_ms)
  2244. idle_ms = (rp->max_idle_timeout / NGTCP2_MILLISECONDS);
  2245. idletime = Curl_timediff(Curl_now(), ctx->q.last_io);
  2246. if(idletime > 0 && (uint64_t)idletime > idle_ms)
  2247. goto out;
  2248. }
  2249. if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending))
  2250. goto out;
  2251. alive = TRUE;
  2252. if(*input_pending) {
  2253. CURLcode result;
  2254. /* This happens before we have sent off a request and the connection is
  2255. not in use by any other transfer, there should not be any data here,
  2256. only "protocol frames" */
  2257. *input_pending = FALSE;
  2258. result = cf_progress_ingress(cf, data, NULL);
  2259. CURL_TRC_CF(data, cf, "is_alive, progress ingress -> %d", result);
  2260. alive = result ? FALSE : TRUE;
  2261. }
  2262. out:
  2263. CF_DATA_RESTORE(cf, save);
  2264. return alive;
  2265. }
  2266. struct Curl_cftype Curl_cft_http3 = {
  2267. "HTTP/3",
  2268. CF_TYPE_IP_CONNECT | CF_TYPE_SSL | CF_TYPE_MULTIPLEX,
  2269. 0,
  2270. cf_ngtcp2_destroy,
  2271. cf_ngtcp2_connect,
  2272. cf_ngtcp2_close,
  2273. cf_ngtcp2_shutdown,
  2274. Curl_cf_def_get_host,
  2275. cf_ngtcp2_adjust_pollset,
  2276. cf_ngtcp2_data_pending,
  2277. cf_ngtcp2_send,
  2278. cf_ngtcp2_recv,
  2279. cf_ngtcp2_data_event,
  2280. cf_ngtcp2_conn_is_alive,
  2281. Curl_cf_def_conn_keep_alive,
  2282. cf_ngtcp2_query,
  2283. };
  2284. CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf,
  2285. struct Curl_easy *data,
  2286. struct connectdata *conn,
  2287. const struct Curl_addrinfo *ai)
  2288. {
  2289. struct cf_ngtcp2_ctx *ctx = NULL;
  2290. struct Curl_cfilter *cf = NULL, *udp_cf = NULL;
  2291. CURLcode result;
  2292. (void)data;
  2293. ctx = calloc(1, sizeof(*ctx));
  2294. if(!ctx) {
  2295. result = CURLE_OUT_OF_MEMORY;
  2296. goto out;
  2297. }
  2298. cf_ngtcp2_ctx_init(ctx);
  2299. result = Curl_cf_create(&cf, &Curl_cft_http3, ctx);
  2300. if(result)
  2301. goto out;
  2302. result = Curl_cf_udp_create(&udp_cf, data, conn, ai, TRNSPRT_QUIC);
  2303. if(result)
  2304. goto out;
  2305. cf->conn = conn;
  2306. udp_cf->conn = cf->conn;
  2307. udp_cf->sockindex = cf->sockindex;
  2308. cf->next = udp_cf;
  2309. out:
  2310. *pcf = (!result) ? cf : NULL;
  2311. if(result) {
  2312. if(udp_cf)
  2313. Curl_conn_cf_discard_sub(cf, udp_cf, data, TRUE);
  2314. Curl_safefree(cf);
  2315. cf_ngtcp2_ctx_free(ctx);
  2316. }
  2317. return result;
  2318. }
  2319. bool Curl_conn_is_ngtcp2(const struct Curl_easy *data,
  2320. const struct connectdata *conn,
  2321. int sockindex)
  2322. {
  2323. struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL;
  2324. (void)data;
  2325. for(; cf; cf = cf->next) {
  2326. if(cf->cft == &Curl_cft_http3)
  2327. return TRUE;
  2328. if(cf->cft->flags & CF_TYPE_IP_CONNECT)
  2329. return FALSE;
  2330. }
  2331. return FALSE;
  2332. }
  2333. #endif