Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

net_chan.c File Reference

#include "../game/q_shared.h"
#include "qcommon.h"

Include dependency graph for net_chan.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  loopback_t
struct  loopmsg_t

Defines

#define FRAGMENT_BIT   (1<<31)
#define FRAGMENT_SIZE   (MAX_PACKETLEN - 100)
#define MAX_LOOPBACK   16
#define MAX_PACKETLEN   1400
#define PACKET_HEADER   10

Functions

const char * NET_AdrToString (netadr_t a)
qboolean NET_CompareAdr (netadr_t a, netadr_t b)
qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b)
qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, msg_t *net_message)
qboolean NET_IsLocalAddress (netadr_t adr)
void QDECL NET_OutOfBandData (netsrc_t sock, netadr_t adr, byte *format, int len)
void QDECL NET_OutOfBandPrint (netsrc_t sock, netadr_t adr, const char *format,...)
void NET_SendLoopPacket (netsrc_t sock, int length, const void *data, netadr_t to)
void NET_SendPacket (netsrc_t sock, int length, const void *data, netadr_t to)
qboolean NET_StringToAdr (const char *s, netadr_t *a)
void Netchan_Init (int port)
qboolean Netchan_Process (netchan_t *chan, msg_t *msg)
void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport)
void Netchan_Transmit (netchan_t *chan, int length, const byte *data)
void Netchan_TransmitNextFragment (netchan_t *chan)

Variables

loopback_t loopbacks [2]
char * netsrcString [2]
cvar_tqport
cvar_tshowdrop
cvar_tshowpackets


Define Documentation

#define FRAGMENT_BIT   (1<<31)
 

Definition at line 55 of file net_chan.c.

Referenced by Netchan_TransmitNextFragment().

#define FRAGMENT_SIZE   (MAX_PACKETLEN - 100)
 

Definition at line 52 of file net_chan.c.

#define MAX_LOOPBACK   16
 

Definition at line 562 of file net_chan.c.

Referenced by NET_GetLoopPacket(), and NET_SendLoopPacket().

#define MAX_PACKETLEN   1400
 

Definition at line 50 of file net_chan.c.

#define PACKET_HEADER   10
 

Definition at line 53 of file net_chan.c.


Function Documentation

const char* NET_AdrToString netadr_t  a  ) 
 

Definition at line 498 of file net_chan.c.

References a, BigShort(), Com_sprintf(), netadr_t::ip, netadr_t::ipx, netadr_t::port, s, and netadr_t::type.

Referenced by CL_ConnectionlessPacket(), CL_GetPing(), CL_PacketEvent(), CL_ServerInfoPacket(), LAN_GetServerAddressString(), LAN_GetServerInfo(), Netchan_Process(), SV_ConnectionlessPacket(), SV_DirectConnect(), SV_GetChallenge(), SV_Status_f(), SV_UserinfoChanged(), SVC_RemoteCommand(), Sys_GetPacket(), and Sys_SendPacket().

00499 {
00500     static  char    s[64];
00501 
00502     if (a.type == NA_LOOPBACK) {
00503         Com_sprintf (s, sizeof(s), "loopback");
00504     } else if (a.type == NA_BOT) {
00505         Com_sprintf (s, sizeof(s), "bot");
00506     } else if (a.type == NA_IP) {
00507         Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%hu",
00508             a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port));
00509     } else {
00510         Com_sprintf (s, sizeof(s), "%02x%02x%02x%02x.%02x%02x%02x%02x%02x%02x:%hu",
00511         a.ipx[0], a.ipx[1], a.ipx[2], a.ipx[3], a.ipx[4], a.ipx[5], a.ipx[6], a.ipx[7], a.ipx[8], a.ipx[9], 
00512         BigShort(a.port));
00513     }
00514 
00515     return s;
00516 }

Here is the call graph for this function:

qboolean NET_CompareAdr netadr_t  a,
netadr_t  b
 

Definition at line 519 of file net_chan.c.

References a, b, Com_Printf(), netadr_t::ip, netadr_t::ipx, memcmp(), netadr_t::port, qboolean, and netadr_t::type.

