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