use a single udp socket for server traffic instead of one port for gameplay and one port for pings

master
lsalzman 2013-04-24 13:32:11 +03:00
parent 73910dfb27
commit 7ded0d7b37
6 changed files with 43 additions and 48 deletions

View File

@ -573,7 +573,7 @@ bool checkclientinput(client &c)
else if(sscanf(c.input, "regserv %d", &port) == 1)
{
if(checkban(servbans, c.address.host)) return false;
if(port < 0 || port + 1 < 0 || (c.servport >= 0 && port != c.servport)) outputf(c, "failreg invalid port\n");
if(port < 0 || (c.servport >= 0 && port != c.servport)) outputf(c, "failreg invalid port\n");
else
{
c.servport = port;
@ -710,7 +710,7 @@ int main(int argc, char **argv)
atexit(enet_deinitialize);
const char *dir = "", *ip = NULL;
int port = 28787;
int port = 41999;
if(argc>=2) dir = argv[1];
if(argc>=3) port = atoi(argv[2]);
if(argc>=4) ip = argv[3];

View File

@ -118,7 +118,7 @@ vector<client *> clients;
ENetHost *serverhost = NULL;
int laststatus = 0;
ENetSocket pongsock = ENET_SOCKET_NULL, lansock = ENET_SOCKET_NULL;
ENetSocket lansock = ENET_SOCKET_NULL;
int localclients = 0, nonlocalclients = 0;
@ -172,9 +172,8 @@ void cleanupserver()
if(serverhost) enet_host_destroy(serverhost);
serverhost = NULL;
if(pongsock != ENET_SOCKET_NULL) enet_socket_destroy(pongsock);
if(lansock != ENET_SOCKET_NULL) enet_socket_destroy(lansock);
pongsock = lansock = ENET_SOCKET_NULL;
lansock = ENET_SOCKET_NULL;
}
void process(ENetPacket *packet, int sender, int chan);
@ -508,53 +507,59 @@ void flushmasterinput()
else disconnectmaster();
}
static ENetAddress pongaddr;
static ENetAddress serverinfoaddress;
void sendserverinforeply(ucharbuf &p)
{
ENetBuffer buf;
buf.data = p.buf;
buf.dataLength = p.length();
enet_socket_send(pongsock, &pongaddr, &buf, 1);
enet_socket_send(serverhost->socket, &serverinfoaddress, &buf, 1);
}
void checkserversockets() // reply all server info requests
{
static ENetSocketSet sockset;
ENET_SOCKETSET_EMPTY(sockset);
ENetSocket maxsock = pongsock;
ENET_SOCKETSET_ADD(sockset, pongsock);
ENetSocket maxsock = ENET_SOCKET_NULL;
if(mastersock != ENET_SOCKET_NULL)
{
maxsock = max(maxsock, mastersock);
maxsock = maxsock == ENET_SOCKET_NULL ? mastersock : max(maxsock, mastersock);
ENET_SOCKETSET_ADD(sockset, mastersock);
}
if(lansock != ENET_SOCKET_NULL)
{
maxsock = max(maxsock, lansock);
maxsock = maxsock == ENET_SOCKET_NULL ? lansock : max(maxsock, lansock);
ENET_SOCKETSET_ADD(sockset, lansock);
}
if(enet_socketset_select(maxsock, &sockset, NULL, 0) <= 0) return;
if(maxsock == ENET_SOCKET_NULL || enet_socketset_select(maxsock, &sockset, NULL, 0) <= 0) return;
ENetBuffer buf;
uchar pong[MAXTRANS];
loopi(2)
if(lansock != ENET_SOCKET_NULL && ENET_SOCKETSET_CHECK(sockset, lansock))
{
ENetSocket sock = i ? lansock : pongsock;
if(sock == ENET_SOCKET_NULL || !ENET_SOCKETSET_CHECK(sockset, sock)) continue;
buf.data = pong;
buf.dataLength = sizeof(pong);
int len = enet_socket_receive(sock, &pongaddr, &buf, 1);
if(len < 0) return;
ucharbuf req(pong, len), p(pong, sizeof(pong));
p.len += len;
ENetBuffer buf;
uchar data[MAXTRANS];
buf.data = data;
buf.dataLength = sizeof(data);
int len = enet_socket_receive(lansock, &serverinfoaddress, &buf, 1);
if(len < 2 || data[0] != 0xFF || data[1] != 0xFF) return;
ucharbuf req(data+2, len-2), p(data+2, sizeof(data)-2);
p.len += len-2;
server::serverinforeply(req, p);
}
if(mastersock != ENET_SOCKET_NULL && ENET_SOCKETSET_CHECK(sockset, mastersock)) flushmasterinput();
}
static int serverinfointercept(ENetHost *host, ENetEvent *event)
{
if(host->receivedDataLength < 2 || host->receivedData[0] != 0xFF || host->receivedData[1] != 0xFF) return 0;
serverinfoaddress = host->receivedAddress;
ucharbuf req(host->receivedData+2, host->receivedDataLength-2), p(host->receivedData+2, sizeof(host->packetData[0])-2);
p.len += host->receivedDataLength-2;
server::serverinforeply(req, p);
return 1;
}
#define DEFAULTCLIENTS 8
VARF(maxclients, 0, DEFAULTCLIENTS, MAXCLIENTS, { if(!maxclients) maxclients = DEFAULTCLIENTS; });
@ -1022,15 +1027,7 @@ bool setuplistenserver(bool dedicated)
serverhost = enet_host_create(&address, min(maxclients + server::reserveclients(), MAXCLIENTS), server::numchannels(), 0, serveruprate);
if(!serverhost) return servererror(dedicated, "could not create server host");
loopi(maxclients) serverhost->peers[i].data = NULL;
address.port = server::serverinfoport(serverport > 0 ? serverport : -1);
pongsock = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
if(pongsock != ENET_SOCKET_NULL && enet_socket_bind(pongsock, &address) < 0)
{
enet_socket_destroy(pongsock);
pongsock = ENET_SOCKET_NULL;
}
if(pongsock == ENET_SOCKET_NULL) return servererror(dedicated, "could not create server info socket");
else enet_socket_set_option(pongsock, ENET_SOCKOPT_NONBLOCK, 1);
serverhost->intercept = serverinfointercept;
address.port = server::laninfoport();
lansock = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
if(lansock != ENET_SOCKET_NULL && (enet_socket_set_option(lansock, ENET_SOCKOPT_REUSEADDR, 1) < 0 || enet_socket_bind(lansock, &address) < 0))