Referenced by CL_DisconnectPacket(), CL_GetServerStatus(), CL_MotdPacket(), CL_PacketEvent(), CL_ServerInfoPacket(), CL_ServerStatus(), CL_ServerStatusResponse(), CL_SetServerInfoByAddress(), CL_UpdateVisiblePings_f(), LAN_AddServer(), LAN_RemoveServer(), SV_DirectConnect(), SV_DropClient(), and SV_GetChallenge().

00520 {
00521     if (a.type != b.type)
00522         return qfalse;
00523 
00524     if (a.type == NA_LOOPBACK)
00525         return qtrue;
00526 
00527     if (a.type == NA_IP)
00528     {
00529         if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port)
00530             return qtrue;
00531         return qfalse;
00532     }
00533 
00534     if (a.type == NA_IPX)
00535     {
00536         if ((memcmp(a.ipx, b.ipx, 10) == 0) && a.port == b.port)
00537             return qtrue;
00538         return qfalse;
00539     }
00540 
00541     Com_Printf ("NET_CompareAdr: bad address type\n");
00542     return qfalse;
00543 }

Here is the call graph for this function:

qboolean NET_CompareBaseAdr netadr_t  a,
netadr_t  b
 

Definition at line 471 of file net_chan.c.

References a, b, Com_Printf(), netadr_t::ip, netadr_t::ipx, memcmp(), qboolean, and netadr_t::type.

Referenced by CL_ConnectionlessPacket(), SV_AuthorizeIpPacket(), SV_DirectConnect(), and SV_PacketEvent().

00472 {
00473     if (a.type != b.type)
00474         return qfalse;
00475 
00476     if (a.type == NA_LOOPBACK)
00477         return qtrue;
00478 
00479     if (a.type == NA_IP)
00480     {
00481         if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3])
00482             return qtrue;
00483         return qfalse;
00484     }
00485 
00486     if (a.type == NA_IPX)
00487     {
00488         if ((memcmp(a.ipx, b.ipx, 10) == 0))
00489             return qtrue;
00490         return qfalse;
00491     }
00492 
00493 
00494     Com_Printf ("NET_CompareBaseAdr: bad address type\n");
00495     return qfalse;
00496 }

Here is the call graph for this function:

qboolean NET_GetLoopPacket netsrc_t  sock,
netadr_t net_from,
msg_t net_message
 

Definition at line 577 of file net_chan.c.

References Com_Memcpy(), Com_Memset(), msg_t::cursize, msg_t::data, loopmsg_t::data, loopmsg_t::datalen, loopback_t::get, i, loopbacks, MAX_LOOPBACK, loopback_t::msgs, qboolean, and loopback_t::send.

Referenced by Com_EventLoop().

00578 {
00579     int     i;
00580     loopback_t  *loop;
00581 
00582     loop = &loopbacks[sock];
00583 
00584     if (loop->send - loop->get > MAX_LOOPBACK)
00585         loop->get = loop->send - MAX_LOOPBACK;
00586 
00587     if (loop->get >= loop->send)
00588         return qfalse;
00589 
00590     i = loop->get & (MAX_LOOPBACK-1);
00591     loop->get++;
00592 
00593     Com_Memcpy (net_message->data, loop->msgs[i].data, loop->msgs[i].datalen);
00594     net_message->cursize = loop->msgs[i].datalen;
00595     Com_Memset (net_from, 0, sizeof(*net_from));
00596     net_from->type = NA_LOOPBACK;
00597     return qtrue;
00598 
00599 }

Here is the call graph for this function:

qboolean NET_IsLocalAddress netadr_t  adr  ) 
 

Definition at line 546 of file net_chan.c.

References qboolean, and netadr_t::type.

Referenced by CL_Connect_f(), SV_DirectConnect(), and SV_UserinfoChanged().

00546                                                {
00547     return adr.type == NA_LOOPBACK;
00548 }

void QDECL NET_OutOfBandData netsrc_t  sock,
netadr_t  adr,
byte format,
int  len
 

Definition at line 673 of file net_chan.c.

References byte, msg_t::cursize, msg_t::data, format, Huff_Compress(), i, MAX_MSGLEN, NET_SendPacket(), QDECL, and string().

