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