View File

@ -356,7 +356,7 @@ static serverinfo *newserver(const char *name, int port, uint ip = ENET_HOST_ANY
{
serverinfo *si = new serverinfo;
si->address.host = ip;
si->address.port = server::serverinfoport(port);
si->address.port = port;
if(ip!=ENET_HOST_ANY) si->resolved = RESOLVED;
si->port = port;
@ -415,6 +415,7 @@ void pingservers()
ENetBuffer buf;
uchar ping[MAXTRANS];
ucharbuf p(ping, sizeof(ping));
p.put(0xFF); p.put(0xFF);
putint(p, totalmillis);
static int lastping = 0;
@ -493,7 +494,7 @@ void checkpings()
if(len <= 0) return;
serverinfo *si = NULL;
loopv(servers) if(addr.host == servers[i]->address.host && addr.port == servers[i]->address.port) { si = servers[i]; break; }
if(!si && searchlan) si = newserver(NULL, server::serverport(addr.port), addr.host);
if(!si && searchlan) si = newserver(NULL, addr.port, addr.host);
if(!si) continue;
ucharbuf p(ping, len);
int millis = getint(p), rtt = clamp(totalmillis - millis, 0, min(servpingdecay, totalmillis));

View File

@ -259,13 +259,12 @@ static const int msgsizes[] = // size inclusive message token, 0 f
-1
};
#define SAUERBRATEN_LANINFO_PORT 28784
#define SAUERBRATEN_SERVER_PORT 28785
#define SAUERBRATEN_SERVINFO_PORT 28786
#define SAUERBRATEN_MASTER_PORT 28787
#define PROTOCOL_VERSION 259 // bump when protocol changes
#define TESSERACT_SERVER_PORT 42000
#define TESSERACT_LANINFO_PORT 41998
#define TESSERACT_MASTER_PORT 41999
#define PROTOCOL_VERSION 1 // bump when protocol changes
#define DEMO_VERSION 1 // bump when demo format changes
#define DEMO_MAGIC "SAUERBRATEN_DEMO"
#define DEMO_MAGIC "TESSERACT_DEMO\0\0"
struct demoheader
{

View File

@ -3522,11 +3522,10 @@ namespace server
}
}
int laninfoport() { return SAUERBRATEN_LANINFO_PORT; }
int serverinfoport(int servport) { return servport < 0 ? SAUERBRATEN_SERVINFO_PORT : servport+1; }
int serverport(int infoport) { return infoport < 0 ? SAUERBRATEN_SERVER_PORT : infoport-1; }
const char *defaultmaster() { return "sauerbraten.org"; }
int masterport() { return SAUERBRATEN_MASTER_PORT; }
int laninfoport() { return TESSERACT_LANINFO_PORT; }
int serverport() { return TESSERACT_SERVER_PORT; }
const char *defaultmaster() { return "tesseract.gg"; }
int masterport() { return TESSERACT_MASTER_PORT; }
int numchannels() { return 3; }
#include "extinfo.h"

View File

@ -112,8 +112,7 @@ namespace server
extern void serverupdate();
extern bool servercompatible(char *name, char *sdec, char *map, int ping, const vector<int> &attr, int np);
extern int laninfoport();
extern int serverinfoport(int servport = -1);
extern int serverport(int infoport = -1);
extern int serverport();
extern const char *defaultmaster();
extern int masterport();
extern void processmasterinput(const char *cmd, int cmdlen, const char *args);