Referenced by CL_CheckForResend().

00673                                                                                    {
00674     byte        string[MAX_MSGLEN*2];
00675     int         i;
00676     msg_t       mbuf;
00677 
00678     // set the header
00679     string[0] = 0xff;
00680     string[1] = 0xff;
00681     string[2] = 0xff;
00682     string[3] = 0xff;
00683 
00684     for(i=0;i<len;i++) {
00685         string[i+4] = format[i];
00686     }
00687 
00688     mbuf.data = string;
00689     mbuf.cursize = len+4;
00690     Huff_Compress( &mbuf, 12);
00691     // send the datagram
00692     NET_SendPacket( sock, mbuf.cursize, mbuf.data, adr );
00693 }

Here is the call graph for this function:

void QDECL NET_OutOfBandPrint netsrc_t  sock,
netadr_t  adr,
const char *  format,
  ...
 

Definition at line 647 of file net_chan.c.

References format, NET_SendPacket(), QDECL, string(), strlen(), va_end, va_list, va_start, and vsprintf().

Referenced by CL_CheckForResend(), CL_ConnectionlessPacket(), CL_GlobalServers_f(), CL_Ping_f(), CL_RequestAuthorization(), CL_RequestMotd(), CL_ServerStatus(), CL_ServerStatus_f(), CL_UpdateVisiblePings_f(), SV_AuthorizeIpPacket(), SV_Ban_f(), SV_BanNum_f(), SV_DirectConnect(), SV_FlushRedirect(), SV_GetChallenge(), SV_MasterHeartbeat(), SV_PacketEvent(), SVC_Info(), and SVC_Status().

00647                                                                                       {
00648     va_list     argptr;
00649     char        string[MAX_MSGLEN];
00650 
00651 
00652     // set the header
00653     string[0] = -1;
00654     string[1] = -1;
00655     string[2] = -1;
00656     string[3] = -1;
00657 
00658     va_start( argptr, format );
00659     vsprintf( string+4, format, argptr );
00660     va_end( argptr );
00661 
00662     // send the datagram
00663     NET_SendPacket( sock, strlen( string ), string, adr );
00664 }

Here is the call graph for this function:

void NET_SendLoopPacket netsrc_t  sock,
int  length,
const void *  data,
netadr_t  to
 

Definition at line 602 of file net_chan.c.

References Com_Memcpy(), data, loopmsg_t::data, loopmsg_t::datalen, i, length(), loopbacks, MAX_LOOPBACK, loopback_t::msgs, and loopback_t::send.

Referenced by NET_SendPacket().

00603 {
00604     int     i;
00605     loopback_t  *loop;
00606 
00607     loop = &loopbacks[sock^1];
00608 
00609     i = loop->send & (MAX_LOOPBACK-1);
00610     loop->send++;
00611 
00612     Com_Memcpy (loop->msgs[i].data, data, length);
00613     loop->msgs[i].datalen = length;
00614 }

Here is the call graph for this function:

void NET_SendPacket netsrc_t  sock,
int  length,
const void *  data,
netadr_t  to
 

Definition at line 619 of file net_chan.c.

References Com_Printf(), data, cvar_s::integer, length(), NET_SendLoopPacket(), showpackets, Sys_SendPacket(), and netadr_t::type.

Referenced by CL_LocalServers_f(), CL_Rcon_f(), NET_OutOfBandData(), NET_OutOfBandPrint(), Netchan_Transmit(), and Netchan_TransmitNextFragment().

00619                                                                                 {
00620 
00621     // sequenced packets are shown in netchan, so just show oob
00622     if ( showpackets->integer && *(int *)data == -1 )   {
00623         Com_Printf ("send packet %4i\n", length);
00624     }
00625 
00626     if ( to.type == NA_LOOPBACK ) {
00627         NET_SendLoopPacket (sock, length, data, to);
00628         return;
00629     }
00630     if ( to.type == NA_BOT ) {
00631         return;
00632     }
00633     if ( to.type == NA_BAD ) {
00634         return;
00635     }
00636 
00637     Sys_SendPacket( length, data, to );
00638 }

Here is the call graph for this function:

