Quake II RTX doxygen  1.0 dev
chan.c File Reference
#include "shared/shared.h"
#include "common/common.h"
#include "common/cvar.h"
#include "common/msg.h"
#include "common/net/chan.h"
#include "common/net/net.h"
#include "common/protocol.h"
#include "common/sizebuf.h"
#include "common/zone.h"
#include "system/system.h"

Go to the source code of this file.

Macros

#define SHOWPACKET(...)
 
#define SHOWDROP(...)
 

Functions

static void net_maxmsglen_changed (cvar_t *self)
 
void Netchan_Init (void)
 
void Netchan_OutOfBand (netsrc_t sock, const netadr_t *address, const char *format,...)
 
static size_t NetchanOld_TransmitNextFragment (netchan_t *netchan)
 
static size_t NetchanOld_Transmit (netchan_t *netchan, size_t length, const void *data, int numpackets)
 
static qboolean NetchanOld_Process (netchan_t *netchan)
 
static qboolean NetchanOld_ShouldUpdate (netchan_t *netchan)
 
static netchan_t * NetchanOld_Setup (netsrc_t sock, const netadr_t *adr, int qport, size_t maxpacketlen)
 
static size_t NetchanNew_TransmitNextFragment (netchan_t *netchan)
 
static size_t NetchanNew_Transmit (netchan_t *netchan, size_t length, const void *data, int numpackets)
 
static qboolean NetchanNew_Process (netchan_t *netchan)
 
static qboolean NetchanNew_ShouldUpdate (netchan_t *netchan)
 
static netchan_t * NetchanNew_Setup (netsrc_t sock, const netadr_t *adr, int qport, size_t maxpacketlen)
 
netchan_t * Netchan_Setup (netsrc_t sock, netchan_type_t type, const netadr_t *adr, int qport, size_t maxpacketlen, int protocol)
 
void Netchan_Close (netchan_t *netchan)
 

Variables

cvar_t * net_qport
 
cvar_t * net_maxmsglen
 
cvar_t * net_chantype
 

Macro Definition Documentation

◆ SHOWDROP

#define SHOWDROP (   ...)

Definition at line 95 of file chan.c.

◆ SHOWPACKET

#define SHOWPACKET (   ...)

Definition at line 94 of file chan.c.

Function Documentation

◆ net_maxmsglen_changed()

static void net_maxmsglen_changed ( cvar_t *  self)
static

Definition at line 103 of file chan.c.

104 {
105  if (self->integer) {
106  Cvar_ClampInteger(self, MIN_PACKETLEN, MAX_PACKETLEN_WRITABLE);
107  }
108 }

Referenced by Netchan_Init().

◆ Netchan_Close()

void Netchan_Close ( netchan_t *  netchan)

Definition at line 866 of file chan.c.

867 {
868  Z_Free(netchan);
869 }

Referenced by CL_ConnectionlessPacket(), CL_Disconnect(), CL_ParseReconnect(), and SV_RemoveClient().

◆ Netchan_Init()

void Netchan_Init ( void  )

Definition at line 116 of file chan.c.

117 {
118  int port;
119 
120 #ifdef _DEBUG
121  showpackets = Cvar_Get("showpackets", "0", 0);
122  showdrop = Cvar_Get("showdrop", "0", 0);
123 #endif
124 
125  // pick a port value that should be nice and random
126  port = Sys_Milliseconds() & 0xffff;
127  net_qport = Cvar_Get("qport", va("%d", port), 0);
128  net_maxmsglen = Cvar_Get("net_maxmsglen", va("%d", MAX_PACKETLEN_WRITABLE_DEFAULT), 0);
130  net_chantype = Cvar_Get("net_chantype", "1", 0);
131 }

Referenced by Qcommon_Init().

◆ Netchan_OutOfBand()

void Netchan_OutOfBand ( netsrc_t  sock,
const netadr_t *  address,
const char *  format,
  ... 
)

Definition at line 140 of file chan.c.

142 {
143  va_list argptr;
144  struct {
145  uint32_t header;
146  char data[MAX_PACKETLEN_DEFAULT - 4];
147  } packet;
148  size_t len;
149 
150  // write the packet header
151  packet.header = 0xffffffff;
152 
153  va_start(argptr, format);
154  len = Q_vsnprintf(packet.data, sizeof(packet.data), format, argptr);
155  va_end(argptr);
156 
157  if (len >= sizeof(packet.data)) {
158  Com_WPrintf("%s: overflow\n", __func__);
159  return;
160  }
161 
162  // send the datagram
163  NET_SendPacket(sock, &packet, len + 4, address);
164 }

