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