qboolean NET_StringToAdr const char *  s,
netadr_t a
 

Definition at line 702 of file net_chan.c.

References a, atoi, BigShort(), Com_Memset(), netadr_t::ip, netadr_t::port, PORT_SERVER, Q_strncpyz(), qboolean, r, s, strcmp(), strstr(), Sys_StringToAdr(), and netadr_t::type.

Referenced by CL_Connect_f(), CL_GlobalServers_f(), CL_MapLoading(), CL_Ping_f(), CL_Rcon_f(), CL_RequestAuthorization(), CL_RequestMotd(), CL_ServerStatus(), CL_ServerStatus_f(), LAN_AddServer(), LAN_RemoveServer(), SV_Ban_f(), SV_BanNum_f(), SV_GetChallenge(), and SV_MasterHeartbeat().

00702                                                           {
00703     qboolean    r;
00704     char    base[MAX_STRING_CHARS];
00705     char    *port;
00706 
00707     if (!strcmp (s, "localhost")) {
00708         Com_Memset (a, 0, sizeof(*a));
00709         a->type = NA_LOOPBACK;
00710         return qtrue;
00711     }
00712 
00713     // look for a port number
00714     Q_strncpyz( base, s, sizeof( base ) );
00715     port = strstr( base, ":" );
00716     if ( port ) {
00717         *port = 0;
00718         port++;
00719     }
00720 
00721     r = Sys_StringToAdr( base, a );
00722 
00723     if ( !r ) {
00724         a->type = NA_BAD;
00725         return qfalse;
00726     }
00727 
00728     // inet_addr returns this if out of range
00729     if ( a->ip[0] == 255 && a->ip[1] == 255 && a->ip[2] == 255 && a->ip[3] == 255 ) {
00730         a->type = NA_BAD;
00731         return qfalse;
00732     }
00733 
00734     if ( port ) {
00735         a->port = BigShort( (short)atoi( port ) );
00736     } else {
00737         a->port = BigShort( PORT_SERVER );
00738     }
00739 
00740     return qtrue;
00741 }

Here is the call graph for this function:

void Netchan_Init int  port  ) 
 

Definition at line 72 of file net_chan.c.

References Cvar_Get(), CVAR_INIT, CVAR_TEMP, qport, showdrop, showpackets, and va().

Referenced by Com_Init().

00072                               {
00073     port &= 0xffff;
00074     showpackets = Cvar_Get ("showpackets", "0", CVAR_TEMP );
00075     showdrop = Cvar_Get ("showdrop", "0", CVAR_TEMP );
00076     qport = Cvar_Get ("net_qport", va("%i", port), CVAR_INIT );
00077 }

Here is the call graph for this function:

qboolean Netchan_Process netchan_t chan,
msg_t msg
 

Definition at line 304 of file net_chan.c.

References msg_t::bit, Com_Memcpy(), Com_Printf(), msg_t::cursize, msg_t::data, netchan_t::dropped, netchan_t::fragmentBuffer, netchan_t::fragmentLength, netchan_t::fragmentSequence, netchan_t::incomingSequence, cvar_s::integer, LittleLong(), msg_t::maxsize, MSG_BeginReadingOOB(), MSG_ReadLong(), MSG_ReadShort(), NET_AdrToString(), netsrcString, qboolean, qport, msg_t::readcount, netchan_t::remoteAddress, showdrop, showpackets, and netchan_t::sock.

Referenced by CL_Netchan_Process(), and SV_Netchan_Process().

