curl_ngtcp2.c 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550
  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. #ifdef OPENSSL_IS_BORINGSSL
  31. #include <ngtcp2/ngtcp2_crypto_boringssl.h>
  32. #else
  33. #include <ngtcp2/ngtcp2_crypto_openssl.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 "sendf.h"
  45. #include "strdup.h"
  46. #include "rand.h"
  47. #include "multiif.h"
  48. #include "strcase.h"
  49. #include "cfilters.h"
  50. #include "cf-socket.h"
  51. #include "connect.h"
  52. #include "progress.h"
  53. #include "strerror.h"
  54. #include "dynbuf.h"
  55. #include "select.h"
  56. #include "vquic.h"
  57. #include "vquic_int.h"
  58. #include "h2h3.h"
  59. #include "vtls/keylog.h"
  60. #include "vtls/vtls.h"
  61. #include "curl_ngtcp2.h"
  62. #include "warnless.h"
  63. /* The last 3 #include files should be in this order */
  64. #include "curl_printf.h"
  65. #include "curl_memory.h"
  66. #include "memdebug.h"
  67. #define H3_ALPN_H3_29 "\x5h3-29"
  68. #define H3_ALPN_H3 "\x2h3"
  69. /*
  70. * This holds outgoing HTTP/3 stream data that is used by nghttp3 until acked.
  71. * It is used as a circular buffer. Add new bytes at the end until it reaches
  72. * the far end, then start over at index 0 again.
  73. */
  74. #define H3_SEND_SIZE (256*1024)
  75. struct h3out {
  76. uint8_t buf[H3_SEND_SIZE];
  77. size_t used; /* number of bytes used in the buffer */
  78. size_t windex; /* index in the buffer where to start writing the next
  79. data block */
  80. };
  81. #define QUIC_MAX_STREAMS (256*1024)
  82. #define QUIC_MAX_DATA (1*1024*1024)
  83. #define QUIC_IDLE_TIMEOUT (60*NGTCP2_SECONDS)
  84. #define QUIC_HANDSHAKE_TIMEOUT (10*NGTCP2_SECONDS)
  85. #ifdef USE_OPENSSL
  86. #define QUIC_CIPHERS \
  87. "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \
  88. "POLY1305_SHA256:TLS_AES_128_CCM_SHA256"
  89. #define QUIC_GROUPS "P-256:X25519:P-384:P-521"
  90. #elif defined(USE_GNUTLS)
  91. #define QUIC_PRIORITY \
  92. "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \
  93. "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \
  94. "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \
  95. "%DISABLE_TLS13_COMPAT_MODE"
  96. #elif defined(USE_WOLFSSL)
  97. #define QUIC_CIPHERS \
  98. "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \
  99. "POLY1305_SHA256:TLS_AES_128_CCM_SHA256"
  100. #define QUIC_GROUPS "P-256:P-384:P-521"
  101. #endif
  102. /*
  103. * Store ngtcp2 version info in this buffer.
  104. */
  105. void Curl_ngtcp2_ver(char *p, size_t len)
  106. {
  107. const ngtcp2_info *ng2 = ngtcp2_version(0);
  108. const nghttp3_info *ht3 = nghttp3_version(0);
  109. (void)msnprintf(p, len, "ngtcp2/%s nghttp3/%s",
  110. ng2->version_str, ht3->version_str);
  111. }
  112. struct cf_ngtcp2_ctx {
  113. struct cf_quic_ctx q;
  114. ngtcp2_path connected_path;
  115. ngtcp2_conn *qconn;
  116. ngtcp2_cid dcid;
  117. ngtcp2_cid scid;
  118. uint32_t version;
  119. ngtcp2_settings settings;
  120. ngtcp2_transport_params transport_params;
  121. ngtcp2_connection_close_error last_error;
  122. ngtcp2_crypto_conn_ref conn_ref;
  123. #ifdef USE_OPENSSL
  124. SSL_CTX *sslctx;
  125. SSL *ssl;
  126. #elif defined(USE_GNUTLS)
  127. struct gtls_instance *gtls;
  128. #elif defined(USE_WOLFSSL)
  129. WOLFSSL_CTX *sslctx;
  130. WOLFSSL *ssl;
  131. #endif
  132. struct cf_call_data call_data;
  133. nghttp3_conn *h3conn;
  134. nghttp3_settings h3settings;
  135. int qlogfd;
  136. struct curltime started_at; /* time the current attempt started */
  137. struct curltime handshake_at; /* time connect handshake finished */
  138. struct curltime first_byte_at; /* when first byte was recvd */
  139. struct curltime reconnect_at; /* time the next attempt should start */
  140. BIT(got_first_byte); /* if first byte was received */
  141. };
  142. /* How to access `call_data` from a cf_ngtcp2 filter */
  143. #define CF_CTX_CALL_DATA(cf) \
  144. ((struct cf_ngtcp2_ctx *)(cf)->ctx)->call_data
  145. /* ngtcp2 default congestion controller does not perform pacing. Limit
  146. the maximum packet burst to MAX_PKT_BURST packets. */
  147. #define MAX_PKT_BURST 10
  148. static CURLcode cf_process_ingress(struct Curl_cfilter *cf,
  149. struct Curl_easy *data);
  150. static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
  151. struct Curl_easy *data);
  152. static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
  153. uint64_t datalen, void *user_data,
  154. void *stream_user_data);
  155. static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref)
  156. {
  157. struct Curl_cfilter *cf = conn_ref->user_data;
  158. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  159. return ctx->qconn;
  160. }
  161. static ngtcp2_tstamp timestamp(void)
  162. {
  163. struct curltime ct = Curl_now();
  164. return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS;
  165. }
  166. #ifdef DEBUG_NGTCP2
  167. static void quic_printf(void *user_data, const char *fmt, ...)
  168. {
  169. struct Curl_cfilter *cf = user_data;
  170. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  171. (void)ctx; /* TODO: need an easy handle to infof() message */
  172. va_list ap;
  173. va_start(ap, fmt);
  174. vfprintf(stderr, fmt, ap);
  175. va_end(ap);
  176. fprintf(stderr, "\n");
  177. }
  178. #endif
  179. static void qlog_callback(void *user_data, uint32_t flags,
  180. const void *data, size_t datalen)
  181. {
  182. struct Curl_cfilter *cf = user_data;
  183. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  184. (void)flags;
  185. if(ctx->qlogfd != -1) {
  186. ssize_t rc = write(ctx->qlogfd, data, datalen);
  187. if(rc == -1) {
  188. /* on write error, stop further write attempts */
  189. close(ctx->qlogfd);
  190. ctx->qlogfd = -1;
  191. }
  192. }
  193. }
  194. static void quic_settings(struct cf_ngtcp2_ctx *ctx,
  195. struct Curl_easy *data)
  196. {
  197. ngtcp2_settings *s = &ctx->settings;
  198. ngtcp2_transport_params *t = &ctx->transport_params;
  199. size_t stream_win_size = CURL_MAX_READ_SIZE;
  200. ngtcp2_settings_default(s);
  201. ngtcp2_transport_params_default(t);
  202. #ifdef DEBUG_NGTCP2
  203. s->log_printf = quic_printf;
  204. #else
  205. s->log_printf = NULL;
  206. #endif
  207. (void)data;
  208. s->initial_ts = timestamp();
  209. s->handshake_timeout = QUIC_HANDSHAKE_TIMEOUT;
  210. s->max_window = 100 * stream_win_size;
  211. s->max_stream_window = stream_win_size;
  212. t->initial_max_data = 10 * stream_win_size;
  213. t->initial_max_stream_data_bidi_local = stream_win_size;
  214. t->initial_max_stream_data_bidi_remote = stream_win_size;
  215. t->initial_max_stream_data_uni = stream_win_size;
  216. t->initial_max_streams_bidi = QUIC_MAX_STREAMS;
  217. t->initial_max_streams_uni = QUIC_MAX_STREAMS;
  218. t->max_idle_timeout = QUIC_IDLE_TIMEOUT;
  219. if(ctx->qlogfd != -1) {
  220. s->qlog.write = qlog_callback;
  221. }
  222. }
  223. #ifdef USE_OPENSSL
  224. static void keylog_callback(const SSL *ssl, const char *line)
  225. {
  226. (void)ssl;
  227. Curl_tls_keylog_write_line(line);
  228. }
  229. #elif defined(USE_GNUTLS)
  230. static int keylog_callback(gnutls_session_t session, const char *label,
  231. const gnutls_datum_t *secret)
  232. {
  233. gnutls_datum_t crandom;
  234. gnutls_datum_t srandom;
  235. gnutls_session_get_random(session, &crandom, &srandom);
  236. if(crandom.size != 32) {
  237. return -1;
  238. }
  239. Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size);
  240. return 0;
  241. }
  242. #elif defined(USE_WOLFSSL)
  243. #if defined(HAVE_SECRET_CALLBACK)
  244. static void keylog_callback(const WOLFSSL *ssl, const char *line)
  245. {
  246. (void)ssl;
  247. Curl_tls_keylog_write_line(line);
  248. }
  249. #endif
  250. #endif
  251. static int init_ngh3_conn(struct Curl_cfilter *cf);
  252. #ifdef USE_OPENSSL
  253. static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx,
  254. struct Curl_cfilter *cf, struct Curl_easy *data)
  255. {
  256. struct connectdata *conn = cf->conn;
  257. CURLcode result = CURLE_FAILED_INIT;
  258. SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method());
  259. if(!ssl_ctx) {
  260. result = CURLE_OUT_OF_MEMORY;
  261. goto out;
  262. }
  263. #ifdef OPENSSL_IS_BORINGSSL
  264. if(ngtcp2_crypto_boringssl_configure_client_context(ssl_ctx) != 0) {
  265. failf(data, "ngtcp2_crypto_boringssl_configure_client_context failed");
  266. goto out;
  267. }
  268. #else
  269. if(ngtcp2_crypto_openssl_configure_client_context(ssl_ctx) != 0) {
  270. failf(data, "ngtcp2_crypto_openssl_configure_client_context failed");
  271. goto out;
  272. }
  273. #endif
  274. SSL_CTX_set_default_verify_paths(ssl_ctx);
  275. #ifdef OPENSSL_IS_BORINGSSL
  276. if(SSL_CTX_set1_curves_list(ssl_ctx, QUIC_GROUPS) != 1) {
  277. failf(data, "SSL_CTX_set1_curves_list failed");
  278. goto out;
  279. }
  280. #else
  281. if(SSL_CTX_set_ciphersuites(ssl_ctx, QUIC_CIPHERS) != 1) {
  282. char error_buffer[256];
  283. ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer));
  284. failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer);
  285. goto out;
  286. }
  287. if(SSL_CTX_set1_groups_list(ssl_ctx, QUIC_GROUPS) != 1) {
  288. failf(data, "SSL_CTX_set1_groups_list failed");
  289. goto out;
  290. }
  291. #endif
  292. /* Open the file if a TLS or QUIC backend has not done this before. */
  293. Curl_tls_keylog_open();
  294. if(Curl_tls_keylog_enabled()) {
  295. SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
  296. }
  297. result = Curl_ssl_setup_x509_store(cf, data, ssl_ctx);
  298. if(result)
  299. goto out;
  300. /* OpenSSL always tries to verify the peer, this only says whether it should
  301. * fail to connect if the verification fails, or if it should continue
  302. * anyway. In the latter case the result of the verification is checked with
  303. * SSL_get_verify_result() below. */
  304. SSL_CTX_set_verify(ssl_ctx, conn->ssl_config.verifypeer ?
  305. SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
  306. /* give application a chance to interfere with SSL set up. */
  307. if(data->set.ssl.fsslctx) {
  308. Curl_set_in_callback(data, true);
  309. result = (*data->set.ssl.fsslctx)(data, ssl_ctx,
  310. data->set.ssl.fsslctxp);
  311. Curl_set_in_callback(data, false);
  312. if(result) {
  313. failf(data, "error signaled by ssl ctx callback");
  314. goto out;
  315. }
  316. }
  317. result = CURLE_OK;
  318. out:
  319. *pssl_ctx = result? NULL : ssl_ctx;
  320. if(result && ssl_ctx)
  321. SSL_CTX_free(ssl_ctx);
  322. return result;
  323. }
  324. static CURLcode quic_set_client_cert(struct Curl_cfilter *cf,
  325. struct Curl_easy *data)
  326. {
  327. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  328. SSL_CTX *ssl_ctx = ctx->sslctx;
  329. const struct ssl_config_data *ssl_config;
  330. ssl_config = Curl_ssl_get_config(data, FIRSTSOCKET);
  331. DEBUGASSERT(ssl_config);
  332. if(ssl_config->primary.clientcert || ssl_config->primary.cert_blob
  333. || ssl_config->cert_type) {
  334. return Curl_ossl_set_client_cert(
  335. data, ssl_ctx, ssl_config->primary.clientcert,
  336. ssl_config->primary.cert_blob, ssl_config->cert_type,
  337. ssl_config->key, ssl_config->key_blob,
  338. ssl_config->key_type, ssl_config->key_passwd);
  339. }
  340. return CURLE_OK;
  341. }
  342. /** SSL callbacks ***/
  343. static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
  344. struct Curl_easy *data)
  345. {
  346. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  347. const uint8_t *alpn = NULL;
  348. size_t alpnlen = 0;
  349. (void)data;
  350. DEBUGASSERT(!ctx->ssl);
  351. ctx->ssl = SSL_new(ctx->sslctx);
  352. SSL_set_app_data(ctx->ssl, &ctx->conn_ref);
  353. SSL_set_connect_state(ctx->ssl);
  354. SSL_set_quic_use_legacy_codepoint(ctx->ssl, 0);
  355. alpn = (const uint8_t *)H3_ALPN_H3_29 H3_ALPN_H3;
  356. alpnlen = sizeof(H3_ALPN_H3_29) - 1 + sizeof(H3_ALPN_H3) - 1;
  357. if(alpn)
  358. SSL_set_alpn_protos(ctx->ssl, alpn, (int)alpnlen);
  359. /* set SNI */
  360. SSL_set_tlsext_host_name(ctx->ssl, cf->conn->host.name);
  361. return CURLE_OK;
  362. }
  363. #elif defined(USE_GNUTLS)
  364. static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
  365. struct Curl_easy *data)
  366. {
  367. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  368. CURLcode result;
  369. gnutls_datum_t alpn[2];
  370. /* this will need some attention when HTTPS proxy over QUIC get fixed */
  371. const char * const hostname = cf->conn->host.name;
  372. long * const pverifyresult = &data->set.ssl.certverifyresult;
  373. int rc;
  374. DEBUGASSERT(ctx->gtls == NULL);
  375. ctx->gtls = calloc(1, sizeof(*(ctx->gtls)));
  376. if(!ctx->gtls)
  377. return CURLE_OUT_OF_MEMORY;
  378. result = gtls_client_init(data, &cf->conn->ssl_config, &data->set.ssl,
  379. hostname, ctx->gtls, pverifyresult);
  380. if(result)
  381. return result;
  382. gnutls_session_set_ptr(ctx->gtls->session, &ctx->conn_ref);
  383. if(ngtcp2_crypto_gnutls_configure_client_session(ctx->gtls->session) != 0) {
  384. DEBUGF(LOG_CF(data, cf,
  385. "ngtcp2_crypto_gnutls_configure_client_session failed\n"));
  386. return CURLE_QUIC_CONNECT_ERROR;
  387. }
  388. rc = gnutls_priority_set_direct(ctx->gtls->session, QUIC_PRIORITY, NULL);
  389. if(rc < 0) {
  390. DEBUGF(LOG_CF(data, cf, "gnutls_priority_set_direct failed: %s\n",
  391. gnutls_strerror(rc)));
  392. return CURLE_QUIC_CONNECT_ERROR;
  393. }
  394. /* Open the file if a TLS or QUIC backend has not done this before. */
  395. Curl_tls_keylog_open();
  396. if(Curl_tls_keylog_enabled()) {
  397. gnutls_session_set_keylog_function(ctx->gtls->session, keylog_callback);
  398. }
  399. /* strip the first byte (the length) from NGHTTP3_ALPN_H3 */
  400. alpn[0].data = (unsigned char *)H3_ALPN_H3_29 + 1;
  401. alpn[0].size = sizeof(H3_ALPN_H3_29) - 2;
  402. alpn[1].data = (unsigned char *)H3_ALPN_H3 + 1;
  403. alpn[1].size = sizeof(H3_ALPN_H3) - 2;
  404. gnutls_alpn_set_protocols(ctx->gtls->session,
  405. alpn, 2, GNUTLS_ALPN_MANDATORY);
  406. return CURLE_OK;
  407. }
  408. #elif defined(USE_WOLFSSL)
  409. static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx,
  410. struct Curl_cfilter *cf, struct Curl_easy *data)
  411. {
  412. struct connectdata *conn = cf->conn;
  413. CURLcode result = CURLE_FAILED_INIT;
  414. WOLFSSL_CTX *ssl_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
  415. if(!ssl_ctx) {
  416. result = CURLE_OUT_OF_MEMORY;
  417. goto out;
  418. }
  419. if(ngtcp2_crypto_wolfssl_configure_client_context(ssl_ctx) != 0) {
  420. failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed");
  421. goto out;
  422. }
  423. wolfSSL_CTX_set_default_verify_paths(ssl_ctx);
  424. if(wolfSSL_CTX_set_cipher_list(ssl_ctx, QUIC_CIPHERS) != 1) {
  425. char error_buffer[256];
  426. ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer));
  427. failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer);
  428. goto out;
  429. }
  430. if(wolfSSL_CTX_set1_groups_list(ssl_ctx, (char *)QUIC_GROUPS) != 1) {
  431. failf(data, "SSL_CTX_set1_groups_list failed");
  432. goto out;
  433. }
  434. /* Open the file if a TLS or QUIC backend has not done this before. */
  435. Curl_tls_keylog_open();
  436. if(Curl_tls_keylog_enabled()) {
  437. #if defined(HAVE_SECRET_CALLBACK)
  438. wolfSSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
  439. #else
  440. failf(data, "wolfSSL was built without keylog callback");
  441. goto out;
  442. #endif
  443. }
  444. if(conn->ssl_config.verifypeer) {
  445. const char * const ssl_cafile = conn->ssl_config.CAfile;
  446. const char * const ssl_capath = conn->ssl_config.CApath;
  447. wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
  448. if(conn->ssl_config.CAfile || conn->ssl_config.CApath) {
  449. /* tell wolfSSL where to find CA certificates that are used to verify
  450. the server's certificate. */
  451. if(!wolfSSL_CTX_load_verify_locations(ssl_ctx, ssl_cafile, ssl_capath)) {
  452. /* Fail if we insist on successfully verifying the server. */
  453. failf(data, "error setting certificate verify locations:"
  454. " CAfile: %s CApath: %s",
  455. ssl_cafile ? ssl_cafile : "none",
  456. ssl_capath ? ssl_capath : "none");
  457. goto out;
  458. }
  459. infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
  460. infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
  461. }
  462. #ifdef CURL_CA_FALLBACK
  463. else {
  464. /* verifying the peer without any CA certificates won't work so
  465. use wolfssl's built-in default as fallback */
  466. wolfSSL_CTX_set_default_verify_paths(ssl_ctx);
  467. }
  468. #endif
  469. }
  470. else {
  471. wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
  472. }
  473. /* give application a chance to interfere with SSL set up. */
  474. if(data->set.ssl.fsslctx) {
  475. Curl_set_in_callback(data, true);
  476. result = (*data->set.ssl.fsslctx)(data, ssl_ctx,
  477. data->set.ssl.fsslctxp);
  478. Curl_set_in_callback(data, false);
  479. if(result) {
  480. failf(data, "error signaled by ssl ctx callback");
  481. goto out;
  482. }
  483. }
  484. result = CURLE_OK;
  485. out:
  486. *pssl_ctx = result? NULL : ssl_ctx;
  487. if(result && ssl_ctx)
  488. SSL_CTX_free(ssl_ctx);
  489. return result;
  490. }
  491. /** SSL callbacks ***/
  492. static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
  493. struct Curl_easy *data)
  494. {
  495. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  496. const uint8_t *alpn = NULL;
  497. size_t alpnlen = 0;
  498. /* this will need some attention when HTTPS proxy over QUIC get fixed */
  499. const char * const hostname = cf->conn->host.name;
  500. (void)data;
  501. DEBUGASSERT(!ctx->ssl);
  502. ctx->ssl = wolfSSL_new(ctx->sslctx);
  503. wolfSSL_set_app_data(ctx->ssl, &ctx->conn_ref);
  504. wolfSSL_set_connect_state(ctx->ssl);
  505. wolfSSL_set_quic_use_legacy_codepoint(ctx->ssl, 0);
  506. alpn = (const uint8_t *)H3_ALPN_H3_29 H3_ALPN_H3;
  507. alpnlen = sizeof(H3_ALPN_H3_29) - 1 + sizeof(H3_ALPN_H3) - 1;
  508. if(alpn)
  509. wolfSSL_set_alpn_protos(ctx->ssl, alpn, (int)alpnlen);
  510. /* set SNI */
  511. wolfSSL_UseSNI(ctx->ssl, WOLFSSL_SNI_HOST_NAME,
  512. hostname, (unsigned short)strlen(hostname));
  513. return CURLE_OK;
  514. }
  515. #endif /* defined(USE_WOLFSSL) */
  516. static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data)
  517. {
  518. (void)user_data;
  519. (void)tconn;
  520. return 0;
  521. }
  522. static void report_consumed_data(struct Curl_cfilter *cf,
  523. struct Curl_easy *data,
  524. size_t consumed)
  525. {
  526. struct HTTP *stream = data->req.p.http;
  527. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  528. /* the HTTP/1.1 response headers are written to the buffer, but
  529. * consuming those does not count against flow control. */
  530. if(stream->recv_buf_nonflow) {
  531. if(consumed >= stream->recv_buf_nonflow) {
  532. consumed -= stream->recv_buf_nonflow;
  533. stream->recv_buf_nonflow = 0;
  534. }
  535. else {
  536. stream->recv_buf_nonflow -= consumed;
  537. consumed = 0;
  538. }
  539. }
  540. if(consumed > 0) {
  541. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] consumed %zu DATA bytes",
  542. stream->stream3_id, consumed));
  543. ngtcp2_conn_extend_max_stream_offset(ctx->qconn, stream->stream3_id,
  544. consumed);
  545. ngtcp2_conn_extend_max_offset(ctx->qconn, consumed);
  546. }
  547. if(!stream->closed && data->state.drain
  548. && !stream->memlen
  549. && !Curl_dyn_len(&stream->overflow)) {
  550. /* nothing buffered any more */
  551. data->state.drain = 0;
  552. }
  553. }
  554. static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
  555. int64_t stream_id, uint64_t offset,
  556. const uint8_t *buf, size_t buflen,
  557. void *user_data, void *stream_user_data)
  558. {
  559. struct Curl_cfilter *cf = user_data;
  560. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  561. nghttp3_ssize nconsumed;
  562. int fin = (flags & NGTCP2_STREAM_DATA_FLAG_FIN) ? 1 : 0;
  563. struct Curl_easy *data = stream_user_data;
  564. (void)offset;
  565. (void)data;
  566. nconsumed =
  567. nghttp3_conn_read_stream(ctx->h3conn, stream_id, buf, buflen, fin);
  568. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] read_stream(len=%zu) -> %zd",
  569. stream_id, buflen, nconsumed));
  570. if(nconsumed < 0) {
  571. ngtcp2_connection_close_error_set_application_error(
  572. &ctx->last_error,
  573. nghttp3_err_infer_quic_app_error_code((int)nconsumed), NULL, 0);
  574. return NGTCP2_ERR_CALLBACK_FAILURE;
  575. }
  576. /* number of bytes inside buflen which consists of framing overhead
  577. * including QPACK HEADERS. In other words, it does not consume payload of
  578. * DATA frame. */
  579. ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed);
  580. ngtcp2_conn_extend_max_offset(tconn, nconsumed);
  581. return 0;
  582. }
  583. static int
  584. cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id,
  585. uint64_t offset, uint64_t datalen, void *user_data,
  586. void *stream_user_data)
  587. {
  588. struct Curl_cfilter *cf = user_data;
  589. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  590. int rv;
  591. (void)stream_id;
  592. (void)tconn;
  593. (void)offset;
  594. (void)datalen;
  595. (void)stream_user_data;
  596. rv = nghttp3_conn_add_ack_offset(ctx->h3conn, stream_id, datalen);
  597. if(rv) {
  598. return NGTCP2_ERR_CALLBACK_FAILURE;
  599. }
  600. return 0;
  601. }
  602. static int cb_stream_close(ngtcp2_conn *tconn, uint32_t flags,
  603. int64_t stream3_id, uint64_t app_error_code,
  604. void *user_data, void *stream_user_data)
  605. {
  606. struct Curl_cfilter *cf = user_data;
  607. struct Curl_easy *data = stream_user_data;
  608. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  609. int rv;
  610. (void)tconn;
  611. (void)data;
  612. /* stream is closed... */
  613. if(!(flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET)) {
  614. app_error_code = NGHTTP3_H3_NO_ERROR;
  615. }
  616. rv = nghttp3_conn_close_stream(ctx->h3conn, stream3_id,
  617. app_error_code);
  618. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] quic close(err=%"
  619. PRIu64 ") -> %d", stream3_id, app_error_code, rv));
  620. if(rv) {
  621. ngtcp2_connection_close_error_set_application_error(
  622. &ctx->last_error, nghttp3_err_infer_quic_app_error_code(rv), NULL, 0);
  623. return NGTCP2_ERR_CALLBACK_FAILURE;
  624. }
  625. return 0;
  626. }
  627. static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id,
  628. uint64_t final_size, uint64_t app_error_code,
  629. void *user_data, void *stream_user_data)
  630. {
  631. struct Curl_cfilter *cf = user_data;
  632. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  633. struct Curl_easy *data = stream_user_data;
  634. int rv;
  635. (void)tconn;
  636. (void)final_size;
  637. (void)app_error_code;
  638. (void)data;
  639. rv = nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream_id);
  640. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] reset -> %d", stream_id, rv));
  641. if(rv) {
  642. return NGTCP2_ERR_CALLBACK_FAILURE;
  643. }
  644. return 0;
  645. }
  646. static int cb_stream_stop_sending(ngtcp2_conn *tconn, int64_t stream_id,
  647. uint64_t app_error_code, void *user_data,
  648. void *stream_user_data)
  649. {
  650. struct Curl_cfilter *cf = user_data;
  651. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  652. int rv;
  653. (void)tconn;
  654. (void)app_error_code;
  655. (void)stream_user_data;
  656. rv = nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream_id);
  657. if(rv) {
  658. return NGTCP2_ERR_CALLBACK_FAILURE;
  659. }
  660. return 0;
  661. }
  662. static int cb_extend_max_local_streams_bidi(ngtcp2_conn *tconn,
  663. uint64_t max_streams,
  664. void *user_data)
  665. {
  666. (void)tconn;
  667. (void)max_streams;
  668. (void)user_data;
  669. return 0;
  670. }
  671. static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id,
  672. uint64_t max_data, void *user_data,
  673. void *stream_user_data)
  674. {
  675. struct Curl_cfilter *cf = user_data;
  676. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  677. int rv;
  678. (void)tconn;
  679. (void)max_data;
  680. (void)stream_user_data;
  681. rv = nghttp3_conn_unblock_stream(ctx->h3conn, stream_id);
  682. if(rv) {
  683. return NGTCP2_ERR_CALLBACK_FAILURE;
  684. }
  685. return 0;
  686. }
  687. static void cb_rand(uint8_t *dest, size_t destlen,
  688. const ngtcp2_rand_ctx *rand_ctx)
  689. {
  690. CURLcode result;
  691. (void)rand_ctx;
  692. result = Curl_rand(NULL, dest, destlen);
  693. if(result) {
  694. /* cb_rand is only used for non-cryptographic context. If Curl_rand
  695. failed, just fill 0 and call it *random*. */
  696. memset(dest, 0, destlen);
  697. }
  698. }
  699. static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
  700. uint8_t *token, size_t cidlen,
  701. void *user_data)
  702. {
  703. CURLcode result;
  704. (void)tconn;
  705. (void)user_data;
  706. result = Curl_rand(NULL, cid->data, cidlen);
  707. if(result)
  708. return NGTCP2_ERR_CALLBACK_FAILURE;
  709. cid->datalen = cidlen;
  710. result = Curl_rand(NULL, token, NGTCP2_STATELESS_RESET_TOKENLEN);
  711. if(result)
  712. return NGTCP2_ERR_CALLBACK_FAILURE;
  713. return 0;
  714. }
  715. static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_crypto_level level,
  716. void *user_data)
  717. {
  718. struct Curl_cfilter *cf = user_data;
  719. (void)tconn;
  720. if(level != NGTCP2_CRYPTO_LEVEL_APPLICATION) {
  721. return 0;
  722. }
  723. if(init_ngh3_conn(cf) != CURLE_OK) {
  724. return NGTCP2_ERR_CALLBACK_FAILURE;
  725. }
  726. return 0;
  727. }
  728. static ngtcp2_callbacks ng_callbacks = {
  729. ngtcp2_crypto_client_initial_cb,
  730. NULL, /* recv_client_initial */
  731. ngtcp2_crypto_recv_crypto_data_cb,
  732. cb_handshake_completed,
  733. NULL, /* recv_version_negotiation */
  734. ngtcp2_crypto_encrypt_cb,
  735. ngtcp2_crypto_decrypt_cb,
  736. ngtcp2_crypto_hp_mask_cb,
  737. cb_recv_stream_data,
  738. cb_acked_stream_data_offset,
  739. NULL, /* stream_open */
  740. cb_stream_close,
  741. NULL, /* recv_stateless_reset */
  742. ngtcp2_crypto_recv_retry_cb,
  743. cb_extend_max_local_streams_bidi,
  744. NULL, /* extend_max_local_streams_uni */
  745. cb_rand,
  746. cb_get_new_connection_id,
  747. NULL, /* remove_connection_id */
  748. ngtcp2_crypto_update_key_cb, /* update_key */
  749. NULL, /* path_validation */
  750. NULL, /* select_preferred_addr */
  751. cb_stream_reset,
  752. NULL, /* extend_max_remote_streams_bidi */
  753. NULL, /* extend_max_remote_streams_uni */
  754. cb_extend_max_stream_data,
  755. NULL, /* dcid_status */
  756. NULL, /* handshake_confirmed */
  757. NULL, /* recv_new_token */
  758. ngtcp2_crypto_delete_crypto_aead_ctx_cb,
  759. ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
  760. NULL, /* recv_datagram */
  761. NULL, /* ack_datagram */
  762. NULL, /* lost_datagram */
  763. ngtcp2_crypto_get_path_challenge_data_cb,
  764. cb_stream_stop_sending,
  765. NULL, /* version_negotiation */
  766. cb_recv_rx_key,
  767. NULL, /* recv_tx_key */
  768. NULL, /* early_data_rejected */
  769. };
  770. static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
  771. struct Curl_easy *data,
  772. curl_socket_t *socks)
  773. {
  774. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  775. struct SingleRequest *k = &data->req;
  776. int rv = GETSOCK_BLANK;
  777. struct HTTP *stream = data->req.p.http;
  778. struct cf_call_data save;
  779. CF_DATA_SAVE(save, cf, data);
  780. socks[0] = ctx->q.sockfd;
  781. /* in an HTTP/3 connection we can basically always get a frame so we should
  782. always be ready for one */
  783. rv |= GETSOCK_READSOCK(0);
  784. /* we're still uploading or the HTTP/2 layer wants to send data */
  785. if((k->keepon & KEEP_SENDBITS) == KEEP_SEND &&
  786. (!stream->h3out || stream->h3out->used < H3_SEND_SIZE) &&
  787. ngtcp2_conn_get_cwnd_left(ctx->qconn) &&
  788. ngtcp2_conn_get_max_data_left(ctx->qconn) &&
  789. nghttp3_conn_is_stream_writable(ctx->h3conn, stream->stream3_id))
  790. rv |= GETSOCK_WRITESOCK(0);
  791. DEBUGF(LOG_CF(data, cf, "get_select_socks -> %x (sock=%d)",
  792. rv, (int)socks[0]));
  793. CF_DATA_RESTORE(cf, save);
  794. return rv;
  795. }
  796. static void notify_drain(struct Curl_cfilter *cf,
  797. struct Curl_easy *data)
  798. {
  799. (void)cf;
  800. if(!data->state.drain) {
  801. data->state.drain = 1;
  802. Curl_expire(data, 0, EXPIRE_RUN_NOW);
  803. }
  804. }
  805. static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
  806. uint64_t app_error_code, void *user_data,
  807. void *stream_user_data)
  808. {
  809. struct Curl_cfilter *cf = user_data;
  810. struct Curl_easy *data = stream_user_data;
  811. struct HTTP *stream = data->req.p.http;
  812. (void)conn;
  813. (void)stream_id;
  814. (void)app_error_code;
  815. (void)cf;
  816. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] h3 close(err=%" PRIx64 ")",
  817. stream_id, app_error_code));
  818. stream->closed = TRUE;
  819. stream->error3 = app_error_code;
  820. if(app_error_code == NGHTTP3_H3_INTERNAL_ERROR) {
  821. /* TODO: we do not get a specific error when the remote end closed
  822. * the response before it was complete. */
  823. stream->reset = TRUE;
  824. }
  825. notify_drain(cf, data);
  826. return 0;
  827. }
  828. /*
  829. * write_resp_raw() copies response data in raw format to the `data`'s
  830. * receive buffer. If not enough space is available, it appends to the
  831. * `data`'s overflow buffer.
  832. */
  833. static CURLcode write_resp_raw(struct Curl_cfilter *cf,
  834. struct Curl_easy *data,
  835. const void *mem, size_t memlen,
  836. bool flow)
  837. {
  838. struct HTTP *stream = data->req.p.http;
  839. CURLcode result = CURLE_OK;
  840. const char *buf = mem;
  841. size_t ncopy = memlen;
  842. /* copy as much as possible to the receive buffer */
  843. if(stream->len) {
  844. size_t len = CURLMIN(ncopy, stream->len);
  845. memcpy(stream->mem + stream->memlen, buf, len);
  846. stream->len -= len;
  847. stream->memlen += len;
  848. buf += len;
  849. ncopy -= len;
  850. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] resp_raw: added %zu bytes"
  851. " to data buffer", stream->stream3_id, len));
  852. }
  853. /* copy the rest to the overflow buffer */
  854. if(ncopy) {
  855. result = Curl_dyn_addn(&stream->overflow, buf, ncopy);
  856. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] resp_raw: added %zu bytes"
  857. " to overflow buffer -> %d",
  858. stream->stream3_id, ncopy, result));
  859. notify_drain(cf, data);
  860. }
  861. if(!flow)
  862. stream->recv_buf_nonflow += memlen;
  863. if(CF_DATA_CURRENT(cf) != data) {
  864. notify_drain(cf, data);
  865. }
  866. return result;
  867. }
  868. static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
  869. const uint8_t *buf, size_t buflen,
  870. void *user_data, void *stream_user_data)
  871. {
  872. struct Curl_cfilter *cf = user_data;
  873. struct Curl_easy *data = stream_user_data;
  874. CURLcode result;
  875. (void)conn;
  876. (void)stream3_id;
  877. result = write_resp_raw(cf, data, buf, buflen, TRUE);
  878. return result? -1 : 0;
  879. }
  880. static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream3_id,
  881. size_t consumed, void *user_data,
  882. void *stream_user_data)
  883. {
  884. struct Curl_cfilter *cf = user_data;
  885. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  886. (void)conn;
  887. (void)stream_user_data;
  888. /* nghttp3 has consumed bytes on the QUIC stream and we need to
  889. * tell the QUIC connection to increase its flow control */
  890. ngtcp2_conn_extend_max_stream_offset(ctx->qconn, stream3_id, consumed);
  891. ngtcp2_conn_extend_max_offset(ctx->qconn, consumed);
  892. return 0;
  893. }
  894. /* Decode HTTP status code. Returns -1 if no valid status code was
  895. decoded. (duplicate from http2.c) */
  896. static int decode_status_code(const uint8_t *value, size_t len)
  897. {
  898. int i;
  899. int res;
  900. if(len != 3) {
  901. return -1;
  902. }
  903. res = 0;
  904. for(i = 0; i < 3; ++i) {
  905. char c = value[i];
  906. if(c < '0' || c > '9') {
  907. return -1;
  908. }
  909. res *= 10;
  910. res += c - '0';
  911. }
  912. return res;
  913. }
  914. static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
  915. int fin, void *user_data, void *stream_user_data)
  916. {
  917. struct Curl_cfilter *cf = user_data;
  918. struct Curl_easy *data = stream_user_data;
  919. struct HTTP *stream = data->req.p.http;
  920. CURLcode result = CURLE_OK;
  921. (void)conn;
  922. (void)stream_id;
  923. (void)fin;
  924. (void)cf;
  925. /* add a CRLF only if we've received some headers */
  926. if(stream->firstheader) {
  927. result = write_resp_raw(cf, data, "\r\n", 2, FALSE);
  928. if(result) {
  929. return -1;
  930. }
  931. }
  932. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] end_headers(status_code=%d",
  933. stream_id, stream->status_code));
  934. if(stream->status_code / 100 != 1) {
  935. stream->bodystarted = TRUE;
  936. }
  937. return 0;
  938. }
  939. static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
  940. int32_t token, nghttp3_rcbuf *name,
  941. nghttp3_rcbuf *value, uint8_t flags,
  942. void *user_data, void *stream_user_data)
  943. {
  944. struct Curl_cfilter *cf = user_data;
  945. nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
  946. nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
  947. struct Curl_easy *data = stream_user_data;
  948. struct HTTP *stream = data->req.p.http;
  949. CURLcode result = CURLE_OK;
  950. (void)conn;
  951. (void)stream_id;
  952. (void)token;
  953. (void)flags;
  954. (void)cf;
  955. if(token == NGHTTP3_QPACK_TOKEN__STATUS) {
  956. char line[14]; /* status line is always 13 characters long */
  957. size_t ncopy;
  958. DEBUGASSERT(!stream->firstheader);
  959. stream->status_code = decode_status_code(h3val.base, h3val.len);
  960. DEBUGASSERT(stream->status_code != -1);
  961. ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n",
  962. stream->status_code);
  963. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] status: %s",
  964. stream_id, line));
  965. result = write_resp_raw(cf, data, line, ncopy, FALSE);
  966. if(result) {
  967. return -1;
  968. }
  969. stream->firstheader = TRUE;
  970. }
  971. else {
  972. /* store as an HTTP1-style header */
  973. DEBUGASSERT(stream->firstheader);
  974. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] header: %.*s: %.*s",
  975. stream_id, (int)h3name.len, h3name.base,
  976. (int)h3val.len, h3val.base));
  977. result = write_resp_raw(cf, data, h3name.base, h3name.len, FALSE);
  978. if(result) {
  979. return -1;
  980. }
  981. result = write_resp_raw(cf, data, ": ", 2, FALSE);
  982. if(result) {
  983. return -1;
  984. }
  985. result = write_resp_raw(cf, data, h3val.base, h3val.len, FALSE);
  986. if(result) {
  987. return -1;
  988. }
  989. result = write_resp_raw(cf, data, "\r\n", 2, FALSE);
  990. if(result) {
  991. return -1;
  992. }
  993. }
  994. return 0;
  995. }
  996. static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id,
  997. uint64_t app_error_code, void *user_data,
  998. void *stream_user_data)
  999. {
  1000. struct Curl_cfilter *cf = user_data;
  1001. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1002. int rv;
  1003. (void)conn;
  1004. (void)stream_user_data;
  1005. rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, stream_id, app_error_code);
  1006. if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
  1007. return NGTCP2_ERR_CALLBACK_FAILURE;
  1008. }
  1009. return 0;
  1010. }
  1011. static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t stream_id,
  1012. uint64_t app_error_code, void *user_data,
  1013. void *stream_user_data) {
  1014. struct Curl_cfilter *cf = user_data;
  1015. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1016. struct Curl_easy *data = stream_user_data;
  1017. int rv;
  1018. (void)conn;
  1019. (void)data;
  1020. rv = ngtcp2_conn_shutdown_stream_write(ctx->qconn, stream_id,
  1021. app_error_code);
  1022. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] reset -> %d", stream_id, rv));
  1023. if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
  1024. return NGTCP2_ERR_CALLBACK_FAILURE;
  1025. }
  1026. return 0;
  1027. }
  1028. static nghttp3_callbacks ngh3_callbacks = {
  1029. cb_h3_acked_stream_data, /* acked_stream_data */
  1030. cb_h3_stream_close,
  1031. cb_h3_recv_data,
  1032. cb_h3_deferred_consume,
  1033. NULL, /* begin_headers */
  1034. cb_h3_recv_header,
  1035. cb_h3_end_headers,
  1036. NULL, /* begin_trailers */
  1037. cb_h3_recv_header,
  1038. NULL, /* end_trailers */
  1039. cb_h3_stop_sending,
  1040. NULL, /* end_stream */
  1041. cb_h3_reset_stream,
  1042. NULL /* shutdown */
  1043. };
  1044. static int init_ngh3_conn(struct Curl_cfilter *cf)
  1045. {
  1046. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1047. CURLcode result;
  1048. int rc;
  1049. int64_t ctrl_stream_id, qpack_enc_stream_id, qpack_dec_stream_id;
  1050. if(ngtcp2_conn_get_max_local_streams_uni(ctx->qconn) < 3) {
  1051. return CURLE_QUIC_CONNECT_ERROR;
  1052. }
  1053. nghttp3_settings_default(&ctx->h3settings);
  1054. rc = nghttp3_conn_client_new(&ctx->h3conn,
  1055. &ngh3_callbacks,
  1056. &ctx->h3settings,
  1057. nghttp3_mem_default(),
  1058. cf);
  1059. if(rc) {
  1060. result = CURLE_OUT_OF_MEMORY;
  1061. goto fail;
  1062. }
  1063. rc = ngtcp2_conn_open_uni_stream(ctx->qconn, &ctrl_stream_id, NULL);
  1064. if(rc) {
  1065. result = CURLE_QUIC_CONNECT_ERROR;
  1066. goto fail;
  1067. }
  1068. rc = nghttp3_conn_bind_control_stream(ctx->h3conn, ctrl_stream_id);
  1069. if(rc) {
  1070. result = CURLE_QUIC_CONNECT_ERROR;
  1071. goto fail;
  1072. }
  1073. rc = ngtcp2_conn_open_uni_stream(ctx->qconn, &qpack_enc_stream_id, NULL);
  1074. if(rc) {
  1075. result = CURLE_QUIC_CONNECT_ERROR;
  1076. goto fail;
  1077. }
  1078. rc = ngtcp2_conn_open_uni_stream(ctx->qconn, &qpack_dec_stream_id, NULL);
  1079. if(rc) {
  1080. result = CURLE_QUIC_CONNECT_ERROR;
  1081. goto fail;
  1082. }
  1083. rc = nghttp3_conn_bind_qpack_streams(ctx->h3conn, qpack_enc_stream_id,
  1084. qpack_dec_stream_id);
  1085. if(rc) {
  1086. result = CURLE_QUIC_CONNECT_ERROR;
  1087. goto fail;
  1088. }
  1089. return CURLE_OK;
  1090. fail:
  1091. return result;
  1092. }
  1093. static void drain_overflow_buffer(struct Curl_cfilter *cf,
  1094. struct Curl_easy *data)
  1095. {
  1096. struct HTTP *stream = data->req.p.http;
  1097. size_t overlen = Curl_dyn_len(&stream->overflow);
  1098. size_t ncopy = CURLMIN(overlen, stream->len);
  1099. (void)cf;
  1100. if(ncopy > 0) {
  1101. memcpy(stream->mem + stream->memlen,
  1102. Curl_dyn_ptr(&stream->overflow), ncopy);
  1103. stream->len -= ncopy;
  1104. stream->memlen += ncopy;
  1105. if(ncopy != overlen)
  1106. /* make the buffer only keep the tail */
  1107. (void)Curl_dyn_tail(&stream->overflow, overlen - ncopy);
  1108. else {
  1109. Curl_dyn_reset(&stream->overflow);
  1110. }
  1111. }
  1112. }
  1113. static ssize_t recv_closed_stream(struct Curl_cfilter *cf,
  1114. struct Curl_easy *data,
  1115. CURLcode *err)
  1116. {
  1117. struct HTTP *stream = data->req.p.http;
  1118. ssize_t nread = -1;
  1119. (void)cf;
  1120. if(stream->reset) {
  1121. failf(data,
  1122. "HTTP/3 stream %" PRId64 " reset by server", stream->stream3_id);
  1123. *err = CURLE_PARTIAL_FILE;
  1124. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_recv, was reset -> %d",
  1125. stream->stream3_id, *err));
  1126. goto out;
  1127. }
  1128. else if(stream->error3 != NGHTTP3_H3_NO_ERROR) {
  1129. failf(data,
  1130. "HTTP/3 stream %" PRId64 " was not closed cleanly: (err 0x%" PRIx64
  1131. ")",
  1132. stream->stream3_id, stream->error3);
  1133. *err = CURLE_HTTP3;
  1134. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_recv, closed uncleanly"
  1135. " -> %d", stream->stream3_id, *err));
  1136. goto out;
  1137. }
  1138. if(!stream->bodystarted) {
  1139. failf(data,
  1140. "HTTP/3 stream %" PRId64 " was closed cleanly, but before getting"
  1141. " all response header fields, treated as error",
  1142. stream->stream3_id);
  1143. *err = CURLE_HTTP3;
  1144. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_recv, closed incomplete"
  1145. " -> %d", stream->stream3_id, *err));
  1146. goto out;
  1147. }
  1148. else {
  1149. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_recv, closed ok"
  1150. " -> %d", stream->stream3_id, *err));
  1151. }
  1152. *err = CURLE_OK;
  1153. nread = 0;
  1154. out:
  1155. data->state.drain = 0;
  1156. return nread;
  1157. }
  1158. /* incoming data frames on the h3 stream */
  1159. static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  1160. char *buf, size_t len, CURLcode *err)
  1161. {
  1162. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1163. struct HTTP *stream = data->req.p.http;
  1164. ssize_t nread = -1;
  1165. struct cf_call_data save;
  1166. (void)ctx;
  1167. CF_DATA_SAVE(save, cf, data);
  1168. DEBUGASSERT(cf->connected);
  1169. DEBUGASSERT(ctx);
  1170. DEBUGASSERT(ctx->qconn);
  1171. DEBUGASSERT(ctx->h3conn);
  1172. *err = CURLE_OK;
  1173. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_recv(len=%zu) start",
  1174. stream->stream3_id, len));
  1175. /* TODO: this implementation of response DATA buffering is fragile.
  1176. * It makes the following assumptions:
  1177. * - the `buf` passed here has the same lifetime as the easy handle
  1178. * - data returned in `buf` from this call is immediately used and `buf`
  1179. * can be overwritten during any handling of other transfers at
  1180. * this connection.
  1181. */
  1182. if(!stream->memlen) {
  1183. /* `buf` was not known before or is currently not used by stream,
  1184. * assign it (again). */
  1185. stream->mem = buf;
  1186. stream->len = len;
  1187. }
  1188. /* if there's data in the overflow buffer, move as much
  1189. as possible to the receive buffer now */
  1190. drain_overflow_buffer(cf, data);
  1191. if(cf_process_ingress(cf, data)) {
  1192. *err = CURLE_RECV_ERROR;
  1193. nread = -1;
  1194. goto out;
  1195. }
  1196. if(stream->memlen) {
  1197. nread = stream->memlen;
  1198. /* reset to allow more data to come */
  1199. /* TODO: very brittle buffer use design:
  1200. * - stream->mem has now `nread` bytes of response data
  1201. * - we assume that the caller will use those immediately and
  1202. * we can overwrite that with new data on our next invocation from
  1203. * anywhere.
  1204. */
  1205. stream->mem = buf;
  1206. stream->memlen = 0;
  1207. stream->len = len;
  1208. /* extend the stream window with the data we're consuming and send out
  1209. any additional packets to tell the server that we can receive more */
  1210. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_recv -> %zd bytes",
  1211. stream->stream3_id, nread));
  1212. report_consumed_data(cf, data, nread);
  1213. if(cf_flush_egress(cf, data)) {
  1214. *err = CURLE_SEND_ERROR;
  1215. nread = -1;
  1216. }
  1217. goto out;
  1218. }
  1219. if(stream->closed) {
  1220. nread = recv_closed_stream(cf, data, err);
  1221. goto out;
  1222. }
  1223. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_recv -> EAGAIN",
  1224. stream->stream3_id));
  1225. *err = CURLE_AGAIN;
  1226. nread = -1;
  1227. out:
  1228. if(cf_flush_egress(cf, data)) {
  1229. *err = CURLE_SEND_ERROR;
  1230. nread = -1;
  1231. goto out;
  1232. }
  1233. CF_DATA_RESTORE(cf, save);
  1234. return nread;
  1235. }
  1236. /* this amount of data has now been acked on this stream */
  1237. static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
  1238. uint64_t datalen, void *user_data,
  1239. void *stream_user_data)
  1240. {
  1241. struct Curl_cfilter *cf = user_data;
  1242. struct Curl_easy *data = stream_user_data;
  1243. struct HTTP *stream = data->req.p.http;
  1244. (void)user_data;
  1245. (void)cf;
  1246. if(!data->set.postfields) {
  1247. stream->h3out->used -= datalen;
  1248. DEBUGF(LOG_CF(data, cf, "cb_h3_acked_stream_data, %"PRIu64" bytes, "
  1249. "%zd left unacked", datalen, stream->h3out->used));
  1250. DEBUGASSERT(stream->h3out->used < H3_SEND_SIZE);
  1251. if(stream->h3out->used == 0) {
  1252. int rv = nghttp3_conn_resume_stream(conn, stream_id);
  1253. if(rv) {
  1254. return NGTCP2_ERR_CALLBACK_FAILURE;
  1255. }
  1256. }
  1257. }
  1258. return 0;
  1259. }
  1260. static nghttp3_ssize cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
  1261. nghttp3_vec *vec, size_t veccnt,
  1262. uint32_t *pflags, void *user_data,
  1263. void *stream_user_data)
  1264. {
  1265. struct Curl_cfilter *cf = user_data;
  1266. struct Curl_easy *data = stream_user_data;
  1267. size_t nread;
  1268. struct HTTP *stream = data->req.p.http;
  1269. (void)cf;
  1270. (void)conn;
  1271. (void)stream_id;
  1272. (void)user_data;
  1273. (void)veccnt;
  1274. if(data->set.postfields) {
  1275. vec[0].base = data->set.postfields;
  1276. vec[0].len = data->state.infilesize;
  1277. *pflags = NGHTTP3_DATA_FLAG_EOF;
  1278. return 1;
  1279. }
  1280. if(stream->upload_len && H3_SEND_SIZE <= stream->h3out->used) {
  1281. return NGHTTP3_ERR_WOULDBLOCK;
  1282. }
  1283. nread = CURLMIN(stream->upload_len, H3_SEND_SIZE - stream->h3out->used);
  1284. if(nread > 0) {
  1285. /* nghttp3 wants us to hold on to the data until it tells us it is okay to
  1286. delete it. Append the data at the end of the h3out buffer. Since we can
  1287. only return consecutive data, copy the amount that fits and the next
  1288. part comes in next invoke. */
  1289. struct h3out *out = stream->h3out;
  1290. if(nread + out->windex > H3_SEND_SIZE)
  1291. nread = H3_SEND_SIZE - out->windex;
  1292. memcpy(&out->buf[out->windex], stream->upload_mem, nread);
  1293. /* that's the chunk we return to nghttp3 */
  1294. vec[0].base = &out->buf[out->windex];
  1295. vec[0].len = nread;
  1296. out->windex += nread;
  1297. out->used += nread;
  1298. if(out->windex == H3_SEND_SIZE)
  1299. out->windex = 0; /* wrap */
  1300. stream->upload_mem += nread;
  1301. stream->upload_len -= nread;
  1302. if(data->state.infilesize != -1) {
  1303. stream->upload_left -= nread;
  1304. if(!stream->upload_left)
  1305. *pflags = NGHTTP3_DATA_FLAG_EOF;
  1306. }
  1307. DEBUGF(LOG_CF(data, cf, "cb_h3_readfunction %zd bytes%s (at %zd unacked)",
  1308. nread, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"",
  1309. out->used));
  1310. }
  1311. if(stream->upload_done && !stream->upload_len &&
  1312. (stream->upload_left <= 0)) {
  1313. DEBUGF(LOG_CF(data, cf, "cb_h3_readfunction sets EOF"));
  1314. *pflags = NGHTTP3_DATA_FLAG_EOF;
  1315. return nread ? 1 : 0;
  1316. }
  1317. else if(!nread) {
  1318. return NGHTTP3_ERR_WOULDBLOCK;
  1319. }
  1320. return 1;
  1321. }
  1322. /* Index where :authority header field will appear in request header
  1323. field list. */
  1324. #define AUTHORITY_DST_IDX 3
  1325. static CURLcode h3_stream_open(struct Curl_cfilter *cf,
  1326. struct Curl_easy *data,
  1327. const void *mem,
  1328. size_t len)
  1329. {
  1330. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1331. struct HTTP *stream = data->req.p.http;
  1332. size_t nheader;
  1333. CURLcode result = CURLE_OK;
  1334. nghttp3_nv *nva = NULL;
  1335. int64_t stream3_id;
  1336. int rc = 0;
  1337. struct h3out *h3out = NULL;
  1338. struct h2h3req *hreq = NULL;
  1339. rc = ngtcp2_conn_open_bidi_stream(ctx->qconn, &stream3_id, NULL);
  1340. if(rc) {
  1341. failf(data, "can get bidi streams");
  1342. goto fail;
  1343. }
  1344. stream->stream3_id = stream3_id;
  1345. stream->h3req = TRUE;
  1346. Curl_dyn_init(&stream->overflow, CURL_MAX_READ_SIZE);
  1347. stream->recv_buf_nonflow = 0;
  1348. result = Curl_pseudo_headers(data, mem, len, NULL, &hreq);
  1349. if(result)
  1350. goto fail;
  1351. nheader = hreq->entries;
  1352. nva = malloc(sizeof(nghttp3_nv) * nheader);
  1353. if(!nva) {
  1354. result = CURLE_OUT_OF_MEMORY;
  1355. goto fail;
  1356. }
  1357. else {
  1358. unsigned int i;
  1359. for(i = 0; i < nheader; i++) {
  1360. nva[i].name = (unsigned char *)hreq->header[i].name;
  1361. nva[i].namelen = hreq->header[i].namelen;
  1362. nva[i].value = (unsigned char *)hreq->header[i].value;
  1363. nva[i].valuelen = hreq->header[i].valuelen;
  1364. nva[i].flags = NGHTTP3_NV_FLAG_NONE;
  1365. }
  1366. }
  1367. switch(data->state.httpreq) {
  1368. case HTTPREQ_POST:
  1369. case HTTPREQ_POST_FORM:
  1370. case HTTPREQ_POST_MIME:
  1371. case HTTPREQ_PUT: {
  1372. nghttp3_data_reader data_reader;
  1373. if(data->state.infilesize != -1)
  1374. stream->upload_left = data->state.infilesize;
  1375. else
  1376. /* data sending without specifying the data amount up front */
  1377. stream->upload_left = -1; /* unknown, but not zero */
  1378. data_reader.read_data = cb_h3_readfunction;
  1379. h3out = calloc(sizeof(struct h3out), 1);
  1380. if(!h3out) {
  1381. result = CURLE_OUT_OF_MEMORY;
  1382. goto fail;
  1383. }
  1384. stream->h3out = h3out;
  1385. rc = nghttp3_conn_submit_request(ctx->h3conn, stream->stream3_id,
  1386. nva, nheader, &data_reader, data);
  1387. if(rc)
  1388. goto fail;
  1389. break;
  1390. }
  1391. default:
  1392. stream->upload_left = 0; /* nothing left to send */
  1393. rc = nghttp3_conn_submit_request(ctx->h3conn, stream->stream3_id,
  1394. nva, nheader, NULL, data);
  1395. if(rc)
  1396. goto fail;
  1397. break;
  1398. }
  1399. Curl_safefree(nva);
  1400. infof(data, "Using HTTP/3 Stream ID: %" PRId64 " (easy handle %p)",
  1401. stream3_id, (void *)data);
  1402. DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] opened for %s",
  1403. stream3_id, data->state.url));
  1404. Curl_pseudo_free(hreq);
  1405. return CURLE_OK;
  1406. fail:
  1407. if(rc) {
  1408. switch(rc) {
  1409. case NGHTTP3_ERR_CONN_CLOSING:
  1410. DEBUGF(LOG_CF(data, cf, "h3sid[%"PRId64"] failed to send, "
  1411. "connection is closing", stream->stream3_id));
  1412. result = CURLE_RECV_ERROR;
  1413. break;
  1414. default:
  1415. DEBUGF(LOG_CF(data, cf, "h3sid[%"PRId64"] failed to send -> %d (%s)",
  1416. stream->stream3_id, rc, ngtcp2_strerror(rc)));
  1417. result = CURLE_SEND_ERROR;
  1418. break;
  1419. }
  1420. }
  1421. free(nva);
  1422. Curl_pseudo_free(hreq);
  1423. return result;
  1424. }
  1425. static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  1426. const void *buf, size_t len, CURLcode *err)
  1427. {
  1428. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1429. ssize_t sent = 0;
  1430. struct HTTP *stream = data->req.p.http;
  1431. struct cf_call_data save;
  1432. CF_DATA_SAVE(save, cf, data);
  1433. DEBUGASSERT(cf->connected);
  1434. DEBUGASSERT(ctx->qconn);
  1435. DEBUGASSERT(ctx->h3conn);
  1436. *err = CURLE_OK;
  1437. if(stream->closed) {
  1438. *err = CURLE_HTTP3;
  1439. sent = -1;
  1440. goto out;
  1441. }
  1442. if(!stream->h3req) {
  1443. CURLcode result = h3_stream_open(cf, data, buf, len);
  1444. if(result) {
  1445. DEBUGF(LOG_CF(data, cf, "failed to open stream -> %d", result));
  1446. sent = -1;
  1447. goto out;
  1448. }
  1449. /* Assume that mem of length len only includes HTTP/1.1 style
  1450. header fields. In other words, it does not contain request
  1451. body. */
  1452. sent = len;
  1453. }
  1454. else {
  1455. DEBUGF(LOG_CF(data, cf, "ngh3_stream_send() wants to send %zd bytes",
  1456. len));
  1457. if(!stream->upload_len) {
  1458. stream->upload_mem = buf;
  1459. stream->upload_len = len;
  1460. (void)nghttp3_conn_resume_stream(ctx->h3conn, stream->stream3_id);
  1461. }
  1462. else {
  1463. *err = CURLE_AGAIN;
  1464. sent = -1;
  1465. goto out;
  1466. }
  1467. }
  1468. if(cf_flush_egress(cf, data)) {
  1469. *err = CURLE_SEND_ERROR;
  1470. sent = -1;
  1471. goto out;
  1472. }
  1473. /* Reset post upload buffer after resumed. */
  1474. if(stream->upload_mem) {
  1475. if(data->set.postfields) {
  1476. sent = len;
  1477. }
  1478. else {
  1479. sent = len - stream->upload_len;
  1480. }
  1481. stream->upload_mem = NULL;
  1482. stream->upload_len = 0;
  1483. if(sent == 0) {
  1484. *err = CURLE_AGAIN;
  1485. sent = -1;
  1486. goto out;
  1487. }
  1488. }
  1489. out:
  1490. CF_DATA_RESTORE(cf, save);
  1491. return sent;
  1492. }
  1493. static CURLcode qng_verify_peer(struct Curl_cfilter *cf,
  1494. struct Curl_easy *data)
  1495. {
  1496. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1497. CURLcode result = CURLE_OK;
  1498. const char *hostname, *disp_hostname;
  1499. int port;
  1500. char *snihost;
  1501. Curl_conn_get_host(data, cf->sockindex, &hostname, &disp_hostname, &port);
  1502. snihost = Curl_ssl_snihost(data, hostname, NULL);
  1503. if(!snihost)
  1504. return CURLE_PEER_FAILED_VERIFICATION;
  1505. cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
  1506. cf->conn->httpversion = 30;
  1507. cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX;
  1508. if(cf->conn->ssl_config.verifyhost) {
  1509. #ifdef USE_OPENSSL
  1510. X509 *server_cert;
  1511. server_cert = SSL_get_peer_certificate(ctx->ssl);
  1512. if(!server_cert) {
  1513. return CURLE_PEER_FAILED_VERIFICATION;
  1514. }
  1515. result = Curl_ossl_verifyhost(data, cf->conn, server_cert);
  1516. X509_free(server_cert);
  1517. if(result)
  1518. return result;
  1519. #elif defined(USE_GNUTLS)
  1520. result = Curl_gtls_verifyserver(data, ctx->gtls->session,
  1521. &cf->conn->ssl_config, &data->set.ssl,
  1522. hostname, disp_hostname,
  1523. data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
  1524. if(result)
  1525. return result;
  1526. #elif defined(USE_WOLFSSL)
  1527. if(wolfSSL_check_domain_name(ctx->ssl, snihost) == SSL_FAILURE)
  1528. return CURLE_PEER_FAILED_VERIFICATION;
  1529. #endif
  1530. infof(data, "Verified certificate just fine");
  1531. }
  1532. else
  1533. infof(data, "Skipped certificate verification");
  1534. #ifdef USE_OPENSSL
  1535. if(data->set.ssl.certinfo)
  1536. /* asked to gather certificate info */
  1537. (void)Curl_ossl_certchain(data, ctx->ssl);
  1538. #endif
  1539. return result;
  1540. }
  1541. static CURLcode cf_process_ingress(struct Curl_cfilter *cf,
  1542. struct Curl_easy *data)
  1543. {
  1544. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1545. ssize_t recvd;
  1546. int rv;
  1547. uint8_t buf[65536];
  1548. int bufsize = (int)sizeof(buf);
  1549. size_t pktcount = 0, total_recvd = 0;
  1550. struct sockaddr_storage remote_addr;
  1551. socklen_t remote_addrlen;
  1552. ngtcp2_path path;
  1553. ngtcp2_tstamp ts = timestamp();
  1554. ngtcp2_pkt_info pi = { 0 };
  1555. for(;;) {
  1556. remote_addrlen = sizeof(remote_addr);
  1557. while((recvd = recvfrom(ctx->q.sockfd, (char *)buf, bufsize, 0,
  1558. (struct sockaddr *)&remote_addr,
  1559. &remote_addrlen)) == -1 &&
  1560. SOCKERRNO == EINTR)
  1561. ;
  1562. if(recvd == -1) {
  1563. if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
  1564. DEBUGF(LOG_CF(data, cf, "ingress, recvfrom -> EAGAIN"));
  1565. goto out;
  1566. }
  1567. if(!cf->connected && SOCKERRNO == ECONNREFUSED) {
  1568. const char *r_ip;
  1569. int r_port;
  1570. Curl_cf_socket_peek(cf->next, data, NULL, NULL,
  1571. &r_ip, &r_port, NULL, NULL);
  1572. failf(data, "ngtcp2: connection to %s port %u refused",
  1573. r_ip, r_port);
  1574. return CURLE_COULDNT_CONNECT;
  1575. }
  1576. failf(data, "ngtcp2: recvfrom() unexpectedly returned %zd (errno=%d)",
  1577. recvd, SOCKERRNO);
  1578. return CURLE_RECV_ERROR;
  1579. }
  1580. if(recvd > 0 && !ctx->got_first_byte) {
  1581. ctx->first_byte_at = Curl_now();
  1582. ctx->got_first_byte = TRUE;
  1583. }
  1584. ++pktcount;
  1585. total_recvd += recvd;
  1586. ngtcp2_addr_init(&path.local, (struct sockaddr *)&ctx->q.local_addr,
  1587. ctx->q.local_addrlen);
  1588. ngtcp2_addr_init(&path.remote, (struct sockaddr *)&remote_addr,
  1589. remote_addrlen);
  1590. rv = ngtcp2_conn_read_pkt(ctx->qconn, &path, &pi, buf, recvd, ts);
  1591. if(rv) {
  1592. DEBUGF(LOG_CF(data, cf, "ingress, read_pkt -> %s",
  1593. ngtcp2_strerror(rv)));
  1594. if(!ctx->last_error.error_code) {
  1595. if(rv == NGTCP2_ERR_CRYPTO) {
  1596. ngtcp2_connection_close_error_set_transport_error_tls_alert(
  1597. &ctx->last_error,
  1598. ngtcp2_conn_get_tls_alert(ctx->qconn), NULL, 0);
  1599. }
  1600. else {
  1601. ngtcp2_connection_close_error_set_transport_error_liberr(
  1602. &ctx->last_error, rv, NULL, 0);
  1603. }
  1604. }
  1605. if(rv == NGTCP2_ERR_CRYPTO)
  1606. /* this is a "TLS problem", but a failed certificate verification
  1607. is a common reason for this */
  1608. return CURLE_PEER_FAILED_VERIFICATION;
  1609. return CURLE_RECV_ERROR;
  1610. }
  1611. }
  1612. out:
  1613. (void)pktcount;
  1614. (void)total_recvd;
  1615. DEBUGF(LOG_CF(data, cf, "ingress, recvd %zu packets with %zd bytes",
  1616. pktcount, total_recvd));
  1617. return CURLE_OK;
  1618. }
  1619. static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
  1620. struct Curl_easy *data)
  1621. {
  1622. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1623. int rv;
  1624. size_t sent;
  1625. ngtcp2_ssize outlen;
  1626. uint8_t *outpos = ctx->q.pktbuf;
  1627. size_t max_udp_payload_size =
  1628. ngtcp2_conn_get_max_tx_udp_payload_size(ctx->qconn);
  1629. size_t path_max_udp_payload_size =
  1630. ngtcp2_conn_get_path_max_tx_udp_payload_size(ctx->qconn);
  1631. size_t max_pktcnt =
  1632. CURLMIN(MAX_PKT_BURST, ctx->q.pktbuflen / max_udp_payload_size);
  1633. size_t pktcnt = 0;
  1634. size_t gsolen = 0; /* this disables gso until we have a clue */
  1635. ngtcp2_path_storage ps;
  1636. ngtcp2_tstamp ts = timestamp();
  1637. ngtcp2_tstamp expiry;
  1638. ngtcp2_duration timeout;
  1639. int64_t stream_id;
  1640. nghttp3_ssize veccnt;
  1641. int fin;
  1642. nghttp3_vec vec[16];
  1643. ngtcp2_ssize ndatalen;
  1644. uint32_t flags;
  1645. CURLcode curlcode;
  1646. rv = ngtcp2_conn_handle_expiry(ctx->qconn, ts);
  1647. if(rv) {
  1648. failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
  1649. ngtcp2_strerror(rv));
  1650. ngtcp2_connection_close_error_set_transport_error_liberr(&ctx->last_error,
  1651. rv, NULL, 0);
  1652. return CURLE_SEND_ERROR;
  1653. }
  1654. if(ctx->q.num_blocked_pkt) {
  1655. curlcode = vquic_send_blocked_pkt(cf, data, &ctx->q);
  1656. if(curlcode) {
  1657. if(curlcode == CURLE_AGAIN) {
  1658. Curl_expire(data, 1, EXPIRE_QUIC);
  1659. return CURLE_OK;
  1660. }
  1661. return curlcode;
  1662. }
  1663. }
  1664. ngtcp2_path_storage_zero(&ps);
  1665. for(;;) {
  1666. veccnt = 0;
  1667. stream_id = -1;
  1668. fin = 0;
  1669. if(ctx->h3conn && ngtcp2_conn_get_max_data_left(ctx->qconn)) {
  1670. veccnt = nghttp3_conn_writev_stream(ctx->h3conn, &stream_id, &fin, vec,
  1671. sizeof(vec) / sizeof(vec[0]));
  1672. if(veccnt < 0) {
  1673. failf(data, "nghttp3_conn_writev_stream returned error: %s",
  1674. nghttp3_strerror((int)veccnt));
  1675. ngtcp2_connection_close_error_set_application_error(
  1676. &ctx->last_error,
  1677. nghttp3_err_infer_quic_app_error_code((int)veccnt), NULL, 0);
  1678. return CURLE_SEND_ERROR;
  1679. }
  1680. }
  1681. flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
  1682. (fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
  1683. outlen = ngtcp2_conn_writev_stream(ctx->qconn, &ps.path, NULL, outpos,
  1684. max_udp_payload_size,
  1685. &ndatalen, flags, stream_id,
  1686. (const ngtcp2_vec *)vec, veccnt, ts);
  1687. if(outlen == 0) {
  1688. /* ngtcp2 does not want to send more packets, if the buffer is
  1689. * not empty, send that now */
  1690. if(outpos != ctx->q.pktbuf) {
  1691. curlcode = vquic_send_packet(cf, data, &ctx->q, ctx->q.pktbuf,
  1692. outpos - ctx->q.pktbuf, gsolen, &sent);
  1693. if(curlcode) {
  1694. if(curlcode == CURLE_AGAIN) {
  1695. vquic_push_blocked_pkt(cf, &ctx->q, ctx->q.pktbuf + sent,
  1696. outpos - ctx->q.pktbuf - sent,
  1697. gsolen);
  1698. Curl_expire(data, 1, EXPIRE_QUIC);
  1699. return CURLE_OK;
  1700. }
  1701. return curlcode;
  1702. }
  1703. }
  1704. /* done for now */
  1705. goto out;
  1706. }
  1707. if(outlen < 0) {
  1708. switch(outlen) {
  1709. case NGTCP2_ERR_STREAM_DATA_BLOCKED:
  1710. assert(ndatalen == -1);
  1711. nghttp3_conn_block_stream(ctx->h3conn, stream_id);
  1712. continue;
  1713. case NGTCP2_ERR_STREAM_SHUT_WR:
  1714. assert(ndatalen == -1);
  1715. nghttp3_conn_shutdown_stream_write(ctx->h3conn, stream_id);
  1716. continue;
  1717. case NGTCP2_ERR_WRITE_MORE:
  1718. /* ngtcp2 wants to send more. update the flow of the stream whose data
  1719. * is in the buffer and continue */
  1720. assert(ndatalen >= 0);
  1721. rv = nghttp3_conn_add_write_offset(ctx->h3conn, stream_id, ndatalen);
  1722. if(rv) {
  1723. failf(data, "nghttp3_conn_add_write_offset returned error: %s\n",
  1724. nghttp3_strerror(rv));
  1725. return CURLE_SEND_ERROR;
  1726. }
  1727. continue;
  1728. default:
  1729. assert(ndatalen == -1);
  1730. failf(data, "ngtcp2_conn_writev_stream returned error: %s",
  1731. ngtcp2_strerror((int)outlen));
  1732. ngtcp2_connection_close_error_set_transport_error_liberr(
  1733. &ctx->last_error, (int)outlen, NULL, 0);
  1734. return CURLE_SEND_ERROR;
  1735. }
  1736. }
  1737. else if(ndatalen >= 0) {
  1738. /* ngtcp2 thinks it has added all it wants. Update the stream */
  1739. rv = nghttp3_conn_add_write_offset(ctx->h3conn, stream_id, ndatalen);
  1740. if(rv) {
  1741. failf(data, "nghttp3_conn_add_write_offset returned error: %s\n",
  1742. nghttp3_strerror(rv));
  1743. return CURLE_SEND_ERROR;
  1744. }
  1745. }
  1746. /* advance to the end of the buffered packet data */
  1747. outpos += outlen;
  1748. if(pktcnt == 0) {
  1749. /* first packet buffer chunk. use this as gsolen. It's how ngtcp2
  1750. * indicates the intended segment size. */
  1751. gsolen = outlen;
  1752. }
  1753. else if((size_t)outlen > gsolen ||
  1754. (gsolen > path_max_udp_payload_size && (size_t)outlen != gsolen)) {
  1755. /* Packet larger than path_max_udp_payload_size is PMTUD probe
  1756. packet and it might not be sent because of EMSGSIZE. Send
  1757. them separately to minimize the loss. */
  1758. /* send the pktbuf *before* the last addition */
  1759. curlcode = vquic_send_packet(cf, data, &ctx->q, ctx->q.pktbuf,
  1760. outpos - outlen - ctx->q.pktbuf, gsolen, &sent);
  1761. if(curlcode) {
  1762. if(curlcode == CURLE_AGAIN) {
  1763. /* blocked, add the pktbuf *before* and *at* the last addition
  1764. * separately to the blocked packages */
  1765. vquic_push_blocked_pkt(cf, &ctx->q, ctx->q.pktbuf + sent,
  1766. outpos - outlen - ctx->q.pktbuf - sent, gsolen);
  1767. vquic_push_blocked_pkt(cf, &ctx->q, outpos - outlen, outlen, outlen);
  1768. Curl_expire(data, 1, EXPIRE_QUIC);
  1769. return CURLE_OK;
  1770. }
  1771. return curlcode;
  1772. }
  1773. /* send the pktbuf *at* the last addition */
  1774. curlcode = vquic_send_packet(cf, data, &ctx->q, outpos - outlen, outlen,
  1775. outlen, &sent);
  1776. if(curlcode) {
  1777. if(curlcode == CURLE_AGAIN) {
  1778. assert(0 == sent);
  1779. vquic_push_blocked_pkt(cf, &ctx->q, outpos - outlen, outlen, outlen);
  1780. Curl_expire(data, 1, EXPIRE_QUIC);
  1781. return CURLE_OK;
  1782. }
  1783. return curlcode;
  1784. }
  1785. /* pktbuf has been completely sent */
  1786. pktcnt = 0;
  1787. outpos = ctx->q.pktbuf;
  1788. continue;
  1789. }
  1790. if(++pktcnt >= max_pktcnt || (size_t)outlen < gsolen) {
  1791. /* enough packets or last one is shorter than the intended
  1792. * segment size, indicating that it is time to send. */
  1793. curlcode = vquic_send_packet(cf, data, &ctx->q, ctx->q.pktbuf,
  1794. outpos - ctx->q.pktbuf, gsolen, &sent);
  1795. if(curlcode) {
  1796. if(curlcode == CURLE_AGAIN) {
  1797. vquic_push_blocked_pkt(cf, &ctx->q, ctx->q.pktbuf + sent,
  1798. outpos - ctx->q.pktbuf - sent, gsolen);
  1799. Curl_expire(data, 1, EXPIRE_QUIC);
  1800. return CURLE_OK;
  1801. }
  1802. return curlcode;
  1803. }
  1804. /* pktbuf has been completely sent */
  1805. pktcnt = 0;
  1806. outpos = ctx->q.pktbuf;
  1807. }
  1808. }
  1809. out:
  1810. /* non-errored exit. check when we should run again. */
  1811. expiry = ngtcp2_conn_get_expiry(ctx->qconn);
  1812. if(expiry != UINT64_MAX) {
  1813. if(expiry <= ts) {
  1814. timeout = 0;
  1815. }
  1816. else {
  1817. timeout = expiry - ts;
  1818. if(timeout % NGTCP2_MILLISECONDS) {
  1819. timeout += NGTCP2_MILLISECONDS;
  1820. }
  1821. }
  1822. Curl_expire(data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
  1823. }
  1824. return CURLE_OK;
  1825. }
  1826. /*
  1827. * Called from transfer.c:data_pending to know if we should keep looping
  1828. * to receive more data from the connection.
  1829. */
  1830. static bool cf_ngtcp2_data_pending(struct Curl_cfilter *cf,
  1831. const struct Curl_easy *data)
  1832. {
  1833. /* We may have received more data than we're able to hold in the receive
  1834. buffer and allocated an overflow buffer. Since it's possible that
  1835. there's no more data coming on the socket, we need to keep reading
  1836. until the overflow buffer is empty. */
  1837. const struct HTTP *stream = data->req.p.http;
  1838. (void)cf;
  1839. return Curl_dyn_len(&stream->overflow) > 0;
  1840. }
  1841. static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
  1842. struct Curl_easy *data,
  1843. int event, int arg1, void *arg2)
  1844. {
  1845. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1846. CURLcode result = CURLE_OK;
  1847. struct cf_call_data save;
  1848. CF_DATA_SAVE(save, cf, data);
  1849. (void)arg1;
  1850. (void)arg2;
  1851. switch(event) {
  1852. case CF_CTRL_DATA_DONE: {
  1853. struct HTTP *stream = data->req.p.http;
  1854. Curl_dyn_free(&stream->overflow);
  1855. free(stream->h3out);
  1856. break;
  1857. }
  1858. case CF_CTRL_DATA_DONE_SEND: {
  1859. struct HTTP *stream = data->req.p.http;
  1860. stream->upload_done = TRUE;
  1861. (void)nghttp3_conn_resume_stream(ctx->h3conn, stream->stream3_id);
  1862. break;
  1863. }
  1864. case CF_CTRL_DATA_IDLE:
  1865. if(timestamp() >= ngtcp2_conn_get_expiry(ctx->qconn)) {
  1866. if(cf_flush_egress(cf, data)) {
  1867. result = CURLE_SEND_ERROR;
  1868. }
  1869. }
  1870. break;
  1871. default:
  1872. break;
  1873. }
  1874. CF_DATA_RESTORE(cf, save);
  1875. return result;
  1876. }
  1877. static void cf_ngtcp2_ctx_clear(struct cf_ngtcp2_ctx *ctx)
  1878. {
  1879. struct cf_call_data save = ctx->call_data;
  1880. if(ctx->qlogfd != -1) {
  1881. close(ctx->qlogfd);
  1882. }
  1883. #ifdef USE_OPENSSL
  1884. if(ctx->ssl)
  1885. SSL_free(ctx->ssl);
  1886. if(ctx->sslctx)
  1887. SSL_CTX_free(ctx->sslctx);
  1888. #elif defined(USE_GNUTLS)
  1889. if(ctx->gtls) {
  1890. if(ctx->gtls->cred)
  1891. gnutls_certificate_free_credentials(ctx->gtls->cred);
  1892. if(ctx->gtls->session)
  1893. gnutls_deinit(ctx->gtls->session);
  1894. free(ctx->gtls);
  1895. }
  1896. #elif defined(USE_WOLFSSL)
  1897. if(ctx->ssl)
  1898. wolfSSL_free(ctx->ssl);
  1899. if(ctx->sslctx)
  1900. wolfSSL_CTX_free(ctx->sslctx);
  1901. #endif
  1902. vquic_ctx_free(&ctx->q);
  1903. if(ctx->h3conn)
  1904. nghttp3_conn_del(ctx->h3conn);
  1905. if(ctx->qconn)
  1906. ngtcp2_conn_del(ctx->qconn);
  1907. memset(ctx, 0, sizeof(*ctx));
  1908. ctx->qlogfd = -1;
  1909. ctx->call_data = save;
  1910. }
  1911. static void cf_ngtcp2_close(struct Curl_cfilter *cf, struct Curl_easy *data)
  1912. {
  1913. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1914. struct cf_call_data save;
  1915. CF_DATA_SAVE(save, cf, data);
  1916. if(ctx && ctx->qconn) {
  1917. char buffer[NGTCP2_MAX_UDP_PAYLOAD_SIZE];
  1918. ngtcp2_tstamp ts;
  1919. ngtcp2_ssize rc;
  1920. DEBUGF(LOG_CF(data, cf, "close"));
  1921. ts = timestamp();
  1922. rc = ngtcp2_conn_write_connection_close(ctx->qconn, NULL, /* path */
  1923. NULL, /* pkt_info */
  1924. (uint8_t *)buffer, sizeof(buffer),
  1925. &ctx->last_error, ts);
  1926. if(rc > 0) {
  1927. while((send(ctx->q.sockfd, buffer, (SEND_TYPE_ARG3)rc, 0) == -1) &&
  1928. SOCKERRNO == EINTR);
  1929. }
  1930. cf_ngtcp2_ctx_clear(ctx);
  1931. }
  1932. cf->connected = FALSE;
  1933. CF_DATA_RESTORE(cf, save);
  1934. }
  1935. static void cf_ngtcp2_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
  1936. {
  1937. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1938. struct cf_call_data save;
  1939. CF_DATA_SAVE(save, cf, data);
  1940. DEBUGF(LOG_CF(data, cf, "destroy"));
  1941. if(ctx) {
  1942. cf_ngtcp2_ctx_clear(ctx);
  1943. free(ctx);
  1944. }
  1945. cf->ctx = NULL;
  1946. /* No CF_DATA_RESTORE(cf, save) possible */
  1947. (void)save;
  1948. }
  1949. /*
  1950. * Might be called twice for happy eyeballs.
  1951. */
  1952. static CURLcode cf_connect_start(struct Curl_cfilter *cf,
  1953. struct Curl_easy *data)
  1954. {
  1955. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  1956. int rc;
  1957. int rv;
  1958. CURLcode result;
  1959. const struct Curl_sockaddr_ex *sockaddr;
  1960. int qfd;
  1961. ctx->version = NGTCP2_PROTO_VER_MAX;
  1962. #ifdef USE_OPENSSL
  1963. result = quic_ssl_ctx(&ctx->sslctx, cf, data);
  1964. if(result)
  1965. return result;
  1966. result = quic_set_client_cert(cf, data);
  1967. if(result)
  1968. return result;
  1969. #elif defined(USE_WOLFSSL)
  1970. result = quic_ssl_ctx(&ctx->sslctx, cf, data);
  1971. if(result)
  1972. return result;
  1973. #endif
  1974. result = quic_init_ssl(cf, data);
  1975. if(result)
  1976. return result;
  1977. ctx->dcid.datalen = NGTCP2_MAX_CIDLEN;
  1978. result = Curl_rand(data, ctx->dcid.data, NGTCP2_MAX_CIDLEN);
  1979. if(result)
  1980. return result;
  1981. ctx->scid.datalen = NGTCP2_MAX_CIDLEN;
  1982. result = Curl_rand(data, ctx->scid.data, NGTCP2_MAX_CIDLEN);
  1983. if(result)
  1984. return result;
  1985. (void)Curl_qlogdir(data, ctx->scid.data, NGTCP2_MAX_CIDLEN, &qfd);
  1986. ctx->qlogfd = qfd; /* -1 if failure above */
  1987. quic_settings(ctx, data);
  1988. result = vquic_ctx_init(&ctx->q,
  1989. NGTCP2_MAX_PMTUD_UDP_PAYLOAD_SIZE * MAX_PKT_BURST);
  1990. if(result)
  1991. return result;
  1992. Curl_cf_socket_peek(cf->next, data, &ctx->q.sockfd,
  1993. &sockaddr, NULL, NULL, NULL, NULL);
  1994. ctx->q.local_addrlen = sizeof(ctx->q.local_addr);
  1995. rv = getsockname(ctx->q.sockfd, (struct sockaddr *)&ctx->q.local_addr,
  1996. &ctx->q.local_addrlen);
  1997. if(rv == -1)
  1998. return CURLE_QUIC_CONNECT_ERROR;
  1999. ngtcp2_addr_init(&ctx->connected_path.local,
  2000. (struct sockaddr *)&ctx->q.local_addr,
  2001. ctx->q.local_addrlen);
  2002. ngtcp2_addr_init(&ctx->connected_path.remote,
  2003. &sockaddr->sa_addr, sockaddr->addrlen);
  2004. rc = ngtcp2_conn_client_new(&ctx->qconn, &ctx->dcid, &ctx->scid,
  2005. &ctx->connected_path,
  2006. NGTCP2_PROTO_VER_V1, &ng_callbacks,
  2007. &ctx->settings, &ctx->transport_params,
  2008. NULL, cf);
  2009. if(rc)
  2010. return CURLE_QUIC_CONNECT_ERROR;
  2011. #ifdef USE_GNUTLS
  2012. ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->gtls->session);
  2013. #else
  2014. ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->ssl);
  2015. #endif
  2016. ngtcp2_connection_close_error_default(&ctx->last_error);
  2017. ctx->conn_ref.get_conn = get_conn;
  2018. ctx->conn_ref.user_data = cf;
  2019. return CURLE_OK;
  2020. }
  2021. static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
  2022. struct Curl_easy *data,
  2023. bool blocking, bool *done)
  2024. {
  2025. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  2026. CURLcode result = CURLE_OK;
  2027. struct cf_call_data save;
  2028. struct curltime now;
  2029. if(cf->connected) {
  2030. *done = TRUE;
  2031. return CURLE_OK;
  2032. }
  2033. /* Connect the UDP filter first */
  2034. if(!cf->next->connected) {
  2035. result = Curl_conn_cf_connect(cf->next, data, blocking, done);
  2036. if(result || !*done)
  2037. return result;
  2038. }
  2039. *done = FALSE;
  2040. now = Curl_now();
  2041. CF_DATA_SAVE(save, cf, data);
  2042. if(ctx->reconnect_at.tv_sec && Curl_timediff(now, ctx->reconnect_at) < 0) {
  2043. /* Not time yet to attempt the next connect */
  2044. DEBUGF(LOG_CF(data, cf, "waiting for reconnect time"));
  2045. goto out;
  2046. }
  2047. if(!ctx->qconn) {
  2048. ctx->started_at = now;
  2049. result = cf_connect_start(cf, data);
  2050. if(result)
  2051. goto out;
  2052. result = cf_flush_egress(cf, data);
  2053. /* we do not expect to be able to recv anything yet */
  2054. goto out;
  2055. }
  2056. result = cf_process_ingress(cf, data);
  2057. if(result)
  2058. goto out;
  2059. result = cf_flush_egress(cf, data);
  2060. if(result)
  2061. goto out;
  2062. if(ngtcp2_conn_get_handshake_completed(ctx->qconn)) {
  2063. ctx->handshake_at = now;
  2064. DEBUGF(LOG_CF(data, cf, "handshake complete after %dms",
  2065. (int)Curl_timediff(now, ctx->started_at)));
  2066. result = qng_verify_peer(cf, data);
  2067. if(!result) {
  2068. DEBUGF(LOG_CF(data, cf, "peer verified"));
  2069. cf->connected = TRUE;
  2070. cf->conn->alpn = CURL_HTTP_VERSION_3;
  2071. *done = TRUE;
  2072. connkeep(cf->conn, "HTTP/3 default");
  2073. }
  2074. }
  2075. out:
  2076. if(result == CURLE_RECV_ERROR && ctx->qconn &&
  2077. ngtcp2_conn_is_in_draining_period(ctx->qconn)) {
  2078. /* When a QUIC server instance is shutting down, it may send us a
  2079. * CONNECTION_CLOSE right away. Our connection then enters the DRAINING
  2080. * state.
  2081. * This may be a stopping of the service or it may be that the server
  2082. * is reloading and a new instance will start serving soon.
  2083. * In any case, we tear down our socket and start over with a new one.
  2084. * We re-open the underlying UDP cf right now, but do not start
  2085. * connecting until called again.
  2086. */
  2087. int reconn_delay_ms = 200;
  2088. DEBUGF(LOG_CF(data, cf, "connect, remote closed, reconnect after %dms",
  2089. reconn_delay_ms));
  2090. Curl_conn_cf_close(cf->next, data);
  2091. cf_ngtcp2_ctx_clear(ctx);
  2092. result = Curl_conn_cf_connect(cf->next, data, FALSE, done);
  2093. if(!result && *done) {
  2094. *done = FALSE;
  2095. ctx->reconnect_at = now;
  2096. ctx->reconnect_at.tv_usec += reconn_delay_ms * 1000;
  2097. Curl_expire(data, reconn_delay_ms, EXPIRE_QUIC);
  2098. result = CURLE_OK;
  2099. }
  2100. }
  2101. #ifndef CURL_DISABLE_VERBOSE_STRINGS
  2102. if(result) {
  2103. const char *r_ip;
  2104. int r_port;
  2105. Curl_cf_socket_peek(cf->next, data, NULL, NULL,
  2106. &r_ip, &r_port, NULL, NULL);
  2107. infof(data, "QUIC connect to %s port %u failed: %s",
  2108. r_ip, r_port, curl_easy_strerror(result));
  2109. }
  2110. #endif
  2111. DEBUGF(LOG_CF(data, cf, "connect -> %d, done=%d", result, *done));
  2112. CF_DATA_RESTORE(cf, save);
  2113. return result;
  2114. }
  2115. static CURLcode cf_ngtcp2_query(struct Curl_cfilter *cf,
  2116. struct Curl_easy *data,
  2117. int query, int *pres1, void *pres2)
  2118. {
  2119. struct cf_ngtcp2_ctx *ctx = cf->ctx;
  2120. struct cf_call_data save;
  2121. switch(query) {
  2122. case CF_QUERY_MAX_CONCURRENT: {
  2123. const ngtcp2_transport_params *rp;
  2124. DEBUGASSERT(pres1);
  2125. CF_DATA_SAVE(save, cf, data);
  2126. rp = ngtcp2_conn_get_remote_transport_params(ctx->qconn);
  2127. if(rp)
  2128. *pres1 = (rp->initial_max_streams_bidi > INT_MAX)?
  2129. INT_MAX : (int)rp->initial_max_streams_bidi;
  2130. else /* not arrived yet? */
  2131. *pres1 = Curl_multi_max_concurrent_streams(data->multi);
  2132. DEBUGF(LOG_CF(data, cf, "query max_conncurrent -> %d", *pres1));
  2133. CF_DATA_RESTORE(cf, save);
  2134. return CURLE_OK;
  2135. }
  2136. case CF_QUERY_CONNECT_REPLY_MS:
  2137. if(ctx->got_first_byte) {
  2138. timediff_t ms = Curl_timediff(ctx->first_byte_at, ctx->started_at);
  2139. *pres1 = (ms < INT_MAX)? (int)ms : INT_MAX;
  2140. }
  2141. else
  2142. *pres1 = -1;
  2143. return CURLE_OK;
  2144. case CF_QUERY_TIMER_CONNECT: {
  2145. struct curltime *when = pres2;
  2146. if(ctx->got_first_byte)
  2147. *when = ctx->first_byte_at;
  2148. return CURLE_OK;
  2149. }
  2150. case CF_QUERY_TIMER_APPCONNECT: {
  2151. struct curltime *when = pres2;
  2152. if(cf->connected)
  2153. *when = ctx->handshake_at;
  2154. return CURLE_OK;
  2155. }
  2156. default:
  2157. break;
  2158. }
  2159. return cf->next?
  2160. cf->next->cft->query(cf->next, data, query, pres1, pres2) :
  2161. CURLE_UNKNOWN_OPTION;
  2162. }
  2163. static bool cf_ngtcp2_conn_is_alive(struct Curl_cfilter *cf,
  2164. struct Curl_easy *data,
  2165. bool *input_pending)
  2166. {
  2167. bool alive = TRUE;
  2168. *input_pending = FALSE;
  2169. if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending))
  2170. return FALSE;
  2171. if(*input_pending) {
  2172. /* This happens before we've sent off a request and the connection is
  2173. not in use by any other transfer, there shouldn't be any data here,
  2174. only "protocol frames" */
  2175. *input_pending = FALSE;
  2176. Curl_attach_connection(data, cf->conn);
  2177. if(cf_process_ingress(cf, data))
  2178. alive = FALSE;
  2179. else {
  2180. alive = TRUE;
  2181. }
  2182. Curl_detach_connection(data);
  2183. }
  2184. return alive;
  2185. }
  2186. struct Curl_cftype Curl_cft_http3 = {
  2187. "HTTP/3",
  2188. CF_TYPE_IP_CONNECT | CF_TYPE_SSL | CF_TYPE_MULTIPLEX,
  2189. 0,
  2190. cf_ngtcp2_destroy,
  2191. cf_ngtcp2_connect,
  2192. cf_ngtcp2_close,
  2193. Curl_cf_def_get_host,
  2194. cf_ngtcp2_get_select_socks,
  2195. cf_ngtcp2_data_pending,
  2196. cf_ngtcp2_send,
  2197. cf_ngtcp2_recv,
  2198. cf_ngtcp2_data_event,
  2199. cf_ngtcp2_conn_is_alive,
  2200. Curl_cf_def_conn_keep_alive,
  2201. cf_ngtcp2_query,
  2202. };
  2203. CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf,
  2204. struct Curl_easy *data,
  2205. struct connectdata *conn,
  2206. const struct Curl_addrinfo *ai)
  2207. {
  2208. struct cf_ngtcp2_ctx *ctx = NULL;
  2209. struct Curl_cfilter *cf = NULL, *udp_cf = NULL;
  2210. CURLcode result;
  2211. (void)data;
  2212. ctx = calloc(sizeof(*ctx), 1);
  2213. if(!ctx) {
  2214. result = CURLE_OUT_OF_MEMORY;
  2215. goto out;
  2216. }
  2217. ctx->qlogfd = -1;
  2218. cf_ngtcp2_ctx_clear(ctx);
  2219. result = Curl_cf_create(&cf, &Curl_cft_http3, ctx);
  2220. if(result)
  2221. goto out;
  2222. result = Curl_cf_udp_create(&udp_cf, data, conn, ai, TRNSPRT_QUIC);
  2223. if(result)
  2224. goto out;
  2225. cf->conn = conn;
  2226. udp_cf->conn = cf->conn;
  2227. udp_cf->sockindex = cf->sockindex;
  2228. cf->next = udp_cf;
  2229. out:
  2230. *pcf = (!result)? cf : NULL;
  2231. if(result) {
  2232. if(udp_cf)
  2233. Curl_conn_cf_discard(udp_cf, data);
  2234. Curl_safefree(cf);
  2235. Curl_safefree(ctx);
  2236. }
  2237. return result;
  2238. }
  2239. bool Curl_conn_is_ngtcp2(const struct Curl_easy *data,
  2240. const struct connectdata *conn,
  2241. int sockindex)
  2242. {
  2243. struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
  2244. (void)data;
  2245. for(; cf; cf = cf->next) {
  2246. if(cf->cft == &Curl_cft_http3)
  2247. return TRUE;
  2248. if(cf->cft->flags & CF_TYPE_IP_CONNECT)
  2249. return FALSE;
  2250. }
  2251. return FALSE;
  2252. }
  2253. #endif