added ipv6 support from the old lua branch

This commit is contained in:
oy 2011-03-28 20:11:28 +02:00
parent 63d2019b19
commit 34a9ca20a7
11 changed files with 479 additions and 150 deletions

View file

@ -25,6 +25,7 @@
#include <netinet/in.h>
#include <fcntl.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <dirent.h>
@ -63,6 +64,8 @@ static int num_loggers = 0;
static NETSTATS network_stats = {0};
static MEMSTATS memory_stats = {0};
static NETSOCKET invalid_socket = {NETTYPE_INVALID, -1, -1};
void dbg_logger(DBG_LOGGER logger)
{
loggers[num_loggers++] = logger;
@ -509,27 +512,55 @@ int64 time_freq()
}
/* ----- network ----- */
static void netaddr_to_sockaddr(const NETADDR *src, struct sockaddr *dest)
static void netaddr_to_sockaddr_in(const NETADDR *src, struct sockaddr_in *dest)
{
/* TODO: IPv6 support */
struct sockaddr_in *p = (struct sockaddr_in *)dest;
mem_zero(p, sizeof(struct sockaddr_in));
p->sin_family = AF_INET;
p->sin_port = htons(src->port);
p->sin_addr.s_addr = htonl(src->ip[0]<<24|src->ip[1]<<16|src->ip[2]<<8|src->ip[3]);
mem_zero(dest, sizeof(struct sockaddr_in));
if(src->type != NETTYPE_IPV4)
{
dbg_msg("system", "couldn't convert NETADDR of type %d to ipv4", src->type);
return;
}
dest->sin_family = AF_INET;
dest->sin_port = htons(src->port);
mem_copy(&dest->sin_addr.s_addr, src->ip, 4);
}
static void netaddr_to_sockaddr_in6(const NETADDR *src, struct sockaddr_in6 *dest)
{
mem_zero(dest, sizeof(struct sockaddr_in6));
if(src->type != NETTYPE_IPV6)
{
dbg_msg("system", "couldn't not convert NETADDR of type %d to ipv6", src->type);
return;
}
dest->sin6_family = AF_INET6;
dest->sin6_port = htons(src->port);
mem_copy(&dest->sin6_addr.s6_addr, src->ip, 16);
}
static void sockaddr_to_netaddr(const struct sockaddr *src, NETADDR *dst)
{
/* TODO: IPv6 support */
unsigned int ip = htonl(((struct sockaddr_in*)src)->sin_addr.s_addr);
mem_zero(dst, sizeof(NETADDR));
dst->type = NETTYPE_IPV4;
dst->port = htons(((struct sockaddr_in*)src)->sin_port);
dst->ip[0] = (unsigned char)((ip>>24)&0xFF);
dst->ip[1] = (unsigned char)((ip>>16)&0xFF);
dst->ip[2] = (unsigned char)((ip>>8)&0xFF);
dst->ip[3] = (unsigned char)(ip&0xFF);
if(src->sa_family == AF_INET)
{
mem_zero(dst, sizeof(NETADDR));
dst->type = NETTYPE_IPV4;
dst->port = htons(((struct sockaddr_in*)src)->sin_port);
mem_copy(dst->ip, &((struct sockaddr_in*)src)->sin_addr.s_addr, 4);
}
else if(src->sa_family == AF_INET6)
{
mem_zero(dst, sizeof(NETADDR));
dst->type = NETTYPE_IPV6;
dst->port = htons(((struct sockaddr_in6*)src)->sin6_port);
mem_copy(dst->ip, &((struct sockaddr_in6*)src)->sin6_addr.s6_addr, 16);
}
else
{
mem_zero(dst, sizeof(struct sockaddr));
dbg_msg("system", "couldn't convert sockaddr of family %d", src->sa_family);
}
}
int net_addr_comp(const NETADDR *a, const NETADDR *b)
@ -552,23 +583,70 @@ void net_addr_str(const NETADDR *addr, char *string, int max_length)
str_format(string, max_length, "unknown type %d", addr->type);
}
static int priv_net_extract(const char *hostname, char *host, int max_host, int *port)
{
int i;
*port = 0;
host[0] = 0;
if(hostname[0] == '[')
{
// ipv6 mode
for(i = 1; i < max_host-1 && hostname[i] && hostname[i] != ']'; i++)
host[i-1] = hostname[i];
host[i-1] = 0;
if(hostname[i] != ']') // malformatted
return -1;
i++;
if(hostname[i] == ':')
*port = atol(hostname+i+1);
}
else
{
// generic mode (ipv4, hostname etc)
for(i = 0; i < max_host-1 && hostname[i] && hostname[i] != ':'; i++)
host[i] = hostname[i];
host[i] = 0;
if(hostname[i] == ':')
*port = atol(hostname+i+1);
}
return 0;
}
int net_host_lookup(const char *hostname, NETADDR *addr, int types)
{
/* TODO: IPv6 support */
struct addrinfo hints;
struct addrinfo *result;
int e;
char host[256];
int port = 0;
if(priv_net_extract(hostname, host, sizeof(host), &port))
return -1;
/*
dbg_msg("host lookup", "host='%s' port=%d %d", host, port, types);
*/
mem_zero(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_family = AF_UNSPEC;
e = getaddrinfo(hostname, NULL, &hints, &result);
if(types == NETTYPE_IPV4)
hints.ai_family = AF_INET;
else if(types == NETTYPE_IPV6)
hints.ai_family = AF_INET6;
e = getaddrinfo(host, NULL, &hints, &result);
if(e != 0 || !result)
return -1;
sockaddr_to_netaddr(result->ai_addr, addr);
freeaddrinfo(result);
addr->port = 0;
addr->port = port;
return 0;
}
@ -629,7 +707,39 @@ int net_addr_from_str(NETADDR *addr, const char *string)
if(str[0] == '[')
{
/* TODO: ipv6 */
/* ipv6 */
struct sockaddr_in6 sa6;
char buf[128];
int i, size;
for(i = 0; i < 127 && str[i] && str[i] != ']'; i++)
buf[i] = str[i];
buf[i] = 0;
str += i;
#if defined(CONF_FAMILY_WINDOWS)
sa6.sin6_family = AF_INET6;
size = (int)sizeof(sa6);
if(WSAStringToAddress(buf, AF_INET6, NULL, (struct sockaddr *)&sa6, &size) != 0)
return -1;
#else
if(inet_pton(AF_INET6, buf, &sa6) != 1)
return -1;
#endif
sockaddr_to_netaddr((struct sockaddr *)&sa6, addr);
if(*str == ']')
{
str++;
if(*str == ':')
{
str++;
if(parse_uint16(&addr->port, &str))
return -1;
}
}
else
return -1;
return 0;
}
else
{
@ -653,25 +763,63 @@ int net_addr_from_str(NETADDR *addr, const char *string)
return 0;
}
NETSOCKET net_udp_create(NETADDR bindaddr)
static void priv_net_close_socket(int sock)
{
/* TODO: IPv6 support */
struct sockaddr addr;
#if defined(CONF_FAMILY_WINDOWS)
closesocket(sock);
#else
close(sock);
#endif
}
static int priv_net_close_all_sockets(NETSOCKET sock)
{
/* close down ipv4 */
if(sock.ipv4sock >= 0)
{
priv_net_close_socket(sock.ipv4sock);
sock.ipv4sock = -1;
sock.type &= ~NETTYPE_IPV4;
}
/* close down ipv6 */
if(sock.ipv6sock >= 0)
{
priv_net_close_socket(sock.ipv6sock);
sock.ipv6sock = -1;
sock.type &= ~NETTYPE_IPV6;
}
return 0;
}
static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, int sockaddrlen)
{
int sock, e;
unsigned long mode = 1;
int broadcast = 1;
/* create socket */
int sock = socket(AF_INET, SOCK_DGRAM, 0);
sock = socket(domain, type, 0);
if(sock < 0)
return NETSOCKET_INVALID;
/* bind, we should check for error */
netaddr_to_sockaddr(&bindaddr, &addr);
if(bind(sock, &addr, sizeof(addr)) != 0)
{
net_udp_close(sock);
return NETSOCKET_INVALID;
dbg_msg("net", "failed to create socket with domain %d and type %d (%d '%s')", domain, type, errno, strerror(errno));
return -1;
}
/* set to IPv6 only if thats what we are creating */
if(domain == AF_INET6)
{
int ipv6only = 1;
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&ipv6only, sizeof(ipv6only));
}
/* bind the socket */
e = bind(sock, addr, sockaddrlen);
if(e != 0)
{
dbg_msg("net", "failed to bind socket with domain %d and type %d (%d '%s')", domain, type, errno, strerror(errno));
priv_net_close_socket(sock);
return -1;
}
/* set non-blocking */
@ -684,23 +832,109 @@ NETSOCKET net_udp_create(NETADDR bindaddr)
/* set boardcast */
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast));
/* return the newly created socket */
return sock;
}
NETSOCKET net_udp_create(NETADDR bindaddr)
{
NETSOCKET sock = invalid_socket;
NETADDR tmpbindaddr = bindaddr;
if(bindaddr.type&NETTYPE_IPV4)
{
struct sockaddr_in addr;
int socket = -1;
/* 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));
if(socket >= 0)
{
sock.type |= NETTYPE_IPV4;
sock.ipv4sock = socket;
}
}
if(bindaddr.type&NETTYPE_IPV6)
{
struct sockaddr_in6 addr;
int socket = -1;
/* 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));
if(socket >= 0)
{
sock.type |= NETTYPE_IPV6;
sock.ipv6sock = socket;
}
}
/* return */
return sock;
}
int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size)
{
struct sockaddr sa;
int d;
mem_zero(&sa, sizeof(sa));
netaddr_to_sockaddr(addr, &sa);
d = sendto((int)sock, (const char*)data, size, 0, &sa, sizeof(sa));
int d = -1;
if(addr->type&NETTYPE_IPV4)
{
if(sock.ipv4sock >= 0)
{
struct sockaddr_in sa;
if(addr->type&NETTYPE_LINK_BROADCAST)
{
mem_zero(&sa, sizeof(sa));
sa.sin_port = htons(addr->port);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_BROADCAST;
}
else
netaddr_to_sockaddr_in(addr, &sa);
d = sendto((int)sock.ipv4sock, (const char*)data, size, 0, (struct sockaddr *)&sa, sizeof(sa));
}
else
dbg_msg("net", "can't sent ipv4 traffic to this socket");
}
if(addr->type&NETTYPE_IPV6)
{
if(sock.ipv6sock >= 0)
{
struct sockaddr_in6 sa;
if(addr->type&NETTYPE_LINK_BROADCAST)
{
mem_zero(&sa, sizeof(sa));
sa.sin6_port = htons(addr->port);
sa.sin6_family = AF_INET6;
sa.sin6_addr.s6_addr[0] = 0xff; /* multicast */
sa.sin6_addr.s6_addr[1] = 0x02; /* link local scope */
sa.sin6_addr.s6_addr[15] = 1; /* all nodes */
}
else
netaddr_to_sockaddr_in6(addr, &sa);
d = sendto((int)sock.ipv6sock, (const char*)data, size, 0, (struct sockaddr *)&sa, sizeof(sa));
}
else
dbg_msg("net", "can't sent ipv6 traffic to this socket");
}
/*
else
dbg_msg("net", "can't sent to network of type %d", addr->type);
*/
/*if(d < 0)
{
char addrstr[256];
net_addr_str(addr, addrstr, sizeof(addrstr));
dbg_msg("net", "sendto error %d %x", d, d);
dbg_msg("net", "sendto error (%d '%s')", errno, strerror(errno));
dbg_msg("net", "\tsock = %d %x", sock, sock);
dbg_msg("net", "\tsize = %d %x", size, size);
dbg_msg("net", "\taddr = %s", addrstr);
@ -713,13 +947,25 @@ int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size
int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize)
{
struct sockaddr from;
int bytes;
socklen_t fromlen = sizeof(struct sockaddr);
bytes = recvfrom(sock, (char*)data, maxsize, 0, &from, &fromlen);
char sockaddrbuf[128];
socklen_t fromlen;// = sizeof(sockaddrbuf);
int bytes = 0;
if(bytes == 0 && sock.ipv4sock >= 0)
{
fromlen = sizeof(struct sockaddr_in);
bytes = recvfrom(sock.ipv4sock, (char*)data, maxsize, 0, (struct sockaddr *)&sockaddrbuf, &fromlen);
}
if(bytes <= 0 && sock.ipv6sock >= 0)
{
fromlen = sizeof(struct sockaddr_in6);
bytes = recvfrom(sock.ipv6sock, (char*)data, maxsize, 0, (struct sockaddr *)&sockaddrbuf, &fromlen);
}
if(bytes > 0)
{
sockaddr_to_netaddr(&from, addr);
sockaddr_to_netaddr((struct sockaddr *)&sockaddrbuf, addr);
network_stats.recv_bytes += bytes;
network_stats.recv_packets++;
return bytes;
@ -731,27 +977,29 @@ int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize)
int net_udp_close(NETSOCKET sock)
{
#if defined(CONF_FAMILY_WINDOWS)
closesocket(sock);
#else
close((int)sock);
#endif
return 0;
return priv_net_close_all_sockets(sock);
}
// TODO: make TCP stuff work again
NETSOCKET net_tcp_create(const NETADDR *a)
{
/* TODO: IPv6 support */
struct sockaddr addr;
NETSOCKET sock = invalid_socket;
/* create socket */
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
return NETSOCKET_INVALID;
if(a->type&NETTYPE_IPV4)
{
struct sockaddr_in addr;
/* bind, we should check for error */
netaddr_to_sockaddr(a, &addr);
bind(sock, &addr, sizeof(addr));
/* create socket */
sock.type |= NETTYPE_IPV4;
sock.ipv4sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock.ipv4sock < 0)
return invalid_socket;
/* bind, we should check for error */
netaddr_to_sockaddr_in(a, &addr);
bind(sock.ipv4sock, (struct sockaddr *)&addr, sizeof(addr));
}
/* return */
return sock;
@ -760,26 +1008,58 @@ NETSOCKET net_tcp_create(const NETADDR *a)
int net_tcp_set_non_blocking(NETSOCKET sock)
{
unsigned long mode = 1;
if(sock.ipv4sock >= 0)
{
#if defined(CONF_FAMILY_WINDOWS)
return ioctlsocket(sock, FIONBIO, &mode);
ioctlsocket(sock.ipv4sock, FIONBIO, (unsigned long *)&mode);
#else
return ioctl(sock, FIONBIO, &mode);
ioctl(sock.ipv4sock, FIONBIO, (unsigned long *)&mode);
#endif
}
if(sock.ipv6sock >= 0)
{
#if defined(CONF_FAMILY_WINDOWS)
ioctlsocket(sock.ipv6sock, FIONBIO, (unsigned long *)&mode);
#else
ioctl(sock.ipv6sock, FIONBIO, (unsigned long *)&mode);
#endif
}
return 0;
}
int net_tcp_set_blocking(NETSOCKET sock)
{
unsigned long mode = 0;
if(sock.ipv4sock >= 0)
{
#if defined(CONF_FAMILY_WINDOWS)
return ioctlsocket(sock, FIONBIO, &mode);
ioctlsocket(sock.ipv4sock, FIONBIO, (unsigned long *)&mode);
#else
return ioctl(sock, FIONBIO, &mode);
ioctl(sock.ipv4sock, FIONBIO, (unsigned long *)&mode);
#endif
}
if(sock.ipv6sock >= 0)
{
#if defined(CONF_FAMILY_WINDOWS)
ioctlsocket(sock.ipv6sock, FIONBIO, (unsigned long *)&mode);
#else
ioctl(sock.ipv6sock, FIONBIO, (unsigned long *)&mode);
#endif
}
return 0;
}
int net_tcp_listen(NETSOCKET sock, int backlog)
{
return listen(sock, backlog);
if(sock.ipv4sock >= 0)
listen(sock.ipv4sock, backlog);
if(sock.ipv6sock >= 0)
listen(sock.ipv6sock, backlog);
return 0;
}
int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a)
@ -788,61 +1068,80 @@ int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a)
socklen_t sockaddr_len;
struct sockaddr addr;
*new_sock = invalid_socket;
sockaddr_len = sizeof(addr);
s = accept(sock, &addr, &sockaddr_len);
if (s != -1)
if(sock.ipv4sock >= 0)
{
sockaddr_to_netaddr(&addr, a);
*new_sock = s;
s = accept(sock.ipv4sock, &addr, &sockaddr_len);
if (s != -1)
{
sockaddr_to_netaddr(&addr, a);
new_sock->type = NETTYPE_IPV4;
new_sock->ipv4sock = s;
return s;
}
}
return s;
if(sock.ipv6sock >= 0)
{
s = accept(sock.ipv6sock, &addr, &sockaddr_len);
if (s != -1)
{
sockaddr_to_netaddr(&addr, a);
new_sock->type = NETTYPE_IPV6;
new_sock->ipv6sock = s;
return s;
}
}
return 0;
}
int net_tcp_connect(NETSOCKET sock, const NETADDR *a)
{
struct sockaddr addr;
netaddr_to_sockaddr(a, &addr);
return connect(sock, &addr, sizeof(addr));
/*struct sockaddr addr;
netaddr_to_sockaddr(a, &addr);
return connect(sock, &addr, sizeof(addr));
*/
return 0;
}
int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a)
{
struct sockaddr addr;
int res;
int res = 0;
/*
netaddr_to_sockaddr(a, &addr);
net_tcp_set_non_blocking(sock);
res = connect(sock, &addr, sizeof(addr));
net_tcp_set_blocking(sock);
*/
return res;
}
int net_tcp_send(NETSOCKET sock, const void *data, int size)
{
int d;
d = send((int)sock, (const char*)data, size, 0);
return d;
int bytes = 0;
/* bytes = send((int)sock, (const char*)data, size, 0); */
return bytes;
}
int net_tcp_recv(NETSOCKET sock, void *data, int maxsize)
{
int bytes;
bytes = recv((int)sock, (char*)data, maxsize, 0);
return bytes;
int bytes = 0;
/* bytes = recv((int)sock, (char*)data, maxsize, 0); */
return bytes;
}
int net_tcp_close(NETSOCKET sock)
{
#if defined(CONF_FAMILY_WINDOWS)
closesocket(sock);
#else
close((int)sock);
#endif
return 0;
return priv_net_close_all_sockets(sock);
}
int net_errno()
@ -1077,17 +1376,34 @@ int net_socket_read_wait(NETSOCKET sock, int time)
{
struct timeval tv;
fd_set readfds;
int sockid;
tv.tv_sec = 0;
tv.tv_usec = 1000*time;
sockid = 0;
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
if(sock.ipv4sock >= 0)
{
FD_SET(sock.ipv4sock, &readfds);
sockid = sock.ipv4sock;
}
if(sock.ipv6sock >= 0)
{
FD_SET(sock.ipv6sock, &readfds);
if(sock.ipv6sock > sockid)
sockid = sock.ipv6sock;
}
/* don't care about writefds and exceptfds */
select(sock+1, &readfds, NULL, NULL, &tv);
if(FD_ISSET(sock, &readfds))
return 1;
select(sockid+1, &readfds, NULL, NULL, &tv);
if(sock.ipv4sock >= 0 && FD_ISSET(sock.ipv4sock, &readfds))
return 1;
if(sock.ipv6sock >= 0 && FD_ISSET(sock.ipv6sock, &readfds))
return 1;
return 0;
}

