Extend network traversal to local addresses

This commit is contained in:
mid 2025-06-29 20:47:14 +03:00
parent e126db573a
commit 355df2ee44
9 changed files with 222 additions and 132 deletions

View File

@ -2224,9 +2224,9 @@ static int dagame_set_texture_reduction(lua_State *L) {
} }
int PeercodeHandler = LUA_NOREF; int PeercodeHandler = LUA_NOREF;
static void get_peercode_callback(void *ud, const char *peercode_bin) { static void get_peercode_callback(void *ud, struct StoonPeercode *peercode_bin) {
char peercode[STOON_CONN_INFO_SIZE * 2 + 1] = {}; char peercode[sizeof(*peercode_bin) * 2 + 1] = {};
for(int i = 0; i < STOON_CONN_INFO_SIZE; i++) { for(int i = 0; i < sizeof(*peercode_bin); i++) {
snprintf(peercode + i * 2, 3, "%02x", ((uint8_t*) peercode_bin)[i]); snprintf(peercode + i * 2, 3, "%02x", ((uint8_t*) peercode_bin)[i]);
} }
@ -2296,11 +2296,11 @@ static int get_peercode_bin(const char *peercode, char *peercode_bin) {
if(!peercode) return 0; if(!peercode) return 0;
if(!peercode_bin) return 0; if(!peercode_bin) return 0;
if(strlen(peercode) < 2 * STOON_CONN_INFO_SIZE) { if(strlen(peercode) < 2 * sizeof(struct StoonPeercode)) {
return 0; return 0;
} }
for(int i = 0; i < STOON_CONN_INFO_SIZE; i++) { for(int i = 0; i < sizeof(struct StoonPeercode); i++) {
int b = 0; int b = 0;
if(peercode[i * 2 + 0] >= '0' && peercode[i * 2 + 0] <= '9') { if(peercode[i * 2 + 0] >= '0' && peercode[i * 2 + 0] <= '9') {
@ -2328,8 +2328,8 @@ static int dagame_net_host(lua_State *L) {
} }
static int dagame_net_join(lua_State *L) { static int dagame_net_join(lua_State *L) {
char peercode[STOON_CONN_INFO_SIZE]; struct StoonPeercode peercode;
if(!get_peercode_bin(lua_tostring(L, 1), peercode)) { if(!get_peercode_bin(lua_tostring(L, 1), &peercode)) {
lua_pushliteral(L, "Invalid peercode"); lua_pushliteral(L, "Invalid peercode");
lua_error(L); lua_error(L);
return 0; return 0;
@ -2337,20 +2337,20 @@ static int dagame_net_join(lua_State *L) {
net_hi_setup(false); net_hi_setup(false);
lua_pushboolean(L, net_hi_connect(peercode)); lua_pushboolean(L, net_hi_connect(&peercode));
return 1; return 1;
} }
static int dagame_net_punch(lua_State *L) { static int dagame_net_punch(lua_State *L) {
char peercode[STOON_CONN_INFO_SIZE]; struct StoonPeercode peercode;
if(!get_peercode_bin(lua_tostring(L, 1), peercode)) { if(!get_peercode_bin(lua_tostring(L, 1), &peercode)) {
lua_pushliteral(L, "Invalid peercode"); lua_pushliteral(L, "Invalid peercode");
lua_error(L); lua_error(L);
return 0; return 0;
} }
net_hi_add_punch(peercode); net_hi_add_punch(&peercode);
return 0; return 0;
} }

View File

@ -26,11 +26,7 @@ void net_client_init() {
Game.isAuthority = 0; Game.isAuthority = 0;
} }
bool net_client_connect(const char *addr, uint16_t port) { bool net_client_connect(ENetAddress eaddr) {
ENetAddress eaddr;
enet_address_set_host(&eaddr, addr);
eaddr.port = port;
peer = enet_host_connect(host, &eaddr, 1, 0); peer = enet_host_connect(host, &eaddr, 1, 0);
ENetEvent ev; ENetEvent ev;

View File

@ -1,7 +1,9 @@
#pragma once #pragma once
#include"enet.h"
void net_client_init(); void net_client_init();
bool net_client_connect(const char *addr, uint16_t port); bool net_client_connect(ENetAddress addr);
void net_client_receive(); void net_client_receive();
void net_client_update(); void net_client_update();
void net_client_dejitter(); void net_client_dejitter();

View File

@ -7,9 +7,15 @@
#include"net_server.h" #include"net_server.h"
#include"net_client.h" #include"net_client.h"
#include<math.h> #include<math.h>
#include"k3.h"
/*
* Handles networking on a higher-level, combining hole punching with
* basic client & server interface
* */
static void *ReqPeercodeUD; static void *ReqPeercodeUD;
static void(*ReqPeercodeCB)(void*, const char *peercode); static void(*ReqPeercodeCB)(void*, struct StoonPeercode *peercode);
static struct Stoon stoon; static struct Stoon stoon;
@ -17,11 +23,11 @@ static bool inited = false;
static bool isHost; static bool isHost;
typedef struct { typedef struct {
#define MASK_IPv4 1 ENetAddress pv4;
#define MASK_IPv6 2 ENetAddress pv6;
int mask;
ENetAddress v4; ENetAddress lv4;
ENetAddress v6; ENetAddress lv6;
} ToPunch; } ToPunch;
static ToPunch *topunch = NULL; static ToPunch *topunch = NULL;
static size_t topunchCount = 0; static size_t topunchCount = 0;
@ -30,13 +36,22 @@ static double Timeout = 0;
static bool connected = false; static bool connected = false;
bool net_hi_request_peercode(void *ud, void(*callback)(void*, const char *peercode)) { static uint16_t servport = 0;
bool net_hi_request_peercode(void *ud, void(*callback)(void*, struct StoonPeercode *peercode)) {
if(inited) return false; if(inited) return false;
ReqPeercodeUD = ud; ReqPeercodeUD = ud;
ReqPeercodeCB = callback; ReqPeercodeCB = callback;
stoon = stoon_init("stun.easybell.de", 3478, 26656); for(size_t port = 25000; port <= 26656; port++) {
stoon = stoon_init("stun.easybell.de", 3478, port);
if(stoon.fd4 >= 0 || stoon.fd6 >= 0) {
servport = port;
break;
}
}
Timeout = 0; Timeout = 0;
@ -52,7 +67,7 @@ bool net_hi_setup(bool host) {
isHost = host; isHost = host;
if(host) { if(host) {
net_server_init(); net_server_init(servport);
} else { } else {
net_client_init(); net_client_init();
} }
@ -67,16 +82,17 @@ void net_hi_update(double now) {
if(stoon_req(&stoon)) { if(stoon_req(&stoon)) {
if(stoon_listen(&stoon)) { if(stoon_listen(&stoon)) {
uint8_t peercode[STOON_CONN_INFO_SIZE] = {}; ReqPeercodeCB(ReqPeercodeUD, &stoon.peercode);
stoon_serialize(&stoon, peercode);
ReqPeercodeCB(ReqPeercodeUD, peercode);
ReqPeercodeCB = NULL; ReqPeercodeCB = NULL;
} else { } else {
k3Log(k3_INFO, "stoon_listen failure");
Timeout = now + 1; Timeout = now + 1;
} }
} else { } else {
k3Log(k3_INFO, "stoon_req failure");
Timeout = now + 1; Timeout = now + 1;
} }
@ -97,11 +113,11 @@ void net_hi_update(double now) {
for(size_t tpi = 0; tpi < topunchCount; tpi++) { for(size_t tpi = 0; tpi < topunchCount; tpi++) {
ToPunch *tp = &topunch[tpi]; ToPunch *tp = &topunch[tpi];
if(tp->mask & MASK_IPv4) { if(tp->lv6.port) enet_socket_send(h->socket, &tp->lv6, &buf, 1);
enet_socket_send(h->socket, &tp->v4, &buf, 1); if(tp->lv4.port) enet_socket_send(h->socket, &tp->lv4, &buf, 1);
} else if(tp->mask & MASK_IPv6) {
enet_socket_send(h->socket, &tp->v6, &buf, 1); if(tp->pv6.port) enet_socket_send(h->socket, &tp->pv6, &buf, 1);
} if(tp->pv4.port) enet_socket_send(h->socket, &tp->pv4, &buf, 1);
} }
} }
@ -111,57 +127,85 @@ void net_hi_update(double now) {
} }
} }
static void stoonpeer_to_enets(const char *peercode, ENetAddress *v4, ENetAddress *v6, int *mask) { static bool stoonpeer_to_enet4(uint8_t *publicV4, uint8_t *publicP4, ENetAddress *enet) {
uint8_t *addr8 = (uint8_t*) &v4->host; memset(enet, 0, sizeof(*enet));
if(*(uint32_t*) publicV4 == 0 || *(uint16_t*) publicP4 == 0) {
return false;
}
uint8_t *addr8 = (uint8_t*) &enet->host;
memset(addr8, 0, 16); memset(addr8, 0, 16);
addr8[10] = 0xFF; addr8[10] = 0xFF;
addr8[11] = 0xFF; addr8[11] = 0xFF;
addr8[12] = peercode[0]; addr8[12] = publicV4[0];
addr8[13] = peercode[1]; addr8[13] = publicV4[1];
addr8[14] = peercode[2]; addr8[14] = publicV4[2];
addr8[15] = peercode[3]; addr8[15] = publicV4[3];
v4->port = ntohs(*(uint16_t*) &peercode[4]); enet->port = *(uint16_t*) publicP4;
memcpy(&v6->host, peercode + 6, 16); return true;
v6->port = ntohs(*(uint16_t*) &peercode[22]);
*mask = 0;
if(v4->port) {
*mask |= MASK_IPv4;
}
if(v6->port) {
*mask |= MASK_IPv6;
}
} }
void net_hi_add_punch(const char *peercode) { static bool stoonpeer_to_enet6(uint8_t *publicV6, uint8_t *publicP6, ENetAddress *enet) {
int mask; memset(enet, 0, sizeof(*enet));
ENetAddress v4 = {}, v6 = {};
stoonpeer_to_enets(peercode, &v4, &v6, &mask);
if(*(uint32_t*) publicV6 == 0 || *(uint16_t*) publicP6 == 0) {
return false;
}
uint8_t *addr8 = (uint8_t*) &enet->host;
memcpy(addr8, publicV6, 16);
enet->port = *(uint16_t*) publicP6;
return true;
}
void net_hi_add_punch(struct StoonPeercode *peercode) {
topunch = realloc(topunch, sizeof(*topunch) * (++topunchCount)); topunch = realloc(topunch, sizeof(*topunch) * (++topunchCount));
topunch[topunchCount - 1] = (ToPunch) { ToPunch *tp = &topunch[topunchCount - 1];
.v4 = v4,
.v6 = v6, stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &tp->pv4);
.mask = mask, stoonpeer_to_enet6(peercode->publicV6, peercode->publicP6, &tp->pv6);
};
stoonpeer_to_enet4(peercode->localV4, peercode->localP4, &tp->lv4);
stoonpeer_to_enet6(peercode->localV6, peercode->localP6, &tp->lv6);
} }
bool net_hi_connect(const char *peercode) { bool net_hi_connect(struct StoonPeercode *peercode) {
if(!inited) return false; if(!inited) return false;
if(connected) return false; if(connected) return false;
char ip[64]; ENetAddress pv4, pv6;
int port; stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &pv4);
if(*(uint16_t*) (peercode + 22) == 0) { stoonpeer_to_enet6(peercode->publicV6, peercode->publicP6, &pv6);
inet_ntop(AF_INET, peercode, ip, sizeof(ip));
port = ntohs(*(uint16_t*) (peercode + 4)); ENetAddress lv4, lv6;
} else { stoonpeer_to_enet4(peercode->localV4, peercode->localP4, &lv4);
inet_ntop(AF_INET6, peercode + 6, ip, sizeof(ip)); stoonpeer_to_enet6(peercode->localV6, peercode->localP6, &lv6);
port = ntohs(*(uint16_t*) (peercode + 22));
if(lv6.port && net_client_connect(lv6)) {
k3Log(k3_INFO, "Found local IPv6");
return true;
}
if(lv4.port && net_client_connect(lv4)) {
k3Log(k3_INFO, "Found local IPv4");
return true;
} }
return net_client_connect(ip, port); if(pv6.port && net_client_connect(pv6)) {
k3Log(k3_INFO, "Found remote IPv6");
return true;
}
if(pv4.port && net_client_connect(pv4)) {
k3Log(k3_INFO, "Found remote IPv4");
return true;
}
k3Log(k3_INFO, "Failed to establish connection");
return false;
} }

View File

@ -2,10 +2,12 @@
#include<stdbool.h> #include<stdbool.h>
bool net_hi_request_peercode(void *ud, void(*callback)(void*, const char *peercode)); struct StoonPeercode;
bool net_hi_request_peercode(void *ud, void(*callback)(void*, struct StoonPeercode *peercode));
bool net_hi_setup(bool host); bool net_hi_setup(bool host);
void net_hi_update(double now); void net_hi_update(double now);
void net_hi_add_punch(const char *peercode); void net_hi_add_punch(struct StoonPeercode *peercode);
bool net_hi_connect(const char *peercode); bool net_hi_connect(struct StoonPeercode *peercode);

View File

@ -18,8 +18,8 @@ struct Conn {
#define MAX_PLAYERS 64 #define MAX_PLAYERS 64
static struct Conn conns[MAX_PLAYERS]; static struct Conn conns[MAX_PLAYERS];
void net_server_init() { void net_server_init(uint16_t port) {
host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = 26656}, 16, 1, 0, 0); host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = port}, 16, 1, 0, 0);
Game.isMultiplayer = 1; Game.isMultiplayer = 1;
Game.isAuthority = 1; Game.isAuthority = 1;

View File

@ -5,7 +5,7 @@
struct _ENetPeer; struct _ENetPeer;
struct bstr; struct bstr;
void net_server_init(); void net_server_init(uint16_t port);
void net_server_receive(); void net_server_receive();
void net_server_update(); void net_server_update();

View File

@ -17,6 +17,7 @@
#include<string.h> #include<string.h>
#include<stdio.h> #include<stdio.h>
#include<errno.h> #include<errno.h>
#include<ifaddrs.h>
#define STUN_BINDING_REQUEST 0x0001 #define STUN_BINDING_REQUEST 0x0001
#define STUN_BINDING_INDICATION 0x1100 #define STUN_BINDING_INDICATION 0x1100
@ -43,7 +44,7 @@ struct StunMsg {
uint8_t id[12]; uint8_t id[12];
}; };
static int stoon_init_mini(struct addrinfo *serv, uint16_t myport) { static int stoon_init_mini(struct Stoon *this, struct addrinfo *serv, uint16_t myport) {
#ifdef _WIN32 #ifdef _WIN32
errno = 0; errno = 0;
int fd = socket(serv->ai_family, serv->ai_socktype, serv->ai_protocol); int fd = socket(serv->ai_family, serv->ai_socktype, serv->ai_protocol);
@ -59,16 +60,71 @@ static int stoon_init_mini(struct addrinfo *serv, uint16_t myport) {
char p[6]; char p[6];
sprintf(p, "%u", myport); sprintf(p, "%u", myport);
struct addrinfo *myaddr; struct addrinfo *myaddrinfo;
if(getaddrinfo(NULL, p, &(struct addrinfo) {.ai_family = serv->ai_family, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP, .ai_flags = AI_PASSIVE}, &myaddr)) { if(getaddrinfo(NULL, p, &(struct addrinfo) {.ai_family = serv->ai_family, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP, .ai_flags = AI_PASSIVE}, &myaddrinfo)) {
close(fd); close(fd);
return -1; return -1;
} }
if(bind(fd, myaddr->ai_addr, myaddr->ai_addrlen)) { if(bind(fd, myaddrinfo->ai_addr, myaddrinfo->ai_addrlen)) {
close(fd); close(fd);
return -2; return -2;
} }
freeaddrinfo(myaddr);
freeaddrinfo(myaddrinfo);
#ifdef _WIN32
IP_ADAPTER_ADDRESSES *addrs = malloc(1024 * 64);
if(GetAdaptersAddresses(serv->ai_family, GAA_FLAG_SKIP_MULTICAST, NULL, &addrs) == NO_ERROR) {
for(IP_ADAPTER_ADDRESSES *ifa = addrs; ifa; ifa = ifa->Next) {
if(serv->ai_family == AF_INET6) {
uint8_t *addr = (void*) &((struct sockaddr_in6*) ifa->FirstUnicastAddress->Address.lpSockaddr)->sin6_addr;
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 && addr[4] == 0 && addr[5] == 0 && addr[6] == 0 && addr[7] == 0 && addr[8] == 0 && addr[9] == 0 && addr[10] == 0 && addr[11] == 0 && addr[12] == 0 && addr[13] == 0 && addr[14] == 0 && (addr[15] == 0 || addr[15] == 1)) {
continue;
}
memcpy(this->peercode.localV6, addr, 16);
memcpy(this->peercode.localP6, &myport, 2);
} else {
uint8_t *addr = (void*) &((struct sockaddr_in*) ifa->FirstUnicastAddress->Address.lpSockaddr)->sin_addr;
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 || addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1) {
continue;
}
memcpy(this->peercode.localV4, addr, 4);
memcpy(this->peercode.localP4, &myport, 2);
}
}
}
free(addrs);
#else
struct ifaddrs *ifaddr;
if(getifaddrs(&ifaddr) >= 0) {
for(struct ifaddrs *ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
if(ifa->ifa_addr->sa_family == serv->ai_family) {
if(serv->ai_family == AF_INET6) {
uint8_t *addr = (void*) &((struct sockaddr_in6*) ifa->ifa_addr)->sin6_addr;
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 && addr[4] == 0 && addr[5] == 0 && addr[6] == 0 && addr[7] == 0 && addr[8] == 0 && addr[9] == 0 && addr[10] == 0 && addr[11] == 0 && addr[12] == 0 && addr[13] == 0 && addr[14] == 0 && (addr[15] == 0 || addr[15] == 1)) {
continue;
}
memcpy(this->peercode.localV6, addr, 16);
memcpy(this->peercode.localP6, &myport, 2);
} else {
uint8_t *addr = (void*) &((struct sockaddr_in*) ifa->ifa_addr)->sin_addr;
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 || addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1) {
continue;
}
memcpy(this->peercode.localV4, addr, 4);
memcpy(this->peercode.localP4, &myport, 2);
}
break;
}
}
freeifaddrs(ifaddr);
}
#endif
return fd; return fd;
} }
@ -92,18 +148,16 @@ struct Stoon stoon_init(const char *stunhost, uint16_t stunport, uint16_t myport
} }
} }
struct Stoon ret; struct Stoon ret = {};
memset(&ret.my4, 0, sizeof(ret.my4));
if(v4) { if(v4) {
memcpy(&ret.stu4, v4->ai_addr, v4->ai_addrlen); memcpy(&ret.stu4, v4->ai_addr, v4->ai_addrlen);
ret.fd4 = stoon_init_mini(v4, myport); ret.fd4 = stoon_init_mini(&ret, v4, myport);
} else ret.fd4 = -1; } else ret.fd4 = -1;
memset(&ret.my6, 0, sizeof(ret.my6));
if(v6) { if(v6) {
memcpy(&ret.stu6, v6->ai_addr, v6->ai_addrlen); memcpy(&ret.stu6, v6->ai_addr, v6->ai_addrlen);
ret.fd6 = stoon_init_mini(v6, myport); ret.fd6 = stoon_init_mini(&ret, v6, myport);
} else ret.fd6 = -1; } else ret.fd6 = -1;
ret.poonchstage = 0; ret.poonchstage = 0;
@ -121,12 +175,21 @@ static int stoon_req_mini(struct Stoon *this, int *fd, struct sockaddr *serv, in
if(errno == ENETUNREACH) { if(errno == ENETUNREACH) {
close(*fd); close(*fd);
*fd = -1; *fd = -1;
return false;
} }
} }
return true;
} }
int stoon_req(struct Stoon *this) { int stoon_req(struct Stoon *this) {
if(this->fd4 >= 0) stoon_req_mini(this, &this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in)); if(this->fd4 >= 0) stoon_req_mini(this, &this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in));
if(this->fd6 >= 0) stoon_req_mini(this, &this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6)); if(this->fd6 >= 0) stoon_req_mini(this, &this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6));
if(this->fd4 < 0 && this->fd6 < 0) {
return false;
}
return true;
} }
static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv, int servlen) { static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv, int servlen) {
@ -161,11 +224,10 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
uint16_t netfam = ntohs(((uint16_t*) d)[2]); uint16_t netfam = ntohs(((uint16_t*) d)[2]);
uint16_t publicPort = ntohs(((uint16_t*) d)[3]) ^ (STUN_MAGIC >> 16); uint16_t publicPort = ntohs(((uint16_t*) d)[3]) ^ (STUN_MAGIC >> 16);
if(netfam == STUN_NETFAM_IPV4) { if(netfam == STUN_NETFAM_IPV4) {
uint32_t publicIp = ntohl(((uint32_t*) d)[2]) ^ STUN_MAGIC; uint32_t publicIp = htonl(ntohl(((uint32_t*) d)[2]) ^ STUN_MAGIC);
this->my4.sin_family = AF_INET; memcpy(this->peercode.publicV4, &publicIp, 4);
memcpy(&this->my4.sin_addr, &publicIp, 4); memcpy(this->peercode.publicP4, &publicPort, 2);
this->my4.sin_port = htons(publicPort);
return 1; return 1;
} else if(netfam == STUN_NETFAM_IPV6) { } else if(netfam == STUN_NETFAM_IPV6) {
@ -175,9 +237,8 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
publicIp[2] = ((uint32_t*) d)[4] ^ ((uint32_t*) res.base.id)[1]; publicIp[2] = ((uint32_t*) d)[4] ^ ((uint32_t*) res.base.id)[1];
publicIp[3] = ((uint32_t*) d)[5] ^ ((uint32_t*) res.base.id)[2]; publicIp[3] = ((uint32_t*) d)[5] ^ ((uint32_t*) res.base.id)[2];
this->my6.sin6_family = AF_INET6; memcpy(this->peercode.publicV6, &publicIp, 16);
memcpy(&this->my6.sin6_addr, &publicIp, 16); memcpy(this->peercode.publicP6, &publicPort, 2);
this->my6.sin6_port = htons(publicPort);
return 1; return 1;
} else { } else {
@ -188,12 +249,12 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
d += 4 + attribLen; d += 4 + attribLen;
} }
return 0; return false;
} }
int stoon_listen(struct Stoon *this) { int stoon_listen(struct Stoon *this) {
if(this->fd4 >= 0) if(stoon_listen_mini(this, this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in)) < 0) return 0; if(this->fd4 >= 0) if(stoon_listen_mini(this, this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in)) < 0) return 0;
if(this->fd6 >= 0) if(stoon_listen_mini(this, this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6)) < 0) return 0; if(this->fd6 >= 0) if(stoon_listen_mini(this, this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6)) < 0) return 0;
return 1; return true;
} }
void stoon_keepalive(struct Stoon *this) { void stoon_keepalive(struct Stoon *this) {
@ -217,31 +278,7 @@ void stoon_kill(struct Stoon *this) {
this->fd6 = -1; this->fd6 = -1;
} }
int stoon_v4_available(struct Stoon *this) { /*int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]) {
return this->fd4 >= 0;
}
int stoon_v6_available(struct Stoon *this) {
return this->fd6 >= 0;
}
void stoon_serialize(struct Stoon *this, uint8_t ret[static STOON_CONN_INFO_SIZE]) {
if(this->fd4 >= 0) {
memcpy(ret + 0, &this->my4.sin_addr, 4);
memcpy(ret + 4, &this->my4.sin_port, 2);
} else {
memset(ret, 0, 6);
}
if(this->fd6 >= 0) {
memcpy(ret + 6, &this->my6.sin6_addr, 16);
memcpy(ret + 22, &this->my6.sin6_port, 2);
} else {
memset(ret + 6, 0, 18);
}
}
int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]) {
struct { struct {
uint32_t addr4; uint32_t addr4;
uint16_t port4; uint16_t port4;
@ -303,7 +340,7 @@ int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_IN
} }
return STOON_POONCH_NO_KNOCK; return STOON_POONCH_NO_KNOCK;
} }*/
#ifdef STOON_STANDALONE #ifdef STOON_STANDALONE
int main() { int main() {

View File

@ -6,6 +6,7 @@
#include<stddef.h> #include<stddef.h>
#include<stdint.h> #include<stdint.h>
#include<stdbool.h>
#ifdef _WIN32 #ifdef _WIN32
#include<winsock2.h> #include<winsock2.h>
@ -16,8 +17,6 @@
/* Standalone hole punching libary (IPv4 & IPv6 compatible) */ /* Standalone hole punching libary (IPv4 & IPv6 compatible) */
#define STOON_CONN_INFO_SIZE (4 + 2 + 16 + 2)
#define POONCH_MAGIC 0x504F4348 #define POONCH_MAGIC 0x504F4348
#define POONCH_STAGE_KNOCKING 0 #define POONCH_STAGE_KNOCKING 0
#define POONCH_STAGE_ACK 1 #define POONCH_STAGE_ACK 1
@ -26,16 +25,30 @@ struct Poonch {
uint32_t stage; uint32_t stage;
}; };
struct StoonPeercode {
uint8_t publicV4[4];
uint8_t publicP4[2];
uint8_t publicV6[16];
uint8_t publicP6[2];
uint8_t localV4[4];
uint8_t localP4[2];
uint8_t localV6[16];
uint8_t localP6[2];
};
struct Stoon { struct Stoon {
struct sockaddr_in stu4; struct sockaddr_in stu4;
struct sockaddr_in my4;
int fd4; int fd4;
struct sockaddr_in6 stu6; struct sockaddr_in6 stu6;
struct sockaddr_in6 my6;
int fd6; int fd6;
uint8_t poonchstage; uint8_t poonchstage;
struct StoonPeercode peercode;
}; };
// stunhost: Self-explanatory // stunhost: Self-explanatory
@ -53,12 +66,8 @@ void stoon_keepalive(struct Stoon*);
void stoon_kill(struct Stoon*); void stoon_kill(struct Stoon*);
int stoon_v4_available(struct Stoon*); /*#define STOON_POONCH_INCOMPATIBLE_NETFAMS (-1)
int stoon_v6_available(struct Stoon*);
void stoon_serialize(struct Stoon*, uint8_t ret[static STOON_CONN_INFO_SIZE]);
#define STOON_POONCH_INCOMPATIBLE_NETFAMS (-1)
#define STOON_POONCH_NO_KNOCK 0 #define STOON_POONCH_NO_KNOCK 0
#define STOON_POONCH_ACKED 1 #define STOON_POONCH_ACKED 1
int stoon_poonch(struct Stoon*, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]); int stoon_poonch(struct Stoon*, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]);
*/