Quake II RTX doxygen  1.0 dev
net.c File Reference
#include "shared/shared.h"
#include "common/common.h"
#include "common/cvar.h"
#include "common/fifo.h"
#include "common/msg.h"
#include "common/net/net.h"
#include "common/protocol.h"
#include "common/zone.h"
#include "client/client.h"
#include "server/server.h"
#include "system/system.h"
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include "inet_ntop.h"
#include "inet_pton.h"
#include "win.h"

Go to the source code of this file.

Macros

#define WIN32_LEAN_AND_MEAN
 
#define MAX_ERROR_RETRIES   64
 
#define NS_INT16SZ   2
 
#define NS_INADDRSZ   4
 
#define NS_IN6ADDRSZ   16
 
#define RATE_SECS   3
 

Functions

static size_t NET_NetadrToSockadr (const netadr_t *a, struct sockaddr_storage *s)
 
static void NET_SockadrToNetadr (const struct sockaddr_storage *s, netadr_t *a)
 
char * NET_BaseAdrToString (const netadr_t *a)
 
char * NET_AdrToString (const netadr_t *a)
 
static struct addrinfo * NET_SearchAdrrInfo (struct addrinfo *rp, int family)
 
qboolean NET_StringPairToAdr (const char *host, const char *port, netadr_t *a)
 
qboolean NET_StringToAdr (const char *s, netadr_t *a, int default_port)
 
void NET_UpdateStats (void)
 
static void NET_Stats_f (void)
 
static size_t NET_UpRate_m (char *buffer, size_t size)
 
static size_t NET_DnRate_m (char *buffer, size_t size)
 
const char * NET_ErrorString (void)
 
ioentry_t * NET_AddFd (qsocket_t fd)
 
void NET_RemoveFd (qsocket_t fd)
 
int NET_Sleep (int msec)
 
static void NET_GetUdpPackets (qsocket_t sock, void(*packet_cb)(void))
 
void NET_GetPackets (netsrc_t sock, void(*packet_cb)(void))
 
qboolean NET_SendPacket (netsrc_t sock, const void *data, size_t len, const netadr_t *to)
 
static qsocket_t UDP_OpenSocket (const char *iface, int port, int family)
 
static qsocket_t TCP_OpenSocket (const char *iface, int port, int family, netsrc_t who)
 
static void NET_OpenServer (void)
 
static void NET_OpenServer6 (void)
 
void NET_Config (netflag_t flag)
 
qboolean NET_GetAddress (netsrc_t sock, netadr_t *adr)
 
void NET_CloseStream (netstream_t *s)
 
static neterr_t NET_Listen4 (qboolean arg)
 
static neterr_t NET_Listen6 (qboolean arg)
 
neterr_t NET_Listen (qboolean arg)
 
static neterr_t NET_AcceptSocket (netstream_t *s, qsocket_t sock)
 
neterr_t NET_Accept (netstream_t *s)
 
neterr_t NET_Connect (const netadr_t *peer, netstream_t *s)
 
neterr_t NET_RunConnect (netstream_t *s)
 
void NET_UpdateStream (netstream_t *s)
 
neterr_t NET_RunStream (netstream_t *s)
 
static void dump_addrinfo (struct addrinfo *ai)
 
static void dump_socket (qsocket_t s, const char *s1, const char *s2)
 
static void NET_ShowIP_f (void)
 
static void NET_Dns_f (void)
 
static void NET_Restart_f (void)
 
static void net_udp_param_changed (cvar_t *self)
 
static const char * NET_EnableIP6 (void)
 
void NET_Init (void)
 
void NET_Shutdown (void)
 

Variables

cvar_t * net_ip
 
cvar_t * net_ip6
 
cvar_t * net_port
 
netadr_t net_from
 
static cvar_t * net_enable_ipv6
 
static netflag_t net_active
 
static int net_error
 
static qsocket_t udp_sockets [NS_COUNT] = { -1, -1 }
 
static qsocket_t tcp_socket = -1
 
static qsocket_t udp6_sockets [NS_COUNT] = { -1, -1 }
 
static qsocket_t tcp6_socket = -1
 
static ioentry_t io_entries [FD_SETSIZE]
 
static int io_numfds
 
static unsigned net_rate_time
 
static size_t net_rate_rcvd
 
static size_t net_rate_sent
 
static size_t net_rate_dn
 
static size_t net_rate_up
 
static uint64_t net_recv_errors
 
static uint64_t net_send_errors
 
static uint64_t net_bytes_rcvd
 
static uint64_t net_bytes_sent
 
static uint64_t net_packets_rcvd
 
static uint64_t net_packets_sent
 

Macro Definition Documentation

◆ MAX_ERROR_RETRIES

#define MAX_ERROR_RETRIES   64

Definition at line 65 of file net.c.

◆ NS_IN6ADDRSZ

#define NS_IN6ADDRSZ   16

Definition at line 208 of file net.c.

◆ NS_INADDRSZ

#define NS_INADDRSZ   4

Definition at line 207 of file net.c.

◆ NS_INT16SZ

#define NS_INT16SZ   2

Definition at line 206 of file net.c.

◆ RATE_SECS

#define RATE_SECS   3

Definition at line 470 of file net.c.

◆ WIN32_LEAN_AND_MEAN

#define WIN32_LEAN_AND_MEAN

Definition at line 39 of file net.c.

Function Documentation

◆ dump_addrinfo()

static void dump_addrinfo ( struct addrinfo *  ai)
static

Definition at line 1747 of file net.c.

1748 {
1749  char buf1[MAX_QPATH], buf2[MAX_STRING_CHARS];
1750  char *fa = (ai->ai_addr->sa_family == AF_INET6) ? "6" : "";
1751 
1752  getnameinfo(ai->ai_addr, ai->ai_addrlen,
1753  buf1, sizeof(buf1), NULL, 0, NI_NUMERICHOST);
1754  if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
1755  buf2, sizeof(buf2), NULL, 0, NI_NAMEREQD) == 0)
1756  Com_Printf("IP%1s : %s (%s)\n", fa, buf1, buf2);
1757  else
1758  Com_Printf("IP%1s : %s\n", fa, buf1);
1759 }

Referenced by NET_Dns_f(), and NET_ShowIP_f().

◆ dump_socket()

static void dump_socket ( qsocket_t  s,
const char *  s1,
const char *  s2 
)
static

Definition at line 1761 of file net.c.

1762 {
1763  netadr_t adr;
1764 
1765  if (s == -1)
1766  return;
1767 
1768  if (os_getsockname(s, &adr)) {
1769  Com_EPrintf("Couldn't get %s %s socket name: %s\n",
1770  s1, s2, NET_ErrorString());
1771  return;
1772  }
1773 
1774  Com_Printf("%s %s socket bound to %s\n",
1775  s1, s2, NET_AdrToString(&adr));
1776 }

Referenced by NET_ShowIP_f().

◆ NET_Accept()

neterr_t NET_Accept ( netstream_t *  s)

Definition at line 1525 of file net.c.

1526 {
1527  neterr_t ret;
1528 
1529  ret = NET_AcceptSocket(s, tcp_socket);
1530  if (ret == NET_AGAIN)
1531  ret = NET_AcceptSocket(s, tcp6_socket);
1532 
1533  return ret;
1534 }

Referenced by CL_GTV_Run(), and SV_MvdRunClients().

◆ NET_AcceptSocket()

static neterr_t NET_AcceptSocket ( netstream_t *  s,
qsocket_t  sock 
)
static

Definition at line 1482 of file net.c.

1483 {
1484  ioentry_t *e;
1485  qsocket_t newsocket;
1486  neterr_t ret;
1487 
1488  if (sock == -1) {
1489  return NET_AGAIN;
1490  }
1491 
1492  e = os_get_io(sock);
1493  if (!e->canread) {
1494  return NET_AGAIN;
1495  }
1496 
1497  ret = os_accept(sock, &newsocket, &net_from);
1498  if (ret) {
1499  e->canread = qfalse;
1500  return ret;
1501  }
1502 
1503  // make it non-blocking
1504  ret = os_make_nonblock(newsocket, 1);
1505  if (ret) {
1506  os_closesocket(newsocket);
1507  return ret;
1508  }
1509 
1510  // initialize stream
1511  memset(s, 0, sizeof(*s));
1512  s->socket = newsocket;
1513  s->address = net_from;
1514  s->state = NS_CONNECTED;
1515 
1516  // initialize io entry
1517  e = NET_AddFd(newsocket);
1518  //e->wantwrite = qtrue;
1519  e->wantread = qtrue;
1520 
1521  return NET_OK;
1522 }

Referenced by NET_Accept().

◆ NET_AddFd()

