/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ /* * lsquic_data_in_if.h -- DATA in interface */ #ifndef LSQUIC_DATA_IN_IF_H #define LSQUIC_DATA_IN_IF_H 1 struct data_frame; struct data_in; struct lsquic_conn_public; struct stream_frame; enum ins_frame { INS_FRAME_OK, INS_FRAME_ERR, INS_FRAME_DUP, INS_FRAME_OVERLAP, }; struct data_in_iface { void (*di_destroy) (struct data_in *); int (*di_empty) (struct data_in *); /* When INS_FRAME_OK, INS_FRAME_ERR, or INS_FRAME_DUP is returned, the * caller releases control of stream frame. Do not reference it after * the call. * * When INS_FRAME_OVERLAP is returned the caller has a choice to switch * to implementation that supports overlaps and try to insert the frame * again or to treat this as an error. Either way, the caller retains * control of the frame. */ enum ins_frame (*di_insert_frame) (struct data_in *, struct stream_frame *, uint64_t read_offset); struct data_frame * (*di_get_frame) (struct data_in *, uint64_t read_offset); void (*di_frame_done) (struct data_in *, struct data_frame *); /* Creates a new data_in object, feeds its stream frames to it, deletes * itself and returns the new object. */ struct data_in * (*di_switch_impl) (struct data_in *, uint64_t read_offset); size_t (*di_mem_used) (struct data_in *); void (*di_dump_state) (struct data_in *); /* Return number of bytes readable starting at offset `read_offset' */ uint64_t (*di_readable_bytes) (struct data_in *, uint64_t read_offset); /* If set, this means that when di_insert_frame() returns INS_FRAME_OK, * the data_in handler has taken ownership of the frame. Otherwise, it * is up to the caller to free it. */ const int di_own_on_ok; }; struct data_in { const struct data_in_iface *di_if; enum { /* If DI_SWITCH_IMPL is set, switching data_in implementation is * recommended in order to get better performance for current * incoming stream frame scenario. Check the value of this flag * after calls to di_insert_frame() and di_frame_done(). */ DI_SWITCH_IMPL = (1 << 0), } di_flags; }; /* This implementation does not support overlapping frame and may return * INS_FRAME_OVERLAP. */ struct data_in * lsquic_data_in_nocopy_new (struct lsquic_conn_public *, lsquic_stream_id_t); /* This implementation supports overlapping frames and will never return * INS_FRAME_OVERLAP. */ struct data_in * lsquic_data_in_hash_new (struct lsquic_conn_public *, lsquic_stream_id_t, uint64_t byteage); enum ins_frame lsquic_data_in_hash_insert_data_frame (struct data_in *data_in, const struct data_frame *data_frame, uint64_t read_offset); struct data_in * lsquic_data_in_error_new (); #endif