00304                                                         {
00305     int         sequence;
00306     int         qport;
00307     int         fragmentStart, fragmentLength;
00308     qboolean    fragmented;
00309 
00310     // XOR unscramble all data in the packet after the header
00311 //  Netchan_UnScramblePacket( msg );
00312 
00313     // get sequence numbers     
00314     MSG_BeginReadingOOB( msg );
00315     sequence = MSG_ReadLong( msg );
00316 
00317     // check for fragment information
00318     if ( sequence & FRAGMENT_BIT ) {
00319         sequence &= ~FRAGMENT_BIT;
00320         fragmented = qtrue;
00321     } else {
00322         fragmented = qfalse;
00323     }
00324 
00325     // read the qport if we are a server
00326     if ( chan->sock == NS_SERVER ) {
00327         qport = MSG_ReadShort( msg );
00328     }
00329 
00330     // read the fragment information
00331     if ( fragmented ) {
00332         fragmentStart = MSG_ReadShort( msg );
00333         fragmentLength = MSG_ReadShort( msg );
00334     } else {
00335         fragmentStart = 0;      // stop warning message
00336         fragmentLength = 0;
00337     }
00338 
00339     if ( showpackets->integer ) {
00340         if ( fragmented ) {
00341             Com_Printf( "%s recv %4i : s=%i fragment=%i,%i\n"
00342                 , netsrcString[ chan->sock ]
00343                 , msg->cursize
00344                 , sequence
00345                 , fragmentStart, fragmentLength );
00346         } else {
00347             Com_Printf( "%s recv %4i : s=%i\n"
00348                 , netsrcString[ chan->sock ]
00349                 , msg->cursize
00350                 , sequence );
00351         }
00352     }
00353 
00354     //
00355     // discard out of order or duplicated packets
00356     //
00357     if ( sequence <= chan->incomingSequence ) {
00358         if ( showdrop->integer || showpackets->integer ) {
00359             Com_Printf( "%s:Out of order packet %i at %i\n"
00360                 , NET_AdrToString( chan->remoteAddress )
00361                 ,  sequence
00362                 , chan->incomingSequence );
00363         }
00364         return qfalse;
00365     }
00366 
00367     //
00368     // dropped packets don't keep the message from being used
00369     //
00370     chan->dropped = sequence - (chan->incomingSequence+1);
00371     if ( chan->dropped > 0 ) {
00372         if ( showdrop->integer || showpackets->integer ) {
00373             Com_Printf( "%s:Dropped %i packets at %i\n"
00374             , NET_AdrToString( chan->remoteAddress )
00375             , chan->dropped
00376             , sequence );
00377         }
00378     }
00379     
00380 
00381     //
00382     // if this is the final framgent of a reliable message,
00383     // bump incoming_reliable_sequence 
00384     //
00385     if ( fragmented ) {
00386         // TTimo
00387         // make sure we add the fragments in correct order
00388         // either a packet was dropped, or we received this one too soon
00389         // we don't reconstruct the fragments. we will wait till this fragment gets to us again
00390         // (NOTE: we could probably try to rebuild by out of order chunks if needed)
00391         if ( sequence != chan->fragmentSequence ) {
00392             chan->fragmentSequence = sequence;
00393             chan->fragmentLength = 0;
00394         }
00395 
00396         // if we missed a fragment, dump the message
00397         if ( fragmentStart != chan->fragmentLength ) {
00398             if ( showdrop->integer || showpackets->integer ) {
00399                 Com_Printf( "%s:Dropped a message fragment\n"
00400                 , NET_AdrToString( chan->remoteAddress )
00401                 , sequence);
00402             }
00403             // we can still keep the part that we have so far,
00404             // so we don't need to clear chan->fragmentLength
00405             return qfalse;
00406         }
00407 
00408         // copy the fragment to the fragment buffer
00409         if ( fragmentLength < 0 || msg->readcount + fragmentLength > msg->cursize ||
00410             chan->fragmentLength + fragmentLength > sizeof( chan->fragmentBuffer ) ) {
00411             if ( showdrop->integer || showpackets->integer ) {
00412                 Com_Printf ("%s:illegal fragment length\n"
00413                 , NET_AdrToString (chan->remoteAddress ) );
00414             }
00415             return qfalse;
00416         }
00417 
00418         Com_Memcpy( chan->fragmentBuffer + chan->fragmentLength, 
00419             msg->data + msg->readcount, fragmentLength );
00420 
00421         chan->fragmentLength += fragmentLength;
00422 
00423         // if this wasn't the last fragment, don't process anything
00424         if ( fragmentLength == FRAGMENT_SIZE ) {
00425             return qfalse;
00426         }
00427 
00428         if ( chan->fragmentLength > msg->maxsize ) {
00429             Com_Printf( "%s:fragmentLength %i > msg->maxsize\n"
00430                 , NET_AdrToString (chan->remoteAddress ),
00431                 chan->fragmentLength );
00432             return qfalse;
00433         }
00434 
00435         // copy the full message over the partial fragment
00436 
00437         // make sure the sequence number is still there
00438         *(int *)msg->data = LittleLong( sequence );
00439 
00440         Com_Memcpy( msg->data + 4, chan->fragmentBuffer, chan->fragmentLength );
00441         msg->cursize = chan->fragmentLength + 4;
00442         chan->fragmentLength = 0;
00443         msg->readcount = 4; // past the sequence number
00444         msg->bit = 32;  // past the sequence number
00445 
00446         // TTimo
00447         // clients were not acking fragmented messages
00448         chan->incomingSequence = sequence;
00449         
00450         return qtrue;
00451     }
00452 
00453     //
00454     // the message can now be read from the current message pointer
00455     //
00456     chan->incomingSequence = sequence;
00457 
00458     return qtrue;
00459 }