ioentry_t* NET_AddFd ( qsocket_t  fd)

Definition at line 671 of file net.c.

672 {
673  ioentry_t *e = os_add_io(fd);
674 
675  e->inuse = qtrue;
676  return e;
677 }

Referenced by NET_AcceptSocket(), NET_Connect(), NET_Listen4(), NET_Listen6(), NET_OpenServer(), and NET_OpenServer6().

◆ NET_AdrToString()

◆ NET_BaseAdrToString()

char* NET_BaseAdrToString ( const netadr_t *  a)

Definition at line 216 of file net.c.

217 {
218  static char s[MAX_QPATH];
219 
220  switch (a->type) {
221  case NA_UNSPECIFIED:
222  return strcpy(s, "<unspecified>");
223  case NA_LOOPBACK:
224  return strcpy(s, "loopback");
225  case NA_IP:
226  case NA_BROADCAST:
227  if (os_inet_ntop(AF_INET, &a->ip, s, sizeof(s)))
228  return s;
229  else
230  return strcpy(s, "<invalid>");
231  case NA_IP6:
232  if (a->scope_id) {
233  struct sockaddr_storage addr;
234  size_t addrlen;
235 
236  addrlen = NET_NetadrToSockadr(a, &addr);
237  if (getnameinfo((struct sockaddr *)&addr, addrlen,
238  s, sizeof(s), NULL, 0, NI_NUMERICHOST) == 0)
239  return s;
240  }
241  if (os_inet_ntop(AF_INET6, &a->ip, s, sizeof(s)))
242  return s;
243  else
244  return strcpy(s, "<invalid>");
245  default:
246  Com_Error(ERR_FATAL, "%s: bad address type", __func__);
247  }
248 
249  return NULL;
250 }

Referenced by format_mask(), and NET_AdrToString().

◆ NET_CloseStream()

void NET_CloseStream ( netstream_t *  s)

Definition at line 1371 of file net.c.

1372 {
1373  if (!s->state) {
1374  return;
1375  }
1376 
1377  NET_RemoveFd(s->socket);
1378  os_closesocket(s->socket);
1379  s->socket = -1;
1380  s->state = NS_DISCONNECTED;
1381 }

Referenced by AC_Disconnect(), AC_Drop(), accept_client(), drop_client(), gtv_destroy(), gtv_drop(), and remove_client().

◆ NET_Config()

void NET_Config ( netflag_t  flag)

Definition at line 1312 of file net.c.

1313 {
1314  netsrc_t sock;
1315 
1316  if (flag == net_active) {
1317  return;
1318  }
1319 
1320  if (flag == NET_NONE) {
1321  // shut down any existing sockets
1322  for (sock = 0; sock < NS_COUNT; sock++) {
1323  if (udp_sockets[sock] != -1) {
1324  NET_RemoveFd(udp_sockets[sock]);
1325  os_closesocket(udp_sockets[sock]);
1326  udp_sockets[sock] = -1;
1327  }
1328  if (udp6_sockets[sock] != -1) {
1329  NET_RemoveFd(udp6_sockets[sock]);
1331  udp6_sockets[sock] = -1;
1332  }
1333  }
1334  net_active = NET_NONE;
1335  return;
1336  }
1337 
1338 #if USE_CLIENT
1339  if (flag & NET_CLIENT) {
1340  NET_OpenClient();
1341  NET_OpenClient6();
1342  }
1343 #endif
1344 
1345  if (flag & NET_SERVER) {
1346  NET_OpenServer();
1347  NET_OpenServer6();
1348  }
1349 
1350  net_active |= flag;
1351 }

Referenced by CL_Connect_f(), CL_PassiveConnect_f(), CL_PingServers_f(), CL_SendRcon(), CL_ServerStatus_f(), NET_Restart_f(), NET_Shutdown(), Qcommon_Init(), and SV_InitGame().

◆ NET_Connect()

neterr_t NET_Connect ( const netadr_t *  peer,
netstream_t *  s 
)

Definition at line 1536 of file net.c.

1537 {
1538  qsocket_t socket;
1539  ioentry_t *e;
1540  neterr_t ret;
1541 
1542  // always bind to `net_ip' for outgoing TCP connections
1543  // to avoid problems with AC or MVD/GTV auth on a multi IP system
1544  switch (peer->type) {
1545  case NA_IP:
1546  socket = TCP_OpenSocket(net_ip->string, PORT_ANY, AF_INET, NS_CLIENT);
1547  break;
1548  case NA_IP6:
1549  socket = TCP_OpenSocket(net_ip6->string, PORT_ANY, AF_INET6, NS_CLIENT);
1550  break;
1551  default:
1552  return NET_ERROR;
1553  }
1554 
1555  if (socket == -1) {
1556  return NET_ERROR;
1557  }
1558 
1559  ret = os_connect(socket, peer);
1560  if (ret) {
1561  os_closesocket(socket);
1562  return NET_ERROR;
1563  }
1564 
1565  // initialize stream
1566  memset(s, 0, sizeof(*s));
1567  s->state = NS_CONNECTING;
1568  s->address = *peer;
1569  s->socket = socket;
1570 
1571  // initialize io entry
1572  e = NET_AddFd(socket);
1573  e->wantwrite = qtrue;
1574 #ifdef _WIN32
1575  e->wantexcept = qtrue;
1576 #endif
1577 
1578  return NET_OK;
1579 }

Referenced by AC_Reconnect(), check_reconnect(), and MVD_Connect_f().

◆ NET_DnRate_m()

static size_t NET_DnRate_m ( char *  buffer,
size_t  size 
)
static

Definition at line 535 of file net.c.

536 {
537  return Q_scnprintf(buffer, size, "%"PRIz, net_rate_dn);
538 }

Referenced by NET_Init().

◆ NET_Dns_f()

static void NET_Dns_f ( void  )
static

Definition at line 1831 of file net.c.

1832 {
1833  char buffer[MAX_STRING_CHARS], *h, *p;
1834  struct addrinfo hints, *res, *rp;
1835  int err;
1836 
1837  if (Cmd_Argc() != 2) {
1838  Com_Printf("Usage: %s <address>\n", Cmd_Argv(0));
1839  return;
1840  }
1841 
1842  Cmd_ArgvBuffer(1, buffer, sizeof(buffer));
1843 
1844  // parse IPv6 address square brackets
1845  h = p = buffer;
1846  if (*h == '[') {
1847  h++;
1848  p = strchr(h, ']');
1849  if (!p) {
1850  Com_Printf("Bad IPv6 address\n");
1851  return;
1852  }
1853  *p++ = 0;
1854  }
1855 
1856  // strip off a trailing :port if present
1857  p = strchr(p, ':');
1858  if (p)
1859  *p++ = 0;
1860 
1861  memset(&hints, 0, sizeof(hints));
1862  hints.ai_flags = AI_CANONNAME;
1863  hints.ai_socktype = SOCK_STREAM;
1864 
1865  if (net_enable_ipv6->integer < 1)
1866  hints.ai_family = AF_INET;
1867 
1868  err = getaddrinfo(h, NULL, &hints, &res);
1869  if (err) {
1870  Com_Printf("Couldn't resolve %s: %s\n", h, gai_strerror(err));
1871  return;
1872  }
1873 
1874  if (res->ai_canonname)
1875  Com_Printf("Hostname: %s\n", res->ai_canonname);
1876 
1877  for (rp = res; rp; rp = rp->ai_next)
1878  dump_addrinfo(rp);
1879 
1880  freeaddrinfo(res);
1881 }

Referenced by NET_Init().

◆ NET_EnableIP6()

static const char* NET_EnableIP6 ( void  )
static

Definition at line 1917 of file net.c.

1918 {
1919  qsocket_t s = os_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
1920 
1921  if (s == -1)
1922  return "0";
1923 
1924  os_closesocket(s);
1925  return "1";
1926 }

Referenced by NET_Init().

◆ NET_ErrorString()

◆ NET_GetAddress()

qboolean NET_GetAddress ( netsrc_t  sock,
netadr_t *  adr 
)

Definition at line 1358 of file net.c.

1359 {
1360  if (udp_sockets[sock] == -1)
1361  return qfalse;
1362 
1363  if (os_getsockname(udp_sockets[sock], adr))
1364  return qfalse;
1365 
1366  return qtrue;
1367 }

Referenced by CL_PassiveConnect_f().

◆ NET_GetPackets()

