src/event/quic/ngx_event_quic_transport.h - nginx source code

Data types defined

Macros defined

Source code


  1. /*
  2. * Copyright (C) Nginx, Inc.
  3. */


  4. #ifndef _NGX_EVENT_QUIC_TRANSPORT_H_INCLUDED_
  5. #define _NGX_EVENT_QUIC_TRANSPORT_H_INCLUDED_


  6. #include <ngx_config.h>
  7. #include <ngx_core.h>


  8. /*
  9. * RFC 9000, 17.2.  Long Header Packets
  10. *           17.3.  Short Header Packets
  11. *
  12. * QUIC flags in first byte
  13. */
  14. #define NGX_QUIC_PKT_LONG       0x80  /* header form */
  15. #define NGX_QUIC_PKT_FIXED_BIT  0x40
  16. #define NGX_QUIC_PKT_TYPE       0x30  /* in long packet */
  17. #define NGX_QUIC_PKT_KPHASE     0x04  /* in short packet */

  18. #define ngx_quic_long_pkt(flags)  ((flags) & NGX_QUIC_PKT_LONG)
  19. #define ngx_quic_short_pkt(flags)  (((flags) & NGX_QUIC_PKT_LONG) == 0)

  20. /* Long packet types */
  21. #define NGX_QUIC_PKT_INITIAL    0x00
  22. #define NGX_QUIC_PKT_ZRTT       0x10
  23. #define NGX_QUIC_PKT_HANDSHAKE  0x20
  24. #define NGX_QUIC_PKT_RETRY      0x30

  25. #define ngx_quic_pkt_in(flags)                                                \
  26.     (((flags) & NGX_QUIC_PKT_TYPE) == NGX_QUIC_PKT_INITIAL)
  27. #define ngx_quic_pkt_zrtt(flags)                                              \
  28.     (((flags) & NGX_QUIC_PKT_TYPE) == NGX_QUIC_PKT_ZRTT)
  29. #define ngx_quic_pkt_hs(flags)                                                \
  30.     (((flags) & NGX_QUIC_PKT_TYPE) == NGX_QUIC_PKT_HANDSHAKE)
  31. #define ngx_quic_pkt_retry(flags)                                             \
  32.     (((flags) & NGX_QUIC_PKT_TYPE) == NGX_QUIC_PKT_RETRY)

  33. #define ngx_quic_pkt_rb_mask(flags)                                           \
  34.     (ngx_quic_long_pkt(flags) ? 0x0C : 0x18)
  35. #define ngx_quic_pkt_hp_mask(flags)                                           \
  36.     (ngx_quic_long_pkt(flags) ? 0x0F : 0x1F)

  37. #define ngx_quic_level_name(lvl)                                              \
  38.     (lvl == ssl_encryption_application) ? "app"                               \
  39.         : (lvl == ssl_encryption_initial) ? "init"                            \
  40.             : (lvl == ssl_encryption_handshake) ? "hs" : "early"

  41. #define NGX_QUIC_MAX_CID_LEN                             20
  42. #define NGX_QUIC_SERVER_CID_LEN                          NGX_QUIC_MAX_CID_LEN

  43. /* 12.4.  Frames and Frame Types */
  44. #define NGX_QUIC_FT_PADDING                              0x00
  45. #define NGX_QUIC_FT_PING                                 0x01
  46. #define NGX_QUIC_FT_ACK                                  0x02
  47. #define NGX_QUIC_FT_ACK_ECN                              0x03
  48. #define NGX_QUIC_FT_RESET_STREAM                         0x04
  49. #define NGX_QUIC_FT_STOP_SENDING                         0x05
  50. #define NGX_QUIC_FT_CRYPTO                               0x06
  51. #define NGX_QUIC_FT_NEW_TOKEN                            0x07
  52. #define NGX_QUIC_FT_STREAM                               0x08
  53. #define NGX_QUIC_FT_STREAM1                              0x09
  54. #define NGX_QUIC_FT_STREAM2                              0x0A
  55. #define NGX_QUIC_FT_STREAM3                              0x0B
  56. #define NGX_QUIC_FT_STREAM4                              0x0C
  57. #define NGX_QUIC_FT_STREAM5                              0x0D
  58. #define NGX_QUIC_FT_STREAM6                              0x0E
  59. #define NGX_QUIC_FT_STREAM7                              0x0F
  60. #define NGX_QUIC_FT_MAX_DATA                             0x10
  61. #define NGX_QUIC_FT_MAX_STREAM_DATA                      0x11
  62. #define NGX_QUIC_FT_MAX_STREAMS                          0x12
  63. #define NGX_QUIC_FT_MAX_STREAMS2                         0x13
  64. #define NGX_QUIC_FT_DATA_BLOCKED                         0x14
  65. #define NGX_QUIC_FT_STREAM_DATA_BLOCKED                  0x15
  66. #define NGX_QUIC_FT_STREAMS_BLOCKED                      0x16
  67. #define NGX_QUIC_FT_STREAMS_BLOCKED2                     0x17
  68. #define NGX_QUIC_FT_NEW_CONNECTION_ID                    0x18
  69. #define NGX_QUIC_FT_RETIRE_CONNECTION_ID                 0x19
  70. #define NGX_QUIC_FT_PATH_CHALLENGE                       0x1A
  71. #define NGX_QUIC_FT_PATH_RESPONSE                        0x1B
  72. #define NGX_QUIC_FT_CONNECTION_CLOSE                     0x1C
  73. #define NGX_QUIC_FT_CONNECTION_CLOSE_APP                 0x1D
  74. #define NGX_QUIC_FT_HANDSHAKE_DONE                       0x1E

  75. #define NGX_QUIC_FT_LAST  NGX_QUIC_FT_HANDSHAKE_DONE

  76. /* 22.5.  QUIC Transport Error Codes Registry */
  77. #define NGX_QUIC_ERR_NO_ERROR                            0x00
  78. #define NGX_QUIC_ERR_INTERNAL_ERROR                      0x01
  79. #define NGX_QUIC_ERR_CONNECTION_REFUSED                  0x02
  80. #define NGX_QUIC_ERR_FLOW_CONTROL_ERROR                  0x03
  81. #define NGX_QUIC_ERR_STREAM_LIMIT_ERROR                  0x04
  82. #define NGX_QUIC_ERR_STREAM_STATE_ERROR                  0x05
  83. #define NGX_QUIC_ERR_FINAL_SIZE_ERROR                    0x06
  84. #define NGX_QUIC_ERR_FRAME_ENCODING_ERROR                0x07
  85. #define NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR           0x08
  86. #define NGX_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR           0x09
  87. #define NGX_QUIC_ERR_PROTOCOL_VIOLATION                  0x0A
  88. #define NGX_QUIC_ERR_INVALID_TOKEN                       0x0B
  89. #define NGX_QUIC_ERR_APPLICATION_ERROR                   0x0C
  90. #define NGX_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED              0x0D
  91. #define NGX_QUIC_ERR_KEY_UPDATE_ERROR                    0x0E
  92. #define NGX_QUIC_ERR_AEAD_LIMIT_REACHED                  0x0F
  93. #define NGX_QUIC_ERR_NO_VIABLE_PATH                      0x10

  94. #define NGX_QUIC_ERR_CRYPTO_ERROR                       0x100

  95. #define NGX_QUIC_ERR_CRYPTO(e)  (NGX_QUIC_ERR_CRYPTO_ERROR + (e))


  96. /* 22.3.  QUIC Transport Parameters Registry */
  97. #define NGX_QUIC_TP_ORIGINAL_DCID                        0x00
  98. #define NGX_QUIC_TP_MAX_IDLE_TIMEOUT                     0x01
  99. #define NGX_QUIC_TP_SR_TOKEN                             0x02
  100. #define NGX_QUIC_TP_MAX_UDP_PAYLOAD_SIZE                 0x03
  101. #define NGX_QUIC_TP_INITIAL_MAX_DATA                     0x04
  102. #define NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL   0x05
  103. #define NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE  0x06
  104. #define NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_UNI          0x07
  105. #define NGX_QUIC_TP_INITIAL_MAX_STREAMS_BIDI             0x08
  106. #define NGX_QUIC_TP_INITIAL_MAX_STREAMS_UNI              0x09
  107. #define NGX_QUIC_TP_ACK_DELAY_EXPONENT                   0x0A
  108. #define NGX_QUIC_TP_MAX_ACK_DELAY                        0x0B
  109. #define NGX_QUIC_TP_DISABLE_ACTIVE_MIGRATION             0x0C
  110. #define NGX_QUIC_TP_PREFERRED_ADDRESS                    0x0D
  111. #define NGX_QUIC_TP_ACTIVE_CONNECTION_ID_LIMIT           0x0E
  112. #define NGX_QUIC_TP_INITIAL_SCID                         0x0F
  113. #define NGX_QUIC_TP_RETRY_SCID                           0x10

  114. #define NGX_QUIC_CID_LEN_MIN                                8
  115. #define NGX_QUIC_CID_LEN_MAX                               20

  116. #define NGX_QUIC_MAX_RANGES                                10


  117. typedef struct {
  118.     uint64_t                                    gap;
  119.     uint64_t                                    range;
  120. } ngx_quic_ack_range_t;


  121. typedef struct {
  122.     uint64_t                                    largest;
  123.     uint64_t                                    delay;
  124.     uint64_t                                    range_count;
  125.     uint64_t                                    first_range;
  126.     uint64_t                                    ect0;
  127.     uint64_t                                    ect1;
  128.     uint64_t                                    ce;
  129.     uint64_t                                    ranges_length;
  130. } ngx_quic_ack_frame_t;


  131. typedef struct {
  132.     uint64_t                                    seqnum;
  133.     uint64_t                                    retire;
  134.     uint8_t                                     len;
  135.     u_char                                      cid[NGX_QUIC_CID_LEN_MAX];
  136.     u_char                                      srt[NGX_QUIC_SR_TOKEN_LEN];
  137. } ngx_quic_new_conn_id_frame_t;


  138. typedef struct {
  139.     uint64_t                                    length;
  140. } ngx_quic_new_token_frame_t;

  141. /*
  142. * common layout for CRYPTO and STREAM frames;
  143. * conceptually, CRYPTO frame is also a stream
  144. * frame lacking some properties
  145. */
  146. typedef struct {
  147.     uint64_t                                    offset;
  148.     uint64_t                                    length;
  149. } ngx_quic_ordered_frame_t;

  150. typedef ngx_quic_ordered_frame_t  ngx_quic_crypto_frame_t;


  151. typedef struct {
  152.     /* initial fields same as in ngx_quic_ordered_frame_t */
  153.     uint64_t                                    offset;
  154.     uint64_t                                    length;

  155.     uint64_t                                    stream_id;
  156.     unsigned                                    off:1;
  157.     unsigned                                    len:1;
  158.     unsigned                                    fin:1;
  159. } ngx_quic_stream_frame_t;


  160. typedef struct {
  161.     uint64_t                                    max_data;
  162. } ngx_quic_max_data_frame_t;


  163. typedef struct {
  164.     uint64_t                                    error_code;
  165.     uint64_t                                    frame_type;
  166.     ngx_str_t                                   reason;
  167. } ngx_quic_close_frame_t;


  168. typedef struct {
  169.     uint64_t                                    id;
  170.     uint64_t                                    error_code;
  171.     uint64_t                                    final_size;
  172. } ngx_quic_reset_stream_frame_t;


  173. typedef struct {
  174.     uint64_t                                    id;
  175.     uint64_t                                    error_code;
  176. } ngx_quic_stop_sending_frame_t;


  177. typedef struct {
  178.     uint64_t                                    limit;
  179.     ngx_uint_t                                  bidi;  /* unsigned: bidi:1 */
  180. } ngx_quic_streams_blocked_frame_t;


  181. typedef struct {
  182.     uint64_t                                    limit;
  183.     ngx_uint_t                                  bidi;  /* unsigned: bidi:1 */
  184. } ngx_quic_max_streams_frame_t;


  185. typedef struct {
  186.     uint64_t                                    id;
  187.     uint64_t                                    limit;
  188. } ngx_quic_max_stream_data_frame_t;


  189. typedef struct {
  190.     uint64_t                                    limit;
  191. } ngx_quic_data_blocked_frame_t;


  192. typedef struct {
  193.     uint64_t                                    id;
  194.     uint64_t                                    limit;
  195. } ngx_quic_stream_data_blocked_frame_t;


  196. typedef struct {
  197.     uint64_t                                    sequence_number;
  198. } ngx_quic_retire_cid_frame_t;


  199. typedef struct {
  200.     u_char                                      data[8];
  201. } ngx_quic_path_challenge_frame_t;


  202. typedef struct ngx_quic_frame_s                 ngx_quic_frame_t;

  203. struct ngx_quic_frame_s {
  204.     ngx_uint_t                                  type;
  205.     enum ssl_encryption_level_t                 level;
  206.     ngx_queue_t                                 queue;
  207.     uint64_t                                    pnum;
  208.     size_t                                      plen;
  209.     ngx_msec_t                                  send_time;
  210.     ssize_t                                     len;
  211.     unsigned                                    need_ack:1;
  212.     unsigned                                    pkt_need_ack:1;
  213.     unsigned                                    ignore_congestion:1;

  214.     ngx_chain_t                                *data;
  215.     union {
  216.         ngx_quic_ack_frame_t                    ack;
  217.         ngx_quic_crypto_frame_t                 crypto;
  218.         ngx_quic_ordered_frame_t                ord;
  219.         ngx_quic_new_conn_id_frame_t            ncid;
  220.         ngx_quic_new_token_frame_t              token;
  221.         ngx_quic_stream_frame_t                 stream;
  222.         ngx_quic_max_data_frame_t               max_data;
  223.         ngx_quic_close_frame_t                  close;
  224.         ngx_quic_reset_stream_frame_t           reset_stream;
  225.         ngx_quic_stop_sending_frame_t           stop_sending;
  226.         ngx_quic_streams_blocked_frame_t        streams_blocked;
  227.         ngx_quic_max_streams_frame_t            max_streams;
  228.         ngx_quic_max_stream_data_frame_t        max_stream_data;
  229.         ngx_quic_data_blocked_frame_t           data_blocked;
  230.         ngx_quic_stream_data_blocked_frame_t    stream_data_blocked;
  231.         ngx_quic_retire_cid_frame_t             retire_cid;
  232.         ngx_quic_path_challenge_frame_t         path_challenge;
  233.         ngx_quic_path_challenge_frame_t         path_response;
  234.     } u;
  235. };


  236. typedef struct {
  237.     ngx_log_t                                  *log;
  238.     ngx_quic_path_t                            *path;

  239.     ngx_quic_keys_t                            *keys;

  240.     ngx_msec_t                                  received;
  241.     uint64_t                                    number;
  242.     uint8_t                                     num_len;
  243.     uint32_t                                    trunc;
  244.     uint8_t                                     flags;
  245.     uint32_t                                    version;
  246.     ngx_str_t                                   token;
  247.     enum ssl_encryption_level_t                 level;
  248.     ngx_uint_t                                  error;

  249.     /* filled in by parser */
  250.     ngx_buf_t                                  *raw;   /* udp datagram */

  251.     u_char                                     *data;  /* quic packet */
  252.     size_t                                      len;

  253.     /* cleartext fields */
  254.     ngx_str_t                                   odcid; /* retry packet tag */
  255.     u_char                                      odcid_buf[NGX_QUIC_MAX_CID_LEN];
  256.     ngx_str_t                                   dcid;
  257.     ngx_str_t                                   scid;
  258.     uint64_t                                    pn;
  259.     u_char                                     *plaintext;
  260.     ngx_str_t                                   payload; /* decrypted data */

  261.     unsigned                                    need_ack:1;
  262.     unsigned                                    key_phase:1;
  263.     unsigned                                    key_update:1;
  264.     unsigned                                    parsed:1;
  265.     unsigned                                    decrypted:1;
  266.     unsigned                                    validated:1;
  267.     unsigned                                    retried:1;
  268.     unsigned                                    first:1;
  269.     unsigned                                    rebound:1;
  270.     unsigned                                    path_challenged:1;
  271. } ngx_quic_header_t;


  272. typedef struct {
  273.     ngx_msec_t                 max_idle_timeout;
  274.     ngx_msec_t                 max_ack_delay;

  275.     size_t                     max_udp_payload_size;
  276.     size_t                     initial_max_data;
  277.     size_t                     initial_max_stream_data_bidi_local;
  278.     size_t                     initial_max_stream_data_bidi_remote;
  279.     size_t                     initial_max_stream_data_uni;
  280.     ngx_uint_t                 initial_max_streams_bidi;
  281.     ngx_uint_t                 initial_max_streams_uni;
  282.     ngx_uint_t                 ack_delay_exponent;
  283.     ngx_uint_t                 active_connection_id_limit;
  284.     ngx_flag_t                 disable_active_migration;

  285.     ngx_str_t                  original_dcid;
  286.     ngx_str_t                  initial_scid;
  287.     ngx_str_t                  retry_scid;
  288.     u_char                     sr_token[NGX_QUIC_SR_TOKEN_LEN];

  289.     /* TODO */
  290.     void                      *preferred_address;
  291. } ngx_quic_tp_t;


  292. ngx_int_t ngx_quic_parse_packet(ngx_quic_header_t *pkt);

  293. size_t ngx_quic_create_version_negotiation(ngx_quic_header_t *pkt, u_char *out);

  294. size_t ngx_quic_payload_size(ngx_quic_header_t *pkt, size_t pkt_len);

  295. size_t ngx_quic_create_header(ngx_quic_header_t *pkt, u_char *out,
  296.     u_char **pnp);

  297. size_t ngx_quic_create_retry_itag(ngx_quic_header_t *pkt, u_char *out,
  298.     u_char **start);

  299. ssize_t ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end,
  300.     ngx_quic_frame_t *frame);
  301. ssize_t ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f);

  302. ssize_t ngx_quic_parse_ack_range(ngx_log_t *log, u_char *start,
  303.     u_char *end, uint64_t *gap, uint64_t *range);
  304. size_t ngx_quic_create_ack_range(u_char *p, uint64_t gap, uint64_t range);

  305. ngx_int_t ngx_quic_init_transport_params(ngx_quic_tp_t *tp,
  306.     ngx_quic_conf_t *qcf);
  307. ngx_int_t ngx_quic_parse_transport_params(u_char *p, u_char *end,
  308.     ngx_quic_tp_t *tp, ngx_log_t *log);
  309. ssize_t ngx_quic_create_transport_params(u_char *p, u_char *end,
  310.     ngx_quic_tp_t *tp, size_t *clen);

  311. void ngx_quic_dcid_encode_key(u_char *dcid, uint64_t key);

  312. #endif /* _NGX_EVENT_QUIC_TRANSPORT_H_INCLUDED_ */