1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // This file contains some protocol structures for use with Flip. 6 7 #ifndef NET_FLIP_FLIP_PROTOCOL_H_ 8 #define NET_FLIP_FLIP_PROTOCOL_H_ 9 10 #ifdef WIN32 11 #include <winsock2.h> 12 #else 13 #include <arpa/inet.h> 14 #endif 15 16 #include "base/basictypes.h" 17 #include "base/logging.h" 18 #include "flip_bitmasks.h" // cross-google3 directory naming. 19 20 // Data Frame Format 21 // +----------------------------------+ 22 // |0| Stream-ID (31bits) | 23 // +----------------------------------+ 24 // | flags (8) | Length (24 bits) | 25 // +----------------------------------+ 26 // | Data | 27 // +----------------------------------+ 28 // 29 // Control Frame Format 30 // +----------------------------------+ 31 // |1| Version(15bits) | Type(16bits) | 32 // +----------------------------------+ 33 // | flags (8) | Length (24 bits) | 34 // +----------------------------------+ 35 // | Data | 36 // +----------------------------------+ 37 // 38 // Control Frame: SYN_STREAM 39 // +----------------------------------+ 40 // |1|000000000000001|0000000000000001| 41 // +----------------------------------+ 42 // | flags (8) | Length (24 bits) | >= 8 43 // +----------------------------------+ 44 // |X| Stream-ID(31bits) | 45 // +----------------------------------+ 46 // |Pri| unused | Length (16bits)| 47 // +----------------------------------+ 48 // 49 // Control Frame: SYN_REPLY 50 // +----------------------------------+ 51 // |1|000000000000001|0000000000000010| 52 // +----------------------------------+ 53 // | flags (8) | Length (24 bits) | >= 8 54 // +----------------------------------+ 55 // |X| Stream-ID(31bits) | 56 // +----------------------------------+ 57 // | unused (16 bits)| Length (16bits)| 58 // +----------------------------------+ 59 // 60 // Control Frame: FIN_STREAM 61 // +----------------------------------+ 62 // |1|000000000000001|0000000000000011| 63 // +----------------------------------+ 64 // | flags (8) | Length (24 bits) | >= 4 65 // +----------------------------------+ 66 // |X| Stream-ID(31bits) | 67 // +----------------------------------+ 68 // | Status (32 bits) | 69 // +----------------------------------+ 70 // 71 // Control Frame: SetMaxStreams 72 // +----------------------------------+ 73 // |1|000000000000001|0000000000000100| 74 // +----------------------------------+ 75 // | flags (8) | Length (24 bits) | >= 4 76 // +----------------------------------+ 77 // |X| Stream-ID(31bits) | 78 // +----------------------------------+ 79 80 // TODO(fenix): add ChangePriority support. 81 82 namespace flip { 83 84 // This implementation of Flip is version 1. 85 const int kFlipProtocolVersion = 1; 86 87 // Note: all protocol data structures are on-the-wire format. That means that 88 // data is stored in network-normalized order. Readers must use the 89 // accessors provided or call ntohX() functions. 90 91 // Types of Flip Control Frames. 92 enum FlipControlType { 93 SYN_STREAM = 1, 94 SYN_REPLY, 95 FIN_STREAM, 96 NOOP 97 }; 98 99 // Flags on data packets 100 enum FlipDataFlags { 101 DATA_FLAG_NONE = 0, 102 DATA_FLAG_FIN = 1, 103 DATA_FLAG_COMPRESSED = 2 // TODO(mbelshe): remove me. 104 }; 105 106 // Flags on control packets 107 enum FlipControlFlags { 108 CONTROL_FLAG_NONE = 0, 109 CONTROL_FLAG_FIN = 1 110 }; 111 112 // A FLIP stream id is a 31 bit entity. 113 typedef uint32 FlipStreamId; 114 115 // FLIP Priorities. (there are only 2 bits) 116 #define FLIP_PRIORITY_LOWEST 3 117 #define FLIP_PRIORITY_HIGHEST 0 118 119 // ------------------------------------------------------------------------- 120 // These structures mirror the protocol structure definitions. 121 122 // For the control data structures, we pack so that sizes match the 123 // protocol over-the-wire sizes. 124 #pragma pack(push) 125 #pragma pack(1) 126 127 // A special structure for the 8 bit flags and 24 bit length fields. 128 union FlagsAndLength { 129 uint8 flags_[4]; // 8 bits 130 uint32 length_; // 24 bits 131 }; 132 133 // The basic FLIP Frame structure. 134 struct FlipFrameBlock { 135 union { 136 struct { 137 uint16 version_; 138 uint16 type_; 139 } control_; 140 struct { 141 FlipStreamId stream_id_; 142 } data_; 143 }; 144 FlagsAndLength flags_length_; 145 }; 146 147 // A Control Frame structure. 148 struct FlipControlFrameBlock : FlipFrameBlock { 149 FlipStreamId stream_id_; 150 }; 151 152 // A SYN_STREAM Control Frame structure. 153 struct FlipSynStreamControlFrameBlock : FlipControlFrameBlock { 154 uint8 priority_; 155 uint8 unused_; 156 }; 157 158 // A SYN_REPLY Control Frame structure. 159 struct FlipSynReplyControlFrameBlock : FlipControlFrameBlock { 160 uint16 unused_; 161 }; 162 163 // A FNI_STREAM Control Frame structure. 164 struct FlipFinStreamControlFrameBlock : FlipControlFrameBlock { 165 uint32 status_; 166 }; 167 168 #pragma pack(pop) 169 170 // ------------------------------------------------------------------------- 171 // Wrapper classes for various FLIP frames. 172 173 // All Flip Frame types derive from this FlipFrame class. 174 class FlipFrame { 175 public: 176 // Create a FlipFrame for a given sized buffer. FlipFrame(size_t size)177 explicit FlipFrame(size_t size) : frame_(NULL), owns_buffer_(true) { 178 DCHECK_GE(size, sizeof(struct FlipFrameBlock)); 179 char* buffer = new char[size]; 180 memset(buffer, 0, size); 181 frame_ = reinterpret_cast<struct FlipFrameBlock*>(buffer); 182 } 183 184 // Create a FlipFrame using a pre-created buffer. 185 // If |owns_buffer| is true, this class takes ownership of the buffer 186 // and will delete it on cleanup. The buffer must have been created using 187 // new char[]. 188 // If |owns_buffer| is false, the caller retains ownership of the buffer and 189 // is responsible for making sure the buffer outlives this frame. In other 190 // words, this class does NOT create a copy of the buffer. FlipFrame(char * data,bool owns_buffer)191 FlipFrame(char* data, bool owns_buffer) 192 : frame_(reinterpret_cast<struct FlipFrameBlock*>(data)), 193 owns_buffer_(owns_buffer) { 194 DCHECK(frame_); 195 } 196 ~FlipFrame()197 virtual ~FlipFrame() { 198 if (owns_buffer_) { 199 char* buffer = reinterpret_cast<char*>(frame_); 200 delete [] buffer; 201 } 202 frame_ = NULL; 203 } 204 205 // Provides access to the frame bytes, which is a buffer containing 206 // the frame packed as expected for sending over the wire. data()207 char* data() const { return reinterpret_cast<char*>(frame_); } 208 flags()209 uint8 flags() const { return frame_->flags_length_.flags_[0]; } set_flags(uint8 flags)210 void set_flags(uint8 flags) { frame_->flags_length_.flags_[0] = flags; } 211 length()212 uint32 length() const { 213 return ntohl(frame_->flags_length_.length_) & kLengthMask; 214 } 215 set_length(uint32 length)216 void set_length(uint32 length) { 217 DCHECK_EQ(0u, (length & ~kLengthMask)); 218 length = htonl(length & kLengthMask); 219 frame_->flags_length_.length_ = flags() | length; 220 } 221 is_control_frame()222 bool is_control_frame() const { 223 return (ntohs(frame_->control_.version_) & kControlFlagMask) == 224 kControlFlagMask; 225 } 226 227 // Returns the size of the FlipFrameBlock structure. 228 // Note: this is not the size of the FlipFrame class. 229 // Every FlipFrame* class has a static size() method for accessing 230 // the size of the data structure which will be sent over the wire. 231 // Note: this is not the same as sizeof(FlipFrame). size()232 static size_t size() { return sizeof(struct FlipFrameBlock); } 233 234 protected: 235 FlipFrameBlock* frame_; 236 237 private: 238 bool owns_buffer_; 239 DISALLOW_COPY_AND_ASSIGN(FlipFrame); 240 }; 241 242 // A Data Frame. 243 class FlipDataFrame : public FlipFrame { 244 public: FlipDataFrame()245 FlipDataFrame() : FlipFrame(size()) {} FlipDataFrame(char * data,bool owns_buffer)246 FlipDataFrame(char* data, bool owns_buffer) 247 : FlipFrame(data, owns_buffer) {} ~FlipDataFrame()248 virtual ~FlipDataFrame() {} 249 stream_id()250 FlipStreamId stream_id() const { 251 return ntohl(frame_->data_.stream_id_) & kStreamIdMask; 252 } 253 254 // Note that setting the stream id sets the control bit to false. 255 // As stream id should always be set, this means the control bit 256 // should always be set correctly. set_stream_id(FlipStreamId id)257 void set_stream_id(FlipStreamId id) { 258 DCHECK_EQ(0u, (id & ~kStreamIdMask)); 259 frame_->data_.stream_id_ = htonl(id & kStreamIdMask); 260 } 261 262 // Returns the size of the FlipFrameBlock structure. 263 // Note: this is not the size of the FlipDataFrame class. size()264 static size_t size() { return FlipFrame::size(); } 265 266 private: 267 DISALLOW_COPY_AND_ASSIGN(FlipDataFrame); 268 }; 269 270 // A Control Frame. 271 class FlipControlFrame : public FlipFrame { 272 public: FlipControlFrame(size_t size)273 explicit FlipControlFrame(size_t size) : FlipFrame(size) {} FlipControlFrame(char * data,bool owns_buffer)274 FlipControlFrame(char* data, bool owns_buffer) 275 : FlipFrame(data, owns_buffer) {} ~FlipControlFrame()276 virtual ~FlipControlFrame() {} 277 version()278 uint16 version() const { 279 const int kVersionMask = 0x7fff; 280 return ntohs(block()->control_.version_) & kVersionMask; 281 } type()282 FlipControlType type() const { 283 uint16 type = ntohs(block()->control_.type_); 284 DCHECK(type >= SYN_STREAM && type <= NOOP); 285 return static_cast<FlipControlType>(type); 286 } stream_id()287 FlipStreamId stream_id() const { 288 return ntohl(block()->stream_id_) & kStreamIdMask; 289 } 290 set_stream_id(FlipStreamId id)291 void set_stream_id(FlipStreamId id) { 292 block()->stream_id_ = htonl(id & kStreamIdMask); 293 } 294 295 // Returns the size of the FlipControlFrameBlock structure. 296 // Note: this is not the size of the FlipControlFrame class. size()297 static size_t size() { return sizeof(FlipControlFrameBlock); } 298 299 private: block()300 struct FlipControlFrameBlock* block() const { 301 return static_cast<FlipControlFrameBlock*>(frame_); 302 } 303 DISALLOW_COPY_AND_ASSIGN(FlipControlFrame); 304 }; 305 306 // A SYN_STREAM frame. 307 class FlipSynStreamControlFrame : public FlipControlFrame { 308 public: FlipSynStreamControlFrame()309 FlipSynStreamControlFrame() : FlipControlFrame(size()) {} FlipSynStreamControlFrame(char * data,bool owns_buffer)310 FlipSynStreamControlFrame(char* data, bool owns_buffer) 311 : FlipControlFrame(data, owns_buffer) {} ~FlipSynStreamControlFrame()312 virtual ~FlipSynStreamControlFrame() {} 313 priority()314 uint8 priority() const { return (block()->priority_ & kPriorityMask) >> 6; } 315 316 // The number of bytes in the header block beyond the frame header length. header_block_len()317 int header_block_len() const { 318 return length() - (size() - FlipFrame::size()); 319 } 320 header_block()321 const char* header_block() const { 322 return reinterpret_cast<const char*>(block()) + size(); 323 } 324 325 // Returns the size of the FlipSynStreamControlFrameBlock structure. 326 // Note: this is not the size of the FlipSynStreamControlFrame class. size()327 static size_t size() { return sizeof(FlipSynStreamControlFrameBlock); } 328 329 private: block()330 struct FlipSynStreamControlFrameBlock* block() const { 331 return static_cast<FlipSynStreamControlFrameBlock*>(frame_); 332 } 333 DISALLOW_COPY_AND_ASSIGN(FlipSynStreamControlFrame); 334 }; 335 336 // A SYN_REPLY frame. 337 class FlipSynReplyControlFrame : public FlipControlFrame { 338 public: FlipSynReplyControlFrame()339 FlipSynReplyControlFrame() : FlipControlFrame(size()) {} FlipSynReplyControlFrame(char * data,bool owns_buffer)340 FlipSynReplyControlFrame(char* data, bool owns_buffer) 341 : FlipControlFrame(data, owns_buffer) {} ~FlipSynReplyControlFrame()342 virtual ~FlipSynReplyControlFrame() {} 343 header_block_len()344 int header_block_len() const { 345 return length() - (size() - FlipFrame::size()); 346 } 347 header_block()348 const char* header_block() const { 349 return reinterpret_cast<const char*>(block()) + size(); 350 } 351 352 // Returns the size of the FlipSynReplyControlFrameBlock structure. 353 // Note: this is not the size of the FlipSynReplyControlFrame class. size()354 static size_t size() { return sizeof(FlipSynReplyControlFrameBlock); } 355 356 private: block()357 struct FlipSynReplyControlFrameBlock* block() const { 358 return static_cast<FlipSynReplyControlFrameBlock*>(frame_); 359 } 360 DISALLOW_COPY_AND_ASSIGN(FlipSynReplyControlFrame); 361 }; 362 363 // A FIN_STREAM frame. 364 class FlipFinStreamControlFrame : public FlipControlFrame { 365 public: FlipFinStreamControlFrame()366 FlipFinStreamControlFrame() : FlipControlFrame(size()) {} FlipFinStreamControlFrame(char * data,bool owns_buffer)367 FlipFinStreamControlFrame(char* data, bool owns_buffer) 368 : FlipControlFrame(data, owns_buffer) {} ~FlipFinStreamControlFrame()369 virtual ~FlipFinStreamControlFrame() {} 370 status()371 uint32 status() const { return ntohl(block()->status_); } set_status(uint32 status)372 void set_status(uint32 status) { block()->status_ = htonl(status); } 373 374 // Returns the size of the FlipFinStreamControlFrameBlock structure. 375 // Note: this is not the size of the FlipFinStreamControlFrame class. size()376 static size_t size() { return sizeof(FlipFinStreamControlFrameBlock); } 377 378 private: block()379 struct FlipFinStreamControlFrameBlock* block() const { 380 return static_cast<FlipFinStreamControlFrameBlock*>(frame_); 381 } 382 DISALLOW_COPY_AND_ASSIGN(FlipFinStreamControlFrame); 383 }; 384 385 } // namespace flip 386 387 #endif // NET_FLIP_FLIP_PROTOCOL_H_ 388