Referenced by CL_CheckForResend(), CL_SendRcon(), redirect(), send_connect_packet(), SVC_GetChallenge(), and SVC_RemoteCommand().

◆ Netchan_Setup()

netchan_t* Netchan_Setup ( netsrc_t  sock,
netchan_type_t  type,
const netadr_t *  adr,
int  qport,
size_t  maxpacketlen,
int  protocol 
)

Definition at line 835 of file chan.c.

837 {
838  netchan_t *netchan;
839 
840  clamp(maxpacketlen, MIN_PACKETLEN, MAX_PACKETLEN_WRITABLE);
841 
842  switch (type) {
843  case NETCHAN_OLD:
844  netchan = NetchanOld_Setup(sock, adr, qport, maxpacketlen);
845  break;
846  case NETCHAN_NEW:
847  netchan = NetchanNew_Setup(sock, adr, qport, maxpacketlen);
848  break;
849  default:
850  Com_Error(ERR_FATAL, "Netchan_Setup: bad type");
851  netchan = NULL;
852  }
853 
854  netchan->protocol = protocol;
855  netchan->type = type;
856 
857  return netchan;
858 
859 }

Referenced by CL_ConnectionlessPacket(), and SVC_DirectConnect().

◆ NetchanNew_Process()

static qboolean NetchanNew_Process ( netchan_t *  netchan)
static

Definition at line 632 of file chan.c.

633 {
634  netchan_new_t *chan = (netchan_new_t *)netchan;
635  uint32_t sequence, sequence_ack, reliable_ack;
636  qboolean reliable_message, fragmented_message, more_fragments;
637  uint16_t fragment_offset;
638  size_t length;
639 
640 // get sequence numbers
642  sequence = MSG_ReadLong();
643  sequence_ack = MSG_ReadLong();
644 
645  // read the qport if we are a server
646 #if USE_CLIENT
647  if (netchan->sock == NS_SERVER)
648 #endif
649  if (netchan->qport) {
650  MSG_ReadByte();
651  }
652 
653  reliable_message = sequence >> 31;
654  reliable_ack = sequence_ack >> 31;
655  fragmented_message = (sequence >> 30) & 1;
656 
657  sequence &= 0x3FFFFFFF;
658  sequence_ack &= 0x3FFFFFFF;
659 
660  fragment_offset = 0;
661  more_fragments = qfalse;
662  if (fragmented_message) {
663  fragment_offset = MSG_ReadShort();
664  more_fragments = fragment_offset >> 15;
665  fragment_offset &= 0x7FFF;
666  }
667 
668  SHOWPACKET("recv %4"PRIz" : s=%d ack=%d rack=%d",
669  msg_read.cursize, sequence, sequence_ack, reliable_ack);
670  if (fragmented_message) {
671  SHOWPACKET(" fragment_offset=%d more_fragments=%d",
672  fragment_offset, more_fragments);
673  }
674  if (reliable_message) {
675  SHOWPACKET(" reliable=%d", chan->incoming_reliable_sequence ^ 1);
676  }
677  SHOWPACKET("\n");
678 
679 //
680 // discard stale or duplicated packets
681 //
682  if (sequence <= netchan->incoming_sequence) {
683  SHOWDROP("%s: out of order packet %i at %i\n",
684  NET_AdrToString(&netchan->remote_address),
685  sequence, netchan->incoming_sequence);
686  return qfalse;
687  }
688 
689 //
690 // dropped packets don't keep the message from being used
691 //
692  netchan->dropped = sequence - (netchan->incoming_sequence + 1);
693  if (netchan->dropped > 0) {
694  SHOWDROP("%s: dropped %i packets at %i\n",
695  NET_AdrToString(&netchan->remote_address),
696  netchan->dropped, sequence);
697  }
698 
699 //
700 // if the current outgoing reliable message has been acknowledged
701 // clear the buffer to make way for the next
702 //
703  chan->incoming_reliable_acknowledged = reliable_ack;
704  if (reliable_ack == chan->reliable_sequence) {
705  netchan->reliable_length = 0; // it has been received
706  }
707 
708 
709 //
710 // parse fragment header, if any
711 //
712  if (fragmented_message) {
713  if (chan->fragment_sequence != sequence) {
714  // start new receive sequence
715  chan->fragment_sequence = sequence;
716  SZ_Clear(&chan->fragment_in);
717  }
718 
719  if (fragment_offset < chan->fragment_in.cursize) {
720  SHOWDROP("%s: out of order fragment at %i\n",
721  NET_AdrToString(&netchan->remote_address), sequence);
722  return qfalse;
723  }
724 
725  if (fragment_offset > chan->fragment_in.cursize) {
726  SHOWDROP("%s: dropped fragment(s) at %i\n",
727  NET_AdrToString(&netchan->remote_address), sequence);
728  return qfalse;
729  }
730 
731  length = msg_read.cursize - msg_read.readcount;
732  if (chan->fragment_in.cursize + length > chan->fragment_in.maxsize) {
733  SHOWDROP("%s: oversize fragment at %i\n",
734  NET_AdrToString(&netchan->remote_address), sequence);
735  return qfalse;
736  }
737 
738  SZ_Write(&chan->fragment_in, msg_read.data +
739  msg_read.readcount, length);
740  if (more_fragments) {
741  return qfalse;
742  }
743 
744  // message has been sucessfully assembled
745  SZ_Clear(&msg_read);
746  SZ_Write(&msg_read, chan->fragment_in.data,
747  chan->fragment_in.cursize);
748  SZ_Clear(&chan->fragment_in);
749  }
750 
751  netchan->incoming_sequence = sequence;
752  netchan->incoming_acknowledged = sequence_ack;
753 
754 //
755 // if this message contains a reliable message, bump incoming_reliable_sequence
756 //
757  if (reliable_message) {
758  netchan->reliable_ack_pending = qtrue;
759  chan->incoming_reliable_sequence ^= 1;
760  }
761 
762 //
763 // the message can now be read from the current message pointer
764 //
765  netchan->last_received = com_localTime;
766 
767  netchan->total_dropped += netchan->dropped;
768  netchan->total_received += netchan->dropped + 1;
769 
770  return qtrue;
771 }