View file

@ -418,15 +418,22 @@ int64 time_freq();
unsigned time_timestamp();
/* Group: Network General */
typedef int NETSOCKET;
typedef struct
{
int type;
int ipv4sock;
int ipv6sock;
} NETSOCKET;
enum
{
NETSOCKET_INVALID = -1,
NETADDR_MAXSTRSIZE = 1+(8*4+7)+1+1+5+1, // [XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]:XXXXX
NETTYPE_INVALID = 0,
NETTYPE_IPV4 = 1,
NETTYPE_IPV6 = 2,
NETTYPE_ALL = ~0
NETTYPE_LINK_BROADCAST = 4,
NETTYPE_ALL = NETTYPE_IPV4|NETTYPE_IPV6
};
typedef struct

View file

@ -692,20 +692,8 @@ void CClient::Connect(const char *pAddress)
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
ServerInfoRequest();
str_copy(aBuf, m_aServerAddressStr, sizeof(aBuf));
for(int k = 0; aBuf[k]; k++)
{
if(aBuf[k] == ':')
{
Port = str_toint(aBuf+k+1);
aBuf[k] = 0;
break;
}
}
// TODO: IPv6 support
if(net_host_lookup(aBuf, &m_ServerAddress, NETTYPE_IPV4) != 0)
if(net_host_lookup(m_aServerAddressStr, &m_ServerAddress, NETTYPE_ALL) != 0)
{
char aBufMsg[256];
str_format(aBufMsg, sizeof(aBufMsg), "could not find the address of %s, connecting to localhost", aBuf);
@ -714,7 +702,8 @@ void CClient::Connect(const char *pAddress)
}
m_RconAuthed = 0;
m_ServerAddress.port = Port;
if(m_ServerAddress.port == 0)
m_ServerAddress.port = Port;
m_NetClient.Connect(&m_ServerAddress);
SetState(IClient::STATE_CONNECTING);
@ -1119,9 +1108,7 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket)
Info.m_NumPlayers < 0 || Info.m_NumPlayers > Info.m_NumClients || Info.m_MaxPlayers < 0 || Info.m_MaxPlayers > Info.m_MaxClients)
return;
str_format(Info.m_aAddress, sizeof(Info.m_aAddress), "%d.%d.%d.%d:%d",
pPacket->m_Address.ip[0], pPacket->m_Address.ip[1], pPacket->m_Address.ip[2],
pPacket->m_Address.ip[3], pPacket->m_Address.port);
net_addr_str(&pPacket->m_Address, Info.m_aAddress, sizeof(Info.m_aAddress));
for(int i = 0; i < Info.m_NumClients; i++)
{
@ -1868,7 +1855,12 @@ void CClient::Run()
{
NETADDR BindAddr;
mem_zero(&BindAddr, sizeof(BindAddr));
m_NetClient.Open(BindAddr, 0);
BindAddr.type = NETTYPE_ALL;
if(!m_NetClient.Open(BindAddr, 0))
{
dbg_msg("client", "couldn't start network");
return;
}
}
// connect to the server if wanted

View file

@ -492,12 +492,10 @@ void CServerBrowser::Refresh(int Type)
mem_copy(Buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO));
Buffer[sizeof(SERVERBROWSE_GETINFO)] = m_CurrentToken;
/* do the broadcast version */
Packet.m_ClientID = -1;
mem_zero(&Packet, sizeof(Packet));
Packet.m_Address.ip[0] = 255;
Packet.m_Address.ip[1] = 255;
Packet.m_Address.ip[2] = 255;
Packet.m_Address.ip[3] = 255;
Packet.m_Address.type = NETTYPE_ALL|NETTYPE_LINK_BROADCAST;
Packet.m_Flags = NETSENDFLAG_CONNLESS;
Packet.m_DataSize = sizeof(Buffer);
Packet.m_pData = Buffer;

