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