Referenced by NetchanNew_Setup().

◆ NetchanNew_Setup()

static netchan_t* NetchanNew_Setup ( netsrc_t  sock,
const netadr_t *  adr,
int  qport,
size_t  maxpacketlen 
)
static

Definition at line 797 of file chan.c.

799 {
800  netchan_new_t *chan;
801  netchan_t *netchan;
802 
803  chan = Z_TagMallocz(sizeof(*chan),
804  sock == NS_SERVER ? TAG_SERVER : TAG_GENERAL);
805  netchan = (netchan_t *)chan;
806  netchan->sock = sock;
807  netchan->remote_address = *adr;
808  netchan->qport = qport;
809  netchan->maxpacketlen = maxpacketlen;
810  netchan->last_received = com_localTime;
811  netchan->last_sent = com_localTime;
812  netchan->incoming_sequence = 0;
813  netchan->outgoing_sequence = 1;
814 
815  netchan->Process = NetchanNew_Process;
816  netchan->Transmit = NetchanNew_Transmit;
817  netchan->TransmitNextFragment = NetchanNew_TransmitNextFragment;
818  netchan->ShouldUpdate = NetchanNew_ShouldUpdate;
819 
820  SZ_Init(&netchan->message, chan->message_buf,
821  sizeof(chan->message_buf));
822  SZ_TagInit(&chan->fragment_in, chan->fragment_in_buf,
823  sizeof(chan->fragment_in_buf), SZ_NC_FRG_IN);
824  SZ_TagInit(&chan->fragment_out, chan->fragment_out_buf,
825  sizeof(chan->fragment_out_buf), SZ_NC_FRG_OUT);
826 
827  return netchan;
828 }

Referenced by Netchan_Setup().

◆ NetchanNew_ShouldUpdate()

static qboolean NetchanNew_ShouldUpdate ( netchan_t *  netchan)
static

Definition at line 778 of file chan.c.

779 {
780  netchan_new_t *chan = (netchan_new_t *)netchan;
781 
782  if (netchan->message.cursize ||
783  netchan->reliable_ack_pending ||
784  chan->fragment_out.cursize ||
785  com_localTime - netchan->last_sent > 1000) {
786  return qtrue;
787  }
788 
789  return qfalse;
790 }

