Add platform-independent Socket and IP implementation

This commit is contained in:
Diadlo 2017-01-03 19:26:15 +03:00
parent 287a29b826
commit f00006cf1d
No known key found for this signature in database
GPG Key ID: 5AF9F2E29107C727
15 changed files with 159 additions and 116 deletions

View File

@ -38,7 +38,7 @@ START_TEST(test_basic)
ck_assert_msg(tcp_s != NULL, "Failed to create TCP relay server");
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports");
sock_t sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
Socket sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in6 addr6_loopback = {0};
addr6_loopback.sin6_family = AF_INET6;
addr6_loopback.sin6_port = htons(ports[rand() % NUM_PORTS]);
@ -126,7 +126,7 @@ START_TEST(test_basic)
END_TEST
struct sec_TCP_con {
sock_t sock;
Socket sock;
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t recv_nonce[CRYPTO_NONCE_SIZE];
uint8_t sent_nonce[CRYPTO_NONCE_SIZE];
@ -136,7 +136,7 @@ struct sec_TCP_con {
static struct sec_TCP_con *new_TCP_con(TCP_Server *tcp_s)
{
struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con));
sock_t sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
Socket sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in6 addr6_loopback = {0};
addr6_loopback.sin6_family = AF_INET6;
addr6_loopback.sin6_port = htons(ports[rand() % NUM_PORTS]);
@ -407,7 +407,7 @@ START_TEST(test_client)
ip_port_tcp_s.port = htons(ports[rand() % NUM_PORTS]);
ip_port_tcp_s.ip.family = AF_INET6;
ip_port_tcp_s.ip.ip6.in6_addr = in6addr_loopback;
get_ip6(&ip_port_tcp_s.ip.ip6, &in6addr_loopback);
TCP_Client_Connection *conn = new_TCP_connection(ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, 0);
c_sleep(50);
do_TCP_connection(conn, NULL);
@ -505,7 +505,7 @@ START_TEST(test_client_invalid)
ip_port_tcp_s.port = htons(ports[rand() % NUM_PORTS]);
ip_port_tcp_s.ip.family = AF_INET6;
ip_port_tcp_s.ip.ip6.in6_addr = in6addr_loopback;
get_ip6(&ip_port_tcp_s.ip.ip6, &in6addr_loopback);
TCP_Client_Connection *conn = new_TCP_connection(ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, 0);
c_sleep(50);
do_TCP_connection(conn, NULL);
@ -574,7 +574,7 @@ START_TEST(test_tcp_connection)
ip_port_tcp_s.port = htons(ports[rand() % NUM_PORTS]);
ip_port_tcp_s.ip.family = AF_INET6;
ip_port_tcp_s.ip.ip6.in6_addr = in6addr_loopback;
get_ip6(&ip_port_tcp_s.ip.ip6, &in6addr_loopback);
int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123);
ck_assert_msg(connection == 0, "Connection id wrong");
@ -683,7 +683,7 @@ START_TEST(test_tcp_connection2)
ip_port_tcp_s.port = htons(ports[rand() % NUM_PORTS]);
ip_port_tcp_s.ip.family = AF_INET6;
ip_port_tcp_s.ip.ip6.in6_addr = in6addr_loopback;
get_ip6(&ip_port_tcp_s.ip.ip6, &in6addr_loopback);
int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123);
ck_assert_msg(connection == 0, "Connection id wrong");

View File

