spdy_protocol.h revision 201ade2fbba22bfb27ae029f4d23fca6ded109a0
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 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef WIN32 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <winsock2.h> 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <arpa/inet.h> 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include <limits> 18201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_bitmasks.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Data Frame Format 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |0| Stream-ID (31bits) | 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Data | 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame Format 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1| Version(15bits) | Type(16bits) | 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Data | 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: SYN_STREAM 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000001| 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 45201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// | flags (8) | Length (24 bits) | >= 12 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Stream-ID(31bits) | 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X|Associated-To-Stream-ID (31bits)| 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |Pri| unused | Length (16bits)| 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: SYN_REPLY 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000010| 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | >= 8 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Stream-ID(31bits) | 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | unused (16 bits)| Length (16bits)| 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: RST_STREAM 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000011| 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | >= 4 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Stream-ID(31bits) | 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Status code (32 bits) | 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: SETTINGS 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000100| 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | # of entries (32) | 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: NOOP 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000101| 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | = 0 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: PING 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000110| 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | = 4 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Unique id (32 bits) | 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: GOAWAY 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000000111| 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | = 4 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Last-accepted-stream-id | 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Control Frame: HEADERS 111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// |1|000000000000001|0000000000001000| 113201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// | flags (8) | Length (24 bits) | >= 8 115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// |X| Stream-ID (31 bits) | 117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// | unused (16 bits)| Length (16bits)| 119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// +----------------------------------+ 120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Control Frame: WINDOW_UPDATE 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |1|000000000000001|0000000000001001| 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | flags (8) | Length (24 bits) | = 8 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |X| Stream-ID (31 bits) | 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | Delta-Window-Size (32 bits) | 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// +----------------------------------+ 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace spdy { 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// This implementation of Spdy is version 2; It's like version 1, with some 134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// minor tweaks. 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst int kSpdyProtocolVersion = 2; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 137201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Initial window size for a Spdy stream 138201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst size_t kSpdyStreamInitialWindowSize = 64 * 1024; // 64 KBytes 139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 140201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Maximum window size for a Spdy stream 141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst size_t kSpdyStreamMaximumWindowSize = std::numeric_limits<int32>::max(); 142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 143201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// HTTP-over-SPDY header constants 144201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kMethod[] = "method"; 145201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kStatus[] = "status"; 146201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kUrl[] = "url"; 147201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kVersion[] = "version"; 148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// When we server push, we will add [path: fully/qualified/url] to the server 149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// push headers so that the client will know what url the data corresponds to. 150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kPath[] = "path"; 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note: all protocol data structures are on-the-wire format. That means that 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// data is stored in network-normalized order. Readers must use the 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// accessors provided or call ntohX() functions. 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Types of Spdy Control Frames. 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdyControlType { 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SYN_STREAM = 1, 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SYN_REPLY, 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RST_STREAM, 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS, 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOOP, 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PING, 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GOAWAY, 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HEADERS, 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WINDOW_UPDATE, 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NUM_CONTROL_FRAME_TYPES 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Flags on data packets. 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdyDataFlags { 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DATA_FLAG_NONE = 0, 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DATA_FLAG_FIN = 1, 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DATA_FLAG_COMPRESSED = 2 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Flags on control packets 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdyControlFlags { 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CONTROL_FLAG_NONE = 0, 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CONTROL_FLAG_FIN = 1, 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CONTROL_FLAG_UNIDIRECTIONAL = 2 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Flags on the SETTINGS control frame. 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdySettingsControlFlags { 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Flags for settings within a SETTINGS frame. 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdySettingsFlags { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_FLAG_PLEASE_PERSIST = 0x1, 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_FLAG_PERSISTED = 0x2 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// List of known settings. 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdySettingsIds { 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_UPLOAD_BANDWIDTH = 0x1, 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_DOWNLOAD_BANDWIDTH = 0x2, 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_ROUND_TRIP_TIME = 0x3, 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_MAX_CONCURRENT_STREAMS = 0x4, 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SETTINGS_CURRENT_CWND = 0x5, 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Downstream byte retransmission rate in percentage. 203201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SETTINGS_DOWNLOAD_RETRANS_RATE = 0x6, 204201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Initial window size in bytes 205201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SETTINGS_INITIAL_WINDOW_SIZE = 0x7 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Status codes, as used in control frames (primarily RST_STREAM). 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SpdyStatusCodes { 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INVALID = 0, 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PROTOCOL_ERROR = 1, 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INVALID_STREAM = 2, 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch REFUSED_STREAM = 3, 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UNSUPPORTED_VERSION = 4, 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CANCEL = 5, 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERNAL_ERROR = 6, 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FLOW_CONTROL_ERROR = 7, 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick INVALID_ASSOCIATED_STREAM = 8, 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NUM_STATUS_CODES = 9 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SPDY stream id is a 31 bit entity. 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef uint32 SpdyStreamId; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 225201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A SPDY priority is a number between 0 and 3 (inclusive). 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef uint8 SpdyPriority; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// SPDY Priorities. (there are only 2 bits) 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define SPDY_PRIORITY_LOWEST 3 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define SPDY_PRIORITY_HIGHEST 0 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------------------------------------------------- 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// These structures mirror the protocol structure definitions. 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For the control data structures, we pack so that sizes match the 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// protocol over-the-wire sizes. 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma pack(push) 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma pack(1) 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A special structure for the 8 bit flags and 24 bit length fields. 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochunion FlagsAndLength { 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint8 flags_[4]; // 8 bits 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 length_; // 24 bits 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The basic SPDY Frame structure. 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdyFrameBlock { 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch union { 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct { 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 version_; 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 type_; 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } control_; 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct { 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id_; 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } data_; 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FlagsAndLength flags_length_; 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SYN_STREAM Control Frame structure. 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdySynStreamControlFrameBlock : SpdyFrameBlock { 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id_; 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId associated_stream_id_; 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyPriority priority_; 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint8 unused_; 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SYN_REPLY Control Frame structure. 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdySynReplyControlFrameBlock : SpdyFrameBlock { 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id_; 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 unused_; 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A RST_STREAM Control Frame structure. 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdyRstStreamControlFrameBlock : SpdyFrameBlock { 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id_; 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 status_; 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A SETTINGS Control Frame structure. 281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstruct SpdySettingsControlFrameBlock : SpdyFrameBlock { 282201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint32 num_entries_; 283201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Variable data here. 284201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 285201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A GOAWAY Control Frame structure. 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SpdyGoAwayControlFrameBlock : SpdyFrameBlock { 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId last_accepted_stream_id_; 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 291201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A HEADERS Control Frame structure. 292201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstruct SpdyHeadersControlFrameBlock : SpdyFrameBlock { 293201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyStreamId stream_id_; 294201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint16 unused_; 295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A WINDOW_UPDATE Control Frame structure 298201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstruct SpdyWindowUpdateControlFrameBlock : SpdyFrameBlock { 299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyStreamId stream_id_; 300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint32 delta_window_size_; 301201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 302201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A structure for the 8 bit flags and 24 bit ID fields. 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochunion SettingsFlagsAndId { 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint8 flags_[4]; // 8 bits 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 id_; // 24 bits 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SettingsFlagsAndId(uint32 val) : id_(val) {} 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint8 flags() const { return flags_[0]; } 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_flags(uint8 flags) { flags_[0] = flags; } 311201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint32 id() const { return (ntohl(id_) & kSettingsIdMask); } 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_id(uint32 id) { 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(0u, (id & ~kSettingsIdMask)); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id = htonl(id & kSettingsIdMask); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id_ = flags() | id; 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma pack(pop) 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------------------------------------------------- 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Wrapper classes for various SPDY frames. 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// All Spdy Frame types derive from this SpdyFrame class. 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyFrame { 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a SpdyFrame for a given sized buffer. 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit SpdyFrame(size_t size) : frame_(NULL), owns_buffer_(true) { 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(size, sizeof(struct SpdyFrameBlock)); 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* buffer = new char[size]; 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch memset(buffer, 0, size); 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_ = reinterpret_cast<struct SpdyFrameBlock*>(buffer); 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a SpdyFrame using a pre-created buffer. 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If |owns_buffer| is true, this class takes ownership of the buffer 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and will delete it on cleanup. The buffer must have been created using 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // new char[]. 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If |owns_buffer| is false, the caller retains ownership of the buffer and 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // is responsible for making sure the buffer outlives this frame. In other 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // words, this class does NOT create a copy of the buffer. 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyFrame(char* data, bool owns_buffer) 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : frame_(reinterpret_cast<struct SpdyFrameBlock*>(data)), 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch owns_buffer_(owns_buffer) { 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(frame_); 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~SpdyFrame() { 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (owns_buffer_) { 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* buffer = reinterpret_cast<char*>(frame_); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete [] buffer; 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_ = NULL; 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Provides access to the frame bytes, which is a buffer containing 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the frame packed as expected for sending over the wire. 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* data() const { return reinterpret_cast<char*>(frame_); } 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint8 flags() const { return frame_->flags_length_.flags_[0]; } 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_flags(uint8 flags) { frame_->flags_length_.flags_[0] = flags; } 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 length() const { 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(frame_->flags_length_.length_) & kLengthMask; 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_length(uint32 length) { 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(0u, (length & ~kLengthMask)); 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch length = htonl(length & kLengthMask); 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_->flags_length_.length_ = flags() | length; 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_control_frame() const { 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (ntohs(frame_->control_.version_) & kControlFlagMask) == 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kControlFlagMask; 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyFrameBlock structure. 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Every SpdyFrame* class has a static size() method for accessing 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the size of the data structure which will be sent over the wire. 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the same as sizeof(SpdyFrame). 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(struct SpdyFrameBlock); } 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyFrameBlock* frame_; 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool owns_buffer_; 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyFrame); 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A Data Frame. 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyDataFrame : public SpdyFrame { 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyDataFrame() : SpdyFrame(size()) {} 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyDataFrame(char* data, bool owns_buffer) 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyFrame(data, owns_buffer) {} 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(frame_->data_.stream_id_) & kStreamIdMask; 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note that setting the stream id sets the control bit to false. 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // As stream id should always be set, this means the control bit 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // should always be set correctly. 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(0u, (id & ~kStreamIdMask)); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_->data_.stream_id_ = htonl(id & kStreamIdMask); 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyFrameBlock structure. 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdyDataFrame class. 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return SpdyFrame::size(); } 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* payload() const { 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return reinterpret_cast<const char*>(frame_) + size(); 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyDataFrame); 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A Control Frame. 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyControlFrame : public SpdyFrame { 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit SpdyControlFrame(size_t size) : SpdyFrame(size) {} 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyControlFrame(char* data, bool owns_buffer) 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyFrame(data, owns_buffer) {} 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Callers can use this method to check if the frame appears to be a valid 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // frame. Does not guarantee that there are no errors. 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool AppearsToBeAValidControlFrame() const { 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Right now we only check if the frame has an out-of-bounds type. 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 type = ntohs(block()->control_.type_); 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES); 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 version() const { 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kVersionMask = 0x7fff; 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohs(block()->control_.version_) & kVersionMask; 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_version(uint16 version) { 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(0u, version & kControlFlagMask); 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->control_.version_ = htons(kControlFlagMask | version); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyControlType type() const { 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16 type = ntohs(block()->control_.type_); 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES); 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyControlType>(type); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_type(SpdyControlType type) { 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(type >= SYN_STREAM && type < NUM_CONTROL_FRAME_TYPES); 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->control_.type_ = htons(type); 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyFrameBlock structure. 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdyControlFrame class. 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdyFrameBlock); } 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdyFrameBlock* block() const { 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return frame_; 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdyFrameBlock* mutable_block() { 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return frame_; 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyControlFrame); 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SYN_STREAM frame. 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdySynStreamControlFrame : public SpdyControlFrame { 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySynStreamControlFrame() : SpdyControlFrame(size()) {} 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySynStreamControlFrame(char* data, bool owns_buffer) 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId associated_stream_id() const { 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->associated_stream_id_) & kStreamIdMask; 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_associated_stream_id(SpdyStreamId id) { 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->associated_stream_id_ = htonl(id & kStreamIdMask); 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyPriority priority() const { 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (block()->priority_ & kPriorityMask) >> 6; 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The number of bytes in the header block beyond the frame header length. 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int header_block_len() const { 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return length() - (size() - SpdyFrame::size()); 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_block() const { 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return reinterpret_cast<const char*>(block()) + size(); 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdySynStreamControlFrameBlock structure. 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdySynStreamControlFrame class. 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdySynStreamControlFrameBlock); } 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdySynStreamControlFrameBlock* block() const { 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdySynStreamControlFrameBlock*>(frame_); 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdySynStreamControlFrameBlock* mutable_block() { 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdySynStreamControlFrameBlock*>(frame_); 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdySynStreamControlFrame); 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A SYN_REPLY frame. 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdySynReplyControlFrame : public SpdyControlFrame { 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySynReplyControlFrame() : SpdyControlFrame(size()) {} 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySynReplyControlFrame(char* data, bool owns_buffer) 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int header_block_len() const { 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return length() - (size() - SpdyFrame::size()); 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_block() const { 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return reinterpret_cast<const char*>(block()) + size(); 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdySynReplyControlFrameBlock structure. 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdySynReplyControlFrame class. 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdySynReplyControlFrameBlock); } 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdySynReplyControlFrameBlock* block() const { 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdySynReplyControlFrameBlock*>(frame_); 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdySynReplyControlFrameBlock* mutable_block() { 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdySynReplyControlFrameBlock*>(frame_); 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdySynReplyControlFrame); 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A RST_STREAM frame. 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyRstStreamControlFrame : public SpdyControlFrame { 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyRstStreamControlFrame() : SpdyControlFrame(size()) {} 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyRstStreamControlFrame(char* data, bool owns_buffer) 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStatusCodes status() const { 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyStatusCodes>(ntohl(block()->status_)); 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_status(SpdyStatusCodes status) { 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->status_ = htonl(static_cast<uint32>(status)); 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyRstStreamControlFrameBlock structure. 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdyRstStreamControlFrame class. 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdyRstStreamControlFrameBlock); } 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdyRstStreamControlFrameBlock* block() const { 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyRstStreamControlFrameBlock*>(frame_); 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdyRstStreamControlFrameBlock* mutable_block() { 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyRstStreamControlFrameBlock*>(frame_); 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamControlFrame); 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 596201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass SpdySettingsControlFrame : public SpdyControlFrame { 597201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch public: 598201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdySettingsControlFrame() : SpdyControlFrame(size()) {} 599201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdySettingsControlFrame(char* data, bool owns_buffer) 600201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch : SpdyControlFrame(data, owns_buffer) {} 601201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 602201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch uint32 num_entries() const { 603201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return ntohl(block()->num_entries_); 604201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 605201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 606201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void set_num_entries(int val) { 607201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch mutable_block()->num_entries_ = htonl(val); 608201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 609201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 610201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int header_block_len() const { 611201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return length() - (size() - SpdyFrame::size()); 612201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 613201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 614201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const char* header_block() const { 615201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return reinterpret_cast<const char*>(block()) + size(); 616201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 617201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 618201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Returns the size of the SpdySettingsControlFrameBlock structure. 619201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Note: this is not the size of the SpdySettingsControlFrameBlock class. 620201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static size_t size() { return sizeof(SpdySettingsControlFrameBlock); } 621201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 622201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch private: 623201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const struct SpdySettingsControlFrameBlock* block() const { 624201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return static_cast<SpdySettingsControlFrameBlock*>(frame_); 625201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 626201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch struct SpdySettingsControlFrameBlock* mutable_block() { 627201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return static_cast<SpdySettingsControlFrameBlock*>(frame_); 628201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 629201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DISALLOW_COPY_AND_ASSIGN(SpdySettingsControlFrame); 630201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 631201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyGoAwayControlFrame : public SpdyControlFrame { 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyGoAwayControlFrame() : SpdyControlFrame(size()) {} 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyGoAwayControlFrame(char* data, bool owns_buffer) 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId last_accepted_stream_id() const { 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->last_accepted_stream_id_) & kStreamIdMask; 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_last_accepted_stream_id(SpdyStreamId id) { 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->last_accepted_stream_id_ = htonl(id & kStreamIdMask); 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdyGoAwayControlFrameBlock); } 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdyGoAwayControlFrameBlock* block() const { 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyGoAwayControlFrameBlock*>(frame_); 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdyGoAwayControlFrameBlock* mutable_block() { 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyGoAwayControlFrameBlock*>(frame_); 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayControlFrame); 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 658201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A HEADERS frame. 659201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass SpdyHeadersControlFrame : public SpdyControlFrame { 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 661201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyHeadersControlFrame() : SpdyControlFrame(size()) {} 662201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyHeadersControlFrame(char* data, bool owns_buffer) 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 665201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SpdyStreamId stream_id() const { 666201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 669201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void set_stream_id(SpdyStreamId id) { 670201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 673201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // The number of bytes in the header block beyond the frame header length. 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int header_block_len() const { 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return length() - (size() - SpdyFrame::size()); 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* header_block() const { 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return reinterpret_cast<const char*>(block()) + size(); 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 682201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Returns the size of the SpdyHeadersControlFrameBlock structure. 683201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Note: this is not the size of the SpdyHeadersControlFrame class. 684201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static size_t size() { return sizeof(SpdyHeadersControlFrameBlock); } 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 687201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const struct SpdyHeadersControlFrameBlock* block() const { 688201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return static_cast<SpdyHeadersControlFrameBlock*>(frame_); 689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 690201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch struct SpdyHeadersControlFrameBlock* mutable_block() { 691201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return static_cast<SpdyHeadersControlFrameBlock*>(frame_); 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 693201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyHeadersControlFrame); 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A WINDOW_UPDATE frame. 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyWindowUpdateControlFrame : public SpdyControlFrame { 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyWindowUpdateControlFrame() : SpdyControlFrame(size()) {} 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyWindowUpdateControlFrame(char* data, bool owns_buffer) 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : SpdyControlFrame(data, owns_buffer) {} 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStreamId stream_id() const { 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->stream_id_) & kStreamIdMask; 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_stream_id(SpdyStreamId id) { 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->stream_id_ = htonl(id & kStreamIdMask); 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 delta_window_size() const { 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ntohl(block()->delta_window_size_); 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_delta_window_size(uint32 delta_window_size) { 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable_block()->delta_window_size_ = htonl(delta_window_size); 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the size of the SpdyWindowUpdateControlFrameBlock structure. 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: this is not the size of the SpdyWindowUpdateControlFrame class. 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static size_t size() { return sizeof(SpdyWindowUpdateControlFrameBlock); } 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const struct SpdyWindowUpdateControlFrameBlock* block() const { 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_); 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SpdyWindowUpdateControlFrameBlock* mutable_block() { 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<SpdyWindowUpdateControlFrameBlock*>(frame_); 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateControlFrame); 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace spdy 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // NET_SPDY_SPDY_PROTOCOL_H_ 737