From 355df2ee442821ae7e3cc385eb9e38be3179f762 Mon Sep 17 00:00:00 2001 From: mid <> Date: Sun, 29 Jun 2025 20:47:14 +0300 Subject: [PATCH] Extend network traversal to local addresses --- src/luaapi.c | 22 +++---- src/net_client.c | 6 +- src/net_client.h | 4 +- src/net_hi.c | 152 ++++++++++++++++++++++++++++++----------------- src/net_hi.h | 8 ++- src/net_server.c | 4 +- src/net_server.h | 2 +- src/stoon.c | 127 +++++++++++++++++++++++++-------------- src/stoon.h | 29 +++++---- 9 files changed, 222 insertions(+), 132 deletions(-) diff --git a/src/luaapi.c b/src/luaapi.c index e80714c..cdb470d 100644 --- a/src/luaapi.c +++ b/src/luaapi.c @@ -2224,9 +2224,9 @@ static int dagame_set_texture_reduction(lua_State *L) { } int PeercodeHandler = LUA_NOREF; -static void get_peercode_callback(void *ud, const char *peercode_bin) { - char peercode[STOON_CONN_INFO_SIZE * 2 + 1] = {}; - for(int i = 0; i < STOON_CONN_INFO_SIZE; i++) { +static void get_peercode_callback(void *ud, struct StoonPeercode *peercode_bin) { + char peercode[sizeof(*peercode_bin) * 2 + 1] = {}; + for(int i = 0; i < sizeof(*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_bin) return 0; - if(strlen(peercode) < 2 * STOON_CONN_INFO_SIZE) { + if(strlen(peercode) < 2 * sizeof(struct StoonPeercode)) { return 0; } - for(int i = 0; i < STOON_CONN_INFO_SIZE; i++) { + for(int i = 0; i < sizeof(struct StoonPeercode); i++) { int b = 0; 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) { - char peercode[STOON_CONN_INFO_SIZE]; - if(!get_peercode_bin(lua_tostring(L, 1), peercode)) { + struct StoonPeercode peercode; + if(!get_peercode_bin(lua_tostring(L, 1), &peercode)) { lua_pushliteral(L, "Invalid peercode"); lua_error(L); return 0; @@ -2337,20 +2337,20 @@ static int dagame_net_join(lua_State *L) { net_hi_setup(false); - lua_pushboolean(L, net_hi_connect(peercode)); + lua_pushboolean(L, net_hi_connect(&peercode)); return 1; } static int dagame_net_punch(lua_State *L) { - char peercode[STOON_CONN_INFO_SIZE]; - if(!get_peercode_bin(lua_tostring(L, 1), peercode)) { + struct StoonPeercode peercode; + if(!get_peercode_bin(lua_tostring(L, 1), &peercode)) { lua_pushliteral(L, "Invalid peercode"); lua_error(L); return 0; } - net_hi_add_punch(peercode); + net_hi_add_punch(&peercode); return 0; } diff --git a/src/net_client.c b/src/net_client.c index fe04bd3..eca190f 100644 --- a/src/net_client.c +++ b/src/net_client.c @@ -26,11 +26,7 @@ void net_client_init() { Game.isAuthority = 0; } -bool net_client_connect(const char *addr, uint16_t port) { - ENetAddress eaddr; - enet_address_set_host(&eaddr, addr); - eaddr.port = port; - +bool net_client_connect(ENetAddress eaddr) { peer = enet_host_connect(host, &eaddr, 1, 0); ENetEvent ev; diff --git a/src/net_client.h b/src/net_client.h index fd303d7..1b22eb8 100644 --- a/src/net_client.h +++ b/src/net_client.h @@ -1,7 +1,9 @@ #pragma once +#include"enet.h" + 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_update(); void net_client_dejitter(); diff --git a/src/net_hi.c b/src/net_hi.c index cbd787d..3c28b1e 100644 --- a/src/net_hi.c +++ b/src/net_hi.c @@ -7,9 +7,15 @@ #include"net_server.h" #include"net_client.h" #include +#include"k3.h" + +/* + * Handles networking on a higher-level, combining hole punching with + * basic client & server interface + * */ static void *ReqPeercodeUD; -static void(*ReqPeercodeCB)(void*, const char *peercode); +static void(*ReqPeercodeCB)(void*, struct StoonPeercode *peercode); static struct Stoon stoon; @@ -17,11 +23,11 @@ static bool inited = false; static bool isHost; typedef struct { -#define MASK_IPv4 1 -#define MASK_IPv6 2 - int mask; - ENetAddress v4; - ENetAddress v6; + ENetAddress pv4; + ENetAddress pv6; + + ENetAddress lv4; + ENetAddress lv6; } ToPunch; static ToPunch *topunch = NULL; static size_t topunchCount = 0; @@ -30,13 +36,22 @@ static double Timeout = 0; 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; ReqPeercodeUD = ud; 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; @@ -52,7 +67,7 @@ bool net_hi_setup(bool host) { isHost = host; if(host) { - net_server_init(); + net_server_init(servport); } else { net_client_init(); } @@ -67,16 +82,17 @@ void net_hi_update(double now) { if(stoon_req(&stoon)) { if(stoon_listen(&stoon)) { - uint8_t peercode[STOON_CONN_INFO_SIZE] = {}; - stoon_serialize(&stoon, peercode); - - ReqPeercodeCB(ReqPeercodeUD, peercode); + ReqPeercodeCB(ReqPeercodeUD, &stoon.peercode); ReqPeercodeCB = NULL; } else { + k3Log(k3_INFO, "stoon_listen failure"); + Timeout = now + 1; } } else { + k3Log(k3_INFO, "stoon_req failure"); + Timeout = now + 1; } @@ -97,11 +113,11 @@ void net_hi_update(double now) { for(size_t tpi = 0; tpi < topunchCount; tpi++) { ToPunch *tp = &topunch[tpi]; - if(tp->mask & MASK_IPv4) { - enet_socket_send(h->socket, &tp->v4, &buf, 1); - } else if(tp->mask & MASK_IPv6) { - enet_socket_send(h->socket, &tp->v6, &buf, 1); - } + if(tp->lv6.port) enet_socket_send(h->socket, &tp->lv6, &buf, 1); + if(tp->lv4.port) enet_socket_send(h->socket, &tp->lv4, &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) { - uint8_t *addr8 = (uint8_t*) &v4->host; +static bool stoonpeer_to_enet4(uint8_t *publicV4, uint8_t *publicP4, ENetAddress *enet) { + 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); addr8[10] = 0xFF; addr8[11] = 0xFF; - addr8[12] = peercode[0]; - addr8[13] = peercode[1]; - addr8[14] = peercode[2]; - addr8[15] = peercode[3]; - v4->port = ntohs(*(uint16_t*) &peercode[4]); + addr8[12] = publicV4[0]; + addr8[13] = publicV4[1]; + addr8[14] = publicV4[2]; + addr8[15] = publicV4[3]; + enet->port = *(uint16_t*) publicP4; - memcpy(&v6->host, peercode + 6, 16); - v6->port = ntohs(*(uint16_t*) &peercode[22]); - - *mask = 0; - if(v4->port) { - *mask |= MASK_IPv4; - } - if(v6->port) { - *mask |= MASK_IPv6; - } + return true; } -void net_hi_add_punch(const char *peercode) { - int mask; - ENetAddress v4 = {}, v6 = {}; - stoonpeer_to_enets(peercode, &v4, &v6, &mask); +static bool stoonpeer_to_enet6(uint8_t *publicV6, uint8_t *publicP6, ENetAddress *enet) { + memset(enet, 0, sizeof(*enet)); + 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[topunchCount - 1] = (ToPunch) { - .v4 = v4, - .v6 = v6, - .mask = mask, - }; + ToPunch *tp = &topunch[topunchCount - 1]; + + stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &tp->pv4); + 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(connected) return false; - char ip[64]; - int port; - if(*(uint16_t*) (peercode + 22) == 0) { - inet_ntop(AF_INET, peercode, ip, sizeof(ip)); - port = ntohs(*(uint16_t*) (peercode + 4)); - } else { - inet_ntop(AF_INET6, peercode + 6, ip, sizeof(ip)); - port = ntohs(*(uint16_t*) (peercode + 22)); + ENetAddress pv4, pv6; + stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &pv4); + stoonpeer_to_enet6(peercode->publicV6, peercode->publicP6, &pv6); + + ENetAddress lv4, lv6; + stoonpeer_to_enet4(peercode->localV4, peercode->localP4, &lv4); + stoonpeer_to_enet6(peercode->localV6, peercode->localP6, &lv6); + + 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; } diff --git a/src/net_hi.h b/src/net_hi.h index 4e75804..d6a7ace 100644 --- a/src/net_hi.h +++ b/src/net_hi.h @@ -2,10 +2,12 @@ #include -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); 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); diff --git a/src/net_server.c b/src/net_server.c index 223f088..1eec7b3 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -18,8 +18,8 @@ struct Conn { #define MAX_PLAYERS 64 static struct Conn conns[MAX_PLAYERS]; -void net_server_init() { - host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = 26656}, 16, 1, 0, 0); +void net_server_init(uint16_t port) { + host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = port}, 16, 1, 0, 0); Game.isMultiplayer = 1; Game.isAuthority = 1; diff --git a/src/net_server.h b/src/net_server.h index 9ffb8b5..2434525 100644 --- a/src/net_server.h +++ b/src/net_server.h @@ -5,7 +5,7 @@ struct _ENetPeer; struct bstr; -void net_server_init(); +void net_server_init(uint16_t port); void net_server_receive(); void net_server_update(); diff --git a/src/stoon.c b/src/stoon.c index 394ca9f..d0efc83 100644 --- a/src/stoon.c +++ b/src/stoon.c @@ -17,6 +17,7 @@ #include #include #include +#include #define STUN_BINDING_REQUEST 0x0001 #define STUN_BINDING_INDICATION 0x1100 @@ -43,7 +44,7 @@ struct StunMsg { 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 errno = 0; 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]; sprintf(p, "%u", myport); - struct addrinfo *myaddr; - if(getaddrinfo(NULL, p, &(struct addrinfo) {.ai_family = serv->ai_family, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP, .ai_flags = AI_PASSIVE}, &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}, &myaddrinfo)) { close(fd); return -1; } - if(bind(fd, myaddr->ai_addr, myaddr->ai_addrlen)) { + if(bind(fd, myaddrinfo->ai_addr, myaddrinfo->ai_addrlen)) { close(fd); 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; } @@ -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) { 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; - memset(&ret.my6, 0, sizeof(ret.my6)); if(v6) { 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; ret.poonchstage = 0; @@ -121,12 +175,21 @@ static int stoon_req_mini(struct Stoon *this, int *fd, struct sockaddr *serv, in if(errno == ENETUNREACH) { close(*fd); *fd = -1; + return false; } } + + return true; } 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->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) { @@ -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 publicPort = ntohs(((uint16_t*) d)[3]) ^ (STUN_MAGIC >> 16); 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->my4.sin_addr, &publicIp, 4); - this->my4.sin_port = htons(publicPort); + memcpy(this->peercode.publicV4, &publicIp, 4); + memcpy(this->peercode.publicP4, &publicPort, 2); return 1; } 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[3] = ((uint32_t*) d)[5] ^ ((uint32_t*) res.base.id)[2]; - this->my6.sin6_family = AF_INET6; - memcpy(&this->my6.sin6_addr, &publicIp, 16); - this->my6.sin6_port = htons(publicPort); + memcpy(this->peercode.publicV6, &publicIp, 16); + memcpy(this->peercode.publicP6, &publicPort, 2); return 1; } else { @@ -188,12 +249,12 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv, d += 4 + attribLen; } - return 0; + return false; } 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->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) { @@ -217,31 +278,7 @@ void stoon_kill(struct Stoon *this) { this->fd6 = -1; } -int stoon_v4_available(struct Stoon *this) { - 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]) { +/*int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]) { struct { uint32_t addr4; 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; -} +}*/ #ifdef STOON_STANDALONE int main() { diff --git a/src/stoon.h b/src/stoon.h index 3e173ee..6e70fff 100644 --- a/src/stoon.h +++ b/src/stoon.h @@ -6,6 +6,7 @@ #include #include +#include #ifdef _WIN32 #include @@ -16,8 +17,6 @@ /* Standalone hole punching libary (IPv4 & IPv6 compatible) */ -#define STOON_CONN_INFO_SIZE (4 + 2 + 16 + 2) - #define POONCH_MAGIC 0x504F4348 #define POONCH_STAGE_KNOCKING 0 #define POONCH_STAGE_ACK 1 @@ -26,16 +25,30 @@ struct Poonch { 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 sockaddr_in stu4; - struct sockaddr_in my4; int fd4; struct sockaddr_in6 stu6; - struct sockaddr_in6 my6; int fd6; uint8_t poonchstage; + + struct StoonPeercode peercode; }; // stunhost: Self-explanatory @@ -53,12 +66,8 @@ void stoon_keepalive(struct Stoon*); void stoon_kill(struct Stoon*); -int stoon_v4_available(struct Stoon*); -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_INCOMPATIBLE_NETFAMS (-1) #define STOON_POONCH_NO_KNOCK 0 #define STOON_POONCH_ACKED 1 int stoon_poonch(struct Stoon*, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]); +*/