1 /* SPDX-License-Identifier: GPL-3.0-or-later
2  * Copyright © 2016-2018 The TokTok team.
3  * Copyright © 2013 Tox project.
4  */
5 
6 /*
7  * Datatypes, functions and includes for the core networking.
8  */
9 #ifndef C_TOXCORE_TOXCORE_NETWORK_H
10 #define C_TOXCORE_TOXCORE_NETWORK_H
11 
12 #include "logger.h"
13 
14 #include <stdbool.h>    // bool
15 #include <stddef.h>     // size_t
16 #include <stdint.h>     // uint*_t
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 typedef struct Family {
23     uint8_t value;
24 } Family;
25 
26 bool net_family_is_unspec(Family family);
27 bool net_family_is_ipv4(Family family);
28 bool net_family_is_ipv6(Family family);
29 bool net_family_is_tcp_family(Family family);
30 bool net_family_is_tcp_onion(Family family);
31 bool net_family_is_tcp_ipv4(Family family);
32 bool net_family_is_tcp_ipv6(Family family);
33 bool net_family_is_tox_tcp_ipv4(Family family);
34 bool net_family_is_tox_tcp_ipv6(Family family);
35 
36 extern const Family net_family_unspec;
37 extern const Family net_family_ipv4;
38 extern const Family net_family_ipv6;
39 extern const Family net_family_tcp_family;
40 extern const Family net_family_tcp_onion;
41 extern const Family net_family_tcp_ipv4;
42 extern const Family net_family_tcp_ipv6;
43 extern const Family net_family_tox_tcp_ipv4;
44 extern const Family net_family_tox_tcp_ipv6;
45 
46 typedef struct Socket {
47     int socket;
48 } Socket;
49 
50 Socket net_socket(Family domain, int type, int protocol);
51 
52 /**
53  * Check if socket is valid.
54  *
55  * @return true if valid, false otherwise.
56  */
57 bool sock_valid(Socket sock);
58 
59 extern const Socket net_invalid_socket;
60 
61 /**
62  * Calls send(sockfd, buf, len, MSG_NOSIGNAL).
63  */
64 int net_send(Socket sock, const void *buf, size_t len);
65 /**
66  * Calls recv(sockfd, buf, len, MSG_NOSIGNAL).
67  */
68 int net_recv(Socket sock, void *buf, size_t len);
69 /**
70  * Calls listen(sockfd, backlog).
71  */
72 int net_listen(Socket sock, int backlog);
73 /**
74  * Calls accept(sockfd, nullptr, nullptr).
75  */
76 Socket net_accept(Socket sock);
77 
78 /**
79  * return the amount of data in the tcp recv buffer.
80  * return 0 on failure.
81  */
82 size_t net_socket_data_recv_buffer(Socket sock);
83 
84 #define MAX_UDP_PACKET_SIZE 2048
85 
86 typedef enum Net_Packet_Type {
87     NET_PACKET_PING_REQUEST         = 0x00, /* Ping request packet ID. */
88     NET_PACKET_PING_RESPONSE        = 0x01, /* Ping response packet ID. */
89     NET_PACKET_GET_NODES            = 0x02, /* Get nodes request packet ID. */
90     NET_PACKET_SEND_NODES_IPV6      = 0x04, /* Send nodes response packet ID for other addresses. */
91     NET_PACKET_COOKIE_REQUEST       = 0x18, /* Cookie request packet */
92     NET_PACKET_COOKIE_RESPONSE      = 0x19, /* Cookie response packet */
93     NET_PACKET_CRYPTO_HS            = 0x1a, /* Crypto handshake packet */
94     NET_PACKET_CRYPTO_DATA          = 0x1b, /* Crypto data packet */
95     NET_PACKET_CRYPTO               = 0x20, /* Encrypted data packet ID. */
96     NET_PACKET_LAN_DISCOVERY        = 0x21, /* LAN discovery packet ID. */
97 
98     /* See: `docs/Prevent_Tracking.txt` and `onion.{c,h}` */
99     NET_PACKET_ONION_SEND_INITIAL   = 0x80,
100     NET_PACKET_ONION_SEND_1         = 0x81,
101     NET_PACKET_ONION_SEND_2         = 0x82,
102 
103     NET_PACKET_ANNOUNCE_REQUEST     = 0x83,
104     NET_PACKET_ANNOUNCE_RESPONSE    = 0x84,
105     NET_PACKET_ONION_DATA_REQUEST   = 0x85,
106     NET_PACKET_ONION_DATA_RESPONSE  = 0x86,
107 
108     NET_PACKET_ONION_RECV_3         = 0x8c,
109     NET_PACKET_ONION_RECV_2         = 0x8d,
110     NET_PACKET_ONION_RECV_1         = 0x8e,
111 
112     BOOTSTRAP_INFO_PACKET_ID        = 0xf0, /* Only used for bootstrap nodes */
113 
114     NET_PACKET_MAX                  = 0xff, /* This type must remain within a single uint8. */
115 } Net_Packet_Type;
116 
117 
118 #define TOX_PORTRANGE_FROM 33445
119 #define TOX_PORTRANGE_TO   33545
120 #define TOX_PORT_DEFAULT   TOX_PORTRANGE_FROM
121 
122 /* Redefinitions of variables for safe transfer over wire. */
123 #define TOX_AF_UNSPEC 0
124 #define TOX_AF_INET 2
125 #define TOX_AF_INET6 10
126 #define TOX_TCP_INET 130
127 #define TOX_TCP_INET6 138
128 
129 #define TOX_SOCK_STREAM 1
130 #define TOX_SOCK_DGRAM 2
131 
132 #define TOX_PROTO_TCP 1
133 #define TOX_PROTO_UDP 2
134 
135 /* TCP related */
136 #define TCP_ONION_FAMILY (TOX_AF_INET6 + 1)
137 #define TCP_INET (TOX_AF_INET6 + 2)
138 #define TCP_INET6 (TOX_AF_INET6 + 3)
139 #define TCP_FAMILY (TOX_AF_INET6 + 4)
140 
141 typedef union IP4 {
142     uint32_t uint32;
143     uint16_t uint16[2];
144     uint8_t uint8[4];
145 } IP4;
146 
147 IP4 get_ip4_loopback(void);
148 extern const IP4 ip4_broadcast;
149 
150 typedef union IP6 {
151     uint8_t uint8[16];
152     uint16_t uint16[8];
153     uint32_t uint32[4];
154     uint64_t uint64[2];
155 } IP6;
156 
157 IP6 get_ip6_loopback(void);
158 extern const IP6 ip6_broadcast;
159 
160 typedef union IP_Union {
161     IP4 v4;
162     IP6 v6;
163 } IP_Union;
164 
165 #define IP_DEFINED
166 typedef struct IP {
167     Family family;
168     IP_Union ip;
169 } IP;
170 
171 #define IP_PORT_DEFINED
172 typedef struct IP_Port {
173     IP ip;
174     uint16_t port;
175 } IP_Port;
176 
177 /* Convert values between host and network byte order.
178  */
179 uint32_t net_htonl(uint32_t hostlong);
180 uint16_t net_htons(uint16_t hostshort);
181 uint32_t net_ntohl(uint32_t hostlong);
182 uint16_t net_ntohs(uint16_t hostshort);
183 
184 size_t net_pack_u16(uint8_t *bytes, uint16_t v);
185 size_t net_pack_u32(uint8_t *bytes, uint32_t v);
186 size_t net_pack_u64(uint8_t *bytes, uint64_t v);
187 
188 size_t net_unpack_u16(const uint8_t *bytes, uint16_t *v);
189 size_t net_unpack_u32(const uint8_t *bytes, uint32_t *v);
190 size_t net_unpack_u64(const uint8_t *bytes, uint64_t *v);
191 
192 /* Does the IP6 struct a contain an IPv4 address in an IPv6 one? */
193 bool ipv6_ipv4_in_v6(IP6 a);
194 
195 #define SIZE_IP4 4
196 #define SIZE_IP6 16
197 #define SIZE_IP (1 + SIZE_IP6)
198 #define SIZE_PORT 2
199 #define SIZE_IPPORT (SIZE_IP + SIZE_PORT)
200 
201 #define TOX_ENABLE_IPV6_DEFAULT true
202 
203 /* addr_resolve return values */
204 #define TOX_ADDR_RESOLVE_INET  1
205 #define TOX_ADDR_RESOLVE_INET6 2
206 
207 #define TOX_INET6_ADDRSTRLEN 66
208 #define TOX_INET_ADDRSTRLEN 22
209 
210 /* ip_ntoa
211  *   converts ip into a string
212  *   ip_str must be of length at least IP_NTOA_LEN
213  *
214  *   IPv6 addresses are enclosed into square brackets, i.e. "[IPv6]"
215  *   writes error message into the buffer on error
216  *
217  *   returns ip_str
218  */
219 /* this would be TOX_INET6_ADDRSTRLEN, but it might be too short for the error message */
220 #define IP_NTOA_LEN 96 // TODO(irungentoo): magic number. Why not INET6_ADDRSTRLEN ?
221 const char *ip_ntoa(const IP *ip, char *ip_str, size_t length);
222 
223 /**
224  * Parses IP structure into an address string.
225  *
226  * @param ip IP of TOX_AF_INET or TOX_AF_INET6 families.
227  * @param length length of the address buffer.
228  *   Must be at least TOX_INET_ADDRSTRLEN for TOX_AF_INET
229  *   and TOX_INET6_ADDRSTRLEN for TOX_AF_INET6
230  *
231  * @param address dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6).
232  *
233  * @return true on success, false on failure.
234  */
235 bool ip_parse_addr(const IP *ip, char *address, size_t length);
236 
237 /**
238  * Directly parses the input into an IP structure.
239  *
240  * Tries IPv4 first, then IPv6.
241  *
242  * @param address dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6).
243  * @param to family and the value is set on success.
244  *
245  * @return true on success, false on failure.
246  */
247 bool addr_parse_ip(const char *address, IP *to);
248 
249 /**
250  * Compares two IPAny structures.
251  *
252  * Unset means unequal.
253  *
254  * @return false when not equal or when uninitialized.
255  */
256 bool ip_equal(const IP *a, const IP *b);
257 
258 /**
259  * Compares two IPAny_Port structures.
260  *
261  * Unset means unequal.
262  *
263  * @return false when not equal or when uninitialized.
264  */
265 bool ipport_equal(const IP_Port *a, const IP_Port *b);
266 
267 /* nulls out ip */
268 void ip_reset(IP *ip);
269 /* nulls out ip, sets family according to flag */
270 void ip_init(IP *ip, bool ipv6enabled);
271 /* checks if ip is valid */
272 bool ip_isset(const IP *ip);
273 /* checks if ip is valid */
274 bool ipport_isset(const IP_Port *ipport);
275 /* copies an ip structure */
276 void ip_copy(IP *target, const IP *source);
277 /* copies an ip_port structure */
278 void ipport_copy(IP_Port *target, const IP_Port *source);
279 
280 /**
281  * Uses getaddrinfo to resolve an address into an IP address.
282  *
283  * Uses the first IPv4/IPv6 addresses returned by getaddrinfo.
284  *
285  * @param address a hostname (or something parseable to an IP address)
286  * @param to to.family MUST be initialized, either set to a specific IP version
287  *     (TOX_AF_INET/TOX_AF_INET6) or to the unspecified TOX_AF_UNSPEC (= 0), if both
288  *     IP versions are acceptable
289  * @param extra can be NULL and is only set in special circumstances, see returns
290  *
291  * returns in `*to` a valid IPAny (v4/v6),
292  *     prefers v6 if `ip.family` was TOX_AF_UNSPEC and both available
293  * returns in `*extra` an IPv4 address, if family was TOX_AF_UNSPEC and `*to` is TOX_AF_INET6
294  *
295  * @return 0 on failure, `TOX_ADDR_RESOLVE_*` on success.
296  */
297 int addr_resolve(const char *address, IP *to, IP *extra);
298 
299 /**
300  * Resolves string into an IP address
301  *
302  * @param address a hostname (or something parseable to an IP address)
303  * @param to to.family MUST be initialized, either set to a specific IP version
304  *     (TOX_AF_INET/TOX_AF_INET6) or to the unspecified TOX_AF_UNSPEC (= 0), if both
305  *     IP versions are acceptable
306  * @param extra can be NULL and is only set in special circumstances, see returns
307  *
308  * returns in `*to` a matching address (IPv6 or IPv4)
309  * returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was TOX_AF_UNSPEC
310  *
311  * @return true on success, false on failure
312  */
313 bool addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra);
314 
315 /* Function to receive data, ip and port of sender is put into ip_port.
316  * Packet data is put into data.
317  * Packet length is put into length.
318  */
319 typedef int packet_handler_cb(void *object, IP_Port ip_port, const uint8_t *data, uint16_t len, void *userdata);
320 
321 typedef struct Networking_Core Networking_Core;
322 
323 Family net_family(const Networking_Core *net);
324 uint16_t net_port(const Networking_Core *net);
325 
326 /* Run this before creating sockets.
327  *
328  * return 0 on success
329  * return -1 on failure
330  */
331 int networking_at_startup(void);
332 
333 /* Close the socket.
334  */
335 void kill_sock(Socket sock);
336 
337 /**
338  * Set socket as nonblocking
339  *
340  * @return true on success, false on failure.
341  */
342 bool set_socket_nonblock(Socket sock);
343 
344 /**
345  * Set socket to not emit SIGPIPE
346  *
347  * @return true on success, false on failure.
348  */
349 bool set_socket_nosigpipe(Socket sock);
350 
351 /**
352  * Enable SO_REUSEADDR on socket.
353  *
354  * @return true on success, false on failure.
355  */
356 bool set_socket_reuseaddr(Socket sock);
357 
358 /**
359  * Set socket to dual (IPv4 + IPv6 socket)
360  *
361  * @return true on success, false on failure.
362  */
363 bool set_socket_dualstack(Socket sock);
364 
365 /* Basic network functions: */
366 
367 /* Function to send packet(data) of length length to ip_port. */
368 int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length);
369 
370 /* Function to call when packet beginning with byte is received. */
371 void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_cb *cb, void *object);
372 
373 /* Call this several times a second. */
374 void networking_poll(Networking_Core *net, void *userdata);
375 
376 /* Connect a socket to the address specified by the ip_port. */
377 int net_connect(Socket sock, IP_Port ip_port);
378 
379 /* High-level getaddrinfo implementation.
380  * Given node, which identifies an Internet host, net_getipport() fills an array
381  * with one or more IP_Port structures, each of which contains an Internet
382  * address that can be specified by calling net_connect(), the port is ignored.
383  *
384  * Skip all addresses with socktype != type (use type = -1 to get all addresses)
385  * To correctly deallocate array memory use net_freeipport()
386  *
387  * return number of elements in res array
388  * and -1 on error.
389  */
390 int32_t net_getipport(const char *node, IP_Port **res, int tox_type);
391 
392 /* Deallocates memory allocated by net_getipport
393  */
394 void net_freeipport(IP_Port *ip_ports);
395 
396 /**
397  * @return true on success, false on failure.
398  */
399 bool bind_to_port(Socket sock, Family family, uint16_t port);
400 
401 /* Get the last networking error code.
402  *
403  * Similar to Unix's errno, but cross-platform, as not all platforms use errno
404  * to indicate networking errors.
405  *
406  * Note that different platforms may return different codes for the same error,
407  * so you likely shouldn't be checking the value returned by this function
408  * unless you know what you are doing, you likely just want to use it in
409  * combination with net_new_strerror() to print the error.
410  *
411  * return platform-dependent network error code, if any.
412  */
413 int net_error(void);
414 
415 /* Get a text explanation for the error code from net_error().
416  *
417  * return NULL on failure.
418  * return pointer to a NULL-terminated string describing the error code on
419  * success. The returned string must be freed using net_kill_strerror().
420  */
421 const char *net_new_strerror(int error);
422 
423 /* Frees the string returned by net_new_strerror().
424  * It's valid to pass NULL as the argument, the function does nothing in this
425  * case.
426  */
427 void net_kill_strerror(const char *strerror);
428 
429 /* Initialize networking.
430  * bind to ip and port.
431  * ip must be in network order EX: 127.0.0.1 = (7F000001).
432  * port is in host byte order (this means don't worry about it).
433  *
434  * return Networking_Core object if no problems
435  * return NULL if there are problems.
436  *
437  * If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other.
438  */
439 Networking_Core *new_networking(const Logger *log, IP ip, uint16_t port);
440 Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error);
441 Networking_Core *new_networking_no_udp(const Logger *log);
442 
443 /* Function to cleanup networking stuff (doesn't do much right now). */
444 void kill_networking(Networking_Core *net);
445 
446 #ifdef __cplusplus
447 }  // extern "C"
448 #endif
449 
450 #endif
451