mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
separated connless packet handling and use random port for client's server connection
This commit is contained in:
parent
b9e4c7e979
commit
d4c00097a5
|
@ -853,7 +853,7 @@ static int priv_net_close_all_sockets(NETSOCKET sock)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, int sockaddrlen)
|
||||
static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, int sockaddrlen, int use_random_port)
|
||||
{
|
||||
int sock, e;
|
||||
|
||||
|
@ -883,27 +883,46 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i
|
|||
#endif
|
||||
|
||||
/* bind the socket */
|
||||
e = bind(sock, addr, sockaddrlen);
|
||||
if(e != 0)
|
||||
while(1)
|
||||
{
|
||||
/* pick random port */
|
||||
if(use_random_port)
|
||||
{
|
||||
int port = htons(rand()%16384+49152); /* 49152 to 65535 */
|
||||
if(domain == AF_INET)
|
||||
((struct sockaddr_in *)(addr))->sin_port = port;
|
||||
else
|
||||
((struct sockaddr_in6 *)(addr))->sin6_port = port;
|
||||
}
|
||||
|
||||
e = bind(sock, addr, sockaddrlen);
|
||||
if(e == 0)
|
||||
break;
|
||||
else
|
||||
{
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
char buf[128];
|
||||
int error = WSAGetLastError();
|
||||
if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, buf, sizeof(buf), 0) == 0)
|
||||
buf[0] = 0;
|
||||
dbg_msg("net", "failed to bind socket with domain %d and type %d (%d '%s')", domain, type, error, buf);
|
||||
char buf[128];
|
||||
int error = WSAGetLastError();
|
||||
if(error == WSAEADDRINUSE && use_random_port)
|
||||
continue;
|
||||
if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, buf, sizeof(buf), 0) == 0)
|
||||
buf[0] = 0;
|
||||
dbg_msg("net", "failed to bind socket with domain %d and type %d (%d '%s')", domain, type, error, buf);
|
||||
#else
|
||||
dbg_msg("net", "failed to bind socket with domain %d and type %d (%d '%s')", domain, type, errno, strerror(errno));
|
||||
if(errno == EADDRINUSE && use_random_port)
|
||||
continue;
|
||||
dbg_msg("net", "failed to bind socket with domain %d and type %d (%d '%s')", domain, type, errno, strerror(errno));
|
||||
#endif
|
||||
priv_net_close_socket(sock);
|
||||
return -1;
|
||||
priv_net_close_socket(sock);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* return the newly created socket */
|
||||
return sock;
|
||||
}
|
||||
|
||||
NETSOCKET net_udp_create(NETADDR bindaddr)
|
||||
NETSOCKET net_udp_create(NETADDR bindaddr, int use_random_port)
|
||||
{
|
||||
NETSOCKET sock = invalid_socket;
|
||||
NETADDR tmpbindaddr = bindaddr;
|
||||
|
@ -918,7 +937,7 @@ NETSOCKET net_udp_create(NETADDR bindaddr)
|
|||
/* bind, we should check for error */
|
||||
tmpbindaddr.type = NETTYPE_IPV4;
|
||||
netaddr_to_sockaddr_in(&tmpbindaddr, &addr);
|
||||
socket = priv_net_create_socket(AF_INET, SOCK_DGRAM, (struct sockaddr *)&addr, sizeof(addr));
|
||||
socket = priv_net_create_socket(AF_INET, SOCK_DGRAM, (struct sockaddr *)&addr, sizeof(addr), use_random_port);
|
||||
if(socket >= 0)
|
||||
{
|
||||
sock.type |= NETTYPE_IPV4;
|
||||
|
@ -940,7 +959,7 @@ NETSOCKET net_udp_create(NETADDR bindaddr)
|
|||
/* bind, we should check for error */
|
||||
tmpbindaddr.type = NETTYPE_IPV6;
|
||||
netaddr_to_sockaddr_in6(&tmpbindaddr, &addr);
|
||||
socket = priv_net_create_socket(AF_INET6, SOCK_DGRAM, (struct sockaddr *)&addr, sizeof(addr));
|
||||
socket = priv_net_create_socket(AF_INET6, SOCK_DGRAM, (struct sockaddr *)&addr, sizeof(addr), use_random_port);
|
||||
if(socket >= 0)
|
||||
{
|
||||
sock.type |= NETTYPE_IPV6;
|
||||
|
@ -1077,7 +1096,7 @@ NETSOCKET net_tcp_create(NETADDR bindaddr)
|
|||
/* bind, we should check for error */
|
||||
tmpbindaddr.type = NETTYPE_IPV4;
|
||||
netaddr_to_sockaddr_in(&tmpbindaddr, &addr);
|
||||
socket = priv_net_create_socket(AF_INET, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr));
|
||||
socket = priv_net_create_socket(AF_INET, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), 0);
|
||||
if(socket >= 0)
|
||||
{
|
||||
sock.type |= NETTYPE_IPV4;
|
||||
|
@ -1093,7 +1112,7 @@ NETSOCKET net_tcp_create(NETADDR bindaddr)
|
|||
/* bind, we should check for error */
|
||||
tmpbindaddr.type = NETTYPE_IPV6;
|
||||
netaddr_to_sockaddr_in6(&tmpbindaddr, &addr);
|
||||
socket = priv_net_create_socket(AF_INET6, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr));
|
||||
socket = priv_net_create_socket(AF_INET6, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), 0);
|
||||
if(socket >= 0)
|
||||
{
|
||||
sock.type |= NETTYPE_IPV6;
|
||||
|
|
|
@ -576,12 +576,13 @@ int net_addr_from_str(NETADDR *addr, const char *string);
|
|||
|
||||
Parameters:
|
||||
bindaddr - Address to bind the socket to.
|
||||
use_random_port - use a random port
|
||||
|
||||
Returns:
|
||||
On success it returns an handle to the socket. On failure it
|
||||
returns NETSOCKET_INVALID.
|
||||
*/
|
||||
NETSOCKET net_udp_create(NETADDR bindaddr);
|
||||
NETSOCKET net_udp_create(NETADDR bindaddr, int use_random_port);
|
||||
|
||||
/*
|
||||
Function: net_udp_send
|
||||
|
|
|
@ -884,7 +884,7 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket)
|
|||
Packet.m_pData = VERSIONSRV_GETMAPLIST;
|
||||
Packet.m_DataSize = sizeof(VERSIONSRV_GETMAPLIST);
|
||||
Packet.m_Flags = NETSENDFLAG_CONNLESS;
|
||||
m_NetClient.Send(&Packet);
|
||||
m_ContactClient.Send(&Packet);
|
||||
}
|
||||
|
||||
// map version list
|
||||
|
@ -1429,14 +1429,20 @@ void CClient::PumpNetwork()
|
|||
}
|
||||
}
|
||||
|
||||
// process packets
|
||||
// process non-connless packets
|
||||
CNetChunk Packet;
|
||||
while(m_NetClient.Recv(&Packet))
|
||||
{
|
||||
if(Packet.m_ClientID != -1)
|
||||
ProcessServerPacket(&Packet);
|
||||
}
|
||||
|
||||
// process connless packets data
|
||||
m_ContactClient.Update();
|
||||
while(m_ContactClient.Recv(&Packet))
|
||||
{
|
||||
if(Packet.m_ClientID == -1)
|
||||
ProcessConnlessPacket(&Packet);
|
||||
else
|
||||
ProcessServerPacket(&Packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1652,7 +1658,7 @@ void CClient::VersionUpdate()
|
|||
{
|
||||
if(m_VersionInfo.m_State == CVersionInfo::STATE_INIT)
|
||||
{
|
||||
Engine()->HostLookup(&m_VersionInfo.m_VersionServeraddr, g_Config.m_ClVersionServer, m_NetClient.NetType());
|
||||
Engine()->HostLookup(&m_VersionInfo.m_VersionServeraddr, g_Config.m_ClVersionServer, m_ContactClient.NetType());
|
||||
m_VersionInfo.m_State = CVersionInfo::STATE_START;
|
||||
}
|
||||
else if(m_VersionInfo.m_State == CVersionInfo::STATE_START)
|
||||
|
@ -1671,7 +1677,7 @@ void CClient::VersionUpdate()
|
|||
Packet.m_DataSize = sizeof(VERSIONSRV_GETVERSION);
|
||||
Packet.m_Flags = NETSENDFLAG_CONNLESS;
|
||||
|
||||
m_NetClient.Send(&Packet);
|
||||
m_ContactClient.Send(&Packet);
|
||||
m_VersionInfo.m_State = CVersionInfo::STATE_READY;
|
||||
}
|
||||
}
|
||||
|
@ -1699,7 +1705,7 @@ void CClient::InitInterfaces()
|
|||
m_pStorage = Kernel()->RequestInterface<IStorage>();
|
||||
|
||||
//
|
||||
m_ServerBrowser.SetBaseInfo(&m_NetClient, m_pGameClient->NetVersion());
|
||||
m_ServerBrowser.SetBaseInfo(&m_ContactClient, m_pGameClient->NetVersion());
|
||||
m_Friends.Init();
|
||||
}
|
||||
|
||||
|
@ -1753,9 +1759,15 @@ void CClient::Run()
|
|||
mem_zero(&BindAddr, sizeof(BindAddr));
|
||||
BindAddr.type = NETTYPE_ALL;
|
||||
}
|
||||
if(!m_NetClient.Open(BindAddr, 0))
|
||||
if(!m_NetClient.Open(BindAddr, BindAddr.port ? 0 : NETCREATE_FLAG_RANDOMPORT))
|
||||
{
|
||||
dbg_msg("client", "couldn't open socket");
|
||||
dbg_msg("client", "couldn't open socket(net)");
|
||||
return;
|
||||
}
|
||||
BindAddr.port = 0;
|
||||
if(!m_ContactClient.Open(BindAddr, 0))
|
||||
{
|
||||
dbg_msg("client", "couldn't open socket(contact)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1767,7 +1779,7 @@ void CClient::Run()
|
|||
Input()->Init();
|
||||
|
||||
// start refreshing addresses while we load
|
||||
MasterServer()->RefreshAddresses(m_NetClient.NetType());
|
||||
MasterServer()->RefreshAddresses(m_ContactClient.NetType());
|
||||
|
||||
// init the editor
|
||||
m_pEditor->Init();
|
||||
|
|
|
@ -70,6 +70,7 @@ class CClient : public IClient, public CDemoPlayer::IListner
|
|||
};
|
||||
|
||||
class CNetClient m_NetClient;
|
||||
class CNetClient m_ContactClient;
|
||||
class CDemoPlayer m_DemoPlayer;
|
||||
class CDemoRecorder m_DemoRecorder;
|
||||
class CServerBrowser m_ServerBrowser;
|
||||
|
|
|
@ -518,7 +518,7 @@ void CServerBrowser::Set(const NETADDR &Addr, int Type, int Token, const CServer
|
|||
pEntry = Find(Addr);
|
||||
if(!pEntry && m_ServerlistType == IServerBrowser::TYPE_LAN)
|
||||
pEntry = Add(Addr);
|
||||
if(pEntry && pEntry->m_InfoState == CServerEntry::STATE_PENDING && Token == pEntry->m_CurrentToken)
|
||||
if(pEntry && ((pEntry->m_InfoState == CServerEntry::STATE_PENDING && Token == pEntry->m_CurrentToken) || m_ServerlistType == IServerBrowser::TYPE_LAN))
|
||||
{
|
||||
SetInfo(pEntry, *pInfo);
|
||||
if(m_ServerlistType == IServerBrowser::TYPE_LAN)
|
||||
|
@ -607,7 +607,7 @@ void CServerBrowser::RequestImpl(const NETADDR &Addr, CServerEntry *pEntry) cons
|
|||
}
|
||||
|
||||
mem_copy(Buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO));
|
||||
Buffer[sizeof(SERVERBROWSE_GETINFO)] = pEntry->m_CurrentToken;
|
||||
Buffer[sizeof(SERVERBROWSE_GETINFO)] = pEntry ? pEntry->m_CurrentToken : m_CurrentLanToken;
|
||||
|
||||
Packet.m_ClientID = -1;
|
||||
Packet.m_Address = Addr;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
#include <stdlib.h> // srand
|
||||
|
||||
#include <base/system.h>
|
||||
|
||||
|
@ -57,6 +58,7 @@ public:
|
|||
|
||||
CEngine(const char *pAppname)
|
||||
{
|
||||
srand(time_get());
|
||||
dbg_logger_stdout();
|
||||
dbg_logger_debugger();
|
||||
|
||||
|
|
|
@ -36,7 +36,9 @@ enum
|
|||
NETSTATE_ONLINE,
|
||||
|
||||
NETBANTYPE_SOFT=1,
|
||||
NETBANTYPE_DROP=2
|
||||
NETBANTYPE_DROP=2,
|
||||
|
||||
NETCREATE_FLAG_RANDOMPORT=1
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ bool CNetClient::Open(NETADDR BindAddr, int Flags)
|
|||
{
|
||||
// open socket
|
||||
NETSOCKET Socket;
|
||||
Socket = net_udp_create(BindAddr);
|
||||
Socket = net_udp_create(BindAddr, (Flags&NETCREATE_FLAG_RANDOMPORT) ? 1 : 0);
|
||||
if(!Socket.type)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int Ma
|
|||
mem_zero(this, sizeof(*this));
|
||||
|
||||
// open socket
|
||||
m_Socket = net_udp_create(BindAddr);
|
||||
m_Socket = net_udp_create(BindAddr, 0);
|
||||
if(!m_Socket.type)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ static int m_ConfigReorder = 0;
|
|||
void Run(unsigned short Port, NETADDR Dest)
|
||||
{
|
||||
NETADDR Src = {NETTYPE_IPV4, {0,0,0,0}, Port};
|
||||
NETSOCKET Socket = net_udp_create(Src);
|
||||
NETSOCKET Socket = net_udp_create(Src, 0);
|
||||
|
||||
char aBuffer[1024*2];
|
||||
int ID = 0;
|
||||
|
|
|
@ -11,7 +11,7 @@ void Run(NETADDR Dest)
|
|||
for(int i = 0; i < NUM_SOCKETS; i++)
|
||||
{
|
||||
NETADDR BindAddr = {NETTYPE_IPV4, {0}, 0};
|
||||
aSockets[i] = net_udp_create(BindAddr);
|
||||
aSockets[i] = net_udp_create(BindAddr, 0);
|
||||
}
|
||||
|
||||
while(1)
|
||||
|
|
Loading…
Reference in a new issue