Compare commits

..

No commits in common. "90f0e2dd420ba62066cc4d1a6cf42e469563baba" and "e126db573a5bf8b0d1a987b1ee52d7150fb6cf8c" have entirely different histories.

10 changed files with 133 additions and 223 deletions

View File

@ -986,8 +986,8 @@ void game_cleanup() {
Game.phys = dWorldCreate(); Game.phys = dWorldCreate();
dWorldSetGravity(Game.phys, 0, -15, 0); dWorldSetGravity(Game.phys, 0, -15, 0);
dWorldSetCFM(Game.phys, 0.0002); dWorldSetCFM(Game.phys, 0.0001);
dWorldSetERP(Game.phys, 0.2); dWorldSetERP(Game.phys, 0.5);
Game.space = dHashSpaceCreate(NULL); Game.space = dHashSpaceCreate(NULL);

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, struct StoonPeercode *peercode_bin) { static void get_peercode_callback(void *ud, const char *peercode_bin) {
char peercode[sizeof(*peercode_bin) * 2 + 1] = {}; char peercode[STOON_CONN_INFO_SIZE * 2 + 1] = {};
for(int i = 0; i < sizeof(*peercode_bin); i++) { for(int i = 0; i < STOON_CONN_INFO_SIZE; 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 * sizeof(struct StoonPeercode)) { if(strlen(peercode) < 2 * STOON_CONN_INFO_SIZE) {
return 0; return 0;
} }
for(int i = 0; i < sizeof(struct StoonPeercode); i++) { for(int i = 0; i < STOON_CONN_INFO_SIZE; 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) {
struct StoonPeercode peercode; char peercode[STOON_CONN_INFO_SIZE];
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) {
struct StoonPeercode peercode; char peercode[STOON_CONN_INFO_SIZE];
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,7 +26,11 @@ void net_client_init() {
Game.isAuthority = 0; Game.isAuthority = 0;
} }
bool net_client_connect(ENetAddress eaddr) { bool net_client_connect(const char *addr, uint16_t port) {
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,9 +1,7 @@
#pragma once #pragma once
#include"enet.h"
void net_client_init(); void net_client_init();
bool net_client_connect(ENetAddress addr); bool net_client_connect(const char *addr, uint16_t port);
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,15 +7,9 @@
#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*, struct StoonPeercode *peercode); static void(*ReqPeercodeCB)(void*, const char *peercode);
static struct Stoon stoon; static struct Stoon stoon;
@ -23,11 +17,11 @@ static bool inited = false;
static bool isHost; static bool isHost;
typedef struct { typedef struct {
ENetAddress pv4; #define MASK_IPv4 1
ENetAddress pv6; #define MASK_IPv6 2
int mask;
ENetAddress lv4; ENetAddress v4;
ENetAddress lv6; ENetAddress v6;
} ToPunch; } ToPunch;
static ToPunch *topunch = NULL; static ToPunch *topunch = NULL;
static size_t topunchCount = 0; static size_t topunchCount = 0;
@ -36,22 +30,13 @@ static double Timeout = 0;
static bool connected = false; static bool connected = false;
static uint16_t servport = 0; bool net_hi_request_peercode(void *ud, void(*callback)(void*, const char *peercode)) {
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;
for(size_t port = 25000; port <= 26656; port++) { stoon = stoon_init("stun.easybell.de", 3478, 26656);
stoon = stoon_init("stun.easybell.de", 3478, port);
if(stoon.fd4 >= 0 || stoon.fd6 >= 0) {
servport = port;
break;
}
}
Timeout = 0; Timeout = 0;
@ -67,7 +52,7 @@ bool net_hi_setup(bool host) {
isHost = host; isHost = host;
if(host) { if(host) {
net_server_init(servport); net_server_init();
} else { } else {
net_client_init(); net_client_init();
} }
@ -82,17 +67,16 @@ void net_hi_update(double now) {
if(stoon_req(&stoon)) { if(stoon_req(&stoon)) {
if(stoon_listen(&stoon)) { if(stoon_listen(&stoon)) {
ReqPeercodeCB(ReqPeercodeUD, &stoon.peercode); uint8_t peercode[STOON_CONN_INFO_SIZE] = {};
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;
} }
@ -113,11 +97,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->lv6.port) enet_socket_send(h->socket, &tp->lv6, &buf, 1); if(tp->mask & MASK_IPv4) {
if(tp->lv4.port) enet_socket_send(h->socket, &tp->lv4, &buf, 1); enet_socket_send(h->socket, &tp->v4, &buf, 1);
} else if(tp->mask & MASK_IPv6) {
if(tp->pv6.port) enet_socket_send(h->socket, &tp->pv6, &buf, 1); enet_socket_send(h->socket, &tp->v6, &buf, 1);
if(tp->pv4.port) enet_socket_send(h->socket, &tp->pv4, &buf, 1); }
} }
} }
@ -127,85 +111,57 @@ void net_hi_update(double now) {
} }
} }
static bool stoonpeer_to_enet4(uint8_t *publicV4, uint8_t *publicP4, ENetAddress *enet) { static void stoonpeer_to_enets(const char *peercode, ENetAddress *v4, ENetAddress *v6, int *mask) {
memset(enet, 0, sizeof(*enet)); uint8_t *addr8 = (uint8_t*) &v4->host;
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] = publicV4[0]; addr8[12] = peercode[0];
addr8[13] = publicV4[1]; addr8[13] = peercode[1];
addr8[14] = publicV4[2]; addr8[14] = peercode[2];
addr8[15] = publicV4[3]; addr8[15] = peercode[3];
enet->port = *(uint16_t*) publicP4; v4->port = ntohs(*(uint16_t*) &peercode[4]);
return true; memcpy(&v6->host, peercode + 6, 16);
} v6->port = ntohs(*(uint16_t*) &peercode[22]);
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) { *mask = 0;
return false; if(v4->port) {
*mask |= MASK_IPv4;
}
if(v6->port) {
*mask |= MASK_IPv6;
} }
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) { void net_hi_add_punch(const char *peercode) {
int mask;
ENetAddress v4 = {}, v6 = {};
stoonpeer_to_enets(peercode, &v4, &v6, &mask);
topunch = realloc(topunch, sizeof(*topunch) * (++topunchCount)); topunch = realloc(topunch, sizeof(*topunch) * (++topunchCount));
ToPunch *tp = &topunch[topunchCount - 1]; topunch[topunchCount - 1] = (ToPunch) {
.v4 = v4,
stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &tp->pv4); .v6 = v6,
stoonpeer_to_enet6(peercode->publicV6, peercode->publicP6, &tp->pv6); .mask = mask,
};
stoonpeer_to_enet4(peercode->localV4, peercode->localP4, &tp->lv4);
stoonpeer_to_enet6(peercode->localV6, peercode->localP6, &tp->lv6);
} }
bool net_hi_connect(struct StoonPeercode *peercode) { bool net_hi_connect(const char *peercode) {
if(!inited) return false; if(!inited) return false;
if(connected) return false; if(connected) return false;
ENetAddress pv4, pv6; char ip[64];
stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &pv4); int port;
stoonpeer_to_enet6(peercode->publicV6, peercode->publicP6, &pv6); if(*(uint16_t*) (peercode + 22) == 0) {
inet_ntop(AF_INET, peercode, ip, sizeof(ip));
ENetAddress lv4, lv6; port = ntohs(*(uint16_t*) (peercode + 4));
stoonpeer_to_enet4(peercode->localV4, peercode->localP4, &lv4); } else {
stoonpeer_to_enet6(peercode->localV6, peercode->localP6, &lv6); inet_ntop(AF_INET6, peercode + 6, ip, sizeof(ip));
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;
} }
if(pv6.port && net_client_connect(pv6)) { return net_client_connect(ip, port);
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,12 +2,10 @@
#include<stdbool.h> #include<stdbool.h>
struct StoonPeercode; bool net_hi_request_peercode(void *ud, void(*callback)(void*, const char *peercode));
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(struct StoonPeercode *peercode); void net_hi_add_punch(const char *peercode);
bool net_hi_connect(struct StoonPeercode *peercode); bool net_hi_connect(const char *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(uint16_t port) { void net_server_init() {
host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = port}, 16, 1, 0, 0); host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = 26656}, 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(uint16_t port); void net_server_init();
void net_server_receive(); void net_server_receive();
void net_server_update(); void net_server_update();

View File

@ -17,7 +17,6 @@
#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
@ -44,7 +43,7 @@ struct StunMsg {
uint8_t id[12]; uint8_t id[12];
}; };
static int stoon_init_mini(struct Stoon *this, struct addrinfo *serv, uint16_t myport) { static int stoon_init_mini(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);
@ -60,71 +59,16 @@ static int stoon_init_mini(struct Stoon *this, struct addrinfo *serv, uint16_t m
char p[6]; char p[6];
sprintf(p, "%u", myport); sprintf(p, "%u", myport);
struct addrinfo *myaddrinfo; 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}, &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)) {
close(fd); close(fd);
return -1; return -1;
} }
if(bind(fd, myaddrinfo->ai_addr, myaddrinfo->ai_addrlen)) { if(bind(fd, myaddr->ai_addr, myaddr->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;
} }
@ -148,16 +92,18 @@ 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(&ret, v4, myport); ret.fd4 = stoon_init_mini(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(&ret, v6, myport); ret.fd6 = stoon_init_mini(v6, myport);
} else ret.fd6 = -1; } else ret.fd6 = -1;
ret.poonchstage = 0; ret.poonchstage = 0;
@ -175,21 +121,12 @@ 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) {
@ -224,10 +161,11 @@ 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 = htonl(ntohl(((uint32_t*) d)[2]) ^ STUN_MAGIC); uint32_t publicIp = ntohl(((uint32_t*) d)[2]) ^ STUN_MAGIC;
memcpy(this->peercode.publicV4, &publicIp, 4); this->my4.sin_family = AF_INET;
memcpy(this->peercode.publicP4, &publicPort, 2); memcpy(&this->my4.sin_addr, &publicIp, 4);
this->my4.sin_port = htons(publicPort);
return 1; return 1;
} else if(netfam == STUN_NETFAM_IPV6) { } else if(netfam == STUN_NETFAM_IPV6) {
@ -237,8 +175,9 @@ 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];
memcpy(this->peercode.publicV6, &publicIp, 16); this->my6.sin6_family = AF_INET6;
memcpy(this->peercode.publicP6, &publicPort, 2); memcpy(&this->my6.sin6_addr, &publicIp, 16);
this->my6.sin6_port = htons(publicPort);
return 1; return 1;
} else { } else {
@ -249,12 +188,12 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
d += 4 + attribLen; d += 4 + attribLen;
} }
return false; return 0;
} }
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 true; return 1;
} }
void stoon_keepalive(struct Stoon *this) { void stoon_keepalive(struct Stoon *this) {
@ -278,7 +217,31 @@ void stoon_kill(struct Stoon *this) {
this->fd6 = -1; this->fd6 = -1;
} }
/*int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]) { 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]) {
struct { struct {
uint32_t addr4; uint32_t addr4;
uint16_t port4; uint16_t port4;
@ -340,7 +303,7 @@ void stoon_kill(struct Stoon *this) {
} }
return STOON_POONCH_NO_KNOCK; return STOON_POONCH_NO_KNOCK;
}*/ }
#ifdef STOON_STANDALONE #ifdef STOON_STANDALONE
int main() { int main() {

View File

@ -6,7 +6,6 @@
#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>
@ -17,6 +16,8 @@
/* 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
@ -25,30 +26,16 @@ 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
@ -66,8 +53,12 @@ void stoon_keepalive(struct Stoon*);
void stoon_kill(struct Stoon*); void stoon_kill(struct Stoon*);
/*#define STOON_POONCH_INCOMPATIBLE_NETFAMS (-1) 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_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]);
*/