1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
#pragma once
//
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
//
typedef uint8_t byte;
typedef byte ipv4[ 4 ];
typedef byte ipv6[ 16 ];
typedef byte hash[ 32 ];
typedef byte public_key[ 32 ];
typedef byte private_key[ 32 ];
typedef byte signature[ 64 ];
typedef byte recipient[ 64 ];
const uint16_t default_port = 8040;
enum client_input {
// ask server for its information (responds with audit_response)
audit_server = 0x10,
// ask server for a random set of neighbors
// (input uint8_t neighbor_count, responds with neighbors_info)
get_neighbors = 0x11,
// monitor incoming packets
// (input struct firehose_request, responds with firehose_reply)
firehose = 0x12,
// give a packet to the relay
// (input struct data_packet, responds with push_packet_result)
push_packet = 0x13,
// get a packet from the server
// (input hash, responds with get_packet_result)
get_packet = 0x14,
// register a new neighbor relay to this server
// (input struct relay_neighbor, responds with register_neighbor_result)
register_neighbor = 0x15,
// query packets for a specific author
// note: to prevent DoS, you must provide a signature by the requested author to be approved.
// the signature needs to be from a struct shaped `public_key + pub_sign_key + u16 count + u64
// offset`.
// server must verify the signing key is of the author's pubkey and signing key by looking at
// the packet's metadata.
// (input public_key, input pub_sign_key, signature, u16 count, u64 offset)
// (responds with queried_author_packets)
query_packets = 0x16,
// query packets for a specific recipient
// note: to prevent DoS, you must provide a signature by the requested author to be approved.
// the signature needs to be from a struct shaped `public_key + pub_sign_key + u16 count + u64
// offset`.
// server must verify the signing key is of the recipient's pubkey and signing key by looking at
// the packet's metadata.
// (input public_key, input pub_sign_key, signature, u16 count, u64 offset)
// (responds with queried_author_packets)
query_by_recipient = 0x17,
};
enum server_reply {
// pretty self-explanatory.
error = 0x1,
// type `struct relay_info`
audit_response = 0x18,
// type `struct relay_neighbor[ neighbor_count ]`
neighbors_info = 0x19,
// type `uint64_t new_offset, struct data_packet[ count ]`
firehose_reply = 0x1a,
// type `bool result_code`
push_packet_result = 0x1b,
// type `struct data_packet`
get_packet_result = 0x1c,
// type `bool result_code`
register_neighbor_result = 0x1d,
// type `u16 count, u64 new_offset, struct data_packet[ count ]`
queried_author_packets = 0x1e,
// type `u16 count, u64 new_offset, struct data_packet[ count ]`
queried_recipient_packets = 0x1f,
};
typedef uint8_t get_neighbors_request;
struct firehose_request {
uint8_t count;
uint64_t offset;
};
typedef uint64_t firehose_reply_new_offset;
struct relay_neighbor {
bool active; // set to 0 to indicate empty quick connect slot
bool has_ipv4; // whether the neighbor supports ipv4 connection
bool has_ipv6; // whether the neighbor supports ipv6 connection
ipv4 v4_addr; // ipv4 address of the neighbor (if supported)
ipv6 v6_addr; // ipv6 address of the neighbor (if supported)
};
struct relay_info {
// -- version info --
byte major_version;
byte minor_version;
// -- motd --
byte motd[ 128 ];
// -- capabilities --
struct {
uint16_t retention_hours; // how many hours packets will be retained for
bool can_store; // whether or not the relay is accepting new packets
byte leading_zeros; // relay challenge level
bool accepts_plain; // whether or not the relay accepts unencrypted packets
} capabilities;
// -- statistics --
struct {
uint16_t neighbors; // current neighboring relay count for this relay
uint64_t held_packets; // how many packets the relay is holding
struct relay_neighbor quick_connect[ 4 ]; // four best neighbors for quick connection
} statistics;
};
// do not change
#define MAX_RECIPIENTS 32
struct data_packet {
// nonce + hash for PoW
uint32_t nonce;
hash hash;
// content inside to be nonce + hashed
struct {
bool encrypted; // whether the contents is encrypted or plaintext
uint64_t created_time_ms; // unix timestamp for creation time in milliseconds
public_key author; // message author
public_key author_signing_pub; // message signing pubkey
uint8_t recipient_count; // number of recipients. leave as 0 for public.
recipient recipients[ 32 ]; // up to 32 recipients for packet
byte data[ 65536 ]; // packet data
signature signature; // data signature
} contents;
};
const size_t CONTENTS_SIZE = 1 + 8 + 32 + 32 + 1 + (64 * MAX_RECIPIENTS) + 65536 + 64;
const size_t PACKET_SIZE = 4 + 32 + (CONTENTS_SIZE);
|