ngtcp2_rtb.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501
  1. /*
  2. * ngtcp2
  3. *
  4. * Copyright (c) 2017 ngtcp2 contributors
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sublicense, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  21. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. */
  25. #include "ngtcp2_rtb.h"
  26. #include <assert.h>
  27. #include <string.h>
  28. #include "ngtcp2_macro.h"
  29. #include "ngtcp2_conn.h"
  30. #include "ngtcp2_log.h"
  31. #include "ngtcp2_vec.h"
  32. #include "ngtcp2_cc.h"
  33. #include "ngtcp2_rcvry.h"
  34. #include "ngtcp2_rst.h"
  35. #include "ngtcp2_unreachable.h"
  36. #include "ngtcp2_tstamp.h"
  37. #include "ngtcp2_frame_chain.h"
  38. ngtcp2_objalloc_def(rtb_entry, ngtcp2_rtb_entry, oplent)
  39. static void rtb_entry_init(ngtcp2_rtb_entry *ent, const ngtcp2_pkt_hd *hd,
  40. ngtcp2_frame_chain *frc, ngtcp2_tstamp ts,
  41. size_t pktlen, uint16_t flags) {
  42. memset(ent, 0, sizeof(*ent));
  43. ent->hd.pkt_num = hd->pkt_num;
  44. ent->hd.type = hd->type;
  45. ent->hd.flags = hd->flags;
  46. ent->frc = frc;
  47. ent->ts = ts;
  48. ent->lost_ts = UINT64_MAX;
  49. ent->pktlen = pktlen;
  50. ent->flags = flags;
  51. }
  52. int ngtcp2_rtb_entry_objalloc_new(ngtcp2_rtb_entry **pent,
  53. const ngtcp2_pkt_hd *hd,
  54. ngtcp2_frame_chain *frc, ngtcp2_tstamp ts,
  55. size_t pktlen, uint16_t flags,
  56. ngtcp2_objalloc *objalloc) {
  57. *pent = ngtcp2_objalloc_rtb_entry_get(objalloc);
  58. if (*pent == NULL) {
  59. return NGTCP2_ERR_NOMEM;
  60. }
  61. rtb_entry_init(*pent, hd, frc, ts, pktlen, flags);
  62. return 0;
  63. }
  64. void ngtcp2_rtb_entry_objalloc_del(ngtcp2_rtb_entry *ent,
  65. ngtcp2_objalloc *objalloc,
  66. ngtcp2_objalloc *frc_objalloc,
  67. const ngtcp2_mem *mem) {
  68. ngtcp2_frame_chain_list_objalloc_del(ent->frc, frc_objalloc, mem);
  69. ent->frc = NULL;
  70. ngtcp2_objalloc_rtb_entry_release(objalloc, ent);
  71. }
  72. void ngtcp2_rtb_init(ngtcp2_rtb *rtb, ngtcp2_rst *rst, ngtcp2_cc *cc,
  73. int64_t cc_pkt_num, ngtcp2_log *log, ngtcp2_qlog *qlog,
  74. ngtcp2_objalloc *rtb_entry_objalloc,
  75. ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
  76. rtb->rtb_entry_objalloc = rtb_entry_objalloc;
  77. rtb->frc_objalloc = frc_objalloc;
  78. ngtcp2_ksl_init(&rtb->ents, ngtcp2_ksl_int64_greater,
  79. ngtcp2_ksl_int64_greater_search, sizeof(int64_t), mem);
  80. rtb->rst = rst;
  81. rtb->cc = cc;
  82. rtb->log = log;
  83. rtb->qlog = qlog;
  84. rtb->mem = mem;
  85. rtb->largest_acked_tx_pkt_num = -1;
  86. rtb->num_ack_eliciting = 0;
  87. rtb->num_retransmittable = 0;
  88. rtb->num_pto_eliciting = 0;
  89. rtb->probe_pkt_left = 0;
  90. rtb->cc_pkt_num = cc_pkt_num;
  91. rtb->cc_bytes_in_flight = 0;
  92. rtb->persistent_congestion_start_ts = UINT64_MAX;
  93. rtb->num_lost_pkts = 0;
  94. rtb->num_lost_pmtud_pkts = 0;
  95. }
  96. void ngtcp2_rtb_free(ngtcp2_rtb *rtb) {
  97. ngtcp2_ksl_it it;
  98. if (rtb == NULL) {
  99. return;
  100. }
  101. it = ngtcp2_ksl_begin(&rtb->ents);
  102. for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) {
  103. ngtcp2_rtb_entry_objalloc_del(ngtcp2_ksl_it_get(&it),
  104. rtb->rtb_entry_objalloc, rtb->frc_objalloc,
  105. rtb->mem);
  106. }
  107. ngtcp2_ksl_free(&rtb->ents);
  108. }
  109. static void rtb_on_add(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
  110. ngtcp2_conn_stat *cstat) {
  111. ngtcp2_rst_on_pkt_sent(rtb->rst, ent, cstat);
  112. assert(rtb->cc_pkt_num <= ent->hd.pkt_num);
  113. cstat->bytes_in_flight += ent->pktlen;
  114. rtb->cc_bytes_in_flight += ent->pktlen;
  115. ngtcp2_rst_update_app_limited(rtb->rst, cstat);
  116. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
  117. ++rtb->num_ack_eliciting;
  118. }
  119. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) {
  120. ++rtb->num_retransmittable;
  121. }
  122. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING) {
  123. ++rtb->num_pto_eliciting;
  124. }
  125. }
  126. static size_t rtb_on_remove(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
  127. ngtcp2_conn_stat *cstat) {
  128. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) {
  129. assert(rtb->num_lost_pkts);
  130. --rtb->num_lost_pkts;
  131. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
  132. assert(rtb->num_lost_pmtud_pkts);
  133. --rtb->num_lost_pmtud_pkts;
  134. }
  135. return 0;
  136. }
  137. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
  138. assert(rtb->num_ack_eliciting);
  139. --rtb->num_ack_eliciting;
  140. }
  141. if ((ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) &&
  142. !(ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED)) {
  143. assert(rtb->num_retransmittable);
  144. --rtb->num_retransmittable;
  145. }
  146. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING) {
  147. assert(rtb->num_pto_eliciting);
  148. --rtb->num_pto_eliciting;
  149. }
  150. if (rtb->cc_pkt_num <= ent->hd.pkt_num) {
  151. assert(cstat->bytes_in_flight >= ent->pktlen);
  152. cstat->bytes_in_flight -= ent->pktlen;
  153. assert(rtb->cc_bytes_in_flight >= ent->pktlen);
  154. rtb->cc_bytes_in_flight -= ent->pktlen;
  155. /* If PMTUD packet is lost, we do not report the lost bytes to the
  156. caller in order to ignore loss of PMTUD packet. */
  157. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
  158. return 0;
  159. }
  160. return ent->pktlen;
  161. }
  162. return 0;
  163. }
  164. /* NGTCP2_RECLAIM_FLAG_NONE indicates that no flag is set. */
  165. #define NGTCP2_RECLAIM_FLAG_NONE 0x00u
  166. /* NGTCP2_RECLAIM_FLAG_ON_LOSS indicates that frames are reclaimed
  167. because of the packet loss.*/
  168. #define NGTCP2_RECLAIM_FLAG_ON_LOSS 0x01u
  169. /*
  170. * rtb_reclaim_frame copies and queues frames included in |ent| for
  171. * retransmission. The frames are not deleted from |ent|. It returns
  172. * the number of frames queued. |flags| is bitwise OR of 0 or more of
  173. * NGTCP2_RECLAIM_FLAG_*.
  174. */
  175. static ngtcp2_ssize rtb_reclaim_frame(ngtcp2_rtb *rtb, uint8_t flags,
  176. ngtcp2_conn *conn, ngtcp2_pktns *pktns,
  177. ngtcp2_rtb_entry *ent) {
  178. ngtcp2_frame_chain *frc, *nfrc, **pfrc = &pktns->tx.frq;
  179. ngtcp2_frame *fr;
  180. ngtcp2_strm *strm;
  181. ngtcp2_range gap, range;
  182. size_t num_reclaimed = 0;
  183. int rv;
  184. assert(ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE);
  185. /* TODO Reconsider the order of pfrc */
  186. for (frc = ent->frc; frc; frc = frc->next) {
  187. fr = &frc->fr;
  188. /* Check that a late ACK acknowledged this frame. */
  189. if (frc->binder &&
  190. (frc->binder->flags & NGTCP2_FRAME_CHAIN_BINDER_FLAG_ACK)) {
  191. continue;
  192. }
  193. switch (frc->fr.type) {
  194. case NGTCP2_FRAME_STREAM:
  195. strm = ngtcp2_conn_find_stream(conn, fr->stream.stream_id);
  196. if (strm == NULL || (strm->flags & NGTCP2_STRM_FLAG_RESET_STREAM)) {
  197. continue;
  198. }
  199. gap = ngtcp2_strm_get_unacked_range_after(strm, fr->stream.offset);
  200. range.begin = fr->stream.offset;
  201. range.end =
  202. fr->stream.offset + ngtcp2_vec_len(fr->stream.data, fr->stream.datacnt);
  203. range = ngtcp2_range_intersect(&range, &gap);
  204. if (ngtcp2_range_len(&range) == 0) {
  205. if (!fr->stream.fin) {
  206. /* 0 length STREAM frame with offset == 0 must be
  207. retransmitted if no non-empty data are sent to this
  208. stream, fin flag is not set, and no data in this stream
  209. are acknowledged. */
  210. if (fr->stream.offset != 0 || fr->stream.datacnt != 0 ||
  211. strm->tx.offset ||
  212. (strm->flags &
  213. (NGTCP2_STRM_FLAG_SHUT_WR | NGTCP2_STRM_FLAG_ANY_ACKED))) {
  214. continue;
  215. }
  216. } else if (strm->flags & NGTCP2_STRM_FLAG_FIN_ACKED) {
  217. continue;
  218. }
  219. }
  220. if ((flags & NGTCP2_RECLAIM_FLAG_ON_LOSS) &&
  221. ent->hd.pkt_num != strm->tx.last_lost_pkt_num) {
  222. strm->tx.last_lost_pkt_num = ent->hd.pkt_num;
  223. ++strm->tx.loss_count;
  224. }
  225. rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new(
  226. &nfrc, fr->stream.datacnt, rtb->frc_objalloc, rtb->mem);
  227. if (rv != 0) {
  228. return rv;
  229. }
  230. nfrc->fr = *fr;
  231. ngtcp2_vec_copy(nfrc->fr.stream.data, fr->stream.data,
  232. fr->stream.datacnt);
  233. rv = ngtcp2_strm_streamfrq_push(strm, nfrc);
  234. if (rv != 0) {
  235. ngtcp2_frame_chain_objalloc_del(nfrc, rtb->frc_objalloc, rtb->mem);
  236. return rv;
  237. }
  238. if (!ngtcp2_strm_is_tx_queued(strm)) {
  239. strm->cycle = ngtcp2_conn_tx_strmq_first_cycle(conn);
  240. rv = ngtcp2_conn_tx_strmq_push(conn, strm);
  241. if (rv != 0) {
  242. return rv;
  243. }
  244. }
  245. ++num_reclaimed;
  246. continue;
  247. case NGTCP2_FRAME_CRYPTO:
  248. /* Do not resend CRYPTO frame if the whole region it contains
  249. has been acknowledged */
  250. gap = ngtcp2_strm_get_unacked_range_after(&pktns->crypto.strm,
  251. fr->stream.offset);
  252. range.begin = fr->stream.offset;
  253. range.end =
  254. fr->stream.offset + ngtcp2_vec_len(fr->stream.data, fr->stream.datacnt);
  255. range = ngtcp2_range_intersect(&range, &gap);
  256. if (ngtcp2_range_len(&range) == 0) {
  257. continue;
  258. }
  259. rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new(
  260. &nfrc, fr->stream.datacnt, rtb->frc_objalloc, rtb->mem);
  261. if (rv != 0) {
  262. return rv;
  263. }
  264. nfrc->fr = *fr;
  265. ngtcp2_vec_copy(nfrc->fr.stream.data, fr->stream.data,
  266. fr->stream.datacnt);
  267. rv = ngtcp2_strm_streamfrq_push(&pktns->crypto.strm, nfrc);
  268. if (rv != 0) {
  269. assert(ngtcp2_err_is_fatal(rv));
  270. ngtcp2_frame_chain_objalloc_del(nfrc, rtb->frc_objalloc, rtb->mem);
  271. return rv;
  272. }
  273. ++num_reclaimed;
  274. continue;
  275. case NGTCP2_FRAME_NEW_TOKEN:
  276. rv = ngtcp2_frame_chain_new_token_objalloc_new(
  277. &nfrc, fr->new_token.token, fr->new_token.tokenlen, rtb->frc_objalloc,
  278. rtb->mem);
  279. if (rv != 0) {
  280. return rv;
  281. }
  282. rv = ngtcp2_bind_frame_chains(frc, nfrc, rtb->mem);
  283. if (rv != 0) {
  284. return rv;
  285. }
  286. ++num_reclaimed;
  287. nfrc->next = *pfrc;
  288. *pfrc = nfrc;
  289. pfrc = &nfrc->next;
  290. continue;
  291. case NGTCP2_FRAME_DATAGRAM:
  292. case NGTCP2_FRAME_DATAGRAM_LEN:
  293. continue;
  294. case NGTCP2_FRAME_RESET_STREAM:
  295. strm = ngtcp2_conn_find_stream(conn, fr->reset_stream.stream_id);
  296. if (strm == NULL || !ngtcp2_strm_require_retransmit_reset_stream(strm)) {
  297. continue;
  298. }
  299. break;
  300. case NGTCP2_FRAME_STOP_SENDING:
  301. strm = ngtcp2_conn_find_stream(conn, fr->stop_sending.stream_id);
  302. if (strm == NULL || !ngtcp2_strm_require_retransmit_stop_sending(strm)) {
  303. continue;
  304. }
  305. break;
  306. case NGTCP2_FRAME_MAX_STREAM_DATA:
  307. strm = ngtcp2_conn_find_stream(conn, fr->max_stream_data.stream_id);
  308. if (strm == NULL || !ngtcp2_strm_require_retransmit_max_stream_data(
  309. strm, &fr->max_stream_data)) {
  310. continue;
  311. }
  312. break;
  313. case NGTCP2_FRAME_STREAM_DATA_BLOCKED:
  314. strm = ngtcp2_conn_find_stream(conn, fr->stream_data_blocked.stream_id);
  315. if (strm == NULL || !ngtcp2_strm_require_retransmit_stream_data_blocked(
  316. strm, &fr->stream_data_blocked)) {
  317. continue;
  318. }
  319. break;
  320. }
  321. rv = ngtcp2_frame_chain_objalloc_new(&nfrc, rtb->frc_objalloc);
  322. if (rv != 0) {
  323. return rv;
  324. }
  325. nfrc->fr = *fr;
  326. rv = ngtcp2_bind_frame_chains(frc, nfrc, rtb->mem);
  327. if (rv != 0) {
  328. return rv;
  329. }
  330. ++num_reclaimed;
  331. nfrc->next = *pfrc;
  332. *pfrc = nfrc;
  333. pfrc = &nfrc->next;
  334. }
  335. return (ngtcp2_ssize)num_reclaimed;
  336. }
  337. /*
  338. * conn_process_lost_datagram calls ngtcp2_lost_datagram callback for
  339. * lost DATAGRAM frames.
  340. */
  341. static int conn_process_lost_datagram(ngtcp2_conn *conn,
  342. ngtcp2_rtb_entry *ent) {
  343. ngtcp2_frame_chain *frc;
  344. int rv;
  345. for (frc = ent->frc; frc; frc = frc->next) {
  346. switch (frc->fr.type) {
  347. case NGTCP2_FRAME_DATAGRAM:
  348. case NGTCP2_FRAME_DATAGRAM_LEN:
  349. assert(conn->callbacks.lost_datagram);
  350. rv = conn->callbacks.lost_datagram(conn, frc->fr.datagram.dgram_id,
  351. conn->user_data);
  352. if (rv != 0) {
  353. return NGTCP2_ERR_CALLBACK_FAILURE;
  354. }
  355. break;
  356. }
  357. }
  358. return 0;
  359. }
  360. static int rtb_on_pkt_lost(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
  361. ngtcp2_conn_stat *cstat, ngtcp2_conn *conn,
  362. ngtcp2_pktns *pktns, ngtcp2_tstamp ts) {
  363. int rv;
  364. ngtcp2_ssize reclaimed;
  365. ngtcp2_cc *cc = rtb->cc;
  366. ngtcp2_cc_pkt pkt;
  367. ngtcp2_log_pkt_lost(rtb->log, ent->hd.pkt_num, ent->hd.type, ent->hd.flags,
  368. ent->ts);
  369. if (rtb->qlog) {
  370. ngtcp2_qlog_pkt_lost(rtb->qlog, ent);
  371. }
  372. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
  373. ++rtb->num_lost_pmtud_pkts;
  374. } else if (rtb->cc->on_pkt_lost) {
  375. cc->on_pkt_lost(cc, cstat,
  376. ngtcp2_cc_pkt_init(&pkt, ent->hd.pkt_num, ent->pktlen,
  377. pktns->id, ent->ts, ent->rst.lost,
  378. ent->rst.tx_in_flight,
  379. ent->rst.is_app_limited),
  380. ts);
  381. }
  382. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED) {
  383. ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
  384. "pkn=%" PRId64 " has already been reclaimed on PTO",
  385. ent->hd.pkt_num);
  386. assert(!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED));
  387. assert(UINT64_MAX == ent->lost_ts);
  388. } else {
  389. if (conn->callbacks.lost_datagram &&
  390. (ent->flags & NGTCP2_RTB_ENTRY_FLAG_DATAGRAM)) {
  391. rv = conn_process_lost_datagram(conn, ent);
  392. if (rv != 0) {
  393. return rv;
  394. }
  395. }
  396. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) {
  397. assert(ent->frc);
  398. assert(!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED));
  399. assert(UINT64_MAX == ent->lost_ts);
  400. reclaimed =
  401. rtb_reclaim_frame(rtb, NGTCP2_RECLAIM_FLAG_ON_LOSS, conn, pktns, ent);
  402. if (reclaimed < 0) {
  403. return (int)reclaimed;
  404. }
  405. }
  406. }
  407. ent->flags |= NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED;
  408. ent->lost_ts = ts;
  409. ++rtb->num_lost_pkts;
  410. return 0;
  411. }
  412. int ngtcp2_rtb_add(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
  413. ngtcp2_conn_stat *cstat) {
  414. int rv;
  415. rv = ngtcp2_ksl_insert(&rtb->ents, NULL, &ent->hd.pkt_num, ent);
  416. if (rv != 0) {
  417. return rv;
  418. }
  419. rtb_on_add(rtb, ent, cstat);
  420. return 0;
  421. }
  422. ngtcp2_ksl_it ngtcp2_rtb_head(const ngtcp2_rtb *rtb) {
  423. return ngtcp2_ksl_begin(&rtb->ents);
  424. }
  425. static void rtb_remove(ngtcp2_rtb *rtb, ngtcp2_ksl_it *it,
  426. ngtcp2_rtb_entry **pent, ngtcp2_rtb_entry *ent,
  427. ngtcp2_conn_stat *cstat) {
  428. int rv;
  429. (void)rv;
  430. rv = ngtcp2_ksl_remove_hint(&rtb->ents, it, it, &ent->hd.pkt_num);
  431. assert(0 == rv);
  432. rtb_on_remove(rtb, ent, cstat);
  433. assert(ent->next == NULL);
  434. ngtcp2_list_insert(ent, pent);
  435. }
  436. static void conn_ack_crypto_data(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
  437. uint64_t datalen) {
  438. ngtcp2_buf_chain **pbufchain, *bufchain;
  439. size_t left;
  440. for (pbufchain = &pktns->crypto.tx.data; *pbufchain;) {
  441. left = ngtcp2_buf_len(&(*pbufchain)->buf);
  442. if (left > datalen) {
  443. (*pbufchain)->buf.pos += datalen;
  444. return;
  445. }
  446. bufchain = *pbufchain;
  447. *pbufchain = bufchain->next;
  448. ngtcp2_mem_free(conn->mem, bufchain);
  449. datalen -= left;
  450. if (datalen == 0) {
  451. return;
  452. }
  453. }
  454. assert(datalen == 0);
  455. return;
  456. }
  457. static int process_acked_pkt(ngtcp2_rtb_entry *ent, ngtcp2_conn *conn,
  458. ngtcp2_pktns *pktns) {
  459. ngtcp2_frame_chain *frc;
  460. uint64_t prev_stream_offset, stream_offset;
  461. ngtcp2_strm *strm;
  462. int rv;
  463. uint64_t datalen;
  464. ngtcp2_strm *crypto = &pktns->crypto.strm;
  465. if ((ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) && conn->pmtud &&
  466. conn->pmtud->tx_pkt_num <= ent->hd.pkt_num) {
  467. ngtcp2_pmtud_probe_success(conn->pmtud, ent->pktlen);
  468. if (conn->dcid.current.max_udp_payload_size < ent->pktlen) {
  469. conn->dcid.current.max_udp_payload_size = ent->pktlen;
  470. conn->cstat.max_tx_udp_payload_size =
  471. ngtcp2_conn_get_path_max_tx_udp_payload_size(conn);
  472. }
  473. if (ngtcp2_pmtud_finished(conn->pmtud)) {
  474. ngtcp2_conn_stop_pmtud(conn);
  475. }
  476. }
  477. for (frc = ent->frc; frc; frc = frc->next) {
  478. if (frc->binder) {
  479. if (frc->binder->flags & NGTCP2_FRAME_CHAIN_BINDER_FLAG_ACK) {
  480. continue;
  481. }
  482. frc->binder->flags |= NGTCP2_FRAME_CHAIN_BINDER_FLAG_ACK;
  483. }
  484. switch (frc->fr.type) {
  485. case NGTCP2_FRAME_STREAM:
  486. strm = ngtcp2_conn_find_stream(conn, frc->fr.stream.stream_id);
  487. if (strm == NULL) {
  488. break;
  489. }
  490. strm->flags |= NGTCP2_STRM_FLAG_ANY_ACKED;
  491. if (frc->fr.stream.fin) {
  492. strm->flags |= NGTCP2_STRM_FLAG_FIN_ACKED;
  493. }
  494. prev_stream_offset = ngtcp2_strm_get_acked_offset(strm);
  495. rv = ngtcp2_strm_ack_data(
  496. strm, frc->fr.stream.offset,
  497. ngtcp2_vec_len(frc->fr.stream.data, frc->fr.stream.datacnt));
  498. if (rv != 0) {
  499. return rv;
  500. }
  501. if (conn->callbacks.acked_stream_data_offset) {
  502. stream_offset = ngtcp2_strm_get_acked_offset(strm);
  503. datalen = stream_offset - prev_stream_offset;
  504. if (datalen == 0 && !frc->fr.stream.fin) {
  505. break;
  506. }
  507. rv = conn->callbacks.acked_stream_data_offset(
  508. conn, strm->stream_id, prev_stream_offset, datalen, conn->user_data,
  509. strm->stream_user_data);
  510. if (rv != 0) {
  511. return NGTCP2_ERR_CALLBACK_FAILURE;
  512. }
  513. }
  514. rv = ngtcp2_conn_close_stream_if_shut_rdwr(conn, strm);
  515. if (rv != 0) {
  516. return rv;
  517. }
  518. break;
  519. case NGTCP2_FRAME_CRYPTO:
  520. prev_stream_offset = ngtcp2_strm_get_acked_offset(crypto);
  521. rv = ngtcp2_strm_ack_data(
  522. crypto, frc->fr.stream.offset,
  523. ngtcp2_vec_len(frc->fr.stream.data, frc->fr.stream.datacnt));
  524. if (rv != 0) {
  525. return rv;
  526. }
  527. stream_offset = ngtcp2_strm_get_acked_offset(crypto);
  528. datalen = stream_offset - prev_stream_offset;
  529. if (datalen == 0) {
  530. break;
  531. }
  532. conn_ack_crypto_data(conn, pktns, datalen);
  533. break;
  534. case NGTCP2_FRAME_RESET_STREAM:
  535. strm = ngtcp2_conn_find_stream(conn, frc->fr.reset_stream.stream_id);
  536. if (strm == NULL) {
  537. break;
  538. }
  539. strm->flags |= NGTCP2_STRM_FLAG_RESET_STREAM_ACKED;
  540. rv = ngtcp2_conn_close_stream_if_shut_rdwr(conn, strm);
  541. if (rv != 0) {
  542. return rv;
  543. }
  544. break;
  545. case NGTCP2_FRAME_RETIRE_CONNECTION_ID:
  546. ngtcp2_conn_untrack_retired_dcid_seq(conn,
  547. frc->fr.retire_connection_id.seq);
  548. break;
  549. case NGTCP2_FRAME_NEW_CONNECTION_ID:
  550. assert(conn->scid.num_in_flight);
  551. --conn->scid.num_in_flight;
  552. break;
  553. case NGTCP2_FRAME_DATAGRAM:
  554. case NGTCP2_FRAME_DATAGRAM_LEN:
  555. if (!conn->callbacks.ack_datagram) {
  556. break;
  557. }
  558. rv = conn->callbacks.ack_datagram(conn, frc->fr.datagram.dgram_id,
  559. conn->user_data);
  560. if (rv != 0) {
  561. return NGTCP2_ERR_CALLBACK_FAILURE;
  562. }
  563. break;
  564. }
  565. }
  566. return 0;
  567. }
  568. static void rtb_on_pkt_acked(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
  569. ngtcp2_conn_stat *cstat, const ngtcp2_pktns *pktns,
  570. ngtcp2_tstamp ts) {
  571. ngtcp2_cc *cc = rtb->cc;
  572. ngtcp2_cc_pkt pkt;
  573. ngtcp2_rst_update_rate_sample(rtb->rst, ent, ts);
  574. if (cc->on_pkt_acked) {
  575. cc->on_pkt_acked(cc, cstat,
  576. ngtcp2_cc_pkt_init(&pkt, ent->hd.pkt_num, ent->pktlen,
  577. pktns->id, ent->ts, ent->rst.lost,
  578. ent->rst.tx_in_flight,
  579. ent->rst.is_app_limited),
  580. ts);
  581. }
  582. if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_PROBE) &&
  583. (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING)) {
  584. cstat->pto_count = 0;
  585. }
  586. }
  587. static void conn_verify_ecn(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
  588. ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
  589. const ngtcp2_ack *fr, size_t ecn_acked,
  590. ngtcp2_tstamp largest_pkt_sent_ts,
  591. ngtcp2_tstamp ts) {
  592. if (conn->tx.ecn.state == NGTCP2_ECN_STATE_FAILED) {
  593. return;
  594. }
  595. if ((ecn_acked && fr->type == NGTCP2_FRAME_ACK) ||
  596. (fr->type == NGTCP2_FRAME_ACK_ECN &&
  597. (pktns->rx.ecn.ack.ect0 > fr->ecn.ect0 ||
  598. pktns->rx.ecn.ack.ect1 > fr->ecn.ect1 ||
  599. pktns->rx.ecn.ack.ce > fr->ecn.ce ||
  600. (fr->ecn.ect0 - pktns->rx.ecn.ack.ect0) +
  601. (fr->ecn.ce - pktns->rx.ecn.ack.ce) <
  602. ecn_acked ||
  603. fr->ecn.ect0 > pktns->tx.ecn.ect0 || fr->ecn.ect1))) {
  604. ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
  605. "path is not ECN capable");
  606. conn->tx.ecn.state = NGTCP2_ECN_STATE_FAILED;
  607. return;
  608. }
  609. if (conn->tx.ecn.state != NGTCP2_ECN_STATE_CAPABLE && ecn_acked) {
  610. ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON, "path is ECN capable");
  611. conn->tx.ecn.state = NGTCP2_ECN_STATE_CAPABLE;
  612. }
  613. if (fr->type == NGTCP2_FRAME_ACK_ECN) {
  614. if (cc->congestion_event && largest_pkt_sent_ts != UINT64_MAX &&
  615. fr->ecn.ce > pktns->rx.ecn.ack.ce) {
  616. cc->congestion_event(cc, cstat, largest_pkt_sent_ts, 0, ts);
  617. }
  618. pktns->rx.ecn.ack.ect0 = fr->ecn.ect0;
  619. pktns->rx.ecn.ack.ect1 = fr->ecn.ect1;
  620. pktns->rx.ecn.ack.ce = fr->ecn.ce;
  621. }
  622. }
  623. static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost,
  624. ngtcp2_conn *conn, ngtcp2_pktns *pktns,
  625. ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts);
  626. ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
  627. ngtcp2_conn_stat *cstat, ngtcp2_conn *conn,
  628. ngtcp2_pktns *pktns, ngtcp2_tstamp pkt_ts,
  629. ngtcp2_tstamp ts) {
  630. ngtcp2_rtb_entry *ent;
  631. int64_t largest_ack = fr->largest_ack, min_ack;
  632. size_t i;
  633. int rv;
  634. ngtcp2_ksl_it it;
  635. size_t num_acked = 0;
  636. ngtcp2_tstamp largest_pkt_sent_ts = UINT64_MAX;
  637. int64_t pkt_num;
  638. ngtcp2_cc *cc = rtb->cc;
  639. ngtcp2_rtb_entry *acked_ent = NULL;
  640. int ack_eliciting_pkt_acked = 0;
  641. size_t ecn_acked = 0;
  642. int verify_ecn = 0;
  643. ngtcp2_cc_ack cc_ack = {0};
  644. size_t num_lost_pkts = rtb->num_lost_pkts - rtb->num_lost_pmtud_pkts;
  645. cc_ack.prior_bytes_in_flight = cstat->bytes_in_flight;
  646. cc_ack.rtt = UINT64_MAX;
  647. if (conn && (conn->flags & NGTCP2_CONN_FLAG_KEY_UPDATE_NOT_CONFIRMED) &&
  648. (conn->flags & NGTCP2_CONN_FLAG_KEY_UPDATE_INITIATOR) &&
  649. largest_ack >= conn->pktns.crypto.tx.ckm->pkt_num) {
  650. conn->flags &= (uint32_t) ~(NGTCP2_CONN_FLAG_KEY_UPDATE_NOT_CONFIRMED |
  651. NGTCP2_CONN_FLAG_KEY_UPDATE_INITIATOR);
  652. conn->crypto.key_update.confirmed_ts = ts;
  653. ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_CRY, "key update confirmed");
  654. }
  655. if (rtb->largest_acked_tx_pkt_num < largest_ack) {
  656. rtb->largest_acked_tx_pkt_num = largest_ack;
  657. verify_ecn = 1;
  658. }
  659. /* Assume that ngtcp2_pkt_validate_ack(fr) returns 0 */
  660. it = ngtcp2_ksl_lower_bound(&rtb->ents, &largest_ack);
  661. if (ngtcp2_ksl_it_end(&it)) {
  662. if (conn && verify_ecn) {
  663. conn_verify_ecn(conn, pktns, rtb->cc, cstat, fr, ecn_acked,
  664. largest_pkt_sent_ts, ts);
  665. }
  666. return 0;
  667. }
  668. min_ack = largest_ack - (int64_t)fr->first_ack_range;
  669. for (; !ngtcp2_ksl_it_end(&it);) {
  670. pkt_num = *(int64_t *)ngtcp2_ksl_it_key(&it);
  671. assert(pkt_num <= largest_ack);
  672. if (pkt_num < min_ack) {
  673. break;
  674. }
  675. ent = ngtcp2_ksl_it_get(&it);
  676. if (largest_ack == pkt_num) {
  677. largest_pkt_sent_ts = ent->ts;
  678. }
  679. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
  680. ack_eliciting_pkt_acked = 1;
  681. }
  682. rtb_remove(rtb, &it, &acked_ent, ent, cstat);
  683. ++num_acked;
  684. }
  685. for (i = 0; i < fr->rangecnt; ++i) {
  686. largest_ack = min_ack - (int64_t)fr->ranges[i].gap - 2;
  687. min_ack = largest_ack - (int64_t)fr->ranges[i].len;
  688. it = ngtcp2_ksl_lower_bound(&rtb->ents, &largest_ack);
  689. if (ngtcp2_ksl_it_end(&it)) {
  690. break;
  691. }
  692. for (; !ngtcp2_ksl_it_end(&it);) {
  693. pkt_num = *(int64_t *)ngtcp2_ksl_it_key(&it);
  694. if (pkt_num < min_ack) {
  695. break;
  696. }
  697. ent = ngtcp2_ksl_it_get(&it);
  698. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
  699. ack_eliciting_pkt_acked = 1;
  700. }
  701. rtb_remove(rtb, &it, &acked_ent, ent, cstat);
  702. ++num_acked;
  703. }
  704. }
  705. if (largest_pkt_sent_ts != UINT64_MAX && ack_eliciting_pkt_acked) {
  706. cc_ack.rtt =
  707. ngtcp2_max_uint64(pkt_ts - largest_pkt_sent_ts, NGTCP2_NANOSECONDS);
  708. rv = ngtcp2_conn_update_rtt(conn, cc_ack.rtt, fr->ack_delay_unscaled, ts);
  709. if (rv == 0 && cc->new_rtt_sample) {
  710. cc->new_rtt_sample(cc, cstat, ts);
  711. }
  712. }
  713. if (conn) {
  714. for (ent = acked_ent; ent; ent = acked_ent) {
  715. if (ent->hd.pkt_num >= pktns->tx.ecn.start_pkt_num &&
  716. (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ECN)) {
  717. ++ecn_acked;
  718. }
  719. rv = process_acked_pkt(ent, conn, pktns);
  720. if (rv != 0) {
  721. goto fail;
  722. }
  723. if (ent->hd.pkt_num >= rtb->cc_pkt_num) {
  724. assert(cc_ack.pkt_delivered <= ent->rst.delivered);
  725. cc_ack.bytes_delivered += ent->pktlen;
  726. cc_ack.pkt_delivered = ent->rst.delivered;
  727. }
  728. rtb_on_pkt_acked(rtb, ent, cstat, pktns, ts);
  729. acked_ent = ent->next;
  730. ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
  731. rtb->frc_objalloc, rtb->mem);
  732. }
  733. if (verify_ecn) {
  734. conn_verify_ecn(conn, pktns, rtb->cc, cstat, fr, ecn_acked,
  735. largest_pkt_sent_ts, ts);
  736. }
  737. } else {
  738. /* For unit tests */
  739. for (ent = acked_ent; ent; ent = acked_ent) {
  740. rtb_on_pkt_acked(rtb, ent, cstat, pktns, ts);
  741. acked_ent = ent->next;
  742. ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
  743. rtb->frc_objalloc, rtb->mem);
  744. }
  745. }
  746. if (rtb->cc->on_spurious_congestion && num_lost_pkts &&
  747. rtb->num_lost_pkts == rtb->num_lost_pmtud_pkts) {
  748. rtb->cc->on_spurious_congestion(cc, cstat, ts);
  749. }
  750. if (num_acked) {
  751. ngtcp2_rst_on_ack_recv(rtb->rst, cstat);
  752. if (conn) {
  753. rv = rtb_detect_lost_pkt(rtb, &cc_ack.bytes_lost, conn, pktns, cstat, ts);
  754. if (rv != 0) {
  755. return rv;
  756. }
  757. }
  758. }
  759. rtb->rst->lost += cc_ack.bytes_lost;
  760. cc_ack.largest_pkt_sent_ts = largest_pkt_sent_ts;
  761. if (num_acked && cc->on_ack_recv) {
  762. cc->on_ack_recv(cc, cstat, &cc_ack, ts);
  763. }
  764. return (ngtcp2_ssize)num_acked;
  765. fail:
  766. for (ent = acked_ent; ent; ent = acked_ent) {
  767. acked_ent = ent->next;
  768. ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
  769. rtb->frc_objalloc, rtb->mem);
  770. }
  771. return rv;
  772. }
  773. static int rtb_pkt_lost(ngtcp2_rtb *rtb, ngtcp2_conn_stat *cstat,
  774. const ngtcp2_rtb_entry *ent, ngtcp2_duration loss_delay,
  775. size_t pkt_thres, const ngtcp2_pktns *pktns,
  776. ngtcp2_tstamp ts) {
  777. ngtcp2_tstamp loss_time;
  778. if (ngtcp2_tstamp_elapsed(ent->ts, loss_delay, ts) ||
  779. rtb->largest_acked_tx_pkt_num >= ent->hd.pkt_num + (int64_t)pkt_thres) {
  780. return 1;
  781. }
  782. loss_time = cstat->loss_time[pktns->id];
  783. if (loss_time == UINT64_MAX) {
  784. loss_time = ent->ts + loss_delay;
  785. } else {
  786. loss_time = ngtcp2_min_uint64(loss_time, ent->ts + loss_delay);
  787. }
  788. cstat->loss_time[pktns->id] = loss_time;
  789. return 0;
  790. }
  791. /*
  792. * compute_pkt_loss_delay computes loss delay.
  793. */
  794. static ngtcp2_duration compute_pkt_loss_delay(const ngtcp2_conn_stat *cstat) {
  795. /* 9/8 is kTimeThreshold */
  796. ngtcp2_duration loss_delay =
  797. ngtcp2_max_uint64(cstat->latest_rtt, cstat->smoothed_rtt) * 9 / 8;
  798. return ngtcp2_max_uint64(loss_delay, NGTCP2_GRANULARITY);
  799. }
  800. /*
  801. * conn_all_ecn_pkt_lost returns nonzero if all ECN QUIC packets are
  802. * lost during validation period.
  803. */
  804. static int conn_all_ecn_pkt_lost(ngtcp2_conn *conn) {
  805. ngtcp2_pktns *in_pktns = conn->in_pktns;
  806. ngtcp2_pktns *hs_pktns = conn->hs_pktns;
  807. ngtcp2_pktns *pktns = &conn->pktns;
  808. return (!in_pktns || in_pktns->tx.ecn.validation_pkt_sent ==
  809. in_pktns->tx.ecn.validation_pkt_lost) &&
  810. (!hs_pktns || hs_pktns->tx.ecn.validation_pkt_sent ==
  811. hs_pktns->tx.ecn.validation_pkt_lost) &&
  812. pktns->tx.ecn.validation_pkt_sent == pktns->tx.ecn.validation_pkt_lost;
  813. }
  814. static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost,
  815. ngtcp2_conn *conn, ngtcp2_pktns *pktns,
  816. ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts) {
  817. ngtcp2_rtb_entry *ent;
  818. ngtcp2_duration loss_delay;
  819. ngtcp2_ksl_it it;
  820. ngtcp2_tstamp latest_ts, oldest_ts;
  821. int64_t last_lost_pkt_num;
  822. ngtcp2_duration loss_window, congestion_period;
  823. ngtcp2_cc *cc = rtb->cc;
  824. int rv;
  825. uint64_t pkt_thres =
  826. rtb->cc_bytes_in_flight / cstat->max_tx_udp_payload_size / 2;
  827. size_t ecn_pkt_lost = 0;
  828. ngtcp2_tstamp start_ts;
  829. ngtcp2_duration pto = ngtcp2_conn_compute_pto(conn, pktns);
  830. uint64_t bytes_lost = 0;
  831. ngtcp2_duration max_ack_delay;
  832. pkt_thres = ngtcp2_max_uint64(pkt_thres, NGTCP2_PKT_THRESHOLD);
  833. pkt_thres = ngtcp2_min_uint64(pkt_thres, 256);
  834. cstat->loss_time[pktns->id] = UINT64_MAX;
  835. loss_delay = compute_pkt_loss_delay(cstat);
  836. it = ngtcp2_ksl_lower_bound(&rtb->ents, &rtb->largest_acked_tx_pkt_num);
  837. for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) {
  838. ent = ngtcp2_ksl_it_get(&it);
  839. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) {
  840. break;
  841. }
  842. if (rtb_pkt_lost(rtb, cstat, ent, loss_delay, (size_t)pkt_thres, pktns,
  843. ts)) {
  844. /* All entries from ent are considered to be lost. */
  845. latest_ts = oldest_ts = ent->ts;
  846. /* +1 to pick this packet for persistent congestion in the
  847. following loop. */
  848. last_lost_pkt_num = ent->hd.pkt_num + 1;
  849. max_ack_delay = conn->remote.transport_params
  850. ? conn->remote.transport_params->max_ack_delay
  851. : 0;
  852. congestion_period =
  853. (cstat->smoothed_rtt +
  854. ngtcp2_max_uint64(4 * cstat->rttvar, NGTCP2_GRANULARITY) +
  855. max_ack_delay) *
  856. NGTCP2_PERSISTENT_CONGESTION_THRESHOLD;
  857. start_ts = ngtcp2_max_uint64(rtb->persistent_congestion_start_ts,
  858. cstat->first_rtt_sample_ts);
  859. for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) {
  860. ent = ngtcp2_ksl_it_get(&it);
  861. if (last_lost_pkt_num == ent->hd.pkt_num + 1 && ent->ts >= start_ts) {
  862. last_lost_pkt_num = ent->hd.pkt_num;
  863. oldest_ts = ent->ts;
  864. } else {
  865. last_lost_pkt_num = -1;
  866. }
  867. if ((ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED)) {
  868. if (pktns->id != NGTCP2_PKTNS_ID_APPLICATION ||
  869. last_lost_pkt_num == -1 ||
  870. latest_ts - oldest_ts >= congestion_period) {
  871. break;
  872. }
  873. continue;
  874. }
  875. if (ent->hd.pkt_num >= pktns->tx.ecn.start_pkt_num &&
  876. (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ECN)) {
  877. ++ecn_pkt_lost;
  878. }
  879. bytes_lost += rtb_on_remove(rtb, ent, cstat);
  880. rv = rtb_on_pkt_lost(rtb, ent, cstat, conn, pktns, ts);
  881. if (rv != 0) {
  882. return rv;
  883. }
  884. }
  885. /* If only PMTUD packets are lost, do not trigger congestion
  886. event. */
  887. if (bytes_lost == 0) {
  888. break;
  889. }
  890. switch (conn->tx.ecn.state) {
  891. case NGTCP2_ECN_STATE_TESTING:
  892. if (conn->tx.ecn.validation_start_ts == UINT64_MAX) {
  893. break;
  894. }
  895. if (ts - conn->tx.ecn.validation_start_ts < 3 * pto) {
  896. pktns->tx.ecn.validation_pkt_lost += ecn_pkt_lost;
  897. assert(pktns->tx.ecn.validation_pkt_sent >=
  898. pktns->tx.ecn.validation_pkt_lost);
  899. break;
  900. }
  901. conn->tx.ecn.state = NGTCP2_ECN_STATE_UNKNOWN;
  902. /* fall through */
  903. case NGTCP2_ECN_STATE_UNKNOWN:
  904. pktns->tx.ecn.validation_pkt_lost += ecn_pkt_lost;
  905. assert(pktns->tx.ecn.validation_pkt_sent >=
  906. pktns->tx.ecn.validation_pkt_lost);
  907. if (conn_all_ecn_pkt_lost(conn)) {
  908. conn->tx.ecn.state = NGTCP2_ECN_STATE_FAILED;
  909. }
  910. break;
  911. default:
  912. break;
  913. }
  914. if (cc->congestion_event) {
  915. cc->congestion_event(cc, cstat, latest_ts, bytes_lost, ts);
  916. }
  917. loss_window = latest_ts - oldest_ts;
  918. /* Persistent congestion situation is only evaluated for app
  919. * packet number space and for the packets sent after handshake
  920. * is confirmed. During handshake, there is not much packets
  921. * sent and also people seem to do lots of effort not to trigger
  922. * persistent congestion there, then it is a lot easier to just
  923. * not enable it during handshake.
  924. */
  925. if (pktns->id == NGTCP2_PKTNS_ID_APPLICATION && loss_window &&
  926. loss_window >= congestion_period) {
  927. ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
  928. "persistent congestion loss_window=%" PRIu64
  929. " congestion_period=%" PRIu64,
  930. loss_window, congestion_period);
  931. /* Reset min_rtt, srtt, and rttvar here. Next new RTT
  932. sample will be used to recalculate these values. */
  933. cstat->min_rtt = UINT64_MAX;
  934. cstat->smoothed_rtt = conn->local.settings.initial_rtt;
  935. cstat->rttvar = conn->local.settings.initial_rtt / 2;
  936. cstat->first_rtt_sample_ts = UINT64_MAX;
  937. if (cc->on_persistent_congestion) {
  938. cc->on_persistent_congestion(cc, cstat, ts);
  939. }
  940. }
  941. break;
  942. }
  943. }
  944. ngtcp2_rtb_remove_excessive_lost_pkt(rtb, (size_t)pkt_thres);
  945. if (ppkt_lost) {
  946. *ppkt_lost = bytes_lost;
  947. }
  948. return 0;
  949. }
  950. int ngtcp2_rtb_detect_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
  951. ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat,
  952. ngtcp2_tstamp ts) {
  953. return rtb_detect_lost_pkt(rtb, /* ppkt_lost = */ NULL, conn, pktns, cstat,
  954. ts);
  955. }
  956. void ngtcp2_rtb_remove_excessive_lost_pkt(ngtcp2_rtb *rtb, size_t n) {
  957. ngtcp2_ksl_it it = ngtcp2_ksl_end(&rtb->ents);
  958. ngtcp2_rtb_entry *ent;
  959. int rv;
  960. (void)rv;
  961. for (; rtb->num_lost_pkts > n;) {
  962. assert(ngtcp2_ksl_it_end(&it));
  963. ngtcp2_ksl_it_prev(&it);
  964. ent = ngtcp2_ksl_it_get(&it);
  965. assert(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED);
  966. ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
  967. "removing stale lost pkn=%" PRId64, ent->hd.pkt_num);
  968. --rtb->num_lost_pkts;
  969. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
  970. --rtb->num_lost_pmtud_pkts;
  971. }
  972. rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
  973. assert(0 == rv);
  974. ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
  975. rtb->frc_objalloc, rtb->mem);
  976. }
  977. }
  978. void ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_duration pto,
  979. ngtcp2_tstamp ts) {
  980. ngtcp2_ksl_it it;
  981. ngtcp2_rtb_entry *ent;
  982. int rv;
  983. (void)rv;
  984. if (ngtcp2_ksl_len(&rtb->ents) == 0) {
  985. return;
  986. }
  987. it = ngtcp2_ksl_end(&rtb->ents);
  988. for (;;) {
  989. assert(ngtcp2_ksl_it_end(&it));
  990. ngtcp2_ksl_it_prev(&it);
  991. ent = ngtcp2_ksl_it_get(&it);
  992. if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) ||
  993. ts - ent->lost_ts < pto) {
  994. return;
  995. }
  996. ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
  997. "removing stale lost pkn=%" PRId64, ent->hd.pkt_num);
  998. --rtb->num_lost_pkts;
  999. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
  1000. --rtb->num_lost_pmtud_pkts;
  1001. }
  1002. rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
  1003. assert(0 == rv);
  1004. ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
  1005. rtb->frc_objalloc, rtb->mem);
  1006. if (ngtcp2_ksl_len(&rtb->ents) == 0) {
  1007. return;
  1008. }
  1009. }
  1010. }
  1011. ngtcp2_tstamp ngtcp2_rtb_lost_pkt_ts(const ngtcp2_rtb *rtb) {
  1012. ngtcp2_ksl_it it;
  1013. ngtcp2_rtb_entry *ent;
  1014. if (ngtcp2_ksl_len(&rtb->ents) == 0) {
  1015. return UINT64_MAX;
  1016. }
  1017. it = ngtcp2_ksl_end(&rtb->ents);
  1018. ngtcp2_ksl_it_prev(&it);
  1019. ent = ngtcp2_ksl_it_get(&it);
  1020. if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED)) {
  1021. return UINT64_MAX;
  1022. }
  1023. return ent->lost_ts;
  1024. }
  1025. static int rtb_on_pkt_lost_resched_move(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
  1026. ngtcp2_pktns *pktns,
  1027. ngtcp2_rtb_entry *ent) {
  1028. ngtcp2_frame_chain **pfrc, *frc;
  1029. ngtcp2_stream *sfr;
  1030. ngtcp2_strm *strm;
  1031. int rv;
  1032. ngtcp2_log_pkt_lost(rtb->log, ent->hd.pkt_num, ent->hd.type, ent->hd.flags,
  1033. ent->ts);
  1034. if (rtb->qlog) {
  1035. ngtcp2_qlog_pkt_lost(rtb->qlog, ent);
  1036. }
  1037. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PROBE) {
  1038. ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
  1039. "pkn=%" PRId64
  1040. " is a probe packet, no retransmission is necessary",
  1041. ent->hd.pkt_num);
  1042. return 0;
  1043. }
  1044. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) {
  1045. --rtb->num_lost_pkts;
  1046. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
  1047. --rtb->num_lost_pmtud_pkts;
  1048. }
  1049. ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
  1050. "pkn=%" PRId64
  1051. " was declared lost and has already been retransmitted",
  1052. ent->hd.pkt_num);
  1053. return 0;
  1054. }
  1055. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED) {
  1056. ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
  1057. "pkn=%" PRId64 " has already been reclaimed on PTO",
  1058. ent->hd.pkt_num);
  1059. return 0;
  1060. }
  1061. if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) &&
  1062. (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_DATAGRAM) ||
  1063. !conn->callbacks.lost_datagram)) {
  1064. /* PADDING only (or PADDING + ACK ) packets will have NULL
  1065. ent->frc. */
  1066. return 0;
  1067. }
  1068. pfrc = &ent->frc;
  1069. for (; *pfrc;) {
  1070. switch ((*pfrc)->fr.type) {
  1071. case NGTCP2_FRAME_STREAM:
  1072. frc = *pfrc;
  1073. *pfrc = frc->next;
  1074. frc->next = NULL;
  1075. sfr = &frc->fr.stream;
  1076. strm = ngtcp2_conn_find_stream(conn, sfr->stream_id);
  1077. if (!strm) {
  1078. ngtcp2_frame_chain_objalloc_del(frc, rtb->frc_objalloc, rtb->mem);
  1079. break;
  1080. }
  1081. rv = ngtcp2_strm_streamfrq_push(strm, frc);
  1082. if (rv != 0) {
  1083. ngtcp2_frame_chain_objalloc_del(frc, rtb->frc_objalloc, rtb->mem);
  1084. return rv;
  1085. }
  1086. if (!ngtcp2_strm_is_tx_queued(strm)) {
  1087. strm->cycle = ngtcp2_conn_tx_strmq_first_cycle(conn);
  1088. rv = ngtcp2_conn_tx_strmq_push(conn, strm);
  1089. if (rv != 0) {
  1090. return rv;
  1091. }
  1092. }
  1093. break;
  1094. case NGTCP2_FRAME_CRYPTO:
  1095. frc = *pfrc;
  1096. *pfrc = frc->next;
  1097. frc->next = NULL;
  1098. rv = ngtcp2_strm_streamfrq_push(&pktns->crypto.strm, frc);
  1099. if (rv != 0) {
  1100. assert(ngtcp2_err_is_fatal(rv));
  1101. ngtcp2_frame_chain_objalloc_del(frc, rtb->frc_objalloc, rtb->mem);
  1102. return rv;
  1103. }
  1104. break;
  1105. case NGTCP2_FRAME_DATAGRAM:
  1106. case NGTCP2_FRAME_DATAGRAM_LEN:
  1107. frc = *pfrc;
  1108. if (conn->callbacks.lost_datagram) {
  1109. rv = conn->callbacks.lost_datagram(conn, frc->fr.datagram.dgram_id,
  1110. conn->user_data);
  1111. if (rv != 0) {
  1112. return NGTCP2_ERR_CALLBACK_FAILURE;
  1113. }
  1114. }
  1115. *pfrc = (*pfrc)->next;
  1116. ngtcp2_frame_chain_objalloc_del(frc, rtb->frc_objalloc, rtb->mem);
  1117. break;
  1118. default:
  1119. pfrc = &(*pfrc)->next;
  1120. }
  1121. }
  1122. *pfrc = pktns->tx.frq;
  1123. pktns->tx.frq = ent->frc;
  1124. ent->frc = NULL;
  1125. return 0;
  1126. }
  1127. int ngtcp2_rtb_remove_all(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
  1128. ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat) {
  1129. ngtcp2_rtb_entry *ent;
  1130. ngtcp2_ksl_it it;
  1131. int rv;
  1132. it = ngtcp2_ksl_begin(&rtb->ents);
  1133. for (; !ngtcp2_ksl_it_end(&it);) {
  1134. ent = ngtcp2_ksl_it_get(&it);
  1135. rtb_on_remove(rtb, ent, cstat);
  1136. rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
  1137. assert(0 == rv);
  1138. rv = rtb_on_pkt_lost_resched_move(rtb, conn, pktns, ent);
  1139. ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
  1140. rtb->frc_objalloc, rtb->mem);
  1141. if (rv != 0) {
  1142. return rv;
  1143. }
  1144. }
  1145. return 0;
  1146. }
  1147. void ngtcp2_rtb_remove_early_data(ngtcp2_rtb *rtb, ngtcp2_conn_stat *cstat) {
  1148. ngtcp2_rtb_entry *ent;
  1149. ngtcp2_ksl_it it;
  1150. int rv;
  1151. (void)rv;
  1152. it = ngtcp2_ksl_begin(&rtb->ents);
  1153. for (; !ngtcp2_ksl_it_end(&it);) {
  1154. ent = ngtcp2_ksl_it_get(&it);
  1155. if (ent->hd.type != NGTCP2_PKT_0RTT) {
  1156. ngtcp2_ksl_it_next(&it);
  1157. continue;
  1158. }
  1159. rtb_on_remove(rtb, ent, cstat);
  1160. rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
  1161. assert(0 == rv);
  1162. ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
  1163. rtb->frc_objalloc, rtb->mem);
  1164. }
  1165. }
  1166. int ngtcp2_rtb_empty(const ngtcp2_rtb *rtb) {
  1167. return ngtcp2_ksl_len(&rtb->ents) == 0;
  1168. }
  1169. void ngtcp2_rtb_reset_cc_state(ngtcp2_rtb *rtb, int64_t cc_pkt_num) {
  1170. rtb->cc_pkt_num = cc_pkt_num;
  1171. rtb->cc_bytes_in_flight = 0;
  1172. }
  1173. ngtcp2_ssize ngtcp2_rtb_reclaim_on_pto(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
  1174. ngtcp2_pktns *pktns, size_t num_pkts) {
  1175. ngtcp2_ksl_it it;
  1176. ngtcp2_rtb_entry *ent;
  1177. ngtcp2_ssize reclaimed;
  1178. size_t atmost = num_pkts;
  1179. it = ngtcp2_ksl_end(&rtb->ents);
  1180. for (; !ngtcp2_ksl_it_begin(&it) && num_pkts;) {
  1181. ngtcp2_ksl_it_prev(&it);
  1182. ent = ngtcp2_ksl_it_get(&it);
  1183. if ((ent->flags & (NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED |
  1184. NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED)) ||
  1185. !(ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE)) {
  1186. continue;
  1187. }
  1188. assert(ent->frc);
  1189. reclaimed =
  1190. rtb_reclaim_frame(rtb, NGTCP2_RECLAIM_FLAG_NONE, conn, pktns, ent);
  1191. if (reclaimed < 0) {
  1192. return reclaimed;
  1193. }
  1194. /* Mark ent reclaimed even if reclaimed == 0 so that we can skip
  1195. it in the next run. */
  1196. ent->flags |= NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED;
  1197. assert(rtb->num_retransmittable);
  1198. --rtb->num_retransmittable;
  1199. if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING) {
  1200. ent->flags &= (uint16_t)~NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING;
  1201. assert(rtb->num_pto_eliciting);
  1202. --rtb->num_pto_eliciting;
  1203. }
  1204. if (reclaimed) {
  1205. --num_pkts;
  1206. }
  1207. }
  1208. return (ngtcp2_ssize)(atmost - num_pkts);
  1209. }