diff options
Diffstat (limited to 'core/network.h')
-rw-r--r-- | core/network.h | 197 |
1 files changed, 80 insertions, 117 deletions
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 | } | ||