// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef NET_CURVECP_PROTOCOL_H_ #define NET_CURVECP_PROTOCOL_H_ // Mike's thoughts on the protocol: // 1) the packet layer probably should have a "close" mechanism. although // some clients won't use it, it is nice to have. // // 2) when do we re "initiate"? maybe connections should have an inferred // lifetime, and client should always re-initiate after 1min? // // 3) An initiate packet can cary 640B of data. But how does the app layer // know that only 640B of data is available there? This is a bit awkward? #include "base/basictypes.h" namespace net { typedef unsigned char uchar; // Messages can range in size from 16 to 1088 bytes. const int kMinMessageLength = 16; const int kMaxMessageLength = 1088; // Maximum packet size. const int kMaxPacketLength = kMaxMessageLength + 96; // Packet layer. // All Packets start with an 8 byte identifier. struct Packet { char id[8]; }; // A HelloPacket is sent from the client to the server to establish a secure // cookie to use when communicating with a server. struct HelloPacket : Packet { uchar server_extension[16]; uchar client_extension[16]; uchar client_shortterm_public_key[32]; uchar zero[64]; uchar nonce[8]; uchar box[80]; }; // A CookiePacket is sent from the server to the client in response to a // HelloPacket. struct CookiePacket : Packet { uchar client_extension[16]; uchar server_extension[16]; uchar nonce[16]; uchar box[144]; }; // An InitiatePacket is sent from the client to the server to initiate // the connection once a cookie has been exchanged. struct InitiatePacket : Packet { uchar server_extension[16]; uchar client_extension[16]; uchar client_shortterm_public_key[32]; uchar server_cookie[96]; uchar initiate_nonce[8]; uchar client_longterm_public_key[32]; uchar nonce[16]; uchar box[48]; uchar server_name[256]; // A message is carried here. }; // A ClientMessagePacket contains a Message from the client to the server. struct ClientMessagePacket : Packet { uchar server_extension[16]; uchar client_extension[16]; uchar client_shortterm_public_key[32]; uchar nonce[8]; // A message is carried here of at least 16 bytes. }; // A ServerMessagePacket contains a Message from the server to the client. struct ServerMessagePacket : Packet { uchar client_extension[16]; uchar server_extension[16]; uchar nonce[8]; // A message is carried here of at least 16 bytes. }; // Messaging layer. struct Message { // If message_id is all zero, this Message is a pure ACK message. uchar message_id[4]; // For regular messages going back and forth, last_message_received will be // zero. For an ACK, it will be filled in and can be used to compute RTT. uchar last_message_received[4]; uchar acknowledge_1[8]; // bytes acknowledged in the first range. uchar gap_1[4]; // gap between the first range and the second range. uchar acknowledge_2[2]; // bytes acknowledged in the second range. uchar gap_2[2]; // gap between the second range and the third range. uchar acknowledge_3[2]; // bytes acknowledged in the third range. uchar gap_3[2]; // gap between the third range and the fourth range. uchar acknowledge_4[2]; // bytes acknowledged in the fourth range. uchar gap_4[2]; // gap between the fourth range and the fifth range. uchar acknowledge_5[2]; // bytes acknowledged in the fifth range. uchar gap_5[2]; // gap between the fifth range and the sixth range. uchar acknowledge_6[2]; // bytes acknowledged in the sixth range. union { struct { unsigned short unused:4; unsigned short fail:1; unsigned short success:1; unsigned short length:10; } bits; uchar val[2]; } size; uchar position[8]; uchar padding[16]; bool is_ack() { return *(reinterpret_cast(message_id)) == 0; } }; // Connection state // TODO(mbelshe) move this to the messenger. struct ConnectionState { uchar client_shortterm_public_key[32]; // Fields we'll need going forward: // // uchar secret_key_client_short_server_short[32]; // crypto_uint64 received_nonce; // crypto_uint64 sent_nonce; // uchar client_extension[16]; // uchar server_extension[16]; }; void uint16_pack(uchar* dest, uint16 val); uint16 uint16_unpack(uchar* src); void uint32_pack(uchar* dest, uint32 val); uint32 uint32_unpack(uchar* src); void uint64_pack(uchar* dest, uint64 val); uint64 uint64_unpack(uchar* src); } // namespace net #endif // NET_CURVECP_PROTOCOL_H_