Referenced by NetchanNew_Setup().

◆ NetchanNew_Transmit()

static size_t NetchanNew_Transmit ( netchan_t *  netchan,
size_t  length,
const void data,
int  numpackets 
)
static

Definition at line 523 of file chan.c.

524 {
525  netchan_new_t *chan = (netchan_new_t *)netchan;
526  sizebuf_t send;
527  byte send_buf[MAX_PACKETLEN];
528  qboolean send_reliable;
529  uint32_t w1, w2;
530  int i;
531 
532 // check for message overflow
533  if (netchan->message.overflowed) {
534  netchan->fatal_error = qtrue;
535  Com_WPrintf("%s: outgoing message overflow\n",
536  NET_AdrToString(&netchan->remote_address));
537  return 0;
538  }
539 
540  if (netchan->fragment_pending) {
541  return NetchanNew_TransmitNextFragment(netchan);
542  }
543 
544  send_reliable = qfalse;
545 
546 // if the remote side dropped the last reliable message, resend it
547  if (netchan->incoming_acknowledged > chan->last_reliable_sequence &&
548  chan->incoming_reliable_acknowledged != chan->reliable_sequence) {
549  send_reliable = qtrue;
550  }
551 
552 // if the reliable transmit buffer is empty, copy the current message out
553  if (!netchan->reliable_length && netchan->message.cursize) {
554  send_reliable = qtrue;
555  memcpy(chan->reliable_buf, chan->message_buf,
556  netchan->message.cursize);
557  netchan->reliable_length = netchan->message.cursize;
558  netchan->message.cursize = 0;
559  chan->reliable_sequence ^= 1;
560  }
561 
562  if (length > netchan->maxpacketlen || (send_reliable &&
563  (netchan->reliable_length + length > netchan->maxpacketlen))) {
564  if (send_reliable) {
565  chan->last_reliable_sequence = netchan->outgoing_sequence;
566  SZ_Write(&chan->fragment_out, chan->reliable_buf,
567  netchan->reliable_length);
568  }
569  // add the unreliable part if space is available
570  if (chan->fragment_out.maxsize - chan->fragment_out.cursize >= length)
571  SZ_Write(&chan->fragment_out, data, length);
572  else
573  Com_WPrintf("%s: dumped unreliable\n",
574  NET_AdrToString(&netchan->remote_address));
575  return NetchanNew_TransmitNextFragment(netchan);
576  }
577 
578 // write the packet header
579  w1 = (netchan->outgoing_sequence & 0x3FFFFFFF) | (send_reliable << 31);
580  w2 = (netchan->incoming_sequence & 0x3FFFFFFF) |
581  (chan->incoming_reliable_sequence << 31);
582 
583  SZ_TagInit(&send, send_buf, sizeof(send_buf), SZ_NC_SEND_NEW);
584 
585  SZ_WriteLong(&send, w1);
586  SZ_WriteLong(&send, w2);
587 
588 #if USE_CLIENT
589  // send the qport if we are a client
590  if (netchan->sock == NS_CLIENT && netchan->qport) {
591  SZ_WriteByte(&send, netchan->qport);
592  }
593 #endif
594 
595  // copy the reliable message to the packet first
596  if (send_reliable) {
597  chan->last_reliable_sequence = netchan->outgoing_sequence;
598  SZ_Write(&send, chan->reliable_buf, netchan->reliable_length);
599  }
600 
601  // add the unreliable part
602  SZ_Write(&send, data, length);
603 
604  SHOWPACKET("send %4"PRIz" : s=%d ack=%d rack=%d",
605  send.cursize,
606  netchan->outgoing_sequence,
607  netchan->incoming_sequence,
608  chan->incoming_reliable_sequence);
609  if (send_reliable) {
610  SHOWPACKET(" reliable=%d", chan->reliable_sequence);
611  }
612  SHOWPACKET("\n");
613 
614  // send the datagram
615  for (i = 0; i < numpackets; i++) {
616  NET_SendPacket(netchan->sock, send.data, send.cursize,
617  &netchan->remote_address);
618  }
619 
620  netchan->outgoing_sequence++;
621  netchan->reliable_ack_pending = qfalse;
622  netchan->last_sent = com_localTime;
623 
624  return send.cursize * numpackets;
625 }

Referenced by NetchanNew_Setup().

◆ NetchanNew_TransmitNextFragment()

