net_chan.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include "quakedef.h"
  16. #ifdef _WIN32
  17. #include "winquake.h"
  18. #endif
  19. #define PACKET_HEADER 8
  20. /*
  21. packet header
  22. -------------
  23. 31 sequence
  24. 1 does this message contain a reliable payload
  25. 31 acknowledge sequence
  26. 1 acknowledge receipt of even/odd message
  27. 16 qport
  28. The remote connection never knows if it missed a reliable message, the
  29. local side detects that it has been dropped by seeing a sequence acknowledge
  30. higher thatn the last reliable sequence, but without the correct evon/odd
  31. bit for the reliable set.
  32. If the sender notices that a reliable message has been dropped, it will be
  33. retransmitted. It will not be retransmitted again until a message after
  34. the retransmit has been acknowledged and the reliable still failed to get there.
  35. if the sequence number is -1, the packet should be handled without a netcon
  36. The reliable message can be added to at any time by doing
  37. MSG_Write* (&netchan->message, <data>).
  38. If the message buffer is overflowed, either by a single message, or by
  39. multiple frames worth piling up while the last reliable transmit goes
  40. unacknowledged, the netchan signals a fatal error.
  41. Reliable messages are allways placed first in a packet, then the unreliable
  42. message is included if there is sufficient room.
  43. To the receiver, there is no distinction between the reliable and unreliable
  44. parts of the message, they are just processed out as a single larger message.
  45. Illogical packet sequence numbers cause the packet to be dropped, but do
  46. not kill the connection. This, combined with the tight window of valid
  47. reliable acknowledgement numbers provides protection against malicious
  48. address spoofing.
  49. The qport field is a workaround for bad address translating routers that
  50. sometimes remap the client's source port on a packet during gameplay.
  51. If the base part of the net address matches and the qport matches, then the
  52. channel matches even if the IP port differs. The IP port should be updated
  53. to the new value before sending out any replies.
  54. */
  55. int net_drop;
  56. cvar_t showpackets = {"showpackets", "0"};
  57. cvar_t showdrop = {"showdrop", "0"};
  58. cvar_t qport = {"qport", "0"};
  59. /*
  60. ===============
  61. Netchan_Init
  62. ===============
  63. */
  64. void Netchan_Init (void)
  65. {
  66. int port;
  67. // pick a port value that should be nice and random
  68. #ifdef _WIN32
  69. port = ((int)(timeGetTime()*1000) * time(NULL)) & 0xffff;
  70. #else
  71. port = ((int)(getpid()+getuid()*1000) * time(NULL)) & 0xffff;
  72. #endif
  73. Cvar_RegisterVariable (&showpackets);
  74. Cvar_RegisterVariable (&showdrop);
  75. Cvar_RegisterVariable (&qport);
  76. Cvar_SetValue("qport", port);
  77. }
  78. /*
  79. ===============
  80. Netchan_OutOfBand
  81. Sends an out-of-band datagram
  82. ================
  83. */
  84. void Netchan_OutOfBand (netadr_t adr, int length, byte *data)
  85. {
  86. sizebuf_t send;
  87. byte send_buf[MAX_MSGLEN + PACKET_HEADER];
  88. // write the packet header
  89. send.data = send_buf;
  90. send.maxsize = sizeof(send_buf);
  91. send.cursize = 0;
  92. MSG_WriteLong (&send, -1); // -1 sequence means out of band
  93. SZ_Write (&send, data, length);
  94. // send the datagram
  95. //zoid, no input in demo playback mode
  96. #ifndef SERVERONLY
  97. if (!cls.demoplayback)
  98. #endif
  99. NET_SendPacket (send.cursize, send.data, adr);
  100. }
  101. /*
  102. ===============
  103. Netchan_OutOfBandPrint
  104. Sends a text message in an out-of-band datagram
  105. ================
  106. */
  107. void Netchan_OutOfBandPrint (netadr_t adr, char *format, ...)
  108. {
  109. va_list argptr;
  110. static char string[8192]; // ??? why static?
  111. va_start (argptr, format);
  112. vsprintf (string, format,argptr);
  113. va_end (argptr);
  114. Netchan_OutOfBand (adr, strlen(string), (byte *)string);
  115. }
  116. /*
  117. ==============
  118. Netchan_Setup
  119. called to open a channel to a remote system
  120. ==============
  121. */
  122. void Netchan_Setup (netchan_t *chan, netadr_t adr, int qport)
  123. {
  124. memset (chan, 0, sizeof(*chan));
  125. chan->remote_address = adr;
  126. chan->last_received = realtime;
  127. chan->message.data = chan->message_buf;
  128. chan->message.allowoverflow = true;
  129. chan->message.maxsize = sizeof(chan->message_buf);
  130. chan->qport = qport;
  131. chan->rate = 1.0/2500;
  132. }
  133. /*
  134. ===============
  135. Netchan_CanPacket
  136. Returns true if the bandwidth choke isn't active
  137. ================
  138. */
  139. #define MAX_BACKUP 200
  140. qboolean Netchan_CanPacket (netchan_t *chan)
  141. {
  142. if (chan->cleartime < realtime + MAX_BACKUP*chan->rate)
  143. return true;
  144. return false;
  145. }
  146. /*
  147. ===============
  148. Netchan_CanReliable
  149. Returns true if the bandwidth choke isn't
  150. ================
  151. */
  152. qboolean Netchan_CanReliable (netchan_t *chan)
  153. {
  154. if (chan->reliable_length)
  155. return false; // waiting for ack
  156. return Netchan_CanPacket (chan);
  157. }
  158. #ifdef SERVERONLY
  159. qboolean ServerPaused(void);
  160. #endif
  161. /*
  162. ===============
  163. Netchan_Transmit
  164. tries to send an unreliable message to a connection, and handles the
  165. transmition / retransmition of the reliable messages.
  166. A 0 length will still generate a packet and deal with the reliable messages.
  167. ================
  168. */
  169. void Netchan_Transmit (netchan_t *chan, int length, byte *data)
  170. {
  171. sizebuf_t send;
  172. byte send_buf[MAX_MSGLEN + PACKET_HEADER];
  173. qboolean send_reliable;
  174. unsigned w1, w2;
  175. int i;
  176. // check for message overflow
  177. if (chan->message.overflowed)
  178. {
  179. chan->fatal_error = true;
  180. Con_Printf ("%s:Outgoing message overflow\n"
  181. , NET_AdrToString (chan->remote_address));
  182. return;
  183. }
  184. // if the remote side dropped the last reliable message, resend it
  185. send_reliable = false;
  186. if (chan->incoming_acknowledged > chan->last_reliable_sequence
  187. && chan->incoming_reliable_acknowledged != chan->reliable_sequence)
  188. send_reliable = true;
  189. // if the reliable transmit buffer is empty, copy the current message out
  190. if (!chan->reliable_length && chan->message.cursize)
  191. {
  192. memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize);
  193. chan->reliable_length = chan->message.cursize;
  194. chan->message.cursize = 0;
  195. chan->reliable_sequence ^= 1;
  196. send_reliable = true;
  197. }
  198. // write the packet header
  199. send.data = send_buf;
  200. send.maxsize = sizeof(send_buf);
  201. send.cursize = 0;
  202. w1 = chan->outgoing_sequence | (send_reliable<<31);
  203. w2 = chan->incoming_sequence | (chan->incoming_reliable_sequence<<31);
  204. chan->outgoing_sequence++;
  205. MSG_WriteLong (&send, w1);
  206. MSG_WriteLong (&send, w2);
  207. // send the qport if we are a client
  208. #ifndef SERVERONLY
  209. MSG_WriteShort (&send, cls.qport);
  210. #endif
  211. // copy the reliable message to the packet first
  212. if (send_reliable)
  213. {
  214. SZ_Write (&send, chan->reliable_buf, chan->reliable_length);
  215. chan->last_reliable_sequence = chan->outgoing_sequence;
  216. }
  217. // add the unreliable part if space is available
  218. if (send.maxsize - send.cursize >= length)
  219. SZ_Write (&send, data, length);
  220. // send the datagram
  221. i = chan->outgoing_sequence & (MAX_LATENT-1);
  222. chan->outgoing_size[i] = send.cursize;
  223. chan->outgoing_time[i] = realtime;
  224. //zoid, no input in demo playback mode
  225. #ifndef SERVERONLY
  226. if (!cls.demoplayback)
  227. #endif
  228. NET_SendPacket (send.cursize, send.data, chan->remote_address);
  229. if (chan->cleartime < realtime)
  230. chan->cleartime = realtime + send.cursize*chan->rate;
  231. else
  232. chan->cleartime += send.cursize*chan->rate;
  233. #ifdef SERVERONLY
  234. if (ServerPaused())
  235. chan->cleartime = realtime;
  236. #endif
  237. if (showpackets.value)
  238. Con_Printf ("--> s=%i(%i) a=%i(%i) %i\n"
  239. , chan->outgoing_sequence
  240. , send_reliable
  241. , chan->incoming_sequence
  242. , chan->incoming_reliable_sequence
  243. , send.cursize);
  244. }
  245. /*
  246. =================
  247. Netchan_Process
  248. called when the current net_message is from remote_address
  249. modifies net_message so that it points to the packet payload
  250. =================
  251. */
  252. qboolean Netchan_Process (netchan_t *chan)
  253. {
  254. unsigned sequence, sequence_ack;
  255. unsigned reliable_ack, reliable_message;
  256. #ifdef SERVERONLY
  257. int qport;
  258. #endif
  259. int i;
  260. if (
  261. #ifndef SERVERONLY
  262. !cls.demoplayback &&
  263. #endif
  264. !NET_CompareAdr (net_from, chan->remote_address))
  265. return false;
  266. // get sequence numbers
  267. MSG_BeginReading ();
  268. sequence = MSG_ReadLong ();
  269. sequence_ack = MSG_ReadLong ();
  270. // read the qport if we are a server
  271. #ifdef SERVERONLY
  272. qport = MSG_ReadShort ();
  273. #endif
  274. reliable_message = sequence >> 31;
  275. reliable_ack = sequence_ack >> 31;
  276. sequence &= ~(1<<31);
  277. sequence_ack &= ~(1<<31);
  278. if (showpackets.value)
  279. Con_Printf ("<-- s=%i(%i) a=%i(%i) %i\n"
  280. , sequence
  281. , reliable_message
  282. , sequence_ack
  283. , reliable_ack
  284. , net_message.cursize);
  285. // get a rate estimation
  286. #if 0
  287. if (chan->outgoing_sequence - sequence_ack < MAX_LATENT)
  288. {
  289. int i;
  290. double time, rate;
  291. i = sequence_ack & (MAX_LATENT - 1);
  292. time = realtime - chan->outgoing_time[i];
  293. time -= 0.1; // subtract 100 ms
  294. if (time <= 0)
  295. { // gotta be a digital link for <100 ms ping
  296. if (chan->rate > 1.0/5000)
  297. chan->rate = 1.0/5000;
  298. }
  299. else
  300. {
  301. if (chan->outgoing_size[i] < 512)
  302. { // only deal with small messages
  303. rate = chan->outgoing_size[i]/time;
  304. if (rate > 5000)
  305. rate = 5000;
  306. rate = 1.0/rate;
  307. if (chan->rate > rate)
  308. chan->rate = rate;
  309. }
  310. }
  311. }
  312. #endif
  313. //
  314. // discard stale or duplicated packets
  315. //
  316. if (sequence <= (unsigned)chan->incoming_sequence)
  317. {
  318. if (showdrop.value)
  319. Con_Printf ("%s:Out of order packet %i at %i\n"
  320. , NET_AdrToString (chan->remote_address)
  321. , sequence
  322. , chan->incoming_sequence);
  323. return false;
  324. }
  325. //
  326. // dropped packets don't keep the message from being used
  327. //
  328. net_drop = sequence - (chan->incoming_sequence+1);
  329. if (net_drop > 0)
  330. {
  331. chan->drop_count += 1;
  332. if (showdrop.value)
  333. Con_Printf ("%s:Dropped %i packets at %i\n"
  334. , NET_AdrToString (chan->remote_address)
  335. , sequence-(chan->incoming_sequence+1)
  336. , sequence);
  337. }
  338. //
  339. // if the current outgoing reliable message has been acknowledged
  340. // clear the buffer to make way for the next
  341. //
  342. if (reliable_ack == (unsigned)chan->reliable_sequence)
  343. chan->reliable_length = 0; // it has been received
  344. //
  345. // if this message contains a reliable message, bump incoming_reliable_sequence
  346. //
  347. chan->incoming_sequence = sequence;
  348. chan->incoming_acknowledged = sequence_ack;
  349. chan->incoming_reliable_acknowledged = reliable_ack;
  350. if (reliable_message)
  351. chan->incoming_reliable_sequence ^= 1;
  352. //
  353. // the message can now be read from the current message pointer
  354. // update statistics counters
  355. //
  356. chan->frame_latency = chan->frame_latency*OLD_AVG
  357. + (chan->outgoing_sequence-sequence_ack)*(1.0-OLD_AVG);
  358. chan->frame_rate = chan->frame_rate*OLD_AVG
  359. + (realtime-chan->last_received)*(1.0-OLD_AVG);
  360. chan->good_count += 1;
  361. chan->last_received = realtime;
  362. return true;
  363. }