mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-26 12:21:19 +00:00
Hole punching
This commit is contained in:
parent
52879a7632
commit
ba5b6aa7af
6 changed files with 161 additions and 23 deletions
|
@ -1908,6 +1908,8 @@ static void SendAskInfo(INT32 node)
|
|||
// now allowed traffic from the host to us in, so once the MS relays
|
||||
// our address to the host, it'll be able to speak to us.
|
||||
HSendPacket(node, false, 0, sizeof (askinfo_pak));
|
||||
|
||||
I_NetRequestHolePunch();
|
||||
}
|
||||
|
||||
serverelem_t serverlist[MAXSERVERLIST];
|
||||
|
@ -5725,6 +5727,19 @@ static void UpdatePingTable(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void RenewHolePunch(void)
|
||||
{
|
||||
static time_t past;
|
||||
|
||||
const time_t now = time(NULL);
|
||||
|
||||
if ((now - past) > 20)
|
||||
{
|
||||
I_NetRegisterHolePunch();
|
||||
past = now;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle timeouts to prevent definitive freezes from happenning
|
||||
static void HandleNodeTimeouts(void)
|
||||
{
|
||||
|
@ -5759,6 +5774,11 @@ FILESTAMP
|
|||
MasterClient_Ticker();
|
||||
#endif
|
||||
|
||||
if (serverrunning)
|
||||
{
|
||||
RenewHolePunch();
|
||||
}
|
||||
|
||||
if (client)
|
||||
{
|
||||
// send keep alive
|
||||
|
@ -5818,6 +5838,11 @@ FILESTAMP
|
|||
MasterClient_Ticker(); // Acking the Master Server
|
||||
#endif
|
||||
|
||||
if (serverrunning)
|
||||
{
|
||||
RenewHolePunch();
|
||||
}
|
||||
|
||||
if (client)
|
||||
{
|
||||
if (!resynch_local_inprogress)
|
||||
|
|
|
@ -49,6 +49,8 @@ tic_t connectiontimeout = (10*TICRATE);
|
|||
doomcom_t *doomcom = NULL;
|
||||
/// \brief network packet data, points inside doomcom
|
||||
doomdata_t *netbuffer = NULL;
|
||||
/// \brief hole punching packet, also points inside doomcom
|
||||
holepunch_t *holepunchpacket = NULL;
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
FILE *debugfile = NULL; // put some net info in a file during the game
|
||||
|
@ -72,6 +74,8 @@ boolean (*I_NetCanGet)(void) = NULL;
|
|||
void (*I_NetCloseSocket)(void) = NULL;
|
||||
void (*I_NetFreeNodenum)(INT32 nodenum) = NULL;
|
||||
SINT8 (*I_NetMakeNodewPort)(const char *address, const char* port) = NULL;
|
||||
void (*I_NetRequestHolePunch)(void) = NULL;
|
||||
void (*I_NetRegisterHolePunch)(void) = NULL;
|
||||
boolean (*I_NetOpenSocket)(void) = NULL;
|
||||
boolean (*I_Ban) (INT32 node) = NULL;
|
||||
void (*I_ClearBans)(void) = NULL;
|
||||
|
@ -1335,6 +1339,7 @@ boolean D_CheckNetGame(void)
|
|||
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
|
||||
|
||||
netbuffer = (doomdata_t *)(void *)&doomcom->data;
|
||||
holepunchpacket = (holepunch_t *)(void *)&doomcom->data;
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
#ifdef _arch_dreamcast
|
||||
|
|
17
src/i_net.h
17
src/i_net.h
|
@ -77,11 +77,19 @@ typedef struct
|
|||
char data[MAXPACKETLENGTH];
|
||||
} ATTRPACK doomcom_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 magic;
|
||||
INT32 addr;
|
||||
INT16 port;
|
||||
} ATTRPACK holepunch_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
extern doomcom_t *doomcom;
|
||||
extern holepunch_t *holepunchpacket;
|
||||
|
||||
/** \brief return packet in doomcom struct
|
||||
*/
|
||||
|
@ -140,6 +148,15 @@ extern boolean (*I_NetOpenSocket)(void);
|
|||
extern void (*I_NetCloseSocket)(void);
|
||||
|
||||
|
||||
/** \brief send a hole punching request
|
||||
*/
|
||||
extern void (*I_NetRequestHolePunch)(void);
|
||||
|
||||
/** \brief register this machine on the hole punching server
|
||||
*/
|
||||
extern void (*I_NetRegisterHolePunch)(void);
|
||||
|
||||
|
||||
extern boolean (*I_Ban) (INT32 node);
|
||||
extern void (*I_ClearBans)(void);
|
||||
extern const char *(*I_GetNodeAddress) (INT32 node);
|
||||
|
|
134
src/i_tcp.c
134
src/i_tcp.c
|
@ -241,6 +241,7 @@ static size_t broadcastaddresses = 0;
|
|||
static boolean nodeconnected[MAXNETNODES+1];
|
||||
static mysockaddr_t banned[MAXBANS];
|
||||
static UINT8 bannedmask[MAXBANS];
|
||||
static const INT32 hole_punch_magic = MSBF_LONG (0x52eb11);
|
||||
#endif
|
||||
|
||||
static size_t numbans = 0;
|
||||
|
@ -597,6 +598,27 @@ void Command_Numnodes(void)
|
|||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
static boolean hole_punch(ssize_t c)
|
||||
{
|
||||
if (c == 10 && holepunchpacket->magic == hole_punch_magic)
|
||||
{
|
||||
mysockaddr_t addr;
|
||||
addr.ip4.sin_family = AF_INET;
|
||||
addr.ip4.sin_addr.s_addr = holepunchpacket->addr;
|
||||
addr.ip4.sin_port = holepunchpacket->port;
|
||||
sendto(mysockets[0], NULL, 0, 0, &addr.any, sizeof addr.ip4);
|
||||
|
||||
CONS_Debug(DBG_NETPLAY,
|
||||
"hole punching request from %s\n", SOCK_AddrToStr(&addr));
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if a packet was received from a new node, false in all other cases
|
||||
static boolean SOCK_Get(void)
|
||||
{
|
||||
|
@ -620,6 +642,11 @@ static boolean SOCK_Get(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (hole_punch(c))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// find remote node number
|
||||
for (j = 1; j <= MAXNETNODES; j++) //include LAN
|
||||
{
|
||||
|
@ -1319,17 +1346,14 @@ void I_ShutdownTcpDriver(void)
|
|||
}
|
||||
|
||||
#ifndef NONET
|
||||
static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||
static boolean SOCK_GetAddr(struct sockaddr_in *sin, const char *address, const char *port, boolean test)
|
||||
{
|
||||
SINT8 newnode = -1;
|
||||
struct my_addrinfo *ai = NULL, *runp, hints;
|
||||
int gaie;
|
||||
|
||||
if (!port || !port[0])
|
||||
if (!port || !port[0])
|
||||
port = DEFAULTPORT;
|
||||
|
||||
DEBFILE(va("Creating new node: %s@%s\n", address, port));
|
||||
|
||||
memset (&hints, 0x00, sizeof (hints));
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
|
@ -1337,30 +1361,91 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
gaie = I_getaddrinfo(address, port, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
newnode = getfreenode();
|
||||
}
|
||||
if (newnode == -1)
|
||||
|
||||
if (gaie != 0)
|
||||
{
|
||||
I_freeaddrinfo(ai);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
runp = ai;
|
||||
|
||||
if (test)
|
||||
{
|
||||
while (runp != NULL)
|
||||
{
|
||||
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
break;
|
||||
|
||||
runp = runp->ai_next;
|
||||
}
|
||||
}
|
||||
|
||||
if (runp != NULL)
|
||||
memcpy(sin, runp->ai_addr, runp->ai_addrlen);
|
||||
|
||||
I_freeaddrinfo(ai);
|
||||
|
||||
return (runp != NULL);
|
||||
}
|
||||
|
||||
static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||
{
|
||||
SINT8 newnode = getfreenode();
|
||||
|
||||
DEBFILE(va("Creating new node: %s@%s\n", address, port));
|
||||
|
||||
if (newnode != -1)
|
||||
{
|
||||
if (!SOCK_GetAddr(&clientaddress[newnode].ip4, address, port, true))
|
||||
{
|
||||
nodeconnected[newnode] = false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static void rendezvous(int size)
|
||||
{
|
||||
char *addrs = strdup(cv_rendezvousserver.string);
|
||||
|
||||
char *host = strtok(addrs, ":");
|
||||
char *port = strtok(NULL, ":");
|
||||
|
||||
mysockaddr_t rzv;
|
||||
|
||||
if (SOCK_GetAddr(&rzv.ip4, host, (port ? port : "7777"), false))
|
||||
{
|
||||
holepunchpacket->magic = hole_punch_magic;
|
||||
sendto(mysockets[0], doomcom->data, size, 0, &rzv.any, sizeof rzv.ip4);
|
||||
}
|
||||
else
|
||||
runp = ai;
|
||||
|
||||
while (runp != NULL)
|
||||
{
|
||||
// find ip of the server
|
||||
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
{
|
||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||
break;
|
||||
}
|
||||
runp = runp->ai_next;
|
||||
CONS_Alert(CONS_ERROR, "Failed to contact rendezvous server (%s).\n",
|
||||
cv_rendezvousserver.string);
|
||||
}
|
||||
I_freeaddrinfo(ai);
|
||||
return newnode;
|
||||
|
||||
free(addrs);
|
||||
}
|
||||
|
||||
static void SOCK_RequestHolePunch(void)
|
||||
{
|
||||
mysockaddr_t * addr = &clientaddress[doomcom->remotenode];
|
||||
|
||||
holepunchpacket->addr = addr->ip4.sin_addr.s_addr;
|
||||
holepunchpacket->port = addr->ip4.sin_port;
|
||||
|
||||
CONS_Debug(DBG_NETPLAY,
|
||||
"requesting hole punch to node %s\n", SOCK_AddrToStr(addr));
|
||||
|
||||
rendezvous(10);
|
||||
}
|
||||
|
||||
static void SOCK_RegisterHolePunch(void)
|
||||
{
|
||||
rendezvous(4);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1387,6 +1472,9 @@ static boolean SOCK_OpenSocket(void)
|
|||
I_NetCanGet = SOCK_CanGet;
|
||||
#endif
|
||||
|
||||
I_NetRequestHolePunch = SOCK_RequestHolePunch;
|
||||
I_NetRegisterHolePunch = SOCK_RegisterHolePunch;
|
||||
|
||||
// build the socket but close it first
|
||||
SOCK_CloseSocket();
|
||||
return UDP_Socket();
|
||||
|
|
|
@ -68,6 +68,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
|||
};
|
||||
|
||||
consvar_t cv_masterserver = {"masterserver", "https://ms.kartkrew.org/ms/api", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_rendezvousserver = {"rendezvousserver", "jart-dev.jameds.org", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_servername = {"servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_server_contact = {"server_contact", "", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
@ -99,6 +100,7 @@ void AddMServCommands(void)
|
|||
CV_RegisterVar(&cv_masterserver_debug);
|
||||
CV_RegisterVar(&cv_masterserver_token);
|
||||
CV_RegisterVar(&cv_advertise);
|
||||
CV_RegisterVar(&cv_rendezvousserver);
|
||||
CV_RegisterVar(&cv_servername);
|
||||
CV_RegisterVar(&cv_server_contact);
|
||||
#ifdef MASTERSERVER
|
||||
|
|
|
@ -58,6 +58,7 @@ extern consvar_t cv_masterserver_update_rate;
|
|||
extern consvar_t cv_masterserver_timeout;
|
||||
extern consvar_t cv_masterserver_debug;
|
||||
extern consvar_t cv_masterserver_token;
|
||||
extern consvar_t cv_rendezvousserver;
|
||||
|
||||
extern consvar_t cv_advertise;
|
||||
|
||||
|
|
Loading…
Reference in a new issue