static size_t NetchanNew_TransmitNextFragment ( netchan_t *  netchan)
static

Definition at line 437 of file chan.c.

438 {
439  netchan_new_t *chan = (netchan_new_t *)netchan;
440  sizebuf_t send;
441  byte send_buf[MAX_PACKETLEN];
442  qboolean send_reliable;
443  uint32_t w1, w2;
444  uint16_t offset;
445  size_t fragment_length;
446  qboolean more_fragments;
447 
448  send_reliable = netchan->reliable_length ? qtrue : qfalse;
449 
450  // write the packet header
451  w1 = (netchan->outgoing_sequence & 0x3FFFFFFF) | (1 << 30) |
452  (send_reliable << 31);
453  w2 = (netchan->incoming_sequence & 0x3FFFFFFF) | (0 << 30) |
454  (chan->incoming_reliable_sequence << 31);
455 
456  SZ_TagInit(&send, send_buf, sizeof(send_buf), SZ_NC_SEND_FRG);
457 
458  SZ_WriteLong(&send, w1);
459  SZ_WriteLong(&send, w2);
460 
461 #if USE_CLIENT
462  // send the qport if we are a client
463  if (netchan->sock == NS_CLIENT && netchan->qport) {
464  SZ_WriteByte(&send, netchan->qport);
465  }
466 #endif
467 
468  fragment_length = chan->fragment_out.cursize - chan->fragment_out.readcount;
469  if (fragment_length > netchan->maxpacketlen) {
470  fragment_length = netchan->maxpacketlen;
471  }
472 
473  more_fragments = qtrue;
474  if (chan->fragment_out.readcount + fragment_length ==
475  chan->fragment_out.cursize) {
476  more_fragments = qfalse;
477  }
478 
479  // write fragment offset
480  offset = (chan->fragment_out.readcount & 0x7FFF) |
481  (more_fragments << 15);
482  SZ_WriteShort(&send, offset);
483 
484  // write fragment contents
485  SZ_Write(&send, chan->fragment_out.data + chan->fragment_out.readcount,
486  fragment_length);
487 
488  SHOWPACKET("send %4"PRIz" : s=%d ack=%d rack=%d "
489  "fragment_offset=%"PRIz" more_fragments=%d",
490  send.cursize,
491  netchan->outgoing_sequence,
492  netchan->incoming_sequence,
493  chan->incoming_reliable_sequence,
494  chan->fragment_out.readcount,
495  more_fragments);
496  if (send_reliable) {
497  SHOWPACKET(" reliable=%i ", chan->reliable_sequence);
498  }
499  SHOWPACKET("\n");
500 
501  chan->fragment_out.readcount += fragment_length;
502  netchan->fragment_pending = more_fragments;
503 
504  // if the message has been sent completely, clear the fragment buffer
505  if (!netchan->fragment_pending) {
506  netchan->outgoing_sequence++;
507  netchan->last_sent = com_localTime;
508  SZ_Clear(&chan->fragment_out);
509  }
510 
511  // send the datagram
512  NET_SendPacket(netchan->sock, send.data, send.cursize,
513  &netchan->remote_address);
514 
515  return send.cursize;
516 }

Referenced by NetchanNew_Setup(), and NetchanNew_Transmit().

◆ NetchanOld_Process()

static qboolean NetchanOld_Process ( netchan_t *  netchan)
static

Definition at line 285 of file chan.c.