View file

@ -30,7 +30,7 @@ public:
virtual int ClientCountry(int ClientID) = 0;
virtual bool ClientIngame(int ClientID) = 0;
virtual int GetClientInfo(int ClientID, CClientInfo *pInfo) = 0;
virtual void GetClientIP(int ClientID, char *pIPString, int Size) = 0;
virtual void GetClientAddr(int ClientID, char *pAddrStr, int Size) = 0;
virtual int *LatestInput(int ClientID, int *pSize) = 0;
virtual int SendMsg(CMsgPacker *pMsg, int Flags, int ClientID) = 0;

View file

@ -333,12 +333,13 @@ int CServer::GetClientInfo(int ClientID, CClientInfo *pInfo)
return 0;
}
void CServer::GetClientIP(int ClientID, char *pIPString, int Size)
void CServer::GetClientAddr(int ClientID, char *pAddrStr, int Size)
{
if(ClientID >= 0 && ClientID < MAX_CLIENTS && m_aClients[ClientID].m_State == CClient::STATE_INGAME)
{
NETADDR Addr = m_NetServer.ClientAddr(ClientID);
str_format(pIPString, Size, "%d.%d.%d.%d", Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
Addr.port = 0;
net_addr_str(&Addr, pAddrStr, Size);
}
}
@ -587,12 +588,10 @@ int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser)
CServer *pThis = (CServer *)pUser;
NETADDR Addr = pThis->m_NetServer.ClientAddr(ClientID);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "client dropped. cid=%d ip=%d.%d.%d.%d reason=\"%s\"",
ClientID,
Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3],
pReason
);
str_format(aBuf, sizeof(aBuf), "client dropped. cid=%d addr=%s reason='%s'", ClientID, aAddrStr, pReason);
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
// notify the mod about the drop
@ -732,10 +731,11 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
if(m_aClients[ClientID].m_State == CClient::STATE_CONNECTING)
{
Addr = m_NetServer.ClientAddr(ClientID);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "player is ready. ClientID=%x ip=%d.%d.%d.%d",
ClientID, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
str_format(aBuf, sizeof(aBuf), "player is ready. ClientID=%x addr=%s", ClientID, aAddrStr);
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
m_aClients[ClientID].m_State = CClient::STATE_READY;
GameServer()->OnClientConnected(ClientID);
@ -747,10 +747,11 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
if(m_aClients[ClientID].m_State == CClient::STATE_READY && GameServer()->IsClientReady(ClientID))
{
Addr = m_NetServer.ClientAddr(ClientID);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "player has entered the game. ClientID=%x ip=%d.%d.%d.%d",
ClientID, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
str_format(aBuf, sizeof(aBuf), "player has entered the game. ClientID=%x addr=%s", ClientID, aAddrStr);
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
m_aClients[ClientID].m_State = CClient::STATE_INGAME;
GameServer()->OnClientEnter(ClientID);
@ -1102,9 +1103,8 @@ int CServer::Run()
}
// start server
// TODO: IPv6 support
NETADDR BindAddr;
if(g_Config.m_SvBindaddr[0] && net_host_lookup(g_Config.m_SvBindaddr, &BindAddr, NETTYPE_IPV4) == 0)
if(g_Config.m_SvBindaddr[0] && net_host_lookup(g_Config.m_SvBindaddr, &BindAddr, NETTYPE_ALL) == 0)
{
// sweet!
BindAddr.port = g_Config.m_SvPort;
@ -1112,6 +1112,7 @@ int CServer::Run()
else
{
mem_zero(&BindAddr, sizeof(BindAddr));
BindAddr.type = NETTYPE_ALL;
BindAddr.port = g_Config.m_SvPort;
}
@ -1342,8 +1343,11 @@ void CServer::ConUnban(IConsole::IResult *pResult, void *pUser)
if(net_addr_from_str(&Addr, pStr) == 0 && !pServer->BanRemove(Addr))
{
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "unbanned %d.%d.%d.%d", Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
str_format(aBuf, sizeof(aBuf), "unbanned %s", aAddrStr);
pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
}
else if(StrAllnum(pStr))
@ -1354,8 +1358,11 @@ void CServer::ConUnban(IConsole::IResult *pResult, void *pUser)
pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "invalid ban index");
else if(!pServer->BanRemove(Info.m_Addr))
{
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&Info.m_Addr, aAddrStr, sizeof(aAddrStr));
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "unbanned %d.%d.%d.%d", Info.m_Addr.ip[0], Info.m_Addr.ip[1], Info.m_Addr.ip[2], Info.m_Addr.ip[3]);
str_format(aBuf, sizeof(aBuf), "unbanned %s", aAddrStr);
pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
}
}
@ -1367,6 +1374,7 @@ void CServer::ConBans(IConsole::IResult *pResult, void *pUser)
{
unsigned Now = time_timestamp();
char aBuf[1024];
char aAddrStr[NETADDR_MAXSTRSIZE];
CServer* pServer = (CServer *)pUser;
int Num = pServer->m_NetServer.BanNum();
@ -1375,15 +1383,16 @@ void CServer::ConBans(IConsole::IResult *pResult, void *pUser)
CNetServer::CBanInfo Info;
pServer->m_NetServer.BanGet(i, &Info);
NETADDR Addr = Info.m_Addr;
net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
if(Info.m_Expires == -1)
{
str_format(aBuf, sizeof(aBuf), "#%d %d.%d.%d.%d for life", i, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
str_format(aBuf, sizeof(aBuf), "#%s for life", i, aAddrStr);
}
else
{
unsigned t = Info.m_Expires - Now;
str_format(aBuf, sizeof(aBuf), "#%d %d.%d.%d.%d for %d minutes and %d seconds", i, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3], t/60, t%60);
str_format(aBuf, sizeof(aBuf), "#%s for %d minutes and %d seconds", i, aAddrStr, t/60, t%60);
}
pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf);
}
@ -1396,6 +1405,7 @@ void CServer::ConStatus(IConsole::IResult *pResult, void *pUser)
int i;
NETADDR Addr;
char aBuf[1024];
char aAddrStr[NETADDR_MAXSTRSIZE];
CServer* pServer = (CServer *)pUser;
for(i = 0; i < MAX_CLIENTS; i++)
@ -1403,13 +1413,12 @@ void CServer::ConStatus(IConsole::IResult *pResult, void *pUser)
if(pServer->m_aClients[i].m_State != CClient::STATE_EMPTY)
{
Addr = pServer->m_NetServer.ClientAddr(i);
net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
if(pServer->m_aClients[i].m_State == CClient::STATE_INGAME)
str_format(aBuf, sizeof(aBuf), "id=%d addr=%d.%d.%d.%d:%d name='%s' score=%d",
i, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3], Addr.port,
str_format(aBuf, sizeof(aBuf), "id=%d addr=%s name='%s' score=%d", i, aAddrStr,
pServer->m_aClients[i].m_aName, pServer->m_aClients[i].m_Score);
else
str_format(aBuf, sizeof(aBuf), "id=%d addr=%d.%d.%d.%d:%d connecting",
i, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3], Addr.port);
str_format(aBuf, sizeof(aBuf), "id=%d addr=%s connecting", i, aAddrStr);
pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf);
}
}