void NET_GetPackets ( netsrc_t  sock,
void(*)(void packet_cb 
)

Definition at line 895 of file net.c.

896 {
897 #if USE_CLIENT
898  memset(&net_from, 0, sizeof(net_from));
899  net_from.type = NA_LOOPBACK;
900 
901  // process loopback packets
902  NET_GetLoopPackets(sock, packet_cb);
903 #endif
904 
905  // process UDP packets
906  NET_GetUdpPackets(udp_sockets[sock], packet_cb);
907 
908  // process UDP6 packets
909  NET_GetUdpPackets(udp6_sockets[sock], packet_cb);
910 }

Referenced by CL_ProcessEvents(), and SV_Frame().

◆ NET_GetUdpPackets()

static void NET_GetUdpPackets ( qsocket_t  sock,
void(*)(void packet_cb 
)
static

Definition at line 845 of file net.c.

846 {
847  ioentry_t *e;
848  ssize_t ret;
849 
850  if (sock == -1)
851  return;
852 
853  e = os_get_io(sock);
854  if (!e->canread)
855  return;
856 
857  while (1) {
858  ret = os_udp_recv(sock, msg_read_buffer, MAX_PACKETLEN, &net_from);
859  if (ret == NET_AGAIN) {
860  e->canread = qfalse;
861  break;
862  }
863 
864  if (ret == NET_ERROR) {
865  Com_DPrintf("%s: %s from %s\n", __func__,
867  net_recv_errors++;
868  break;
869  }
870 
871 #ifdef _DEBUG
872  if (net_log_enable->integer)
873  NET_LogPacket(&net_from, "UDP recv", msg_read_buffer, ret);
874 #endif
875 
876  net_rate_rcvd += ret;
877  net_bytes_rcvd += ret;
879 
881  msg_read.cursize = ret;
882 
883  (*packet_cb)();
884  }
885 }

Referenced by NET_GetPackets().

◆ NET_Init()

void NET_Init ( void  )

Definition at line 1933 of file net.c.

1934 {
1935  os_net_init();
1936 
1937  net_ip = Cvar_Get("net_ip", "", 0);
1938  net_ip->changed = net_udp_param_changed;
1939  net_ip6 = Cvar_Get("net_ip6", "", 0);
1940  net_ip6->changed = net_udp_param_changed;
1941  net_port = Cvar_Get("net_port", STRINGIFY(PORT_SERVER), 0);
1942  net_port->changed = net_udp_param_changed;
1943 
1944 #if USE_CLIENT
1945  net_clientport = Cvar_Get("net_clientport", STRINGIFY(PORT_ANY), 0);
1946  net_clientport->changed = net_udp_param_changed;
1947  net_dropsim = Cvar_Get("net_dropsim", "0", 0);
1948 #endif
1949 
1950 #if _DEBUG
1951  net_log_enable = Cvar_Get("net_log_enable", "0", 0);
1952  net_log_enable->changed = net_log_enable_changed;
1953  net_log_name = Cvar_Get("net_log_name", "network", 0);
1954  net_log_name->changed = net_log_param_changed;
1955  net_log_flush = Cvar_Get("net_log_flush", "0", 0);
1956  net_log_flush->changed = net_log_param_changed;
1957 #endif
1958 
1959  net_enable_ipv6 = Cvar_Get("net_enable_ipv6", NET_EnableIP6(), 0);
1961 
1962 #if USE_ICMP
1963  net_ignore_icmp = Cvar_Get("net_ignore_icmp", "0", 0);
1964 #endif
1965 
1966 #if _DEBUG
1967  net_log_enable_changed(net_log_enable);
1968 #endif
1969 
1971 
1972  Cmd_AddCommand("net_restart", NET_Restart_f);
1973  Cmd_AddCommand("net_stats", NET_Stats_f);
1974  Cmd_AddCommand("showip", NET_ShowIP_f);
1975  Cmd_AddCommand("dns", NET_Dns_f);
1976 
1977  Cmd_AddMacro("net_uprate", NET_UpRate_m);
1978  Cmd_AddMacro("net_dnrate", NET_DnRate_m);
1979 }

Referenced by Qcommon_Init().

◆ NET_Listen()

neterr_t NET_Listen ( qboolean  arg)

Definition at line 1466 of file net.c.

1467 {
1468  neterr_t ret4, ret6;
1469 
1470  ret4 = NET_Listen4(arg);
1471  ret6 = NET_Listen6(arg);
1472 
1473  if (ret4 == NET_OK || ret6 == NET_OK)
1474  return NET_OK;
1475 
1476  if (ret4 == NET_ERROR || ret6 == NET_ERROR)
1477  return NET_ERROR;
1478 
1479  return NET_AGAIN;
1480 }

Referenced by CL_GTV_Start_f(), CL_GTV_Stop_f(), NET_Shutdown(), SV_MvdInit(), and SV_MvdShutdown().

◆ NET_Listen4()

static neterr_t NET_Listen4 ( qboolean  arg)
static

Definition at line 1383 of file net.c.

1384 {
1385  qsocket_t s;
1386  ioentry_t *e;
1387  neterr_t ret;
1388 
1389  if (!arg) {
1390  if (tcp_socket != -1) {
1393  tcp_socket = -1;
1394  }
1395  return NET_OK;
1396  }
1397 
1398  if (tcp_socket != -1) {
1399  return NET_AGAIN;
1400  }
1401 
1402  s = TCP_OpenSocket(net_ip->string, net_port->integer, AF_INET, NS_SERVER);
1403  if (s == -1) {
1404  return NET_ERROR;
1405  }
1406 
1407  ret = os_listen(s, 16);
1408  if (ret) {
1409  os_closesocket(s);
1410  return ret;
1411  }
1412 
1413  tcp_socket = s;
1414 
1415  // initialize io entry
1416  e = NET_AddFd(s);
1417  e->wantread = qtrue;
1418 
1419  return NET_OK;
1420 }

Referenced by NET_Listen(), and NET_Restart_f().

◆ NET_Listen6()

static neterr_t NET_Listen6 ( qboolean  arg)
static

Definition at line 1422 of file net.c.

1423 {
1424  qsocket_t s;
1425  ioentry_t *e;
1426  neterr_t ret;
1427 
1428  if (!arg) {
1429  if (tcp6_socket != -1) {
1432  tcp6_socket = -1;
1433  }
1434  return NET_OK;
1435  }
1436 
1437 
1438  if (tcp6_socket != -1) {
1439  return NET_AGAIN;
1440  }
1441 
1442  if (net_enable_ipv6->integer < 2) {
1443  return NET_AGAIN;
1444  }
1445 
1446  s = TCP_OpenSocket(net_ip6->string, net_port->integer, AF_INET6, NS_SERVER);
1447  if (s == -1) {
1448  return NET_ERROR;
1449  }
1450 
1451  ret = os_listen(s, 16);
1452  if (ret) {
1453  os_closesocket(s);
1454  return ret;
1455  }
1456 
1457  tcp6_socket = s;
1458 
1459  // initialize io entry
1460  e = NET_AddFd(s);
1461  e->wantread = qtrue;
1462 
1463  return NET_OK;
1464 }

Referenced by NET_Listen(), and NET_Restart_f().

◆ NET_NetadrToSockadr()

static size_t NET_NetadrToSockadr ( const netadr_t *  a,
struct sockaddr_storage *  s 
)
static

Definition at line 145 of file net.c.

146 {
147  struct sockaddr_in *s4 = (struct sockaddr_in *)s;
148  struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)s;
149 
150  memset(s, 0, sizeof(*s));
151 
152  switch (a->type) {
153  case NA_BROADCAST:
154  s4->sin_family = AF_INET;
155  s4->sin_addr.s_addr = INADDR_BROADCAST;
156  s4->sin_port = a->port;
157  return sizeof(*s4);
158  case NA_IP:
159  s4->sin_family = AF_INET;
160  memcpy(&s4->sin_addr, &a->ip, 4);
161  s4->sin_port = a->port;
162  return sizeof(*s4);
163  case NA_IP6:
164  s6->sin6_family = AF_INET6;
165  memcpy(&s6->sin6_addr, &a->ip, 16);
166  s6->sin6_port = a->port;
167  s6->sin6_scope_id = a->scope_id;
168  return sizeof(*s6);
169  default:
170  break;
171  }
172 
173  return 0;
174 }

Referenced by NET_BaseAdrToString(), os_connect(), and os_udp_send().

◆ NET_OpenServer()

static void NET_OpenServer ( void  )
static

Definition at line 1195 of file net.c.

1196 {
1197  static int saved_port;
1198  ioentry_t *e;
1199  qsocket_t s;
1200 
1201  if (udp_sockets[NS_SERVER] != -1)
1202  return;
1203 
1204  s = UDP_OpenSocket(net_ip->string, net_port->integer, AF_INET);
1205  if (s != -1) {
1206  saved_port = net_port->integer;
1207  udp_sockets[NS_SERVER] = s;
1208  e = NET_AddFd(s);
1209  e->wantread = qtrue;
1210  return;
1211  }
1212 
1213  if (saved_port && saved_port != net_port->integer) {
1214  // revert to the last valid port
1215  Com_Printf("Reverting to the last valid port %d...\n", saved_port);
1216  Cbuf_AddText(&cmd_buffer, va("set net_port %d\n", saved_port));
1217  return;
1218  }
1219 
1220 #if USE_CLIENT
1221  if (!dedicated->integer) {
1222  Com_WPrintf("Couldn't open server UDP port.\n");
1223  return;
1224  }
1225 #endif
1226 
1227  Com_Error(ERR_FATAL, "Couldn't open dedicated server UDP port");
1228 }

Referenced by NET_Config().

◆ NET_OpenServer6()

static void NET_OpenServer6 ( void  )
static

Definition at line 1230 of file net.c.

1231 {
1232  ioentry_t *e;
1233  qsocket_t s;
1234 
1235  if (net_enable_ipv6->integer < 2)
1236  return;
1237 
1238  if (udp6_sockets[NS_SERVER] != -1)
1239  return;
1240 
1241  s = UDP_OpenSocket(net_ip6->string, net_port->integer, AF_INET6);
1242  if (s == -1)
1243  return;
1244 
1245  udp6_sockets[NS_SERVER] = s;
1246  e = NET_AddFd(s);
1247  e->wantread = qtrue;
1248 }

Referenced by NET_Config().

◆ NET_RemoveFd()

void NET_RemoveFd ( qsocket_t  fd)

Definition at line 686 of file net.c.

687 {
688  ioentry_t *e = os_get_io(fd);
689  int i;
690 
691  memset(e, 0, sizeof(*e));
692 
693  for (i = io_numfds - 1; i >= 0; i--) {
694  e = &io_entries[i];
695  if (e->inuse) {
696  break;
697  }
698  }
699 
700  io_numfds = i + 1;
701 }

Referenced by NET_CloseStream(), NET_Config(), NET_Listen4(), and NET_Listen6().

◆ NET_Restart_f()

static void NET_Restart_f ( void  )
static

Definition at line 1888 of file net.c.

1889 {
1890  netflag_t flag = net_active;
1891  qboolean listen4 = (tcp_socket != -1);
1892  qboolean listen6 = (tcp6_socket != -1);
1893 
1894  Com_DPrintf("%s\n", __func__);
1895 
1896  NET_Listen4(qfalse);
1897  NET_Listen6(qfalse);
1898  NET_Config(NET_NONE);
1899 
1900  listen6 |= listen4;
1901  listen6 &= net_enable_ipv6->integer > 1;
1902 
1903  NET_Config(flag);
1904  NET_Listen4(listen4);
1905  NET_Listen6(listen6);
1906 
1907 #if USE_SYSCON
1908  SV_SetConsoleTitle();
1909 #endif
1910 }

Referenced by NET_Init(), and net_udp_param_changed().

◆ NET_RunConnect()

neterr_t NET_RunConnect ( netstream_t *  s)

Definition at line 1581 of file net.c.

1582 {
1583  ioentry_t *e;
1584  neterr_t ret;
1585  int err;
1586 
1587  if (s->state != NS_CONNECTING) {
1588  return NET_AGAIN;
1589  }
1590 
1591  e = os_get_io(s->socket);
1592  if (!e->canwrite
1593 #ifdef _WIN32
1594  && !e->canexcept
1595 #endif
1596  ) {
1597  return NET_AGAIN;
1598  }
1599 
1600  ret = os_getsockopt(s->socket, SOL_SOCKET, SO_ERROR, &err);
1601  if (ret) {
1602  goto fail;
1603  }
1604  if (err) {
1605  net_error = err;
1606  goto fail;
1607  }
1608 
1609  s->state = NS_CONNECTED;
1610  e->wantwrite = qfalse;
1611  e->wantread = qtrue;
1612 #ifdef _WIN32
1613  e->wantexcept = qfalse;
1614 #endif
1615  return NET_OK;
1616 
1617 fail:
1618  s->state = NS_BROKEN;
1619  e->wantwrite = qfalse;
1620  e->wantread = qfalse;
1621 #ifdef _WIN32
1622  e->wantexcept = qfalse;
1623 #endif
1624  return NET_ERROR;
1625 }

Referenced by AC_Run(), and run_connect().

◆ NET_RunStream()

neterr_t NET_RunStream ( netstream_t *  s)

Definition at line 1647 of file net.c.

1648 {
1649  ssize_t ret;
1650  size_t len;
1651  void *data;
1652  neterr_t result = NET_AGAIN;
1653  ioentry_t *e;
1654 
1655  if (s->state != NS_CONNECTED) {
1656  return result;
1657  }
1658 
1659  e = os_get_io(s->socket);
1660  if (e->wantread && e->canread) {
1661  // read as much as we can
1662  data = FIFO_Reserve(&s->recv, &len);
1663  if (len) {
1664  ret = os_recv(s->socket, data, len, 0);
1665  if (!ret) {
1666  goto closed;
1667  }
1668  if (ret == NET_ERROR) {
1669  goto error;
1670  }
1671  if (ret == NET_AGAIN) {
1672  // wouldblock is silent
1673  e->canread = qfalse;
1674  } else {
1675  FIFO_Commit(&s->recv, ret);
1676 #if _DEBUG
1677  if (net_log_enable->integer) {
1678  NET_LogPacket(&s->address, "TCP recv", data, ret);
1679  }
1680 #endif
1681  net_rate_rcvd += ret;
1682  net_bytes_rcvd += ret;
1683 
1684  result = NET_OK;
1685 
1686  // now see if there's more space to read
1687  FIFO_Reserve(&s->recv, &len);
1688  if (!len) {
1689  e->wantread = qfalse;
1690  }
1691  }
1692  }
1693  }
1694 
1695  if (e->wantwrite && e->canwrite) {
1696  // write as much as we can
1697  data = FIFO_Peek(&s->send, &len);
1698  if (len) {
1699  ret = os_send(s->socket, data, len, 0);
1700  if (!ret) {
1701  goto closed;
1702  }
1703  if (ret == NET_ERROR) {
1704  goto error;
1705  }
1706  if (ret == NET_AGAIN) {
1707  // wouldblock is silent
1708  e->canwrite = qfalse;
1709  } else {
1710  FIFO_Decommit(&s->send, ret);
1711 #if _DEBUG
1712  if (net_log_enable->integer) {
1713  NET_LogPacket(&s->address, "TCP send", data, ret);
1714  }
1715 #endif
1716  net_rate_sent += ret;
1717  net_bytes_sent += ret;
1718 
1719  //result = NET_OK;
1720 
1721  // now see if there's more data to write
1722  FIFO_Peek(&s->send, &len);
1723  if (!len) {
1724  e->wantwrite = qfalse;
1725  }
1726 
1727  }
1728  }
1729  }
1730 
1731  return result;
1732 
1733 closed:
1734  s->state = NS_CLOSED;
1735  e->wantread = qfalse;
1736  return NET_CLOSED;
1737 
1738 error:
1739  s->state = NS_BROKEN;
1740  e->wantread = qfalse;
1741  e->wantwrite = qfalse;
1742  return NET_ERROR;
1743 }

Referenced by AC_Run(), CL_GTV_Run(), drop_client(), mvd_drop(), run_stream(), and SV_MvdRunClients().

◆ NET_SearchAdrrInfo()

static struct addrinfo* NET_SearchAdrrInfo ( struct addrinfo *  rp,
int  family 
)
static

Definition at line 273 of file net.c.

274 {
275  while (rp) {
276  if (rp->ai_family == family)
277  return rp;
278  rp = rp->ai_next;
279  }
280 
281  return NULL;
282 }

Referenced by NET_StringPairToAdr().

◆ NET_SendPacket()

qboolean NET_SendPacket ( netsrc_t  sock,
const void data,
size_t  len,
const netadr_t *  to 
)

Definition at line 918 of file net.c.

920 {
921  ssize_t ret;
922  qsocket_t s;
923 
924  if (len == 0)
925  return qfalse;
926 
927  if (len > MAX_PACKETLEN) {
928  Com_EPrintf("%s: oversize packet to %s\n", __func__,
929  NET_AdrToString(to));
930  return qfalse;
931  }
932 
933  switch (to->type) {
934  case NA_UNSPECIFIED:
935  return qfalse;
936 #if USE_CLIENT
937  case NA_LOOPBACK:
938  return NET_SendLoopPacket(sock, data, len, to);
939 #endif
940  case NA_IP:
941  case NA_BROADCAST:
942  s = udp_sockets[sock];
943  break;
944  case NA_IP6:
945  s = udp6_sockets[sock];
946  break;
947  default:
948  Com_Error(ERR_FATAL, "%s: bad address type", __func__);
949  }
950 
951  if (s == -1)
952  return qfalse;
953 
954  ret = os_udp_send(s, data, len, to);
955  if (ret == NET_AGAIN)
956  return qfalse;
957 
958  if (ret == NET_ERROR) {
959  Com_DPrintf("%s: %s to %s\n", __func__,
961  net_send_errors++;
962  return qfalse;
963  }
964 
965  if (ret < len)
966  Com_WPrintf("%s: short send to %s\n", __func__,
967  NET_AdrToString(to));
968 
969 #ifdef _DEBUG
970  if (net_log_enable->integer)
971  NET_LogPacket(to, "UDP send", data, ret);
972 #endif
973 
974  net_rate_sent += ret;
975  net_bytes_sent += ret;
977 
978  return qtrue;
979 }

Referenced by Netchan_OutOfBand(), NetchanNew_Transmit(), NetchanNew_TransmitNextFragment(), NetchanOld_Transmit(), redirect(), SV_FlushRedirect(), SV_MasterHeartbeat(), SVC_Info(), and SVC_Status().

◆ NET_ShowIP_f()

static void NET_ShowIP_f ( void  )
static

Definition at line 1783 of file net.c.

1784 {
1785  char buffer[MAX_STRING_CHARS];
1786  struct addrinfo hints, *res, *rp;
1787  int err;
1788 
1789  if (gethostname(buffer, sizeof(buffer)) == -1) {
1790  Com_EPrintf("Couldn't get system host name\n");
1791  return;
1792  }
1793 
1794  memset(&hints, 0, sizeof(hints));
1795  hints.ai_flags = AI_CANONNAME;
1796  hints.ai_socktype = SOCK_STREAM;
1797 
1798  if (net_enable_ipv6->integer < 1)
1799  hints.ai_family = AF_INET;
1800 
1801  err = getaddrinfo(buffer, NULL, &hints, &res);
1802  if (err) {
1803  Com_Printf("Couldn't resolve %s: %s\n", buffer, gai_strerror(err));
1804  return;
1805  }
1806 
1807  if (res->ai_canonname)
1808  Com_Printf("Hostname: %s\n", res->ai_canonname);
1809 
1810  for (rp = res; rp; rp = rp->ai_next)
1811  dump_addrinfo(rp);
1812 
1813  freeaddrinfo(res);
1814 
1815  // dump listening IP sockets
1816  dump_socket(udp_sockets[NS_CLIENT], "Client", "UDP");
1817  dump_socket(udp_sockets[NS_SERVER], "Server", "UDP");
1818  dump_socket(tcp_socket, "Server", "TCP");
1819 
1820  // dump listening IPv6 sockets
1821  dump_socket(udp6_sockets[NS_CLIENT], "Client", "UDP6");
1822  dump_socket(udp6_sockets[NS_SERVER], "Server", "UDP6");
1823  dump_socket(tcp6_socket, "Server", "TCP6");
1824 }

Referenced by NET_Init().

◆ NET_Shutdown()

void NET_Shutdown ( void  )

Definition at line 1986 of file net.c.

1987 {
1988 #if _DEBUG
1989  logfile_close();
1990 #endif
1991 
1992  NET_Listen(qfalse);
1993  NET_Config(NET_NONE);
1994  os_net_shutdown();
1995 
1996  Cmd_RemoveCommand("net_restart");
1997  Cmd_RemoveCommand("net_stats");
1998  Cmd_RemoveCommand("showip");
1999  Cmd_RemoveCommand("dns");
2000 }

Referenced by Com_Error(), and Com_Quit().

◆ NET_Sleep()

int NET_Sleep ( int  msec)

Definition at line 712 of file net.c.

713 {
714  struct timeval tv;
715  fd_set rfds, wfds, efds;
716  ioentry_t *e;
717  qsocket_t fd;
718  int i, ret;
719 
720  if (!io_numfds) {
721  // don't bother with select()
722  Sys_Sleep(msec);
723  return 0;
724  }
725 
726  FD_ZERO(&rfds);
727  FD_ZERO(&wfds);
728  FD_ZERO(&efds);
729 
730  for (i = 0, e = io_entries; i < io_numfds; i++, e++) {
731  if (!e->inuse) {
732  continue;
733  }
734  fd = os_get_fd(e);
735  e->canread = qfalse;
736  e->canwrite = qfalse;
737  e->canexcept = qfalse;
738  if (e->wantread) FD_SET(fd, &rfds);
739  if (e->wantwrite) FD_SET(fd, &wfds);
740  if (e->wantexcept) FD_SET(fd, &efds);
741  }
742 
743  tv.tv_sec = msec / 1000;
744  tv.tv_usec = (msec % 1000) * 1000;
745 
746  ret = os_select(io_numfds, &rfds, &wfds, &efds, &tv);
747  if (ret == -1) {
748  Com_EPrintf("%s: %s\n", __func__, NET_ErrorString());
749  return ret;
750  }
751 
752  if (ret == 0)
753  return ret;
754 
755  for (i = 0; i < io_numfds; i++) {
756  e = &io_entries[i];
757  if (!e->inuse) {
758  continue;
759  }
760  fd = os_get_fd(e);
761  if (FD_ISSET(fd, &rfds)) e->canread = qtrue;
762  if (FD_ISSET(fd, &wfds)) e->canwrite = qtrue;
763  if (FD_ISSET(fd, &efds)) e->canexcept = qtrue;
764  }
765 
766  return ret;
767 }

Referenced by drop_client(), mvd_drop(), and Qcommon_Frame().

◆ NET_SockadrToNetadr()

static void NET_SockadrToNetadr ( const struct sockaddr_storage *  s,
netadr_t *  a 
)
static

Definition at line 176 of file net.c.

177 {
178  const struct sockaddr_in *s4 = (const struct sockaddr_in *)s;
179  const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *)s;
180 
181  memset(a, 0, sizeof(*a));
182 
183  switch (s->ss_family) {
184  case AF_INET:
185  a->type = NA_IP;
186  memcpy(&a->ip, &s4->sin_addr, 4);
187  a->port = s4->sin_port;
188  break;
189  case AF_INET6:
190  if (IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr)) {
191  a->type = NA_IP;
192  memcpy(&a->ip, &s6->sin6_addr.s6_addr[12], 4);
193  } else {
194  a->type = NA_IP6;
195  memcpy(&a->ip, &s6->sin6_addr, 16);
196  a->scope_id = s6->sin6_scope_id;
197  }
198  a->port = s6->sin6_port;
199  break;
200  default:
201  break;
202  }
203 }

Referenced by NET_StringPairToAdr(), os_accept(), os_getsockname(), os_udp_recv(), and process_error_queue().

◆ NET_Stats_f()

static void NET_Stats_f ( void  )
static

Definition at line 496 of file net.c.

497 {
498  time_t diff, now = time(NULL);
499  char buffer[MAX_QPATH];
500 
501  if (com_startTime > now) {
502  com_startTime = now;
503  }
504  diff = now - com_startTime;
505  if (diff < 1) {
506  diff = 1;
507  }
508 
509  Com_FormatTime(buffer, sizeof(buffer), diff);
510  Com_Printf("Network uptime: %s\n", buffer);
511  Com_Printf("Bytes sent: %"PRIu64" (%"PRIu64" bytes/sec)\n",
513  Com_Printf("Bytes rcvd: %"PRIu64" (%"PRIu64" bytes/sec)\n",
515  Com_Printf("Packets sent: %"PRIu64" (%"PRIu64" packets/sec)\n",
517  Com_Printf("Packets rcvd: %"PRIu64" (%"PRIu64" packets/sec)\n",
519 #if USE_ICMP
520  Com_Printf("Total errors: %"PRIu64"/%"PRIu64"/%"PRIu64" (send/recv/icmp)\n",
521  net_send_errors, net_recv_errors, net_icmp_errors);
522 #else
523  Com_Printf("Total errors: %"PRIu64"/%"PRIu64" (send/recv)\n",
525 #endif
526  Com_Printf("Current upload rate: %"PRIz" bytes/sec\n", net_rate_up);
527  Com_Printf("Current download rate: %"PRIz" bytes/sec\n", net_rate_dn);
528 }

Referenced by NET_Init().

◆ NET_StringPairToAdr()

qboolean NET_StringPairToAdr ( const char *  host,
const char *  port,
netadr_t *  a 
)

Definition at line 284 of file net.c.

285 {
286  byte buf[128];
287  struct addrinfo hints, *res, *rp;
288  int err;
289 
290  memset(&hints, 0, sizeof(hints));
291 
292  if (net_enable_ipv6->integer < 1)
293  hints.ai_family = AF_INET;
294 
295  if (os_inet_pton(AF_INET, host, buf) == 1 ||
296  os_inet_pton(AF_INET6, host, buf) == 1)
297  hints.ai_flags |= AI_NUMERICHOST;
298 
299 #ifdef AI_NUMERICSERV
300  if (port && COM_IsUint(port))
301  hints.ai_flags |= AI_NUMERICSERV;
302 #endif
303 
304  err = getaddrinfo(host, port, &hints, &res);
305  if (err)
306  return qfalse;
307 
308  rp = res;
309  if (net_enable_ipv6->integer < 2) {
310  rp = NET_SearchAdrrInfo(res, AF_INET);
311  if (!rp)
312  rp = res;
313  }
314 
315  NET_SockadrToNetadr((struct sockaddr_storage *)rp->ai_addr, a);
316 
317  freeaddrinfo(res);
318  return qtrue;
319 }

Referenced by NET_StringToAdr().

◆ NET_StringToAdr()

qboolean NET_StringToAdr ( const char *  s,
netadr_t *  a,
int  default_port 
)

Definition at line 332 of file net.c.

333 {
334  char copy[MAX_STRING_CHARS], *h, *p;
335  size_t len;
336 
337  len = Q_strlcpy(copy, s, sizeof(copy));
338  if (len >= sizeof(copy))
339  return qfalse;
340 
341  // parse IPv6 address in square brackets
342  h = p = copy;
343  if (*h == '[') {
344  h++;
345  p = strchr(h, ']');
346  if (!p)
347  return qfalse;
348  *p++ = 0;
349  }
350 
351  // strip off a trailing :port if present
352  p = strchr(p, ':');
353  if (p)
354  *p++ = 0;
355 
356  if (!NET_StringPairToAdr(h, p, a))
357  return qfalse;
358 
359  if (!a->port)
360  a->port = BigShort(default_port);
361 
362  return qtrue;
363 }

Referenced by AC_Reconnect(), AddServer(), check_reconnect(), CL_Connect_f(), CL_PingServers_f(), CL_Rcon_f(), CL_ServerStatus_f(), Con_RemoteMode_f(), MVD_Connect_f(), resolve_masters(), SV_PickClient_f(), and SV_SetMaster_f().

◆ net_udp_param_changed()

static void net_udp_param_changed ( cvar_t *  self)
static

Definition at line 1912 of file net.c.

1913 {
1914  NET_Restart_f();
1915 }

Referenced by NET_Init().

◆ NET_UpdateStats()

void NET_UpdateStats ( void  )

Definition at line 472 of file net.c.

473 {
474  unsigned diff;
475 
478  }
480  if (diff < RATE_SECS * 1000) {
481  return;
482  }
484 
487  net_rate_sent = 0;
488  net_rate_rcvd = 0;
489 }

Referenced by Qcommon_Frame().

◆ NET_UpdateStream()

void NET_UpdateStream ( netstream_t *  s)

Definition at line 1628 of file net.c.

1629 {
1630  size_t len;
1631  ioentry_t *e;
1632 
1633  if (s->state != NS_CONNECTED) {
1634  return;
1635  }
1636 
1637  e = os_get_io(s->socket);
1638 
1639  FIFO_Reserve(&s->recv, &len);
1640  e->wantread = len ? qtrue : qfalse;
1641 
1642  FIFO_Peek(&s->send, &len);
1643  e->wantwrite = len ? qtrue : qfalse;
1644 }

Referenced by AC_Flush(), AC_Run(), AC_Write(), CL_GTV_Run(), CL_GTV_Transmit(), drop_client(), gtv_forward_cmd(), gtv_run(), gtv_wait_start(), mvd_drop(), resume_streams(), suspend_streams(), SV_MvdEndFrame(), SV_MvdMapChanged(), and SV_MvdRunClients().

◆ NET_UpRate_m()

static size_t NET_UpRate_m ( char *  buffer,
size_t  size 
)
static

Definition at line 530 of file net.c.

531 {
532  return Q_scnprintf(buffer, size, "%"PRIz, net_rate_up);
533 }

Referenced by NET_Init().

◆ TCP_OpenSocket()

static qsocket_t TCP_OpenSocket ( const char *  iface,
int  port,
int  family,
netsrc_t  who 
)
static

Definition at line 1101 of file net.c.

1102 {
1103  qsocket_t s, newsocket;
1104  struct addrinfo hints, *res, *rp;
1105  char buf[MAX_QPATH];
1106  const char *node, *service;
1107  int err;
1108 
1109  Com_DPrintf("Opening TCP%s socket: %s:%d\n",
1110  (family == AF_INET6) ? "6" : "", iface, port);
1111 
1112  memset(&hints, 0, sizeof(hints));
1113  hints.ai_flags = AI_PASSIVE;
1114  hints.ai_family = family;
1115  hints.ai_socktype = SOCK_STREAM;
1116  hints.ai_protocol = IPPROTO_TCP;
1117 
1118  // empty string binds to all interfaces
1119  if (!*iface) {
1120  node = NULL;
1121  } else {
1122  node = iface;
1123  }
1124 
1125  if (port == PORT_ANY) {
1126  service = "0";
1127  } else {
1128  Q_snprintf(buf, sizeof(buf), "%d", port);
1129  service = buf;
1130  }
1131 
1132 #ifdef AI_NUMERICSERV
1133  hints.ai_flags |= AI_NUMERICSERV;
1134 #endif
1135 
1136  // resolve iface addr
1137  err = getaddrinfo(node, service, &hints, &res);
1138  if (err) {
1139  Com_EPrintf("%s: %s:%d: bad interface address: %s\n",
1140  __func__, iface, port, gai_strerror(err));
1141  return -1;
1142  }
1143 
1144  newsocket = -1;
1145  for (rp = res; rp; rp = rp->ai_next) {
1146  s = os_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
1147  if (s == -1) {
1148  Com_EPrintf("%s: %s:%d: can't create socket: %s\n",
1149  __func__, iface, port, NET_ErrorString());
1150  continue;
1151  }
1152 
1153  // make it non-blocking
1154  if (os_make_nonblock(s, 1)) {
1155  Com_EPrintf("%s: %s:%d: can't make socket non-blocking: %s\n",
1156  __func__, iface, port, NET_ErrorString());
1157  os_closesocket(s);
1158  continue;
1159  }
1160 
1161  if (who == NS_SERVER) {
1162  // give it a chance to reuse previous port
1163  if (os_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 1)) {
1164  Com_WPrintf("%s: %s:%d: can't force socket to reuse address: %s\n",
1165  __func__, iface, port, NET_ErrorString());
1166  }
1167  }
1168 
1169  if (rp->ai_family == AF_INET6) {
1170 #ifdef IPV6_V6ONLY
1171  // disable IPv4-mapped addresses
1172  if (os_setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, 1)) {
1173  Com_WPrintf("%s: %s:%d: can't make socket IPv6-only: %s\n",
1174  __func__, iface, port, NET_ErrorString());
1175  }
1176 #endif
1177  }
1178 
1179  if (os_bind(s, rp->ai_addr, rp->ai_addrlen)) {
1180  Com_EPrintf("%s: %s:%d: can't bind socket: %s\n",
1181  __func__, iface, port, NET_ErrorString());
1182  os_closesocket(s);
1183  continue;
1184  }
1185 
1186  newsocket = s;
1187  break;
1188  }
1189 
1190  freeaddrinfo(res);
1191 
1192  return newsocket;
1193 }

Referenced by NET_Connect(), NET_Listen4(), and NET_Listen6().

◆ UDP_OpenSocket()

static qsocket_t UDP_OpenSocket ( const char *  iface,
int  port,
int  family 
)
static

Definition at line 983 of file net.c.

984 {
985  qsocket_t s, newsocket;
986  struct addrinfo hints, *res, *rp;
987  char buf[MAX_QPATH];
988  const char *node, *service;
989  int err;
990 
991  Com_DPrintf("Opening UDP%s socket: %s:%d\n",
992  (family == AF_INET6) ? "6" : "", iface, port);
993 
994  memset(&hints, 0, sizeof(hints));
995  hints.ai_flags = AI_PASSIVE;
996  hints.ai_family = family;
997  hints.ai_socktype = SOCK_DGRAM;
998  hints.ai_protocol = IPPROTO_UDP;
999 
1000  // empty string binds to all interfaces
1001  if (!*iface) {
1002  node = NULL;
1003  } else {
1004  node = iface;
1005  }
1006 
1007  if (port == PORT_ANY) {
1008  service = "0";
1009  } else {
1010  Q_snprintf(buf, sizeof(buf), "%d", port);
1011  service = buf;
1012  }
1013 
1014 #ifdef AI_NUMERICSERV
1015  hints.ai_flags |= AI_NUMERICSERV;
1016 #endif
1017 
1018  // resolve iface addr
1019  err = getaddrinfo(node, service, &hints, &res);
1020  if (err) {
1021  Com_EPrintf("%s: %s:%d: bad interface address: %s\n",
1022  __func__, iface, port, gai_strerror(err));
1023  return -1;
1024  }
1025 
1026  newsocket = -1;
1027  for (rp = res; rp; rp = rp->ai_next) {
1028  s = os_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
1029  if (s == -1) {
1030  Com_EPrintf("%s: %s:%d: can't create socket: %s\n",
1031  __func__, iface, port, NET_ErrorString());
1032  continue;
1033  }
1034 
1035  // make it non-blocking
1036  if (os_make_nonblock(s, 1)) {
1037  Com_EPrintf("%s: %s:%d: can't make socket non-blocking: %s\n",
1038  __func__, iface, port, NET_ErrorString());
1039  os_closesocket(s);
1040  continue;
1041  }
1042 
1043  if (rp->ai_family == AF_INET) {
1044  // make it broadcast capable
1045  if (os_setsockopt(s, SOL_SOCKET, SO_BROADCAST, 1)) {
1046  Com_WPrintf("%s: %s:%d: can't make socket broadcast capable: %s\n",
1047  __func__, iface, port, NET_ErrorString());
1048  }
1049 
1050 #ifdef IP_RECVERR
1051  // enable ICMP error queue
1052  if (os_setsockopt(s, IPPROTO_IP, IP_RECVERR, 1)) {
1053  Com_WPrintf("%s: %s:%d: can't enable ICMP error queue: %s\n",
1054  __func__, iface, port, NET_ErrorString());
1055  }
1056 #endif
1057 
1058 #ifdef IP_MTU_DISCOVER
1059  // allow IP fragmentation by disabling path MTU discovery
1060  if (os_setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DONT)) {
1061  Com_WPrintf("%s: %s:%d: can't disable path MTU discovery: %s\n",
1062  __func__, iface, port, NET_ErrorString());
1063  }
1064 #endif
1065  }
1066 
1067  if (rp->ai_family == AF_INET6) {
1068 #ifdef IPV6_RECVERR
1069  // enable ICMP6 error queue
1070  if (os_setsockopt(s, IPPROTO_IPV6, IPV6_RECVERR, 1)) {
1071  Com_WPrintf("%s: %s:%d: can't enable ICMP6 error queue: %s\n",
1072  __func__, iface, port, NET_ErrorString());
1073  }
1074 #endif
1075 
1076 #ifdef IPV6_V6ONLY
1077  // disable IPv4-mapped addresses
1078  if (os_setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, 1)) {
1079  Com_WPrintf("%s: %s:%d: can't make socket IPv6-only: %s\n",
1080  __func__, iface, port, NET_ErrorString());
1081  }
1082 #endif
1083  }
1084 
1085  if (os_bind(s, rp->ai_addr, rp->ai_addrlen)) {
1086  Com_EPrintf("%s: %s:%d: can't bind socket: %s\n",
1087  __func__, iface, port, NET_ErrorString());
1088  os_closesocket(s);
1089  continue;
1090  }
1091 
1092  newsocket = s;
1093  break;
1094  }
1095 
1096  freeaddrinfo(res);
1097 
1098  return newsocket;
1099 }

Referenced by NET_OpenServer(), and NET_OpenServer6().

Variable Documentation

◆ io_entries

ioentry_t io_entries[FD_SETSIZE]
static

Definition at line 122 of file net.c.

Referenced by _os_get_io(), NET_RemoveFd(), NET_Sleep(), os_add_io(), os_get_fd(), and os_get_io().

◆ io_numfds

int io_numfds
static

Definition at line 123 of file net.c.

Referenced by NET_RemoveFd(), NET_Sleep(), os_add_io(), and os_get_io().

◆ net_active

netflag_t net_active
static

Definition at line 109 of file net.c.

Referenced by NET_Config(), and NET_Restart_f().

◆ net_bytes_rcvd

uint64_t net_bytes_rcvd
static

Definition at line 138 of file net.c.

Referenced by NET_GetUdpPackets(), NET_RunStream(), and NET_Stats_f().

◆ net_bytes_sent

uint64_t net_bytes_sent
static

Definition at line 139 of file net.c.

Referenced by NET_RunStream(), NET_SendPacket(), and NET_Stats_f().

◆ net_enable_ipv6

cvar_t* net_enable_ipv6
static

◆ net_error

◆ net_from

◆ net_ip

cvar_t* net_ip

Definition at line 86 of file net.c.

Referenced by NET_Connect(), NET_Init(), NET_Listen4(), and NET_OpenServer().

◆ net_ip6

cvar_t* net_ip6

Definition at line 87 of file net.c.

Referenced by NET_Connect(), NET_Init(), NET_Listen6(), and NET_OpenServer6().

◆ net_packets_rcvd

uint64_t net_packets_rcvd
static

Definition at line 140 of file net.c.

Referenced by NET_GetUdpPackets(), and NET_Stats_f().

◆ net_packets_sent

uint64_t net_packets_sent
static

Definition at line 141 of file net.c.

Referenced by NET_SendPacket(), and NET_Stats_f().

◆ net_port

cvar_t* net_port

◆ net_rate_dn

size_t net_rate_dn
static

Definition at line 129 of file net.c.

Referenced by NET_DnRate_m(), NET_Stats_f(), and NET_UpdateStats().

◆ net_rate_rcvd

size_t net_rate_rcvd
static

Definition at line 127 of file net.c.

Referenced by NET_GetUdpPackets(), NET_RunStream(), and NET_UpdateStats().

◆ net_rate_sent

size_t net_rate_sent
static

Definition at line 128 of file net.c.

Referenced by NET_RunStream(), NET_SendPacket(), and NET_UpdateStats().

◆ net_rate_time

unsigned net_rate_time
static

Definition at line 126 of file net.c.

Referenced by NET_Init(), and NET_UpdateStats().

◆ net_rate_up

size_t net_rate_up
static

Definition at line 130 of file net.c.

Referenced by NET_Stats_f(), NET_UpdateStats(), and NET_UpRate_m().

◆ net_recv_errors

uint64_t net_recv_errors
static

Definition at line 133 of file net.c.

Referenced by NET_GetUdpPackets(), and NET_Stats_f().

◆ net_send_errors

uint64_t net_send_errors
static

Definition at line 134 of file net.c.

Referenced by NET_SendPacket(), and NET_Stats_f().

◆ tcp6_socket

qsocket_t tcp6_socket = -1
static

Definition at line 116 of file net.c.

Referenced by NET_Accept(), NET_Listen6(), NET_Restart_f(), and NET_ShowIP_f().

◆ tcp_socket

qsocket_t tcp_socket = -1
static

Definition at line 113 of file net.c.

Referenced by NET_Accept(), NET_Listen4(), NET_Restart_f(), and NET_ShowIP_f().

◆ udp6_sockets

qsocket_t udp6_sockets[NS_COUNT] = { -1, -1 }
static

Definition at line 115 of file net.c.

Referenced by NET_Config(), NET_GetPackets(), NET_OpenServer6(), NET_SendPacket(), and NET_ShowIP_f().

◆ udp_sockets

qsocket_t udp_sockets[NS_COUNT] = { -1, -1 }
static
os_get_fd
static qsocket_t os_get_fd(ioentry_t *e)
Definition: unix.h:341
net_enable_ipv6
static cvar_t * net_enable_ipv6
Definition: net.c:103
NET_Listen4
static neterr_t NET_Listen4(qboolean arg)
Definition: net.c:1383
os_recv
static ssize_t os_recv(qsocket_t sock, void *data, size_t len, int flags)
Definition: unix.h:175
msg_read
sizebuf_t msg_read
Definition: msg.c:37
os_bind
static neterr_t os_bind(qsocket_t sock, const struct sockaddr *addr, size_t addrlen)
Definition: unix.h:276
msg_read_buffer
byte msg_read_buffer[MAX_MSGLEN]
Definition: msg.c:38
NET_AdrToString
char * NET_AdrToString(const netadr_t *a)
Definition: net.c:257
os_getsockname
static neterr_t os_getsockname(qsocket_t sock, netadr_t *name)
Definition: unix.h:286
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
net_error
static int net_error
Definition: net.c:110
net_packets_rcvd
static uint64_t net_packets_rcvd
Definition: net.c:140
os_connect
static neterr_t os_connect(qsocket_t sock, const netadr_t *to)
Definition: unix.h:226
NET_EnableIP6
static const char * NET_EnableIP6(void)
Definition: net.c:1917
Cmd_AddCommand
void Cmd_AddCommand(const char *name, xcommand_t function)
Definition: cmd.c:1562
TCP_OpenSocket
static qsocket_t TCP_OpenSocket(const char *iface, int port, int family, netsrc_t who)
Definition: net.c:1101
NET_RemoveFd
void NET_RemoveFd(qsocket_t fd)
Definition: net.c:686
NET_Dns_f
static void NET_Dns_f(void)
Definition: net.c:1831
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
os_udp_recv
static ssize_t os_udp_recv(qsocket_t sock, void *data, size_t len, netadr_t *from)
Definition: unix.h:105
net_rate_sent
static size_t net_rate_sent
Definition: net.c:128
net_ip6
cvar_t * net_ip6
Definition: net.c:87
os_accept
static neterr_t os_accept(qsocket_t sock, qsocket_t *newsock, netadr_t *from)
Definition: unix.h:205
tcp6_socket
static qsocket_t tcp6_socket
Definition: net.c:116
net_bytes_rcvd
static uint64_t net_bytes_rcvd
Definition: net.c:138
os_closesocket
static void os_closesocket(qsocket_t sock)
Definition: unix.h:302
NET_UpRate_m
static size_t NET_UpRate_m(char *buffer, size_t size)
Definition: net.c:530
os_get_io
static ioentry_t * os_get_io(qsocket_t fd)
Definition: unix.h:336
NET_OpenServer6
static void NET_OpenServer6(void)
Definition: net.c:1230
tv
float * tv(float x, float y, float z)
Definition: g_utils.c:248
udp_sockets
static qsocket_t udp_sockets[NS_COUNT]
Definition: net.c:112
os_add_io
static ioentry_t * os_add_io(qsocket_t fd)
Definition: unix.h:327
NET_DnRate_m
static size_t NET_DnRate_m(char *buffer, size_t size)
Definition: net.c:535
Cmd_Argv
char * Cmd_Argv(int arg)
Definition: cmd.c:899
os_error_string
static const char * os_error_string(int err)
Definition: unix.h:23
SZ_Init
void SZ_Init(sizebuf_t *buf, void *data, size_t size)
Definition: sizebuf.c:31
net_recv_errors
static uint64_t net_recv_errors
Definition: net.c:133
Cmd_Argc
int Cmd_Argc(void)
Definition: cmd.c:889
NET_Listen6
static neterr_t NET_Listen6(qboolean arg)
Definition: net.c:1422
net_from
netadr_t net_from
Definition: net.c:90
os_inet_pton
static int os_inet_pton(int af, const char *src, void *dst)
Definition: inet_pton.h:41
cmd_buffer
cmdbuf_t cmd_buffer
Definition: cmd.c:49
UDP_OpenSocket
static qsocket_t UDP_OpenSocket(const char *iface, int port, int family)
Definition: net.c:983
os_inet_ntop
static const char * os_inet_ntop(int af, const void *src, char *dst, size_t size)
Definition: inet_ntop.h:40
com_startTime
time_t com_startTime
Definition: common.c:125
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition: g_main.c:258
dedicated
cvar_t * dedicated
Definition: g_main.c:46
Cmd_RemoveCommand
void Cmd_RemoveCommand(const char *name)
Definition: cmd.c:1593
NET_Listen
neterr_t NET_Listen(qboolean arg)
Definition: net.c:1466
io_numfds
static int io_numfds
Definition: net.c:123
NET_Stats_f
static void NET_Stats_f(void)
Definition: net.c:496
net_packets_sent
static uint64_t net_packets_sent
Definition: net.c:141
Com_FormatTime
size_t Com_FormatTime(char *buffer, size_t size, time_t t)
Definition: utils.c:391
NET_ErrorString
const char * NET_ErrorString(void)
Definition: net.c:659
NET_BaseAdrToString
char * NET_BaseAdrToString(const netadr_t *a)
Definition: net.c:216
net_port
cvar_t * net_port
Definition: net.c:88
Cbuf_AddText
void Cbuf_AddText(cmdbuf_t *buf, const char *text)
Definition: cmd.c:95
va
char * va(const char *format,...)
Definition: shared.c:429
os_socket
static qsocket_t os_socket(int domain, int type, int protocol)
Definition: unix.h:307
net_bytes_sent
static uint64_t net_bytes_sent
Definition: net.c:139
NET_SearchAdrrInfo
static struct addrinfo * NET_SearchAdrrInfo(struct addrinfo *rp, int family)
Definition: net.c:273
logfile_close
static void logfile_close(void)
Definition: common.c:204
net_send_errors
static uint64_t net_send_errors
Definition: net.c:134
NET_SockadrToNetadr
static void NET_SockadrToNetadr(const struct sockaddr_storage *s, netadr_t *a)
Definition: net.c:176
NET_Config
void NET_Config(netflag_t flag)
Definition: net.c:1312
Q_strlcpy
size_t Q_strlcpy(char *dst, const char *src, size_t size)
Definition: shared.c:715
NET_NetadrToSockadr
static size_t NET_NetadrToSockadr(const netadr_t *a, struct sockaddr_storage *s)
Definition: net.c:145
os_getsockopt
static neterr_t os_getsockopt(qsocket_t sock, int level, int name, int *val)
Definition: unix.h:264
os_send
static ssize_t os_send(qsocket_t sock, const void *data, size_t len, int flags)
Definition: unix.h:185
os_make_nonblock
static neterr_t os_make_nonblock(qsocket_t sock, int val)
Definition: unix.h:244
os_net_shutdown
static void os_net_shutdown(void)
Definition: unix.h:364
NET_OpenServer
static void NET_OpenServer(void)
Definition: net.c:1195
io_entries
static ioentry_t io_entries[FD_SETSIZE]
Definition: net.c:122
COM_IsUint
qboolean COM_IsUint(const char *s)
Definition: shared.c:330
NET_AddFd
ioentry_t * NET_AddFd(qsocket_t fd)
Definition: net.c:671
os_listen
static neterr_t os_listen(qsocket_t sock, int backlog)
Definition: unix.h:195
NET_ShowIP_f
static void NET_ShowIP_f(void)
Definition: net.c:1783
RATE_SECS
#define RATE_SECS
Definition: net.c:470
net_rate_rcvd
static size_t net_rate_rcvd
Definition: net.c:127
NET_GetUdpPackets
static void NET_GetUdpPackets(qsocket_t sock, void(*packet_cb)(void))
Definition: net.c:845
os_select
static int os_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
Definition: unix.h:346
os_setsockopt
static neterr_t os_setsockopt(qsocket_t sock, int level, int name, int val)
Definition: unix.h:254
NET_StringPairToAdr
qboolean NET_StringPairToAdr(const char *host, const char *port, netadr_t *a)
Definition: net.c:284
Sys_Sleep
void Sys_Sleep(int msec)
Definition: system.c:653
diff
static q_noinline int diff(uint32_t A_u32, uint32_t B_u32)
Definition: hq2x.c:55
Cmd_ArgvBuffer
size_t Cmd_ArgvBuffer(int arg, char *buffer, size_t size)
Definition: cmd.c:912
NET_AcceptSocket
static neterr_t NET_AcceptSocket(netstream_t *s, qsocket_t sock)
Definition: net.c:1482
os_net_init
static void os_net_init(void)
Definition: unix.h:360
net_rate_time
static unsigned net_rate_time
Definition: net.c:126
err
int err
Definition: win.h:24
os_udp_send
static ssize_t os_udp_send(qsocket_t sock, const void *data, size_t len, const netadr_t *to)
Definition: unix.h:137
net_rate_dn
static size_t net_rate_dn
Definition: net.c:129
NET_Restart_f
static void NET_Restart_f(void)
Definition: net.c:1888
Cmd_AddMacro
void Cmd_AddMacro(const char *name, xmacro_t function)
Definition: cmd.c:770
net_ip
cvar_t * net_ip
Definition: net.c:86
tcp_socket
static qsocket_t tcp_socket
Definition: net.c:113
udp6_sockets
static qsocket_t udp6_sockets[NS_COUNT]
Definition: net.c:115
Q_scnprintf
size_t Q_scnprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:867
net_udp_param_changed
static void net_udp_param_changed(cvar_t *self)
Definition: net.c:1912
net_active
static netflag_t net_active
Definition: net.c:109
net_rate_up
static size_t net_rate_up
Definition: net.c:130
com_eventTime
unsigned com_eventTime
Definition: common.c:122
dump_socket
static void dump_socket(qsocket_t s, const char *s1, const char *s2)
Definition: net.c:1761
dump_addrinfo
static void dump_addrinfo(struct addrinfo *ai)
Definition: net.c:1747