@ -3,6 +3,7 @@
#endif
#include <check.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@ -36,8 +37,9 @@ START_TEST(test_addr_resolv_localhost)
if (res > 0) {
ck_assert_msg(ip.family == AF_INET, "Expected family AF_INET, got %u.", ip.family);
ck_assert_msg(ip.ip4.uint32 == htonl(0x7F000001), "Expected 127.0.0.1, got %s.",
inet_ntoa(ip.ip4.in_addr));
struct in_addr addr;
fill_addr4(ip.ip4, &addr);
ck_assert_msg(ip.ip4.uint32 == htonl(0x7F000001), "Expected 127.0.0.1, got %s.", inet_ntoa(addr));
}
ip_init(&ip, 1); // ipv6enabled = 1
@ -71,8 +73,10 @@ START_TEST(test_addr_resolv_localhost)
ck_assert_msg(!memcmp(&ip.ip6, &in6addr_loopback, sizeof(IP6)), "Expected ::1, got %s.",
ip_ntoa(&ip, ip_str, sizeof(ip_str)));
struct in_addr addr;
fill_addr4(ip.ip4, &addr);
ck_assert_msg(extra.family == AF_INET, "Expected family AF_INET (%u), got %u.", AF_INET, extra.family);
ck_assert_msg(extra.ip4.uint32 == htonl(0x7F000001), "Expected 127.0.0.1, got %s.", inet_ntoa(extra.ip4.in_addr));
ck_assert_msg(extra.ip4.uint32 == htonl(0x7F000001), "Expected 127.0.0.1, got %s.", inet_ntoa(addr));
}
} else {
printf("Localhost seems to be split in two.\n");

View File

@ -1,5 +1,9 @@
#include "helpers.h"
#if defined(__AIX__)
# define _XOPEN_SOURCE 1
#endif
// See man 2 sbrk.
#if _BSD_SOURCE || _SVID_SOURCE || \
(_XOPEN_SOURCE >= 500 || \

View File

@ -50,7 +50,7 @@ int main(int argc, char *argv[])
IP ip = {0};
ip.family = AF_INET;
sock_t sock = socket(ip.family, SOCK_DGRAM, IPPROTO_UDP);
Socket sock = socket(ip.family, SOCK_DGRAM, IPPROTO_UDP);
if (!sock_valid(sock)) {
return -1;
@ -66,7 +66,7 @@ int main(int argc, char *argv[])
target.sin_family = AF_INET;
target.sin_addr = ip.ip4.in_addr;
fill_addr4(ip.ip4, &target.sin_addr);
target.sin_port = htons(53);

View File

@ -29,6 +29,7 @@
#include "../toxcore/util.h"
#include <assert.h>
#include <errno.h>
#define BWC_PACKET_ID 196
#define BWC_SEND_INTERVAL_MS 1000

View File

@ -30,6 +30,7 @@
#include "../toxcore/util.h"
#include <assert.h>
#include <errno.h>
#include <stdlib.h>

View File

@ -31,6 +31,7 @@
#include "../toxcore/util.h"
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

View File

@ -121,7 +121,8 @@ static void fetch_broadcast_info(uint16_t port)
* so it's wrapped in __linux for now.
* Definitely won't work like this on Windows...
*/
sock_t sock = 0;
broadcast_count = 0;
Socket sock = 0;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return;
@ -173,7 +174,7 @@ static void fetch_broadcast_info(uint16_t port)
IP_Port *ip_port = &ip_ports[count];
ip_port->ip.family = AF_INET;
ip_port->ip.ip4.in_addr = sock4->sin_addr;
get_ip4(&ip_port->ip.ip4, &sock4->sin_addr);
if (ip_port->ip.ip4.uint32 == 0) {
continue;

View File

@ -36,7 +36,7 @@
/* return 1 on success
* return 0 on failure
*/
static int connect_sock_to(sock_t sock, IP_Port ip_port, TCP_Proxy_Info *proxy_info)
static int connect_sock_to(Socket sock, IP_Port ip_port, TCP_Proxy_Info *proxy_info)
{
if (proxy_info->proxy_type != TCP_PROXY_NONE) {
ip_port = proxy_info->ip_port;
@ -51,14 +51,14 @@ static int connect_sock_to(sock_t sock, IP_Port ip_port, TCP_Proxy_Info *proxy_i
addrsize = sizeof(struct sockaddr_in);
addr4->sin_family = AF_INET;
addr4->sin_addr = ip_port.ip.ip4.in_addr;
fill_addr4(ip_port.ip.ip4, &addr4->sin_addr);
addr4->sin_port = ip_port.port;
} else if (ip_port.ip.family == AF_INET6) {
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
addrsize = sizeof(struct sockaddr_in6);
addr6->sin6_family = AF_INET6;
addr6->sin6_addr = ip_port.ip.ip6.in6_addr;
fill_addr6(ip_port.ip.ip6, &addr6->sin6_addr);
addr6->sin6_port = ip_port.port;
} else {
return 0;
@ -653,7 +653,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public
family = proxy_info->ip_port.ip.family;
}
sock_t sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
Socket sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
if (!sock_valid(sock)) {
return NULL;

View File

@ -52,7 +52,7 @@ enum {
};
typedef struct {
uint8_t status;
sock_t sock;
Socket sock;
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */
IP_Port ip_port; /* The ip and port of the server */

View File

@ -40,7 +40,7 @@ struct TCP_Server {
int efd;
uint64_t last_run_pinged;
#endif
sock_t *socks_listening;
Socket *socks_listening;
unsigned int num_listening_socks;
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
@ -78,7 +78,7 @@ size_t tcp_server_listen_count(const TCP_Server *tcp_server)
/* return 1 on success
* return 0 on failure
*/
static int bind_to_port(sock_t sock, int family, uint16_t port)
static int bind_to_port(Socket sock, int family, uint16_t port)
{
struct sockaddr_storage addr = {0};
size_t addrsize;
@ -232,7 +232,7 @@ static int del_accepted(TCP_Server *TCP_server, int index)
/* return the amount of data in the tcp recv buffer.
* return 0 on failure.
*/
unsigned int TCP_socket_data_recv_buffer(sock_t sock)
unsigned int TCP_socket_data_recv_buffer(Socket sock)
{
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
unsigned long count = 0;
@ -252,7 +252,7 @@ unsigned int TCP_socket_data_recv_buffer(sock_t sock)
* return 0 if nothing has been read from socket.
* return ~0 on failure.
*/
uint16_t read_TCP_length(sock_t sock)
uint16_t read_TCP_length(Socket sock)
{
unsigned int count = TCP_socket_data_recv_buffer(sock);
@ -282,7 +282,7 @@ uint16_t read_TCP_length(sock_t sock)
* return length on success
* return -1 on failure/no data in buffer.
*/
int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length)
int read_TCP_packet(Socket sock, uint8_t *data, uint16_t length)
{
unsigned int count = TCP_socket_data_recv_buffer(sock);
@ -304,7 +304,7 @@ int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length)
* return 0 if could not read any packet.
* return -1 on failure (connection must be killed).
*/
int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, const uint8_t *shared_key,
int read_packet_TCP_secure_connection(Socket sock, uint16_t *next_packet_length, const uint8_t *shared_key,
uint8_t *recv_nonce, uint8_t *data, uint16_t max_len)
{
if (*next_packet_length == 0) {
@ -529,7 +529,7 @@ static int kill_accepted(TCP_Server *TCP_server, int index)
rm_connection_index(TCP_server, &TCP_server->accepted_connection_array[index], i);
}
sock_t sock = TCP_server->accepted_connection_array[index].sock;
Socket sock = TCP_server->accepted_connection_array[index].sock;
if (del_accepted(TCP_server, index) != 0) {
return -1;
@ -971,7 +971,7 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection
/* return index on success
* return -1 on failure
*/
static int accept_connection(TCP_Server *TCP_server, sock_t sock)
static int accept_connection(TCP_Server *TCP_server, Socket sock)
{
if (!sock_valid(sock)) {
return -1;
@ -1003,9 +1003,9 @@ static int accept_connection(TCP_Server *TCP_server, sock_t sock)
return index;
}
static sock_t new_listening_TCP_socket(int family, uint16_t port)
static Socket new_listening_TCP_socket(int family, uint16_t port)
{
sock_t sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
Socket sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
if (!sock_valid(sock)) {
return ~0;
@ -1048,7 +1048,7 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin
return NULL;
}
temp->socks_listening = (sock_t *)calloc(num_sockets, sizeof(sock_t));
temp->socks_listening = (Socket *)calloc(num_sockets, sizeof(Socket));
if (temp->socks_listening == NULL) {
free(temp);
@ -1080,7 +1080,7 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin
#endif
for (i = 0; i < num_sockets; ++i) {
sock_t sock = new_listening_TCP_socket(family, ports[i]);
Socket sock = new_listening_TCP_socket(family, ports[i]);
if (sock_valid(sock)) {
#ifdef TCP_SERVER_USE_EPOLL
@ -1124,7 +1124,7 @@ static void do_TCP_accept_new(TCP_Server *TCP_server)
for (i = 0; i < TCP_server->num_listening_socks; ++i) {
struct sockaddr_storage addr;
socklen_t addrlen = sizeof(addr);
sock_t sock;
Socket sock;
do {
sock = accept(TCP_server->socks_listening[i], (struct sockaddr *)&addr, &addrlen);
@ -1292,7 +1292,7 @@ static void do_TCP_epoll(TCP_Server *TCP_server)
int n;
for (n = 0; n < nfds; ++n) {
sock_t sock = events[n].data.u64 & 0xFFFFFFFF;
Socket sock = events[n].data.u64 & 0xFFFFFFFF;
int status = (events[n].data.u64 >> 32) & 0xFF, index = (events[n].data.u64 >> 40);
if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP) || (events[n].events & EPOLLRDHUP)) {
@ -1333,7 +1333,7 @@ static void do_TCP_epoll(TCP_Server *TCP_server)
socklen_t addrlen = sizeof(addr);
while (1) {
sock_t sock_new = accept(sock, (struct sockaddr *)&addr, &addrlen);
Socket sock_new = accept(sock, (struct sockaddr *)&addr, &addrlen);
if (!sock_valid(sock_new)) {
break;

View File

@ -90,7 +90,7 @@ struct TCP_Priority_List {
};
typedef struct TCP_Secure_Connection {
sock_t sock;
Socket sock;
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */
uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */
@ -137,7 +137,7 @@ void kill_TCP_server(TCP_Server *TCP_server);
/* return the amount of data in the tcp recv buffer.
* return 0 on failure.
*/
unsigned int TCP_socket_data_recv_buffer(sock_t sock);
unsigned int TCP_socket_data_recv_buffer(Socket sock);
/* Read the next two bytes in TCP stream then convert them to
* length (host byte order).
@ -146,20 +146,20 @@ unsigned int TCP_socket_data_recv_buffer(sock_t sock);
* return 0 if nothing has been read from socket.
* return ~0 on failure.
*/
uint16_t read_TCP_length(sock_t sock);
uint16_t read_TCP_length(Socket sock);
/* Read length bytes from socket.
*
* return length on success
* return -1 on failure/no data in buffer.
*/
int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length);
int read_TCP_packet(Socket sock, uint8_t *data, uint16_t length);
/* return length of received packet on success.
* return 0 if could not read any packet.
* return -1 on failure (connection must be killed).
*/
int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, const uint8_t *shared_key,
int read_packet_TCP_secure_connection(Socket sock, uint16_t *next_packet_length, const uint8_t *shared_key,
uint8_t *recv_nonce, uint8_t *data, uint16_t max_len);

View File

@ -37,16 +37,38 @@
#include "logger.h"
#include "util.h"
#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32)
#include <errno.h>
#endif
#include <assert.h>
#ifdef __APPLE__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
#ifndef IPV6_ADD_MEMBERSHIP
#ifdef IPV6_JOIN_GROUP
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#endif
#endif
#if !(defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#else
#ifndef IPV6_V6ONLY
#define IPV6_V6ONLY 27
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK
#endif
static const char *inet_ntop(sa_family_t family, const void *addr, char *buf, size_t bufsize)
{
@ -123,7 +145,7 @@ static int inet_pton(sa_family_t family, const char *addrString, void *addrbuf)
* return 1 if valid
* return 0 if not valid
*/
int sock_valid(sock_t sock)
int sock_valid(Socket sock)
{
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
@ -140,7 +162,7 @@ int sock_valid(sock_t sock)
/* Close the socket.
*/
void kill_sock(sock_t sock)
void kill_sock(Socket sock)
{
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
closesocket(sock);
@ -154,7 +176,7 @@ void kill_sock(sock_t sock)
* return 1 on success
* return 0 on failure
*/
int set_socket_nonblock(sock_t sock)
int set_socket_nonblock(Socket sock)
{
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
u_long mode = 1;
@ -169,7 +191,7 @@ int set_socket_nonblock(sock_t sock)
* return 1 on success
* return 0 on failure
*/
int set_socket_nosigpipe(sock_t sock)
int set_socket_nosigpipe(Socket sock)
{
#if defined(__MACH__)
int set = 1;
@ -184,7 +206,7 @@ int set_socket_nosigpipe(sock_t sock)
* return 1 on success
* return 0 on failure
*/
int set_socket_reuseaddr(sock_t sock)
int set_socket_reuseaddr(Socket sock)
{
int set = 1;
return (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&set, sizeof(set)) == 0);
@ -195,7 +217,7 @@ int set_socket_reuseaddr(sock_t sock)
* return 1 on success
* return 0 on failure
*/
int set_socket_dualstack(sock_t sock)
int set_socket_dualstack(Socket sock)
{
int ipv6only = 0;
socklen_t optsize = sizeof(ipv6only);
@ -310,6 +332,28 @@ static void loglogdata(Logger *log, const char *message, const uint8_t *buffer,
}
}
void get_ip4(IP4 *result, const struct in_addr *addr)
{
result->uint32 = addr->s_addr;
}
void get_ip6(IP6 *result, const struct in6_addr *addr)
{
assert(sizeof(result->uint8) == sizeof(addr->s6_addr));
memcpy(result->uint8, addr->s6_addr, sizeof(result->uint8));
}
void fill_addr4(IP4 ip, struct in_addr *addr)
{
addr->s_addr = ip.uint32;
}
void fill_addr6(IP6 ip, struct in6_addr *addr)
{
assert(sizeof(ip.uint8) == sizeof(addr->s6_addr));
memcpy(addr->s6_addr, ip.uint8, sizeof(ip.uint8));
}
/* Basic network functions:
* Function to send packet(data) of length length to ip_port.
@ -346,7 +390,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1
ip6.uint32[1] = 0;
ip6.uint32[2] = htonl(0xFFFF);
ip6.uint32[3] = ip_port.ip.ip4.uint32;
addr6->sin6_addr = ip6.in6_addr;
fill_addr6(ip6, &addr6->sin6_addr);
addr6->sin6_flowinfo = 0;
addr6->sin6_scope_id = 0;
@ -355,7 +399,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1
addrsize = sizeof(struct sockaddr_in);
addr4->sin_family = AF_INET;
addr4->sin_addr = ip_port.ip.ip4.in_addr;
fill_addr4(ip_port.ip.ip4, &addr4->sin_addr);
addr4->sin_port = ip_port.port;
}
} else if (ip_port.ip.family == AF_INET6) {
@ -364,7 +408,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1
addrsize = sizeof(struct sockaddr_in6);
addr6->sin6_family = AF_INET6;
addr6->sin6_port = ip_port.port;
addr6->sin6_addr = ip_port.ip.ip6.in6_addr;
fill_addr6(ip_port.ip.ip6, &addr6->sin6_addr);
addr6->sin6_flowinfo = 0;
addr6->sin6_scope_id = 0;
@ -385,7 +429,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1
* Packet data is put into data.
* Packet length is put into length.
*/
static int receivepacket(Logger *log, sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
static int receivepacket(Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
{
memset(ip_port, 0, sizeof(IP_Port));
struct sockaddr_storage addr;
@ -412,12 +456,12 @@ static int receivepacket(Logger *log, sock_t sock, IP_Port *ip_port, uint8_t *da
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
ip_port->ip.family = addr_in->sin_family;
ip_port->ip.ip4.in_addr = addr_in->sin_addr;
get_ip4(&ip_port->ip.ip4, &addr_in->sin_addr);
ip_port->port = addr_in->sin_port;
} else if (addr.ss_family == AF_INET6) {
struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr;
ip_port->ip.family = addr_in6->sin6_family;
ip_port->ip.ip6.in6_addr = addr_in6->sin6_addr;
get_ip6(&ip_port->ip.ip6, &addr_in6->sin6_addr);
ip_port->port = addr_in6->sin6_port;
if (IPV6_IPV4_IN_V6(ip_port->ip.ip6)) {
@ -634,7 +678,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1
addrsize = sizeof(struct sockaddr_in);
addr4->sin_family = AF_INET;
addr4->sin_port = 0;
addr4->sin_addr = ip.ip4.in_addr;
fill_addr4(ip.ip4, &addr4->sin_addr);
portptr = &addr4->sin_port;
} else if (temp->family == AF_INET6) {
@ -643,7 +687,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1
addrsize = sizeof(struct sockaddr_in6);
addr6->sin6_family = AF_INET6;
addr6->sin6_port = 0;
addr6->sin6_addr = ip.ip6.in6_addr;
fill_addr6(ip.ip6, &addr6->sin6_addr);
addr6->sin6_flowinfo = 0;
addr6->sin6_scope_id = 0;
@ -767,11 +811,16 @@ int ip_equal(const IP *a, const IP *b)
/* same family */
if (a->family == b->family) {
if (a->family == AF_INET) {
return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr);
struct in_addr addr_a;
struct in_addr addr_b;
fill_addr4(a->ip4, &addr_a);
fill_addr4(b->ip4, &addr_b);
return addr_a.s_addr == addr_b.s_addr;
}
if (a->family == AF_INET6) {
return a->ip6.uint64[0] == b->ip6.uint64[0] && a->ip6.uint64[1] == b->ip6.uint64[1];
return a->ip6.uint64[0] == b->ip6.uint64[0] &&
a->ip6.uint64[1] == b->ip6.uint64[1];
}
return 0;
@ -780,11 +829,15 @@ int ip_equal(const IP *a, const IP *b)
/* different family: check on the IPv6 one if it is the IPv4 one embedded */
if ((a->family == AF_INET) && (b->family == AF_INET6)) {
if (IPV6_IPV4_IN_V6(b->ip6)) {
return (a->ip4.in_addr.s_addr == b->ip6.uint32[3]);
struct in_addr addr_a;
fill_addr4(a->ip4, &addr_a);
return addr_a.s_addr == b->ip6.uint32[3];
}
} else if ((a->family == AF_INET6) && (b->family == AF_INET)) {
if (IPV6_IPV4_IN_V6(a->ip6)) {
return (a->ip6.uint32[3] == b->ip4.in_addr.s_addr);
struct in_addr addr_b;
fill_addr4(b->ip4, &addr_b);
return a->ip6.uint32[3] == addr_b.s_addr;
}
}
@ -976,7 +1029,7 @@ int addr_parse_ip(const char *address, IP *to)
if (1 == inet_pton(AF_INET, address, &addr4)) {
to->family = AF_INET;
to->ip4.in_addr = addr4;
get_ip4(&to->ip4, &addr4);
return 1;
}
@ -984,7 +1037,7 @@ int addr_parse_ip(const char *address, IP *to)
if (1 == inet_pton(AF_INET6, address, &addr6)) {
to->family = AF_INET6;
to->ip6.in6_addr = addr6;
get_ip6(&to->ip6, &addr6);
return 1;
}
@ -1048,12 +1101,12 @@ int addr_resolve(const char *address, IP *to, IP *extra)
case AF_INET:
if (walker->ai_family == family) { /* AF_INET requested, done */
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
to->ip4.in_addr = addr->sin_addr;
get_ip4(&to->ip4, &addr->sin_addr);
result = TOX_ADDR_RESOLVE_INET;
done = 1;
} else if (!(result & TOX_ADDR_RESOLVE_INET)) { /* AF_UNSPEC requested, store away */
struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
ip4.ip4.in_addr = addr->sin_addr;
get_ip4(&ip4.ip4, &addr->sin_addr);
result |= TOX_ADDR_RESOLVE_INET;
}
@ -1063,14 +1116,14 @@ int addr_resolve(const char *address, IP *to, IP *extra)
if (walker->ai_family == family) { /* AF_INET6 requested, done */
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
to->ip6.in6_addr = addr->sin6_addr;
get_ip6(&to->ip6, &addr->sin6_addr);
result = TOX_ADDR_RESOLVE_INET6;
done = 1;
}
} else if (!(result & TOX_ADDR_RESOLVE_INET6)) { /* AF_UNSPEC requested, store away */
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
ip6.ip6.in6_addr = addr->sin6_addr;
get_ip6(&ip6.ip6, &addr->sin6_addr);
result |= TOX_ADDR_RESOLVE_INET6;
}
}

View File

@ -58,53 +58,21 @@
#include <windows.h>
#include <ws2tcpip.h>
#ifndef IPV6_V6ONLY
#define IPV6_V6ONLY 27
#endif
typedef unsigned int sock_t;
/* sa_family_t is the sockaddr_in / sockaddr_in6 family field */
typedef short sa_family_t;
#ifndef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK
#endif
#else // Linux includes
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
typedef int sock_t;
#endif
#if defined(__AIX__)
# define _XOPEN_SOURCE 1
#endif
struct in_addr;
struct in6_addr;
#if defined(__sun__)
#define __EXTENSIONS__ 1 // SunOS!
#if defined(__SunOS5_6__) || defined(__SunOS5_7__) || defined(__SunOS5_8__) || defined(__SunOS5_9__) || defined(__SunOS5_10__)
//Nothing needed
#else
#define __MAKECONTEXT_V2_SOURCE 1
#endif
#endif
#ifndef IPV6_ADD_MEMBERSHIP
#ifdef IPV6_JOIN_GROUP
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#endif
#endif
typedef int Socket;
#define MAX_UDP_PACKET_SIZE 2048
@ -154,7 +122,6 @@ typedef union {
uint8_t uint8[4];
uint16_t uint16[2];
uint32_t uint32;
struct in_addr in_addr;
}
IP4;
@ -163,7 +130,6 @@ typedef union {
uint16_t uint16[8];
uint32_t uint32[4];
uint64_t uint64[2];
struct in6_addr in6_addr;
}
IP6;
@ -182,6 +148,14 @@ typedef struct {
}
IP_Port;
/* Convert in_addr to IP */
void get_ip4(IP4 *ip, const struct in_addr *addr);
void get_ip6(IP6 *ip, const struct in6_addr *addr);
/* Conevrt IP to in_addr */
void fill_addr4(IP4 ip, struct in_addr *addr);
void fill_addr6(IP6 ip, struct in6_addr *addr);
/* Does the IP6 struct a contain an IPv4 address in an IPv6 one? */
#define IPV6_IPV4_IN_V6(a) ((a.uint64[0] == 0) && (a.uint32[2] == htonl (0xffff)))
@ -326,7 +300,7 @@ typedef struct {
sa_family_t family;
uint16_t port;
/* Our UDP socket. */
sock_t sock;
Socket sock;
} Networking_Core;
/* Run this before creating sockets.
@ -341,39 +315,39 @@ int networking_at_startup(void);
* return 1 if valid
* return 0 if not valid
*/
int sock_valid(sock_t sock);
int sock_valid(Socket sock);
/* Close the socket.
*/
void kill_sock(sock_t sock);
void kill_sock(Socket sock);
/* Set socket as nonblocking
*
* return 1 on success
* return 0 on failure
*/
int set_socket_nonblock(sock_t sock);
int set_socket_nonblock(Socket sock);
/* Set socket to not emit SIGPIPE
*
* return 1 on success
* return 0 on failure
*/
int set_socket_nosigpipe(sock_t sock);
int set_socket_nosigpipe(Socket sock);
/* Enable SO_REUSEADDR on socket.
*
* return 1 on success
* return 0 on failure
*/
int set_socket_reuseaddr(sock_t sock);
int set_socket_reuseaddr(Socket sock);
/* Set socket to dual (IPv4 + IPv6 socket)
*
* return 1 on success
* return 0 on failure
*/
int set_socket_dualstack(sock_t sock);
int set_socket_dualstack(Socket sock);
/* return current monotonic time in milliseconds (ms). */
uint64_t current_time_monotonic(void);

View File

@ -254,9 +254,11 @@ bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *
}
if (info->ai_family == AF_INET) {
ip_port.ip.ip4.in_addr = ((struct sockaddr_in *)info->ai_addr)->sin_addr;
struct sockaddr_in *addr = (struct sockaddr_in *)info->ai_addr;
get_ip4(&ip_port.ip.ip4, &addr->sin_addr);
} else if (info->ai_family == AF_INET6) {
ip_port.ip.ip6.in6_addr = ((struct sockaddr_in6 *)info->ai_addr)->sin6_addr;
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)info->ai_addr;
get_ip6(&ip_port.ip.ip6, &addr->sin6_addr);
} else {
continue;
}
@ -312,9 +314,11 @@ bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8
}
if (info->ai_family == AF_INET) {
ip_port.ip.ip4.in_addr = ((struct sockaddr_in *)info->ai_addr)->sin_addr;
struct sockaddr_in *addr = (struct sockaddr_in *)info->ai_addr;
get_ip4(&ip_port.ip.ip4, &addr->sin_addr);
} else if (info->ai_family == AF_INET6) {
ip_port.ip.ip6.in6_addr = ((struct sockaddr_in6 *)info->ai_addr)->sin6_addr;
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)info->ai_addr;
get_ip6(&ip_port.ip.ip6, &addr->sin6_addr);
} else {
continue;
}