curl_osslq.c 69 KB

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