1 /***************************************************************************** 2 * h2frame.h: HTTP/2 frame formatting 3 ***************************************************************************** 4 * Copyright (C) 2015 Rémi Denis-Courmont 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation; either version 2.1 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with this program; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 19 *****************************************************************************/ 20 21 #include <stdbool.h> 22 #include <stdint.h> 23 24 /** 25 * \defgroup h2_frames HTTP/2 frames 26 * \ingroup h2 27 * @{ 28 */ 29 30 struct vlc_h2_frame 31 { 32 struct vlc_h2_frame *next; 33 uint8_t data[]; 34 }; 35 36 size_t vlc_h2_frame_size(const struct vlc_h2_frame *); 37 38 struct vlc_h2_frame * 39 vlc_h2_frame_headers(uint_fast32_t stream_id, uint_fast32_t mtu, bool eos, 40 unsigned count, const char *const headers[][2]); 41 struct vlc_h2_frame * 42 vlc_h2_frame_data(uint_fast32_t stream_id, const void *buf, size_t len, 43 bool eos); 44 struct vlc_h2_frame * 45 vlc_h2_frame_rst_stream(uint_fast32_t stream_id, uint_fast32_t error_code); 46 struct vlc_h2_frame *vlc_h2_frame_settings(void); 47 struct vlc_h2_frame *vlc_h2_frame_settings_ack(void); 48 struct vlc_h2_frame *vlc_h2_frame_ping(uint64_t opaque); 49 struct vlc_h2_frame *vlc_h2_frame_pong(uint64_t opaque); 50 struct vlc_h2_frame * 51 vlc_h2_frame_goaway(uint_fast32_t last_stream_id, uint_fast32_t error_code); 52 struct vlc_h2_frame * 53 vlc_h2_frame_window_update(uint_fast32_t stream_id, uint_fast32_t credit); 54 55 void vlc_h2_frame_dump(void *, const struct vlc_h2_frame *, const char *); 56 57 enum vlc_h2_error { 58 VLC_H2_NO_ERROR, 59 VLC_H2_PROTOCOL_ERROR, 60 VLC_H2_INTERNAL_ERROR, 61 VLC_H2_FLOW_CONTROL_ERROR, 62 VLC_H2_SETTINGS_TIMEOUT, 63 VLC_H2_STREAM_CLOSED, 64 VLC_H2_FRAME_SIZE_ERROR, 65 VLC_H2_REFUSED_STREAM, 66 VLC_H2_CANCEL, 67 VLC_H2_COMPRESSION_ERROR, 68 VLC_H2_CONNECT_ERROR, 69 VLC_H2_ENHANCE_YOUR_CALM, 70 VLC_H2_INADEQUATE_SECURITY, 71 VLC_H2_HTTP_1_1_REQUIRED, 72 }; 73 74 const char *vlc_h2_strerror(uint_fast32_t); 75 76 enum vlc_h2_setting { 77 VLC_H2_SETTING_HEADER_TABLE_SIZE = 0x0001, 78 VLC_H2_SETTING_ENABLE_PUSH, 79 VLC_H2_SETTING_MAX_CONCURRENT_STREAMS, 80 VLC_H2_SETTING_INITIAL_WINDOW_SIZE, 81 VLC_H2_SETTING_MAX_FRAME_SIZE, 82 VLC_H2_SETTING_MAX_HEADER_LIST_SIZE, 83 }; 84 85 const char *vlc_h2_setting_name(uint_fast16_t); 86 87 /* Our settings */ 88 #define VLC_H2_MAX_HEADER_TABLE 4096 /* Header (compression) table size */ 89 #define VLC_H2_MAX_STREAMS 0 /* Concurrent peer-initiated streams */ 90 #define VLC_H2_INIT_WINDOW 1048575 /* Initial congestion window size */ 91 #define VLC_H2_MAX_FRAME 1048576 /* Frame size */ 92 #define VLC_H2_MAX_HEADER_LIST 65536 /* Header (decompressed) list size */ 93 94 /* Protocol default settings */ 95 #define VLC_H2_DEFAULT_MAX_HEADER_TABLE 4096 96 #define VLC_H2_DEFAULT_INIT_WINDOW 65535 97 #define VLC_H2_DEFAULT_MAX_FRAME 16384 98 99 struct vlc_h2_parser; 100 struct vlc_h2_parser_cbs 101 { 102 void (*setting)(void *ctx, uint_fast16_t id, uint_fast32_t value); 103 int (*settings_done)(void *ctx); 104 int (*ping)(void *ctx, uint_fast64_t opaque); 105 void (*error)(void *ctx, uint_fast32_t code); 106 int (*reset)(void *ctx, uint_fast32_t last_seq, uint_fast32_t code); 107 void (*window_status)(void *ctx, uint32_t *rcwd); 108 109 void *(*stream_lookup)(void *ctx, uint_fast32_t id); 110 int (*stream_error)(void *ctx, uint_fast32_t id, uint_fast32_t code); 111 void (*stream_headers)(void *ctx, unsigned count, 112 const char *const headers[][2]); 113 int (*stream_data)(void *ctx, struct vlc_h2_frame *f); 114 void (*stream_end)(void *ctx); 115 int (*stream_reset)(void *ctx, uint_fast32_t code); 116 }; 117 118 struct vlc_h2_parser *vlc_h2_parse_init(void *ctx, 119 const struct vlc_h2_parser_cbs *cbs); 120 int vlc_h2_parse(struct vlc_h2_parser *, struct vlc_h2_frame *); 121 void vlc_h2_parse_destroy(struct vlc_h2_parser *); 122 123 #define VLC_H2_MAX_HEADERS 255 124 125 const uint8_t *vlc_h2_frame_data_get(const struct vlc_h2_frame *f, 126 size_t *restrict len); 127 #define vlc_h2_frame_data_get(f, l) \ 128 _Generic((f), \ 129 const struct vlc_h2_frame *: (vlc_h2_frame_data_get)(f, l), \ 130 struct vlc_h2_frame *: (uint8_t *)(vlc_h2_frame_data_get)(f, l)) 131 132 /** @} */ 133