ngtcp2_rtb.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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. #ifndef NGTCP2_RTB_H
  26. #define NGTCP2_RTB_H
  27. #ifdef HAVE_CONFIG_H
  28. # include <config.h>
  29. #endif /* defined(HAVE_CONFIG_H) */
  30. #include <ngtcp2/ngtcp2.h>
  31. #include "ngtcp2_pkt.h"
  32. #include "ngtcp2_ksl.h"
  33. #include "ngtcp2_pq.h"
  34. #include "ngtcp2_objalloc.h"
  35. #include "ngtcp2_pktns_id.h"
  36. typedef struct ngtcp2_conn ngtcp2_conn;
  37. typedef struct ngtcp2_pktns ngtcp2_pktns;
  38. typedef struct ngtcp2_log ngtcp2_log;
  39. typedef struct ngtcp2_qlog ngtcp2_qlog;
  40. typedef struct ngtcp2_strm ngtcp2_strm;
  41. typedef struct ngtcp2_rst ngtcp2_rst;
  42. typedef struct ngtcp2_cc ngtcp2_cc;
  43. typedef struct ngtcp2_conn_stat ngtcp2_conn_stat;
  44. typedef struct ngtcp2_frame_chain ngtcp2_frame_chain;
  45. /* NGTCP2_RTB_ENTRY_FLAG_NONE indicates that no flag is set. */
  46. #define NGTCP2_RTB_ENTRY_FLAG_NONE 0x00u
  47. /* NGTCP2_RTB_ENTRY_FLAG_PROBE indicates that the entry includes a
  48. probe packet. */
  49. #define NGTCP2_RTB_ENTRY_FLAG_PROBE 0x01u
  50. /* NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE indicates that the entry
  51. includes a frame which must be retransmitted until it is
  52. acknowledged. In most cases, this flag is used along with
  53. NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING and
  54. NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING. */
  55. #define NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE 0x02u
  56. /* NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING indicates that the entry
  57. elicits acknowledgement. */
  58. #define NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING 0x04u
  59. /* NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED indicates that the packet has
  60. been reclaimed on PTO. It is not marked lost yet and still
  61. consumes congestion window. */
  62. #define NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED 0x08u
  63. /* NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED indicates that the entry
  64. has been marked lost and, optionally, scheduled to retransmit. */
  65. #define NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED 0x10u
  66. /* NGTCP2_RTB_ENTRY_FLAG_ECN indicates that the entry is included in a
  67. UDP datagram with ECN marking. */
  68. #define NGTCP2_RTB_ENTRY_FLAG_ECN 0x20u
  69. /* NGTCP2_RTB_ENTRY_FLAG_DATAGRAM indicates that the entry includes
  70. DATAGRAM frame. */
  71. #define NGTCP2_RTB_ENTRY_FLAG_DATAGRAM 0x40u
  72. /* NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE indicates that the entry includes
  73. a PMTUD probe packet. */
  74. #define NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE 0x80u
  75. /* NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING indicates that the entry
  76. includes a packet which elicits PTO probe packets. */
  77. #define NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING 0x100u
  78. typedef struct ngtcp2_rtb_entry ngtcp2_rtb_entry;
  79. /*
  80. * ngtcp2_rtb_entry is an object stored in ngtcp2_rtb. It corresponds
  81. * to the one packet which is waiting for its acknowledgement.
  82. */
  83. struct ngtcp2_rtb_entry {
  84. union {
  85. struct {
  86. ngtcp2_rtb_entry *next;
  87. struct {
  88. int64_t pkt_num;
  89. uint8_t type;
  90. uint8_t flags;
  91. } hd;
  92. ngtcp2_frame_chain *frc;
  93. /* ts is the time point when a packet included in this entry is
  94. sent to a remote endpoint. */
  95. ngtcp2_tstamp ts;
  96. /* lost_ts is the time when this entry is declared to be
  97. lost. */
  98. ngtcp2_tstamp lost_ts;
  99. /* pktlen is the length of QUIC packet */
  100. size_t pktlen;
  101. struct {
  102. uint64_t delivered;
  103. ngtcp2_tstamp delivered_ts;
  104. ngtcp2_tstamp first_sent_ts;
  105. uint64_t tx_in_flight;
  106. uint64_t lost;
  107. int64_t end_seq;
  108. int is_app_limited;
  109. } rst;
  110. /* flags is bitwise-OR of zero or more of
  111. NGTCP2_RTB_ENTRY_FLAG_*. */
  112. uint16_t flags;
  113. };
  114. ngtcp2_opl_entry oplent;
  115. };
  116. };
  117. ngtcp2_objalloc_decl(rtb_entry, ngtcp2_rtb_entry, oplent)
  118. /*
  119. * ngtcp2_rtb_entry_objalloc_new allocates ngtcp2_rtb_entry object via
  120. * |objalloc|, and assigns its pointer to |*pent|.
  121. */
  122. int ngtcp2_rtb_entry_objalloc_new(ngtcp2_rtb_entry **pent,
  123. const ngtcp2_pkt_hd *hd,
  124. ngtcp2_frame_chain *frc, ngtcp2_tstamp ts,
  125. size_t pktlen, uint16_t flags,
  126. ngtcp2_objalloc *objalloc);
  127. /*
  128. * ngtcp2_rtb_entry_objalloc_del adds |ent| to |objalloc| for reuse.
  129. * ngtcp2_frame_chain linked from ent->frc are also added to
  130. * |frc_objalloc| depending on their frame type and size.
  131. */
  132. void ngtcp2_rtb_entry_objalloc_del(ngtcp2_rtb_entry *ent,
  133. ngtcp2_objalloc *objalloc,
  134. ngtcp2_objalloc *frc_objalloc,
  135. const ngtcp2_mem *mem);
  136. /*
  137. * ngtcp2_rtb tracks sent packets, and its acknowledgement timeout for
  138. * retransmission.
  139. */
  140. typedef struct ngtcp2_rtb {
  141. ngtcp2_objalloc *frc_objalloc;
  142. ngtcp2_objalloc *rtb_entry_objalloc;
  143. /* ents includes ngtcp2_rtb_entry sorted by decreasing order of
  144. packet number. */
  145. ngtcp2_ksl ents;
  146. ngtcp2_rst *rst;
  147. ngtcp2_cc *cc;
  148. ngtcp2_log *log;
  149. ngtcp2_qlog *qlog;
  150. const ngtcp2_mem *mem;
  151. /* largest_acked_tx_pkt_num is the largest packet number
  152. acknowledged by a remote endpoint. */
  153. int64_t largest_acked_tx_pkt_num;
  154. /* num_ack_eliciting is the number of ACK eliciting entries in
  155. ents. */
  156. size_t num_ack_eliciting;
  157. /* num_retransmittable is the number of packets which contain frames
  158. that must be retransmitted on loss in ents. */
  159. size_t num_retransmittable;
  160. /* num_pto_eliciting is the number of packets that elicit PTO probe
  161. packets in ents. */
  162. size_t num_pto_eliciting;
  163. /* probe_pkt_left is the number of probe packet to send */
  164. size_t probe_pkt_left;
  165. /* cc_pkt_num is the smallest packet number that is contributed to
  166. ngtcp2_conn_stat.bytes_in_flight. */
  167. int64_t cc_pkt_num;
  168. /* cc_bytes_in_flight is the number of in-flight bytes that is
  169. contributed to ngtcp2_conn_stat.bytes_in_flight. It only
  170. includes the bytes after congestion state is reset, that is only
  171. count a packet whose packet number is greater than or equals to
  172. cc_pkt_num. */
  173. uint64_t cc_bytes_in_flight;
  174. /* persistent_congestion_start_ts is the time when persistent
  175. congestion evaluation is started. It happens roughly after
  176. handshake is confirmed. */
  177. ngtcp2_tstamp persistent_congestion_start_ts;
  178. /* num_lost_pkts is the number entries in ents which has
  179. NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED flag set. */
  180. size_t num_lost_pkts;
  181. /* num_lost_pmtud_pkts is the number of entries in ents which have
  182. both NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED and
  183. NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE flags set. */
  184. size_t num_lost_pmtud_pkts;
  185. } ngtcp2_rtb;
  186. /*
  187. * ngtcp2_rtb_init initializes |rtb|.
  188. */
  189. void ngtcp2_rtb_init(ngtcp2_rtb *rtb, ngtcp2_rst *rst, ngtcp2_cc *cc,
  190. int64_t cc_pkt_num, ngtcp2_log *log, ngtcp2_qlog *qlog,
  191. ngtcp2_objalloc *rtb_entry_objalloc,
  192. ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem);
  193. /*
  194. * ngtcp2_rtb_free deallocates resources allocated for |rtb|.
  195. */
  196. void ngtcp2_rtb_free(ngtcp2_rtb *rtb);
  197. /*
  198. * ngtcp2_rtb_add adds |ent| to |rtb|.
  199. *
  200. * This function returns 0 if it succeeds, or one of the following
  201. * negative error codes:
  202. *
  203. * NGTCP2_ERR_NOMEM
  204. * Out of memory
  205. */
  206. int ngtcp2_rtb_add(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
  207. ngtcp2_conn_stat *cstat);
  208. /*
  209. * ngtcp2_rtb_head returns the iterator which points to the entry
  210. * which has the largest packet number. If there is no entry,
  211. * returned value satisfies ngtcp2_ksl_it_end(&it) != 0.
  212. */
  213. ngtcp2_ksl_it ngtcp2_rtb_head(const ngtcp2_rtb *rtb);
  214. /*
  215. * ngtcp2_rtb_recv_ack removes an acknowledged ngtcp2_rtb_entry from
  216. * |rtb|. |pkt_num| is a packet number which includes |fr|. |pkt_ts|
  217. * is the timestamp when packet is received. |ts| should be the
  218. * current time. Usually they are the same, but for buffered packets,
  219. * |pkt_ts| would be earlier than |ts|.
  220. *
  221. * This function returns the number of newly acknowledged packets if
  222. * it succeeds, or one of the following negative error codes:
  223. *
  224. * NGTCP2_ERR_CALLBACK_FAILURE
  225. * User callback failed
  226. * NGTCP2_ERR_NOMEM
  227. * Out of memory
  228. */
  229. ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
  230. ngtcp2_conn_stat *cstat, ngtcp2_conn *conn,
  231. ngtcp2_pktns *pktns, ngtcp2_tstamp pkt_ts,
  232. ngtcp2_tstamp ts);
  233. /*
  234. * ngtcp2_rtb_detect_lost_pkt detects lost packets and prepends the
  235. * frames contained them to |*pfrc|. Even when this function fails,
  236. * some frames might be prepended to |*pfrc|, and the caller should
  237. * handle them.
  238. */
  239. int ngtcp2_rtb_detect_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
  240. ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat,
  241. ngtcp2_tstamp ts);
  242. /*
  243. * ngtcp2_rtb_remove_expired_lost_pkt removes expired lost packet.
  244. */
  245. void ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_duration pto,
  246. ngtcp2_tstamp ts);
  247. /*
  248. * ngtcp2_rtb_lost_pkt_ts returns the timestamp when an oldest lost
  249. * packet tracked by |rtb| was declared lost. It returns UINT64_MAX
  250. * if no such packet exists.
  251. */
  252. ngtcp2_tstamp ngtcp2_rtb_lost_pkt_ts(const ngtcp2_rtb *rtb);
  253. /*
  254. * ngtcp2_rtb_remove_all removes all packets from |rtb|, and prepends
  255. * all frames to |*pfrc|. Even when this function fails, some frames
  256. * might be prepended to |*pfrc|, and the caller should handle them.
  257. */
  258. int ngtcp2_rtb_remove_all(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
  259. ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat);
  260. /*
  261. * ngtcp2_rtb_remove_early_data removes all entries for 0RTT packets.
  262. */
  263. void ngtcp2_rtb_remove_early_data(ngtcp2_rtb *rtb, ngtcp2_conn_stat *cstat);
  264. /*
  265. * ngtcp2_rtb_empty returns nonzero if |rtb| has no entry.
  266. */
  267. int ngtcp2_rtb_empty(const ngtcp2_rtb *rtb);
  268. /*
  269. * ngtcp2_rtb_reset_cc_state resets congestion state in |rtb|.
  270. * |cc_pkt_num| is the next outbound packet number which is sent under
  271. * new congestion state.
  272. */
  273. void ngtcp2_rtb_reset_cc_state(ngtcp2_rtb *rtb, int64_t cc_pkt_num);
  274. /*
  275. * ngtcp2_rtb_remove_excessive_lost_pkt ensures that the number of
  276. * lost packets is at most |n|.
  277. */
  278. void ngtcp2_rtb_remove_excessive_lost_pkt(ngtcp2_rtb *rtb, size_t n);
  279. /*
  280. * ngtcp2_rtb_reclaim_on_pto reclaims up to |num_pkts| packets which
  281. * are in-flight and not marked lost. The reclaimed frames may be
  282. * sent in a PTO probe packet.
  283. *
  284. * This function returns the number of packets reclaimed if it
  285. * succeeds, or one of the following negative error codes:
  286. *
  287. * NGTCP2_ERR_NOMEM
  288. * Out of memory
  289. */
  290. ngtcp2_ssize ngtcp2_rtb_reclaim_on_pto(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
  291. ngtcp2_pktns *pktns, size_t num_pkts);
  292. #endif /* !defined(NGTCP2_RTB_H) */