Here is the call graph for this function:

void Netchan_Setup netsrc_t  sock,
netchan_t chan,
netadr_t  adr,
int  qport
 

Definition at line 86 of file net_chan.c.

References Com_Memset().

Referenced by CL_ConnectionlessPacket(), and SV_DirectConnect().

00086                                                                               {
00087     Com_Memset (chan, 0, sizeof(*chan));
00088     
00089     chan->sock = sock;
00090     chan->remoteAddress = adr;
00091     chan->qport = qport;
00092     chan->incomingSequence = 0;
00093     chan->outgoingSequence = 1;
00094 }

Here is the call graph for this function:

void Netchan_Transmit netchan_t chan,
int  length,
const byte data
 

Definition at line 246 of file net_chan.c.

References byte, Com_Error(), Com_Memcpy(), Com_Printf(), msg_t::cursize, data, msg_t::data, ERR_DROP, netchan_t::incomingSequence, cvar_s::integer, length(), MSG_InitOOB(), MSG_WriteData(), MSG_WriteLong(), MSG_WriteShort(), NET_SendPacket(), Netchan_TransmitNextFragment(), netsrcString, netchan_t::outgoingSequence, qport, netchan_t::remoteAddress, showpackets, netchan_t::sock, netchan_t::unsentBuffer, netchan_t::unsentFragments, netchan_t::unsentFragmentStart, and netchan_t::unsentLength.

Referenced by CL_Netchan_Transmit(), SV_Netchan_Transmit(), and SV_Netchan_TransmitNextFragment().

00246                                                                        {
00247     msg_t       send;
00248     byte        send_buf[MAX_PACKETLEN];
00249 
00250     if ( length > MAX_MSGLEN ) {
00251         Com_Error( ERR_DROP, "Netchan_Transmit: length = %i", length );
00252     }
00253     chan->unsentFragmentStart = 0;
00254 
00255     // fragment large reliable messages
00256     if ( length >= FRAGMENT_SIZE ) {
00257         chan->unsentFragments = qtrue;
00258         chan->unsentLength = length;
00259         Com_Memcpy( chan->unsentBuffer, data, length );
00260 
00261         // only send the first fragment now
00262         Netchan_TransmitNextFragment( chan );
00263 
00264         return;
00265     }
00266 
00267     // write the packet header
00268     MSG_InitOOB (&send, send_buf, sizeof(send_buf));
00269 
00270     MSG_WriteLong( &send, chan->outgoingSequence );
00271     chan->outgoingSequence++;
00272 
00273     // send the qport if we are a client
00274     if ( chan->sock == NS_CLIENT ) {
00275         MSG_WriteShort( &send, qport->integer );
00276     }
00277 
00278     MSG_WriteData( &send, data, length );
00279 
00280     // send the datagram
00281     NET_SendPacket( chan->sock, send.cursize, send.data, chan->remoteAddress );
00282 
00283     if ( showpackets->integer ) {
00284         Com_Printf( "%s send %4i : s=%i ack=%i\n"
00285             , netsrcString[ chan->sock ]
00286             , send.cursize
00287             , chan->outgoingSequence - 1
00288             , chan->incomingSequence );
00289     }
00290 }

