bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags) { // zero out the whole structure mem_zero(this, sizeof(*this)); // open socket m_Socket = net_udp_create(BindAddr); if(!m_Socket.type) return false; m_pNetBan = pNetBan; // clamp clients m_MaxClients = MaxClients; if(m_MaxClients > NET_MAX_CLIENTS) m_MaxClients = NET_MAX_CLIENTS; if(m_MaxClients < 1) m_MaxClients = 1; m_MaxClientsPerIP = MaxClientsPerIP; for(int i = 0; i < NET_MAX_CLIENTS; i++) m_aSlots[i].m_Connection.Init(m_Socket, true); return true; }
bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags) { // zero out the whole structure mem_zero(this, sizeof(*this)); // open socket m_Socket = net_udp_create(BindAddr); if(!m_Socket.type) return false; m_pNetBan = pNetBan; // clamp clients m_MaxClients = MaxClients; if(m_MaxClients > NET_MAX_CLIENTS) m_MaxClients = NET_MAX_CLIENTS; if(m_MaxClients < 1) m_MaxClients = 1; m_MaxClientsPerIP = MaxClientsPerIP; m_NumConAttempts = 0; m_TimeNumConAttempts = time_get(); m_VConnHighLoad = false; m_VConnNum = 0; m_VConnFirst = 0; secure_random_fill(m_SecurityTokenSeed, sizeof(m_SecurityTokenSeed)); for(int i = 0; i < NET_MAX_CLIENTS; i++) m_aSlots[i].m_Connection.Init(m_Socket, true); return true; }
NETSERVER *netserver_open(NETADDR bindaddr, int max_clients, int flags) { int i; NETSERVER *server; NETSOCKET socket = net_udp_create(bindaddr); if(socket == NETSOCKET_INVALID) return 0; server = (NETSERVER *)mem_alloc(sizeof(NETSERVER), 1); mem_zero(server, sizeof(NETSERVER)); server->socket = socket; server->max_clients = max_clients; if(server->max_clients > NET_MAX_CLIENTS) server->max_clients = NET_MAX_CLIENTS; if(server->max_clients < 1) server->max_clients = 1; for(i = 0; i < NET_MAX_CLIENTS; i++) conn_init(&server->slots[i].conn, server->socket); /* setup all pointers for bans */ for(i = 1; i < NET_SERVER_MAXBANS-1; i++) { server->banpool[i].next = &server->banpool[i+1]; server->banpool[i].prev = &server->banpool[i-1]; } server->banpool[0].next = &server->banpool[1]; server->banpool[NET_SERVER_MAXBANS-1].prev = &server->banpool[NET_SERVER_MAXBANS-2]; server->banpool_firstfree = &server->banpool[0]; return server; }
bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int Flags) { // zero out the whole structure mem_zero(this, sizeof(*this)); // open socket m_Socket = net_udp_create(BindAddr); if(!m_Socket.type) return false; // clamp clients m_MaxClients = MaxClients; if(m_MaxClients > NET_MAX_CLIENTS) m_MaxClients = NET_MAX_CLIENTS; if(m_MaxClients < 1) m_MaxClients = 1; m_MaxClientsPerIP = MaxClientsPerIP; for(int i = 0; i < NET_MAX_CLIENTS; i++) m_aSlots[i].m_Connection.Init(m_Socket); // setup all pointers for bans for(int i = 1; i < NET_SERVER_MAXBANS-1; i++) { m_BanPool[i].m_pNext = &m_BanPool[i+1]; m_BanPool[i].m_pPrev = &m_BanPool[i-1]; } m_BanPool[0].m_pNext = &m_BanPool[1]; m_BanPool[NET_SERVER_MAXBANS-1].m_pPrev = &m_BanPool[NET_SERVER_MAXBANS-2]; m_BanPool_FirstFree = &m_BanPool[0]; return true; }
bool CNetClient::Open(NETADDR BindAddr, int Flags) { // clean it mem_zero(this, sizeof(*this)); // open socket m_Socket = net_udp_create(BindAddr); m_Connection.Init(m_Socket); return true; }
bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags) { // zero out the whole structure mem_zero(this, sizeof(*this)); // open socket m_Socket = net_udp_create(BindAddr); if(!m_Socket.type) return false; m_pNetBan = pNetBan; // clamp clients m_MaxClients = MaxClients; if(m_MaxClients > NET_MAX_CLIENTS) m_MaxClients = NET_MAX_CLIENTS; if(m_MaxClients < 1) m_MaxClients = 1; m_MaxClientsPerIP = MaxClientsPerIP; IOHANDLE urandom = io_open("/dev/urandom", IOFLAG_READ); if (urandom) { io_read(urandom, m_SecurityTokenSeed, sizeof(m_SecurityTokenSeed)); io_close(urandom); } else { dbg_msg("security", "/dev/urandom is not available. using sv_rcon_password for security token seed, make sure you have a long password!"); str_copy(m_SecurityTokenSeed, g_Config.m_SvRconPassword, sizeof(m_SecurityTokenSeed)); long timestamp = time_get(); md5_state_t md5; md5_byte_t digest[16]; // do over 9000 rounds of md5 on the rcon password, to make it harder to recover the password from the token values for (int i = 0; i < 1000000; i++) { md5_init(&md5); md5_append(&md5, (unsigned char*)m_SecurityTokenSeed, sizeof(m_SecurityTokenSeed)); md5_append(&md5, (unsigned char*)×tamp, sizeof(timestamp)); md5_finish(&md5, digest); mem_copy(m_SecurityTokenSeed, digest, sizeof(m_SecurityTokenSeed) < sizeof(digest) ? sizeof(m_SecurityTokenSeed) : sizeof(digest)); } } for(int i = 0; i < NET_MAX_CLIENTS; i++) m_aSlots[i].m_Connection.Init(m_Socket, true); return true; }
bool CNetClient::Open(NETADDR BindAddr, int Flags) { // open socket NETSOCKET Socket; Socket = net_udp_create(BindAddr); if(!Socket.type) return false; // clean it mem_zero(this, sizeof(*this)); // init m_Socket = Socket; m_Connection.Init(m_Socket, false); return true; }
bool CNetClient::Open(NETADDR BindAddr, int Flags) { // open socket NETSOCKET Socket; Socket = net_udp_create(BindAddr, (Flags&NETCREATE_FLAG_RANDOMPORT) ? 1 : 0); if(!Socket.type) return false; // clean it mem_zero(this, sizeof(*this)); // init m_Socket = Socket; m_Connection.Init(m_Socket, false); m_TokenManager.Init(Socket); m_TokenCache.Init(Socket, &m_TokenManager); m_Flags = Flags; return true; }
int run(NETADDR dest) { NETSOCKET sockets[NUM_SOCKETS]; int i; for(i = 0; i < NUM_SOCKETS; i++) { NETADDR bindaddr = {NETTYPE_IPV4, {0}, 0}; sockets[i] = net_udp_create(bindaddr); } while(1) { unsigned char data[1024]; int size = 0; int socket_to_use = 0; io_read(io_stdin(), &size, 2); io_read(io_stdin(), &socket_to_use, 1); size %= 256; socket_to_use %= NUM_SOCKETS; io_read(io_stdin(), data, size); net_udp_send(sockets[socket_to_use], &dest, data, size); } }
void Run(int Port, NETADDR Dest) { NETADDR Src = {NETTYPE_IPV4, {0,0,0,0}, Port}; NETSOCKET Socket = net_udp_create(Src); char aBuffer[1024*2]; int ID = 0; int Delaycounter = 0; while(1) { static int Lastcfg = 0; int n = ((time_get()/time_freq())/m_ConfigInterval) % m_ConfigNumpingconfs; CPingConfig Ping = m_aConfigPings[n]; if(n != Lastcfg) dbg_msg("crapnet", "cfg = %d", n); Lastcfg = n; // handle incomming packets while(1) { // fetch data int DataTrash = 0; NETADDR From; int Bytes = net_udp_recv(Socket, &From, aBuffer, 1024*2); if(Bytes <= 0) break; if((rand()%100) < Ping.m_Loss) // drop the packet { if(m_ConfigLog) dbg_msg("crapnet", "dropped packet"); continue; } // create new packet CPacket *p = (CPacket *)mem_alloc(sizeof(CPacket)+Bytes, 1); if(net_addr_comp(&From, &Dest) == 0) p->m_SendTo = Src; // from the server else { Src = From; // from the client p->m_SendTo = Dest; } // queue packet p->m_pPrev = m_pLast; p->m_pNext = 0; if(m_pLast) m_pLast->m_pNext = p; else { m_pFirst = p; m_pLast = p; } m_pLast = p; // set data in packet p->m_Timestamp = time_get(); p->m_DataSize = Bytes; p->m_ID = ID++; mem_copy(p->m_aData, aBuffer, Bytes); if(ID > 20 && Bytes > 6 && DataTrash) { p->m_aData[6+(rand()%(Bytes-6))] = rand()&255; // modify a byte if((rand()%10) == 0) { p->m_DataSize -= rand()%32; if(p->m_DataSize < 6) p->m_DataSize = 6; } } if(Delaycounter <= 0) { if(Ping.m_Delay) p->m_Timestamp += (time_freq()*1000)/Ping.m_Delay; Delaycounter = Ping.m_DelayFreq; } Delaycounter--; if(m_ConfigLog) { char aAddrStr[NETADDR_MAXSTRSIZE]; net_addr_str(&From, aAddrStr, sizeof(aAddrStr), true); dbg_msg("crapnet", "<< %08d %s (%d)", p->m_ID, aAddrStr, p->m_DataSize); } } // /*while(1) {*/ CPacket *p = 0; CPacket *pNext = m_pFirst; while(1) { p = pNext; if(!p) break; pNext = p->m_pNext; if((time_get()-p->m_Timestamp) > m_CurrentLatency) { char aFlags[] = " "; if(m_ConfigReorder && (rand()%2) == 0 && p->m_pNext) { aFlags[0] = 'R'; p = m_pFirst->m_pNext; } if(p->m_pNext) p->m_pNext->m_pPrev = p->m_pPrev; else m_pLast = p->m_pPrev; if(p->m_pPrev) p->m_pPrev->m_pNext = p->m_pNext; else m_pFirst = p->m_pNext; /*CPacket *cur = first; while(cur) { dbg_assert(cur != p, "p still in list"); cur = cur->next; }*/ // send and remove packet //if((rand()%20) != 0) // heavy packetloss net_udp_send(Socket, &p->m_SendTo, p->m_aData, p->m_DataSize); // update lag double Flux = rand()/(double)RAND_MAX; int MsSpike = Ping.m_Spike; int MsFlux = Ping.m_Flux; int MsPing = Ping.m_Base; m_CurrentLatency = ((time_freq()*MsPing)/1000) + (int64)(((time_freq()*MsFlux)/1000)*Flux); // 50ms if(MsSpike && (p->m_ID%100) == 0) { m_CurrentLatency += (time_freq()*MsSpike)/1000; aFlags[1] = 'S'; } if(m_ConfigLog) { char aAddrStr[NETADDR_MAXSTRSIZE]; net_addr_str(&p->m_SendTo, aAddrStr, sizeof(aAddrStr), true); dbg_msg("crapnet", ">> %08d %s (%d) %s", p->m_ID, aAddrStr, p->m_DataSize, aFlags); } mem_free(p); } } thread_sleep(1); } }