📄 tcp2.c
字号:
/*********************************************************************
* Function: static TCP_SOCKET FindMatchingSocket(TCP_HEADER *h,
* NODE_INFO* remote)
*
* PreCondition: TCPInit() is already called
*
* Input: h - TCP Header to be matched against.
* remote - Node who sent this header.
*
* Output: A socket that matches with given header and remote
* node is searched.
* If such socket is found, its index is returned
* else INVALID_SOCKET is returned.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
static TCP_SOCKET FindMatchingSocket(TCP_HEADER *h, NODE_INFO *remote)
{
SOCKET_INFO *ps;
TCP_SOCKET s;
TCP_SOCKET partialMatch;
partialMatch = INVALID_SOCKET;
for ( s = 0; s < MAX_SOCKETS; s++ )
{
ps = &TCB[s];
//putrsUSART("PORT FIND\n");
if ( ps->smState != TCP_CLOSED )
{
if ( ps->localPort == h->DestPort )
{
//putrsUSART("PORT Match\n");
if ( ps->smState == TCP_LISTEN )
partialMatch = s;
if ( ps->remotePort == h->SourcePort &&
ps->remote.IPAddr.Val == remote->IPAddr.Val )
{
return s;
}
}
}
}
ps = &TCB[partialMatch];
if ( partialMatch != INVALID_SOCKET &&
ps->smState == TCP_LISTEN )
{
memcpy((void*)&ps->remote, (void*)remote, sizeof(*remote));
//ps->remote = *remote;
ps->localPort = h->DestPort;
ps->remotePort = h->SourcePort;
ps->Flags.bIsGetReady = FALSE;
ps->TxBuffer = INVALID_BUFFER;
ps->Flags.bIsPutReady = TRUE;
//putrsUSART("TCP Match\n");
return partialMatch;
}
if ( partialMatch == INVALID_SOCKET )
return UNKNOWN_SOCKET;
else
return INVALID_SOCKET;
}
/*********************************************************************
* Function: static void SwapTCPHeader(TCP_HEADER* header)
*
* PreCondition: None
*
* Input: header - TCP Header to be swapped.
*
* Output: Given header is swapped.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
static void SwapTCPHeader(TCP_HEADER* header)
{
header->SourcePort = swaps(header->SourcePort);
header->DestPort = swaps(header->DestPort);
header->SeqNumber = swapl(header->SeqNumber);
header->AckNumber = swapl(header->AckNumber);
header->Window = swaps(header->Window);
header->Checksum = swaps(header->Checksum);
header->UrgentPointer = swaps(header->UrgentPointer);
}
/*********************************************************************
* Function: static void CloseSocket(SOCKET_INFO* ps)
*
* PreCondition: TCPInit() is already called
*
* Input: ps - Pointer to a socket info that is to be
* closed.
*
* Output: Given socket information is reset and any
* buffer held by this socket is discarded.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
/*static*/extern void CloseSocket(SOCKET_INFO* ps)
{
if ( ps->TxBuffer != INVALID_BUFFER )
{
MACDiscardTx(ps->TxBuffer);
ps->TxBuffer = INVALID_BUFFER;
ps->Flags.bIsPutReady = TRUE;
}
ps->remote.IPAddr.Val = 0x00;
ps->remotePort = 0x00;
if ( ps->Flags.bIsGetReady )
{
MACDiscardRx();
}
ps->Flags.bIsGetReady = FALSE;
// ps->TimeOut = TCP_START_TIMEOUT_VAL;
ps->Flags.bIsTxInProgress = FALSE;
if ( ps->Flags.bServer )
ps->smState = TCP_LISTEN;
else
ps->smState = TCP_CLOSED;
return;
}
/*********************************************************************
* Function: static void HandleTCPSeg(TCP_SOCKET s,
* NODE_INFO *remote,
* TCP_HEADER* h,
* WORD len)
*
* PreCondition: TCPInit() is already called AND
* TCPProcess() is the caller.
*
* Input: s - Socket that owns this segment
* remote - Remote node info
* h - TCP Header
* len - Total buffer length.
*
* Output: TCP FSM is executed on given socket with
* given TCP segment.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
static void HandleTCPSeg(TCP_SOCKET s,
NODE_INFO *remote,
TCP_HEADER *h,
WORD len)
{
DWORD ack;
DWORD seq;
DWORD prevAck, prevSeq;
SOCKET_INFO *ps;
BYTE flags;
flags = 0x00;
ps = &TCB[s];
/*
* Remember current seq and ack for our connection so that if
* we have to silently discard this packet, we can go back to
* previous ack and seq numbers.
*/
prevAck = ps->SND_ACK; //
prevSeq = ps->SND_SEQ; //
ack = h->SeqNumber ; //取出受到的TCP包的序列号
ack += (DWORD)len; //计算确认号(此次确认号=序列号+数据长度)
seq = ps->SND_SEQ; //??????????????
/*
* Clear retry counts and timeout tick counter.
* 设定差错控制
*/
ps->RetryCount = 0;
ps->startTick = TickGet();
ps->TimeOut = TCP_START_TIMEOUT_VAL;
if ( ps->smState == TCP_LISTEN ) //如果处于TCP_LISTEN状态,那么需要被动打开
{
MACDiscardRx();
ps->SND_SEQ = ++ISS;
ps->SND_ACK = ++ack;
seq = ps->SND_SEQ;
++ps->SND_SEQ;
if ( h->Flags.bits.flagSYN ) //收到SYN包,发送SYN+ACK,进入SYN_RECVD,等待ACK
{
/*
* This socket has received connection request.
* Remember calling node, assign next segment seq. number
* for this potential connection.
*/
memcpy((void*)&ps->remote, (const void*)remote, sizeof(*remote));
ps->remotePort = h->SourcePort;
/*
* Grant connection request.
*/
flags = SYN | ACK;
ps->smState = TCP_SYN_RCVD;
//putrsUSART("TCP LISTEN\n");
}
else
{
/*
* Anything other than connection request is ignored in
* LISTEN state.
*/
flags = RST;
seq = ack;
ack = h->SeqNumber;
ps->remote.IPAddr.Val = 0x00;
//putrsUSART("TCPRST\n");
}
}
else //如果当前TCP不是处于LISTEN状态
{
/*
* Reset FSM, if RST is received.
*/
if ( h->Flags.bits.flagRST ) //收到的flagRST,TCP复位
{
MACDiscardRx();
CloseSocket(ps);
//putrsUSART("CLOSEsocket\n");
return;
}
else if ( seq == h->AckNumber ) //收到的ACK等于将要发送的TCP包的seq
//本地发送的ACK是对远端seq的响应
//远端发送的ACK是对本地seq的响应
{
if ( ps->smState == TCP_SYN_RCVD ) //如果处于TCP_SYN_RCVD状态
{
if ( h->Flags.bits.flagACK ) //处于TCP_SYN_RCVD状态时收到ACK包
{
ps->SND_ACK = ack; //本地Socket将要发送的ACK值=本地收到的seq+收到的数据长度
ps->RetryCount = 0;
ps->startTick = TickGet();
ps->smState = TCP_EST; //状态机切换到“连接建立”状态
//putrsUSART("TCP EST\n");
if ( len > 0 )
{
ps->Flags.bIsGetReady = TRUE; //本地数据准备好
ps->RxCount = len;
ps->Flags.bFirstRead = TRUE;
}
else
MACDiscardRx();
}
else //处于TCP_SYN_RCVD状态时,如果收到非ACK包,
//那么,将接收到的包丢弃
{
MACDiscardRx();
}
}
else if ( ps->smState == TCP_SYN_SENT ) //如果本地SOCKET处于TCP_SYN_SENT状态
{
if ( h->Flags.bits.flagSYN ) //同时收到的包是同步包
{
ps->SND_ACK = ++ack; //将要发送的TCP包的ACK
if ( h->Flags.bits.flagACK ) //此包既是同步包又是ACK包
{
flags = ACK;
ps->smState = TCP_EST; //转为建立状态
//putrsUSART("TCP EST\n");
}
else
{
flags = SYN | ACK;
ps->smState = TCP_SYN_RCVD; //只收到SYN包,也转为SYN_RCVD状态
ps->SND_SEQ = ++seq;
//putrsUSART("TCPSYNRCVD\n");
}
if ( len > 0 )
{
ps->Flags.bIsGetReady = TRUE;
ps->RxCount = len;
ps->Flags.bFirstRead = TRUE;
}
else
MACDiscardRx();
}
else
{
MACDiscardRx();
}
}
else
{
if ( h->SeqNumber != ps->SND_ACK )
{
// Discard buffer.
MACDiscardRx();
return;
}
ps->SND_ACK = ack; //本地Socket将要发送的ACK值=本地收到的seq+收到的数据长度
if ( ps->smState == TCP_EST ) //如果SOCKET处于“建立状态“
{
if ( h->Flags.bits.flagACK ) //收到ACK包
{
if ( ps->TxBuffer != INVALID_BUFFER ) //#define INVALID_BUFFER (0xff)
{
MACDiscardTx(ps->TxBuffer);
ps->TxBuffer = INVALID_BUFFER;
ps->Flags.bIsPutReady = TRUE;
}
//putrsUSART("TCP ESTACK\n");
}
if ( h->Flags.bits.flagFIN )
{
flags = FIN | ACK;
seq = ps->SND_SEQ++;
ack = ++ps->SND_ACK;
if(h->Flags.bits.flagACK )
{
CloseSocket(ps);
}
else
{
ps->smState = TCP_LAST_ACK;
}
//putrsUSART("TCPLASTACK\n");
}
if ( len > 0 )
{
if ( !ps->Flags.bIsGetReady )
{
ps->Flags.bIsGetReady = TRUE;
ps->RxCount = len;
ps->Flags.bFirstRead = TRUE;
// 4/1/02
flags = ACK;
}
else
{
/*
* Since we cannot accept this packet,
* restore to previous seq and ack.
* and do not send anything back.
* Host has to resend this packet when
* we are ready.
*/
flags = 0x00;
ps->SND_SEQ = prevSeq;
ps->SND_ACK = prevAck;
MACDiscardRx();
}
}
else
{
MACDiscardRx();
}
}
else if ( ps->smState == TCP_LAST_ACK ) //只等待最后一个ACK,不接收别的包
{
MACDiscardRx(); //包已经读进来了,把缓存中的包丢弃
//putrsUSART("TCPLASKCLOSE\n");
if ( h->Flags.bits.flagACK ) //等到了ACK,关闭SOCKET
{
CloseSocket(ps);
}
}
else if ( ps->smState == TCP_FIN_WAIT_1 )
{
MACDiscardRx();
//putrsUSART("TCP FIN\n");
if ( h->Flags.bits.flagFIN )
{
flags = ACK;
ack = ++ps->SND_ACK;
if ( h->Flags.bits.flagACK )
{
CloseSocket(ps);
//putrsUSART("end\n");
}
else
{
ps->smState = TCP_CLOSING;
}
}
}
else if ( ps->smState == TCP_CLOSING ) //TCP_CLOSING状态,也只是等待一个ACK
{
MACDiscardRx();
//putrsUSART("TCP CLOSING\n");
if ( h->Flags.bits.flagACK )
{
CloseSocket(ps);
}
}
}
}
else
{
MACDiscardRx();
}
}
if ( flags > 0x00 )
{ //putrsUSART("SENTTCP\n");
SendTCP(remote,
h->DestPort,
h->SourcePort,
seq,
ack,
flags);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -