2013-06-26 21:56:15 +08:00
|
|
|
/* network.h
|
2013-07-27 20:43:36 +08:00
|
|
|
*
|
2013-07-26 09:45:56 +08:00
|
|
|
* Datatypes, functions and includes for the core networking.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 Tox project All Rights Reserved.
|
|
|
|
*
|
|
|
|
* This file is part of Tox.
|
|
|
|
*
|
|
|
|
* Tox is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Tox is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
2013-07-27 20:43:36 +08:00
|
|
|
*
|
2013-07-26 09:45:56 +08:00
|
|
|
*/
|
2013-07-20 23:02:43 +08:00
|
|
|
|
2013-07-27 20:43:36 +08:00
|
|
|
#ifndef NETWORK_H
|
|
|
|
#define NETWORK_H
|
2013-07-20 23:02:43 +08:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#ifdef WIN32 /* Put win32 includes here */
|
2013-08-12 02:17:02 +08:00
|
|
|
#ifndef WINVER
|
2013-07-23 13:46:45 +08:00
|
|
|
//Windows XP
|
|
|
|
#define WINVER 0x0501
|
2013-08-12 02:17:02 +08:00
|
|
|
#endif
|
2013-07-20 23:02:43 +08:00
|
|
|
#include <winsock2.h>
|
|
|
|
#include <windows.h>
|
2013-07-23 13:46:45 +08:00
|
|
|
#include <ws2tcpip.h>
|
2013-07-20 23:02:43 +08:00
|
|
|
|
2013-09-09 19:56:03 +08:00
|
|
|
typedef unsigned int sock_t;
|
|
|
|
|
2013-08-30 05:17:51 +08:00
|
|
|
#else // Linux includes
|
2013-07-20 23:02:43 +08:00
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
2013-09-09 22:35:39 +08:00
|
|
|
#include <arpa/inet.h>
|
2013-07-20 23:02:43 +08:00
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/time.h>
|
2013-07-27 20:43:36 +08:00
|
|
|
#include <sys/types.h>
|
2013-07-21 05:31:36 +08:00
|
|
|
#include <netdb.h>
|
2013-07-27 09:45:58 +08:00
|
|
|
#include <unistd.h>
|
2013-07-13 04:27:19 +08:00
|
|
|
|
2013-09-09 19:56:03 +08:00
|
|
|
typedef int sock_t;
|
|
|
|
|
2013-07-20 23:02:43 +08:00
|
|
|
#endif
|
2013-07-13 04:27:19 +08:00
|
|
|
|
2013-07-20 23:02:43 +08:00
|
|
|
#ifndef VANILLA_NACL
|
2013-08-30 05:17:51 +08:00
|
|
|
/* We use libsodium by default. */
|
2013-07-20 23:02:43 +08:00
|
|
|
#include <sodium.h>
|
|
|
|
#else
|
2013-07-30 22:00:55 +08:00
|
|
|
#include <crypto_box.h>
|
2013-09-13 22:42:14 +08:00
|
|
|
#include <randombytes.h>
|
2013-08-04 00:45:44 +08:00
|
|
|
#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
|
2013-07-20 23:02:43 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#define MAX_UDP_PACKET_SIZE 65507
|
|
|
|
|
2013-08-30 05:17:51 +08:00
|
|
|
#define NET_PACKET_PING_REQUEST 0 /* Ping request packet ID. */
|
|
|
|
#define NET_PACKET_PING_RESPONSE 1 /* Ping response packet ID. */
|
|
|
|
#define NET_PACKET_GET_NODES 2 /* Get nodes request packet ID. */
|
2013-09-10 01:17:21 +08:00
|
|
|
#define NET_PACKET_SEND_NODES 3 /* Send nodes response packet ID for IPv4 addresses. */
|
2013-09-12 21:42:03 +08:00
|
|
|
#define NET_PACKET_SEND_NODES_IPV6 4 /* Send nodes response packet ID for other addresses. */
|
2013-08-30 05:17:51 +08:00
|
|
|
#define NET_PACKET_HANDSHAKE 16 /* Handshake packet ID. */
|
|
|
|
#define NET_PACKET_SYNC 17 /* SYNC packet ID. */
|
|
|
|
#define NET_PACKET_DATA 18 /* Data packet ID. */
|
|
|
|
#define NET_PACKET_CRYPTO 32 /* Encrypted data packet ID. */
|
|
|
|
#define NET_PACKET_LAN_DISCOVERY 33 /* LAN discovery packet ID. */
|
2013-09-12 08:42:25 +08:00
|
|
|
#define NET_PACKET_GROUP_CHATS 48 /* Group chats packet ID. */
|
2013-08-21 15:55:43 +08:00
|
|
|
|
2013-09-12 21:42:03 +08:00
|
|
|
#define TOX_PORTRANGE_FROM 33445
|
|
|
|
#define TOX_PORTRANGE_TO 33455
|
|
|
|
#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM
|
2013-08-08 22:59:22 +08:00
|
|
|
|
|
|
|
/* Current time, unix format */
|
|
|
|
#define unix_time() ((uint64_t)time(NULL))
|
|
|
|
|
|
|
|
|
2013-07-27 20:48:50 +08:00
|
|
|
typedef union {
|
2013-08-30 15:02:11 +08:00
|
|
|
uint8_t uint8[4];
|
|
|
|
uint16_t uint16[2];
|
|
|
|
uint32_t uint32;
|
2013-09-09 20:53:27 +08:00
|
|
|
struct in_addr in_addr;
|
2013-09-09 20:16:40 +08:00
|
|
|
} IP4;
|
2013-07-27 20:48:50 +08:00
|
|
|
|
2013-09-15 21:31:27 +08:00
|
|
|
typedef union {
|
|
|
|
uint8_t uint8[16];
|
|
|
|
uint16_t uint16[8];
|
|
|
|
uint32_t uint32[4];
|
|
|
|
struct in6_addr in6_addr;
|
|
|
|
} IP6;
|
2013-09-09 20:53:27 +08:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
sa_family_t family;
|
|
|
|
union {
|
|
|
|
IP4 ip4;
|
|
|
|
IP6 ip6;
|
|
|
|
};
|
|
|
|
} IPAny;
|
|
|
|
|
2013-08-30 14:51:15 +08:00
|
|
|
typedef union {
|
|
|
|
struct {
|
2013-09-09 20:16:40 +08:00
|
|
|
IP4 ip;
|
2013-08-30 14:51:15 +08:00
|
|
|
uint16_t port;
|
|
|
|
/* Not used for anything right now. */
|
|
|
|
uint16_t padding;
|
|
|
|
};
|
|
|
|
uint8_t uint8[8];
|
2013-09-10 01:17:21 +08:00
|
|
|
} IP4_Port;
|
2013-09-09 22:12:50 +08:00
|
|
|
|
|
|
|
/* will replace IP_Port as soon as the complete infrastructure is in place
|
|
|
|
* removed the unused union and padding also */
|
|
|
|
typedef struct {
|
|
|
|
IPAny ip;
|
|
|
|
uint16_t port;
|
|
|
|
} IPAny_Port;
|
|
|
|
|
2013-09-13 14:50:46 +08:00
|
|
|
/* #undef TOX_ENABLE_IPV6 */
|
|
|
|
#define TOX_ENABLE_IPV6
|
2013-09-10 22:36:20 +08:00
|
|
|
#ifdef TOX_ENABLE_IPV6
|
|
|
|
#define TOX_ENABLE_IPV6_DEFAULT 1
|
|
|
|
typedef IPAny IP;
|
2013-09-10 01:17:21 +08:00
|
|
|
typedef IPAny_Port IP_Port;
|
|
|
|
#else
|
2013-09-10 22:36:20 +08:00
|
|
|
#define TOX_ENABLE_IPV6_DEFAULT 0
|
|
|
|
typedef IP4 IP;
|
2013-09-10 01:17:21 +08:00
|
|
|
typedef IP4_Port IP_Port;
|
|
|
|
#endif
|
|
|
|
|
2013-09-10 22:36:20 +08:00
|
|
|
/* ip_ntoa
|
|
|
|
* converts ip into a string
|
|
|
|
* uses a static buffer, so mustn't used multiple times in the same output
|
|
|
|
*/
|
|
|
|
const char *ip_ntoa(IP *ip);
|
|
|
|
|
2013-09-11 22:57:26 +08:00
|
|
|
/* ip_equal
|
|
|
|
* compares two IPAny structures
|
|
|
|
* unset means unequal
|
|
|
|
*
|
|
|
|
* returns 0 when not equal or when uninitialized
|
|
|
|
*/
|
|
|
|
int ip_equal(IP *a, IP *b);
|
|
|
|
|
2013-09-09 22:12:50 +08:00
|
|
|
/* ipport_equal
|
|
|
|
* compares two IPAny_Port structures
|
|
|
|
* unset means unequal
|
|
|
|
*
|
|
|
|
* returns 0 when not equal or when uninitialized
|
|
|
|
*/
|
2013-09-10 22:36:20 +08:00
|
|
|
int ipport_equal(IP_Port *a, IP_Port *b);
|
|
|
|
|
|
|
|
/* nulls out ip */
|
|
|
|
void ip_reset(IP *ip);
|
|
|
|
/* nulls out ip, sets family according to flag */
|
|
|
|
void ip_init(IP *ip, uint8_t ipv6enabled);
|
|
|
|
/* checks if ip is valid */
|
|
|
|
int ip_isset(IP *ip);
|
|
|
|
/* checks if ip is valid */
|
|
|
|
int ipport_isset(IP_Port *ipport);
|
|
|
|
/* copies an ip structure */
|
|
|
|
void ip_copy(IP *target, IP *source);
|
|
|
|
/* copies an ip_port structure */
|
|
|
|
void ipport_copy(IP_Port *target, IP_Port *source);
|
2013-07-27 20:48:50 +08:00
|
|
|
|
2013-09-11 22:57:26 +08:00
|
|
|
/*
|
|
|
|
* addr_resolve():
|
|
|
|
* uses getaddrinfo to resolve an address into an IP address
|
|
|
|
* uses the first IPv4/IPv6 addresses returned by getaddrinfo
|
|
|
|
*
|
|
|
|
* input
|
|
|
|
* address: a hostname (or something parseable to an IP address)
|
2013-09-13 00:39:21 +08:00
|
|
|
* to: to.family MUST be initialized, either set to a specific IP version
|
2013-09-11 22:57:26 +08:00
|
|
|
* (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
|
|
|
|
* IP versions are acceptable
|
2013-09-13 00:39:21 +08:00
|
|
|
* extra can be NULL and is only set in special circumstances, see returns
|
2013-09-11 22:57:26 +08:00
|
|
|
*
|
2013-09-13 00:39:21 +08:00
|
|
|
* returns in *to a valid IPAny (v4/v6),
|
2013-09-11 22:57:26 +08:00
|
|
|
* prefers v6 if ip.family was AF_UNSPEC and both available
|
2013-09-13 00:39:21 +08:00
|
|
|
* returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is AF_INET6
|
2013-09-11 22:57:26 +08:00
|
|
|
* returns 0 on failure
|
|
|
|
*/
|
2013-09-13 00:39:21 +08:00
|
|
|
int addr_resolve(const char *address, IP *to, IP *extra);
|
2013-09-11 22:57:26 +08:00
|
|
|
|
2013-09-09 20:53:27 +08:00
|
|
|
/*
|
|
|
|
* addr_resolve_or_parse_ip
|
|
|
|
* resolves string into an IP address
|
|
|
|
*
|
2013-09-13 00:39:21 +08:00
|
|
|
* address: a hostname (or something parseable to an IP address)
|
|
|
|
* to: to.family MUST be initialized, either set to a specific IP version
|
|
|
|
* (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
|
|
|
|
* IP versions are acceptable
|
|
|
|
* extra can be NULL and is only set in special circumstances, see returns
|
|
|
|
*
|
|
|
|
* returns in *tro a matching address (IPv6 or IPv4)
|
|
|
|
* returns in *extra, if not NULL, an IPv4 address, if to->family was AF_UNSPEC
|
|
|
|
* returns 1 on success
|
|
|
|
* returns 0 on failure
|
2013-09-09 20:53:27 +08:00
|
|
|
*/
|
2013-09-13 00:39:21 +08:00
|
|
|
int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra);
|
2013-09-09 20:53:27 +08:00
|
|
|
|
2013-08-30 05:17:51 +08:00
|
|
|
/* Function to receive data, ip and port of sender is put into ip_port.
|
|
|
|
* Packet data is put into data.
|
|
|
|
* Packet length is put into length.
|
|
|
|
*/
|
2013-08-21 07:37:05 +08:00
|
|
|
typedef int (*packet_handler_callback)(void *object, IP_Port ip_port, uint8_t *data, uint32_t len);
|
2013-08-10 07:30:18 +08:00
|
|
|
|
2013-08-20 11:54:28 +08:00
|
|
|
typedef struct {
|
|
|
|
packet_handler_callback function;
|
2013-08-21 07:37:05 +08:00
|
|
|
void *object;
|
|
|
|
} Packet_Handles;
|
2013-08-20 11:54:28 +08:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
Packet_Handles packethandlers[256];
|
2013-09-02 23:41:06 +08:00
|
|
|
|
2013-09-09 19:56:03 +08:00
|
|
|
/* Our UDP socket. */
|
|
|
|
sa_family_t family;
|
|
|
|
uint16_t port;
|
|
|
|
sock_t sock;
|
2013-08-21 07:37:05 +08:00
|
|
|
} Networking_Core;
|
2013-08-20 11:54:28 +08:00
|
|
|
|
2013-09-03 00:25:28 +08:00
|
|
|
/* return current time in milleseconds since the epoch. */
|
2013-08-05 21:57:17 +08:00
|
|
|
uint64_t current_time(void);
|
2013-07-27 20:48:50 +08:00
|
|
|
|
2013-09-03 00:25:28 +08:00
|
|
|
/* return a random number.
|
2013-08-30 05:17:51 +08:00
|
|
|
*/
|
2013-08-05 21:57:17 +08:00
|
|
|
uint32_t random_int(void);
|
2013-07-27 20:48:50 +08:00
|
|
|
|
|
|
|
/* Basic network functions: */
|
|
|
|
|
2013-08-30 05:17:51 +08:00
|
|
|
/* Function to send packet(data) of length length to ip_port. */
|
2013-09-09 19:56:03 +08:00
|
|
|
int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length);
|
2013-07-27 20:48:50 +08:00
|
|
|
|
2013-08-30 05:17:51 +08:00
|
|
|
/* Function to call when packet beginning with byte is received. */
|
2013-08-21 07:37:05 +08:00
|
|
|
void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object);
|
2013-08-10 07:30:18 +08:00
|
|
|
|
2013-08-30 05:17:51 +08:00
|
|
|
/* Call this several times a second. */
|
2013-08-21 07:37:05 +08:00
|
|
|
void networking_poll(Networking_Core *net);
|
2013-07-27 20:48:50 +08:00
|
|
|
|
2013-08-30 05:17:51 +08:00
|
|
|
/* Initialize networking.
|
2013-09-03 00:25:28 +08:00
|
|
|
* bind to ip and port.
|
|
|
|
* ip must be in network order EX: 127.0.0.1 = (7F000001).
|
|
|
|
* port is in host byte order (this means don't worry about it).
|
2013-08-30 05:17:51 +08:00
|
|
|
*
|
2013-09-03 00:25:28 +08:00
|
|
|
* return 0 if no problems.
|
|
|
|
* return -1 if there were problems.
|
2013-08-30 05:17:51 +08:00
|
|
|
*/
|
2013-09-10 22:36:20 +08:00
|
|
|
Networking_Core *new_networking(IP ip, uint16_t port);
|
2013-07-27 20:48:50 +08:00
|
|
|
|
2013-08-30 05:17:51 +08:00
|
|
|
/* Function to cleanup networking stuff (doesn't do much right now). */
|
2013-08-21 07:37:05 +08:00
|
|
|
void kill_networking(Networking_Core *net);
|
2013-07-27 20:48:50 +08:00
|
|
|
|
2013-07-20 23:02:43 +08:00
|
|
|
#endif
|