summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/DHT.c26
-rw-r--r--core/LAN_discovery.c6
-rw-r--r--core/Lossless_UDP.c570
-rw-r--r--core/Lossless_UDP.h126
-rw-r--r--core/Messenger.c58
-rw-r--r--core/Messenger.h5
-rw-r--r--core/friend_requests.c8
-rw-r--r--core/net_crypto.c414
-rw-r--r--core/net_crypto.h88
-rw-r--r--core/network.c92
-rw-r--r--core/network.h24
-rw-r--r--core/ping.c8
-rw-r--r--core/ping.h4
13 files changed, 760 insertions, 669 deletions
diff --git a/core/DHT.c b/core/DHT.c
index 924e3216..b2aa44f8 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -544,7 +544,7 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id)
544 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 544 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
545 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 545 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
546 546
547 return sendpacket(ip_port, data, sizeof(data)); 547 return sendpacket(temp_net->sock, ip_port, data, sizeof(data));
548} 548}
549 549
550/* send a send nodes response */ 550/* send a send nodes response */
@@ -586,10 +586,10 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u
586 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 586 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
587 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 587 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
588 588
589 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 589 return sendpacket(temp_net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
590} 590}
591 591
592static int handle_getnodes(IP_Port source, uint8_t *packet, uint32_t length) 592static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length)
593{ 593{
594 uint64_t ping_id; 594 uint64_t ping_id;
595 595
@@ -621,7 +621,7 @@ static int handle_getnodes(IP_Port source, uint8_t *packet, uint32_t length)
621 return 0; 621 return 0;
622} 622}
623 623
624static int handle_sendnodes(IP_Port source, uint8_t *packet, uint32_t length) 624static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length)
625{ 625{
626 uint64_t ping_id; 626 uint64_t ping_id;
627 uint32_t cid_size = 1 + CLIENT_ID_SIZE; 627 uint32_t cid_size = 1 + CLIENT_ID_SIZE;
@@ -841,7 +841,7 @@ int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length)
841 841
842 for (i = 0; i < LCLIENT_LIST; ++i) { 842 for (i = 0; i < LCLIENT_LIST; ++i) {
843 if (id_equal(client_id, close_clientlist[i].client_id)) 843 if (id_equal(client_id, close_clientlist[i].client_id))
844 return sendpacket(close_clientlist[i].ip_port, packet, length); 844 return sendpacket(temp_net->sock, close_clientlist[i].ip_port, packet, length);
845 } 845 }
846 846
847 return -1; 847 return -1;
@@ -912,7 +912,7 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length)
912 912
913 /*If ip is not zero and node is good */ 913 /*If ip is not zero and node is good */
914 if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 914 if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
915 if (sendpacket(client->ip_port, packet, length) == length) 915 if (sendpacket(temp_net->sock, client->ip_port, packet, length) == length)
916 ++sent; 916 ++sent;
917 } 917 }
918 } 918 }
@@ -951,7 +951,7 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt
951 if (n < 1) 951 if (n < 1)
952 return 0; 952 return 0;
953 953
954 if (sendpacket(ip_list[rand() % n], packet, length) == length) 954 if (sendpacket(temp_net->sock, ip_list[rand() % n], packet, length) == length)
955 return 1; 955 return 1;
956 956
957 return 0; 957 return 0;
@@ -989,7 +989,7 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type)
989 data[0] = type; 989 data[0] = type;
990 memcpy(data + 1, &ping_id, sizeof(uint64_t)); 990 memcpy(data + 1, &ping_id, sizeof(uint64_t));
991 /* 254 is NAT ping request packet id */ 991 /* 254 is NAT ping request packet id */
992 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); 992 int len = create_request(self_public_key, self_secret_key, packet, public_key, data, sizeof(uint64_t) + 1, 254);
993 993
994 if (len == -1) 994 if (len == -1)
995 return -1; 995 return -1;
@@ -1201,11 +1201,11 @@ static void do_toping()
1201 1201
1202void DHT_init(void) 1202void DHT_init(void)
1203{ 1203{
1204 networking_registerhandler(0, &handle_ping_request); 1204 networking_registerhandler(temp_net, 0, &handle_ping_request, NULL);
1205 networking_registerhandler(1, &handle_ping_response); 1205 networking_registerhandler(temp_net, 1, &handle_ping_response, NULL);
1206 networking_registerhandler(2, &handle_getnodes); 1206 networking_registerhandler(temp_net, 2, &handle_getnodes, NULL);
1207 networking_registerhandler(3, &handle_sendnodes); 1207 networking_registerhandler(temp_net, 3, &handle_sendnodes, NULL);
1208 cryptopacket_registerhandler(254, &handle_NATping); 1208 cryptopacket_registerhandler(temp_net_crypto, 254, &handle_NATping);
1209} 1209}
1210 1210
1211void doDHT(void) 1211void doDHT(void)
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c
index ad1337ef..3045e215 100644
--- a/core/LAN_discovery.c
+++ b/core/LAN_discovery.c
@@ -121,7 +121,7 @@ static int LAN_ip(IP ip)
121 return -1; 121 return -1;
122} 122}
123 123
124static int handle_LANdiscovery(IP_Port source, uint8_t *packet, uint32_t length) 124static int handle_LANdiscovery(void * object, IP_Port source, uint8_t *packet, uint32_t length)
125{ 125{
126 if (LAN_ip(source.ip) == -1) 126 if (LAN_ip(source.ip) == -1)
127 return 1; 127 return 1;
@@ -140,11 +140,11 @@ int send_LANdiscovery(uint16_t port)
140 data[0] = 33; 140 data[0] = 33;
141 memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); 141 memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES);
142 IP_Port ip_port = {broadcast_ip(), port}; 142 IP_Port ip_port = {broadcast_ip(), port};
143 return sendpacket(ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); 143 return sendpacket(temp_net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
144} 144}
145 145
146 146
147void LANdiscovery_init(void) 147void LANdiscovery_init(void)
148{ 148{
149 networking_registerhandler(33, &handle_LANdiscovery); 149 networking_registerhandler(temp_net, 33, &handle_LANdiscovery, NULL);
150} 150}
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index 506a06eb..3e71ffbb 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -28,97 +28,6 @@
28 28
29#include "Lossless_UDP.h" 29#include "Lossless_UDP.h"
30 30
31/* maximum data packets in sent and receive queues. */
32#define MAX_QUEUE_NUM 16
33
34/* maximum number of data packets in the buffer */
35#define BUFFER_PACKET_NUM (16-1)
36
37/* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */
38#define CONNEXION_TIMEOUT 5
39
40/* initial amount of sync/hanshake packets to send per second. */
41#define SYNC_RATE 2
42
43/* initial send rate of data. */
44#define DATA_SYNC_RATE 30
45
46typedef struct {
47 uint8_t data[MAX_DATA_SIZE];
48 uint16_t size;
49} Data;
50
51typedef struct {
52 IP_Port ip_port;
53
54 /*
55 * 0 if connection is dead, 1 if attempting handshake,
56 * 2 if handshake is done (we start sending SYNC packets)
57 * 3 if we are sending SYNC packets and can send data
58 * 4 if the connection has timed out.
59 */
60 uint8_t status;
61
62 /*
63 * 1 or 2 if connection was initiated by someone else, 0 if not.
64 * 2 if incoming_connection() has not returned it yet, 1 if it has.
65 */
66 uint8_t inbound;
67
68 uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */
69 uint16_t data_rate; /* current data packet send rate packets per second. */
70
71 uint64_t last_SYNC; /* time our last SYNC packet was sent. */
72 uint64_t last_sent; /* time our last data or handshake packet was sent. */
73 uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */
74 uint64_t last_recvdata; /* time we last received a DATA packet from the other */
75 uint64_t killat; /* time to kill the connection */
76
77 Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */
78 Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */
79
80 uint32_t handshake_id1;
81 uint32_t handshake_id2;
82
83 /* number of data packets received (also used as handshake_id1) */
84 uint32_t recv_packetnum;
85
86 /* number of packets received by the other peer */
87 uint32_t orecv_packetnum;
88
89 /* number of data packets sent */
90 uint32_t sent_packetnum;
91
92 /* number of packets sent by the other peer. */
93 uint32_t osent_packetnum;
94
95 /* number of latest packet written onto the sendbuffer */
96 uint32_t sendbuff_packetnum;
97
98 /* we know all packets before that number were successfully sent */
99 uint32_t successful_sent;
100
101 /* packet number of last packet read with the read_packet function */
102 uint32_t successful_read;
103
104 /* list of currently requested packet numbers(by the other person) */
105 uint32_t req_packets[BUFFER_PACKET_NUM];
106
107 /* total number of currently requested packets(by the other person) */
108 uint16_t num_req_paquets;
109
110 uint8_t recv_counter;
111 uint8_t send_counter;
112 uint8_t timeout; /* connection timeout in seconds. */
113} Connection;
114
115
116static Connection *connections;
117
118static uint32_t connections_length; /* Length of connections array */
119static uint32_t connections_number; /* Number of connections in connections array */
120
121#define MAX_CONNECTIONS connections_length
122 31
123/* Functions */ 32/* Functions */
124 33
@@ -127,22 +36,20 @@ static uint32_t connections_number; /* Number of connections in connections arra
127 * Return -1 if there are no connections like we are looking for 36 * Return -1 if there are no connections like we are looking for
128 * Return id if it found it 37 * Return id if it found it
129 */ 38 */
130int getconnection_id(IP_Port ip_port) 39int getconnection_id(Lossless_UDP * ludp, IP_Port ip_port)
131{ 40{
132 uint32_t i; 41 uint32_t i;
133 42
134 for (i = 0; i < MAX_CONNECTIONS; ++i) { 43 for (i = 0; i < ludp->connections_length; ++i) {
135 if (connections[i].ip_port.ip.i == ip_port.ip.i && 44 if (ludp->connections[i].ip_port.ip.i == ip_port.ip.i &&
136 connections[i].ip_port.port == ip_port.port && 45 ludp->connections[i].ip_port.port == ip_port.port &&
137 connections[i].status > 0) 46 ludp->connections[i].status > 0)
138 return i; 47 return i;
139 } 48 }
140 49
141 return -1; 50 return -1;
142} 51}
143 52
144/* table of random numbers used below. */
145static uint32_t randtable[6][256];
146 53
147/* 54/*
148 * Generate a handshake_id which depends on the ip_port. 55 * Generate a handshake_id which depends on the ip_port.
@@ -150,15 +57,15 @@ static uint32_t randtable[6][256];
150 * 57 *
151 * TODO: make this better 58 * TODO: make this better
152 */ 59 */
153static uint32_t handshake_id(IP_Port source) 60static uint32_t handshake_id(Lossless_UDP * ludp, IP_Port source)
154{ 61{
155 uint32_t id = 0, i; 62 uint32_t id = 0, i;
156 63
157 for (i = 0; i < 6; ++i) { 64 for (i = 0; i < 6; ++i) {
158 if (randtable[i][((uint8_t *)&source)[i]] == 0) 65 if (ludp->randtable[i][((uint8_t *)&source)[i]] == 0)
159 randtable[i][((uint8_t *)&source)[i]] = random_int(); 66 ludp->randtable[i][((uint8_t *)&source)[i]] = random_int();
160 67
161 id ^= randtable[i][((uint8_t *)&source)[i]]; 68 id ^= ludp->randtable[i][((uint8_t *)&source)[i]];
162 } 69 }
163 70
164 if (id == 0) /* id can't be zero */ 71 if (id == 0) /* id can't be zero */
@@ -172,10 +79,10 @@ static uint32_t handshake_id(IP_Port source)
172 * 79 *
173 * TODO: make this better 80 * TODO: make this better
174 */ 81 */
175static void change_handshake(IP_Port source) 82static void change_handshake(Lossless_UDP * ludp, IP_Port source)
176{ 83{
177 uint8_t rand = random_int() % 4; 84 uint8_t rand = random_int() % 4;
178 randtable[rand][((uint8_t *)&source)[rand]] = random_int(); 85 ludp->randtable[rand][((uint8_t *)&source)[rand]] = random_int();
179} 86}
180 87
181/* 88/*
@@ -184,33 +91,33 @@ static void change_handshake(IP_Port source)
184 * Return -1 if it could not initialize the connectiont 91 * Return -1 if it could not initialize the connectiont
185 * If there already was an existing connection to that ip_port return its number. 92 * If there already was an existing connection to that ip_port return its number.
186 */ 93 */
187int new_connection(IP_Port ip_port) 94int new_connection(Lossless_UDP * ludp, IP_Port ip_port)
188{ 95{
189 int connect = getconnection_id(ip_port); 96 int connect = getconnection_id(ludp, ip_port);
190 97
191 if (connect != -1) 98 if (connect != -1)
192 return connect; 99 return connect;
193 100
194 if (connections_number == connections_length) { 101 if (ludp->connections_number == ludp->connections_length) {
195 Connection *temp; 102 Connection *temp;
196 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 103 temp = realloc(ludp->connections, sizeof(Connection) * (ludp->connections_length + 1));
197 104
198 if (temp == NULL) 105 if (temp == NULL)
199 return -1; 106 return -1;
200 107
201 memset(&temp[connections_length], 0, sizeof(Connection)); 108 memset(&temp[ludp->connections_length], 0, sizeof(Connection));
202 ++connections_length; 109 ++ludp->connections_length;
203 connections = temp; 110 ludp->connections = temp;
204 } 111 }
205 112
206 uint32_t i; 113 uint32_t i;
207 114
208 for (i = 0; i < MAX_CONNECTIONS; ++i) { 115 for (i = 0; i < ludp->connections_length; ++i) {
209 if (connections[i].status == 0) { 116 if (ludp->connections[i].status == 0) {
210 memset(&connections[i], 0, sizeof(Connection)); 117 memset(&ludp->connections[i], 0, sizeof(Connection));
211 uint32_t handshake_id1 = handshake_id(ip_port); 118 uint32_t handshake_id1 = handshake_id(ludp, ip_port);
212 119
213 connections[i] = (Connection) { 120 ludp->connections[i] = (Connection) {
214 .ip_port = ip_port, 121 .ip_port = ip_port,
215 .status = 1, 122 .status = 1,
216 .inbound = 0, 123 .inbound = 0,
@@ -227,7 +134,7 @@ int new_connection(IP_Port ip_port)
227 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 134 /* add randomness to timeout to prevent connections getting stuck in a loop. */
228 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT 135 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
229 }; 136 };
230 ++connections_number; 137 ++ludp->connections_number;
231 138
232 return i; 139 return i;
233 } 140 }
@@ -241,31 +148,31 @@ int new_connection(IP_Port ip_port)
241 * Returns an integer corresponding to the connection id. 148 * Returns an integer corresponding to the connection id.
242 * Return -1 if it could not initialize the connection. 149 * Return -1 if it could not initialize the connection.
243 */ 150 */
244static int new_inconnection(IP_Port ip_port) 151static int new_inconnection(Lossless_UDP * ludp, IP_Port ip_port)
245{ 152{
246 if (getconnection_id(ip_port) != -1) 153 if (getconnection_id(ludp, ip_port) != -1)
247 return -1; 154 return -1;
248 155
249 if (connections_number == connections_length) { 156 if (ludp->connections_number == ludp->connections_length) {
250 Connection *temp; 157 Connection *temp;
251 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 158 temp = realloc(ludp->connections, sizeof(Connection) * (ludp->connections_length + 1));
252 159
253 if (temp == NULL) 160 if (temp == NULL)
254 return -1; 161 return -1;
255 162
256 memset(&temp[connections_length], 0, sizeof(Connection)); 163 memset(&temp[ludp->connections_length], 0, sizeof(Connection));
257 ++connections_length; 164 ++ludp->connections_length;
258 connections = temp; 165 ludp->connections = temp;
259 } 166 }
260 167
261 uint32_t i; 168 uint32_t i;
262 169
263 for (i = 0; i < MAX_CONNECTIONS; ++i) { 170 for (i = 0; i < ludp->connections_length; ++i) {
264 if (connections[i].status == 0) { 171 if (ludp->connections[i].status == 0) {
265 memset(&connections[i], 0, sizeof(Connection)); 172 memset(&ludp->connections[i], 0, sizeof(Connection));
266 uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; 173 uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT;
267 174
268 connections[i] = (Connection) { 175 ludp->connections[i] = (Connection) {
269 .ip_port = ip_port, 176 .ip_port = ip_port,
270 .status = 2, 177 .status = 2,
271 .inbound = 2, 178 .inbound = 2,
@@ -281,7 +188,7 @@ static int new_inconnection(IP_Port ip_port)
281 /* if this connection isn't handled within the timeout kill it. */ 188 /* if this connection isn't handled within the timeout kill it. */
282 .killat = current_time() + 1000000UL * timeout 189 .killat = current_time() + 1000000UL * timeout
283 }; 190 };
284 ++connections_number; 191 ++ludp->connections_number;
285 return i; 192 return i;
286 } 193 }
287 } 194 }
@@ -293,13 +200,13 @@ static int new_inconnection(IP_Port ip_port)
293 * Returns an integer corresponding to the next connection in our incoming connection list. 200 * Returns an integer corresponding to the next connection in our incoming connection list.
294 * Return -1 if there are no new incoming connections in the list. 201 * Return -1 if there are no new incoming connections in the list.
295 */ 202 */
296int incoming_connection(void) 203int incoming_connection(Lossless_UDP * ludp)
297{ 204{
298 uint32_t i; 205 uint32_t i;
299 206
300 for (i = 0; i < MAX_CONNECTIONS; ++i) { 207 for (i = 0; i < ludp->connections_length; ++i) {
301 if (connections[i].inbound == 2) { 208 if (ludp->connections[i].inbound == 2) {
302 connections[i].inbound = 1; 209 ludp->connections[i].inbound = 1;
303 return i; 210 return i;
304 } 211 }
305 } 212 }
@@ -308,46 +215,46 @@ int incoming_connection(void)
308} 215}
309 216
310/* Try to free some memory from the connections array. */ 217/* Try to free some memory from the connections array. */
311static void free_connections(void) 218static void free_connections(Lossless_UDP * ludp)
312{ 219{
313 uint32_t i; 220 uint32_t i;
314 221
315 for (i = connections_length; i != 0; --i) 222 for (i = ludp->connections_length; i != 0; --i)
316 if (connections[i - 1].status != 0) 223 if (ludp->connections[i - 1].status != 0)
317 break; 224 break;
318 225
319 if (connections_length == i) 226 if (ludp->connections_length == i)
320 return; 227 return;
321 228
322 if (i == 0) { 229 if (i == 0) {
323 free(connections); 230 free(ludp->connections);
324 connections = NULL; 231 ludp->connections = NULL;
325 connections_length = i; 232 ludp->connections_length = i;
326 return; 233 return;
327 } 234 }
328 235
329 Connection *temp; 236 Connection *temp;
330 temp = realloc(connections, sizeof(Connection) * i); 237 temp = realloc(ludp->connections, sizeof(Connection) * i);
331 238
332 if (temp == NULL && i != 0) 239 if (temp == NULL && i != 0)
333 return; 240 return;
334 241
335 connections = temp; 242 ludp->connections = temp;
336 connections_length = i; 243 ludp->connections_length = i;
337} 244}
338 245
339/* 246/*
340 * Return -1 if it could not kill the connection. 247 * Return -1 if it could not kill the connection.
341 * Return 0 if killed successfully 248 * Return 0 if killed successfully
342 */ 249 */
343int kill_connection(int connection_id) 250int kill_connection(Lossless_UDP * ludp, int connection_id)
344{ 251{
345 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { 252 if (connection_id >= 0 && connection_id < ludp->connections_length) {
346 if (connections[connection_id].status > 0) { 253 if (ludp->connections[connection_id].status > 0) {
347 connections[connection_id].status = 0; 254 ludp->connections[connection_id].status = 0;
348 change_handshake(connections[connection_id].ip_port); 255 change_handshake(ludp, ludp->connections[connection_id].ip_port);
349 --connections_number; 256 --ludp->connections_number;
350 free_connections(); 257 free_connections(ludp);
351 return 0; 258 return 0;
352 } 259 }
353 } 260 }
@@ -360,11 +267,11 @@ int kill_connection(int connection_id)
360 * Return -1 if it can not kill the connection. 267 * Return -1 if it can not kill the connection.
361 * Return 0 if it will kill it. 268 * Return 0 if it will kill it.
362 */ 269 */
363int kill_connection_in(int connection_id, uint32_t seconds) 270int kill_connection_in(Lossless_UDP * ludp, int connection_id, uint32_t seconds)
364{ 271{
365 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { 272 if (connection_id >= 0 && connection_id < ludp->connections_length) {
366 if (connections[connection_id].status > 0) { 273 if (ludp->connections[connection_id].status > 0) {
367 connections[connection_id].killat = current_time() + 1000000UL * seconds; 274 ludp->connections[connection_id].killat = current_time() + 1000000UL * seconds;
368 return 0; 275 return 0;
369 } 276 }
370 } 277 }
@@ -380,65 +287,65 @@ int kill_connection_in(int connection_id, uint32_t seconds)
380 * Return 3 if fully connected. 287 * Return 3 if fully connected.
381 * Return 4 if timed out and waiting to be killed. 288 * Return 4 if timed out and waiting to be killed.
382 */ 289 */
383int is_connected(int connection_id) 290int is_connected(Lossless_UDP * ludp, int connection_id)
384{ 291{
385 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) 292 if (connection_id >= 0 && connection_id < ludp->connections_length)
386 return connections[connection_id].status; 293 return ludp->connections[connection_id].status;
387 294
388 return 0; 295 return 0;
389} 296}
390 297
391/* returns the ip_port of the corresponding connection. */ 298/* returns the ip_port of the corresponding connection. */
392IP_Port connection_ip(int connection_id) 299IP_Port connection_ip(Lossless_UDP * ludp, int connection_id)
393{ 300{
394 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) 301 if (connection_id >= 0 && connection_id < ludp->connections_length)
395 return connections[connection_id].ip_port; 302 return ludp->connections[connection_id].ip_port;
396 303
397 IP_Port zero = {{{0}}, 0}; 304 IP_Port zero = {{{0}}, 0};
398 return zero; 305 return zero;
399} 306}
400 307
401/* returns the number of packets in the queue waiting to be successfully sent. */ 308/* returns the number of packets in the queue waiting to be successfully sent. */
402uint32_t sendqueue(int connection_id) 309uint32_t sendqueue(Lossless_UDP * ludp, int connection_id)
403{ 310{
404 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 311 if (connection_id < 0 || connection_id >= ludp->connections_length)
405 return 0; 312 return 0;
406 313
407 return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; 314 return ludp->connections[connection_id].sendbuff_packetnum - ludp->connections[connection_id].successful_sent;
408} 315}
409 316
410/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ 317/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */
411uint32_t recvqueue(int connection_id) 318uint32_t recvqueue(Lossless_UDP * ludp, int connection_id)
412{ 319{
413 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 320 if (connection_id < 0 || connection_id >= ludp->connections_length)
414 return 0; 321 return 0;
415 322
416 return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; 323 return ludp->connections[connection_id].recv_packetnum - ludp->connections[connection_id].successful_read;
417} 324}
418 325
419/* returns the id of the next packet in the queue 326/* returns the id of the next packet in the queue
420 return -1 if no packet in queue */ 327 return -1 if no packet in queue */
421char id_packet(int connection_id) 328char id_packet(Lossless_UDP * ludp, int connection_id)
422{ 329{
423 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 330 if (connection_id < 0 || connection_id >= ludp->connections_length)
424 return -1; 331 return -1;
425 332
426 if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) 333 if (recvqueue(ludp, connection_id) != 0 && ludp->connections[connection_id].status != 0)
427 return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; 334 return ludp->connections[connection_id].recvbuffer[ludp->connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0];
428 335
429 return -1; 336 return -1;
430} 337}
431 338
432/* return 0 if there is no received data in the buffer. 339/* return 0 if there is no received data in the buffer.
433 return length of received packet if successful */ 340 return length of received packet if successful */
434int read_packet(int connection_id, uint8_t *data) 341int read_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data)
435{ 342{
436 if (recvqueue(connection_id) != 0) { 343 if (recvqueue(ludp, connection_id) != 0) {
437 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; 344 uint16_t index = ludp->connections[connection_id].successful_read % MAX_QUEUE_NUM;
438 uint16_t size = connections[connection_id].recvbuffer[index].size; 345 uint16_t size = ludp->connections[connection_id].recvbuffer[index].size;
439 memcpy(data, connections[connection_id].recvbuffer[index].data, size); 346 memcpy(data, ludp->connections[connection_id].recvbuffer[index].data, size);
440 ++connections[connection_id].successful_read; 347 ++ludp->connections[connection_id].successful_read;
441 connections[connection_id].recvbuffer[index].size = 0; 348 ludp->connections[connection_id].recvbuffer[index].size = 0;
442 return size; 349 return size;
443 } 350 }
444 351
@@ -449,16 +356,16 @@ int read_packet(int connection_id, uint8_t *data)
449 * Return 0 if data could not be put in packet queue 356 * Return 0 if data could not be put in packet queue
450 * Return 1 if data was put into the queue 357 * Return 1 if data was put into the queue
451 */ 358 */
452int write_packet(int connection_id, uint8_t *data, uint32_t length) 359int write_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data, uint32_t length)
453{ 360{
454 if (length > MAX_DATA_SIZE || length == 0) 361 if (length > MAX_DATA_SIZE || length == 0)
455 return 0; 362 return 0;
456 363
457 if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { 364 if (sendqueue(ludp, connection_id) < BUFFER_PACKET_NUM) {
458 uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; 365 uint32_t index = ludp->connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM;
459 memcpy(connections[connection_id].sendbuffer[index].data, data, length); 366 memcpy(ludp->connections[connection_id].sendbuffer[index].data, data, length);
460 connections[connection_id].sendbuffer[index].size = length; 367 ludp->connections[connection_id].sendbuffer[index].size = length;
461 connections[connection_id].sendbuff_packetnum++; 368 ludp->connections[connection_id].sendbuff_packetnum++;
462 return 1; 369 return 1;
463 } 370 }
464 371
@@ -466,18 +373,18 @@ int write_packet(int connection_id, uint8_t *data, uint32_t length)
466} 373}
467 374
468/* put the packet numbers the we are missing in requested and return the number */ 375/* put the packet numbers the we are missing in requested and return the number */
469uint32_t missing_packets(int connection_id, uint32_t *requested) 376uint32_t missing_packets(Lossless_UDP * ludp, int connection_id, uint32_t *requested)
470{ 377{
471 uint32_t number = 0; 378 uint32_t number = 0;
472 uint32_t i; 379 uint32_t i;
473 uint32_t temp; 380 uint32_t temp;
474 381
475 /* don't request packets if the buffer is full. */ 382 /* don't request packets if the buffer is full. */
476 if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) 383 if (recvqueue(ludp, connection_id) >= (BUFFER_PACKET_NUM - 1))
477 return 0; 384 return 0;
478 385
479 for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { 386 for (i = ludp->connections[connection_id].recv_packetnum; i != ludp->connections[connection_id].osent_packetnum; i++) {
480 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { 387 if (ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) {
481 temp = htonl(i); 388 temp = htonl(i);
482 memcpy(requested + number, &temp, 4); 389 memcpy(requested + number, &temp, 4);
483 ++number; 390 ++number;
@@ -485,7 +392,7 @@ uint32_t missing_packets(int connection_id, uint32_t *requested)
485 } 392 }
486 393
487 if (number == 0) 394 if (number == 0)
488 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; 395 ludp->connections[connection_id].recv_packetnum = ludp->connections[connection_id].osent_packetnum;
489 396
490 return number; 397 return number;
491} 398}
@@ -496,7 +403,7 @@ uint32_t missing_packets(int connection_id, uint32_t *requested)
496 * see http://wiki.tox.im/index.php/Lossless_UDP for more information. 403 * see http://wiki.tox.im/index.php/Lossless_UDP for more information.
497 */ 404 */
498 405
499static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) 406static int send_handshake(Lossless_UDP * ludp, IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2)
500{ 407{
501 uint8_t packet[1 + 4 + 4]; 408 uint8_t packet[1 + 4 + 4];
502 uint32_t temp; 409 uint32_t temp;
@@ -507,21 +414,21 @@ static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t hand
507 temp = htonl(handshake_id2); 414 temp = htonl(handshake_id2);
508 memcpy(packet + 5, &temp, 4); 415 memcpy(packet + 5, &temp, 4);
509 416
510 return sendpacket(ip_port, packet, sizeof(packet)); 417 return sendpacket(ludp->net->sock, ip_port, packet, sizeof(packet));
511} 418}
512 419
513static int send_SYNC(uint32_t connection_id) 420static int send_SYNC(Lossless_UDP * ludp, uint32_t connection_id)
514{ 421{
515 uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)]; 422 uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)];
516 uint16_t index = 0; 423 uint16_t index = 0;
517 424
518 IP_Port ip_port = connections[connection_id].ip_port; 425 IP_Port ip_port = ludp->connections[connection_id].ip_port;
519 uint8_t counter = connections[connection_id].send_counter; 426 uint8_t counter = ludp->connections[connection_id].send_counter;
520 uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); 427 uint32_t recv_packetnum = htonl(ludp->connections[connection_id].recv_packetnum);
521 uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); 428 uint32_t sent_packetnum = htonl(ludp->connections[connection_id].sent_packetnum);
522 429
523 uint32_t requested[BUFFER_PACKET_NUM]; 430 uint32_t requested[BUFFER_PACKET_NUM];
524 uint32_t number = missing_packets(connection_id, requested); 431 uint32_t number = missing_packets(ludp, connection_id, requested);
525 432
526 packet[0] = 17; 433 packet[0] = 17;
527 index += 1; 434 index += 1;
@@ -533,11 +440,11 @@ static int send_SYNC(uint32_t connection_id)
533 index += 4; 440 index += 4;
534 memcpy(packet + index, requested, 4 * number); 441 memcpy(packet + index, requested, 4 * number);
535 442
536 return sendpacket(ip_port, packet, (number * 4 + 4 + 4 + 2)); 443 return sendpacket(ludp->net->sock, ip_port, packet, (number * 4 + 4 + 4 + 2));
537 444
538} 445}
539 446
540static int send_data_packet(uint32_t connection_id, uint32_t packet_num) 447static int send_data_packet(Lossless_UDP * ludp, uint32_t connection_id, uint32_t packet_num)
541{ 448{
542 uint32_t index = packet_num % MAX_QUEUE_NUM; 449 uint32_t index = packet_num % MAX_QUEUE_NUM;
543 uint32_t temp; 450 uint32_t temp;
@@ -545,29 +452,29 @@ static int send_data_packet(uint32_t connection_id, uint32_t packet_num)
545 packet[0] = 18; 452 packet[0] = 18;
546 temp = htonl(packet_num); 453 temp = htonl(packet_num);
547 memcpy(packet + 1, &temp, 4); 454 memcpy(packet + 1, &temp, 4);
548 memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, 455 memcpy(packet + 5, ludp->connections[connection_id].sendbuffer[index].data,
549 connections[connection_id].sendbuffer[index].size); 456 ludp->connections[connection_id].sendbuffer[index].size);
550 return sendpacket(connections[connection_id].ip_port, packet, 457 return sendpacket(ludp->net->sock, ludp->connections[connection_id].ip_port, packet,
551 1 + 4 + connections[connection_id].sendbuffer[index].size); 458 1 + 4 + ludp->connections[connection_id].sendbuffer[index].size);
552} 459}
553 460
554/* sends 1 data packet */ 461/* sends 1 data packet */
555static int send_DATA(uint32_t connection_id) 462static int send_DATA(Lossless_UDP * ludp, uint32_t connection_id)
556{ 463{
557 int ret; 464 int ret;
558 uint32_t buffer[BUFFER_PACKET_NUM]; 465 uint32_t buffer[BUFFER_PACKET_NUM];
559 466
560 if (connections[connection_id].num_req_paquets > 0) { 467 if (ludp->connections[connection_id].num_req_paquets > 0) {
561 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); 468 ret = send_data_packet(ludp, connection_id, ludp->connections[connection_id].req_packets[0]);
562 connections[connection_id].num_req_paquets--; 469 ludp->connections[connection_id].num_req_paquets--;
563 memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); 470 memcpy(buffer, ludp->connections[connection_id].req_packets + 1, ludp->connections[connection_id].num_req_paquets * 4);
564 memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); 471 memcpy(ludp->connections[connection_id].req_packets, buffer, ludp->connections[connection_id].num_req_paquets * 4);
565 return ret; 472 return ret;
566 } 473 }
567 474
568 if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) { 475 if (ludp->connections[connection_id].sendbuff_packetnum != ludp->connections[connection_id].sent_packetnum) {
569 ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); 476 ret = send_data_packet(ludp, connection_id, ludp->connections[connection_id].sent_packetnum);
570 connections[connection_id].sent_packetnum++; 477 ludp->connections[connection_id].sent_packetnum++;
571 return ret; 478 return ret;
572 } 479 }
573 480
@@ -584,37 +491,38 @@ static int send_DATA(uint32_t connection_id)
584 491
585 492
586/* Return 0 if handled correctly, 1 if packet is bad. */ 493/* Return 0 if handled correctly, 1 if packet is bad. */
587static int handle_handshake(IP_Port source, uint8_t *packet, uint32_t length) 494static int handle_handshake(void * object, IP_Port source, uint8_t *packet, uint32_t length)
588{ 495{
496 Lossless_UDP * ludp = object;
589 if (length != (1 + 4 + 4)) 497 if (length != (1 + 4 + 4))
590 return 1; 498 return 1;
591 499
592 uint32_t temp; 500 uint32_t temp;
593 uint32_t handshake_id1, handshake_id2; 501 uint32_t handshake_id1, handshake_id2;
594 502
595 int connection = getconnection_id(source); 503 int connection = getconnection_id(ludp, source);
596 memcpy(&temp, packet + 1, 4); 504 memcpy(&temp, packet + 1, 4);
597 handshake_id1 = ntohl(temp); 505 handshake_id1 = ntohl(temp);
598 memcpy(&temp, packet + 5, 4); 506 memcpy(&temp, packet + 5, 4);
599 handshake_id2 = ntohl(temp); 507 handshake_id2 = ntohl(temp);
600 508
601 if (handshake_id2 == 0 && is_connected(connection) < 3) { 509 if (handshake_id2 == 0 && is_connected(ludp, connection) < 3) {
602 send_handshake(source, handshake_id(source), handshake_id1); 510 send_handshake(ludp, source, handshake_id(ludp, source), handshake_id1);
603 return 0; 511 return 0;
604 } 512 }
605 513
606 if (is_connected(connection) != 1) 514 if (is_connected(ludp, connection) != 1)
607 return 1; 515 return 1;
608 516
609 /* if handshake_id2 is what we sent previously as handshake_id1 */ 517 /* if handshake_id2 is what we sent previously as handshake_id1 */
610 if (handshake_id2 == connections[connection].handshake_id1) { 518 if (handshake_id2 == ludp->connections[connection].handshake_id1) {
611 connections[connection].status = 2; 519 ludp->connections[connection].status = 2;
612 /* NOTE: is this necessary? 520 /* NOTE: is this necessary?
613 connections[connection].handshake_id2 = handshake_id1; */ 521 ludp->connections[connection].handshake_id2 = handshake_id1; */
614 connections[connection].orecv_packetnum = handshake_id2; 522 ludp->connections[connection].orecv_packetnum = handshake_id2;
615 connections[connection].osent_packetnum = handshake_id1; 523 ludp->connections[connection].osent_packetnum = handshake_id1;
616 connections[connection].recv_packetnum = handshake_id1; 524 ludp->connections[connection].recv_packetnum = handshake_id1;
617 connections[connection].successful_read = handshake_id1; 525 ludp->connections[connection].successful_read = handshake_id1;
618 } 526 }
619 527
620 return 0; 528 return 0;
@@ -634,19 +542,19 @@ static int SYNC_valid(uint32_t length)
634} 542}
635 543
636/* case 1 in handle_SYNC: */ 544/* case 1 in handle_SYNC: */
637static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) 545static int handle_SYNC1(Lossless_UDP * ludp, IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum)
638{ 546{
639 if (handshake_id(source) == recv_packetnum) { 547 if (handshake_id(ludp, source) == recv_packetnum) {
640 int x = new_inconnection(source); 548 int x = new_inconnection(ludp, source);
641 549
642 if (x != -1) { 550 if (x != -1) {
643 connections[x].orecv_packetnum = recv_packetnum; 551 ludp->connections[x].orecv_packetnum = recv_packetnum;
644 connections[x].sent_packetnum = recv_packetnum; 552 ludp->connections[x].sent_packetnum = recv_packetnum;
645 connections[x].sendbuff_packetnum = recv_packetnum; 553 ludp->connections[x].sendbuff_packetnum = recv_packetnum;
646 connections[x].successful_sent = recv_packetnum; 554 ludp->connections[x].successful_sent = recv_packetnum;
647 connections[x].osent_packetnum = sent_packetnum; 555 ludp->connections[x].osent_packetnum = sent_packetnum;
648 connections[x].recv_packetnum = sent_packetnum; 556 ludp->connections[x].recv_packetnum = sent_packetnum;
649 connections[x].successful_read = sent_packetnum; 557 ludp->connections[x].successful_read = sent_packetnum;
650 558
651 return x; 559 return x;
652 } 560 }
@@ -656,63 +564,63 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p
656} 564}
657 565
658/* case 2 in handle_SYNC: */ 566/* case 2 in handle_SYNC: */
659static int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) 567static int handle_SYNC2(Lossless_UDP * ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum)
660{ 568{
661 if (recv_packetnum == connections[connection_id].orecv_packetnum) { 569 if (recv_packetnum == ludp->connections[connection_id].orecv_packetnum) {
662 /* && sent_packetnum == connections[connection_id].osent_packetnum) */ 570 /* && sent_packetnum == ludp->connections[connection_id].osent_packetnum) */
663 connections[connection_id].status = 3; 571 ludp->connections[connection_id].status = 3;
664 connections[connection_id].recv_counter = counter; 572 ludp->connections[connection_id].recv_counter = counter;
665 ++connections[connection_id].send_counter; 573 ++ludp->connections[connection_id].send_counter;
666 send_SYNC(connection_id); 574 send_SYNC(ludp, connection_id);
667 return 0; 575 return 0;
668 } 576 }
669 577
670 return 1; 578 return 1;
671} 579}
672/* case 3 in handle_SYNC: */ 580/* case 3 in handle_SYNC: */
673static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, 581static int handle_SYNC3(Lossless_UDP * ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum,
674 uint32_t *req_packets, 582 uint32_t *req_packets,
675 uint16_t number) 583 uint16_t number)
676{ 584{
677 uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); 585 uint8_t comp_counter = (counter - ludp->connections[connection_id].recv_counter );
678 uint32_t i, temp; 586 uint32_t i, temp;
679 /* uint32_t comp_1 = (recv_packetnum - connections[connection_id].successful_sent); 587 /* uint32_t comp_1 = (recv_packetnum - ludp->connections[connection_id].successful_sent);
680 uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ 588 uint32_t comp_2 = (sent_packetnum - ludp->connections[connection_id].successful_read); */
681 uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); 589 uint32_t comp_1 = (recv_packetnum - ludp->connections[connection_id].orecv_packetnum);
682 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); 590 uint32_t comp_2 = (sent_packetnum - ludp->connections[connection_id].osent_packetnum);
683 591
684 /* packet valid */ 592 /* packet valid */
685 if (comp_1 <= BUFFER_PACKET_NUM && 593 if (comp_1 <= BUFFER_PACKET_NUM &&
686 comp_2 <= BUFFER_PACKET_NUM && 594 comp_2 <= BUFFER_PACKET_NUM &&
687 comp_counter < 10 && comp_counter != 0) { 595 comp_counter < 10 && comp_counter != 0) {
688 596
689 connections[connection_id].orecv_packetnum = recv_packetnum; 597 ludp->connections[connection_id].orecv_packetnum = recv_packetnum;
690 connections[connection_id].osent_packetnum = sent_packetnum; 598 ludp->connections[connection_id].osent_packetnum = sent_packetnum;
691 connections[connection_id].successful_sent = recv_packetnum; 599 ludp->connections[connection_id].successful_sent = recv_packetnum;
692 connections[connection_id].last_recvSYNC = current_time(); 600 ludp->connections[connection_id].last_recvSYNC = current_time();
693 connections[connection_id].recv_counter = counter; 601 ludp->connections[connection_id].recv_counter = counter;
694 602
695 ++connections[connection_id].send_counter; 603 ++ludp->connections[connection_id].send_counter;
696 604
697 for (i = 0; i < number; ++i) { 605 for (i = 0; i < number; ++i) {
698 temp = ntohl(req_packets[i]); 606 temp = ntohl(req_packets[i]);
699 memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); 607 memcpy(ludp->connections[connection_id].req_packets + i, &temp, 4 * number);
700 } 608 }
701 609
702 connections[connection_id].num_req_paquets = number; 610 ludp->connections[connection_id].num_req_paquets = number;
703 return 0; 611 return 0;
704 } 612 }
705 613
706 return 1; 614 return 1;
707} 615}
708 616
709static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) 617static int handle_SYNC(void * object, IP_Port source, uint8_t *packet, uint32_t length)
710{ 618{
711 619 Lossless_UDP * ludp = object;
712 if (!SYNC_valid(length)) 620 if (!SYNC_valid(length))
713 return 1; 621 return 1;
714 622
715 int connection = getconnection_id(source); 623 int connection = getconnection_id(ludp, source);
716 uint8_t counter; 624 uint8_t counter;
717 uint32_t temp; 625 uint32_t temp;
718 uint32_t recv_packetnum, sent_packetnum; 626 uint32_t recv_packetnum, sent_packetnum;
@@ -729,14 +637,14 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
729 memcpy(req_packets, packet + 10, 4 * number); 637 memcpy(req_packets, packet + 10, 4 * number);
730 638
731 if (connection == -1) 639 if (connection == -1)
732 return handle_SYNC1(source, recv_packetnum, sent_packetnum); 640 return handle_SYNC1(ludp, source, recv_packetnum, sent_packetnum);
733 641
734 if (connections[connection].status == 2) 642 if (ludp->connections[connection].status == 2)
735 return handle_SYNC2(connection, counter, 643 return handle_SYNC2(ludp, connection, counter,
736 recv_packetnum, sent_packetnum); 644 recv_packetnum, sent_packetnum);
737 645
738 if (connections[connection].status == 3) 646 if (ludp->connections[connection].status == 3)
739 return handle_SYNC3(connection, counter, recv_packetnum, 647 return handle_SYNC3(ludp, connection, counter, recv_packetnum,
740 sent_packetnum, req_packets, number); 648 sent_packetnum, req_packets, number);
741 649
742 return 0; 650 return 0;
@@ -746,33 +654,33 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
746 * Add a packet to the received buffer and set the recv_packetnum of the 654 * Add a packet to the received buffer and set the recv_packetnum of the
747 * connection to its proper value. Return 1 if data was too big, 0 if not. 655 * connection to its proper value. Return 1 if data was too big, 0 if not.
748 */ 656 */
749static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) 657static int add_recv(Lossless_UDP * ludp, int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
750{ 658{
751 if (size > MAX_DATA_SIZE) 659 if (size > MAX_DATA_SIZE)
752 return 1; 660 return 1;
753 661
754 uint32_t i; 662 uint32_t i;
755 uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; 663 uint32_t maxnum = ludp->connections[connection_id].successful_read + BUFFER_PACKET_NUM;
756 uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; 664 uint32_t sent_packet = data_num - ludp->connections[connection_id].osent_packetnum;
757 665
758 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { 666 for (i = ludp->connections[connection_id].recv_packetnum; i != maxnum; ++i) {
759 if (i == data_num) { 667 if (i == data_num) {
760 memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); 668 memcpy(ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size);
761 669
762 connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; 670 ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size;
763 connections[connection_id].last_recvdata = current_time(); 671 ludp->connections[connection_id].last_recvdata = current_time();
764 672
765 if (sent_packet < BUFFER_PACKET_NUM) { 673 if (sent_packet < BUFFER_PACKET_NUM) {
766 connections[connection_id].osent_packetnum = data_num; 674 ludp->connections[connection_id].osent_packetnum = data_num;
767 } 675 }
768 676
769 break; 677 break;
770 } 678 }
771 } 679 }
772 680
773 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { 681 for (i = ludp->connections[connection_id].recv_packetnum; i != maxnum; ++i) {
774 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) 682 if (ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0)
775 connections[connection_id].recv_packetnum = i; 683 ludp->connections[connection_id].recv_packetnum = i;
776 else 684 else
777 break; 685 break;
778 } 686 }
@@ -780,15 +688,16 @@ static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_
780 return 0; 688 return 0;
781} 689}
782 690
783static int handle_data(IP_Port source, uint8_t *packet, uint32_t length) 691static int handle_data(void * object, IP_Port source, uint8_t *packet, uint32_t length)
784{ 692{
785 int connection = getconnection_id(source); 693 Lossless_UDP * ludp = object;
694 int connection = getconnection_id(ludp, source);
786 695
787 if (connection == -1) 696 if (connection == -1)
788 return 1; 697 return 1;
789 698
790 /* Drop the data packet if connection is not connected. */ 699 /* Drop the data packet if connection is not connected. */
791 if (connections[connection].status != 3) 700 if (ludp->connections[connection].status != 3)
792 return 1; 701 return 1;
793 702
794 if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) 703 if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1)
@@ -801,76 +710,81 @@ static int handle_data(IP_Port source, uint8_t *packet, uint32_t length)
801 memcpy(&temp, packet + 1, 4); 710 memcpy(&temp, packet + 1, 4);
802 number = ntohl(temp); 711 number = ntohl(temp);
803 712
804 return add_recv(connection, number, packet + 5, size); 713 return add_recv(ludp, connection, number, packet + 5, size);
805} 714}
806 715
807/* 716/*
808 * END of packet handling functions 717 * END of packet handling functions
809 */ 718 */
810 719
811void LosslessUDP_init(void) 720Lossless_UDP * new_lossless_udp(Networking_Core * net)
812{ 721{
813 networking_registerhandler(16, &handle_handshake); 722 Lossless_UDP * temp = calloc(1, sizeof(Lossless_UDP));
814 networking_registerhandler(17, &handle_SYNC); 723 if (temp == NULL)
815 networking_registerhandler(18, &handle_data); 724 return NULL;
725 temp->net = net;
726 networking_registerhandler(net, 16, &handle_handshake, temp);
727 networking_registerhandler(net, 17, &handle_SYNC, temp);
728 networking_registerhandler(net, 18, &handle_data, temp);
729 return temp;
816} 730}
817 731
818/* 732/*
819 * Send handshake requests 733 * Send handshake requests
820 * handshake packets are sent at the same rate as SYNC packets 734 * handshake packets are sent at the same rate as SYNC packets
821 */ 735 */
822static void doNew(void) 736static void do_new(Lossless_UDP * ludp)
823{ 737{
824 uint32_t i; 738 uint32_t i;
825 uint64_t temp_time = current_time(); 739 uint64_t temp_time = current_time();
826 740
827 for (i = 0; i < MAX_CONNECTIONS; ++i) { 741 for (i = 0; i < ludp->connections_length; ++i) {
828 if (connections[i].status == 1) 742 if (ludp->connections[i].status == 1)
829 if ((connections[i].last_sent + (1000000UL / connections[i].SYNC_rate)) <= temp_time) { 743 if ((ludp->connections[i].last_sent + (1000000UL / ludp->connections[i].SYNC_rate)) <= temp_time) {
830 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); 744 send_handshake(ludp, ludp->connections[i].ip_port, ludp->connections[i].handshake_id1, 0);
831 connections[i].last_sent = temp_time; 745 ludp->connections[i].last_sent = temp_time;
832 } 746 }
833 747
834 /* kill all timed out connections */ 748 /* kill all timed out connections */
835 if (connections[i].status > 0 && 749 if (ludp->connections[i].status > 0 &&
836 (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && 750 (ludp->connections[i].last_recvSYNC + ludp->connections[i].timeout * 1000000UL) < temp_time &&
837 connections[i].status != 4) { 751 ludp->connections[i].status != 4) {
838 connections[i].status = 4; 752 ludp->connections[i].status = 4;
839 /* kill_connection(i); */ 753 /* kill_connection(i); */
840 } 754 }
841 755
842 if (connections[i].status > 0 && connections[i].killat < temp_time) 756 if (ludp->connections[i].status > 0 && ludp->connections[i].killat < temp_time)
843 kill_connection(i); 757 kill_connection(ludp, i);
844 } 758 }
845} 759}
846 760
847static void doSYNC(void) 761static void do_SYNC(Lossless_UDP * ludp)
848{ 762{
849 uint32_t i; 763 uint32_t i;
850 uint64_t temp_time = current_time(); 764 uint64_t temp_time = current_time();
851 765
852 for (i = 0; i < MAX_CONNECTIONS; ++i) { 766 for (i = 0; i < ludp->connections_length; ++i) {
853 if (connections[i].status == 2 || connections[i].status == 3) 767 if (ludp->connections[i].status == 2 || ludp->connections[i].status == 3)
854 if ((connections[i].last_SYNC + (1000000UL / connections[i].SYNC_rate)) <= temp_time) { 768 if ((ludp->connections[i].last_SYNC + (1000000UL / ludp->connections[i].SYNC_rate)) <= temp_time) {
855 send_SYNC(i); 769 send_SYNC(ludp, i);
856 connections[i].last_SYNC = temp_time; 770 ludp->connections[i].last_SYNC = temp_time;
857 } 771 }
858 } 772 }
859} 773}
860 774
861static void doData(void) 775static void do_data(Lossless_UDP * ludp)
862{ 776{
863 uint32_t i; 777 uint32_t i;
864 uint64_t j; 778 uint64_t j;
865 uint64_t temp_time = current_time(); 779 uint64_t temp_time = current_time();
866 780
867 for (i = 0; i < MAX_CONNECTIONS; ++i) 781 for (i = 0; i < ludp->connections_length; ++i)
868 if (connections[i].status == 3 && sendqueue(i) != 0) 782 if (ludp->connections[i].status == 3 && sendqueue(ludp, i) != 0)
869 if ((connections[i].last_sent + (1000000UL / connections[i].data_rate)) <= temp_time) { 783 if ((ludp->connections[i].last_sent + (1000000UL / ludp->connections[i].data_rate)) <= temp_time) {
870 for (j = connections[i].last_sent; j < temp_time; j += (1000000UL / connections[i].data_rate)) 784 for (j = ludp->connections[i].last_sent; j < temp_time; j += (1000000UL / ludp->connections[i].data_rate))
871 send_DATA(i); 785 send_DATA(ludp, i);
872 786
873 connections[i].last_sent = temp_time; 787 ludp->connections[i].last_sent = temp_time;
874 } 788 }
875} 789}
876 790
@@ -881,32 +795,38 @@ static void doData(void)
881 * 795 *
882 * TODO: flow control. 796 * TODO: flow control.
883 */ 797 */
884static void adjustRates(void) 798static void adjust_rates(Lossless_UDP * ludp)
885{ 799{
886 uint32_t i; 800 uint32_t i;
887 uint64_t temp_time = current_time(); 801 uint64_t temp_time = current_time();
888 802
889 for (i = 0; i < MAX_CONNECTIONS; ++i) { 803 for (i = 0; i < ludp->connections_length; ++i) {
890 if (connections[i].status == 1 || connections[i].status == 2) 804 if (ludp->connections[i].status == 1 || ludp->connections[i].status == 2)
891 connections[i].SYNC_rate = MAX_SYNC_RATE; 805 ludp->connections[i].SYNC_rate = MAX_SYNC_RATE;
892 806
893 if (connections[i].status == 3) { 807 if (ludp->connections[i].status == 3) {
894 if (sendqueue(i) != 0) { 808 if (sendqueue(ludp, i) != 0) {
895 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; 809 ludp->connections[i].data_rate = (BUFFER_PACKET_NUM - ludp->connections[i].num_req_paquets) * MAX_SYNC_RATE;
896 connections[i].SYNC_rate = MAX_SYNC_RATE; 810 ludp->connections[i].SYNC_rate = MAX_SYNC_RATE;
897 } else if (connections[i].last_recvdata + 1000000UL > temp_time) 811 } else if (ludp->connections[i].last_recvdata + 1000000UL > temp_time)
898 connections[i].SYNC_rate = MAX_SYNC_RATE; 812 ludp->connections[i].SYNC_rate = MAX_SYNC_RATE;
899 else 813 else
900 connections[i].SYNC_rate = SYNC_RATE; 814 ludp->connections[i].SYNC_rate = SYNC_RATE;
901 } 815 }
902 } 816 }
903} 817}
904 818
905/* Call this function a couple times per second It's the main loop. */ 819/* Call this function a couple times per second It's the main loop. */
906void doLossless_UDP(void) 820void do_lossless_udp(Lossless_UDP * ludp)
907{ 821{
908 doNew(); 822 do_new(ludp);
909 doSYNC(); 823 do_SYNC(ludp);
910 doData(); 824 do_data(ludp);
911 adjustRates(); 825 adjust_rates(ludp);
912} 826}
827
828void kill_lossless_udp(Lossless_UDP * ludp)
829{
830 free(ludp->connections);
831 free(ludp);
832} \ No newline at end of file
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h
index bd426ee0..6d0ee6a2 100644
--- a/core/Lossless_UDP.h
+++ b/core/Lossless_UDP.h
@@ -33,72 +33,168 @@ extern "C" {
33/* maximum length of the data in the data packets */ 33/* maximum length of the data in the data packets */
34#define MAX_DATA_SIZE 1024 34#define MAX_DATA_SIZE 1024
35 35
36/* maximum data packets in sent and receive queues. */
37#define MAX_QUEUE_NUM 16
38
39/* maximum number of data packets in the buffer */
40#define BUFFER_PACKET_NUM (16-1)
41
42/* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */
43#define CONNEXION_TIMEOUT 5
44
45/* initial amount of sync/hanshake packets to send per second. */
46#define SYNC_RATE 2
47
48/* initial send rate of data. */
49#define DATA_SYNC_RATE 30
50
51typedef struct {
52 uint8_t data[MAX_DATA_SIZE];
53 uint16_t size;
54} Data;
55
56typedef struct {
57 IP_Port ip_port;
58
59 /*
60 * 0 if connection is dead, 1 if attempting handshake,
61 * 2 if handshake is done (we start sending SYNC packets)
62 * 3 if we are sending SYNC packets and can send data
63 * 4 if the connection has timed out.
64 */
65 uint8_t status;
66
67 /*
68 * 1 or 2 if connection was initiated by someone else, 0 if not.
69 * 2 if incoming_connection() has not returned it yet, 1 if it has.
70 */
71 uint8_t inbound;
72
73 uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */
74 uint16_t data_rate; /* current data packet send rate packets per second. */
75
76 uint64_t last_SYNC; /* time our last SYNC packet was sent. */
77 uint64_t last_sent; /* time our last data or handshake packet was sent. */
78 uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */
79 uint64_t last_recvdata; /* time we last received a DATA packet from the other */
80 uint64_t killat; /* time to kill the connection */
81
82 Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */
83 Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */
84
85 uint32_t handshake_id1;
86 uint32_t handshake_id2;
87
88 /* number of data packets received (also used as handshake_id1) */
89 uint32_t recv_packetnum;
90
91 /* number of packets received by the other peer */
92 uint32_t orecv_packetnum;
93
94 /* number of data packets sent */
95 uint32_t sent_packetnum;
96
97 /* number of packets sent by the other peer. */
98 uint32_t osent_packetnum;
99
100 /* number of latest packet written onto the sendbuffer */
101 uint32_t sendbuff_packetnum;
102
103 /* we know all packets before that number were successfully sent */
104 uint32_t successful_sent;
105
106 /* packet number of last packet read with the read_packet function */
107 uint32_t successful_read;
108
109 /* list of currently requested packet numbers(by the other person) */
110 uint32_t req_packets[BUFFER_PACKET_NUM];
111
112 /* total number of currently requested packets(by the other person) */
113 uint16_t num_req_paquets;
114
115 uint8_t recv_counter;
116 uint8_t send_counter;
117 uint8_t timeout; /* connection timeout in seconds. */
118} Connection;
119
120typedef struct {
121Networking_Core *net;
122Connection *connections;
123
124uint32_t connections_length; /* Length of connections array */
125uint32_t connections_number; /* Number of connections in connections array */
126
127/* table of random numbers used in handshake_id. */
128uint32_t randtable[6][256];
129
130} Lossless_UDP;
131
36/* 132/*
37 * Initialize a new connection to ip_port 133 * Initialize a new connection to ip_port
38 * Returns an integer corresponding to the connection id. 134 * Returns an integer corresponding to the connection id.
39 * Return -1 if it could not initialize the connection. 135 * Return -1 if it could not initialize the connection.
40 * Return number if there already was an existing connection to that ip_port. 136 * Return number if there already was an existing connection to that ip_port.
41 */ 137 */
42int new_connection(IP_Port ip_port); 138int new_connection(Lossless_UDP * ludp, IP_Port ip_port);
43 139
44/* 140/*
45 * Get connection id from IP_Port. 141 * Get connection id from IP_Port.
46 * Return -1 if there are no connections like we are looking for. 142 * Return -1 if there are no connections like we are looking for.
47 * Return id if it found it . 143 * Return id if it found it .
48 */ 144 */
49int getconnection_id(IP_Port ip_port); 145int getconnection_id(Lossless_UDP * ludp, IP_Port ip_port);
50 146
51/* 147/*
52 * Returns an int corresponding to the next connection in our imcoming connection list 148 * Returns an int corresponding to the next connection in our imcoming connection list
53 * Return -1 if there are no new incoming connections in the list. 149 * Return -1 if there are no new incoming connections in the list.
54 */ 150 */
55int incoming_connection(void); 151int incoming_connection(Lossless_UDP * ludp);
56 152
57/* 153/*
58 * Return -1 if it could not kill the connection. 154 * Return -1 if it could not kill the connection.
59 * Return 0 if killed successfully 155 * Return 0 if killed successfully
60 */ 156 */
61int kill_connection(int connection_id); 157int kill_connection(Lossless_UDP * ludp, int connection_id);
62 158
63/* 159/*
64 * Kill connection in seconds seconds. 160 * Kill connection in seconds seconds.
65 * Return -1 if it can not kill the connection. 161 * Return -1 if it can not kill the connection.
66 * Return 0 if it will kill it 162 * Return 0 if it will kill it
67 */ 163 */
68int kill_connection_in(int connection_id, uint32_t seconds); 164int kill_connection_in(Lossless_UDP * ludp, int connection_id, uint32_t seconds);
69 165
70/* 166/*
71 * Returns the ip_port of the corresponding connection. 167 * Returns the ip_port of the corresponding connection.
72 * Return 0 if there is no such connection. 168 * Return 0 if there is no such connection.
73 */ 169 */
74IP_Port connection_ip(int connection_id); 170IP_Port connection_ip(Lossless_UDP * ludp, int connection_id);
75 171
76/* 172/*
77 * Returns the id of the next packet in the queue 173 * Returns the id of the next packet in the queue
78 * Return -1 if no packet in queue 174 * Return -1 if no packet in queue
79 */ 175 */
80char id_packet(int connection_id); 176char id_packet(Lossless_UDP * ludp, int connection_id);
81 177
82/* 178/*
83 * Return 0 if there is no received data in the buffer. 179 * Return 0 if there is no received data in the buffer.
84 * Return length of received packet if successful 180 * Return length of received packet if successful
85 */ 181 */
86int read_packet(int connection_id, uint8_t *data); 182int read_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data);
87 183
88/* 184/*
89 * Return 0 if data could not be put in packet queue 185 * Return 0 if data could not be put in packet queue
90 * Return 1 if data was put into the queue 186 * Return 1 if data was put into the queue
91 */ 187 */
92int write_packet(int connection_id, uint8_t *data, uint32_t length); 188int write_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data, uint32_t length);
93 189
94/* Returns the number of packets in the queue waiting to be successfully sent. */ 190/* Returns the number of packets in the queue waiting to be successfully sent. */
95uint32_t sendqueue(int connection_id); 191uint32_t sendqueue(Lossless_UDP * ludp, int connection_id);
96 192
97/* 193/*
98 * returns the number of packets in the queue waiting to be successfully 194 * returns the number of packets in the queue waiting to be successfully
99 * read with read_packet(...) 195 * read with read_packet(...)
100 */ 196 */
101uint32_t recvqueue(int connection_id); 197uint32_t recvqueue(Lossless_UDP * ludp, int connection_id);
102 198
103/* Check if connection is connected: 199/* Check if connection is connected:
104 * Return 0 no. 200 * Return 0 no.
@@ -107,15 +203,17 @@ uint32_t recvqueue(int connection_id);
107 * Return 3 if fully connected. 203 * Return 3 if fully connected.
108 * Return 4 if timed out and wating to be killed. 204 * Return 4 if timed out and wating to be killed.
109 */ 205 */
110int is_connected(int connection_id); 206int is_connected(Lossless_UDP * ludp, int connection_id);
111 207
112/* Call this function a couple times per second It's the main loop. */ 208/* Call this function a couple times per second It's the main loop. */
113void doLossless_UDP(void); 209void do_lossless_udp(Lossless_UDP * ludp);
114 210
115/* 211/*
116 * This function sets up LosslessUDP packet handling. 212 * This function sets up LosslessUDP packet handling.
117 */ 213 */
118void LosslessUDP_init(void); 214Lossless_UDP * new_lossless_udp(Networking_Core * net);
215
216void kill_lossless_udp(Lossless_UDP * ludp);
119 217
120#ifdef __cplusplus 218#ifdef __cplusplus
121} 219}
diff --git a/core/Messenger.c b/core/Messenger.c
index 7fd6a569..cb3d2551 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -246,7 +246,7 @@ int m_delfriend(Messenger *m, int friendnumber)
246 return -1; 246 return -1;
247 247
248 DHT_delfriend(m->friendlist[friendnumber].client_id); 248 DHT_delfriend(m->friendlist[friendnumber].client_id);
249 crypto_kill(m->friendlist[friendnumber].crypt_connection_id); 249 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
250 free(m->friendlist[friendnumber].statusmessage); 250 free(m->friendlist[friendnumber].statusmessage);
251 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); 251 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
252 uint32_t i; 252 uint32_t i;
@@ -606,7 +606,7 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
606 if (length != 0) 606 if (length != 0)
607 memcpy(packet + 1, data, length); 607 memcpy(packet + 1, data, length);
608 608
609 return write_cryptpacket(m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); 609 return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1);
610} 610}
611 611
612 612
@@ -626,21 +626,25 @@ int LANdiscovery(timer *t, void *arg)
626Messenger *initMessenger(void) 626Messenger *initMessenger(void)
627{ 627{
628 Messenger *m = calloc(1, sizeof(Messenger)); 628 Messenger *m = calloc(1, sizeof(Messenger));
629
630 if ( ! m ) 629 if ( ! m )
631 return 0; 630 return 0;
632
633 new_keys();
634 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
635 initNetCrypto();
636 IP ip; 631 IP ip;
637 ip.i = 0; 632 ip.i = 0;
638 633 m->net = new_networking(ip, PORT);
639 if (init_networking(ip, PORT) == -1) 634 if (m->net == NULL) {
640 return 0; 635 free(m);
636 return NULL;
637 }
638 m->net_crypto = new_net_crypto(m->net);
639 if (m->net_crypto == NULL) {
640 free(m);
641 free(m->net);
642 return NULL;
643 }
644 new_keys(m->net_crypto);
645 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
641 646
642 DHT_init(); 647 DHT_init();
643 LosslessUDP_init();
644 friendreq_init(); 648 friendreq_init();
645 LANdiscovery_init(); 649 LANdiscovery_init();
646 set_nospam(random_int()); 650 set_nospam(random_int());
@@ -657,6 +661,7 @@ void cleanupMessenger(Messenger *m)
657 /* FIXME TODO ideally cleanupMessenger will mirror initMessenger 661 /* FIXME TODO ideally cleanupMessenger will mirror initMessenger
658 * this requires the other modules to expose cleanup functions 662 * this requires the other modules to expose cleanup functions
659 */ 663 */
664 kill_net_crypto(m->net_crypto);
660 free(m->friendlist); 665 free(m->friendlist);
661 free(m); 666 free(m);
662} 667}
@@ -696,10 +701,10 @@ void doFriends(Messenger *m)
696 701
697 IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); 702 IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id);
698 703
699 switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) { 704 switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) {
700 case 0: 705 case 0:
701 if (friendip.ip.i > 1) 706 if (friendip.ip.i > 1)
702 m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip); 707 m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip);
703 708
704 break; 709 break;
705 710
@@ -712,7 +717,7 @@ void doFriends(Messenger *m)
712 break; 717 break;
713 718
714 case 4: 719 case 4:
715 crypto_kill(m->friendlist[i].crypt_connection_id); 720 crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id);
716 m->friendlist[i].crypt_connection_id = -1; 721 m->friendlist[i].crypt_connection_id = -1;
717 break; 722 break;
718 723
@@ -741,7 +746,7 @@ void doFriends(Messenger *m)
741 send_ping(m, i); 746 send_ping(m, i);
742 } 747 }
743 748
744 len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp); 749 len = read_cryptpacket(m->net_crypto, m->friendlist[i].crypt_connection_id, temp);
745 uint8_t packet_id = temp[0]; 750 uint8_t packet_id = temp[0];
746 uint8_t *data = temp + 1; 751 uint8_t *data = temp + 1;
747 int data_length = len - 1; 752 int data_length = len - 1;
@@ -833,8 +838,8 @@ void doFriends(Messenger *m)
833 } 838 }
834 } 839 }
835 } else { 840 } else {
836 if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ 841 if (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
837 crypto_kill(m->friendlist[i].crypt_connection_id); 842 crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id);
838 m->friendlist[i].crypt_connection_id = -1; 843 m->friendlist[i].crypt_connection_id = -1;
839 set_friend_status(m, i, FRIEND_CONFIRMED); 844 set_friend_status(m, i, FRIEND_CONFIRMED);
840 } 845 }
@@ -844,7 +849,7 @@ void doFriends(Messenger *m)
844 849
845 if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { 850 if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) {
846 /* if we stopped recieving ping packets kill it */ 851 /* if we stopped recieving ping packets kill it */
847 crypto_kill(m->friendlist[i].crypt_connection_id); 852 crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id);
848 m->friendlist[i].crypt_connection_id = -1; 853 m->friendlist[i].crypt_connection_id = -1;
849 set_friend_status(m, i, FRIEND_CONFIRMED); 854 set_friend_status(m, i, FRIEND_CONFIRMED);
850 } 855 }
@@ -857,15 +862,15 @@ void doInbound(Messenger *m)
857 uint8_t secret_nonce[crypto_box_NONCEBYTES]; 862 uint8_t secret_nonce[crypto_box_NONCEBYTES];
858 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 863 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
859 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 864 uint8_t session_key[crypto_box_PUBLICKEYBYTES];
860 int inconnection = crypto_inbound(public_key, secret_nonce, session_key); 865 int inconnection = crypto_inbound(m->net_crypto, public_key, secret_nonce, session_key);
861 866
862 if (inconnection != -1) { 867 if (inconnection != -1) {
863 int friend_id = getfriend_id(m, public_key); 868 int friend_id = getfriend_id(m, public_key);
864 869
865 if (friend_id != -1) { 870 if (friend_id != -1) {
866 crypto_kill(m->friendlist[friend_id].crypt_connection_id); 871 crypto_kill(m->net_crypto, m->friendlist[friend_id].crypt_connection_id);
867 m->friendlist[friend_id].crypt_connection_id = 872 m->friendlist[friend_id].crypt_connection_id =
868 accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); 873 accept_crypto_inbound(m->net_crypto, inconnection, public_key, secret_nonce, session_key);
869 874
870 set_friend_status(m, friend_id, FRIEND_CONFIRMED); 875 set_friend_status(m, friend_id, FRIEND_CONFIRMED);
871 } 876 }
@@ -873,14 +878,13 @@ void doInbound(Messenger *m)
873} 878}
874 879
875 880
876/* the main loop that needs to be run at least 200 times per second. */ 881/* the main loop that needs to be run at least 20 times per second. */
877void doMessenger(Messenger *m) 882void doMessenger(Messenger *m)
878{ 883{
879 networking_poll(); 884 networking_poll(m->net);
880 885
881 doDHT(); 886 doDHT();
882 doLossless_UDP(); 887 do_net_crypto(m->net_crypto);
883 doNetCrypto();
884 doInbound(m); 888 doInbound(m);
885 doFriends(m); 889 doFriends(m);
886 890
@@ -904,7 +908,7 @@ uint32_t Messenger_size(Messenger *m)
904/* save the messenger in data of size Messenger_size() */ 908/* save the messenger in data of size Messenger_size() */
905void Messenger_save(Messenger *m, uint8_t *data) 909void Messenger_save(Messenger *m, uint8_t *data)
906{ 910{
907 save_keys(data); 911 save_keys(m->net_crypto, data);
908 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 912 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
909 uint32_t nospam = get_nospam(); 913 uint32_t nospam = get_nospam();
910 memcpy(data, &nospam, sizeof(nospam)); 914 memcpy(data, &nospam, sizeof(nospam));
@@ -935,7 +939,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
935 return -1; 939 return -1;
936 940
937 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3; 941 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3;
938 load_keys(data); 942 load_keys(m->net_crypto, data);
939 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 943 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
940 uint32_t nospam; 944 uint32_t nospam;
941 memcpy(&nospam, data, sizeof(nospam)); 945 memcpy(&nospam, data, sizeof(nospam));
diff --git a/core/Messenger.h b/core/Messenger.h
index 9016be93..a2e8f16e 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -112,8 +112,9 @@ typedef struct {
112} Friend; 112} Friend;
113 113
114typedef struct Messenger { 114typedef struct Messenger {
115 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 115
116 116 Networking_Core *net;
117 Net_Crypto * net_crypto;
117 uint8_t name[MAX_NAME_LENGTH]; 118 uint8_t name[MAX_NAME_LENGTH];
118 uint16_t name_length; 119 uint16_t name_length;
119 120
diff --git a/core/friend_requests.c b/core/friend_requests.c
index 3708f154..7be7a4bd 100644
--- a/core/friend_requests.c
+++ b/core/friend_requests.c
@@ -24,7 +24,7 @@
24#include "friend_requests.h" 24#include "friend_requests.h"
25 25
26uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 26uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
27 27uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
28 28
29/* Try to send a friendrequest to peer with public_key 29/* Try to send a friendrequest to peer with public_key
30 data is the data in the request and length is the length. 30 data is the data in the request and length is the length.
@@ -40,7 +40,7 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data,
40 memcpy(temp, &nospam_num, sizeof(nospam_num)); 40 memcpy(temp, &nospam_num, sizeof(nospam_num));
41 memcpy(temp + sizeof(nospam_num), data, length); 41 memcpy(temp + sizeof(nospam_num), data, length);
42 uint8_t packet[MAX_DATA_SIZE]; 42 uint8_t packet[MAX_DATA_SIZE];
43 int len = create_request(packet, public_key, temp, length + sizeof(nospam_num), 43 int len = create_request(self_public_key, self_secret_key, packet, public_key, temp, length + sizeof(nospam_num),
44 32); /* 32 is friend request packet id */ 44 32); /* 32 is friend request packet id */
45 45
46 if (len == -1) 46 if (len == -1)
@@ -52,7 +52,7 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data,
52 return -1; 52 return -1;
53 53
54 if (ip_port.ip.i != 0) { 54 if (ip_port.ip.i != 0) {
55 if (sendpacket(ip_port, packet, len) != -1) 55 if (sendpacket(temp_net->sock, ip_port, packet, len) != -1)
56 return 0; 56 return 0;
57 57
58 return -1; 58 return -1;
@@ -146,5 +146,5 @@ static int friendreq_handlepacket(IP_Port source, uint8_t *source_pubkey, uint8_
146 146
147void friendreq_init(void) 147void friendreq_init(void)
148{ 148{
149 cryptopacket_registerhandler(32, &friendreq_handlepacket); 149 cryptopacket_registerhandler(temp_net_crypto, 32, &friendreq_handlepacket);
150} 150}
diff --git a/core/net_crypto.c b/core/net_crypto.c
index 8fcb62e1..dcf36a12 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -26,42 +26,12 @@
26 26
27#include "net_crypto.h" 27#include "net_crypto.h"
28 28
29/* Our public and secret keys. */
30uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
31uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
32
33typedef struct {
34 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */
35 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */
36 uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */
37 uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */
38 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */
39 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
40 uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* the precomputed shared key from encrypt_precompute */
41 uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
42 (we have received a handshake but no empty data packet), 3 if the connection is established.
43 4 if the connection is timed out. */
44 uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */
45
46} Crypto_Connection;
47
48static Crypto_Connection *crypto_connections;
49
50static uint32_t crypto_connections_length; /* Length of connections array */
51
52#define MAX_CRYPTO_CONNECTIONS crypto_connections_length
53
54#define CONN_NO_CONNECTION 0 29#define CONN_NO_CONNECTION 0
55#define CONN_HANDSHAKE_SENT 1 30#define CONN_HANDSHAKE_SENT 1
56#define CONN_NOT_CONFIRMED 2 31#define CONN_NOT_CONFIRMED 2
57#define CONN_ESTABLISHED 3 32#define CONN_ESTABLISHED 3
58#define CONN_TIMED_OUT 4 33#define CONN_TIMED_OUT 4
59 34
60#define MAX_INCOMING 64
61
62/* keeps track of the connection numbers for friends request so we can check later if they were sent */
63static int incoming_connections[MAX_INCOMING];
64
65/* Use this instead of memcmp; not vulnerable to timing attacks. */ 35/* Use this instead of memcmp; not vulnerable to timing attacks. */
66uint8_t crypto_iszero(uint8_t *mem, uint32_t length) 36uint8_t crypto_iszero(uint8_t *mem, uint32_t length)
67{ 37{
@@ -175,16 +145,16 @@ void random_nonce(uint8_t *nonce)
175/* return 0 if there is no received data in the buffer 145/* return 0 if there is no received data in the buffer
176 return -1 if the packet was discarded. 146 return -1 if the packet was discarded.
177 return length of received data if successful */ 147 return length of received data if successful */
178int read_cryptpacket(int crypt_connection_id, uint8_t *data) 148int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data)
179{ 149{
180 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 150 if (crypt_connection_id < 0 || crypt_connection_id >= c->crypto_connections_length)
181 return 0; 151 return 0;
182 152
183 if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) 153 if (c->crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
184 return 0; 154 return 0;
185 155
186 uint8_t temp_data[MAX_DATA_SIZE]; 156 uint8_t temp_data[MAX_DATA_SIZE];
187 int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); 157 int length = read_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data);
188 158
189 if (length == 0) 159 if (length == 0)
190 return 0; 160 return 0;
@@ -192,12 +162,12 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
192 if (temp_data[0] != 3) 162 if (temp_data[0] != 3)
193 return -1; 163 return -1;
194 164
195 int len = decrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, 165 int len = decrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key,
196 crypto_connections[crypt_connection_id].recv_nonce, 166 c->crypto_connections[crypt_connection_id].recv_nonce,
197 temp_data + 1, length - 1, data); 167 temp_data + 1, length - 1, data);
198 168
199 if (len != -1) { 169 if (len != -1) {
200 increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); 170 increment_nonce(c->crypto_connections[crypt_connection_id].recv_nonce);
201 return len; 171 return len;
202 } 172 }
203 173
@@ -206,20 +176,20 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
206 176
207/* return 0 if data could not be put in packet queue 177/* return 0 if data could not be put in packet queue
208 return 1 if data was put into the queue */ 178 return 1 if data was put into the queue */
209int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) 179int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length)
210{ 180{
211 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 181 if (crypt_connection_id < 0 || crypt_connection_id >= c->crypto_connections_length)
212 return 0; 182 return 0;
213 183
214 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) 184 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
215 return 0; 185 return 0;
216 186
217 if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) 187 if (c->crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
218 return 0; 188 return 0;
219 189
220 uint8_t temp_data[MAX_DATA_SIZE]; 190 uint8_t temp_data[MAX_DATA_SIZE];
221 int len = encrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, 191 int len = encrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key,
222 crypto_connections[crypt_connection_id].sent_nonce, 192 c->crypto_connections[crypt_connection_id].sent_nonce,
223 data, length, temp_data + 1); 193 data, length, temp_data + 1);
224 194
225 if (len == -1) 195 if (len == -1)
@@ -227,20 +197,22 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length)
227 197
228 temp_data[0] = 3; 198 temp_data[0] = 3;
229 199
230 if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) 200 if (write_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0)
231 return 0; 201 return 0;
232 202
233 increment_nonce(crypto_connections[crypt_connection_id].sent_nonce); 203 increment_nonce(c->crypto_connections[crypt_connection_id].sent_nonce);
234 return 1; 204 return 1;
235} 205}
236 206
237/* create a request to peer with public_key. 207/* create a request to peer.
208 send_public_key and send_secret_key are the pub/secret keys of the sender
209 recv_public_key is public key of reciever
238 packet must be an array of MAX_DATA_SIZE big. 210 packet must be an array of MAX_DATA_SIZE big.
239 Data represents the data we send with the request with length being the length of the data. 211 Data represents the data we send with the request with length being the length of the data.
240 request_id is the id of the request (32 = friend request, 254 = ping request) 212 request_id is the id of the request (32 = friend request, 254 = ping request)
241 returns -1 on failure 213 returns -1 on failure
242 returns the length of the created packet on success */ 214 returns the length of the created packet on success */
243int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id) 215int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, uint8_t *data, uint32_t length, uint8_t request_id)
244{ 216{
245 if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) 217 if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING)
246 return -1; 218 return -1;
@@ -250,15 +222,15 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
250 memcpy(temp + 1, data, length); 222 memcpy(temp + 1, data, length);
251 temp[0] = request_id; 223 temp[0] = request_id;
252 random_nonce(nonce); 224 random_nonce(nonce);
253 int len = encrypt_data(public_key, self_secret_key, nonce, temp, length + 1, 225 int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
254 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); 226 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
255 227
256 if (len == -1) 228 if (len == -1)
257 return -1; 229 return -1;
258 230
259 packet[0] = 32; 231 packet[0] = 32;
260 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 232 memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES);
261 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); 233 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES);
262 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); 234 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
263 235
264 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; 236 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
@@ -268,17 +240,17 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
268 in data if a friend or ping request was sent to us and returns the length of the data. 240 in data if a friend or ping request was sent to us and returns the length of the data.
269 packet is the request packet and length is its length 241 packet is the request packet and length is its length
270 return -1 if not valid request. */ 242 return -1 if not valid request. */
271static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_id, uint8_t *packet, uint16_t length) 243static int handle_request(Net_Crypto *c, uint8_t *public_key, uint8_t *data, uint8_t *request_id, uint8_t *packet, uint16_t length)
272{ 244{
273 245
274 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 246 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
275 length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && 247 length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
276 memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { 248 memcmp(packet + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
277 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); 249 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
278 uint8_t nonce[crypto_box_NONCEBYTES]; 250 uint8_t nonce[crypto_box_NONCEBYTES];
279 uint8_t temp[MAX_DATA_SIZE]; 251 uint8_t temp[MAX_DATA_SIZE];
280 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); 252 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
281 int len1 = decrypt_data(public_key, self_secret_key, nonce, 253 int len1 = decrypt_data(public_key, c->self_secret_key, nonce,
282 packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, 254 packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
283 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); 255 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp);
284 256
@@ -293,15 +265,14 @@ static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_i
293 return -1; 265 return -1;
294} 266}
295 267
296static cryptopacket_handler_callback cryptopackethandlers[256] = {0}; 268void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb)
297
298void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb)
299{ 269{
300 cryptopackethandlers[byte] = cb; 270 c->cryptopackethandlers[byte] = cb;
301} 271}
302 272
303static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length) 273static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length)
304{ 274{
275 Net_Crypto *c = object;
305 if (packet[0] == 32) { 276 if (packet[0] == 32) {
306 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || 277 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING ||
307 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 278 length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
@@ -311,17 +282,17 @@ static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length)
311 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 282 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
312 uint8_t data[MAX_DATA_SIZE]; 283 uint8_t data[MAX_DATA_SIZE];
313 uint8_t number; 284 uint8_t number;
314 int len = handle_request(public_key, data, &number, packet, length); 285 int len = handle_request(c, public_key, data, &number, packet, length);
315 286
316 if (len == -1 || len == 0) 287 if (len == -1 || len == 0)
317 return 1; 288 return 1;
318 289
319 if (!cryptopackethandlers[number]) return 1; 290 if (!c->cryptopackethandlers[number]) return 1;
320 291
321 cryptopackethandlers[number](source, public_key, data, len); 292 c->cryptopackethandlers[number](source, public_key, data, len);
322 293
323 } else { /* if request is not for us, try routing it. */ 294 } else { /* if request is not for us, try routing it. */
324 if (route_packet(packet + 1, packet, length) == length) 295 if (route_packet(packet + 1, packet, length) == length) //NOTE
325 return 0; 296 return 0;
326 } 297 }
327 } 298 }
@@ -332,7 +303,7 @@ static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length)
332/* Send a crypto handshake packet containing an encrypted secret nonce and session public key 303/* Send a crypto handshake packet containing an encrypted secret nonce and session public key
333 to peer with connection_id and public_key 304 to peer with connection_id and public_key
334 the packet is encrypted with a random nonce which is sent in plain text with the packet */ 305 the packet is encrypted with a random nonce which is sent in plain text with the packet */
335static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) 306static int send_cryptohandshake(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
336{ 307{
337 uint8_t temp_data[MAX_DATA_SIZE]; 308 uint8_t temp_data[MAX_DATA_SIZE];
338 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; 309 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
@@ -342,22 +313,22 @@ static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t
342 memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); 313 memcpy(temp, secret_nonce, crypto_box_NONCEBYTES);
343 memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES); 314 memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES);
344 315
345 int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 316 int len = encrypt_data(public_key, c->self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
346 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); 317 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
347 318
348 if (len == -1) 319 if (len == -1)
349 return 0; 320 return 0;
350 321
351 temp_data[0] = 2; 322 temp_data[0] = 2;
352 memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); 323 memcpy(temp_data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES);
353 memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); 324 memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
354 return write_packet(connection_id, temp_data, len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); 325 return write_packet(c->lossless_udp, connection_id, temp_data, len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
355} 326}
356 327
357/* Extract secret nonce, session public key and public_key from a packet(data) with length length 328/* Extract secret nonce, session public key and public_key from a packet(data) with length length
358 return 1 if successful 329 return 1 if successful
359 return 0 if failure */ 330 return 0 if failure */
360static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, 331static int handle_cryptohandshake(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce,
361 uint8_t *session_key, uint8_t *data, uint16_t length) 332 uint8_t *session_key, uint8_t *data, uint16_t length)
362{ 333{
363 int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); 334 int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
@@ -374,7 +345,7 @@ static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
374 345
375 memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); 346 memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES);
376 347
377 int len = decrypt_data(public_key, self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, 348 int len = decrypt_data(public_key, c->self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES,
378 data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, 349 data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
379 crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); 350 crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp);
380 351
@@ -389,13 +360,13 @@ static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
389/* get crypto connection id from public key of peer 360/* get crypto connection id from public key of peer
390 return -1 if there are no connections like we are looking for 361 return -1 if there are no connections like we are looking for
391 return id if it found it */ 362 return id if it found it */
392static int getcryptconnection_id(uint8_t *public_key) 363static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key)
393{ 364{
394 uint32_t i; 365 uint32_t i;
395 366
396 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 367 for (i = 0; i < c->crypto_connections_length; ++i) {
397 if (crypto_connections[i].status != CONN_NO_CONNECTION) 368 if (c->crypto_connections[i].status != CONN_NO_CONNECTION)
398 if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) 369 if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
399 return i; 370 return i;
400 } 371 }
401 372
@@ -404,63 +375,63 @@ static int getcryptconnection_id(uint8_t *public_key)
404 375
405/* set the size of the friend list to numfriends 376/* set the size of the friend list to numfriends
406 return -1 if realloc fails */ 377 return -1 if realloc fails */
407int realloc_cryptoconnection(uint32_t num) 378int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
408{ 379{
409 if (num == 0) { 380 if (num == 0) {
410 free(crypto_connections); 381 free(c->crypto_connections);
411 crypto_connections = NULL; 382 c->crypto_connections = NULL;
412 return 0; 383 return 0;
413 } 384 }
414 385
415 Crypto_Connection *newcrypto_connections = realloc(crypto_connections, num * sizeof(Crypto_Connection)); 386 Crypto_Connection *newcrypto_connections = realloc(c->crypto_connections, num * sizeof(Crypto_Connection));
416 387
417 if (newcrypto_connections == NULL) 388 if (newcrypto_connections == NULL)
418 return -1; 389 return -1;
419 390
420 crypto_connections = newcrypto_connections; 391 c->crypto_connections = newcrypto_connections;
421 return 0; 392 return 0;
422} 393}
423 394
424/* Start a secure connection with other peer who has public_key and ip_port 395/* Start a secure connection with other peer who has public_key and ip_port
425 returns -1 if failure 396 returns -1 if failure
426 returns crypt_connection_id of the initialized connection if everything went well. */ 397 returns crypt_connection_id of the initialized connection if everything went well. */
427int crypto_connect(uint8_t *public_key, IP_Port ip_port) 398int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port)
428{ 399{
429 uint32_t i; 400 uint32_t i;
430 int id = getcryptconnection_id(public_key); 401 int id = getcryptconnection_id(c, public_key);
431 402
432 if (id != -1) { 403 if (id != -1) {
433 IP_Port c_ip = connection_ip(crypto_connections[id].number); 404 IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id].number);
434 405
435 if (c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port) 406 if (c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port)
436 return -1; 407 return -1;
437 } 408 }
438 409
439 if (realloc_cryptoconnection(crypto_connections_length + 1) == -1) 410 if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1)
440 return -1; 411 return -1;
441 412
442 memset(&crypto_connections[crypto_connections_length], 0, sizeof(Crypto_Connection)); 413 memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection));
443 crypto_connections[crypto_connections_length].number = ~0; 414 c->crypto_connections[c->crypto_connections_length].number = ~0;
444 415
445 for (i = 0; i <= MAX_CRYPTO_CONNECTIONS; ++i) { 416 for (i = 0; i <= c->crypto_connections_length; ++i) {
446 if (crypto_connections[i].status == CONN_NO_CONNECTION) { 417 if (c->crypto_connections[i].status == CONN_NO_CONNECTION) {
447 int id = new_connection(ip_port); 418 int id = new_connection(c->lossless_udp, ip_port);
448 419
449 if (id == -1) 420 if (id == -1)
450 return -1; 421 return -1;
451 422
452 crypto_connections[i].number = id; 423 c->crypto_connections[i].number = id;
453 crypto_connections[i].status = CONN_HANDSHAKE_SENT; 424 c->crypto_connections[i].status = CONN_HANDSHAKE_SENT;
454 random_nonce(crypto_connections[i].recv_nonce); 425 random_nonce(c->crypto_connections[i].recv_nonce);
455 memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); 426 memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
456 crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); 427 crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key);
457 428
458 if (crypto_connections_length == i) 429 if (c->crypto_connections_length == i)
459 ++crypto_connections_length; 430 ++c->crypto_connections_length;
460 431
461 if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce, 432 if (send_cryptohandshake(c, id, public_key, c->crypto_connections[i].recv_nonce,
462 crypto_connections[i].sessionpublic_key) == 1) { 433 c->crypto_connections[i].sessionpublic_key) == 1) {
463 increment_nonce(crypto_connections[i].recv_nonce); 434 increment_nonce(c->crypto_connections[i].recv_nonce);
464 return i; 435 return i;
465 } 436 }
466 437
@@ -478,25 +449,25 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
478 and the session public key for the connection in session_key 449 and the session public key for the connection in session_key
479 to accept it see: accept_crypto_inbound(...) 450 to accept it see: accept_crypto_inbound(...)
480 to refuse it just call kill_connection(...) on the connection id */ 451 to refuse it just call kill_connection(...) on the connection id */
481int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) 452int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
482{ 453{
483 uint32_t i; 454 uint32_t i;
484 455
485 for (i = 0; i < MAX_INCOMING; ++i) { 456 for (i = 0; i < MAX_INCOMING; ++i) {
486 if (incoming_connections[i] != -1) { 457 if (c->incoming_connections[i] != -1) {
487 if (is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) { 458 if (is_connected(c->lossless_udp, c->incoming_connections[i]) == 4 || is_connected(c->lossless_udp, c->incoming_connections[i]) == 0) {
488 kill_connection(incoming_connections[i]); 459 kill_connection(c->lossless_udp, c->incoming_connections[i]);
489 incoming_connections[i] = -1; 460 c->incoming_connections[i] = -1;
490 continue; 461 continue;
491 } 462 }
492 463
493 if (id_packet(incoming_connections[i]) == 2) { 464 if (id_packet(c->lossless_udp, c->incoming_connections[i]) == 2) {
494 uint8_t temp_data[MAX_DATA_SIZE]; 465 uint8_t temp_data[MAX_DATA_SIZE];
495 uint16_t len = read_packet(incoming_connections[i], temp_data); 466 uint16_t len = read_packet(c->lossless_udp, c->incoming_connections[i], temp_data);
496 467
497 if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { 468 if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) {
498 int connection_id = incoming_connections[i]; 469 int connection_id = c->incoming_connections[i];
499 incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */ 470 c->incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */
500 return connection_id; 471 return connection_id;
501 } 472 }
502 } 473 }
@@ -509,25 +480,25 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_
509/* kill a crypto connection 480/* kill a crypto connection
510 return 0 if killed successfully 481 return 0 if killed successfully
511 return 1 if there was a problem. */ 482 return 1 if there was a problem. */
512int crypto_kill(int crypt_connection_id) 483int crypto_kill(Net_Crypto *c, int crypt_connection_id)
513{ 484{
514 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 485 if (crypt_connection_id < 0 || crypt_connection_id >= c->crypto_connections_length)
515 return 1; 486 return 1;
516 487
517 if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) { 488 if (c->crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) {
518 crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION; 489 c->crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION;
519 kill_connection(crypto_connections[crypt_connection_id].number); 490 kill_connection(c->lossless_udp, c->crypto_connections[crypt_connection_id].number);
520 memset(&crypto_connections[crypt_connection_id], 0 , sizeof(Crypto_Connection)); 491 memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection));
521 crypto_connections[crypt_connection_id].number = ~0; 492 c->crypto_connections[crypt_connection_id].number = ~0;
522 uint32_t i; 493 uint32_t i;
523 494
524 for (i = crypto_connections_length; i != 0; --i) { 495 for (i = c->crypto_connections_length; i != 0; --i) {
525 if (crypto_connections[i - 1].status != CONN_NO_CONNECTION) 496 if (c->crypto_connections[i - 1].status != CONN_NO_CONNECTION)
526 break; 497 break;
527 } 498 }
528 499
529 crypto_connections_length = i; 500 c->crypto_connections_length = i;
530 realloc_cryptoconnection(crypto_connections_length); 501 realloc_cryptoconnection(c, c->crypto_connections_length);
531 return 0; 502 return 0;
532 } 503 }
533 504
@@ -537,7 +508,7 @@ int crypto_kill(int crypt_connection_id)
537/* accept an incoming connection using the parameters provided by crypto_inbound 508/* accept an incoming connection using the parameters provided by crypto_inbound
538 return -1 if not successful 509 return -1 if not successful
539 returns the crypt_connection_id if successful */ 510 returns the crypt_connection_id if successful */
540int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) 511int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
541{ 512{
542 uint32_t i; 513 uint32_t i;
543 514
@@ -549,37 +520,37 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
549 { 520 {
550 return -1; 521 return -1;
551 }*/ 522 }*/
552 if (realloc_cryptoconnection(crypto_connections_length + 1) == -1) 523 if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1)
553 return -1; 524 return -1;
554 525
555 memset(&crypto_connections[crypto_connections_length], 0, sizeof(Crypto_Connection)); 526 memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection));
556 crypto_connections[crypto_connections_length].number = ~0; 527 c->crypto_connections[c->crypto_connections_length].number = ~0;
557 528
558 for (i = 0; i <= MAX_CRYPTO_CONNECTIONS; ++i) { 529 for (i = 0; i <= c->crypto_connections_length; ++i) {
559 if (crypto_connections[i].status == CONN_NO_CONNECTION) { 530 if (c->crypto_connections[i].status == CONN_NO_CONNECTION) {
560 crypto_connections[i].number = connection_id; 531 c->crypto_connections[i].number = connection_id;
561 crypto_connections[i].status = CONN_NOT_CONFIRMED; 532 c->crypto_connections[i].status = CONN_NOT_CONFIRMED;
562 random_nonce(crypto_connections[i].recv_nonce); 533 random_nonce(c->crypto_connections[i].recv_nonce);
563 memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); 534 memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
564 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); 535 memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
565 increment_nonce(crypto_connections[i].sent_nonce); 536 increment_nonce(c->crypto_connections[i].sent_nonce);
566 memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); 537 memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
567 538
568 crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); 539 crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key);
569 540
570 if (crypto_connections_length == i) 541 if (c->crypto_connections_length == i)
571 ++crypto_connections_length; 542 ++c->crypto_connections_length;
572 543
573 if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce, 544 if (send_cryptohandshake(c, connection_id, public_key, c->crypto_connections[i].recv_nonce,
574 crypto_connections[i].sessionpublic_key) == 1) { 545 c->crypto_connections[i].sessionpublic_key) == 1) {
575 increment_nonce(crypto_connections[i].recv_nonce); 546 increment_nonce(c->crypto_connections[i].recv_nonce);
576 uint32_t zero = 0; 547 uint32_t zero = 0;
577 encrypt_precompute(crypto_connections[i].peersessionpublic_key, 548 encrypt_precompute(c->crypto_connections[i].peersessionpublic_key,
578 crypto_connections[i].sessionsecret_key, 549 c->crypto_connections[i].sessionsecret_key,
579 crypto_connections[i].shared_key); 550 c->crypto_connections[i].shared_key);
580 crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ 551 c->crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
581 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); 552 write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero));
582 crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ 553 c->crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */
583 return i; 554 return i;
584 } 555 }
585 556
@@ -593,48 +564,54 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
593/* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet 564/* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet
594 (we have received a handshake but no empty data packet), 3 if the connection is established. 565 (we have received a handshake but no empty data packet), 3 if the connection is established.
595 4 if the connection is timed out and waiting to be killed */ 566 4 if the connection is timed out and waiting to be killed */
596int is_cryptoconnected(int crypt_connection_id) 567int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id)
597{ 568{
598 if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) 569 if (crypt_connection_id >= 0 && crypt_connection_id < c->crypto_connections_length)
599 return crypto_connections[crypt_connection_id].status; 570 return c->crypto_connections[crypt_connection_id].status;
600 571
601 return CONN_NO_CONNECTION; 572 return CONN_NO_CONNECTION;
602} 573}
603 574
604/* Generate our public and private keys 575/* Generate our public and private keys
605 Only call this function the first time the program starts. */ 576 Only call this function the first time the program starts. */
606void new_keys(void) 577
578extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this
579extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
580
581void new_keys(Net_Crypto *c)
607{ 582{
608 crypto_box_keypair(self_public_key, self_secret_key); 583 crypto_box_keypair(c->self_public_key, c->self_secret_key);
584 memcpy(self_public_key, c->self_public_key, crypto_box_PUBLICKEYBYTES);
585 memcpy(self_secret_key, c->self_secret_key, crypto_box_PUBLICKEYBYTES);
609} 586}
610 587
611/* save the public and private keys to the keys array 588/* save the public and private keys to the keys array
612 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ 589 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
613void save_keys(uint8_t *keys) 590void save_keys(Net_Crypto *c, uint8_t *keys)
614{ 591{
615 memcpy(keys, self_public_key, crypto_box_PUBLICKEYBYTES); 592 memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES);
616 memcpy(keys + crypto_box_PUBLICKEYBYTES, self_secret_key, crypto_box_SECRETKEYBYTES); 593 memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES);
617} 594}
618 595
619/* load the public and private keys from the keys array 596/* load the public and private keys from the keys array
620 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ 597 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
621void load_keys(uint8_t *keys) 598void load_keys(Net_Crypto *c, uint8_t *keys)
622{ 599{
623 memcpy(self_public_key, keys, crypto_box_PUBLICKEYBYTES); 600 memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES);
624 memcpy(self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); 601 memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES);
625} 602}
626 603
627/* TODO: optimize this 604/* TODO: optimize this
628 adds an incoming connection to the incoming_connection list. 605 adds an incoming connection to the incoming_connection list.
629 returns 0 if successful 606 returns 0 if successful
630 returns 1 if failure */ 607 returns 1 if failure */
631static int new_incoming(int id) 608static int new_incoming(Net_Crypto *c, int id)
632{ 609{
633 uint32_t i; 610 uint32_t i;
634 611
635 for (i = 0; i < MAX_INCOMING; ++i) { 612 for (i = 0; i < MAX_INCOMING; ++i) {
636 if (incoming_connections[i] == -1) { 613 if (c->incoming_connections[i] == -1) {
637 incoming_connections[i] = id; 614 c->incoming_connections[i] = id;
638 return 0; 615 return 0;
639 } 616 }
640 } 617 }
@@ -644,81 +621,81 @@ static int new_incoming(int id)
644 621
645/* TODO: optimize this 622/* TODO: optimize this
646 handle all new incoming connections. */ 623 handle all new incoming connections. */
647static void handle_incomings(void) 624static void handle_incomings(Net_Crypto *c)
648{ 625{
649 int income; 626 int income;
650 627
651 while (1) { 628 while (1) {
652 income = incoming_connection(); 629 income = incoming_connection(c->lossless_udp);
653 630
654 if (income == -1 || new_incoming(income) ) 631 if (income == -1 || new_incoming(c, income) )
655 break; 632 break;
656 } 633 }
657} 634}
658 635
659/* handle received packets for not yet established crypto connections. */ 636/* handle received packets for not yet established crypto connections. */
660static void receive_crypto(void) 637static void receive_crypto(Net_Crypto *c)
661{ 638{
662 uint32_t i; 639 uint32_t i;
663 640
664 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 641 for (i = 0; i < c->crypto_connections_length; ++i) {
665 if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) { 642 if (c->crypto_connections[i].status == CONN_HANDSHAKE_SENT) {
666 uint8_t temp_data[MAX_DATA_SIZE]; 643 uint8_t temp_data[MAX_DATA_SIZE];
667 uint8_t secret_nonce[crypto_box_NONCEBYTES]; 644 uint8_t secret_nonce[crypto_box_NONCEBYTES];
668 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 645 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
669 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 646 uint8_t session_key[crypto_box_PUBLICKEYBYTES];
670 uint16_t len; 647 uint16_t len;
671 648
672 if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ 649 if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 2) { /* handle handshake packet. */
673 len = read_packet(crypto_connections[i].number, temp_data); 650 len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data);
674 651
675 if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { 652 if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) {
676 if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { 653 if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
677 memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); 654 memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
678 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); 655 memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
679 increment_nonce(crypto_connections[i].sent_nonce); 656 increment_nonce(c->crypto_connections[i].sent_nonce);
680 uint32_t zero = 0; 657 uint32_t zero = 0;
681 encrypt_precompute(crypto_connections[i].peersessionpublic_key, 658 encrypt_precompute(c->crypto_connections[i].peersessionpublic_key,
682 crypto_connections[i].sessionsecret_key, 659 c->crypto_connections[i].sessionsecret_key,
683 crypto_connections[i].shared_key); 660 c->crypto_connections[i].shared_key);
684 crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ 661 c->crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
685 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); 662 write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero));
686 crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ 663 c->crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */
687 } 664 }
688 } 665 }
689 } else if (id_packet(crypto_connections[i].number) != -1) { // This should not happen kill the connection if it does 666 } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != -1) { // This should not happen kill the connection if it does
690 crypto_kill(crypto_connections[i].number); 667 crypto_kill(c, i);
691 return; 668 return;
692 } 669 }
693 } 670 }
694 671
695 if (crypto_connections[i].status == CONN_NOT_CONFIRMED) { 672 if (c->crypto_connections[i].status == CONN_NOT_CONFIRMED) {
696 if (id_packet(crypto_connections[i].number) == 3) { 673 if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 3) {
697 uint8_t temp_data[MAX_DATA_SIZE]; 674 uint8_t temp_data[MAX_DATA_SIZE];
698 uint8_t data[MAX_DATA_SIZE]; 675 uint8_t data[MAX_DATA_SIZE];
699 int length = read_packet(crypto_connections[i].number, temp_data); 676 int length = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data);
700 int len = decrypt_data(crypto_connections[i].peersessionpublic_key, 677 int len = decrypt_data(c->crypto_connections[i].peersessionpublic_key,
701 crypto_connections[i].sessionsecret_key, 678 c->crypto_connections[i].sessionsecret_key,
702 crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); 679 c->crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data);
703 uint32_t zero = 0; 680 uint32_t zero = 0;
704 681
705 if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { 682 if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
706 increment_nonce(crypto_connections[i].recv_nonce); 683 increment_nonce(c->crypto_connections[i].recv_nonce);
707 encrypt_precompute(crypto_connections[i].peersessionpublic_key, 684 encrypt_precompute(c->crypto_connections[i].peersessionpublic_key,
708 crypto_connections[i].sessionsecret_key, 685 c->crypto_connections[i].sessionsecret_key,
709 crypto_connections[i].shared_key); 686 c->crypto_connections[i].shared_key);
710 crypto_connections[i].status = CONN_ESTABLISHED; 687 c->crypto_connections[i].status = CONN_ESTABLISHED;
711 688
712 /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ 689 /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */
713 kill_connection_in(crypto_connections[i].number, 3000000); 690 kill_connection_in(c->lossless_udp, c->crypto_connections[i].number, 3000000);
714 } else { 691 } else {
715 crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does 692 crypto_kill(c, i); // This should not happen kill the connection if it does
716 return; 693 return;
717 } 694 }
718 } else if (id_packet(crypto_connections[i].number) != -1) 695 } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != -1)
719 /* This should not happen 696 /* This should not happen
720 kill the connection if it does */ 697 kill the connection if it does */
721 crypto_kill(crypto_connections[i].number); 698 crypto_kill(c, i);
722 699
723 return; 700 return;
724 } 701 }
@@ -727,33 +704,52 @@ static void receive_crypto(void)
727 704
728/* run this to (re)initialize net_crypto 705/* run this to (re)initialize net_crypto
729 sets all the global connection variables to their default values. */ 706 sets all the global connection variables to their default values. */
730void initNetCrypto(void) 707Net_Crypto * new_net_crypto(Networking_Core * net)
731{ 708{
732 memset(incoming_connections, -1 , sizeof(incoming_connections)); 709 Net_Crypto * temp = calloc(1, sizeof(Net_Crypto));
733 networking_registerhandler(32, &cryptopacket_handle); 710 if (temp == NULL)
711 return NULL;
712 temp->lossless_udp = new_lossless_udp(net);
713 if (temp->lossless_udp == NULL)
714 return NULL;
715 memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING);
716 //networking_registerhandler(temp, 32, &cryptopacket_handle);
717 networking_registerhandler(net, 32, &cryptopacket_handle, temp);
718 temp_net_crypto = temp; //TODO remove
719 return temp;
734} 720}
735 721
736static void killTimedout(void) 722static void kill_timedout(Net_Crypto *c)
737{ 723{
738 uint32_t i; 724 uint32_t i;
739 725
740 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 726 for (i = 0; i < c->crypto_connections_length; ++i) {
741 if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4) 727 if (c->crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(c->lossless_udp, c->crypto_connections[i].number) == 4)
742 crypto_connections[i].status = CONN_TIMED_OUT; 728 c->crypto_connections[i].status = CONN_TIMED_OUT;
743 else if (is_connected(crypto_connections[i].number) == 4) { 729 else if (is_connected(c->lossless_udp, c->crypto_connections[i].number) == 4) {
744 kill_connection(crypto_connections[i].number); 730 kill_connection(c->lossless_udp, c->crypto_connections[i].number);
745 crypto_connections[i].number = ~0; 731 c->crypto_connections[i].number = ~0;
746 } 732 }
747 } 733 }
748} 734}
749 735
750/* main loop */ 736/* main loop */
751void doNetCrypto(void) 737void do_net_crypto(Net_Crypto *c)
752{ 738{
753 /* TODO:check if friend requests were sent correctly 739 do_lossless_udp(c->lossless_udp);
754 handle new incoming connections 740 handle_incomings(c);
755 handle friend requests */ 741 receive_crypto(c);
756 handle_incomings(); 742 kill_timedout(c);
757 receive_crypto(); 743}
758 killTimedout(); 744
745void kill_net_crypto(Net_Crypto *c)
746{
747 uint32_t i;
748
749 for (i = 0; i < c->crypto_connections_length; ++i) {
750 crypto_kill(c, i);
751 }
752 kill_lossless_udp(c->lossless_udp);
753 memset(c, 0, sizeof(Net_Crypto));
754 free(c);
759} 755}
diff --git a/core/net_crypto.h b/core/net_crypto.h
index 742d9fdc..745f1f14 100644
--- a/core/net_crypto.h
+++ b/core/net_crypto.h
@@ -31,10 +31,47 @@
31extern "C" { 31extern "C" {
32#endif 32#endif
33 33
34/* Our public key. */ 34#define MAX_INCOMING 64
35extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 35
36extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this
36extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 37extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
37 38
39typedef struct {
40 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */
41 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */
42 uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */
43 uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */
44 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */
45 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
46 uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* the precomputed shared key from encrypt_precompute */
47 uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
48 (we have received a handshake but no empty data packet), 3 if the connection is established.
49 4 if the connection is timed out. */
50 uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */
51
52} Crypto_Connection;
53
54typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
55
56typedef struct {
57Lossless_UDP * lossless_udp;
58
59Crypto_Connection *crypto_connections;
60
61uint32_t crypto_connections_length; /* Length of connections array */
62
63/* Our public and secret keys. */
64uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
65uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
66
67/* keeps track of the connection numbers for friends request so we can check later if they were sent */
68int incoming_connections[MAX_INCOMING];
69
70cryptopacket_handler_callback cryptopackethandlers[256];
71} Net_Crypto;
72
73Net_Crypto * temp_net_crypto; //TODO: remove this
74
38#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 75#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
39 76
40/* returns zero if the buffer contains only zeros */ 77/* returns zero if the buffer contains only zeros */
@@ -75,34 +112,35 @@ void random_nonce(uint8_t *nonce);
75/* return 0 if there is no received data in the buffer 112/* return 0 if there is no received data in the buffer
76 return -1 if the packet was discarded. 113 return -1 if the packet was discarded.
77 return length of received data if successful */ 114 return length of received data if successful */
78int read_cryptpacket(int crypt_connection_id, uint8_t *data); 115int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data);
79 116
80/* return 0 if data could not be put in packet queue 117/* return 0 if data could not be put in packet queue
81 return 1 if data was put into the queue */ 118 return 1 if data was put into the queue */
82int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length); 119int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length);
83 120
84/* create a request to peer with public_key. 121/* create a request to peer.
85 packet must be an array of MAX_DATA_SIZE big. 122 send_public_key and send_secret_key are the pub/secret keys of the sender
86 Data represents the data we send with the request with length being the length of the data. 123 recv_public_key is public key of reciever
87 request_id is the id of the request (32 = friend request, 254 = ping request) 124 packet must be an array of MAX_DATA_SIZE big.
88 returns -1 on failure 125 Data represents the data we send with the request with length being the length of the data.
89 returns the length of the created packet on success */ 126 request_id is the id of the request (32 = friend request, 254 = ping request)
90int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id); 127 returns -1 on failure
128 returns the length of the created packet on success */
129int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, uint8_t *data, uint32_t length, uint8_t request_id);
91 130
92 131
93typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
94/* Function to call when request beginning with byte is received */ 132/* Function to call when request beginning with byte is received */
95void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb); 133void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb);
96 134
97/* Start a secure connection with other peer who has public_key and ip_port 135/* Start a secure connection with other peer who has public_key and ip_port
98 returns -1 if failure 136 returns -1 if failure
99 returns crypt_connection_id of the initialized connection if everything went well. */ 137 returns crypt_connection_id of the initialized connection if everything went well. */
100int crypto_connect(uint8_t *public_key, IP_Port ip_port); 138int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port);
101 139
102/* kill a crypto connection 140/* kill a crypto connection
103 return 0 if killed successfully 141 return 0 if killed successfully
104 return 1 if there was a problem. */ 142 return 1 if there was a problem. */
105int crypto_kill(int crypt_connection_id); 143int crypto_kill(Net_Crypto *c, int crypt_connection_id);
106 144
107/* handle an incoming connection 145/* handle an incoming connection
108 return -1 if no crypto inbound connection 146 return -1 if no crypto inbound connection
@@ -111,37 +149,39 @@ int crypto_kill(int crypt_connection_id);
111 and the session public key for the connection in session_key 149 and the session public key for the connection in session_key
112 to accept it see: accept_crypto_inbound(...) 150 to accept it see: accept_crypto_inbound(...)
113 to refuse it just call kill_connection(...) on the connection id */ 151 to refuse it just call kill_connection(...) on the connection id */
114int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key); 152int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key);
115 153
116/* accept an incoming connection using the parameters provided by crypto_inbound 154/* accept an incoming connection using the parameters provided by crypto_inbound
117 return -1 if not successful 155 return -1 if not successful
118 returns the crypt_connection_id if successful */ 156 returns the crypt_connection_id if successful */
119int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key); 157int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key);
120 158
121/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet 159/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
122 (we have received a handshake but no empty data packet), 3 if the connection is established. 160 (we have received a handshake but no empty data packet), 3 if the connection is established.
123 4 if the connection is timed out and waiting to be killed */ 161 4 if the connection is timed out and waiting to be killed */
124int is_cryptoconnected(int crypt_connection_id); 162int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id);
125 163
126 164
127/* Generate our public and private keys 165/* Generate our public and private keys
128 Only call this function the first time the program starts. */ 166 Only call this function the first time the program starts. */
129void new_keys(void); 167void new_keys(Net_Crypto *c);
130 168
131/* save the public and private keys to the keys array 169/* save the public and private keys to the keys array
132 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ 170 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
133void save_keys(uint8_t *keys); 171void save_keys(Net_Crypto *c, uint8_t *keys);
134 172
135/* load the public and private keys from the keys array 173/* load the public and private keys from the keys array
136 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ 174 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
137void load_keys(uint8_t *keys); 175void load_keys(Net_Crypto *c, uint8_t *keys);
138 176
139/* run this to (re)initialize net_crypto 177/* create new instance of Net_Crypto
140 sets all the global connection variables to their default values. */ 178 sets all the global connection variables to their default values. */
141void initNetCrypto(void); 179Net_Crypto * new_net_crypto(Networking_Core * net);
142 180
143/* main loop */ 181/* main loop */
144void doNetCrypto(void); 182void do_net_crypto(Net_Crypto *c);
183
184void kill_net_crypto(Net_Crypto *c);
145 185
146#ifdef __cplusplus 186#ifdef __cplusplus
147} 187}
diff --git a/core/network.c b/core/network.c
index 1977ce38..684a4227 100644
--- a/core/network.c
+++ b/core/network.c
@@ -56,12 +56,9 @@ uint32_t random_int(void)
56#endif 56#endif
57} 57}
58 58
59/* our UDP socket, a global variable. */
60static int sock;
61
62/* Basic network functions: 59/* Basic network functions:
63 Function to send packet(data) of length length to ip_port */ 60 Function to send packet(data) of length length to ip_port */
64int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length) 61int sendpacket(int sock, IP_Port ip_port, uint8_t *data, uint32_t length)
65{ 62{
66 ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; 63 ADDR addr = {AF_INET, ip_port.port, ip_port.ip};
67 return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); 64 return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr));
@@ -71,7 +68,7 @@ int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length)
71 the packet data into data 68 the packet data into data
72 the packet length into length. 69 the packet length into length.
73 dump all empty packets. */ 70 dump all empty packets. */
74static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length) 71static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
75{ 72{
76 ADDR addr; 73 ADDR addr;
77#ifdef WIN32 74#ifdef WIN32
@@ -89,36 +86,32 @@ static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length)
89 return 0; 86 return 0;
90} 87}
91 88
92static packet_handler_callback packethandlers[256] = {0}; 89void networking_registerhandler(Networking_Core * net, uint8_t byte, packet_handler_callback cb, void * object)
93
94void networking_registerhandler(uint8_t byte, packet_handler_callback cb)
95{ 90{
96 packethandlers[byte] = cb; 91 net->packethandlers[byte].function = cb;
92 net->packethandlers[byte].object = object;
97} 93}
98 94
99void networking_poll() 95void networking_poll(Networking_Core * net)
100{ 96{
101 IP_Port ip_port; 97 IP_Port ip_port;
102 uint8_t data[MAX_UDP_PACKET_SIZE]; 98 uint8_t data[MAX_UDP_PACKET_SIZE];
103 uint32_t length; 99 uint32_t length;
104 100
105 while (receivepacket(&ip_port, data, &length) != -1) { 101 while (receivepacket(net->sock, &ip_port, data, &length) != -1) {
106 if (length < 1) continue; 102 if (length < 1) continue;
107 103
108 if (!packethandlers[data[0]]) continue; 104 if (!(net->packethandlers[data[0]].function)) continue;
109 105
110 packethandlers[data[0]](ip_port, data, length); 106 net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length);
111 } 107 }
112} 108}
113 109
114/* initialize networking 110uint8_t at_startup_ran;
115 bind to ip and port 111static void at_startup(void)
116 ip must be in network order EX: 127.0.0.1 = (7F000001)
117 port is in host byte order (this means don't worry about it)
118 returns 0 if no problems
119 returns -1 if there are problems */
120int init_networking(IP ip, uint16_t port)
121{ 112{
113 if (at_startup_ran != 0)
114 return;
122#ifdef WIN32 115#ifdef WIN32
123 WSADATA wsaData; 116 WSADATA wsaData;
124 117
@@ -128,21 +121,48 @@ int init_networking(IP ip, uint16_t port)
128#else 121#else
129 srandom((uint32_t)current_time()); 122 srandom((uint32_t)current_time());
130#endif 123#endif
131 srand((uint32_t)current_time()); 124 srand((uint32_t)current_time());
125 at_startup_ran = 1;
126}
127
128/* TODO: put this somewhere
129static void at_shutdown(void)
130{
131#ifdef WIN32
132 WSACleanup();
133#endif
134}
135*/
132 136
137/* initialize networking
138 bind to ip and port
139 ip must be in network order EX: 127.0.0.1 = (7F000001)
140 port is in host byte order (this means don't worry about it)
141 returns Networking_Core object if no problems
142 returns NULL if there are problems */
143Networking_Core * new_networking(IP ip, uint16_t port)
144{
145 at_startup();
133 /* initialize our socket */ 146 /* initialize our socket */
134 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 147 Networking_Core * temp = calloc(1, sizeof(Networking_Core));
148 if (temp == NULL)
149 return NULL;
150 temp->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
135 151
136 /* Check for socket error */ 152 /* Check for socket error */
137#ifdef WIN32 153#ifdef WIN32
138 154
139 if (sock == INVALID_SOCKET) /* MSDN recommends this */ 155 if (temp->sock == INVALID_SOCKET) { /* MSDN recommends this */
140 return -1; 156 free(temp);
157 return NULL;
158 }
141 159
142#else 160#else
143 161
144 if (sock < 0) 162 if (temp->sock < 0) {
145 return -1; 163 free(temp);
164 return NULL;
165 }
146 166
147#endif 167#endif
148 168
@@ -161,34 +181,34 @@ int init_networking(IP ip, uint16_t port)
161 181
162 /* Enable broadcast on socket */ 182 /* Enable broadcast on socket */
163 int broadcast = 1; 183 int broadcast = 1;
164 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); 184 setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast));
165 185
166 /* Set socket nonblocking */ 186 /* Set socket nonblocking */
167#ifdef WIN32 187#ifdef WIN32
168 /* I think this works for windows */ 188 /* I think this works for windows */
169 u_long mode = 1; 189 u_long mode = 1;
170 /* ioctl(sock, FIONBIO, &mode); */ 190 /* ioctl(sock, FIONBIO, &mode); */
171 ioctlsocket(sock, FIONBIO, &mode); 191 ioctlsocket(temp->sock, FIONBIO, &mode);
172#else 192#else
173 fcntl(sock, F_SETFL, O_NONBLOCK, 1); 193 fcntl(temp->sock, F_SETFL, O_NONBLOCK, 1);
174#endif 194#endif
175 195
176 /* Bind our socket to port PORT and address 0.0.0.0 */ 196 /* Bind our socket to port PORT and address 0.0.0.0 */
177 ADDR addr = {AF_INET, htons(port), ip}; 197 ADDR addr = {AF_INET, htons(port), ip};
178 bind(sock, (struct sockaddr *)&addr, sizeof(addr)); 198 bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr));
179 199 temp_net = temp;
180 return 0; 200 return temp;
181} 201}
182 202
183/* function to cleanup networking stuff */ 203/* function to cleanup networking stuff */
184void shutdown_networking(void) 204void kill_networking(Networking_Core * net)
185{ 205{
186#ifdef WIN32 206#ifdef WIN32
187 closesocket(sock); 207 closesocket(net->sock);
188 WSACleanup();
189#else 208#else
190 close(sock); 209 close(net->sock);
191#endif 210#endif
211 free(net);
192 return; 212 return;
193} 213}
194 214
diff --git a/core/network.h b/core/network.h
index 127a55d1..5ed25620 100644
--- a/core/network.h
+++ b/core/network.h
@@ -99,8 +99,20 @@ typedef struct {
99/* Function to receive data, ip and port of sender is put into ip_port 99/* Function to receive data, ip and port of sender is put into ip_port
100 the packet data into data 100 the packet data into data
101 the packet length into length. */ 101 the packet length into length. */
102typedef int (*packet_handler_callback)(IP_Port ip_port, uint8_t *data, uint32_t len); 102typedef int (*packet_handler_callback)(void * object, IP_Port ip_port, uint8_t *data, uint32_t len);
103 103
104typedef struct {
105 packet_handler_callback function;
106 void * object;
107}Packet_Handles;
108
109typedef struct {
110 Packet_Handles packethandlers[256];
111 /* our UDP socket */
112 int sock;
113}Networking_Core;
114
115Networking_Core * temp_net;
104/* returns current time in milleseconds since the epoch. */ 116/* returns current time in milleseconds since the epoch. */
105uint64_t current_time(void); 117uint64_t current_time(void);
106 118
@@ -111,13 +123,13 @@ uint32_t random_int(void);
111/* Basic network functions: */ 123/* Basic network functions: */
112 124
113/* Function to send packet(data) of length length to ip_port */ 125/* Function to send packet(data) of length length to ip_port */
114int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length); 126int sendpacket(int sock, IP_Port ip_port, uint8_t *data, uint32_t length);
115 127
116/* Function to call when packet beginning with byte is received */ 128/* Function to call when packet beginning with byte is received */
117void networking_registerhandler(uint8_t byte, packet_handler_callback cb); 129void networking_registerhandler(Networking_Core * net, uint8_t byte, packet_handler_callback cb, void * object);
118 130
119/* call this several times a second */ 131/* call this several times a second */
120void networking_poll(); 132void networking_poll(Networking_Core * net);
121 133
122/* initialize networking 134/* initialize networking
123 bind to ip and port 135 bind to ip and port
@@ -125,10 +137,10 @@ void networking_poll();
125 port is in host byte order (this means don't worry about it) 137 port is in host byte order (this means don't worry about it)
126 returns 0 if no problems 138 returns 0 if no problems
127 returns -1 if there were problems */ 139 returns -1 if there were problems */
128int init_networking(IP ip, uint16_t port); 140Networking_Core * new_networking(IP ip, uint16_t port);
129 141
130/* function to cleanup networking stuff(doesn't do much right now) */ 142/* function to cleanup networking stuff(doesn't do much right now) */
131void shutdown_networking(void); 143void kill_networking(Networking_Core * net);
132 144
133/* 145/*
134 resolve_addr(): 146 resolve_addr():
diff --git a/core/ping.c b/core/ping.c
index 47d6e163..d2b290a0 100644
--- a/core/ping.c
+++ b/core/ping.c
@@ -135,7 +135,7 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id)
135 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 135 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
136 return 1; 136 return 1;
137 137
138 return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk)); 138 return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
139} 139}
140 140
141int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) 141int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
@@ -160,10 +160,10 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
160 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 160 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
161 return 1; 161 return 1;
162 162
163 return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk)); 163 return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
164} 164}
165 165
166int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length) 166int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length)
167{ 167{
168 pingreq_t *p = (pingreq_t *) packet; 168 pingreq_t *p = (pingreq_t *) packet;
169 int rc; 169 int rc;
@@ -190,7 +190,7 @@ int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length)
190 return 0; 190 return 0;
191} 191}
192 192
193int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length) 193int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length)
194{ 194{
195 pingres_t *p = (pingres_t *) packet; 195 pingres_t *p = (pingres_t *) packet;
196 int rc; 196 int rc;
diff --git a/core/ping.h b/core/ping.h
index 0c44874b..6d5a0ea6 100644
--- a/core/ping.h
+++ b/core/ping.h
@@ -12,5 +12,5 @@ uint64_t add_ping(IP_Port ipp);
12bool is_pinging(IP_Port ipp, uint64_t ping_id); 12bool is_pinging(IP_Port ipp, uint64_t ping_id);
13int send_ping_request(IP_Port ipp, clientid_t *client_id); 13int send_ping_request(IP_Port ipp, clientid_t *client_id);
14int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id); 14int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id);
15int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length); 15int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length);
16int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length); 16int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length);