⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.c

📁 本附件为嵌入式Web的相关资料
💻 C
📖 第 1 页 / 共 4 页
字号:
	ps->Flags.bTimerEnabled = FALSE;
	ps->remoteHash.Val = MyTCB.localPort.Val;
	ps->txTail = ps->bufferTxStart;
	ps->txHead = ps->bufferTxStart;
	ps->rxTail = ps->bufferRxStart;
	ps->rxHead = ps->bufferRxStart;
	MyTCB.txUnackedTail = ps->bufferTxStart;
	((DWORD_VAL*)(&MyTCB.MySEQ))->w[0] = rand();
	((DWORD_VAL*)(&MyTCB.MySEQ))->w[1] = rand();
}



/*********************************************************************
* Function:        static void HandleTCPSeg(TCP_SOCKET s,
*                                      		TCP_HEADER* h,
*                                      		WORD len)
*
* PreCondition:    TCPInit() is already called     AND
*                  TCPProcess() is the caller.
*
* Input:           hTCP        - Socket that owns this segment
*                  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 hTCP,
						 TCP_HEADER *h,
						 WORD len)
{
	DWORD dwTemp;
	WORD wTemp;
	TCB_STUB *ps;
	BYTE flags;

	ps = &TCBStubs[hTCP];
	flags = 0x00;


	// Reset FSM, if RST is received.
	if(h->Flags.bits.flagRST)
	{
		SendTCP(hTCP, RST);
		CloseSocket(hTCP);
		MACDiscardRx();
		return;
	}
	
	if ( h->SeqNumber == 751 )
		h->SeqNumber = 751;

	// Update the local stored copy of the RemoteWindow
	MyTCB.remoteWindow = h->Window;


	switch(ps->smState)
	{
		case TCP_LISTEN:
			if(!h->Flags.bits.flagSYN)
			{
				SendTCP(hTCP, RST);
				CloseSocket(hTCP);
				break;
			}
			
			flags = SYN | ACK;
			ps->smState = TCP_SYN_RECEIVED;

			// Clear timeout info
			MyTCB.retryCount = 0;
			MyTCB.retryInterval = TCP_START_TIMEOUT_VAL;
			ps->eventTime = TickGet() + TCP_START_TIMEOUT_VAL;
			ps->Flags.bTimerEnabled = TRUE;

			// We now have a sequence number for the remote node
			MyTCB.RemoteSEQ = h->SeqNumber + 1;

			break;

		case TCP_SYN_SENT:
			if(!h->Flags.bits.flagSYN)
				break;

			if(h->Flags.bits.flagACK)
			{
				// If SYN+ACK, we may need to go to TCP_ESTABLISHED state
				if(h->AckNumber == MyTCB.MySEQ)
				{
					flags = ACK;
					ps->smState = TCP_ESTABLISHED;
					ps->Flags.bTimerEnabled = FALSE;

					// Check for application data and make it 
					// available, if present
					if(len)
					{
						dwTemp = MyTCB.RemoteSEQ - h->SeqNumber;
						if(((LONG)dwTemp >= 0) && ((LONG)((DWORD)len - dwTemp) > 0))
						{
							len -= (WORD)dwTemp;

							// Calculate the lesser of RX buffer space and new packet data length
							if(ps->rxHead >= ps->rxTail)
								wTemp = (ps->bufferEnd - ps->bufferRxStart) - (ps->rxHead - ps->rxTail);
							else
								wTemp = ps->rxTail - ps->rxHead - 1;
						
							if(wTemp < len)
								len = wTemp;
							
							if(len)
							{
								// Position packet read pointer to start of useful data area.
								IPSetRxBuffer((h->DataOffset.Val << 2) + (WORD)dwTemp);

								flags |= ACK;					
								// See if we need a two part copy (spans bufferEnd->bufferRxStart)
								if(ps->rxHead + len > ps->bufferEnd)
								{
									wTemp = ps->bufferEnd - ps->rxHead + 1;
									MACMemCopyAsync(ps->rxHead, -1, wTemp);
									len -= wTemp;
									MyTCB.RemoteSEQ += wTemp;
									ps->rxHead = ps->bufferRxStart;
								}
							
								MACMemCopyAsync(ps->rxHead, -1, len);
								ps->rxHead += len;
								MyTCB.RemoteSEQ += (DWORD)len;
							}
						}
					}
				}
				else
				{
					// ACK number incorrect: ignore this packet
					flags = RST;
					break;
				}
			}
			else
			{
				// Got SYN without ACK, need to go to TCP_SYN_RECEIVED state
				flags = SYN | ACK;
				ps->smState = TCP_SYN_RECEIVED;

				// Clear timeout info
				MyTCB.retryCount  = 0;
				MyTCB.retryInterval = TCP_START_TIMEOUT_VAL;
				ps->eventTime = TickGet() + TCP_START_TIMEOUT_VAL;
			}

			// We now have a sequence number for the remote node
			MyTCB.RemoteSEQ = h->SeqNumber + 1;

			break;

		case TCP_SYN_RECEIVED:
			if(h->Flags.bits.flagACK && (h->AckNumber == MyTCB.MySEQ))
			{
				ps->smState = TCP_ESTABLISHED;
				ps->Flags.bTimerEnabled = FALSE;

				// Check for application data and make it 
				// available, if present
				if(len)
				{
					dwTemp = MyTCB.RemoteSEQ - h->SeqNumber;
					if(((LONG)dwTemp >= 0) && ((LONG)((DWORD)len - dwTemp) > 0))
					{
						len -= (WORD)dwTemp;
	
						// Calculate the lesser of RX buffer space and new packet data length
						if(ps->rxHead >= ps->rxTail)
							wTemp = (ps->bufferEnd - ps->bufferRxStart) - (ps->rxHead - ps->rxTail);
						else
							wTemp = ps->rxTail - ps->rxHead - 1;
					
						if(wTemp < len)
							len = wTemp;
						
						if(len)
						{
							// Position packet read pointer to start of useful data area.
							IPSetRxBuffer((h->DataOffset.Val << 2) + (WORD)dwTemp);
	
							flags |= ACK;					
							// See if we need a two part copy (spans bufferEnd->bufferRxStart)
							if(ps->rxHead + len > ps->bufferEnd)
							{
								wTemp = ps->bufferEnd - ps->rxHead + 1;
								MACMemCopyAsync(ps->rxHead, -1, wTemp);
								len -= wTemp;
								MyTCB.RemoteSEQ += wTemp;
								ps->rxHead = ps->bufferRxStart;
							}
						
							MACMemCopyAsync(ps->rxHead, -1, len);
							ps->rxHead += len;
							MyTCB.RemoteSEQ += (DWORD)len;
						}
					}
				}
			}
			break;

		case TCP_ESTABLISHED:
			// Check for application data and make it 
			// available, if present
			if(len)
			{
				dwTemp = MyTCB.RemoteSEQ - h->SeqNumber;
				if(((LONG)dwTemp >= 0) && ((LONG)((DWORD)len - dwTemp) > 0))
				{
					len -= (WORD)dwTemp;

					// Calculate the lesser of RX buffer space and new packet data length
					if(ps->rxHead >= ps->rxTail)
						wTemp = (ps->bufferEnd - ps->bufferRxStart) - (ps->rxHead - ps->rxTail);
					else
						wTemp = ps->rxTail - ps->rxHead - 1;
				
					if(wTemp < len)
						len = wTemp;
					
					if(len)
					{
						// Position packet read pointer to start of useful data area.
						IPSetRxBuffer((h->DataOffset.Val << 2) + (WORD)dwTemp);

						flags |= ACK;					
						// See if we need a two part copy (spans bufferEnd->bufferRxStart)
						if(ps->rxHead + len > ps->bufferEnd)
						{
							wTemp = ps->bufferEnd - ps->rxHead + 1;
							MACMemCopyAsync(ps->rxHead, -1, wTemp);
							len -= wTemp;
							MyTCB.RemoteSEQ += wTemp;
							ps->rxHead = ps->bufferRxStart;
						}
					
						MACMemCopyAsync(ps->rxHead, -1, len);
						ps->rxHead += len;
						MyTCB.RemoteSEQ += (DWORD)len;
					}
				}
			}

			// Handle any requests to close the connection
			if(h->Flags.bits.flagFIN)
			{
				MyTCB.RemoteSEQ++;

				if(len == 0u)
				{
					flags = FIN | ACK;
					MyTCB.MySEQ++;
					ps->smState = TCP_LAST_ACK;
				}
				else
				{
					// Don't send a FIN back immediately.  The application 
					// may want to send a little bit more data before closing 
					// the socket.
					flags = ACK;
					ps->smState = TCP_CLOSE_WAIT;
				}

				// Clear timeout info
				MyTCB.retryCount  = 0;
				MyTCB.retryInterval = TCP_START_TIMEOUT_VAL;
				ps->eventTime = TickGet() + TCP_START_TIMEOUT_VAL;
				ps->Flags.bTimerEnabled = TRUE;
			}

			break;

		case TCP_FIN_WAIT_1:
			if(h->Flags.bits.flagFIN && h->Flags.bits.flagACK && (h->AckNumber == MyTCB.MySEQ))
			{
				MyTCB.RemoteSEQ++;
				flags = ACK;
				ps->smState = TCP_TIME_WAIT;
				ps->eventTime = TickGet() + TCP_TIME_WAIT_TIMEOUT_VAL;
			}
			else if(h->Flags.bits.flagACK && (h->AckNumber == MyTCB.MySEQ))
			{
				ps->smState = TCP_FIN_WAIT_2;
			}
			else if(h->Flags.bits.flagFIN)
			{
				MyTCB.RemoteSEQ++;
				flags = ACK;
				ps->smState = TCP_CLOSING;

				// Clear timeout info
				MyTCB.retryCount  = 0;
				MyTCB.retryInterval = TCP_START_TIMEOUT_VAL;
				ps->eventTime = TickGet() + TCP_START_TIMEOUT_VAL;
			}

			// Check for application data and make it 
			// available, if present
			if(len)
			{
				dwTemp = MyTCB.RemoteSEQ - h->SeqNumber;
				if(((LONG)dwTemp >= 0) && ((LONG)((DWORD)len - dwTemp) > 0))
				{
					len -= (WORD)dwTemp;
		
					// Calculate the lesser of RX buffer space and new packet data length
					if(ps->rxHead >= ps->rxTail)
						wTemp = (ps->bufferEnd - ps->bufferRxStart) - (ps->rxHead - ps->rxTail);
					else
						wTemp = ps->rxTail - ps->rxHead - 1;
				
					if(wTemp < len)
						len = wTemp;
					
					if(len)
					{
						// Position packet read pointer to start of useful data area.
						IPSetRxBuffer((h->DataOffset.Val << 2) + (WORD)dwTemp);
		
						flags |= ACK;					
						// See if we need a two part copy (spans bufferEnd->bufferRxStart)
						if(ps->rxHead + len > ps->bufferEnd)
						{
							wTemp = ps->bufferEnd - ps->rxHead + 1;
							MACMemCopyAsync(ps->rxHead, -1, wTemp);
							len -= wTemp;
							MyTCB.RemoteSEQ += wTemp;
							ps->rxHead = ps->bufferRxStart;
						}
					
						MACMemCopyAsync(ps->rxHead, -1, len);
						ps->rxHead += len;
						MyTCB.RemoteSEQ += (DWORD)len;
					}
				}
			}

			break;

		case TCP_FIN_WAIT_2:
			if(h->Flags.bits.flagFIN)
			{
				MyTCB.RemoteSEQ++;
				flags = ACK;
				ps->smState = TCP_TIME_WAIT;
				ps->eventTime = TickGet() + TCP_TIME_WAIT_TIMEOUT_VAL;
			}

			// Check for application data and make it 
			// available, if present
			if(len)
			{
				dwTemp = MyTCB.RemoteSEQ - h->SeqNumber;
				if(((LONG)dwTemp >= 0) && ((LONG)((DWORD)len - dwTemp) > 0))
				{
					len -= (WORD)dwTemp;

					// Calculate the lesser of RX buffer space and new packet data length
					if(ps->rxHead >= ps->rxTail)
						wTemp = (ps->bufferEnd - ps->bufferRxStart) - (ps->rxHead - ps->rxTail);
					else
						wTemp = ps->rxTail - ps->rxHead - 1;
				
					if(wTemp < len)
						len = wTemp;
					
					if(len)
					{
						// Position packet read pointer to start of useful data area.
						IPSetRxBuffer((h->DataOffset.Val << 2) + (WORD)dwTemp);

						flags |= ACK;					
						// See if we need a two part copy (spans bufferEnd->bufferRxStart)
						if(ps->rxHead + len > ps->bufferEnd)
						{
							wTemp = ps->bufferEnd - ps->rxHead + 1;
							MACMemCopyAsync(ps->rxHead, -1, wTemp);
							len -= wTemp;
							MyTCB.RemoteSEQ += wTemp;
							ps->rxHead = ps->bufferRxStart;
						}
					
						MACMemCopyAsync(ps->rxHead, -1, len);
						ps->rxHead += len;
						MyTCB.RemoteSEQ += (DWORD)len;
					}
				}
			}


			break;

		case TCP_CLOSING:
			if(h->Flags.bits.flagACK && (h->AckNumber == MyTCB.MySEQ))
			{
				ps->smState = TCP_TIME_WAIT;
				ps->eventTime = TickGet() + TCP_TIME_WAIT_TIMEOUT_VAL;
			}

			// Check for application data and make it 
			// available, if present
			if(len)
			{
				dwTemp = MyTCB.RemoteSEQ - h->SeqNumber;
				if(((LONG)dwTemp >= 0) && ((LONG)((DWORD)len - dwTemp) > 0))
				{
					len -= (WORD)dwTemp;

					// Calculate the lesser of RX buffer space and new packet data length
					if(ps->rxHead >= ps->rxTail)
						wTemp = (ps->bufferEnd - ps->bufferRxStart) - (ps->rxHead - ps->rxTail);
					else
						wTemp = ps->rxTail - ps->rxHead - 1;
				
					if(wTemp < len)
						len = wTemp;
					
					if(len)
					{
						// Position packet read pointer to start of useful data area.
						IPSetRxBuffer((h->DataOffset.Val << 2) + (WORD)dwTemp);

						flags |= ACK;					
						// See if we need a two part copy (spans bufferEnd->bufferRxStart)
						if(ps->rxHead + len > ps->bufferEnd)
						{
							wTemp = ps->bufferEnd - ps->rxHead + 1;
							MACMemCopyAsync(ps->rxHead, -1, wTemp);
							len -= wTemp;
							MyTCB.RemoteSEQ += wTemp;
							ps->rxHead = ps->bufferRxStart;
						}
					
						MACMemCopyAsync(ps->rxHead, -1, len);
						ps->rxHead += len;
						MyTCB.RemoteSEQ += (DWORD)len;
					}
				}
			}

			break;

		case TCP_CLOSE_WAIT:
			flags = ACK;
			break;

		case TCP_LAST_ACK:
			if(h->Flags.bits.flagACK && (h->AckNumber == MyTCB.MySEQ))
			{
				CloseSocket(hTCP);
			}
			break;

		case TCP_TIME_WAIT:
			flags = RST;
			break;
	}


	// Throw away all ACKnowledged TX data
	if(h->Flags.bits.flagACK && ps->smState != TCP_CLOSED && ps->smState != TCP_LISTEN)
	{
		// Calculate what the last acknowledged sequence number was
		dwTemp = MyTCB.MySEQ - (LONG)(SHORT)(MyTCB.txUnackedTail - ps->txTail);
		if(MyTCB.txUnackedTail < ps->txTail)
			dwTemp -= ps->bufferRxStart - ps->bufferTxStart;

		dwTemp = h->AckNumber - dwTemp;
		if((LONG)(dwTemp) > 0)
		{
			ps->txTail += dwTemp;
			if(ps->txTail >= ps->bufferRxStart)
			{
				ps->txTail -= ps->bufferRxStart - ps->bufferTxStart;
			}
		}
	}


	while(!MACIsMemCopyDone());
	MACDiscardRx();

	if(flags)
		SendTCP(hTCP, flags);
}


#endif //#if defined(STACK_USE_TCP)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -