Permalink
Browse files

separated connless packet handling and use random port for client's s…

…erver connection
  • Loading branch information...
1 parent 8af77b6 commit 7c43b76758d44ab0edeeea2de177f3b08af8a008 @oy oy committed Mar 18, 2015
View
@@ -852,7 +852,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;
@@ -882,27 +882,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;
@@ -917,7 +936,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;
@@ -939,7 +958,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;
@@ -1076,7 +1095,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;
@@ -1092,7 +1111,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;
View
@@ -566,12 +566,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
@@ -894,7 +894,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
@@ -1434,14 +1434,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);
}
}
@@ -1657,7 +1663,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)
@@ -1676,7 +1682,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;
}
}
@@ -1704,7 +1710,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();
}
@@ -1758,9 +1764,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(net)");
+ return;
+ }
+ BindAddr.port = 0;
+ if(!m_ContactClient.Open(BindAddr, 0))
{
- dbg_msg("client", "couldn't open socket");
+ dbg_msg("client", "couldn't open socket(contact)");
return;
}
}
@@ -1772,7 +1784,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();
@@ -72,6 +72,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;
@@ -452,7 +452,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)
@@ -534,7 +534,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 @@ class CEngine : public IEngine
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(int 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)

0 comments on commit 7c43b76

Please sign in to comment.