lsquic_data_in_if.h revision 06b2a236
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_data_in_if.h -- DATA in interface
4 */
5
6#ifndef LSQUIC_DATA_IN_IF_H
7#define LSQUIC_DATA_IN_IF_H 1
8
9
10struct data_frame;
11struct data_in;
12struct lsquic_conn_public;
13struct stream_frame;
14
15
16enum ins_frame
17{
18    INS_FRAME_OK,
19    INS_FRAME_ERR,
20    INS_FRAME_DUP,
21    INS_FRAME_OVERLAP,
22};
23
24
25struct data_in_iface
26{
27    void
28    (*di_destroy) (struct data_in *);
29
30    int
31    (*di_empty) (struct data_in *);
32
33    /* When INS_FRAME_OK, INS_FRAME_ERR, or INS_FRAME_DUP is returned, the
34     * caller releases control of stream frame.  Do not reference it after
35     * the call.
36     *
37     * When INS_FRAME_OVERLAP is returned the caller has a choice to switch
38     * to implementation that supports overlaps and try to insert the frame
39     * again or to treat this as an error.  Either way, the caller retains
40     * control of the frame.
41     */
42    enum ins_frame
43    (*di_insert_frame) (struct data_in *, struct stream_frame *,
44                                                        uint64_t read_offset);
45
46    struct data_frame *
47    (*di_get_frame) (struct data_in *, uint64_t read_offset);
48
49    void
50    (*di_frame_done) (struct data_in *, struct data_frame *);
51
52    /* Creates a new data_in object, feeds its stream frames to it, deletes
53     * itself and returns the new object.
54     */
55    struct data_in *
56    (*di_switch_impl) (struct data_in *, uint64_t read_offset);
57
58    size_t
59    (*di_mem_used) (struct data_in *);
60
61    void
62    (*di_dump_state) (struct data_in *);
63
64    /* Return number of bytes readable starting at offset `read_offset' */
65    uint64_t
66    (*di_readable_bytes) (struct data_in *, uint64_t read_offset);
67
68    /* If set, this means that when di_insert_frame() returns INS_FRAME_OK,
69     * the data_in handler has taken ownership of the frame.  Otherwise, it
70     * is up to the caller to free it.
71     */
72    const int
73    di_own_on_ok;
74};
75
76
77struct data_in
78{
79    const struct data_in_iface  *di_if;
80    enum {
81        /* If DI_SWITCH_IMPL is set, switching data_in implementation is
82         * recommended in order to get better performance for current
83         * incoming stream frame scenario.  Check the value of this flag
84         * after calls to di_insert_frame() and di_frame_done().
85         */
86        DI_SWITCH_IMPL = (1 << 0),
87    }                            di_flags;
88};
89
90
91/* This implementation does not support overlapping frame and may return
92 * INS_FRAME_OVERLAP.
93 */
94struct data_in *
95lsquic_data_in_nocopy_new (struct lsquic_conn_public *, lsquic_stream_id_t);
96
97/* This implementation supports overlapping frames and will never return
98 * INS_FRAME_OVERLAP.
99 */
100struct data_in *
101lsquic_data_in_hash_new (struct lsquic_conn_public *, lsquic_stream_id_t,
102                  uint64_t byteage);
103
104enum ins_frame
105lsquic_data_in_hash_insert_data_frame (struct data_in *data_in,
106                const struct data_frame *data_frame, uint64_t read_offset);
107
108struct data_in *
109lsquic_data_in_error_new ();
110
111#endif
112