1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This file contains some protocol structures for use with Spdy. 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NET_SPDY_SPDY_PROTOCOL_H_ 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NET_SPDY_SPDY_PROTOCOL_H_ 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include <limits> 12201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/sys_byteorder.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_bitmasks.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Data Frame Format 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |0| Stream-ID (31bits) | 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Data | 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame Format 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1| Version(15bits) | Type(16bits) | 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Data | 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: SYN_STREAM 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000001| 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 40201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// | flags (8) | Length (24 bits) | >= 12 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Stream-ID(31bits) | 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X|Associated-To-Stream-ID (31bits)| 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |Pri| unused | Length (16bits)| 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: SYN_REPLY 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000010| 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | >= 8 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Stream-ID(31bits) | 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | unused (16 bits)| Length (16bits)| 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: RST_STREAM 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000011| 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | >= 4 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Stream-ID(31bits) | 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Status code (32 bits) | 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: SETTINGS 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000100| 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | # of entries (32) | 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: NOOP 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000101| 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | = 0 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: PING 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000110| 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | = 4 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Unique id (32 bits) | 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: GOAWAY 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000111| 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | = 4 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Last-accepted-stream-id | 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 105201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Control Frame: HEADERS 106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// |1|000000000000001|0000000000001000| 108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// | flags (8) | Length (24 bits) | >= 8 110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// |X| Stream-ID (31 bits) | 112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 113201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// | unused (16 bits)| Length (16bits)| 114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: WINDOW_UPDATE 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000001001| 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | = 8 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Stream-ID (31 bits) | 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Delta-Window-Size (32 bits) | 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace spdy { 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// This implementation of Spdy is version 2; It's like version 1, with some 129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// minor tweaks. 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst int kSpdyProtocolVersion = 2; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Initial window size for a Spdy stream 133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst size_t kSpdyStreamInitialWindowSize = 64 * 1024; // 64 KBytes 134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 135201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Maximum window size for a Spdy stream 136201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst size_t kSpdyStreamMaximumWindowSize = std::numeric_limits<int32>::max(); 137201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 138201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// HTTP-over-SPDY header constants 139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kMethod[] = "method"; 140201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kStatus[] = "status"; 141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kUrl[] = "url"; 142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kVersion[] = "version"; 143201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// When we server push, we will add [path: fully/qualified/url] to the server 144201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// push headers so that the client will know what url the data corresponds to. 145201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kPath[] = "path"; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note: all protocol data structures are on-the-wire format. That means that 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// data is stored in network-normalized order. Readers must use the 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// accessors provided or call ntohX() functions. 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Types of Spdy Control Frames. 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdyControlType { 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SYN_STREAM = 1, 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SYN_REPLY, 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RST_STREAM, 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS, 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOOP, 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PING, 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GOAWAY, 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HEADERS, 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WINDOW_UPDATE, 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NUM_CONTROL_FRAME_TYPES 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Flags on data packets. 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdyDataFlags { 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DATA_FLAG_NONE = 0, 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DATA_FLAG_FIN = 1, 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DATA_FLAG_COMPRESSED = 2 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Flags on control packets 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdyControlFlags { 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CONTROL_FLAG_NONE = 0, 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CONTROL_FLAG_FIN = 1, 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CONTROL_FLAG_UNIDIRECTIONAL = 2 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Flags on the SETTINGS control frame. 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdySettingsControlFlags { 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Flags for settings within a SETTINGS frame. 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdySettingsFlags { 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_FLAG_PLEASE_PERSIST = 0x1, 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_FLAG_PERSISTED = 0x2 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// List of known settings. 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdySettingsIds { 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_UPLOAD_BANDWIDTH = 0x1, 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_DOWNLOAD_BANDWIDTH = 0x2, 1942c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Network round trip time in milliseconds. 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_ROUND_TRIP_TIME = 0x3, 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_MAX_CONCURRENT_STREAMS = 0x4, 1972c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // TCP congestion window in packets. 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_CURRENT_CWND = 0x5, 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Downstream byte retransmission rate in percentage. 200201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SETTINGS_DOWNLOAD_RETRANS_RATE = 0x6, 201201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Initial window size in bytes 202201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SETTINGS_INITIAL_WINDOW_SIZE = 0x7 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Status codes, as used in control frames (primarily RST_STREAM). 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdyStatusCodes { 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INVALID = 0, 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PROTOCOL_ERROR = 1, 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INVALID_STREAM = 2, 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch REFUSED_STREAM = 3, 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UNSUPPORTED_VERSION = 4, 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CANCEL = 5, 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERNAL_ERROR = 6, 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FLOW_CONTROL_ERROR = 7, 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick INVALID_ASSOCIATED_STREAM = 8, 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NUM_STATUS_CODES = 9 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SPDY stream id is a 31 bit entity. 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef uint32 SpdyStreamId; 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 222201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A SPDY priority is a number between 0 and 3 (inclusive). 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef uint8 SpdyPriority; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// SPDY Priorities. (there are only 2 bits) 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define SPDY_PRIORITY_LOWEST 3 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define SPDY_PRIORITY_HIGHEST 0 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------------------------------------------------- 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// These structures mirror the protocol structure definitions. 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For the control data structures, we pack so that sizes match the 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// protocol over-the-wire sizes. 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma pack(push) 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma pack(1) 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A special structure for the 8 bit flags and 24 bit length fields. 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochunion FlagsAndLength { 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint8 flags_[4]; // 8 bits 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 length_; // 24 bits 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The basic SPDY Frame structure. 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdyFrameBlock { 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch union { 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct { 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 version_; 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 type_; 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } control_; 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct { 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id_; 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } data_; 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FlagsAndLength flags_length_; 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SYN_STREAM Control Frame structure. 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdySynStreamControlFrameBlock : SpdyFrameBlock { 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id_; 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId associated_stream_id_; 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyPriority priority_; 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint8 unused_; 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SYN_REPLY Control Frame structure. 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdySynReplyControlFrameBlock : SpdyFrameBlock { 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id_; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 unused_; 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A RST_STREAM Control Frame structure. 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdyRstStreamControlFrameBlock : SpdyFrameBlock { 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id_; 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 status_; 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A SETTINGS Control Frame structure. 278201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstruct SpdySettingsControlFrameBlock : SpdyFrameBlock { 279201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint32 num_entries_; 280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Variable data here. 281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 282201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2832c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun// A NOOP Control Frame structure. 2842c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurunstruct SpdyNoopControlFrameBlock : SpdyFrameBlock { 2852c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun}; 2862c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 2872c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun// A PING Control Frame structure. 2882c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurunstruct SpdyPingControlFrameBlock : SpdyFrameBlock { 2892c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun uint32 unique_id_; 2902c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun}; 2912c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A GOAWAY Control Frame structure. 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdyGoAwayControlFrameBlock : SpdyFrameBlock { 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId last_accepted_stream_id_; 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A HEADERS Control Frame structure. 298201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstruct SpdyHeadersControlFrameBlock : SpdyFrameBlock { 299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyStreamId stream_id_; 300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint16 unused_; 301201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 302201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 303201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A WINDOW_UPDATE Control Frame structure 304201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstruct SpdyWindowUpdateControlFrameBlock : SpdyFrameBlock { 305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyStreamId stream_id_; 306201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint32 delta_window_size_; 307201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A structure for the 8 bit flags and 24 bit ID fields. 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochunion SettingsFlagsAndId { 3112c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Sets both flags and id to the value for flags-and-id as sent over the wire 312201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SettingsFlagsAndId(uint32 val) : id_(val) {} 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint8 flags() const { return flags_[0]; } 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_flags(uint8 flags) { flags_[0] = flags; } 315201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint32 id() const { return (ntohl(id_) & kSettingsIdMask); } 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_id(uint32 id) { 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(0u, (id & ~kSettingsIdMask)); 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id = htonl(id & kSettingsIdMask); 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id_ = flags() | id; 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 3223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen uint8 flags_[4]; // 8 bits 3233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen uint32 id_; // 24 bits 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma pack(pop) 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------------------------------------------------- 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Wrapper classes for various SPDY frames. 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// All Spdy Frame types derive from this SpdyFrame class. 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyFrame { 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a SpdyFrame for a given sized buffer. 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit SpdyFrame(size_t size) : frame_(NULL), owns_buffer_(true) { 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(size, sizeof(struct SpdyFrameBlock)); 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* buffer = new char[size]; 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch memset(buffer, 0, size); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_ = reinterpret_cast<struct SpdyFrameBlock*>(buffer); 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a SpdyFrame using a pre-created buffer. 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If |owns_buffer| is true, this class takes ownership of the buffer 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and will delete it on cleanup. The buffer must have been created using 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // new char[]. 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If |owns_buffer| is false, the caller retains ownership of the buffer and 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // is responsible for making sure the buffer outlives this frame. In other 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // words, this class does NOT create a copy of the buffer. 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyFrame(char* data, bool owns_buffer) 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : frame_(reinterpret_cast<struct SpdyFrameBlock*>(data)), 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owns_buffer_(owns_buffer) { 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(frame_); 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~SpdyFrame() { 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (owns_buffer_) { 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* buffer = reinterpret_cast<char*>(frame_); 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete [] buffer; 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_ = NULL; 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Provides access to the frame bytes, which is a buffer containing 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the frame packed as expected for sending over the wire. 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* data() const { return reinterpret_cast<char*>(frame_); } 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint8 flags() const { return frame_->flags_length_.flags_[0]; } 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_flags(uint8 flags) { frame_->flags_length_.flags_[0] = flags; } 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 length() const { 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(frame_->flags_length_.length_) & kLengthMask; 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_length(uint32 length) { 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(0u, (length & ~kLengthMask)); 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch length = htonl(length & kLengthMask); 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_->flags_length_.length_ = flags() | length; 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_control_frame() const { 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (ntohs(frame_->control_.version_) & kControlFlagMask) == 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kControlFlagMask; 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyFrameBlock structure. 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Every SpdyFrame* class has a static size() method for accessing 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the size of the data structure which will be sent over the wire. 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the same as sizeof(SpdyFrame). 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(struct SpdyFrameBlock); } 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyFrameBlock* frame_; 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool owns_buffer_; 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyFrame); 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A Data Frame. 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyDataFrame : public SpdyFrame { 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyDataFrame() : SpdyFrame(size()) {} 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyDataFrame(char* data, bool owns_buffer) 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyFrame(data, owns_buffer) {} 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(frame_->data_.stream_id_) & kStreamIdMask; 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note that setting the stream id sets the control bit to false. 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // As stream id should always be set, this means the control bit 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // should always be set correctly. 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(0u, (id & ~kStreamIdMask)); 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_->data_.stream_id_ = htonl(id & kStreamIdMask); 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyFrameBlock structure. 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdyDataFrame class. 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return SpdyFrame::size(); } 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* payload() const { 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return reinterpret_cast<const char*>(frame_) + size(); 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyDataFrame); 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A Control Frame. 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyControlFrame : public SpdyFrame { 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit SpdyControlFrame(size_t size) : SpdyFrame(size) {} 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyControlFrame(char* data, bool owns_buffer) 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyFrame(data, owns_buffer) {} 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Callers can use this method to check if the frame appears to be a valid 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // frame. Does not guarantee that there are no errors. 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool AppearsToBeAValidControlFrame() const { 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Right now we only check if the frame has an out-of-bounds type. 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 type = ntohs(block()->control_.type_); 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES); 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 version() const { 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kVersionMask = 0x7fff; 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohs(block()->control_.version_) & kVersionMask; 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_version(uint16 version) { 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(0u, version & kControlFlagMask); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->control_.version_ = htons(kControlFlagMask | version); 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyControlType type() const { 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 type = ntohs(block()->control_.type_); 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES); 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyControlType>(type); 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_type(SpdyControlType type) { 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES); 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->control_.type_ = htons(type); 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4662c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Returns true if this control frame is of a type that has a header block, 4672c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // otherwise it returns false. 4682c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun bool has_header_block() const { 4692c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return type() == SYN_STREAM || type() == SYN_REPLY || type() == HEADERS; 4702c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 4712c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyFrameBlock structure. 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdyControlFrame class. 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdyFrameBlock); } 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4762c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // The size of the 'Number of Name/Value pairs' field in a Name/Value block. 4772c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static const size_t kNumNameValuePairsSize = 2; 4782c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 4792c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // The size of the 'Length of a name' field in a Name/Value block. 4802c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static const size_t kLengthOfNameSize = 2; 4812c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 4822c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // The size of the 'Length of a value' field in a Name/Value block. 4832c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static const size_t kLengthOfValueSize = 2; 4842c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdyFrameBlock* block() const { 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return frame_; 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdyFrameBlock* mutable_block() { 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return frame_; 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyControlFrame); 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SYN_STREAM frame. 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdySynStreamControlFrame : public SpdyControlFrame { 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySynStreamControlFrame() : SpdyControlFrame(size()) {} 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySynStreamControlFrame(char* data, bool owns_buffer) 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId associated_stream_id() const { 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->associated_stream_id_) & kStreamIdMask; 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_associated_stream_id(SpdyStreamId id) { 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->associated_stream_id_ = htonl(id & kStreamIdMask); 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyPriority priority() const { 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (block()->priority_ & kPriorityMask) >> 6; 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The number of bytes in the header block beyond the frame header length. 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int header_block_len() const { 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return length() - (size() - SpdyFrame::size()); 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_block() const { 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return reinterpret_cast<const char*>(block()) + size(); 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdySynStreamControlFrameBlock structure. 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdySynStreamControlFrame class. 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdySynStreamControlFrameBlock); } 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdySynStreamControlFrameBlock* block() const { 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdySynStreamControlFrameBlock*>(frame_); 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdySynStreamControlFrameBlock* mutable_block() { 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdySynStreamControlFrameBlock*>(frame_); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdySynStreamControlFrame); 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SYN_REPLY frame. 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdySynReplyControlFrame : public SpdyControlFrame { 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySynReplyControlFrame() : SpdyControlFrame(size()) {} 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySynReplyControlFrame(char* data, bool owns_buffer) 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int header_block_len() const { 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return length() - (size() - SpdyFrame::size()); 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_block() const { 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return reinterpret_cast<const char*>(block()) + size(); 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdySynReplyControlFrameBlock structure. 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdySynReplyControlFrame class. 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdySynReplyControlFrameBlock); } 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdySynReplyControlFrameBlock* block() const { 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdySynReplyControlFrameBlock*>(frame_); 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdySynReplyControlFrameBlock* mutable_block() { 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdySynReplyControlFrameBlock*>(frame_); 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdySynReplyControlFrame); 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A RST_STREAM frame. 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyRstStreamControlFrame : public SpdyControlFrame { 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyRstStreamControlFrame() : SpdyControlFrame(size()) {} 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyRstStreamControlFrame(char* data, bool owns_buffer) 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStatusCodes status() const { 5982c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun SpdyStatusCodes status = 5992c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static_cast<SpdyStatusCodes>(ntohl(block()->status_)); 6002c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun if (status < INVALID || status >= NUM_STATUS_CODES) { 6012c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun status = INVALID; 6022c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 6032c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return status; 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_status(SpdyStatusCodes status) { 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->status_ = htonl(static_cast<uint32>(status)); 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyRstStreamControlFrameBlock structure. 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdyRstStreamControlFrame class. 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdyRstStreamControlFrameBlock); } 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdyRstStreamControlFrameBlock* block() const { 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyRstStreamControlFrameBlock*>(frame_); 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdyRstStreamControlFrameBlock* mutable_block() { 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyRstStreamControlFrameBlock*>(frame_); 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamControlFrame); 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 623201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass SpdySettingsControlFrame : public SpdyControlFrame { 624201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch public: 625201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdySettingsControlFrame() : SpdyControlFrame(size()) {} 626201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdySettingsControlFrame(char* data, bool owns_buffer) 627201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch : SpdyControlFrame(data, owns_buffer) {} 628201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 629201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint32 num_entries() const { 630201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return ntohl(block()->num_entries_); 631201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 632201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 633201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void set_num_entries(int val) { 634201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch mutable_block()->num_entries_ = htonl(val); 635201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 636201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 637201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int header_block_len() const { 638201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return length() - (size() - SpdyFrame::size()); 639201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 640201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 641201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* header_block() const { 642201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return reinterpret_cast<const char*>(block()) + size(); 643201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 644201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 645201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Returns the size of the SpdySettingsControlFrameBlock structure. 646201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Note: this is not the size of the SpdySettingsControlFrameBlock class. 647201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static size_t size() { return sizeof(SpdySettingsControlFrameBlock); } 648201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 649201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch private: 650201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const struct SpdySettingsControlFrameBlock* block() const { 651201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return static_cast<SpdySettingsControlFrameBlock*>(frame_); 652201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 653201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch struct SpdySettingsControlFrameBlock* mutable_block() { 654201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return static_cast<SpdySettingsControlFrameBlock*>(frame_); 655201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 656201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DISALLOW_COPY_AND_ASSIGN(SpdySettingsControlFrame); 657201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 658201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 6592c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurunclass SpdyNoOpControlFrame : public SpdyControlFrame { 6602c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun public: 6612c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun SpdyNoOpControlFrame() : SpdyControlFrame(size()) {} 6622c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun SpdyNoOpControlFrame(char* data, bool owns_buffer) 6632c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun : SpdyControlFrame(data, owns_buffer) {} 6642c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 6652c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static size_t size() { return sizeof(SpdyNoopControlFrameBlock); } 6662c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun}; 6672c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 6682c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurunclass SpdyPingControlFrame : public SpdyControlFrame { 6692c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun public: 6702c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun SpdyPingControlFrame() : SpdyControlFrame(size()) {} 6712c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun SpdyPingControlFrame(char* data, bool owns_buffer) 6722c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun : SpdyControlFrame(data, owns_buffer) {} 6732c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 6742c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun uint32 unique_id() const { 6752c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return ntohl(block()->unique_id_); 6762c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 6772c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 6782c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun void set_unique_id(uint32 unique_id) { 6792c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun mutable_block()->unique_id_ = htonl(unique_id); 6802c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 6812c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 6822c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static size_t size() { return sizeof(SpdyPingControlFrameBlock); } 6832c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 6842c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun private: 6852c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun const struct SpdyPingControlFrameBlock* block() const { 6862c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return static_cast<SpdyPingControlFrameBlock*>(frame_); 6872c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 6882c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun struct SpdyPingControlFrameBlock* mutable_block() { 6892c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return static_cast<SpdyPingControlFrameBlock*>(frame_); 6902c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 6912c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun}; 6922c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyGoAwayControlFrame : public SpdyControlFrame { 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyGoAwayControlFrame() : SpdyControlFrame(size()) {} 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyGoAwayControlFrame(char* data, bool owns_buffer) 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId last_accepted_stream_id() const { 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->last_accepted_stream_id_) & kStreamIdMask; 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_last_accepted_stream_id(SpdyStreamId id) { 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->last_accepted_stream_id_ = htonl(id & kStreamIdMask); 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdyGoAwayControlFrameBlock); } 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdyGoAwayControlFrameBlock* block() const { 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyGoAwayControlFrameBlock*>(frame_); 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdyGoAwayControlFrameBlock* mutable_block() { 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyGoAwayControlFrameBlock*>(frame_); 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayControlFrame); 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 719201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A HEADERS frame. 720201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass SpdyHeadersControlFrame : public SpdyControlFrame { 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 722201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyHeadersControlFrame() : SpdyControlFrame(size()) {} 723201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyHeadersControlFrame(char* data, bool owns_buffer) 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 726201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyStreamId stream_id() const { 727201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 730201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void set_stream_id(SpdyStreamId id) { 731201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 734201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // The number of bytes in the header block beyond the frame header length. 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int header_block_len() const { 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return length() - (size() - SpdyFrame::size()); 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_block() const { 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return reinterpret_cast<const char*>(block()) + size(); 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 743201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Returns the size of the SpdyHeadersControlFrameBlock structure. 744201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Note: this is not the size of the SpdyHeadersControlFrame class. 745201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static size_t size() { return sizeof(SpdyHeadersControlFrameBlock); } 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 748201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const struct SpdyHeadersControlFrameBlock* block() const { 749201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return static_cast<SpdyHeadersControlFrameBlock*>(frame_); 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 751201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch struct SpdyHeadersControlFrameBlock* mutable_block() { 752201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return static_cast<SpdyHeadersControlFrameBlock*>(frame_); 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 754201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyHeadersControlFrame); 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A WINDOW_UPDATE frame. 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyWindowUpdateControlFrame : public SpdyControlFrame { 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyWindowUpdateControlFrame() : SpdyControlFrame(size()) {} 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyWindowUpdateControlFrame(char* data, bool owns_buffer) 762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 delta_window_size() const { 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->delta_window_size_); 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_delta_window_size(uint32 delta_window_size) { 777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->delta_window_size_ = htonl(delta_window_size); 778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyWindowUpdateControlFrameBlock structure. 781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdyWindowUpdateControlFrame class. 782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdyWindowUpdateControlFrameBlock); } 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdyWindowUpdateControlFrameBlock* block() const { 786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_); 787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdyWindowUpdateControlFrameBlock* mutable_block() { 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_); 790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateControlFrame); 793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace spdy 796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // NET_SPDY_SPDY_PROTOCOL_H_ 798