📄 tcp.c
字号:
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// TCP.C
//
// TCP General Functions
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include "tcp.h"
// Private and Public Globals
UINT32 tcp_iss = 0x7F000000; // Initial send sequence
UINT32 tcp_now = 0; // current TCP time (in 500mS ticks)
TCPSTATS tcps; // Stats
TCPPROT *ptTimeFirst = 0; // Pointer to first time-out candidate
PSEUDO tpseudo; // Pseudo header for checksum
static void TcpTimeoutCheck();
//--------------------------------------------------------------------
// TcpMsg()
//
// Services Intialization and Resource Messages
//--------------------------------------------------------------------
void TcpMsg( uint Msg )
{
static HANDLE hTimer;
switch( Msg )
{
// System Initialization
case MSG_EXEC_SYSTEM_INIT:
// Initialize TCP Timer
hTimer = TimerNew( &TcpMsg, 1, MSG_TCP_TIMER );
// Initialize Stats
mmZeroInit( &tcps, sizeof( TCPSTATS ) );
// We Init ICMP/UDP/RAW stats here since they do not
// require their own MSG routine
mmZeroInit( _dwICMPIn, sizeof( UINT32 ) * (ICMP_MAXTYPE+1) );
mmZeroInit( _dwICMPOut, sizeof( UINT32 ) * (ICMP_MAXTYPE+1) );
mmZeroInit( &udps, sizeof( UDPSTATS ) );
mmZeroInit( &raws, sizeof( RAWSTATS ) );
break;
// System Shutdown
case MSG_EXEC_SYSTEM_SHUTDOWN:
// Continue shutdown
if( hTimer )
TimerFree( hTimer );
break;
// Low Resoruces
case MSG_EXEC_LOW_RESOURCES:
break;
// Half Second Timer
case MSG_TCP_TIMER:
TcpTimeoutCheck();
break;
}
}
//--------------------------------------------------------------------
// void TcpChecksum( TCPHDR *pbHdr )
//
// Checksums the TCP header
//--------------------------------------------------------------------
void TcpChecksum( TCPHDR *pTcpHdr )
{
int tmp1;
UINT16 *pw;
UINT32 dwTSum;
// Get header size in bytes
tmp1 = (int)HNC16(tpseudo.Length);
// Checksum field is NULL in checksum calculations
pTcpHdr->TCPChecksum = 0;
// Checksum the header
pw = (UINT16 *)pTcpHdr;
dwTSum = 0;
for( ; tmp1 > 1; tmp1 -= 2 )
dwTSum += (UINT32)*pw++;
if( tmp1 )
dwTSum += (UINT32)(*pw & 0xFF);
// Checksum the pseudo header
pw = (UINT16 *)&tpseudo;
for( tmp1=0; tmp1 < 6; tmp1++ )
dwTSum += (UINT32)*pw++;
dwTSum = (dwTSum&0xFFFF) + (dwTSum>>16);
dwTSum = (dwTSum&0xFFFF) + (dwTSum>>16);
dwTSum = ~dwTSum;
// Note checksum is Net/Host byte order independent
pTcpHdr->TCPChecksum = (UINT16)dwTSum;
}
//--------------------------------------------------------------------
// TCP Timeout Functions
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// TcpTimeoutAdd
//
// Add TCP object to timeout canditate list
//--------------------------------------------------------------------
void TcpTimeoutAdd( TCPPROT *pt )
{
// Easiest to always insert at head of list
pt->pPrev = 0;
pt->pNext = ptTimeFirst;
if( ptTimeFirst )
ptTimeFirst->pPrev = pt;
ptTimeFirst = pt;
}
//--------------------------------------------------------------------
// TcpTimeoutRemove
//
// Remove TCP object from timeout canditate list
//--------------------------------------------------------------------
void TcpTimeoutRemove( TCPPROT *pt )
{
// Patch preceeding entry
if( !pt->pPrev )
ptTimeFirst = pt->pNext;
else
pt->pPrev->pNext = pt->pNext;
// Patch following entry
if( pt->pNext )
pt->pNext->pPrev = pt->pPrev;
}
//--------------------------------------------------------------------
// TcpTimeoutCheck
//
// Scan timeout list for TCP timeouts
//--------------------------------------------------------------------
static void TcpTimeoutCheck()
{
TCPPROT *pt;
TCPPROT **ppt;
ppt = &ptTimeFirst;
while( *ppt )
{
pt = *ppt;
//
// Check all timers. If pt goes away by calling the timeout
// function, then move on to the next one.
//
if( pt->dwTicksRexmt && !--pt->dwTicksRexmt )
{
TcpTimeoutRexmt( pt );
if( *ppt != pt )
continue;
}
if( pt->dwTicksPersist && !--pt->dwTicksPersist )
{
TcpTimeoutPersist( pt );
if( *ppt != pt )
continue;
}
if( pt->dwTicksKeep && !--pt->dwTicksKeep )
{
TcpTimeoutKeep( pt );
if( *ppt != pt )
continue;
}
if( pt->dwTicksWait2 && !--pt->dwTicksWait2 )
{
TcpTimeoutWait2( pt );
if( *ppt != pt )
continue;
}
// Perform any delayed ACK
if( pt->t_flags & TF_DELACK )
{
pt->t_flags &= ~TF_DELACK;
pt->t_flags |= TF_ACKNOW;
tcps.dwDelAck++;
TcpOutput(pt);
}
else if( pt->t_flags & TF_NEEDOUTPUT )
TcpOutput(pt);
// Bump Idle time
pt->t_tidle++;
// Bump RTT counter if active
if( pt->t_trtt )
pt->t_trtt++;
// Move on to next block
ppt = &pt->pNext;
}
// Bump TCP start sequence
tcp_iss += TCP_ISSINCR/2;
// Bump TCP time
tcp_now++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -