diff options
Diffstat (limited to 'core/network.h')
-rw-r--r-- | core/network.h | 215 |
1 files changed, 126 insertions, 89 deletions
diff --git a/core/network.h b/core/network.h index 33f11239..8f88940c 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* network.h | 1 | /* network.h |
2 | * | 2 | * |
3 | * Datatypes, functions and includes for the core networking. | 3 | * Functions 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,104 +21,141 @@ | |||
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> | ||
51 | 24 | ||
25 | #include "network.h" | ||
52 | 26 | ||
53 | #endif | ||
54 | 27 | ||
55 | #ifndef VANILLA_NACL | 28 | /* returns current UNIX time in microseconds (us). */ |
56 | //we use libsodium by default | 29 | uint64_t current_time() |
57 | #include <sodium.h> | 30 | { |
58 | #else | 31 | uint64_t time; |
59 | 32 | #ifdef WIN32 | |
60 | //TODO: Including stuff like this is bad. This needs fixing. | 33 | /* This probably works fine */ |
61 | //We keep support for the original NaCl for now. | 34 | FILETIME ft; |
62 | #include "../nacl/build/Linux/include/amd64/crypto_box.h" | 35 | GetSystemTimeAsFileTime(&ft); |
63 | 36 | time = ft.dwHighDateTime; | |
64 | #endif | 37 | time <<=32; |
38 | time |= ft.dwLowDateTime; | ||
39 | time -= 116444736000000000UL; | ||
40 | return time/10; | ||
41 | #else | ||
42 | struct timeval a; | ||
43 | gettimeofday(&a, NULL); | ||
44 | time = 1000000UL*a.tv_sec + a.tv_usec; | ||
45 | return time; | ||
46 | #endif | ||
47 | |||
48 | |||
49 | } | ||
65 | 50 | ||
51 | /* return a random number | ||
52 | NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */ | ||
53 | 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 | } | ||
66 | 62 | ||
67 | #define MAX_UDP_PACKET_SIZE 65507 | 63 | /* our UDP socket, a global variable. */ |
64 | static int sock; | ||
68 | 65 | ||
69 | typedef union | 66 | /* Basic network functions: |
67 | Function to send packet(data) of length length to ip_port */ | ||
68 | int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) | ||
70 | { | 69 | { |
71 | uint8_t c[4]; | 70 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; |
72 | uint16_t s[2]; | 71 | return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); |
73 | uint32_t i; | 72 | |
74 | }IP; | 73 | } |
75 | 74 | ||
76 | typedef struct | 75 | /* Function to receive data, ip and port of sender is put into ip_port |
76 | the packet data into data | ||
77 | the packet length into length. | ||
78 | dump all empty packets. */ | ||
79 | int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) | ||
77 | { | 80 | { |
78 | IP ip; | 81 | ADDR addr; |
79 | uint16_t port; | 82 | #ifdef WIN32 |
80 | //not used for anything right now | 83 | int addrlen = sizeof(addr); |
81 | uint16_t padding; | 84 | #else |
82 | }IP_Port; | 85 | uint32_t addrlen = sizeof(addr); |
83 | 86 | #endif | |
84 | typedef struct | 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 | |||
100 | /* initialize networking | ||
101 | bind to ip and port | ||
102 | ip must be in network order EX: 127.0.0.1 = (7F000001) | ||
103 | port is in host byte order (this means don't worry about it) | ||
104 | returns 0 if no problems | ||
105 | TODO: add something to check if there are errors */ | ||
106 | int init_networking(IP ip ,uint16_t port) | ||
85 | { | 107 | { |
86 | int16_t family; | 108 | #ifdef WIN32 |
87 | uint16_t port; | 109 | WSADATA wsaData; |
88 | IP ip; | 110 | if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) |
89 | uint8_t zeroes[8]; | 111 | { |
90 | #ifdef ENABLE_IPV6 | 112 | return -1; |
91 | uint8_t zeroes2[12]; | 113 | } |
114 | |||
115 | #else | ||
116 | srandom((uint32_t)current_time()); | ||
92 | #endif | 117 | #endif |
93 | }ADDR; | 118 | srand((uint32_t)current_time()); |
94 | 119 | ||
95 | 120 | /* initialize our socket */ | |
96 | //returns current time in milleseconds since the epoch. | 121 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
97 | uint64_t current_time(); | 122 | |
98 | 123 | /* Functions to increase the size of the send and receive UDP buffers | |
99 | //return a random number | 124 | NOTE: uncomment if necessary |
100 | //NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary | 125 | |
101 | uint32_t random_int(); | 126 | int n = 1024 * 1024 * 2; |
102 | 127 | if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&n, sizeof(n)) == -1) | |
103 | //Basic network functions: | 128 | { |
104 | 129 | return -1; | |
105 | //Function to send packet(data) of length length to ip_port | 130 | } |
106 | int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length); | 131 | |
107 | 132 | if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&n, sizeof(n)) == -1) | |
108 | //Function to receive data, ip and port of sender is put into ip_port | 133 | { |
109 | //the packet data into data | 134 | return -1; |
110 | //the packet length into length. | 135 | }*/ |
111 | int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length); | 136 | |
112 | 137 | /*Set socket nonblocking */ | |
113 | //initialize networking | 138 | #ifdef WIN32 |
114 | //bind to ip and port | 139 | /* I think this works for windows */ |
115 | //ip must be in network order EX: 127.0.0.1 = (7F000001) | 140 | u_long mode = 1; |
116 | //port is in host byte order (this means don't worry about it) | 141 | /* ioctl(sock, FIONBIO, &mode); */ |
117 | //returns 0 if no problems | 142 | ioctlsocket(sock, FIONBIO, &mode); |
118 | //TODO: add something to check if there are errors | 143 | #else |
119 | int init_networking(IP ip ,uint16_t port); | 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; | ||
120 | 151 | ||
152 | } | ||
121 | 153 | ||
122 | //function to cleanup networking stuff(doesn't do much right now) | 154 | /* function to cleanup networking stuff */ |
123 | void shutdown_networking(); | 155 | void shutdown_networking() |
124 | #endif | 156 | { |
157 | #ifdef WIN32 | ||
158 | WSACleanup(); | ||
159 | #endif | ||
160 | return; | ||
161 | } | ||