286 {
287  netchan_old_t *chan = (netchan_old_t *)netchan;
288  uint32_t sequence, sequence_ack;
289  uint32_t reliable_ack, reliable_message;
290 
291 // get sequence numbers
293  sequence = MSG_ReadLong();
294  sequence_ack = MSG_ReadLong();
295 
296  // read the qport if we are a server
297 #if USE_CLIENT
298  if (netchan->sock == NS_SERVER)
299 #endif
300  {
301  if (netchan->protocol < PROTOCOL_VERSION_R1Q2) {
302  MSG_ReadShort();
303  } else if (netchan->qport) {
304  MSG_ReadByte();
305  }
306  }
307 
308  reliable_message = sequence >> 31;
309  reliable_ack = sequence_ack >> 31;
310 
311  sequence &= ~(1 << 31);
312  sequence_ack &= ~(1 << 31);
313 
314  SHOWPACKET("recv %4"PRIz" : s=%d ack=%d rack=%d",
315  msg_read.cursize,
316  sequence,
317  sequence_ack,
318  reliable_ack);
319  if (reliable_message) {
320  SHOWPACKET(" reliable=%d", chan->incoming_reliable_sequence ^ 1);
321  }
322  SHOWPACKET("\n");
323 
324 //
325 // discard stale or duplicated packets
326 //
327  if (sequence <= netchan->incoming_sequence) {
328  SHOWDROP("%s: out of order packet %i at %i\n",
329  NET_AdrToString(&netchan->remote_address),
330  sequence, netchan->incoming_sequence);
331  return qfalse;
332  }
333 
334 //
335 // dropped packets don't keep the message from being used
336 //
337  netchan->dropped = sequence - (netchan->incoming_sequence + 1);
338  if (netchan->dropped > 0) {
339  SHOWDROP("%s: dropped %i packets at %i\n",
340  NET_AdrToString(&netchan->remote_address),
341  netchan->dropped, sequence);
342  }
343 
344 //
345 // if the current outgoing reliable message has been acknowledged
346 // clear the buffer to make way for the next
347 //
348  chan->incoming_reliable_acknowledged = reliable_ack;
349  if (reliable_ack == chan->reliable_sequence)
350  netchan->reliable_length = 0; // it has been received
351 
352 //
353 // if this message contains a reliable message, bump incoming_reliable_sequence
354 //
355  netchan->incoming_sequence = sequence;
356  netchan->incoming_acknowledged = sequence_ack;
357  if (reliable_message) {
358  netchan->reliable_ack_pending = qtrue;
359  chan->incoming_reliable_sequence ^= 1;
360  }
361 
362 //
363 // the message can now be read from the current message pointer
364 //
365  netchan->last_received = com_localTime;
366 
367  netchan->total_dropped += netchan->dropped;
368  netchan->total_received += netchan->dropped + 1;
369 
370  return qtrue;
371 }

Referenced by NetchanOld_Setup().

◆ NetchanOld_Setup()

static netchan_t* NetchanOld_Setup ( netsrc_t  sock,
const netadr_t *  adr,
int  qport,
size_t  maxpacketlen 
)
static

Definition at line 395 of file chan.c.

397 {
398  netchan_old_t *chan;
399  netchan_t *netchan;
400 
401  Z_TagReserve(sizeof(*chan) + maxpacketlen * 2,
402  sock == NS_SERVER ? TAG_SERVER : TAG_GENERAL);
403 
404  chan = Z_ReservedAlloc(sizeof(*chan));
405  memset(chan, 0, sizeof(*chan));
406  netchan = (netchan_t *)chan;
407  netchan->sock = sock;
408  netchan->remote_address = *adr;
409  netchan->qport = qport;
410  netchan->maxpacketlen = maxpacketlen;
411  netchan->last_received = com_localTime;
412  netchan->last_sent = com_localTime;
413  netchan->incoming_sequence = 0;
414  netchan->outgoing_sequence = 1;
415 
416  netchan->Process = NetchanOld_Process;
417  netchan->Transmit = NetchanOld_Transmit;
418  netchan->TransmitNextFragment = NetchanOld_TransmitNextFragment;
419  netchan->ShouldUpdate = NetchanOld_ShouldUpdate;
420 
421  chan->message_buf = Z_ReservedAlloc(maxpacketlen);
422  SZ_Init(&netchan->message, chan->message_buf, maxpacketlen);
423 
424  chan->reliable_buf = Z_ReservedAlloc(maxpacketlen);
425 
426  return netchan;
427 }

Referenced by Netchan_Setup().

◆ NetchanOld_ShouldUpdate()

static qboolean NetchanOld_ShouldUpdate ( netchan_t *  netchan)
static

Definition at line 378 of file chan.c.

379 {
380  if (netchan->message.cursize || netchan->reliable_ack_pending ||
381  com_localTime - netchan->last_sent > 1000) {
382  return qtrue;
383  }
384 
385  return qfalse;
386 }

Referenced by NetchanOld_Setup().

◆ NetchanOld_Transmit()

static size_t NetchanOld_Transmit ( netchan_t *  netchan,
size_t  length,
const void data,
int  numpackets 
)
static

Definition at line 184 of file chan.c.

