lsquic_packet_in.h revision c7d81ce1
1229fce07SDmitri Tikhonov/* Copyright (c) 2017 - 2019 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
950aadb33SDmitri Tikhonovstruct lsquic_packet_in;
1050aadb33SDmitri Tikhonov
1150aadb33SDmitri Tikhonovstruct data_frame
1250aadb33SDmitri Tikhonov{
1350aadb33SDmitri Tikhonov    const unsigned char *df_data;       /* Pointer to data */
1450aadb33SDmitri Tikhonov    uint64_t             df_offset;     /* Stream offset */
1550aadb33SDmitri Tikhonov    uint16_t             df_read_off;   /* Read offset */
1650aadb33SDmitri Tikhonov    uint16_t             df_size;       /* Size of df_data */
1750aadb33SDmitri Tikhonov    signed char          df_fin;        /* FIN? */
1850aadb33SDmitri Tikhonov};
1950aadb33SDmitri Tikhonov
2050aadb33SDmitri Tikhonovtypedef struct stream_frame
2150aadb33SDmitri Tikhonov{
2250aadb33SDmitri Tikhonov    /* Stream frames are stored in a list inside stream. */
2350aadb33SDmitri Tikhonov    TAILQ_ENTRY(stream_frame)       next_frame;
2450aadb33SDmitri Tikhonov
2550aadb33SDmitri Tikhonov    /* `data' points somewhere into the packet payload.  The packet object
2650aadb33SDmitri Tikhonov     * is reference-counted.  When the frame is freed, the packet is released
2750aadb33SDmitri Tikhonov     * via lsquic_packet_put().  If data_length is zero, the frame does not
2850aadb33SDmitri Tikhonov     * keep a reference to the incoming packet and this pointer is not set.
2950aadb33SDmitri Tikhonov     */
3050aadb33SDmitri Tikhonov    struct lsquic_packet_in        *packet_in;
3150aadb33SDmitri Tikhonov
3250aadb33SDmitri Tikhonov    struct data_frame               data_frame;
3350aadb33SDmitri Tikhonov
3450aadb33SDmitri Tikhonov    uint32_t stream_id;     /* Parsed from packet */
3550aadb33SDmitri Tikhonov} stream_frame_t;
3650aadb33SDmitri Tikhonov
3750aadb33SDmitri Tikhonovtypedef struct lsquic_packet_in
3850aadb33SDmitri Tikhonov{
3950aadb33SDmitri Tikhonov    TAILQ_ENTRY(lsquic_packet_in)   pi_next;
4050aadb33SDmitri Tikhonov    lsquic_time_t                   pi_received;   /* Time received */
4150aadb33SDmitri Tikhonov    lsquic_cid_t                    pi_conn_id;
4250aadb33SDmitri Tikhonov    lsquic_packno_t                 pi_packno;
4350aadb33SDmitri Tikhonov    unsigned short                  pi_header_sz;  /* Points to payload */
4450aadb33SDmitri Tikhonov    unsigned short                  pi_data_sz;    /* Data plus header */
4550aadb33SDmitri Tikhonov    /* A packet may be referred to by one or more frames and packets_in
4650aadb33SDmitri Tikhonov     * list.
4750aadb33SDmitri Tikhonov     */
4850aadb33SDmitri Tikhonov    unsigned short                  pi_refcnt;
49bfc7bfd8SDmitri Tikhonov    enum quic_ft_bit                pi_frame_types:16;
5050aadb33SDmitri Tikhonov    unsigned short                  pi_hsk_stream; /* Offset to handshake stream
5150aadb33SDmitri Tikhonov                                                    * frame, only valid if
5250aadb33SDmitri Tikhonov                                                    * PI_HSK_STREAM is set.
5350aadb33SDmitri Tikhonov                                                    */
5450aadb33SDmitri Tikhonov    unsigned char                   pi_quic_ver;   /* Offset to QUIC version */
5550aadb33SDmitri Tikhonov    unsigned char                   pi_nonce;      /* Offset to nonce */
5650aadb33SDmitri Tikhonov    enum {
5750aadb33SDmitri Tikhonov        PI_DECRYPTED    = (1 << 0),
5850aadb33SDmitri Tikhonov        PI_OWN_DATA     = (1 << 1),                /* We own pi_data */
5950aadb33SDmitri Tikhonov        PI_CONN_ID      = (1 << 2),                /* pi_conn_id is set */
60c51ce338SDmitri Tikhonov#define PIBIT_ENC_LEV_SHIFT 5
61c51ce338SDmitri Tikhonov        PI_ENC_LEV_BIT_0= (1 << 5),                /* Encodes encryption level */
62c51ce338SDmitri Tikhonov        PI_ENC_LEV_BIT_1= (1 << 6),                /*  (see enum enc_level). */
639626cfc2SDmitri Tikhonov        PI_GQUIC        = (1 << 7),
64c7d81ce1SDmitri Tikhonov#define PIBIT_BITS_SHIFT 8
65c7d81ce1SDmitri Tikhonov        PI_BITS_BIT_0   = (1 << 8),
66c7d81ce1SDmitri Tikhonov        PI_BITS_BIT_1   = (1 << 9),
67c7d81ce1SDmitri Tikhonov    }                               pi_flags:16;
689626cfc2SDmitri Tikhonov    enum header_type                pi_header_type:8;
6950aadb33SDmitri Tikhonov    /* If PI_OWN_DATA flag is not set, `pi_data' points to user-supplied
7050aadb33SDmitri Tikhonov     * packet data, which is NOT TO BE MODIFIED.
7150aadb33SDmitri Tikhonov     */
7250aadb33SDmitri Tikhonov    unsigned char                  *pi_data;
7350aadb33SDmitri Tikhonov} lsquic_packet_in_t;
7450aadb33SDmitri Tikhonov
7550aadb33SDmitri Tikhonov#define lsquic_packet_in_public_flags(p) ((p)->pi_data[0])
7650aadb33SDmitri Tikhonov
779626cfc2SDmitri Tikhonov#define lsquic_packet_in_is_gquic_prst(p) \
789626cfc2SDmitri Tikhonov    (((p)->pi_flags & PI_GQUIC) \
799626cfc2SDmitri Tikhonov        && (lsquic_packet_in_public_flags(p) & PACKET_PUBLIC_FLAGS_RST))
809626cfc2SDmitri Tikhonov
819626cfc2SDmitri Tikhonov#define lsquic_packet_in_is_verneg(p) \
829626cfc2SDmitri Tikhonov    (((p)->pi_flags & PI_GQUIC) ? \
839626cfc2SDmitri Tikhonov        lsquic_packet_in_public_flags(p) & PACKET_PUBLIC_FLAGS_VERSION : \
849626cfc2SDmitri Tikhonov        (p)->pi_header_type == HETY_VERNEG)
8550aadb33SDmitri Tikhonov
8650aadb33SDmitri Tikhonov#define lsquic_packet_in_packno_bits(p) \
87c7d81ce1SDmitri Tikhonov                        (((p)->pi_flags >> PIBIT_BITS_SHIFT) & 3)
8850aadb33SDmitri Tikhonov
8950aadb33SDmitri Tikhonov#define lsquic_packet_in_upref(p) (++(p)->pi_refcnt)
9050aadb33SDmitri Tikhonov
9150aadb33SDmitri Tikhonov#define lsquic_packet_in_get(p) (lsquic_packet_in_upref(p), (p))
9250aadb33SDmitri Tikhonov
9350aadb33SDmitri Tikhonov#define lsquic_packet_in_nonce(p) \
9450aadb33SDmitri Tikhonov                    ((p)->pi_nonce ? (p)->pi_data + (p)->pi_nonce : NULL)
9550aadb33SDmitri Tikhonov
96c51ce338SDmitri Tikhonov#define lsquic_packet_in_enc_level(p) \
97c51ce338SDmitri Tikhonov    (((p)->pi_flags >> PIBIT_ENC_LEV_SHIFT) & 0x3)
98c51ce338SDmitri Tikhonov
9950aadb33SDmitri Tikhonov/* The version iterator is used on a version negotiation packet only.
10050aadb33SDmitri Tikhonov * The iterator functions return 1 when next version is returned and
10150aadb33SDmitri Tikhonov * 0 when there are no more versions.
10250aadb33SDmitri Tikhonov */
10350aadb33SDmitri Tikhonovstruct ver_iter
10450aadb33SDmitri Tikhonov{
10550aadb33SDmitri Tikhonov    const struct lsquic_packet_in  *packet_in;
10650aadb33SDmitri Tikhonov    unsigned                        off;
10750aadb33SDmitri Tikhonov};
10850aadb33SDmitri Tikhonov
10950aadb33SDmitri Tikhonovint
11050aadb33SDmitri Tikhonovpacket_in_ver_first (const lsquic_packet_in_t *packet_in, struct ver_iter *,
11150aadb33SDmitri Tikhonov                     lsquic_ver_tag_t *ver_tag);
11250aadb33SDmitri Tikhonov
11350aadb33SDmitri Tikhonovint
11450aadb33SDmitri Tikhonovpacket_in_ver_next (struct ver_iter *, lsquic_ver_tag_t *ver_tag);
11550aadb33SDmitri Tikhonov
116c51ce338SDmitri Tikhonovsize_t
117c51ce338SDmitri Tikhonovlsquic_packet_in_mem_used (const struct lsquic_packet_in *);
118c51ce338SDmitri Tikhonov
11950aadb33SDmitri Tikhonov#endif
120