lsquic_packet_in.h revision de1c35dd
1/* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_packet_in.h
4 */
5
6#ifndef LSQUIC_PACKET_IN_H
7#define LSQUIC_PACKET_IN_H 1
8
9struct lsquic_packet_in;
10
11struct data_frame
12{
13    const unsigned char *df_data;       /* Pointer to data */
14    uint64_t             df_offset;     /* Stream offset */
15    uint16_t             df_read_off;   /* Read offset */
16    uint16_t             df_size;       /* Size of df_data */
17    signed char          df_fin;        /* FIN? */
18};
19
20typedef struct stream_frame
21{
22    /* Stream frames are stored in a list inside stream. */
23    TAILQ_ENTRY(stream_frame)       next_frame;
24
25    /* `data' points somewhere into the packet payload.  The packet object
26     * is reference-counted.  When the frame is freed, the packet is released
27     * via lsquic_packet_put().  If data_length is zero, the frame does not
28     * keep a reference to the incoming packet and this pointer is not set.
29     */
30    struct lsquic_packet_in        *packet_in;
31
32    struct data_frame               data_frame;
33
34    uint32_t stream_id;     /* Parsed from packet */
35} stream_frame_t;
36
37typedef struct lsquic_packet_in
38{
39    TAILQ_ENTRY(lsquic_packet_in)   pi_next;
40    lsquic_time_t                   pi_received;   /* Time received */
41    lsquic_cid_t                    pi_conn_id;
42    lsquic_packno_t                 pi_packno;
43    unsigned short                  pi_header_sz;  /* Points to payload */
44    unsigned short                  pi_data_sz;    /* Data plus header */
45    /* A packet may be referred to by one or more frames and packets_in
46     * list.
47     */
48    unsigned short                  pi_refcnt;
49    enum quic_ft_bit                pi_frame_types:16;
50    unsigned short                  pi_hsk_stream; /* Offset to handshake stream
51                                                    * frame, only valid if
52                                                    * PI_HSK_STREAM is set.
53                                                    */
54    unsigned char                   pi_quic_ver;   /* Offset to QUIC version */
55    unsigned char                   pi_nonce;      /* Offset to nonce */
56    enum {
57        PI_DECRYPTED    = (1 << 0),
58        PI_OWN_DATA     = (1 << 1),                /* We own pi_data */
59        PI_CONN_ID      = (1 << 2),                /* pi_conn_id is set */
60#define PIBIT_ENC_LEV_SHIFT 5
61        PI_ENC_LEV_BIT_0= (1 << 5),                /* Encodes encryption level */
62        PI_ENC_LEV_BIT_1= (1 << 6),                /*  (see enum enc_level). */
63        PI_GQUIC        = (1 << 7),
64    }                               pi_flags:8;
65    enum header_type                pi_header_type:8;
66    /* If PI_OWN_DATA flag is not set, `pi_data' points to user-supplied
67     * packet data, which is NOT TO BE MODIFIED.
68     */
69    unsigned char                  *pi_data;
70} lsquic_packet_in_t;
71
72#define lsquic_packet_in_public_flags(p) ((p)->pi_data[0])
73
74#define lsquic_packet_in_is_gquic_prst(p) \
75    (((p)->pi_flags & PI_GQUIC) \
76        && (lsquic_packet_in_public_flags(p) & PACKET_PUBLIC_FLAGS_RST))
77
78#define lsquic_packet_in_is_verneg(p) \
79    (((p)->pi_flags & PI_GQUIC) ? \
80        lsquic_packet_in_public_flags(p) & PACKET_PUBLIC_FLAGS_VERSION : \
81        (p)->pi_header_type == HETY_VERNEG)
82
83#define lsquic_packet_in_packno_bits(p) \
84    (((p)->pi_flags & PI_GQUIC) ? \
85                    ((lsquic_packet_in_public_flags(p) >> 4) & 3) : \
86                    ((p)->pi_header_type == HETY_NOT_SET ? \
87                    ((p)->pi_data[0] & 3) : PACKNO_LEN_4))
88
89#define lsquic_packet_in_upref(p) (++(p)->pi_refcnt)
90
91#define lsquic_packet_in_get(p) (lsquic_packet_in_upref(p), (p))
92
93#define lsquic_packet_in_nonce(p) \
94                    ((p)->pi_nonce ? (p)->pi_data + (p)->pi_nonce : NULL)
95
96#define lsquic_packet_in_enc_level(p) \
97    (((p)->pi_flags >> PIBIT_ENC_LEV_SHIFT) & 0x3)
98
99/* The version iterator is used on a version negotiation packet only.
100 * The iterator functions return 1 when next version is returned and
101 * 0 when there are no more versions.
102 */
103struct ver_iter
104{
105    const struct lsquic_packet_in  *packet_in;
106    unsigned                        off;
107};
108
109int
110packet_in_ver_first (const lsquic_packet_in_t *packet_in, struct ver_iter *,
111                     lsquic_ver_tag_t *ver_tag);
112
113int
114packet_in_ver_next (struct ver_iter *, lsquic_ver_tag_t *ver_tag);
115
116size_t
117lsquic_packet_in_mem_used (const struct lsquic_packet_in *);
118
119#endif
120