185 {
186  netchan_old_t *chan = (netchan_old_t *)netchan;
187  sizebuf_t send;
188  byte send_buf[MAX_PACKETLEN];
189  qboolean send_reliable;
190  uint32_t w1, w2;
191  int i;
192 
193 // check for message overflow
194  if (netchan->message.overflowed) {
195  netchan->fatal_error = qtrue;
196  Com_WPrintf("%s: outgoing message overflow\n",
197  NET_AdrToString(&netchan->remote_address));
198  return 0;
199  }
200 
201  send_reliable = qfalse;
202 
203  // if the remote side dropped the last reliable message, resend it
204  if (netchan->incoming_acknowledged > chan->last_reliable_sequence &&
205  chan->incoming_reliable_acknowledged != chan->reliable_sequence) {
206  send_reliable = qtrue;
207  }
208 
209 // if the reliable transmit buffer is empty, copy the current message out
210  if (!netchan->reliable_length && netchan->message.cursize) {
211  send_reliable = qtrue;
212  memcpy(chan->reliable_buf, chan->message_buf,
213  netchan->message.cursize);
214  netchan->reliable_length = netchan->message.cursize;
215  netchan->message.cursize = 0;
216  chan->reliable_sequence ^= 1;
217  }
218 
219 // write the packet header
220  w1 = (netchan->outgoing_sequence & ~(1 << 31)) |
221  (send_reliable << 31);
222  w2 = (netchan->incoming_sequence & ~(1 << 31)) |
223  (chan->incoming_reliable_sequence << 31);
224 
225  SZ_TagInit(&send, send_buf, sizeof(send_buf), SZ_NC_SEND_OLD);
226 
227  SZ_WriteLong(&send, w1);
228  SZ_WriteLong(&send, w2);
229 
230 #if USE_CLIENT
231  // send the qport if we are a client
232  if (netchan->sock == NS_CLIENT) {
233  if (netchan->protocol < PROTOCOL_VERSION_R1Q2) {
234  SZ_WriteShort(&send, netchan->qport);
235  } else if (netchan->qport) {
236  SZ_WriteByte(&send, netchan->qport);
237  }
238  }
239 #endif
240 
241 // copy the reliable message to the packet first
242  if (send_reliable) {
243  SZ_Write(&send, chan->reliable_buf, netchan->reliable_length);
244  chan->last_reliable_sequence = netchan->outgoing_sequence;
245  }
246 
247 // add the unreliable part if space is available
248  if (send.maxsize - send.cursize >= length)
249  SZ_Write(&send, data, length);
250  else
251  Com_WPrintf("%s: dumped unreliable\n",
252  NET_AdrToString(&netchan->remote_address));
253 
254  SHOWPACKET("send %4"PRIz" : s=%d ack=%d rack=%d",
255  send.cursize,
256  netchan->outgoing_sequence,
257  netchan->incoming_sequence,
258  chan->incoming_reliable_sequence);
259  if (send_reliable) {
260  SHOWPACKET(" reliable=%i", chan->reliable_sequence);
261  }
262  SHOWPACKET("\n");
263 
264  // send the datagram
265  for (i = 0; i < numpackets; i++) {
266  NET_SendPacket(netchan->sock, send.data, send.cursize,
267  &netchan->remote_address);
268  }
269 
270  netchan->outgoing_sequence++;
271  netchan->reliable_ack_pending = qfalse;
272  netchan->last_sent = com_localTime;
273 
274  return send.cursize * numpackets;
275 }

Referenced by NetchanOld_Setup().

◆ NetchanOld_TransmitNextFragment()

static size_t NetchanOld_TransmitNextFragment ( netchan_t *  netchan)
static

Definition at line 168 of file chan.c.

169 {
170  Com_Error(ERR_FATAL, "%s: not implemented", __func__);
171  return 0;
172 }

Referenced by NetchanOld_Setup().

Variable Documentation

◆ net_chantype

cvar_t* net_chantype

Definition at line 100 of file chan.c.

Referenced by CL_CheckForResend(), and Netchan_Init().

◆ net_maxmsglen

cvar_t* net_maxmsglen

Definition at line 99 of file chan.c.

Referenced by CL_CheckForResend(), Netchan_Init(), and parse_packet_length().

◆ net_qport

cvar_t* net_qport

Definition at line 98 of file chan.c.

Referenced by CL_CheckForResend(), and Netchan_Init().

