23 #include "shared/shared.h"
24 #include "common/common.h"
25 #include "common/cvar.h"
26 #include "common/fifo.h"
28 #include "common/files.h"
30 #include "common/msg.h"
31 #include "common/net/net.h"
32 #include "common/protocol.h"
33 #include "common/zone.h"
36 #include "system/system.h"
39 #define WIN32_LEAN_AND_MEAN
45 #include <sys/types.h>
46 #include <sys/socket.h>
47 #include <netinet/in.h>
49 #include <sys/param.h>
50 #include <sys/ioctl.h>
51 #include <arpa/inet.h>
54 #include <linux/types.h>
56 #include <linux/errqueue.h>
65 #define MAX_ERROR_RETRIES 64
69 #define MAX_LOOPBACK 4
72 byte data[MAX_PACKETLEN];
77 loopmsg_t msgs[MAX_LOOPBACK];
82 static loopback_t loopbacks[NS_COUNT];
93 static cvar_t *net_clientport;
94 static cvar_t *net_dropsim;
98 static cvar_t *net_log_enable;
99 static cvar_t *net_log_name;
100 static cvar_t *net_log_flush;
106 static cvar_t *net_ignore_icmp;
119 static qhandle_t net_logFile;
136 static uint64_t net_icmp_errors;
147 struct sockaddr_in *s4 = (
struct sockaddr_in *)s;
148 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *)s;
150 memset(s, 0,
sizeof(*s));
154 s4->sin_family = AF_INET;
155 s4->sin_addr.s_addr = INADDR_BROADCAST;
156 s4->sin_port = a->port;
159 s4->sin_family = AF_INET;
160 memcpy(&s4->sin_addr, &a->ip, 4);
161 s4->sin_port = a->port;
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;
178 const struct sockaddr_in *s4 = (
const struct sockaddr_in *)s;
179 const struct sockaddr_in6 *s6 = (
const struct sockaddr_in6 *)s;
181 memset(a, 0,
sizeof(*a));
183 switch (s->ss_family) {
186 memcpy(&a->ip, &s4->sin_addr, 4);
187 a->port = s4->sin_port;
190 if (IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr)) {
192 memcpy(&a->ip, &s6->sin6_addr.s6_addr[12], 4);
195 memcpy(&a->ip, &s6->sin6_addr, 16);
196 a->scope_id = s6->sin6_scope_id;
198 a->port = s6->sin6_port;
207 #define NS_INADDRSZ 4
208 #define NS_IN6ADDRSZ 16
212 #define os_inet_ntop inet_ntop
213 #define os_inet_pton inet_pton
218 static char s[MAX_QPATH];
222 return strcpy(s,
"<unspecified>");
224 return strcpy(s,
"loopback");
230 return strcpy(s,
"<invalid>");
233 struct sockaddr_storage addr;
237 if (getnameinfo((
struct sockaddr *)&addr, addrlen,
238 s,
sizeof(s), NULL, 0, NI_NUMERICHOST) == 0)
244 return strcpy(s,
"<invalid>");
246 Com_Error(ERR_FATAL,
"%s: bad address type", __func__);
259 static char s[MAX_QPATH];
263 return strcpy(s,
"<unspecified>");
265 return strcpy(s,
"loopback");
267 Q_snprintf(s,
sizeof(s), (a->type == NA_IP6) ?
"[%s]:%u" :
"%s:%u",
276 if (rp->ai_family == family)
287 struct addrinfo hints, *res, *rp;
290 memset(&hints, 0,
sizeof(hints));
293 hints.ai_family = AF_INET;
297 hints.ai_flags |= AI_NUMERICHOST;
299 #ifdef AI_NUMERICSERV
301 hints.ai_flags |= AI_NUMERICSERV;
304 err = getaddrinfo(host, port, &hints, &res);
334 char copy[MAX_STRING_CHARS], *h, *p;
338 if (len >=
sizeof(copy))
360 a->port = BigShort(default_port);
375 Com_Printf(
"Closing network log.\n");
383 char buffer[MAX_OSPATH];
387 mode = net_log_enable->integer > 1 ? FS_MODE_APPEND : FS_MODE_WRITE;
388 if (net_log_flush->integer > 0) {
389 if (net_log_flush->integer > 1) {
397 "logs/", net_log_name->string,
".log");
404 Com_Printf(
"Logging network packets to %s\n", buffer);
407 static void net_log_enable_changed(cvar_t *
self)
415 static void net_log_param_changed(cvar_t *
self)
417 if (net_log_enable->integer) {
428 static void NET_LogPacket(
const netadr_t *address,
const char *prefix,
429 const byte *data,
size_t length)
438 FS_FPrintf(net_logFile,
"%u : %s : %s : %"PRIz
" bytes\n",
441 numRows = (length + 15) / 16;
442 for (i = 0; i < numRows; i++) {
444 for (j = 0; j < 16; j++) {
445 if (i * 16 + j < length) {
446 FS_FPrintf(net_logFile,
"%02x ", data[i * 16 + j]);
452 for (j = 0; j < 16; j++) {
453 if (i * 16 + j < length) {
454 c = data[i * 16 + j];
498 time_t
diff, now = time(NULL);
499 char buffer[MAX_QPATH];
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",
520 Com_Printf(
"Total errors: %"PRIu64
"/%"PRIu64
"/%"PRIu64
" (send/recv/icmp)\n",
523 Com_Printf(
"Total errors: %"PRIu64
"/%"PRIu64
" (send/recv)\n",
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);
544 static void NET_GetLoopPackets(netsrc_t sock,
void (*packet_cb)(
void))
549 loop = &loopbacks[sock];
551 if (loop->send - loop->get > MAX_LOOPBACK - 1) {
552 loop->get = loop->send - MAX_LOOPBACK + 1;
555 while (loop->get < loop->send) {
556 loopmsg = &loop->msgs[loop->get & (MAX_LOOPBACK - 1)];
562 if (net_log_enable->integer > 1) {
563 NET_LogPacket(&
net_from,
"LP recv", loopmsg->data, loopmsg->datalen);
566 if (sock == NS_CLIENT) {
571 msg_read.cursize = loopmsg->datalen;
577 static qboolean NET_SendLoopPacket(netsrc_t sock,
const void *data,
578 size_t len,
const netadr_t *to)
583 if (net_dropsim->integer > 0 && (rand() % 100) < net_dropsim->integer) {
587 loop = &loopbacks[sock ^ 1];
589 msg = &loop->msgs[loop->send & (MAX_LOOPBACK - 1)];
592 memcpy(
msg->data, data, len);
596 if (net_log_enable->integer > 1) {
597 NET_LogPacket(to,
"LP send", data, len);
600 if (sock == NS_CLIENT) {
615 static void NET_ErrorEvent(qsocket_t sock, netadr_t *from,
616 int ee_errno,
int ee_info)
618 if (net_ignore_icmp->integer > 0) {
622 if (from->type == NA_UNSPECIFIED) {
626 Com_DPrintf(
"%s: %s from %s\n", __func__,
632 SV_ErrorEvent(from, ee_errno, ee_info);
691 memset(e, 0,
sizeof(*e));
715 fd_set rfds, wfds, efds;
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);
743 tv.tv_sec = msec / 1000;
744 tv.tv_usec = (msec % 1000) * 1000;
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;
778 int NET_Sleepv(
int msec, ...)
782 fd_set rfds, wfds, efds;
791 va_start(argptr, msec);
793 fd = va_arg(argptr, qsocket_t);
802 e->canwrite = qfalse;
803 e->canexcept = qfalse;
804 if (e->wantread) FD_SET(fd, &rfds);
805 if (e->wantwrite) FD_SET(fd, &wfds);
806 if (e->wantexcept) FD_SET(fd, &efds);
810 tv.tv_sec = msec / 1000;
811 tv.tv_usec = (msec % 1000) * 1000;
822 va_start(argptr, msec);
824 fd = va_arg(argptr, qsocket_t);
832 if (FD_ISSET(fd, &rfds)) e->canread = qtrue;
833 if (FD_ISSET(fd, &wfds)) e->canwrite = qtrue;
834 if (FD_ISSET(fd, &efds)) e->canexcept = qtrue;
841 #endif // USE_AC_SERVER
859 if (ret == NET_AGAIN) {
864 if (ret == NET_ERROR) {
865 Com_DPrintf(
"%s: %s from %s\n", __func__,
872 if (net_log_enable->integer)
902 NET_GetLoopPackets(sock, packet_cb);
919 size_t len,
const netadr_t *to)
927 if (len > MAX_PACKETLEN) {
928 Com_EPrintf(
"%s: oversize packet to %s\n", __func__,
938 return NET_SendLoopPacket(sock, data, len, to);
948 Com_Error(ERR_FATAL,
"%s: bad address type", __func__);
955 if (ret == NET_AGAIN)
958 if (ret == NET_ERROR) {
959 Com_DPrintf(
"%s: %s to %s\n", __func__,
966 Com_WPrintf(
"%s: short send to %s\n", __func__,
970 if (net_log_enable->integer)
971 NET_LogPacket(to,
"UDP send", data, ret);
985 qsocket_t s, newsocket;
986 struct addrinfo hints, *res, *rp;
988 const char *node, *service;
991 Com_DPrintf(
"Opening UDP%s socket: %s:%d\n",
992 (family == AF_INET6) ?
"6" :
"", iface, port);
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;
1007 if (port == PORT_ANY) {
1014 #ifdef AI_NUMERICSERV
1015 hints.ai_flags |= AI_NUMERICSERV;
1019 err = getaddrinfo(node, service, &hints, &res);
1021 Com_EPrintf(
"%s: %s:%d: bad interface address: %s\n",
1022 __func__, iface, port, gai_strerror(
err));
1027 for (rp = res; rp; rp = rp->ai_next) {
1028 s =
os_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
1030 Com_EPrintf(
"%s: %s:%d: can't create socket: %s\n",
1037 Com_EPrintf(
"%s: %s:%d: can't make socket non-blocking: %s\n",
1043 if (rp->ai_family == AF_INET) {
1046 Com_WPrintf(
"%s: %s:%d: can't make socket broadcast capable: %s\n",
1053 Com_WPrintf(
"%s: %s:%d: can't enable ICMP error queue: %s\n",
1058 #ifdef IP_MTU_DISCOVER
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",
1067 if (rp->ai_family == AF_INET6) {
1071 Com_WPrintf(
"%s: %s:%d: can't enable ICMP6 error queue: %s\n",
1079 Com_WPrintf(
"%s: %s:%d: can't make socket IPv6-only: %s\n",
1085 if (
os_bind(s, rp->ai_addr, rp->ai_addrlen)) {
1086 Com_EPrintf(
"%s: %s:%d: can't bind socket: %s\n",
1101 static qsocket_t
TCP_OpenSocket(
const char *iface,
int port,
int family, netsrc_t who)
1103 qsocket_t s, newsocket;
1104 struct addrinfo hints, *res, *rp;
1105 char buf[MAX_QPATH];
1106 const char *node, *service;
1109 Com_DPrintf(
"Opening TCP%s socket: %s:%d\n",
1110 (family == AF_INET6) ?
"6" :
"", iface, port);
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;
1125 if (port == PORT_ANY) {
1132 #ifdef AI_NUMERICSERV
1133 hints.ai_flags |= AI_NUMERICSERV;
1137 err = getaddrinfo(node, service, &hints, &res);
1139 Com_EPrintf(
"%s: %s:%d: bad interface address: %s\n",
1140 __func__, iface, port, gai_strerror(
err));
1145 for (rp = res; rp; rp = rp->ai_next) {
1146 s =
os_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
1148 Com_EPrintf(
"%s: %s:%d: can't create socket: %s\n",
1155 Com_EPrintf(
"%s: %s:%d: can't make socket non-blocking: %s\n",
1161 if (who == NS_SERVER) {
1164 Com_WPrintf(
"%s: %s:%d: can't force socket to reuse address: %s\n",
1169 if (rp->ai_family == AF_INET6) {
1173 Com_WPrintf(
"%s: %s:%d: can't make socket IPv6-only: %s\n",
1179 if (
os_bind(s, rp->ai_addr, rp->ai_addrlen)) {
1180 Com_EPrintf(
"%s: %s:%d: can't bind socket: %s\n",
1197 static int saved_port;
1209 e->wantread = qtrue;
1213 if (saved_port && saved_port !=
net_port->integer) {
1215 Com_Printf(
"Reverting to the last valid port %d...\n", saved_port);
1222 Com_WPrintf(
"Couldn't open server UDP port.\n");
1227 Com_Error(ERR_FATAL,
"Couldn't open dedicated server UDP port");
1247 e->wantread = qtrue;
1251 static void NET_OpenClient(
void)
1263 if (net_clientport->integer != PORT_ANY)
1267 Com_WPrintf(
"Couldn't open client UDP port.\n");
1272 Com_EPrintf(
"Couldn't get client UDP socket name: %s\n",
NET_ErrorString());
1277 Com_WPrintf(
"Client UDP socket bound to %s.\n",
NET_AdrToString(&adr));
1283 e->wantread = qtrue;
1286 static void NET_OpenClient6(
void)
1303 e->wantread = qtrue;
1320 if (flag == NET_NONE) {
1322 for (sock = 0; sock < NS_COUNT; sock++) {
1339 if (flag & NET_CLIENT) {
1345 if (flag & NET_SERVER) {
1380 s->state = NS_DISCONNECTED;
1417 e->wantread = qtrue;
1461 e->wantread = qtrue;
1468 neterr_t ret4, ret6;
1473 if (ret4 == NET_OK || ret6 == NET_OK)
1476 if (ret4 == NET_ERROR || ret6 == NET_ERROR)
1485 qsocket_t newsocket;
1499 e->canread = qfalse;
1511 memset(s, 0,
sizeof(*s));
1512 s->socket = newsocket;
1514 s->state = NS_CONNECTED;
1519 e->wantread = qtrue;
1530 if (ret == NET_AGAIN)
1544 switch (peer->type) {
1566 memset(s, 0,
sizeof(*s));
1567 s->state = NS_CONNECTING;
1573 e->wantwrite = qtrue;
1575 e->wantexcept = qtrue;
1587 if (s->state != NS_CONNECTING) {
1609 s->state = NS_CONNECTED;
1610 e->wantwrite = qfalse;
1611 e->wantread = qtrue;
1613 e->wantexcept = qfalse;
1618 s->state = NS_BROKEN;
1619 e->wantwrite = qfalse;
1620 e->wantread = qfalse;
1622 e->wantexcept = qfalse;
1633 if (s->state != NS_CONNECTED) {
1639 FIFO_Reserve(&s->recv, &len);
1640 e->wantread = len ? qtrue : qfalse;
1642 FIFO_Peek(&s->send, &len);
1643 e->wantwrite = len ? qtrue : qfalse;
1652 neterr_t result = NET_AGAIN;
1655 if (s->state != NS_CONNECTED) {
1660 if (e->wantread && e->canread) {
1662 data = FIFO_Reserve(&s->recv, &len);
1664 ret =
os_recv(s->socket, data, len, 0);
1668 if (ret == NET_ERROR) {
1671 if (ret == NET_AGAIN) {
1673 e->canread = qfalse;
1675 FIFO_Commit(&s->recv, ret);
1677 if (net_log_enable->integer) {
1678 NET_LogPacket(&s->address,
"TCP recv", data, ret);
1687 FIFO_Reserve(&s->recv, &len);
1689 e->wantread = qfalse;
1695 if (e->wantwrite && e->canwrite) {
1697 data = FIFO_Peek(&s->send, &len);
1699 ret =
os_send(s->socket, data, len, 0);
1703 if (ret == NET_ERROR) {
1706 if (ret == NET_AGAIN) {
1708 e->canwrite = qfalse;
1710 FIFO_Decommit(&s->send, ret);
1712 if (net_log_enable->integer) {
1713 NET_LogPacket(&s->address,
"TCP send", data, ret);
1722 FIFO_Peek(&s->send, &len);
1724 e->wantwrite = qfalse;
1734 s->state = NS_CLOSED;
1735 e->wantread = qfalse;
1739 s->state = NS_BROKEN;
1740 e->wantread = qfalse;
1741 e->wantwrite = qfalse;
1749 char buf1[MAX_QPATH], buf2[MAX_STRING_CHARS];
1750 char *fa = (ai->ai_addr->sa_family == AF_INET6) ?
"6" :
"";
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);
1758 Com_Printf(
"IP%1s : %s\n", fa, buf1);
1769 Com_EPrintf(
"Couldn't get %s %s socket name: %s\n",
1774 Com_Printf(
"%s %s socket bound to %s\n",
1785 char buffer[MAX_STRING_CHARS];
1786 struct addrinfo hints, *res, *rp;
1789 if (gethostname(buffer,
sizeof(buffer)) == -1) {
1790 Com_EPrintf(
"Couldn't get system host name\n");
1794 memset(&hints, 0,
sizeof(hints));
1795 hints.ai_flags = AI_CANONNAME;
1796 hints.ai_socktype = SOCK_STREAM;
1799 hints.ai_family = AF_INET;
1801 err = getaddrinfo(buffer, NULL, &hints, &res);
1803 Com_Printf(
"Couldn't resolve %s: %s\n", buffer, gai_strerror(
err));
1807 if (res->ai_canonname)
1808 Com_Printf(
"Hostname: %s\n", res->ai_canonname);
1810 for (rp = res; rp; rp = rp->ai_next)
1833 char buffer[MAX_STRING_CHARS], *h, *p;
1834 struct addrinfo hints, *res, *rp;
1838 Com_Printf(
"Usage: %s <address>\n",
Cmd_Argv(0));
1850 Com_Printf(
"Bad IPv6 address\n");
1861 memset(&hints, 0,
sizeof(hints));
1862 hints.ai_flags = AI_CANONNAME;
1863 hints.ai_socktype = SOCK_STREAM;
1866 hints.ai_family = AF_INET;
1868 err = getaddrinfo(h, NULL, &hints, &res);
1870 Com_Printf(
"Couldn't resolve %s: %s\n", h, gai_strerror(
err));
1874 if (res->ai_canonname)
1875 Com_Printf(
"Hostname: %s\n", res->ai_canonname);
1877 for (rp = res; rp; rp = rp->ai_next)
1894 Com_DPrintf(
"%s\n", __func__);
1908 SV_SetConsoleTitle();
1919 qsocket_t s =
os_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
1945 net_clientport =
Cvar_Get(
"net_clientport", STRINGIFY(PORT_ANY), 0);
1947 net_dropsim =
Cvar_Get(
"net_dropsim",
"0", 0);
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;
1963 net_ignore_icmp =
Cvar_Get(
"net_ignore_icmp",
"0", 0);
1967 net_log_enable_changed(net_log_enable);