lsquic_packet_in.h revision 9fc12041
17d09751dSDmitri Tikhonov/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * lsquic_packet_in.h
450aadb33SDmitri Tikhonov */
550aadb33SDmitri Tikhonov
650aadb33SDmitri Tikhonov#ifndef LSQUIC_PACKET_IN_H
750aadb33SDmitri Tikhonov#define LSQUIC_PACKET_IN_H 1
850aadb33SDmitri Tikhonov
95392f7a3SLiteSpeed Tech
1050aadb33SDmitri Tikhonovstruct lsquic_packet_in;
115392f7a3SLiteSpeed Techstruct lsquic_cid;
125392f7a3SLiteSpeed Tech
1350aadb33SDmitri Tikhonov
1450aadb33SDmitri Tikhonovstruct data_frame
1550aadb33SDmitri Tikhonov{
1650aadb33SDmitri Tikhonov    const unsigned char *df_data;       /* Pointer to data */
1750aadb33SDmitri Tikhonov    uint64_t             df_offset;     /* Stream offset */
1850aadb33SDmitri Tikhonov    uint16_t             df_read_off;   /* Read offset */
1950aadb33SDmitri Tikhonov    uint16_t             df_size;       /* Size of df_data */
2050aadb33SDmitri Tikhonov    signed char          df_fin;        /* FIN? */
2150aadb33SDmitri Tikhonov};
2250aadb33SDmitri Tikhonov
235392f7a3SLiteSpeed Tech
2450aadb33SDmitri Tikhonovtypedef struct stream_frame
2550aadb33SDmitri Tikhonov{
2650aadb33SDmitri Tikhonov    /* Stream frames are stored in a list inside stream. */
2750aadb33SDmitri Tikhonov    TAILQ_ENTRY(stream_frame)       next_frame;
2850aadb33SDmitri Tikhonov
2950aadb33SDmitri Tikhonov    /* `data' points somewhere into the packet payload.  The packet object
3050aadb33SDmitri Tikhonov     * is reference-counted.  When the frame is freed, the packet is released
3150aadb33SDmitri Tikhonov     * via lsquic_packet_put().  If data_length is zero, the frame does not
3250aadb33SDmitri Tikhonov     * keep a reference to the incoming packet and this pointer is not set.
3350aadb33SDmitri Tikhonov     */
3450aadb33SDmitri Tikhonov    struct lsquic_packet_in        *packet_in;
3550aadb33SDmitri Tikhonov
3650aadb33SDmitri Tikhonov    struct data_frame               data_frame;
3750aadb33SDmitri Tikhonov
385392f7a3SLiteSpeed Tech    lsquic_stream_id_t stream_id;     /* Parsed from packet */
3950aadb33SDmitri Tikhonov} stream_frame_t;
4050aadb33SDmitri Tikhonov
415392f7a3SLiteSpeed Tech
425392f7a3SLiteSpeed Tech#define DF_OFF(frame) (frame)->data_frame.df_offset
435392f7a3SLiteSpeed Tech#define DF_ROFF(frame) (DF_OFF(frame) + (frame)->data_frame.df_read_off)
445392f7a3SLiteSpeed Tech#define DF_FIN(frame) (frame)->data_frame.df_fin
455392f7a3SLiteSpeed Tech#define DF_SIZE(frame) (frame)->data_frame.df_size
465392f7a3SLiteSpeed Tech#define DF_END(frame) (DF_OFF(frame) + DF_SIZE(frame))
475392f7a3SLiteSpeed Tech
485392f7a3SLiteSpeed Tech
4950aadb33SDmitri Tikhonovtypedef struct lsquic_packet_in
5050aadb33SDmitri Tikhonov{
5150aadb33SDmitri Tikhonov    TAILQ_ENTRY(lsquic_packet_in)   pi_next;
5250aadb33SDmitri Tikhonov    lsquic_time_t                   pi_received;   /* Time received */
535392f7a3SLiteSpeed Tech    lsquic_cid_t                    pi_dcid;
545392f7a3SLiteSpeed Tech#define pi_conn_id pi_dcid
5550aadb33SDmitri Tikhonov    lsquic_packno_t                 pi_packno;
565392f7a3SLiteSpeed Tech    enum quic_ft_bit                pi_frame_types;
5750aadb33SDmitri Tikhonov    unsigned short                  pi_header_sz;  /* Points to payload */
5850aadb33SDmitri Tikhonov    unsigned short                  pi_data_sz;    /* Data plus header */
5950aadb33SDmitri Tikhonov    /* A packet may be referred to by one or more frames and packets_in
6050aadb33SDmitri Tikhonov     * list.
6150aadb33SDmitri Tikhonov     */
6250aadb33SDmitri Tikhonov    unsigned short                  pi_refcnt;
6350aadb33SDmitri Tikhonov    unsigned short                  pi_hsk_stream; /* Offset to handshake stream
6450aadb33SDmitri Tikhonov                                                    * frame, only valid if
6550aadb33SDmitri Tikhonov                                                    * PI_HSK_STREAM is set.
6650aadb33SDmitri Tikhonov                                                    */
6750aadb33SDmitri Tikhonov    enum {
6850aadb33SDmitri Tikhonov        PI_DECRYPTED    = (1 << 0),
6950aadb33SDmitri Tikhonov        PI_OWN_DATA     = (1 << 1),                /* We own pi_data */
7050aadb33SDmitri Tikhonov        PI_CONN_ID      = (1 << 2),                /* pi_conn_id is set */
715392f7a3SLiteSpeed Tech        PI_HSK_STREAM   = (1 << 3),                /* Has handshake data (mini only) */
725392f7a3SLiteSpeed Tech        PI_FROM_MINI    = (1 << 4),                /* Handed off by mini connection */
73c51ce338SDmitri Tikhonov#define PIBIT_ENC_LEV_SHIFT 5
74c51ce338SDmitri Tikhonov        PI_ENC_LEV_BIT_0= (1 << 5),                /* Encodes encryption level */
75c51ce338SDmitri Tikhonov        PI_ENC_LEV_BIT_1= (1 << 6),                /*  (see enum enc_level). */
769626cfc2SDmitri Tikhonov        PI_GQUIC        = (1 << 7),
775392f7a3SLiteSpeed Tech        PI_UNUSED_8     = (1 << 8),                /* <-- hole, reuse me! */
785392f7a3SLiteSpeed Tech#define PIBIT_ECN_SHIFT 9
795392f7a3SLiteSpeed Tech        PI_ECN_BIT_0    = (1 << 9),
805392f7a3SLiteSpeed Tech        PI_ECN_BIT_1    = (1 <<10),
815392f7a3SLiteSpeed Tech#define PIBIT_SPIN_SHIFT 11
825392f7a3SLiteSpeed Tech        PI_SPIN_BIT     = (1 <<11),
835392f7a3SLiteSpeed Tech#define PIBIT_BITS_SHIFT 12
845392f7a3SLiteSpeed Tech        PI_BITS_BIT_0   = (1 <<12),
855392f7a3SLiteSpeed Tech        PI_BITS_BIT_1   = (1 <<13),
8602b6086dSDmitri Tikhonov        /* Square bit and loss bit flags are used for logging */
8702b6086dSDmitri Tikhonov        PI_LOG_QL_BITS  = (1 <<14),
8802b6086dSDmitri Tikhonov        PI_SQUARE_BIT   = (1 <<15),
8902b6086dSDmitri Tikhonov        PI_LOSS_BIT     = (1 <<16),
9002b6086dSDmitri Tikhonov    }                               pi_flags;
915392f7a3SLiteSpeed Tech    /* pi_token and pi_token_size are set in Initial and Retry packets */
925392f7a3SLiteSpeed Tech    unsigned short                  pi_token_size; /* Size of the token */
935392f7a3SLiteSpeed Tech    unsigned char                   pi_token;      /* Offset to token */
949fc12041SDmitri Tikhonov    /* pi_odcid and pi_odcid_len are only set in Retry packets for I-D < 25 */
955392f7a3SLiteSpeed Tech    unsigned char                   pi_odcid;      /* Offset to Original DCID */
965392f7a3SLiteSpeed Tech    unsigned char                   pi_odcid_len;  /* Size of ODCID */
975392f7a3SLiteSpeed Tech    unsigned char                   pi_scid_off;   /* Offset to SCID */
985392f7a3SLiteSpeed Tech    unsigned char                   pi_scid_len;   /* Size of SCID */
995392f7a3SLiteSpeed Tech    unsigned char                   pi_quic_ver;   /* Offset to QUIC version */
1005392f7a3SLiteSpeed Tech    unsigned char                   pi_nonce;      /* Offset to nonce */
1019626cfc2SDmitri Tikhonov    enum header_type                pi_header_type:8;
1025392f7a3SLiteSpeed Tech    unsigned char                   pi_path_id;
10350aadb33SDmitri Tikhonov    /* If PI_OWN_DATA flag is not set, `pi_data' points to user-supplied
10450aadb33SDmitri Tikhonov     * packet data, which is NOT TO BE MODIFIED.
10550aadb33SDmitri Tikhonov     */
10650aadb33SDmitri Tikhonov    unsigned char                  *pi_data;
10750aadb33SDmitri Tikhonov} lsquic_packet_in_t;
10850aadb33SDmitri Tikhonov
1095392f7a3SLiteSpeed Tech
11050aadb33SDmitri Tikhonov#define lsquic_packet_in_public_flags(p) ((p)->pi_data[0])
11150aadb33SDmitri Tikhonov
1129626cfc2SDmitri Tikhonov#define lsquic_packet_in_is_gquic_prst(p) \
1139626cfc2SDmitri Tikhonov    (((p)->pi_flags & PI_GQUIC) \
1149626cfc2SDmitri Tikhonov        && (lsquic_packet_in_public_flags(p) & PACKET_PUBLIC_FLAGS_RST))
1159626cfc2SDmitri Tikhonov
1169626cfc2SDmitri Tikhonov#define lsquic_packet_in_is_verneg(p) \
1179626cfc2SDmitri Tikhonov    (((p)->pi_flags & PI_GQUIC) ? \
1189626cfc2SDmitri Tikhonov        lsquic_packet_in_public_flags(p) & PACKET_PUBLIC_FLAGS_VERSION : \
1199626cfc2SDmitri Tikhonov        (p)->pi_header_type == HETY_VERNEG)
12050aadb33SDmitri Tikhonov
12150aadb33SDmitri Tikhonov#define lsquic_packet_in_packno_bits(p) \
122c7d81ce1SDmitri Tikhonov                        (((p)->pi_flags >> PIBIT_BITS_SHIFT) & 3)
12350aadb33SDmitri Tikhonov
12450aadb33SDmitri Tikhonov#define lsquic_packet_in_upref(p) (++(p)->pi_refcnt)
12550aadb33SDmitri Tikhonov
12650aadb33SDmitri Tikhonov#define lsquic_packet_in_get(p) (lsquic_packet_in_upref(p), (p))
12750aadb33SDmitri Tikhonov
12850aadb33SDmitri Tikhonov#define lsquic_packet_in_nonce(p) \
12950aadb33SDmitri Tikhonov                    ((p)->pi_nonce ? (p)->pi_data + (p)->pi_nonce : NULL)
13050aadb33SDmitri Tikhonov
131c51ce338SDmitri Tikhonov#define lsquic_packet_in_enc_level(p) \
132c51ce338SDmitri Tikhonov    (((p)->pi_flags >> PIBIT_ENC_LEV_SHIFT) & 0x3)
133c51ce338SDmitri Tikhonov
1345392f7a3SLiteSpeed Tech#define lsquic_packet_in_ecn(p) \
1355392f7a3SLiteSpeed Tech    (((p)->pi_flags >> PIBIT_ECN_SHIFT) & 0x3)
1365392f7a3SLiteSpeed Tech
1375392f7a3SLiteSpeed Tech#define lsquic_packet_in_spin_bit(p) (((p)->pi_flags & PI_SPIN_BIT) > 0)
1385392f7a3SLiteSpeed Tech
1395392f7a3SLiteSpeed Tech/* PATH_CHALLENGE, PATH_RESPONSE, NEW_CONNECTION_ID, and PADDING frames
1405392f7a3SLiteSpeed Tech * are "probing frames", and all other frames are "non-probing frames".
1415392f7a3SLiteSpeed Tech * A packet containing only probing frames is a "probing packet", and a
1425392f7a3SLiteSpeed Tech * packet containing any other frame is a "non-probing packet".
1435392f7a3SLiteSpeed Tech *
1445392f7a3SLiteSpeed Tech * [draft-ietf-quic-transport-20], Section 9.1
1455392f7a3SLiteSpeed Tech */
1465392f7a3SLiteSpeed Tech#define lsquic_packet_in_non_probing(p) \
1475392f7a3SLiteSpeed Tech   (!!((p)->pi_frame_types & ~(QUIC_FTBIT_PATH_CHALLENGE                \
1485392f7a3SLiteSpeed Tech                        |QUIC_FTBIT_PATH_RESPONSE|QUIC_FTBIT_PADDING    \
1495392f7a3SLiteSpeed Tech                        |QUIC_FTBIT_NEW_CONNECTION_ID)))
1505392f7a3SLiteSpeed Tech
15150aadb33SDmitri Tikhonov/* The version iterator is used on a version negotiation packet only.
15250aadb33SDmitri Tikhonov * The iterator functions return 1 when next version is returned and
15350aadb33SDmitri Tikhonov * 0 when there are no more versions.
15450aadb33SDmitri Tikhonov */
15550aadb33SDmitri Tikhonovstruct ver_iter
15650aadb33SDmitri Tikhonov{
15750aadb33SDmitri Tikhonov    const struct lsquic_packet_in  *packet_in;
15850aadb33SDmitri Tikhonov    unsigned                        off;
15950aadb33SDmitri Tikhonov};
16050aadb33SDmitri Tikhonov
16150aadb33SDmitri Tikhonovint
16250aadb33SDmitri Tikhonovpacket_in_ver_first (const lsquic_packet_in_t *packet_in, struct ver_iter *,
16350aadb33SDmitri Tikhonov                     lsquic_ver_tag_t *ver_tag);
16450aadb33SDmitri Tikhonov
16550aadb33SDmitri Tikhonovint
16650aadb33SDmitri Tikhonovpacket_in_ver_next (struct ver_iter *, lsquic_ver_tag_t *ver_tag);
16750aadb33SDmitri Tikhonov
168c51ce338SDmitri Tikhonovsize_t
169c51ce338SDmitri Tikhonovlsquic_packet_in_mem_used (const struct lsquic_packet_in *);
170c51ce338SDmitri Tikhonov
1715392f7a3SLiteSpeed Techvoid
1725392f7a3SLiteSpeed Techlsquic_scid_from_packet_in (const struct lsquic_packet_in *,
1735392f7a3SLiteSpeed Tech                                                    struct lsquic_cid *);
1745392f7a3SLiteSpeed Tech
17550aadb33SDmitri Tikhonov#endif
176