View file

@ -141,7 +141,7 @@ public:
bool IsAuthed(int ClientID);
int GetClientInfo(int ClientID, CClientInfo *pInfo);
void GetClientIP(int ClientID, char *pIPString, int Size);
void GetClientAddr(int ClientID, char *pAddrStr, int Size);
const char *ClientName(int ClientID);
const char *ClientClan(int ClientID);
int ClientCountry(int ClientID);

View file

@ -44,7 +44,7 @@ public:
char m_aName[64];
char m_aMap[32];
char m_aVersion[32];
char m_aAddress[24];
char m_aAddress[NETADDR_MAXSTRSIZE];
CClient m_aClients[MAX_CLIENTS];
};

View file

@ -5,11 +5,17 @@
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));
// open socket
m_Socket = net_udp_create(BindAddr);
// init
m_Socket = Socket;
m_Connection.Init(m_Socket);
return true;
}

View file

@ -33,7 +33,7 @@ bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int
// open socket
m_Socket = net_udp_create(BindAddr);
if(m_Socket == NETSOCKET_INVALID)
if(!m_Socket.type)
return false;
// clamp clients

View file

@ -414,10 +414,10 @@ void CGameContext::OnTick()
if(m_VoteUpdate)
{
// count votes
char aaBuf[MAX_CLIENTS][64] = {{0}};
char aaBuf[MAX_CLIENTS][NETADDR_MAXSTRSIZE] = {{0}};
for(int i = 0; i < MAX_CLIENTS; i++)
if(m_apPlayers[i])
Server()->GetClientIP(i, aaBuf[i], 64);
Server()->GetClientAddr(i, aaBuf[i], NETADDR_MAXSTRSIZE);
bool aVoteChecked[MAX_CLIENTS] = {0};
for(int i = 0; i < MAX_CLIENTS; i++)
{
@ -709,9 +709,10 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
str_format(aCmd, sizeof(aCmd), "kick %d Kicked by vote", KickID);
else
{
char aBuf[64] = {0};
Server()->GetClientIP(KickID, aBuf, sizeof(aBuf));
str_format(aCmd, sizeof(aCmd), "ban %s %d Banned by vote", aBuf, g_Config.m_SvVoteKickBantime);
char aAddrStr[NETADDR_MAXSTRSIZE] = {0};
Server()->GetClientAddr(KickID, aAddrStr, sizeof(aAddrStr));
str_format(aCmd, sizeof(aCmd), "ban %s %d Banned by vote", aAddrStr, g_Config.m_SvVoteKickBantime);
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aCmd);
}
}
else if(str_comp_nocase(pMsg->m_Type, "spectate") == 0)
@ -1229,9 +1230,9 @@ void CGameContext::ConForceVote(IConsole::IResult *pResult, void *pUserData)
}
else
{
char aIP[64] = {0};
pSelf->Server()->GetClientIP(KickID, aIP, sizeof(aIP));
str_format(aBuf, sizeof(aBuf), "ban %s %d %s", aIP, g_Config.m_SvVoteKickBantime, pReason);
char aAddrStr[NETADDR_MAXSTRSIZE] = {0};
pSelf->Server()->GetClientAddr(KickID, aAddrStr, sizeof(aAddrStr));
str_format(aBuf, sizeof(aBuf), "ban %s %d %s", aAddrStr, g_Config.m_SvVoteKickBantime, pReason);
pSelf->Console()->ExecuteLine(aBuf);
}
}