Here is the call graph for this function:

void Netchan_TransmitNextFragment netchan_t chan  ) 
 

Definition at line 189 of file net_chan.c.

References byte, Com_Printf(), msg_t::cursize, msg_t::data, FRAGMENT_BIT, cvar_s::integer, MSG_InitOOB(), MSG_WriteData(), MSG_WriteLong(), MSG_WriteShort(), NET_SendPacket(), netsrcString, netchan_t::outgoingSequence, qport, netchan_t::remoteAddress, showpackets, netchan_t::sock, netchan_t::unsentBuffer, netchan_t::unsentFragments, netchan_t::unsentFragmentStart, and netchan_t::unsentLength.

Referenced by CL_Netchan_TransmitNextFragment(), Netchan_Transmit(), SV_Netchan_Transmit(), and SV_Netchan_TransmitNextFragment().

00189                                                      {
00190     msg_t       send;
00191     byte        send_buf[MAX_PACKETLEN];
00192     int         fragmentLength;
00193 
00194     // write the packet header
00195     MSG_InitOOB (&send, send_buf, sizeof(send_buf));                // <-- only do the oob here
00196 
00197     MSG_WriteLong( &send, chan->outgoingSequence | FRAGMENT_BIT );
00198 
00199     // send the qport if we are a client
00200     if ( chan->sock == NS_CLIENT ) {
00201         MSG_WriteShort( &send, qport->integer );
00202     }
00203 
00204     // copy the reliable message to the packet first
00205     fragmentLength = FRAGMENT_SIZE;
00206     if ( chan->unsentFragmentStart  + fragmentLength > chan->unsentLength ) {
00207         fragmentLength = chan->unsentLength - chan->unsentFragmentStart;
00208     }
00209 
00210     MSG_WriteShort( &send, chan->unsentFragmentStart );
00211     MSG_WriteShort( &send, fragmentLength );
00212     MSG_WriteData( &send, chan->unsentBuffer + chan->unsentFragmentStart, fragmentLength );
00213 
00214     // send the datagram
00215     NET_SendPacket( chan->sock, send.cursize, send.data, chan->remoteAddress );
00216 
00217     if ( showpackets->integer ) {
00218         Com_Printf ("%s send %4i : s=%i fragment=%i,%i\n"
00219             , netsrcString[ chan->sock ]
00220             , send.cursize
00221             , chan->outgoingSequence
00222             , chan->unsentFragmentStart, fragmentLength);
00223     }
00224 
00225     chan->unsentFragmentStart += fragmentLength;
00226 
00227     // this exit condition is a little tricky, because a packet
00228     // that is exactly the fragment length still needs to send
00229     // a second packet of zero length so that the other side
00230     // can tell there aren't more to follow
00231     if ( chan->unsentFragmentStart == chan->unsentLength && fragmentLength != FRAGMENT_SIZE ) {
00232         chan->outgoingSequence++;
00233         chan->unsentFragments = qfalse;
00234     }
00235 }

Here is the call graph for this function:


Variable Documentation

loopback_t loopbacks[2]
 

Definition at line 574 of file net_chan.c.

Referenced by NET_GetLoopPacket(), and NET_SendLoopPacket().

char* netsrcString[2] [static]
 

Initial value:

 {
    "client",
    "server"
}

Definition at line 61 of file net_chan.c.

Referenced by Netchan_Process(), Netchan_Transmit(), and Netchan_TransmitNextFragment().

cvar_t* qport
 

Definition at line 59 of file net_chan.c.

Referenced by Netchan_Init(), Netchan_Process(), Netchan_Transmit(), Netchan_TransmitNextFragment(), SV_DirectConnect(), and SV_PacketEvent().

cvar_t* showdrop
 

Definition at line 58 of file net_chan.c.

Referenced by Netchan_Init(), and Netchan_Process().

cvar_t* showpackets
 

Definition at line 57 of file net_chan.c.

Referenced by NET_SendPacket(), Netchan_Init(), Netchan_Process(), Netchan_Transmit(), and Netchan_TransmitNextFragment().


Generated on Thu Aug 25 14:44:01 2005 for Quake III Arena by  doxygen 1.3.9.1