diff options
Diffstat (limited to 'src/core/transport/chttp2/internal.h')
-rw-r--r-- | src/core/transport/chttp2/internal.h | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h new file mode 100644 index 0000000000..e09c6bc742 --- /dev/null +++ b/src/core/transport/chttp2/internal.h @@ -0,0 +1,306 @@ +#ifndef GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H +#define GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H + +#include "src/core/transport/transport_impl.h" + +typedef struct transport transport; +typedef struct stream stream; + +/* streams are kept in various linked lists depending on what things need to + happen to them... this enum labels each list */ +typedef enum { + /* streams that have pending writes */ + WRITABLE = 0, + /* streams that have been selected to be written */ + WRITING, + /* streams that have just been written, and included a close */ + WRITTEN_CLOSED, + /* streams that have been cancelled and have some pending state updates + to perform */ + CANCELLED, + /* streams that want to send window updates */ + WINDOW_UPDATE, + /* streams that are waiting to start because there are too many concurrent + streams on the connection */ + WAITING_FOR_CONCURRENCY, + /* streams that have finished reading: we wait until unlock to coalesce + all changes into one callback */ + FINISHED_READ_OP, + MAYBE_FINISH_READ_AFTER_PARSE, + PARSER_CHECK_WINDOW_UPDATES_AFTER_PARSE, + OTHER_CHECK_WINDOW_UPDATES_AFTER_PARSE, + NEW_OUTGOING_WINDOW, + STREAM_LIST_COUNT /* must be last */ +} stream_list_id; + +/* deframer state for the overall http2 stream of bytes */ +typedef enum { + /* prefix: one entry per http2 connection prefix byte */ + DTS_CLIENT_PREFIX_0 = 0, + DTS_CLIENT_PREFIX_1, + DTS_CLIENT_PREFIX_2, + DTS_CLIENT_PREFIX_3, + DTS_CLIENT_PREFIX_4, + DTS_CLIENT_PREFIX_5, + DTS_CLIENT_PREFIX_6, + DTS_CLIENT_PREFIX_7, + DTS_CLIENT_PREFIX_8, + DTS_CLIENT_PREFIX_9, + DTS_CLIENT_PREFIX_10, + DTS_CLIENT_PREFIX_11, + DTS_CLIENT_PREFIX_12, + DTS_CLIENT_PREFIX_13, + DTS_CLIENT_PREFIX_14, + DTS_CLIENT_PREFIX_15, + DTS_CLIENT_PREFIX_16, + DTS_CLIENT_PREFIX_17, + DTS_CLIENT_PREFIX_18, + DTS_CLIENT_PREFIX_19, + DTS_CLIENT_PREFIX_20, + DTS_CLIENT_PREFIX_21, + DTS_CLIENT_PREFIX_22, + DTS_CLIENT_PREFIX_23, + /* frame header byte 0... */ + /* must follow from the prefix states */ + DTS_FH_0, + DTS_FH_1, + DTS_FH_2, + DTS_FH_3, + DTS_FH_4, + DTS_FH_5, + DTS_FH_6, + DTS_FH_7, + /* ... frame header byte 8 */ + DTS_FH_8, + /* inside a http2 frame */ + DTS_FRAME +} deframe_transport_state; + +typedef enum { + WRITE_STATE_OPEN, + WRITE_STATE_QUEUED_CLOSE, + WRITE_STATE_SENT_CLOSE +} write_state; + +typedef enum { + DONT_SEND_CLOSED = 0, + SEND_CLOSED, + SEND_CLOSED_WITH_RST_STREAM +} send_closed; + +typedef struct { + stream *head; + stream *tail; +} stream_list; + +typedef struct { + stream *next; + stream *prev; +} stream_link; + +typedef enum { + ERROR_STATE_NONE, + ERROR_STATE_SEEN, + ERROR_STATE_NOTIFIED +} error_state; + +/* We keep several sets of connection wide parameters */ +typedef enum { + /* The settings our peer has asked for (and we have acked) */ + PEER_SETTINGS = 0, + /* The settings we'd like to have */ + LOCAL_SETTINGS, + /* The settings we've published to our peer */ + SENT_SETTINGS, + /* The settings the peer has acked */ + ACKED_SETTINGS, + NUM_SETTING_SETS +} setting_set; + +/* Outstanding ping request data */ +typedef struct { + gpr_uint8 id[8]; + void (*cb)(void *user_data); + void *user_data; +} outstanding_ping; + +typedef struct { + grpc_status_code status; + gpr_slice debug; +} pending_goaway; + +struct transport { + grpc_transport base; /* must be first */ + grpc_endpoint *ep; + grpc_mdctx *metadata_context; + gpr_refcount refs; + gpr_uint8 is_client; + + gpr_mu mu; + gpr_cv cv; + + /* basic state management - what are we doing at the moment? */ + gpr_uint8 reading; + /** are we calling back any grpc_transport_op completion events */ + gpr_uint8 calling_back_ops; + gpr_uint8 destroying; + gpr_uint8 closed; + error_state error_state; + + /* stream indexing */ + gpr_uint32 next_stream_id; + gpr_uint32 last_incoming_stream_id; + + /* settings */ + gpr_uint32 settings[NUM_SETTING_SETS][GRPC_CHTTP2_NUM_SETTINGS]; + gpr_uint32 force_send_settings; /* bitmask of setting indexes to send out */ + gpr_uint8 sent_local_settings; /* have local settings been sent? */ + gpr_uint8 dirtied_local_settings; /* are the local settings dirty? */ + + /* window management */ + gpr_uint32 outgoing_window; + gpr_uint32 outgoing_window_update; + gpr_uint32 incoming_window; + gpr_uint32 connection_window_target; + + /* deframing */ + deframe_transport_state deframe_state; + gpr_uint8 incoming_frame_type; + gpr_uint8 incoming_frame_flags; + gpr_uint8 header_eof; + gpr_uint32 expect_continuation_stream_id; + gpr_uint32 incoming_frame_size; + gpr_uint32 incoming_stream_id; + + /* goaway */ + pending_goaway *pending_goaways; + size_t num_pending_goaways; + size_t cap_pending_goaways; + + /* state for a stream that's not yet been created */ + grpc_stream_op_buffer new_stream_sopb; + + /* stream ops that need to be destroyed, but outside of the lock */ + grpc_stream_op_buffer nuke_later_sopb; + + /* active parser */ + void *parser_data; + stream *incoming_stream; + grpc_chttp2_parse_error (*parser)(void *parser_user_data, + grpc_chttp2_parse_state *state, + gpr_slice slice, int is_last); + + stream_list lists[STREAM_LIST_COUNT]; + grpc_chttp2_stream_map stream_map; + + /* pings */ + outstanding_ping *pings; + size_t ping_count; + size_t ping_capacity; + gpr_int64 ping_counter; + + struct { + /* metadata object cache */ + grpc_mdstr *str_grpc_timeout; + } constants; + + struct { + /** data to write next write */ + gpr_slice_buffer qbuf; + /* queued callbacks */ + grpc_iomgr_closure *pending_closures; + } global; + + struct { + /** is a thread currently writing */ + gpr_uint8 executing; + /** closure to execute this action */ + grpc_iomgr_closure action; + /** data to write now */ + gpr_slice_buffer outbuf; + /* hpack encoding */ + grpc_chttp2_hpack_compressor hpack_compressor; + } writing; + + struct { + /** is a thread currently parsing */ + gpr_uint8 executing; + /** data to write later - after parsing */ + gpr_slice_buffer qbuf; + /** parser for headers */ + grpc_chttp2_hpack_parser hpack_parser; + /** simple one shot parsers */ + union { + grpc_chttp2_window_update_parser window_update; + grpc_chttp2_settings_parser settings; + grpc_chttp2_ping_parser ping; + grpc_chttp2_rst_stream_parser rst_stream; + } simple; + /** parser for goaway frames */ + grpc_chttp2_goaway_parser goaway_parser; + } parsing; + + struct { + /** is a thread currently performing channel callbacks */ + gpr_uint8 executing; + /** transport channel-level callback */ + const grpc_transport_callbacks *cb; + /** user data for cb calls */ + void *cb_user_data; + /** closure for notifying transport closure */ + grpc_iomgr_closure notify_closed; + } channel_callback; +}; + +struct stream { + struct { + grpc_iomgr_closure *send_done_closure; + grpc_iomgr_closure *recv_done_closure; + } global; + + struct { + /* sops that have passed flow control to be written */ + grpc_stream_op_buffer sopb; + /* how strongly should we indicate closure with the next write */ + send_closed send_closed; + } writing; + + struct { + int unused; + } parsing; + + gpr_uint32 id; + + gpr_uint32 incoming_window; + gpr_int64 outgoing_window; + gpr_uint32 outgoing_window_update; + /* when the application requests writes be closed, the write_closed is + 'queued'; when the close is flow controlled into the send path, we are + 'sending' it; when the write has been performed it is 'sent' */ + write_state write_state; + gpr_uint8 read_closed; + gpr_uint8 cancelled; + + stream_link links[STREAM_LIST_COUNT]; + gpr_uint8 included[STREAM_LIST_COUNT]; + + /* incoming metadata */ + grpc_linked_mdelem *incoming_metadata; + size_t incoming_metadata_count; + size_t incoming_metadata_capacity; + grpc_linked_mdelem *old_incoming_metadata; + gpr_timespec incoming_deadline; + + /* sops from application */ + grpc_stream_op_buffer *outgoing_sopb; + grpc_stream_op_buffer *incoming_sopb; + grpc_stream_state *publish_state; + grpc_stream_state published_state; + + grpc_chttp2_data_parser parser; + + grpc_stream_state callback_state; + grpc_stream_op_buffer callback_sopb; +}; + +#endif |