diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/net_crypto.c | 34 | ||||
-rw-r--r-- | core/network.h | 197 |
2 files changed, 97 insertions, 134 deletions
diff --git a/core/net_crypto.c b/core/net_crypto.c index c819c8c4..b3c752e0 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -39,11 +39,11 @@ typedef struct | |||
39 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ | 39 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ |
40 | uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */ | 40 | uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */ |
41 | uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ | 41 | uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ |
42 | uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES];our private key for this session. | 42 | uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */ |
43 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ | 43 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ |
44 | uint8_t status;/* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | 44 | uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet |
45 | (we have received a handshake but no empty data packet), 3 if the connection is established. | 45 | (we have received a handshake but no empty data packet), 3 if the connection is established. |
46 | 4 if the connection is timed out. */ | 46 | 4 if the connection is timed out. */ |
47 | uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ | 47 | uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ |
48 | 48 | ||
49 | }Crypto_Connection; | 49 | }Crypto_Connection; |
@@ -65,7 +65,7 @@ static int incoming_connections[MAX_INCOMING]; | |||
65 | /* encrypts plain of length length to encrypted of length + 16 using the | 65 | /* encrypts plain of length length to encrypted of length + 16 using the |
66 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce | 66 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce |
67 | return -1 if there was a problem. | 67 | return -1 if there was a problem. |
68 | return length of encrypted data if everything was fine. */ | 68 | return length of encrypted data if everything was fine. */ |
69 | int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, | 69 | int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, |
70 | uint8_t * plain, uint32_t length, uint8_t * encrypted) | 70 | uint8_t * plain, uint32_t length, uint8_t * encrypted) |
71 | { | 71 | { |
@@ -128,9 +128,9 @@ int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, | |||
128 | void increment_nonce(uint8_t * nonce) | 128 | void increment_nonce(uint8_t * nonce) |
129 | { | 129 | { |
130 | uint32_t i; | 130 | uint32_t i; |
131 | for(i = 0; i < crypto_box_NONCEBYTES; ++i) | 131 | for(i = 0; i < crypto_box_NONCEBYTES; i++) |
132 | { | 132 | { |
133 | ++nonce[i]; | 133 | nonce[i]++; |
134 | if(nonce[i] != 0) | 134 | if(nonce[i] != 0) |
135 | { | 135 | { |
136 | break; | 136 | break; |
@@ -143,7 +143,7 @@ void increment_nonce(uint8_t * nonce) | |||
143 | void random_nonce(uint8_t * nonce) | 143 | void random_nonce(uint8_t * nonce) |
144 | { | 144 | { |
145 | uint32_t i; | 145 | uint32_t i; |
146 | for(i = 0; i < crypto_box_NONCEBYTES; ++i) | 146 | for(i = 0; i < crypto_box_NONCEBYTES; i++) |
147 | { | 147 | { |
148 | nonce[i] = random_int() % 256; | 148 | nonce[i] = random_int() % 256; |
149 | } | 149 | } |
@@ -228,7 +228,7 @@ int send_friendrequest(uint8_t * public_key, IP_Port ip_port, uint8_t * data, ui | |||
228 | return -1; | 228 | return -1; |
229 | } | 229 | } |
230 | uint32_t i; | 230 | uint32_t i; |
231 | for(i = 0; i < MAX_FRIEND_REQUESTS; ++i) | 231 | for(i = 0; i < MAX_FRIEND_REQUESTS; i++) |
232 | { | 232 | { |
233 | if(outbound_friendrequests[i] == -1) | 233 | if(outbound_friendrequests[i] == -1) |
234 | { | 234 | { |
@@ -365,7 +365,7 @@ int handle_cryptohandshake(uint8_t * public_key, uint8_t * secret_nonce, | |||
365 | int handle_friendrequest(uint8_t * public_key, uint8_t * data) | 365 | int handle_friendrequest(uint8_t * public_key, uint8_t * data) |
366 | { | 366 | { |
367 | uint32_t i; | 367 | uint32_t i; |
368 | for(i = 0; i < MAX_INCOMING; ++i) | 368 | for(i = 0; i < MAX_INCOMING; i++) |
369 | { | 369 | { |
370 | if(incoming_connections[i] != -1) | 370 | if(incoming_connections[i] != -1) |
371 | { | 371 | { |
@@ -403,7 +403,7 @@ int handle_friendrequest(uint8_t * public_key, uint8_t * data) | |||
403 | int getcryptconnection_id(uint8_t * public_key) | 403 | int getcryptconnection_id(uint8_t * public_key) |
404 | { | 404 | { |
405 | uint32_t i; | 405 | uint32_t i; |
406 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) | 406 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) |
407 | { | 407 | { |
408 | if(crypto_connections[i].status > 0) | 408 | if(crypto_connections[i].status > 0) |
409 | { | 409 | { |
@@ -432,7 +432,7 @@ int crypto_connect(uint8_t * public_key, IP_Port ip_port) | |||
432 | return -1; | 432 | return -1; |
433 | } | 433 | } |
434 | } | 434 | } |
435 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) | 435 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) |
436 | { | 436 | { |
437 | if(crypto_connections[i].status == 0) | 437 | if(crypto_connections[i].status == 0) |
438 | { | 438 | { |
@@ -469,7 +469,7 @@ int crypto_connect(uint8_t * public_key, IP_Port ip_port) | |||
469 | int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * session_key) | 469 | int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * session_key) |
470 | { | 470 | { |
471 | uint32_t i; | 471 | uint32_t i; |
472 | for(i = 0; i < MAX_INCOMING; ++i) | 472 | for(i = 0; i < MAX_INCOMING; i++) |
473 | { | 473 | { |
474 | if(incoming_connections[i] != -1) | 474 | if(incoming_connections[i] != -1) |
475 | { | 475 | { |
@@ -530,7 +530,7 @@ int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * sec | |||
530 | { | 530 | { |
531 | return -1; | 531 | return -1; |
532 | }*/ | 532 | }*/ |
533 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) | 533 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) |
534 | { | 534 | { |
535 | if(crypto_connections[i].status == 0) | 535 | if(crypto_connections[i].status == 0) |
536 | { | 536 | { |
@@ -603,7 +603,7 @@ void load_keys(uint8_t * keys) | |||
603 | int new_incoming(int id) | 603 | int new_incoming(int id) |
604 | { | 604 | { |
605 | uint32_t i; | 605 | uint32_t i; |
606 | for(i = 0; i < MAX_INCOMING; ++i) | 606 | for(i = 0; i < MAX_INCOMING; i++) |
607 | { | 607 | { |
608 | if(incoming_connections[i] == -1) | 608 | if(incoming_connections[i] == -1) |
609 | { | 609 | { |
@@ -633,7 +633,7 @@ static void handle_incomings() | |||
633 | static void receive_crypto() | 633 | static void receive_crypto() |
634 | { | 634 | { |
635 | uint32_t i; | 635 | uint32_t i; |
636 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) | 636 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) |
637 | { | 637 | { |
638 | if(crypto_connections[i].status == 1) | 638 | if(crypto_connections[i].status == 1) |
639 | { | 639 | { |
@@ -717,7 +717,7 @@ void initNetCrypto() | |||
717 | memset(outbound_friendrequests, -1 ,sizeof(outbound_friendrequests)); | 717 | memset(outbound_friendrequests, -1 ,sizeof(outbound_friendrequests)); |
718 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); | 718 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); |
719 | uint32_t i; | 719 | uint32_t i; |
720 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) | 720 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) |
721 | { | 721 | { |
722 | crypto_connections[i].number = ~0; | 722 | crypto_connections[i].number = ~0; |
723 | } | 723 | } |
diff --git a/core/network.h b/core/network.h index 8f88940c..fe0c48eb 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* network.h | 1 | /* network.h |
2 | * | 2 | * |
3 | * Functions for the core networking. | 3 | * Datatypes, functions and includes for the core networking. |
4 | * | 4 | * |
5 | 5 | ||
6 | Copyright (C) 2013 Tox project All Rights Reserved. | 6 | Copyright (C) 2013 Tox project All Rights Reserved. |
@@ -21,81 +21,94 @@ | |||
21 | along with Tox. If not, see <http://www.gnu.org/licenses/>. | 21 | along with Tox. If not, see <http://www.gnu.org/licenses/>. |
22 | 22 | ||
23 | */ | 23 | */ |
24 | |||
25 | |||
26 | #ifndef NETWORK_H | ||
27 | #define NETWORK_H | ||
28 | |||
29 | #include <stdlib.h> | ||
30 | #include <stdio.h> | ||
31 | #include <stdint.h> | ||
32 | #include <string.h> | ||
33 | #include <time.h> | ||
34 | |||
35 | |||
36 | |||
37 | #ifdef WIN32 /* Put win32 includes here */ | ||
38 | |||
39 | #include <winsock2.h> | ||
40 | #include <windows.h> | ||
41 | |||
42 | #undef VANILLA_NACL /* make sure on windows we use libsodium */ | ||
43 | |||
44 | #else //Linux includes | ||
45 | |||
46 | #include <fcntl.h> | ||
47 | #include <sys/socket.h> | ||
48 | #include <netinet/in.h> | ||
49 | #include <errno.h> | ||
50 | #include <sys/time.h> | ||
24 | 51 | ||
25 | #include "network.h" | ||
26 | 52 | ||
53 | #endif | ||
27 | 54 | ||
28 | /* returns current UNIX time in microseconds (us). */ | 55 | #ifndef VANILLA_NACL |
29 | uint64_t current_time() | 56 | /* we use libsodium by default */ |
57 | #include <sodium.h> | ||
58 | #else | ||
59 | |||
60 | /* TODO: Including stuff like this is bad. This needs fixing. | ||
61 | We keep support for the original NaCl for now. */ | ||
62 | #include "../nacl/build/Linux/include/amd64/crypto_box.h" | ||
63 | |||
64 | #endif | ||
65 | |||
66 | |||
67 | #define MAX_UDP_PACKET_SIZE 65507 | ||
68 | |||
69 | typedef union | ||
30 | { | 70 | { |
31 | uint64_t time; | 71 | uint8_t c[4]; |
32 | #ifdef WIN32 | 72 | uint16_t s[2]; |
33 | /* This probably works fine */ | 73 | uint32_t i; |
34 | FILETIME ft; | 74 | }IP; |
35 | GetSystemTimeAsFileTime(&ft); | 75 | |
36 | time = ft.dwHighDateTime; | 76 | typedef struct |
37 | time <<=32; | 77 | { |
38 | time |= ft.dwLowDateTime; | 78 | IP ip; |
39 | time -= 116444736000000000UL; | 79 | uint16_t port; |
40 | return time/10; | 80 | /* not used for anything right now */ |
41 | #else | 81 | uint16_t padding; |
42 | struct timeval a; | 82 | }IP_Port; |
43 | gettimeofday(&a, NULL); | 83 | |
44 | time = 1000000UL*a.tv_sec + a.tv_usec; | 84 | typedef struct |
45 | return time; | 85 | { |
86 | int16_t family; | ||
87 | uint16_t port; | ||
88 | IP ip; | ||
89 | uint8_t zeroes[8]; | ||
90 | #ifdef ENABLE_IPV6 | ||
91 | uint8_t zeroes2[12]; | ||
46 | #endif | 92 | #endif |
47 | 93 | }ADDR; | |
48 | 94 | ||
49 | } | 95 | |
96 | /* returns current time in milleseconds since the epoch. */ | ||
97 | uint64_t current_time(); | ||
50 | 98 | ||
51 | /* return a random number | 99 | /* return a random number |
52 | NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */ | 100 | NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */ |
53 | uint32_t random_int() | 101 | uint32_t random_int(); |
54 | { | ||
55 | #ifndef VANILLA_NACL | ||
56 | /* NOTE: this function comes from libsodium */ | ||
57 | return randombytes_random(); | ||
58 | #else | ||
59 | return random(); | ||
60 | #endif | ||
61 | } | ||
62 | 102 | ||
63 | /* our UDP socket, a global variable. */ | 103 | /* Basic network functions: */ |
64 | static int sock; | ||
65 | 104 | ||
66 | /* Basic network functions: | 105 | /* Function to send packet(data) of length length to ip_port */ |
67 | Function to send packet(data) of length length to ip_port */ | 106 | int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length); |
68 | int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) | ||
69 | { | ||
70 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; | ||
71 | return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); | ||
72 | |||
73 | } | ||
74 | 107 | ||
75 | /* Function to receive data, ip and port of sender is put into ip_port | 108 | /* Function to receive data, ip and port of sender is put into ip_port |
76 | the packet data into data | 109 | the packet data into data |
77 | the packet length into length. | 110 | the packet length into length. */ |
78 | dump all empty packets. */ | 111 | int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length); |
79 | int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) | ||
80 | { | ||
81 | ADDR addr; | ||
82 | #ifdef WIN32 | ||
83 | int addrlen = sizeof(addr); | ||
84 | #else | ||
85 | uint32_t addrlen = sizeof(addr); | ||
86 | #endif | ||
87 | (*(int32_t *)length) = recvfrom(sock,(char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); | ||
88 | if(*(int32_t *)length <= 0) | ||
89 | { | ||
90 | /* nothing received | ||
91 | or empty packet */ | ||
92 | return -1; | ||
93 | } | ||
94 | ip_port->ip = addr.ip; | ||
95 | ip_port->port = addr.port; | ||
96 | return 0; | ||
97 | |||
98 | } | ||
99 | 112 | ||
100 | /* initialize networking | 113 | /* initialize networking |
101 | bind to ip and port | 114 | bind to ip and port |
@@ -103,59 +116,9 @@ int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) | |||
103 | port is in host byte order (this means don't worry about it) | 116 | port is in host byte order (this means don't worry about it) |
104 | returns 0 if no problems | 117 | returns 0 if no problems |
105 | TODO: add something to check if there are errors */ | 118 | TODO: add something to check if there are errors */ |
106 | int init_networking(IP ip ,uint16_t port) | 119 | int init_networking(IP ip ,uint16_t port); |
107 | { | ||
108 | #ifdef WIN32 | ||
109 | WSADATA wsaData; | ||
110 | if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) | ||
111 | { | ||
112 | return -1; | ||
113 | } | ||
114 | |||
115 | #else | ||
116 | srandom((uint32_t)current_time()); | ||
117 | #endif | ||
118 | srand((uint32_t)current_time()); | ||
119 | |||
120 | /* initialize our socket */ | ||
121 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||
122 | |||
123 | /* Functions to increase the size of the send and receive UDP buffers | ||
124 | NOTE: uncomment if necessary | ||
125 | |||
126 | int n = 1024 * 1024 * 2; | ||
127 | if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&n, sizeof(n)) == -1) | ||
128 | { | ||
129 | return -1; | ||
130 | } | ||
131 | |||
132 | if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&n, sizeof(n)) == -1) | ||
133 | { | ||
134 | return -1; | ||
135 | }*/ | ||
136 | |||
137 | /*Set socket nonblocking */ | ||
138 | #ifdef WIN32 | ||
139 | /* I think this works for windows */ | ||
140 | u_long mode = 1; | ||
141 | /* ioctl(sock, FIONBIO, &mode); */ | ||
142 | ioctlsocket(sock, FIONBIO, &mode); | ||
143 | #else | ||
144 | fcntl(sock, F_SETFL, O_NONBLOCK, 1); | ||
145 | #endif | ||
146 | |||
147 | /* Bind our socket to port PORT and address 0.0.0.0 */ | ||
148 | ADDR addr = {AF_INET, htons(port), ip}; | ||
149 | bind(sock, (struct sockaddr*)&addr, sizeof(addr)); | ||
150 | return 0; | ||
151 | 120 | ||
152 | } | ||
153 | 121 | ||
154 | /* function to cleanup networking stuff */ | 122 | /* function to cleanup networking stuff(doesn't do much right now) */ |
155 | void shutdown_networking() | 123 | void shutdown_networking(); |
156 | { | 124 | #endif |
157 | #ifdef WIN32 | ||
158 | WSACleanup(); | ||
159 | #endif | ||
160 | return; | ||
161 | } | ||