ngtcp2.c 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at https://curl.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. * SPDX-License-Identifier: curl
  22. *
  23. ***************************************************************************/
  24. #include "curl_setup.h"
  25. #ifdef USE_NGTCP2
  26. #error #include <ngtcp2/ngtcp2.h>
  27. #error #include <nghttp3/nghttp3.h>
  28. #ifdef USE_OPENSSL
  29. #include <openssl/err.h>
  30. #ifdef OPENSSL_IS_BORINGSSL
  31. #error #include <ngtcp2/ngtcp2_crypto_boringssl.h>
  32. #else
  33. #error #include <ngtcp2/ngtcp2_crypto_openssl.h>
  34. #endif
  35. #include "vtls/openssl.h"
  36. #elif defined(USE_GNUTLS)
  37. #error #include <ngtcp2/ngtcp2_crypto_gnutls.h>
  38. #include "vtls/gtls.h"
  39. #elif defined(USE_WOLFSSL)
  40. #error #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. #error #include "ngtcp2.h"
  48. #include "multiif.h"
  49. #include "strcase.h"
  50. #include "connect.h"
  51. #include "strerror.h"
  52. #include "dynbuf.h"
  53. #error #include "vquic.h"
  54. #include "h2h3.h"
  55. #include "vtls/keylog.h"
  56. #include "vtls/vtls.h"
  57. /* The last 3 #include files should be in this order */
  58. #include "curl_printf.h"
  59. #include "curl_memory.h"
  60. #include "memdebug.h"
  61. /* #define DEBUG_NGTCP2 */
  62. #ifdef CURLDEBUG
  63. #define DEBUG_HTTP3
  64. #endif
  65. #ifdef DEBUG_HTTP3
  66. #define H3BUGF(x) x
  67. #else
  68. #define H3BUGF(x) do { } while(0)
  69. #endif
  70. #define H3_ALPN_H3_29 "\x5h3-29"
  71. #define H3_ALPN_H3 "\x2h3"
  72. /*
  73. * This holds outgoing HTTP/3 stream data that is used by nghttp3 until acked.
  74. * It is used as a circular buffer. Add new bytes at the end until it reaches
  75. * the far end, then start over at index 0 again.
  76. */
  77. #define H3_SEND_SIZE (256*1024)
  78. struct h3out {
  79. uint8_t buf[H3_SEND_SIZE];
  80. size_t used; /* number of bytes used in the buffer */
  81. size_t windex; /* index in the buffer where to start writing the next
  82. data block */
  83. };
  84. #define QUIC_MAX_STREAMS (256*1024)
  85. #define QUIC_MAX_DATA (1*1024*1024)
  86. #define QUIC_IDLE_TIMEOUT (60*NGTCP2_SECONDS)
  87. #ifdef USE_OPENSSL
  88. #define QUIC_CIPHERS \
  89. "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \
  90. "POLY1305_SHA256:TLS_AES_128_CCM_SHA256"
  91. #define QUIC_GROUPS "P-256:X25519:P-384:P-521"
  92. #elif defined(USE_GNUTLS)
  93. #define QUIC_PRIORITY \
  94. "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \
  95. "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \
  96. "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \
  97. "%DISABLE_TLS13_COMPAT_MODE"
  98. #elif defined(USE_WOLFSSL)
  99. #define QUIC_CIPHERS \
  100. "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \
  101. "POLY1305_SHA256:TLS_AES_128_CCM_SHA256"
  102. #define QUIC_GROUPS "P-256:P-384:P-521"
  103. #endif
  104. /* ngtcp2 default congestion controller does not perform pacing. Limit
  105. the maximum packet burst to MAX_PKT_BURST packets. */
  106. #define MAX_PKT_BURST 10
  107. static CURLcode ng_process_ingress(struct Curl_easy *data,
  108. curl_socket_t sockfd,
  109. struct quicsocket *qs);
  110. static CURLcode ng_flush_egress(struct Curl_easy *data, int sockfd,
  111. struct quicsocket *qs);
  112. static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
  113. uint64_t datalen, void *user_data,
  114. void *stream_user_data);
  115. static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref)
  116. {
  117. struct quicsocket *qs = conn_ref->user_data;
  118. return qs->qconn;
  119. }
  120. static ngtcp2_tstamp timestamp(void)
  121. {
  122. struct curltime ct = Curl_now();
  123. return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS;
  124. }
  125. #ifdef DEBUG_NGTCP2
  126. static void quic_printf(void *user_data, const char *fmt, ...)
  127. {
  128. va_list ap;
  129. (void)user_data; /* TODO, use this to do infof() instead long-term */
  130. va_start(ap, fmt);
  131. vfprintf(stderr, fmt, ap);
  132. va_end(ap);
  133. fprintf(stderr, "\n");
  134. }
  135. #endif
  136. static void qlog_callback(void *user_data, uint32_t flags,
  137. const void *data, size_t datalen)
  138. {
  139. struct quicsocket *qs = (struct quicsocket *)user_data;
  140. (void)flags;
  141. if(qs->qlogfd != -1) {
  142. ssize_t rc = write(qs->qlogfd, data, datalen);
  143. if(rc == -1) {
  144. /* on write error, stop further write attempts */
  145. close(qs->qlogfd);
  146. qs->qlogfd = -1;
  147. }
  148. }
  149. }
  150. static void quic_settings(struct quicsocket *qs,
  151. uint64_t stream_buffer_size)
  152. {
  153. ngtcp2_settings *s = &qs->settings;
  154. ngtcp2_transport_params *t = &qs->transport_params;
  155. ngtcp2_settings_default(s);
  156. ngtcp2_transport_params_default(t);
  157. #ifdef DEBUG_NGTCP2
  158. s->log_printf = quic_printf;
  159. #else
  160. s->log_printf = NULL;
  161. #endif
  162. s->initial_ts = timestamp();
  163. t->initial_max_stream_data_bidi_local = stream_buffer_size;
  164. t->initial_max_stream_data_bidi_remote = QUIC_MAX_STREAMS;
  165. t->initial_max_stream_data_uni = QUIC_MAX_STREAMS;
  166. t->initial_max_data = QUIC_MAX_DATA;
  167. t->initial_max_streams_bidi = 1;
  168. t->initial_max_streams_uni = 3;
  169. t->max_idle_timeout = QUIC_IDLE_TIMEOUT;
  170. if(qs->qlogfd != -1) {
  171. s->qlog.write = qlog_callback;
  172. }
  173. }
  174. #ifdef USE_OPENSSL
  175. static void keylog_callback(const SSL *ssl, const char *line)
  176. {
  177. (void)ssl;
  178. Curl_tls_keylog_write_line(line);
  179. }
  180. #elif defined(USE_GNUTLS)
  181. static int keylog_callback(gnutls_session_t session, const char *label,
  182. const gnutls_datum_t *secret)
  183. {
  184. gnutls_datum_t crandom;
  185. gnutls_datum_t srandom;
  186. gnutls_session_get_random(session, &crandom, &srandom);
  187. if(crandom.size != 32) {
  188. return -1;
  189. }
  190. Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size);
  191. return 0;
  192. }
  193. #elif defined(USE_WOLFSSL)
  194. #if defined(HAVE_SECRET_CALLBACK)
  195. static void keylog_callback(const WOLFSSL *ssl, const char *line)
  196. {
  197. (void)ssl;
  198. Curl_tls_keylog_write_line(line);
  199. }
  200. #endif
  201. #endif
  202. static int init_ngh3_conn(struct quicsocket *qs);
  203. #ifdef USE_OPENSSL
  204. static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
  205. {
  206. struct connectdata *conn = data->conn;
  207. SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method());
  208. #ifdef OPENSSL_IS_BORINGSSL
  209. if(ngtcp2_crypto_boringssl_configure_client_context(ssl_ctx) != 0) {
  210. failf(data, "ngtcp2_crypto_boringssl_configure_client_context failed");
  211. return NULL;
  212. }
  213. #else
  214. if(ngtcp2_crypto_openssl_configure_client_context(ssl_ctx) != 0) {
  215. failf(data, "ngtcp2_crypto_openssl_configure_client_context failed");
  216. return NULL;
  217. }
  218. #endif
  219. SSL_CTX_set_default_verify_paths(ssl_ctx);
  220. #ifdef OPENSSL_IS_BORINGSSL
  221. if(SSL_CTX_set1_curves_list(ssl_ctx, QUIC_GROUPS) != 1) {
  222. failf(data, "SSL_CTX_set1_curves_list failed");
  223. return NULL;
  224. }
  225. #else
  226. if(SSL_CTX_set_ciphersuites(ssl_ctx, QUIC_CIPHERS) != 1) {
  227. char error_buffer[256];
  228. ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer));
  229. failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer);
  230. return NULL;
  231. }
  232. if(SSL_CTX_set1_groups_list(ssl_ctx, QUIC_GROUPS) != 1) {
  233. failf(data, "SSL_CTX_set1_groups_list failed");
  234. return NULL;
  235. }
  236. #endif
  237. /* Open the file if a TLS or QUIC backend has not done this before. */
  238. Curl_tls_keylog_open();
  239. if(Curl_tls_keylog_enabled()) {
  240. SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
  241. }
  242. if(conn->ssl_config.verifypeer) {
  243. const char * const ssl_cafile = conn->ssl_config.CAfile;
  244. const char * const ssl_capath = conn->ssl_config.CApath;
  245. if(ssl_cafile || ssl_capath) {
  246. SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
  247. /* tell OpenSSL where to find CA certificates that are used to verify
  248. the server's certificate. */
  249. if(!SSL_CTX_load_verify_locations(ssl_ctx, ssl_cafile, ssl_capath)) {
  250. /* Fail if we insist on successfully verifying the server. */
  251. failf(data, "error setting certificate verify locations:"
  252. " CAfile: %s CApath: %s",
  253. ssl_cafile ? ssl_cafile : "none",
  254. ssl_capath ? ssl_capath : "none");
  255. return NULL;
  256. }
  257. infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
  258. infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
  259. }
  260. #ifdef CURL_CA_FALLBACK
  261. else {
  262. /* verifying the peer without any CA certificates won't work so
  263. use openssl's built-in default as fallback */
  264. SSL_CTX_set_default_verify_paths(ssl_ctx);
  265. }
  266. #endif
  267. }
  268. return ssl_ctx;
  269. }
  270. static CURLcode quic_set_client_cert(struct Curl_easy *data,
  271. struct quicsocket *qs)
  272. {
  273. struct connectdata *conn = data->conn;
  274. SSL_CTX *ssl_ctx = qs->sslctx;
  275. char *const ssl_cert = SSL_SET_OPTION(primary.clientcert);
  276. const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
  277. const char *const ssl_cert_type = SSL_SET_OPTION(cert_type);
  278. if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
  279. return Curl_ossl_set_client_cert(
  280. data, ssl_ctx, ssl_cert, ssl_cert_blob, ssl_cert_type,
  281. SSL_SET_OPTION(key), SSL_SET_OPTION(key_blob),
  282. SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd));
  283. }
  284. return CURLE_OK;
  285. }
  286. /** SSL callbacks ***/
  287. static int quic_init_ssl(struct quicsocket *qs)
  288. {
  289. const uint8_t *alpn = NULL;
  290. size_t alpnlen = 0;
  291. /* this will need some attention when HTTPS proxy over QUIC get fixed */
  292. const char * const hostname = qs->conn->host.name;
  293. DEBUGASSERT(!qs->ssl);
  294. qs->ssl = SSL_new(qs->sslctx);
  295. SSL_set_app_data(qs->ssl, &qs->conn_ref);
  296. SSL_set_connect_state(qs->ssl);
  297. SSL_set_quic_use_legacy_codepoint(qs->ssl, 0);
  298. alpn = (const uint8_t *)H3_ALPN_H3_29 H3_ALPN_H3;
  299. alpnlen = sizeof(H3_ALPN_H3_29) - 1 + sizeof(H3_ALPN_H3) - 1;
  300. if(alpn)
  301. SSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen);
  302. /* set SNI */
  303. SSL_set_tlsext_host_name(qs->ssl, hostname);
  304. return 0;
  305. }
  306. #elif defined(USE_GNUTLS)
  307. static int quic_init_ssl(struct quicsocket *qs)
  308. {
  309. gnutls_datum_t alpn[2];
  310. /* this will need some attention when HTTPS proxy over QUIC get fixed */
  311. const char * const hostname = qs->conn->host.name;
  312. int rc;
  313. DEBUGASSERT(!qs->ssl);
  314. gnutls_init(&qs->ssl, GNUTLS_CLIENT);
  315. gnutls_session_set_ptr(qs->ssl, &qs->conn_ref);
  316. if(ngtcp2_crypto_gnutls_configure_client_session(qs->ssl) != 0) {
  317. H3BUGF(fprintf(stderr,
  318. "ngtcp2_crypto_gnutls_configure_client_session failed\n"));
  319. return 1;
  320. }
  321. rc = gnutls_priority_set_direct(qs->ssl, QUIC_PRIORITY, NULL);
  322. if(rc < 0) {
  323. H3BUGF(fprintf(stderr, "gnutls_priority_set_direct failed: %s\n",
  324. gnutls_strerror(rc)));
  325. return 1;
  326. }
  327. /* Open the file if a TLS or QUIC backend has not done this before. */
  328. Curl_tls_keylog_open();
  329. if(Curl_tls_keylog_enabled()) {
  330. gnutls_session_set_keylog_function(qs->ssl, keylog_callback);
  331. }
  332. if(qs->cred)
  333. gnutls_certificate_free_credentials(qs->cred);
  334. rc = gnutls_certificate_allocate_credentials(&qs->cred);
  335. if(rc < 0) {
  336. H3BUGF(fprintf(stderr,
  337. "gnutls_certificate_allocate_credentials failed: %s\n",
  338. gnutls_strerror(rc)));
  339. return 1;
  340. }
  341. rc = gnutls_certificate_set_x509_system_trust(qs->cred);
  342. if(rc < 0) {
  343. H3BUGF(fprintf(stderr,
  344. "gnutls_certificate_set_x509_system_trust failed: %s\n",
  345. gnutls_strerror(rc)));
  346. return 1;
  347. }
  348. rc = gnutls_credentials_set(qs->ssl, GNUTLS_CRD_CERTIFICATE, qs->cred);
  349. if(rc < 0) {
  350. H3BUGF(fprintf(stderr, "gnutls_credentials_set failed: %s\n",
  351. gnutls_strerror(rc)));
  352. return 1;
  353. }
  354. /* strip the first byte (the length) from NGHTTP3_ALPN_H3 */
  355. alpn[0].data = (unsigned char *)H3_ALPN_H3_29 + 1;
  356. alpn[0].size = sizeof(H3_ALPN_H3_29) - 2;
  357. alpn[1].data = (unsigned char *)H3_ALPN_H3 + 1;
  358. alpn[1].size = sizeof(H3_ALPN_H3) - 2;
  359. gnutls_alpn_set_protocols(qs->ssl, alpn, 2, GNUTLS_ALPN_MANDATORY);
  360. /* set SNI */
  361. gnutls_server_name_set(qs->ssl, GNUTLS_NAME_DNS, hostname, strlen(hostname));
  362. return 0;
  363. }
  364. #elif defined(USE_WOLFSSL)
  365. static WOLFSSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
  366. {
  367. struct connectdata *conn = data->conn;
  368. WOLFSSL_CTX *ssl_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
  369. if(ngtcp2_crypto_wolfssl_configure_client_context(ssl_ctx) != 0) {
  370. failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed");
  371. return NULL;
  372. }
  373. wolfSSL_CTX_set_default_verify_paths(ssl_ctx);
  374. if(wolfSSL_CTX_set_cipher_list(ssl_ctx, QUIC_CIPHERS) != 1) {
  375. char error_buffer[256];
  376. ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer));
  377. failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer);
  378. return NULL;
  379. }
  380. if(wolfSSL_CTX_set1_groups_list(ssl_ctx, (char *)QUIC_GROUPS) != 1) {
  381. failf(data, "SSL_CTX_set1_groups_list failed");
  382. return NULL;
  383. }
  384. /* Open the file if a TLS or QUIC backend has not done this before. */
  385. Curl_tls_keylog_open();
  386. if(Curl_tls_keylog_enabled()) {
  387. #if defined(HAVE_SECRET_CALLBACK)
  388. wolfSSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
  389. #else
  390. failf(data, "wolfSSL was built without keylog callback");
  391. return NULL;
  392. #endif
  393. }
  394. if(conn->ssl_config.verifypeer) {
  395. const char * const ssl_cafile = conn->ssl_config.CAfile;
  396. const char * const ssl_capath = conn->ssl_config.CApath;
  397. if(ssl_cafile || ssl_capath) {
  398. wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
  399. /* tell wolfSSL where to find CA certificates that are used to verify
  400. the server's certificate. */
  401. if(!wolfSSL_CTX_load_verify_locations(ssl_ctx, ssl_cafile, ssl_capath)) {
  402. /* Fail if we insist on successfully verifying the server. */
  403. failf(data, "error setting certificate verify locations:"
  404. " CAfile: %s CApath: %s",
  405. ssl_cafile ? ssl_cafile : "none",
  406. ssl_capath ? ssl_capath : "none");
  407. return NULL;
  408. }
  409. infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
  410. infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
  411. }
  412. #ifdef CURL_CA_FALLBACK
  413. else {
  414. /* verifying the peer without any CA certificates won't work so
  415. use wolfssl's built-in default as fallback */
  416. wolfSSL_CTX_set_default_verify_paths(ssl_ctx);
  417. }
  418. #endif
  419. }
  420. else {
  421. wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
  422. }
  423. return ssl_ctx;
  424. }
  425. /** SSL callbacks ***/
  426. static int quic_init_ssl(struct quicsocket *qs)
  427. {
  428. const uint8_t *alpn = NULL;
  429. size_t alpnlen = 0;
  430. /* this will need some attention when HTTPS proxy over QUIC get fixed */
  431. const char * const hostname = qs->conn->host.name;
  432. DEBUGASSERT(!qs->ssl);
  433. qs->ssl = SSL_new(qs->sslctx);
  434. wolfSSL_set_app_data(qs->ssl, &qs->conn_ref);
  435. wolfSSL_set_connect_state(qs->ssl);
  436. wolfSSL_set_quic_use_legacy_codepoint(qs->ssl, 0);
  437. alpn = (const uint8_t *)H3_ALPN_H3_29 H3_ALPN_H3;
  438. alpnlen = sizeof(H3_ALPN_H3_29) - 1 + sizeof(H3_ALPN_H3) - 1;
  439. if(alpn)
  440. wolfSSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen);
  441. /* set SNI */
  442. wolfSSL_UseSNI(qs->ssl, WOLFSSL_SNI_HOST_NAME,
  443. hostname, (unsigned short)strlen(hostname));
  444. return 0;
  445. }
  446. #endif /* defined(USE_WOLFSSL) */
  447. static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data)
  448. {
  449. (void)user_data;
  450. (void)tconn;
  451. return 0;
  452. }
  453. static void extend_stream_window(ngtcp2_conn *tconn,
  454. struct HTTP *stream)
  455. {
  456. size_t thismuch = stream->unacked_window;
  457. ngtcp2_conn_extend_max_stream_offset(tconn, stream->stream3_id, thismuch);
  458. ngtcp2_conn_extend_max_offset(tconn, thismuch);
  459. stream->unacked_window = 0;
  460. }
  461. static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
  462. int64_t stream_id, uint64_t offset,
  463. const uint8_t *buf, size_t buflen,
  464. void *user_data, void *stream_user_data)
  465. {
  466. struct quicsocket *qs = (struct quicsocket *)user_data;
  467. nghttp3_ssize nconsumed;
  468. int fin = (flags & NGTCP2_STREAM_DATA_FLAG_FIN) ? 1 : 0;
  469. (void)offset;
  470. (void)stream_user_data;
  471. nconsumed =
  472. nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin);
  473. if(nconsumed < 0) {
  474. ngtcp2_connection_close_error_set_application_error(
  475. &qs->last_error, nghttp3_err_infer_quic_app_error_code((int)nconsumed),
  476. NULL, 0);
  477. return NGTCP2_ERR_CALLBACK_FAILURE;
  478. }
  479. /* number of bytes inside buflen which consists of framing overhead
  480. * including QPACK HEADERS. In other words, it does not consume payload of
  481. * DATA frame. */
  482. ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed);
  483. ngtcp2_conn_extend_max_offset(tconn, nconsumed);
  484. return 0;
  485. }
  486. static int
  487. cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id,
  488. uint64_t offset, uint64_t datalen, void *user_data,
  489. void *stream_user_data)
  490. {
  491. struct quicsocket *qs = (struct quicsocket *)user_data;
  492. int rv;
  493. (void)stream_id;
  494. (void)tconn;
  495. (void)offset;
  496. (void)datalen;
  497. (void)stream_user_data;
  498. rv = nghttp3_conn_add_ack_offset(qs->h3conn, stream_id, datalen);
  499. if(rv) {
  500. return NGTCP2_ERR_CALLBACK_FAILURE;
  501. }
  502. return 0;
  503. }
  504. static int cb_stream_close(ngtcp2_conn *tconn, uint32_t flags,
  505. int64_t stream_id, uint64_t app_error_code,
  506. void *user_data, void *stream_user_data)
  507. {
  508. struct quicsocket *qs = (struct quicsocket *)user_data;
  509. int rv;
  510. (void)tconn;
  511. (void)stream_user_data;
  512. /* stream is closed... */
  513. if(!(flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET)) {
  514. app_error_code = NGHTTP3_H3_NO_ERROR;
  515. }
  516. rv = nghttp3_conn_close_stream(qs->h3conn, stream_id,
  517. app_error_code);
  518. if(rv) {
  519. ngtcp2_connection_close_error_set_application_error(
  520. &qs->last_error, nghttp3_err_infer_quic_app_error_code(rv), NULL, 0);
  521. return NGTCP2_ERR_CALLBACK_FAILURE;
  522. }
  523. return 0;
  524. }
  525. static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id,
  526. uint64_t final_size, uint64_t app_error_code,
  527. void *user_data, void *stream_user_data)
  528. {
  529. struct quicsocket *qs = (struct quicsocket *)user_data;
  530. int rv;
  531. (void)tconn;
  532. (void)final_size;
  533. (void)app_error_code;
  534. (void)stream_user_data;
  535. rv = nghttp3_conn_shutdown_stream_read(qs->h3conn, stream_id);
  536. if(rv) {
  537. return NGTCP2_ERR_CALLBACK_FAILURE;
  538. }
  539. return 0;
  540. }
  541. static int cb_stream_stop_sending(ngtcp2_conn *tconn, int64_t stream_id,
  542. uint64_t app_error_code, void *user_data,
  543. void *stream_user_data)
  544. {
  545. struct quicsocket *qs = (struct quicsocket *)user_data;
  546. int rv;
  547. (void)tconn;
  548. (void)app_error_code;
  549. (void)stream_user_data;
  550. rv = nghttp3_conn_shutdown_stream_read(qs->h3conn, stream_id);
  551. if(rv) {
  552. return NGTCP2_ERR_CALLBACK_FAILURE;
  553. }
  554. return 0;
  555. }
  556. static int cb_extend_max_local_streams_bidi(ngtcp2_conn *tconn,
  557. uint64_t max_streams,
  558. void *user_data)
  559. {
  560. (void)tconn;
  561. (void)max_streams;
  562. (void)user_data;
  563. return 0;
  564. }
  565. static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id,
  566. uint64_t max_data, void *user_data,
  567. void *stream_user_data)
  568. {
  569. struct quicsocket *qs = (struct quicsocket *)user_data;
  570. int rv;
  571. (void)tconn;
  572. (void)max_data;
  573. (void)stream_user_data;
  574. rv = nghttp3_conn_unblock_stream(qs->h3conn, stream_id);
  575. if(rv) {
  576. return NGTCP2_ERR_CALLBACK_FAILURE;
  577. }
  578. return 0;
  579. }
  580. static void cb_rand(uint8_t *dest, size_t destlen,
  581. const ngtcp2_rand_ctx *rand_ctx)
  582. {
  583. CURLcode result;
  584. (void)rand_ctx;
  585. result = Curl_rand(NULL, dest, destlen);
  586. if(result) {
  587. /* cb_rand is only used for non-cryptographic context. If Curl_rand
  588. failed, just fill 0 and call it *random*. */
  589. memset(dest, 0, destlen);
  590. }
  591. }
  592. static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
  593. uint8_t *token, size_t cidlen,
  594. void *user_data)
  595. {
  596. CURLcode result;
  597. (void)tconn;
  598. (void)user_data;
  599. result = Curl_rand(NULL, cid->data, cidlen);
  600. if(result)
  601. return NGTCP2_ERR_CALLBACK_FAILURE;
  602. cid->datalen = cidlen;
  603. result = Curl_rand(NULL, token, NGTCP2_STATELESS_RESET_TOKENLEN);
  604. if(result)
  605. return NGTCP2_ERR_CALLBACK_FAILURE;
  606. return 0;
  607. }
  608. static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_crypto_level level,
  609. void *user_data)
  610. {
  611. struct quicsocket *qs = (struct quicsocket *)user_data;
  612. (void)tconn;
  613. if(level != NGTCP2_CRYPTO_LEVEL_APPLICATION) {
  614. return 0;
  615. }
  616. if(init_ngh3_conn(qs) != CURLE_OK) {
  617. return NGTCP2_ERR_CALLBACK_FAILURE;
  618. }
  619. return 0;
  620. }
  621. static ngtcp2_callbacks ng_callbacks = {
  622. ngtcp2_crypto_client_initial_cb,
  623. NULL, /* recv_client_initial */
  624. ngtcp2_crypto_recv_crypto_data_cb,
  625. cb_handshake_completed,
  626. NULL, /* recv_version_negotiation */
  627. ngtcp2_crypto_encrypt_cb,
  628. ngtcp2_crypto_decrypt_cb,
  629. ngtcp2_crypto_hp_mask_cb,
  630. cb_recv_stream_data,
  631. cb_acked_stream_data_offset,
  632. NULL, /* stream_open */
  633. cb_stream_close,
  634. NULL, /* recv_stateless_reset */
  635. ngtcp2_crypto_recv_retry_cb,
  636. cb_extend_max_local_streams_bidi,
  637. NULL, /* extend_max_local_streams_uni */
  638. cb_rand,
  639. cb_get_new_connection_id,
  640. NULL, /* remove_connection_id */
  641. ngtcp2_crypto_update_key_cb, /* update_key */
  642. NULL, /* path_validation */
  643. NULL, /* select_preferred_addr */
  644. cb_stream_reset,
  645. NULL, /* extend_max_remote_streams_bidi */
  646. NULL, /* extend_max_remote_streams_uni */
  647. cb_extend_max_stream_data,
  648. NULL, /* dcid_status */
  649. NULL, /* handshake_confirmed */
  650. NULL, /* recv_new_token */
  651. ngtcp2_crypto_delete_crypto_aead_ctx_cb,
  652. ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
  653. NULL, /* recv_datagram */
  654. NULL, /* ack_datagram */
  655. NULL, /* lost_datagram */
  656. ngtcp2_crypto_get_path_challenge_data_cb,
  657. cb_stream_stop_sending,
  658. NULL, /* version_negotiation */
  659. cb_recv_rx_key,
  660. NULL, /* recv_tx_key */
  661. NULL, /* early_data_rejected */
  662. };
  663. /*
  664. * Might be called twice for happy eyeballs.
  665. */
  666. CURLcode Curl_quic_connect(struct Curl_easy *data,
  667. struct connectdata *conn,
  668. curl_socket_t sockfd,
  669. int sockindex,
  670. const struct sockaddr *addr,
  671. socklen_t addrlen)
  672. {
  673. int rc;
  674. int rv;
  675. CURLcode result;
  676. ngtcp2_path path; /* TODO: this must be initialized properly */
  677. struct quicsocket *qs = &conn->hequic[sockindex];
  678. char ipbuf[40];
  679. int port;
  680. int qfd;
  681. if(qs->conn)
  682. Curl_quic_disconnect(data, conn, sockindex);
  683. qs->conn = conn;
  684. /* extract the used address as a string */
  685. if(!Curl_addr2string((struct sockaddr*)addr, addrlen, ipbuf, &port)) {
  686. char buffer[STRERROR_LEN];
  687. failf(data, "ssrem inet_ntop() failed with errno %d: %s",
  688. SOCKERRNO, Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  689. return CURLE_BAD_FUNCTION_ARGUMENT;
  690. }
  691. infof(data, "Connect socket %d over QUIC to %s:%d",
  692. sockfd, ipbuf, port);
  693. qs->version = NGTCP2_PROTO_VER_MAX;
  694. #ifdef USE_OPENSSL
  695. qs->sslctx = quic_ssl_ctx(data);
  696. if(!qs->sslctx)
  697. return CURLE_QUIC_CONNECT_ERROR;
  698. result = quic_set_client_cert(data, qs);
  699. if(result)
  700. return result;
  701. #elif defined(USE_WOLFSSL)
  702. qs->sslctx = quic_ssl_ctx(data);
  703. if(!qs->sslctx)
  704. return CURLE_QUIC_CONNECT_ERROR;
  705. #endif
  706. if(quic_init_ssl(qs))
  707. return CURLE_QUIC_CONNECT_ERROR;
  708. qs->dcid.datalen = NGTCP2_MAX_CIDLEN;
  709. result = Curl_rand(data, qs->dcid.data, NGTCP2_MAX_CIDLEN);
  710. if(result)
  711. return result;
  712. qs->scid.datalen = NGTCP2_MAX_CIDLEN;
  713. result = Curl_rand(data, qs->scid.data, NGTCP2_MAX_CIDLEN);
  714. if(result)
  715. return result;
  716. (void)Curl_qlogdir(data, qs->scid.data, NGTCP2_MAX_CIDLEN, &qfd);
  717. qs->qlogfd = qfd; /* -1 if failure above */
  718. quic_settings(qs, data->set.buffer_size);
  719. qs->local_addrlen = sizeof(qs->local_addr);
  720. rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr,
  721. &qs->local_addrlen);
  722. if(rv == -1)
  723. return CURLE_QUIC_CONNECT_ERROR;
  724. ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr,
  725. qs->local_addrlen);
  726. ngtcp2_addr_init(&path.remote, addr, addrlen);
  727. rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path,
  728. NGTCP2_PROTO_VER_V1, &ng_callbacks,
  729. &qs->settings, &qs->transport_params, NULL, qs);
  730. if(rc)
  731. return CURLE_QUIC_CONNECT_ERROR;
  732. ngtcp2_conn_set_tls_native_handle(qs->qconn, qs->ssl);
  733. ngtcp2_connection_close_error_default(&qs->last_error);
  734. #if defined(__linux__) && defined(UDP_SEGMENT) && defined(HAVE_SENDMSG)
  735. qs->no_gso = FALSE;
  736. #else
  737. qs->no_gso = TRUE;
  738. #endif
  739. qs->num_blocked_pkt = 0;
  740. qs->num_blocked_pkt_sent = 0;
  741. memset(&qs->blocked_pkt, 0, sizeof(qs->blocked_pkt));
  742. qs->pktbuflen = NGTCP2_MAX_PMTUD_UDP_PAYLOAD_SIZE * MAX_PKT_BURST;
  743. qs->pktbuf = malloc(qs->pktbuflen);
  744. if(!qs->pktbuf) {
  745. ngtcp2_conn_del(qs->qconn);
  746. qs->qconn = NULL;
  747. return CURLE_OUT_OF_MEMORY;
  748. }
  749. qs->conn_ref.get_conn = get_conn;
  750. qs->conn_ref.user_data = qs;
  751. return CURLE_OK;
  752. }
  753. /*
  754. * Store ngtcp2 version info in this buffer.
  755. */
  756. void Curl_quic_ver(char *p, size_t len)
  757. {
  758. const ngtcp2_info *ng2 = ngtcp2_version(0);
  759. const nghttp3_info *ht3 = nghttp3_version(0);
  760. (void)msnprintf(p, len, "ngtcp2/%s nghttp3/%s",
  761. ng2->version_str, ht3->version_str);
  762. }
  763. static int ng_getsock(struct Curl_easy *data, struct connectdata *conn,
  764. curl_socket_t *socks)
  765. {
  766. struct SingleRequest *k = &data->req;
  767. int bitmap = GETSOCK_BLANK;
  768. struct HTTP *stream = data->req.p.http;
  769. struct quicsocket *qs = conn->quic;
  770. socks[0] = conn->sock[FIRSTSOCKET];
  771. /* in a HTTP/2 connection we can basically always get a frame so we should
  772. always be ready for one */
  773. bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
  774. /* we're still uploading or the HTTP/2 layer wants to send data */
  775. if((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND &&
  776. (!stream->h3out || stream->h3out->used < H3_SEND_SIZE) &&
  777. ngtcp2_conn_get_cwnd_left(qs->qconn) &&
  778. ngtcp2_conn_get_max_data_left(qs->qconn) &&
  779. nghttp3_conn_is_stream_writable(qs->h3conn, stream->stream3_id))
  780. bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
  781. return bitmap;
  782. }
  783. static void qs_disconnect(struct quicsocket *qs)
  784. {
  785. char buffer[NGTCP2_MAX_UDP_PAYLOAD_SIZE];
  786. ngtcp2_tstamp ts;
  787. ngtcp2_ssize rc;
  788. if(!qs->conn) /* already closed */
  789. return;
  790. ts = timestamp();
  791. rc = ngtcp2_conn_write_connection_close(qs->qconn, NULL, /* path */
  792. NULL, /* pkt_info */
  793. (uint8_t *)buffer, sizeof(buffer),
  794. &qs->last_error, ts);
  795. if(rc > 0) {
  796. while((send(qs->conn->sock[FIRSTSOCKET], buffer, rc, 0) == -1) &&
  797. SOCKERRNO == EINTR);
  798. }
  799. qs->conn = NULL;
  800. if(qs->qlogfd != -1) {
  801. close(qs->qlogfd);
  802. qs->qlogfd = -1;
  803. }
  804. if(qs->ssl)
  805. #ifdef USE_OPENSSL
  806. SSL_free(qs->ssl);
  807. #elif defined(USE_GNUTLS)
  808. gnutls_deinit(qs->ssl);
  809. #elif defined(USE_WOLFSSL)
  810. wolfSSL_free(qs->ssl);
  811. #endif
  812. qs->ssl = NULL;
  813. #ifdef USE_GNUTLS
  814. if(qs->cred) {
  815. gnutls_certificate_free_credentials(qs->cred);
  816. qs->cred = NULL;
  817. }
  818. #endif
  819. free(qs->pktbuf);
  820. nghttp3_conn_del(qs->h3conn);
  821. ngtcp2_conn_del(qs->qconn);
  822. #ifdef USE_OPENSSL
  823. SSL_CTX_free(qs->sslctx);
  824. #elif defined(USE_WOLFSSL)
  825. wolfSSL_CTX_free(qs->sslctx);
  826. #endif
  827. }
  828. void Curl_quic_disconnect(struct Curl_easy *data,
  829. struct connectdata *conn,
  830. int tempindex)
  831. {
  832. (void)data;
  833. if(conn->transport == TRNSPRT_QUIC)
  834. qs_disconnect(&conn->hequic[tempindex]);
  835. }
  836. static CURLcode ng_disconnect(struct Curl_easy *data,
  837. struct connectdata *conn,
  838. bool dead_connection)
  839. {
  840. (void)dead_connection;
  841. Curl_quic_disconnect(data, conn, 0);
  842. Curl_quic_disconnect(data, conn, 1);
  843. return CURLE_OK;
  844. }
  845. static unsigned int ng_conncheck(struct Curl_easy *data,
  846. struct connectdata *conn,
  847. unsigned int checks_to_perform)
  848. {
  849. (void)data;
  850. (void)conn;
  851. (void)checks_to_perform;
  852. return CONNRESULT_NONE;
  853. }
  854. static const struct Curl_handler Curl_handler_http3 = {
  855. "HTTPS", /* scheme */
  856. ZERO_NULL, /* setup_connection */
  857. Curl_http, /* do_it */
  858. Curl_http_done, /* done */
  859. ZERO_NULL, /* do_more */
  860. ZERO_NULL, /* connect_it */
  861. ZERO_NULL, /* connecting */
  862. ZERO_NULL, /* doing */
  863. ng_getsock, /* proto_getsock */
  864. ng_getsock, /* doing_getsock */
  865. ZERO_NULL, /* domore_getsock */
  866. ng_getsock, /* perform_getsock */
  867. ng_disconnect, /* disconnect */
  868. ZERO_NULL, /* readwrite */
  869. ng_conncheck, /* connection_check */
  870. ZERO_NULL, /* attach connection */
  871. PORT_HTTP, /* defport */
  872. CURLPROTO_HTTPS, /* protocol */
  873. CURLPROTO_HTTP, /* family */
  874. PROTOPT_SSL | PROTOPT_STREAM /* flags */
  875. };
  876. static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
  877. uint64_t app_error_code, void *user_data,
  878. void *stream_user_data)
  879. {
  880. struct Curl_easy *data = stream_user_data;
  881. struct HTTP *stream = data->req.p.http;
  882. (void)conn;
  883. (void)stream_id;
  884. (void)app_error_code;
  885. (void)user_data;
  886. H3BUGF(infof(data, "cb_h3_stream_close CALLED"));
  887. stream->closed = TRUE;
  888. stream->error3 = app_error_code;
  889. Curl_expire(data, 0, EXPIRE_QUIC);
  890. /* make sure that ngh3_stream_recv is called again to complete the transfer
  891. even if there are no more packets to be received from the server. */
  892. data->state.drain = 1;
  893. return 0;
  894. }
  895. /*
  896. * write_data() copies data to the stream's receive buffer. If not enough
  897. * space is available in the receive buffer, it copies the rest to the
  898. * stream's overflow buffer.
  899. */
  900. static CURLcode write_data(struct HTTP *stream, const void *mem, size_t memlen)
  901. {
  902. CURLcode result = CURLE_OK;
  903. const char *buf = mem;
  904. size_t ncopy = memlen;
  905. /* copy as much as possible to the receive buffer */
  906. if(stream->len) {
  907. size_t len = CURLMIN(ncopy, stream->len);
  908. memcpy(stream->mem, buf, len);
  909. stream->len -= len;
  910. stream->memlen += len;
  911. stream->mem += len;
  912. buf += len;
  913. ncopy -= len;
  914. }
  915. /* copy the rest to the overflow buffer */
  916. if(ncopy)
  917. result = Curl_dyn_addn(&stream->overflow, buf, ncopy);
  918. return result;
  919. }
  920. static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id,
  921. const uint8_t *buf, size_t buflen,
  922. void *user_data, void *stream_user_data)
  923. {
  924. struct Curl_easy *data = stream_user_data;
  925. struct HTTP *stream = data->req.p.http;
  926. CURLcode result = CURLE_OK;
  927. (void)conn;
  928. result = write_data(stream, buf, buflen);
  929. if(result) {
  930. return -1;
  931. }
  932. stream->unacked_window += buflen;
  933. (void)stream_id;
  934. (void)user_data;
  935. return 0;
  936. }
  937. static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream_id,
  938. size_t consumed, void *user_data,
  939. void *stream_user_data)
  940. {
  941. struct quicsocket *qs = user_data;
  942. (void)conn;
  943. (void)stream_user_data;
  944. (void)stream_id;
  945. ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, consumed);
  946. ngtcp2_conn_extend_max_offset(qs->qconn, consumed);
  947. return 0;
  948. }
  949. /* Decode HTTP status code. Returns -1 if no valid status code was
  950. decoded. (duplicate from http2.c) */
  951. static int decode_status_code(const uint8_t *value, size_t len)
  952. {
  953. int i;
  954. int res;
  955. if(len != 3) {
  956. return -1;
  957. }
  958. res = 0;
  959. for(i = 0; i < 3; ++i) {
  960. char c = value[i];
  961. if(c < '0' || c > '9') {
  962. return -1;
  963. }
  964. res *= 10;
  965. res += c - '0';
  966. }
  967. return res;
  968. }
  969. static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
  970. int fin, void *user_data, void *stream_user_data)
  971. {
  972. struct Curl_easy *data = stream_user_data;
  973. struct HTTP *stream = data->req.p.http;
  974. CURLcode result = CURLE_OK;
  975. (void)conn;
  976. (void)stream_id;
  977. (void)user_data;
  978. (void)fin;
  979. /* add a CRLF only if we've received some headers */
  980. if(stream->firstheader) {
  981. result = write_data(stream, "\r\n", 2);
  982. if(result) {
  983. return -1;
  984. }
  985. }
  986. if(stream->status_code / 100 != 1) {
  987. stream->bodystarted = TRUE;
  988. }
  989. return 0;
  990. }
  991. static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
  992. int32_t token, nghttp3_rcbuf *name,
  993. nghttp3_rcbuf *value, uint8_t flags,
  994. void *user_data, void *stream_user_data)
  995. {
  996. nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
  997. nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
  998. struct Curl_easy *data = stream_user_data;
  999. struct HTTP *stream = data->req.p.http;
  1000. CURLcode result = CURLE_OK;
  1001. (void)conn;
  1002. (void)stream_id;
  1003. (void)token;
  1004. (void)flags;
  1005. (void)user_data;
  1006. if(token == NGHTTP3_QPACK_TOKEN__STATUS) {
  1007. char line[14]; /* status line is always 13 characters long */
  1008. size_t ncopy;
  1009. stream->status_code = decode_status_code(h3val.base, h3val.len);
  1010. DEBUGASSERT(stream->status_code != -1);
  1011. ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n",
  1012. stream->status_code);
  1013. result = write_data(stream, line, ncopy);
  1014. if(result) {
  1015. return -1;
  1016. }
  1017. }
  1018. else {
  1019. /* store as a HTTP1-style header */
  1020. result = write_data(stream, h3name.base, h3name.len);
  1021. if(result) {
  1022. return -1;
  1023. }
  1024. result = write_data(stream, ": ", 2);
  1025. if(result) {
  1026. return -1;
  1027. }
  1028. result = write_data(stream, h3val.base, h3val.len);
  1029. if(result) {
  1030. return -1;
  1031. }
  1032. result = write_data(stream, "\r\n", 2);
  1033. if(result) {
  1034. return -1;
  1035. }
  1036. }
  1037. stream->firstheader = TRUE;
  1038. return 0;
  1039. }
  1040. static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id,
  1041. uint64_t app_error_code, void *user_data,
  1042. void *stream_user_data)
  1043. {
  1044. struct quicsocket *qs = user_data;
  1045. int rv;
  1046. (void)conn;
  1047. (void)stream_user_data;
  1048. rv = ngtcp2_conn_shutdown_stream_read(qs->qconn, stream_id, app_error_code);
  1049. if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
  1050. return NGTCP2_ERR_CALLBACK_FAILURE;
  1051. }
  1052. return 0;
  1053. }
  1054. static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t stream_id,
  1055. uint64_t app_error_code, void *user_data,
  1056. void *stream_user_data) {
  1057. struct quicsocket *qs = user_data;
  1058. int rv;
  1059. (void)conn;
  1060. (void)stream_user_data;
  1061. rv = ngtcp2_conn_shutdown_stream_write(qs->qconn, stream_id, app_error_code);
  1062. if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
  1063. return NGTCP2_ERR_CALLBACK_FAILURE;
  1064. }
  1065. return 0;
  1066. }
  1067. static nghttp3_callbacks ngh3_callbacks = {
  1068. cb_h3_acked_stream_data, /* acked_stream_data */
  1069. cb_h3_stream_close,
  1070. cb_h3_recv_data,
  1071. cb_h3_deferred_consume,
  1072. NULL, /* begin_headers */
  1073. cb_h3_recv_header,
  1074. cb_h3_end_headers,
  1075. NULL, /* begin_trailers */
  1076. cb_h3_recv_header,
  1077. NULL, /* end_trailers */
  1078. cb_h3_stop_sending,
  1079. NULL, /* end_stream */
  1080. cb_h3_reset_stream,
  1081. NULL /* shutdown */
  1082. };
  1083. static int init_ngh3_conn(struct quicsocket *qs)
  1084. {
  1085. CURLcode result;
  1086. int rc;
  1087. int64_t ctrl_stream_id, qpack_enc_stream_id, qpack_dec_stream_id;
  1088. if(ngtcp2_conn_get_max_local_streams_uni(qs->qconn) < 3) {
  1089. return CURLE_QUIC_CONNECT_ERROR;
  1090. }
  1091. nghttp3_settings_default(&qs->h3settings);
  1092. rc = nghttp3_conn_client_new(&qs->h3conn,
  1093. &ngh3_callbacks,
  1094. &qs->h3settings,
  1095. nghttp3_mem_default(),
  1096. qs);
  1097. if(rc) {
  1098. result = CURLE_OUT_OF_MEMORY;
  1099. goto fail;
  1100. }
  1101. rc = ngtcp2_conn_open_uni_stream(qs->qconn, &ctrl_stream_id, NULL);
  1102. if(rc) {
  1103. result = CURLE_QUIC_CONNECT_ERROR;
  1104. goto fail;
  1105. }
  1106. rc = nghttp3_conn_bind_control_stream(qs->h3conn, ctrl_stream_id);
  1107. if(rc) {
  1108. result = CURLE_QUIC_CONNECT_ERROR;
  1109. goto fail;
  1110. }
  1111. rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_enc_stream_id, NULL);
  1112. if(rc) {
  1113. result = CURLE_QUIC_CONNECT_ERROR;
  1114. goto fail;
  1115. }
  1116. rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_dec_stream_id, NULL);
  1117. if(rc) {
  1118. result = CURLE_QUIC_CONNECT_ERROR;
  1119. goto fail;
  1120. }
  1121. rc = nghttp3_conn_bind_qpack_streams(qs->h3conn, qpack_enc_stream_id,
  1122. qpack_dec_stream_id);
  1123. if(rc) {
  1124. result = CURLE_QUIC_CONNECT_ERROR;
  1125. goto fail;
  1126. }
  1127. return CURLE_OK;
  1128. fail:
  1129. return result;
  1130. }
  1131. static Curl_recv ngh3_stream_recv;
  1132. static Curl_send ngh3_stream_send;
  1133. static size_t drain_overflow_buffer(struct HTTP *stream)
  1134. {
  1135. size_t overlen = Curl_dyn_len(&stream->overflow);
  1136. size_t ncopy = CURLMIN(overlen, stream->len);
  1137. if(ncopy > 0) {
  1138. memcpy(stream->mem, Curl_dyn_ptr(&stream->overflow), ncopy);
  1139. stream->len -= ncopy;
  1140. stream->mem += ncopy;
  1141. stream->memlen += ncopy;
  1142. if(ncopy != overlen)
  1143. /* make the buffer only keep the tail */
  1144. (void)Curl_dyn_tail(&stream->overflow, overlen - ncopy);
  1145. else
  1146. Curl_dyn_reset(&stream->overflow);
  1147. }
  1148. return ncopy;
  1149. }
  1150. /* incoming data frames on the h3 stream */
  1151. static ssize_t ngh3_stream_recv(struct Curl_easy *data,
  1152. int sockindex,
  1153. char *buf,
  1154. size_t buffersize,
  1155. CURLcode *curlcode)
  1156. {
  1157. struct connectdata *conn = data->conn;
  1158. curl_socket_t sockfd = conn->sock[sockindex];
  1159. struct HTTP *stream = data->req.p.http;
  1160. struct quicsocket *qs = conn->quic;
  1161. if(!stream->memlen) {
  1162. /* remember where to store incoming data for this stream and how big the
  1163. buffer is */
  1164. stream->mem = buf;
  1165. stream->len = buffersize;
  1166. }
  1167. /* else, there's data in the buffer already */
  1168. /* if there's data in the overflow buffer from a previous call, copy as much
  1169. as possible to the receive buffer before receiving more */
  1170. drain_overflow_buffer(stream);
  1171. if(ng_process_ingress(data, sockfd, qs)) {
  1172. *curlcode = CURLE_RECV_ERROR;
  1173. return -1;
  1174. }
  1175. if(ng_flush_egress(data, sockfd, qs)) {
  1176. *curlcode = CURLE_SEND_ERROR;
  1177. return -1;
  1178. }
  1179. if(stream->memlen) {
  1180. ssize_t memlen = stream->memlen;
  1181. /* data arrived */
  1182. *curlcode = CURLE_OK;
  1183. /* reset to allow more data to come */
  1184. stream->memlen = 0;
  1185. stream->mem = buf;
  1186. stream->len = buffersize;
  1187. /* extend the stream window with the data we're consuming and send out
  1188. any additional packets to tell the server that we can receive more */
  1189. extend_stream_window(qs->qconn, stream);
  1190. if(ng_flush_egress(data, sockfd, qs)) {
  1191. *curlcode = CURLE_SEND_ERROR;
  1192. return -1;
  1193. }
  1194. return memlen;
  1195. }
  1196. if(stream->closed) {
  1197. if(stream->error3 != NGHTTP3_H3_NO_ERROR) {
  1198. failf(data,
  1199. "HTTP/3 stream %" PRId64 " was not closed cleanly: (err %" PRIu64
  1200. ")",
  1201. stream->stream3_id, stream->error3);
  1202. *curlcode = CURLE_HTTP3;
  1203. return -1;
  1204. }
  1205. if(!stream->bodystarted) {
  1206. failf(data,
  1207. "HTTP/3 stream %" PRId64 " was closed cleanly, but before getting"
  1208. " all response header fields, treated as error",
  1209. stream->stream3_id);
  1210. *curlcode = CURLE_HTTP3;
  1211. return -1;
  1212. }
  1213. *curlcode = CURLE_OK;
  1214. return 0;
  1215. }
  1216. infof(data, "ngh3_stream_recv returns 0 bytes and EAGAIN");
  1217. *curlcode = CURLE_AGAIN;
  1218. return -1;
  1219. }
  1220. /* this amount of data has now been acked on this stream */
  1221. static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
  1222. uint64_t datalen, void *user_data,
  1223. void *stream_user_data)
  1224. {
  1225. struct Curl_easy *data = stream_user_data;
  1226. struct HTTP *stream = data->req.p.http;
  1227. (void)user_data;
  1228. if(!data->set.postfields) {
  1229. stream->h3out->used -= datalen;
  1230. H3BUGF(infof(data,
  1231. "cb_h3_acked_stream_data, %zd bytes, %zd left unacked",
  1232. datalen, stream->h3out->used));
  1233. DEBUGASSERT(stream->h3out->used < H3_SEND_SIZE);
  1234. if(stream->h3out->used == 0) {
  1235. int rv = nghttp3_conn_resume_stream(conn, stream_id);
  1236. if(rv) {
  1237. return NGTCP2_ERR_CALLBACK_FAILURE;
  1238. }
  1239. }
  1240. }
  1241. return 0;
  1242. }
  1243. static nghttp3_ssize cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
  1244. nghttp3_vec *vec, size_t veccnt,
  1245. uint32_t *pflags, void *user_data,
  1246. void *stream_user_data)
  1247. {
  1248. struct Curl_easy *data = stream_user_data;
  1249. size_t nread;
  1250. struct HTTP *stream = data->req.p.http;
  1251. (void)conn;
  1252. (void)stream_id;
  1253. (void)user_data;
  1254. (void)veccnt;
  1255. if(data->set.postfields) {
  1256. vec[0].base = data->set.postfields;
  1257. vec[0].len = data->state.infilesize;
  1258. *pflags = NGHTTP3_DATA_FLAG_EOF;
  1259. return 1;
  1260. }
  1261. if(stream->upload_len && H3_SEND_SIZE <= stream->h3out->used) {
  1262. return NGHTTP3_ERR_WOULDBLOCK;
  1263. }
  1264. nread = CURLMIN(stream->upload_len, H3_SEND_SIZE - stream->h3out->used);
  1265. if(nread > 0) {
  1266. /* nghttp3 wants us to hold on to the data until it tells us it is okay to
  1267. delete it. Append the data at the end of the h3out buffer. Since we can
  1268. only return consecutive data, copy the amount that fits and the next
  1269. part comes in next invoke. */
  1270. struct h3out *out = stream->h3out;
  1271. if(nread + out->windex > H3_SEND_SIZE)
  1272. nread = H3_SEND_SIZE - out->windex;
  1273. memcpy(&out->buf[out->windex], stream->upload_mem, nread);
  1274. /* that's the chunk we return to nghttp3 */
  1275. vec[0].base = &out->buf[out->windex];
  1276. vec[0].len = nread;
  1277. out->windex += nread;
  1278. out->used += nread;
  1279. if(out->windex == H3_SEND_SIZE)
  1280. out->windex = 0; /* wrap */
  1281. stream->upload_mem += nread;
  1282. stream->upload_len -= nread;
  1283. if(data->state.infilesize != -1) {
  1284. stream->upload_left -= nread;
  1285. if(!stream->upload_left)
  1286. *pflags = NGHTTP3_DATA_FLAG_EOF;
  1287. }
  1288. H3BUGF(infof(data, "cb_h3_readfunction %zd bytes%s (at %zd unacked)",
  1289. nread, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"",
  1290. out->used));
  1291. }
  1292. if(stream->upload_done && !stream->upload_len &&
  1293. (stream->upload_left <= 0)) {
  1294. H3BUGF(infof(data, "cb_h3_readfunction sets EOF"));
  1295. *pflags = NGHTTP3_DATA_FLAG_EOF;
  1296. return nread ? 1 : 0;
  1297. }
  1298. else if(!nread) {
  1299. return NGHTTP3_ERR_WOULDBLOCK;
  1300. }
  1301. return 1;
  1302. }
  1303. /* Index where :authority header field will appear in request header
  1304. field list. */
  1305. #define AUTHORITY_DST_IDX 3
  1306. static CURLcode http_request(struct Curl_easy *data, const void *mem,
  1307. size_t len)
  1308. {
  1309. struct connectdata *conn = data->conn;
  1310. struct HTTP *stream = data->req.p.http;
  1311. size_t nheader;
  1312. struct quicsocket *qs = conn->quic;
  1313. CURLcode result = CURLE_OK;
  1314. nghttp3_nv *nva = NULL;
  1315. int64_t stream3_id;
  1316. int rc;
  1317. struct h3out *h3out = NULL;
  1318. struct h2h3req *hreq = NULL;
  1319. rc = ngtcp2_conn_open_bidi_stream(qs->qconn, &stream3_id, NULL);
  1320. if(rc) {
  1321. failf(data, "can get bidi streams");
  1322. result = CURLE_SEND_ERROR;
  1323. goto fail;
  1324. }
  1325. stream->stream3_id = stream3_id;
  1326. stream->h3req = TRUE; /* senf off! */
  1327. Curl_dyn_init(&stream->overflow, CURL_MAX_READ_SIZE);
  1328. result = Curl_pseudo_headers(data, mem, len, &hreq);
  1329. if(result)
  1330. goto fail;
  1331. nheader = hreq->entries;
  1332. nva = malloc(sizeof(nghttp3_nv) * nheader);
  1333. if(!nva) {
  1334. result = CURLE_OUT_OF_MEMORY;
  1335. goto fail;
  1336. }
  1337. else {
  1338. unsigned int i;
  1339. for(i = 0; i < nheader; i++) {
  1340. nva[i].name = (unsigned char *)hreq->header[i].name;
  1341. nva[i].namelen = hreq->header[i].namelen;
  1342. nva[i].value = (unsigned char *)hreq->header[i].value;
  1343. nva[i].valuelen = hreq->header[i].valuelen;
  1344. nva[i].flags = NGHTTP3_NV_FLAG_NONE;
  1345. }
  1346. }
  1347. switch(data->state.httpreq) {
  1348. case HTTPREQ_POST:
  1349. case HTTPREQ_POST_FORM:
  1350. case HTTPREQ_POST_MIME:
  1351. case HTTPREQ_PUT: {
  1352. nghttp3_data_reader data_reader;
  1353. if(data->state.infilesize != -1)
  1354. stream->upload_left = data->state.infilesize;
  1355. else
  1356. /* data sending without specifying the data amount up front */
  1357. stream->upload_left = -1; /* unknown, but not zero */
  1358. data_reader.read_data = cb_h3_readfunction;
  1359. h3out = calloc(sizeof(struct h3out), 1);
  1360. if(!h3out) {
  1361. result = CURLE_OUT_OF_MEMORY;
  1362. goto fail;
  1363. }
  1364. stream->h3out = h3out;
  1365. rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id,
  1366. nva, nheader, &data_reader, data);
  1367. if(rc) {
  1368. result = CURLE_SEND_ERROR;
  1369. goto fail;
  1370. }
  1371. break;
  1372. }
  1373. default:
  1374. stream->upload_left = 0; /* nothing left to send */
  1375. rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id,
  1376. nva, nheader, NULL, data);
  1377. if(rc) {
  1378. result = CURLE_SEND_ERROR;
  1379. goto fail;
  1380. }
  1381. break;
  1382. }
  1383. Curl_safefree(nva);
  1384. infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)",
  1385. stream3_id, (void *)data);
  1386. Curl_pseudo_free(hreq);
  1387. return CURLE_OK;
  1388. fail:
  1389. free(nva);
  1390. Curl_pseudo_free(hreq);
  1391. return result;
  1392. }
  1393. static ssize_t ngh3_stream_send(struct Curl_easy *data,
  1394. int sockindex,
  1395. const void *mem,
  1396. size_t len,
  1397. CURLcode *curlcode)
  1398. {
  1399. ssize_t sent = 0;
  1400. struct connectdata *conn = data->conn;
  1401. struct quicsocket *qs = conn->quic;
  1402. curl_socket_t sockfd = conn->sock[sockindex];
  1403. struct HTTP *stream = data->req.p.http;
  1404. if(stream->closed) {
  1405. *curlcode = CURLE_HTTP3;
  1406. return -1;
  1407. }
  1408. if(!stream->h3req) {
  1409. CURLcode result = http_request(data, mem, len);
  1410. if(result) {
  1411. *curlcode = CURLE_SEND_ERROR;
  1412. return -1;
  1413. }
  1414. /* Assume that mem of length len only includes HTTP/1.1 style
  1415. header fields. In other words, it does not contain request
  1416. body. */
  1417. sent = len;
  1418. }
  1419. else {
  1420. H3BUGF(infof(data, "ngh3_stream_send() wants to send %zd bytes",
  1421. len));
  1422. if(!stream->upload_len) {
  1423. stream->upload_mem = mem;
  1424. stream->upload_len = len;
  1425. (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id);
  1426. }
  1427. else {
  1428. *curlcode = CURLE_AGAIN;
  1429. return -1;
  1430. }
  1431. }
  1432. if(ng_flush_egress(data, sockfd, qs)) {
  1433. *curlcode = CURLE_SEND_ERROR;
  1434. return -1;
  1435. }
  1436. /* Reset post upload buffer after resumed. */
  1437. if(stream->upload_mem) {
  1438. if(data->set.postfields) {
  1439. sent = len;
  1440. }
  1441. else {
  1442. sent = len - stream->upload_len;
  1443. }
  1444. stream->upload_mem = NULL;
  1445. stream->upload_len = 0;
  1446. if(sent == 0) {
  1447. *curlcode = CURLE_AGAIN;
  1448. return -1;
  1449. }
  1450. }
  1451. *curlcode = CURLE_OK;
  1452. return sent;
  1453. }
  1454. static CURLcode ng_has_connected(struct Curl_easy *data,
  1455. struct connectdata *conn, int tempindex)
  1456. {
  1457. CURLcode result = CURLE_OK;
  1458. conn->recv[FIRSTSOCKET] = ngh3_stream_recv;
  1459. conn->send[FIRSTSOCKET] = ngh3_stream_send;
  1460. conn->handler = &Curl_handler_http3;
  1461. conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
  1462. conn->httpversion = 30;
  1463. conn->bundle->multiuse = BUNDLE_MULTIPLEX;
  1464. conn->quic = &conn->hequic[tempindex];
  1465. if(conn->ssl_config.verifyhost) {
  1466. #ifdef USE_OPENSSL
  1467. X509 *server_cert;
  1468. server_cert = SSL_get_peer_certificate(conn->quic->ssl);
  1469. if(!server_cert) {
  1470. return CURLE_PEER_FAILED_VERIFICATION;
  1471. }
  1472. result = Curl_ossl_verifyhost(data, conn, server_cert);
  1473. X509_free(server_cert);
  1474. if(result)
  1475. return result;
  1476. infof(data, "Verified certificate just fine");
  1477. #elif defined(USE_GNUTLS)
  1478. result = Curl_gtls_verifyserver(data, conn, conn->quic->ssl, FIRSTSOCKET);
  1479. #elif defined(USE_WOLFSSL)
  1480. char *snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
  1481. if(!snihost ||
  1482. (wolfSSL_check_domain_name(conn->quic->ssl, snihost) == SSL_FAILURE))
  1483. return CURLE_PEER_FAILED_VERIFICATION;
  1484. infof(data, "Verified certificate just fine");
  1485. #endif
  1486. }
  1487. else
  1488. infof(data, "Skipped certificate verification");
  1489. #ifdef USE_OPENSSL
  1490. if(data->set.ssl.certinfo)
  1491. /* asked to gather certificate info */
  1492. (void)Curl_ossl_certchain(data, conn->quic->ssl);
  1493. #endif
  1494. return result;
  1495. }
  1496. /*
  1497. * There can be multiple connection attempts going on in parallel.
  1498. */
  1499. CURLcode Curl_quic_is_connected(struct Curl_easy *data,
  1500. struct connectdata *conn,
  1501. int sockindex,
  1502. bool *done)
  1503. {
  1504. CURLcode result;
  1505. struct quicsocket *qs = &conn->hequic[sockindex];
  1506. curl_socket_t sockfd = conn->tempsock[sockindex];
  1507. result = ng_process_ingress(data, sockfd, qs);
  1508. if(result)
  1509. goto error;
  1510. result = ng_flush_egress(data, sockfd, qs);
  1511. if(result)
  1512. goto error;
  1513. if(ngtcp2_conn_get_handshake_completed(qs->qconn)) {
  1514. result = ng_has_connected(data, conn, sockindex);
  1515. if(!result)
  1516. *done = TRUE;
  1517. }
  1518. return result;
  1519. error:
  1520. (void)qs_disconnect(qs);
  1521. return result;
  1522. }
  1523. static CURLcode ng_process_ingress(struct Curl_easy *data,
  1524. curl_socket_t sockfd,
  1525. struct quicsocket *qs)
  1526. {
  1527. ssize_t recvd;
  1528. int rv;
  1529. uint8_t buf[65536];
  1530. size_t bufsize = sizeof(buf);
  1531. struct sockaddr_storage remote_addr;
  1532. socklen_t remote_addrlen;
  1533. ngtcp2_path path;
  1534. ngtcp2_tstamp ts = timestamp();
  1535. ngtcp2_pkt_info pi = { 0 };
  1536. for(;;) {
  1537. remote_addrlen = sizeof(remote_addr);
  1538. while((recvd = recvfrom(sockfd, (char *)buf, bufsize, 0,
  1539. (struct sockaddr *)&remote_addr,
  1540. &remote_addrlen)) == -1 &&
  1541. SOCKERRNO == EINTR)
  1542. ;
  1543. if(recvd == -1) {
  1544. if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK)
  1545. break;
  1546. failf(data, "ngtcp2: recvfrom() unexpectedly returned %zd", recvd);
  1547. return CURLE_RECV_ERROR;
  1548. }
  1549. ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr,
  1550. qs->local_addrlen);
  1551. ngtcp2_addr_init(&path.remote, (struct sockaddr *)&remote_addr,
  1552. remote_addrlen);
  1553. rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts);
  1554. if(rv) {
  1555. if(!qs->last_error.error_code) {
  1556. if(rv == NGTCP2_ERR_CRYPTO) {
  1557. ngtcp2_connection_close_error_set_transport_error_tls_alert(
  1558. &qs->last_error, ngtcp2_conn_get_tls_alert(qs->qconn), NULL, 0);
  1559. }
  1560. else {
  1561. ngtcp2_connection_close_error_set_transport_error_liberr(
  1562. &qs->last_error, rv, NULL, 0);
  1563. }
  1564. }
  1565. if(rv == NGTCP2_ERR_CRYPTO)
  1566. /* this is a "TLS problem", but a failed certificate verification
  1567. is a common reason for this */
  1568. return CURLE_PEER_FAILED_VERIFICATION;
  1569. return CURLE_RECV_ERROR;
  1570. }
  1571. }
  1572. return CURLE_OK;
  1573. }
  1574. static CURLcode do_sendmsg(size_t *sent, struct Curl_easy *data, int sockfd,
  1575. struct quicsocket *qs, const uint8_t *pkt,
  1576. size_t pktlen, size_t gsolen);
  1577. static CURLcode send_packet_no_gso(size_t *psent, struct Curl_easy *data,
  1578. int sockfd, struct quicsocket *qs,
  1579. const uint8_t *pkt, size_t pktlen,
  1580. size_t gsolen)
  1581. {
  1582. const uint8_t *p, *end = pkt + pktlen;
  1583. size_t sent;
  1584. *psent = 0;
  1585. for(p = pkt; p < end; p += gsolen) {
  1586. size_t len = CURLMIN(gsolen, (size_t)(end - p));
  1587. CURLcode curlcode = do_sendmsg(&sent, data, sockfd, qs, p, len, len);
  1588. if(curlcode != CURLE_OK) {
  1589. return curlcode;
  1590. }
  1591. *psent += sent;
  1592. }
  1593. return CURLE_OK;
  1594. }
  1595. static CURLcode do_sendmsg(size_t *psent, struct Curl_easy *data, int sockfd,
  1596. struct quicsocket *qs, const uint8_t *pkt,
  1597. size_t pktlen, size_t gsolen)
  1598. {
  1599. #ifdef HAVE_SENDMSG
  1600. struct iovec msg_iov;
  1601. struct msghdr msg = {0};
  1602. ssize_t sent;
  1603. #if defined(__linux__) && defined(UDP_SEGMENT)
  1604. uint8_t msg_ctrl[32];
  1605. struct cmsghdr *cm;
  1606. #endif
  1607. *psent = 0;
  1608. msg_iov.iov_base = (uint8_t *)pkt;
  1609. msg_iov.iov_len = pktlen;
  1610. msg.msg_iov = &msg_iov;
  1611. msg.msg_iovlen = 1;
  1612. #if defined(__linux__) && defined(UDP_SEGMENT)
  1613. if(pktlen > gsolen) {
  1614. /* Only set this, when we need it. macOS, for example,
  1615. * does not seem to like a msg_control of length 0. */
  1616. msg.msg_control = msg_ctrl;
  1617. assert(sizeof(msg_ctrl) >= CMSG_SPACE(sizeof(uint16_t)));
  1618. msg.msg_controllen = CMSG_SPACE(sizeof(uint16_t));
  1619. cm = CMSG_FIRSTHDR(&msg);
  1620. cm->cmsg_level = SOL_UDP;
  1621. cm->cmsg_type = UDP_SEGMENT;
  1622. cm->cmsg_len = CMSG_LEN(sizeof(uint16_t));
  1623. *(uint16_t *)(void *)CMSG_DATA(cm) = gsolen & 0xffff;
  1624. }
  1625. #endif
  1626. while((sent = sendmsg(sockfd, &msg, 0)) == -1 && SOCKERRNO == EINTR)
  1627. ;
  1628. if(sent == -1) {
  1629. switch(SOCKERRNO) {
  1630. case EAGAIN:
  1631. #if EAGAIN != EWOULDBLOCK
  1632. case EWOULDBLOCK:
  1633. #endif
  1634. return CURLE_AGAIN;
  1635. case EMSGSIZE:
  1636. /* UDP datagram is too large; caused by PMTUD. Just let it be lost. */
  1637. break;
  1638. case EIO:
  1639. if(pktlen > gsolen) {
  1640. /* GSO failure */
  1641. failf(data, "sendmsg() returned %zd (errno %d); disable GSO", sent,
  1642. SOCKERRNO);
  1643. qs->no_gso = TRUE;
  1644. return send_packet_no_gso(psent, data, sockfd, qs, pkt, pktlen,
  1645. gsolen);
  1646. }
  1647. /* FALLTHROUGH */
  1648. default:
  1649. failf(data, "sendmsg() returned %zd (errno %d)", sent, SOCKERRNO);
  1650. return CURLE_SEND_ERROR;
  1651. }
  1652. }
  1653. else {
  1654. assert(pktlen == (size_t)sent);
  1655. }
  1656. #else
  1657. ssize_t sent;
  1658. (void)qs;
  1659. (void)gsolen;
  1660. *psent = 0;
  1661. while((sent = send(sockfd, (const char *)pkt, pktlen, 0)) == -1 &&
  1662. SOCKERRNO == EINTR)
  1663. ;
  1664. if(sent == -1) {
  1665. if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
  1666. return CURLE_AGAIN;
  1667. }
  1668. else {
  1669. failf(data, "send() returned %zd (errno %d)", sent, SOCKERRNO);
  1670. if(SOCKERRNO != EMSGSIZE) {
  1671. return CURLE_SEND_ERROR;
  1672. }
  1673. /* UDP datagram is too large; caused by PMTUD. Just let it be
  1674. lost. */
  1675. }
  1676. }
  1677. #endif
  1678. *psent = pktlen;
  1679. return CURLE_OK;
  1680. }
  1681. static CURLcode send_packet(size_t *psent, struct Curl_easy *data, int sockfd,
  1682. struct quicsocket *qs, const uint8_t *pkt,
  1683. size_t pktlen, size_t gsolen)
  1684. {
  1685. if(qs->no_gso && pktlen > gsolen) {
  1686. return send_packet_no_gso(psent, data, sockfd, qs, pkt, pktlen, gsolen);
  1687. }
  1688. return do_sendmsg(psent, data, sockfd, qs, pkt, pktlen, gsolen);
  1689. }
  1690. static void push_blocked_pkt(struct quicsocket *qs, const uint8_t *pkt,
  1691. size_t pktlen, size_t gsolen)
  1692. {
  1693. struct blocked_pkt *blkpkt;
  1694. assert(qs->num_blocked_pkt <
  1695. sizeof(qs->blocked_pkt) / sizeof(qs->blocked_pkt[0]));
  1696. blkpkt = &qs->blocked_pkt[qs->num_blocked_pkt++];
  1697. blkpkt->pkt = pkt;
  1698. blkpkt->pktlen = pktlen;
  1699. blkpkt->gsolen = gsolen;
  1700. }
  1701. static CURLcode send_blocked_pkt(struct Curl_easy *data, int sockfd,
  1702. struct quicsocket *qs)
  1703. {
  1704. size_t sent;
  1705. CURLcode curlcode;
  1706. struct blocked_pkt *blkpkt;
  1707. for(; qs->num_blocked_pkt_sent < qs->num_blocked_pkt;
  1708. ++qs->num_blocked_pkt_sent) {
  1709. blkpkt = &qs->blocked_pkt[qs->num_blocked_pkt_sent];
  1710. curlcode = send_packet(&sent, data, sockfd, qs, blkpkt->pkt,
  1711. blkpkt->pktlen, blkpkt->gsolen);
  1712. if(curlcode) {
  1713. if(curlcode == CURLE_AGAIN) {
  1714. blkpkt->pkt += sent;
  1715. blkpkt->pktlen -= sent;
  1716. }
  1717. return curlcode;
  1718. }
  1719. }
  1720. qs->num_blocked_pkt = 0;
  1721. qs->num_blocked_pkt_sent = 0;
  1722. return CURLE_OK;
  1723. }
  1724. static CURLcode ng_flush_egress(struct Curl_easy *data,
  1725. int sockfd,
  1726. struct quicsocket *qs)
  1727. {
  1728. int rv;
  1729. size_t sent;
  1730. ngtcp2_ssize outlen;
  1731. uint8_t *outpos = qs->pktbuf;
  1732. size_t max_udp_payload_size =
  1733. ngtcp2_conn_get_max_tx_udp_payload_size(qs->qconn);
  1734. size_t path_max_udp_payload_size =
  1735. ngtcp2_conn_get_path_max_tx_udp_payload_size(qs->qconn);
  1736. size_t max_pktcnt =
  1737. CURLMIN(MAX_PKT_BURST, qs->pktbuflen / max_udp_payload_size);
  1738. size_t pktcnt = 0;
  1739. size_t gsolen;
  1740. ngtcp2_path_storage ps;
  1741. ngtcp2_tstamp ts = timestamp();
  1742. ngtcp2_tstamp expiry;
  1743. ngtcp2_duration timeout;
  1744. int64_t stream_id;
  1745. nghttp3_ssize veccnt;
  1746. int fin;
  1747. nghttp3_vec vec[16];
  1748. ngtcp2_ssize ndatalen;
  1749. uint32_t flags;
  1750. CURLcode curlcode;
  1751. rv = ngtcp2_conn_handle_expiry(qs->qconn, ts);
  1752. if(rv) {
  1753. failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
  1754. ngtcp2_strerror(rv));
  1755. ngtcp2_connection_close_error_set_transport_error_liberr(&qs->last_error,
  1756. rv, NULL, 0);
  1757. return CURLE_SEND_ERROR;
  1758. }
  1759. if(qs->num_blocked_pkt) {
  1760. curlcode = send_blocked_pkt(data, sockfd, qs);
  1761. if(curlcode) {
  1762. if(curlcode == CURLE_AGAIN) {
  1763. Curl_expire(data, 1, EXPIRE_QUIC);
  1764. return CURLE_OK;
  1765. }
  1766. return curlcode;
  1767. }
  1768. }
  1769. ngtcp2_path_storage_zero(&ps);
  1770. for(;;) {
  1771. veccnt = 0;
  1772. stream_id = -1;
  1773. fin = 0;
  1774. if(qs->h3conn && ngtcp2_conn_get_max_data_left(qs->qconn)) {
  1775. veccnt = nghttp3_conn_writev_stream(qs->h3conn, &stream_id, &fin, vec,
  1776. sizeof(vec) / sizeof(vec[0]));
  1777. if(veccnt < 0) {
  1778. failf(data, "nghttp3_conn_writev_stream returned error: %s",
  1779. nghttp3_strerror((int)veccnt));
  1780. ngtcp2_connection_close_error_set_application_error(
  1781. &qs->last_error,
  1782. nghttp3_err_infer_quic_app_error_code((int)veccnt), NULL, 0);
  1783. return CURLE_SEND_ERROR;
  1784. }
  1785. }
  1786. flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
  1787. (fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
  1788. outlen = ngtcp2_conn_writev_stream(qs->qconn, &ps.path, NULL, outpos,
  1789. max_udp_payload_size,
  1790. &ndatalen, flags, stream_id,
  1791. (const ngtcp2_vec *)vec, veccnt, ts);
  1792. if(outlen == 0) {
  1793. if(outpos != qs->pktbuf) {
  1794. curlcode = send_packet(&sent, data, sockfd, qs, qs->pktbuf,
  1795. outpos - qs->pktbuf, gsolen);
  1796. if(curlcode) {
  1797. if(curlcode == CURLE_AGAIN) {
  1798. push_blocked_pkt(qs, qs->pktbuf + sent, outpos - qs->pktbuf - sent,
  1799. gsolen);
  1800. Curl_expire(data, 1, EXPIRE_QUIC);
  1801. return CURLE_OK;
  1802. }
  1803. return curlcode;
  1804. }
  1805. }
  1806. break;
  1807. }
  1808. if(outlen < 0) {
  1809. switch(outlen) {
  1810. case NGTCP2_ERR_STREAM_DATA_BLOCKED:
  1811. assert(ndatalen == -1);
  1812. nghttp3_conn_block_stream(qs->h3conn, stream_id);
  1813. continue;
  1814. case NGTCP2_ERR_STREAM_SHUT_WR:
  1815. assert(ndatalen == -1);
  1816. nghttp3_conn_shutdown_stream_write(qs->h3conn, stream_id);
  1817. continue;
  1818. case NGTCP2_ERR_WRITE_MORE:
  1819. assert(ndatalen >= 0);
  1820. rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen);
  1821. if(rv) {
  1822. failf(data, "nghttp3_conn_add_write_offset returned error: %s\n",
  1823. nghttp3_strerror(rv));
  1824. return CURLE_SEND_ERROR;
  1825. }
  1826. continue;
  1827. default:
  1828. assert(ndatalen == -1);
  1829. failf(data, "ngtcp2_conn_writev_stream returned error: %s",
  1830. ngtcp2_strerror((int)outlen));
  1831. ngtcp2_connection_close_error_set_transport_error_liberr(
  1832. &qs->last_error, (int)outlen, NULL, 0);
  1833. return CURLE_SEND_ERROR;
  1834. }
  1835. }
  1836. else if(ndatalen >= 0) {
  1837. rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen);
  1838. if(rv) {
  1839. failf(data, "nghttp3_conn_add_write_offset returned error: %s\n",
  1840. nghttp3_strerror(rv));
  1841. return CURLE_SEND_ERROR;
  1842. }
  1843. }
  1844. outpos += outlen;
  1845. if(pktcnt == 0) {
  1846. gsolen = outlen;
  1847. }
  1848. else if((size_t)outlen > gsolen ||
  1849. (gsolen > path_max_udp_payload_size &&
  1850. (size_t)outlen != gsolen)) {
  1851. /* Packet larger than path_max_udp_payload_size is PMTUD probe
  1852. packet and it might not be sent because of EMSGSIZE. Send
  1853. them separately to minimize the loss. */
  1854. curlcode = send_packet(&sent, data, sockfd, qs, qs->pktbuf,
  1855. outpos - outlen - qs->pktbuf, gsolen);
  1856. if(curlcode) {
  1857. if(curlcode == CURLE_AGAIN) {
  1858. push_blocked_pkt(qs, qs->pktbuf + sent,
  1859. outpos - outlen - qs->pktbuf - sent, gsolen);
  1860. push_blocked_pkt(qs, outpos - outlen, outlen, outlen);
  1861. Curl_expire(data, 1, EXPIRE_QUIC);
  1862. return CURLE_OK;
  1863. }
  1864. return curlcode;
  1865. }
  1866. curlcode = send_packet(&sent, data, sockfd, qs, outpos - outlen, outlen,
  1867. outlen);
  1868. if(curlcode) {
  1869. if(curlcode == CURLE_AGAIN) {
  1870. assert(0 == sent);
  1871. push_blocked_pkt(qs, outpos - outlen, outlen, outlen);
  1872. Curl_expire(data, 1, EXPIRE_QUIC);
  1873. return CURLE_OK;
  1874. }
  1875. return curlcode;
  1876. }
  1877. pktcnt = 0;
  1878. outpos = qs->pktbuf;
  1879. continue;
  1880. }
  1881. if(++pktcnt >= max_pktcnt || (size_t)outlen < gsolen) {
  1882. curlcode = send_packet(&sent, data, sockfd, qs, qs->pktbuf,
  1883. outpos - qs->pktbuf, gsolen);
  1884. if(curlcode) {
  1885. if(curlcode == CURLE_AGAIN) {
  1886. push_blocked_pkt(qs, qs->pktbuf + sent, outpos - qs->pktbuf - sent,
  1887. gsolen);
  1888. Curl_expire(data, 1, EXPIRE_QUIC);
  1889. return CURLE_OK;
  1890. }
  1891. return curlcode;
  1892. }
  1893. pktcnt = 0;
  1894. outpos = qs->pktbuf;
  1895. }
  1896. }
  1897. expiry = ngtcp2_conn_get_expiry(qs->qconn);
  1898. if(expiry != UINT64_MAX) {
  1899. if(expiry <= ts) {
  1900. timeout = 0;
  1901. }
  1902. else {
  1903. timeout = expiry - ts;
  1904. if(timeout % NGTCP2_MILLISECONDS) {
  1905. timeout += NGTCP2_MILLISECONDS;
  1906. }
  1907. }
  1908. Curl_expire(data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
  1909. }
  1910. return CURLE_OK;
  1911. }
  1912. /*
  1913. * Called from transfer.c:done_sending when we stop HTTP/3 uploading.
  1914. */
  1915. CURLcode Curl_quic_done_sending(struct Curl_easy *data)
  1916. {
  1917. struct connectdata *conn = data->conn;
  1918. DEBUGASSERT(conn);
  1919. if(conn->handler == &Curl_handler_http3) {
  1920. /* only for HTTP/3 transfers */
  1921. struct HTTP *stream = data->req.p.http;
  1922. struct quicsocket *qs = conn->quic;
  1923. stream->upload_done = TRUE;
  1924. (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id);
  1925. }
  1926. return CURLE_OK;
  1927. }
  1928. /*
  1929. * Called from http.c:Curl_http_done when a request completes.
  1930. */
  1931. void Curl_quic_done(struct Curl_easy *data, bool premature)
  1932. {
  1933. (void)premature;
  1934. if(data->conn->handler == &Curl_handler_http3) {
  1935. /* only for HTTP/3 transfers */
  1936. struct HTTP *stream = data->req.p.http;
  1937. Curl_dyn_free(&stream->overflow);
  1938. free(stream->h3out);
  1939. }
  1940. }
  1941. /*
  1942. * Called from transfer.c:data_pending to know if we should keep looping
  1943. * to receive more data from the connection.
  1944. */
  1945. bool Curl_quic_data_pending(const struct Curl_easy *data)
  1946. {
  1947. /* We may have received more data than we're able to hold in the receive
  1948. buffer and allocated an overflow buffer. Since it's possible that
  1949. there's no more data coming on the socket, we need to keep reading
  1950. until the overflow buffer is empty. */
  1951. const struct HTTP *stream = data->req.p.http;
  1952. return Curl_dyn_len(&stream->overflow) > 0;
  1953. }
  1954. /*
  1955. * Called from transfer.c:Curl_readwrite when neither HTTP level read
  1956. * nor write is performed. It is a good place to handle timer expiry
  1957. * for QUIC transport.
  1958. */
  1959. CURLcode Curl_quic_idle(struct Curl_easy *data)
  1960. {
  1961. struct connectdata *conn = data->conn;
  1962. curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
  1963. struct quicsocket *qs = conn->quic;
  1964. if(ngtcp2_conn_get_expiry(qs->qconn) > timestamp()) {
  1965. return CURLE_OK;
  1966. }
  1967. if(ng_flush_egress(data, sockfd, qs)) {
  1968. return CURLE_SEND_ERROR;
  1969. }
  1970. return CURLE_OK;
  1971. }
  1972. #endif