Z_ReservedAlloc
void * Z_ReservedAlloc(size_t size)
Definition: zone.c:349
NetchanOld_Process
static qboolean NetchanOld_Process(netchan_t *netchan)
Definition: chan.c:285
msg_read
sizebuf_t msg_read
Definition: msg.c:37
NET_AdrToString
char * NET_AdrToString(const netadr_t *a)
Definition: net.c:257
MSG_BeginReading
void MSG_BeginReading(void)
Definition: msg.c:1437
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
net_maxmsglen
cvar_t * net_maxmsglen
Definition: chan.c:99
net_chantype
cvar_t * net_chantype
Definition: chan.c:100
SZ_WriteByte
void SZ_WriteByte(sizebuf_t *sb, int c)
Definition: sizebuf.c:82
net_maxmsglen_changed
static void net_maxmsglen_changed(cvar_t *self)
Definition: chan.c:103
SZ_WriteShort
void SZ_WriteShort(sizebuf_t *sb, int c)
Definition: sizebuf.c:90
net_qport
cvar_t * net_qport
Definition: chan.c:98
Q_vsnprintf
size_t Q_vsnprintf(char *dest, size_t size, const char *fmt, va_list argptr)
Definition: shared.c:791
NetchanOld_Setup
static netchan_t * NetchanOld_Setup(netsrc_t sock, const netadr_t *adr, int qport, size_t maxpacketlen)
Definition: chan.c:395
Sys_Milliseconds
unsigned Sys_Milliseconds(void)
Definition: system.c:644
SZ_Init
void SZ_Init(sizebuf_t *buf, void *data, size_t size)
Definition: sizebuf.c:31
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition: g_main.c:258
NetchanNew_ShouldUpdate
static qboolean NetchanNew_ShouldUpdate(netchan_t *netchan)
Definition: chan.c:778
NetchanNew_Transmit
static size_t NetchanNew_Transmit(netchan_t *netchan, size_t length, const void *data, int numpackets)
Definition: chan.c:523
va
char * va(const char *format,...)
Definition: shared.c:429
Z_Free
void Z_Free(void *ptr)
Definition: zone.c:147
SHOWPACKET
#define SHOWPACKET(...)
Definition: chan.c:94
Z_TagMallocz
void * Z_TagMallocz(size_t size, memtag_t tag)
Definition: zone.c:330
MSG_ReadLong
int MSG_ReadLong(void)
Definition: msg.c:1517
NetchanNew_Process
static qboolean NetchanNew_Process(netchan_t *netchan)
Definition: chan.c:632
NetchanNew_Setup
static netchan_t * NetchanNew_Setup(netsrc_t sock, const netadr_t *adr, int qport, size_t maxpacketlen)
Definition: chan.c:797
SZ_TagInit
void SZ_TagInit(sizebuf_t *buf, void *data, size_t size, uint32_t tag)
Definition: sizebuf.c:23
com_localTime
unsigned com_localTime
Definition: common.c:123
Z_TagReserve
void Z_TagReserve(size_t size, memtag_t tag)
Definition: zone.c:342
SHOWDROP
#define SHOWDROP(...)
Definition: chan.c:95
NetchanOld_ShouldUpdate
static qboolean NetchanOld_ShouldUpdate(netchan_t *netchan)
Definition: chan.c:378
NET_SendPacket
qboolean NET_SendPacket(netsrc_t sock, const void *data, size_t len, const netadr_t *to)
Definition: net.c:918
Cvar_ClampInteger
int Cvar_ClampInteger(cvar_t *var, int min, int max)
Definition: cvar.c:549
NetchanOld_Transmit
static size_t NetchanOld_Transmit(netchan_t *netchan, size_t length, const void *data, int numpackets)
Definition: chan.c:184
SZ_WriteLong
void SZ_WriteLong(sizebuf_t *sb, int c)
Definition: sizebuf.c:99
MSG_ReadByte
int MSG_ReadByte(void)
Definition: msg.c:1475
NetchanNew_TransmitNextFragment
static size_t NetchanNew_TransmitNextFragment(netchan_t *netchan)
Definition: chan.c:437
SZ_Clear
void SZ_Clear(sizebuf_t *buf)
Definition: sizebuf.c:40
NetchanOld_TransmitNextFragment
static size_t NetchanOld_TransmitNextFragment(netchan_t *netchan)
Definition: chan.c:168
MSG_ReadShort
int MSG_ReadShort(void)
Definition: msg.c:1489