blob: 07eea491df22b214cb1fa7ba45c2c886e67cd915 [file] [log] [blame]
// 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_
#pragma once
// 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<int32*>(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_