📄 tcp.c
字号:
switch (Socket->Stage)
{
case TCP_LISTEN : return;
case TCP_SYN_SENT : Socket->Flags |= TCP_FIN;
case TCP_SYN_RECEIVED : TCP_SocketStage(Socket, TCP_CLOSE_WAIT);
break;
case TCP_ESTABLISHED : TCP_SocketStage(Socket, TCP_CLOSE_WAIT);
break;
case TCP_FIN_WAIT_1 : TCP_SocketStage(Socket, TCP_FIN_WAIT_2);
break;
case TCP_FIN_WAIT_2 : TCP_SocketStage(Socket, TCP_TIME_WAIT);
u16_Put(&Socket->Retry_Timer, 0);
break;
case TCP_CLOSE_WAIT :
case TCP_CLOSING :
case TCP_LAST_ACK :
case TCP_TIME_WAIT : TCP_SocketStage(Socket, TCP_TIME_WAIT);
break;
default : TCP_SocketStage(Socket, TCP_CLOSED);
return;
}
Socket->TheirSequenceNum = ntohl(TCP_Header->SequenceNum) + 1; // their sequence number
Socket->Flags |= TCP_ACK; // we need to send an ACK back
}
// *******************
// ack
if (TCP_Header->ControlBits & TCP_ACK)
{ // ACK
switch (Socket->Stage)
{
case TCP_LISTEN : return;
case TCP_SYN_SENT : TCP_SendPacket(Socket, TCP_RST); // send a packet back
TCP_SocketStage(Socket, TCP_CLOSED);
return;
case TCP_SYN_RECEIVED : // we were waiting for the ack
TCP_UpdateRoundTripTime(Socket, u16_Get(&Socket->Retry_Timer));
Socket->OurSequenceNum++;
TCP_SocketStage(Socket, TCP_ESTABLISHED);
if (!Socket->OutGoing)
{
strcpy(ScratchPad, "z8 Tcp server\r\n--------------\r\n");
TCP_TxData(Socket, ScratchPad, strlen((char*)ScratchPad)); // send them some text
}
break;
case TCP_ESTABLISHED : if (Socket->OurSequenceNum != ntohl(TCP_Header->AckNum))
{ // ack to some data we have sent
TCP_UpdateRoundTripTime(Socket, u16_Get(&Socket->Retry_Timer));
dw = ntohl(TCP_Header->AckNum);
if (dw < Socket->OurSequenceNum)
dw += 1 + (0xffffffff - Socket->OurSequenceNum); // 32-bit unsigned rap-around number
else
dw -= Socket->OurSequenceNum;
if (dw > Socket->OurLastBytesSent) dw = Socket->OurLastBytesSent; // hmmm
Socket->TxBufferRd += (s16)dw;
while (Socket->TxBufferRd >= sizeof(Socket->TxBuffer)) Socket->TxBufferRd -= sizeof(Socket->TxBuffer);
Socket->OurSequenceNum += dw;
Socket->OurLastBytesSent = 0;
Socket->Retries = 0;
u16_Put(&Socket->Retry_Timer, Socket->RoundTripTime * TCP_Retry_Time); // next packet asap
}
break;
case TCP_FIN_WAIT_1 : TCP_UpdateRoundTripTime(Socket, u16_Get(&Socket->Retry_Timer));
TCP_SocketStage(Socket, TCP_FIN_WAIT_2); // we got an ack back for the FIN we sent
break;
case TCP_FIN_WAIT_2 : TCP_SocketStage(Socket, TCP_TIME_WAIT);
break;
case TCP_CLOSE_WAIT : break;
case TCP_CLOSING : TCP_SocketStage(Socket, TCP_TIME_WAIT);
break;
case TCP_LAST_ACK : TCP_SocketStage(Socket, TCP_CLOSED);
case TCP_TIME_WAIT : break;
default : break;
}
if (TCP_Header->ControlBits & TCP_URG) //
{ //
if (TCP_Header->UrgentPointer) //
{ //
// dw = ntohl(TCP_Header->SequenceNum); //
// dw += (u32)ntohs(TCP_Header->UrgentPointer); // dw = the sequence number of this data
Socket->Flags |= TCP_ACK; // send an ACK back
goto SendNow; // we don't yet deal with urgent pointers :(
} //
} //
//
if (ntohl(TCP_Header->SequenceNum) == Socket->TheirSequenceNum) //
{ //
if (len) i = TCP_RxSaveData(Socket, MainBuffer + MainBufferRd_Rx, (int)len); // save the data sent in the packet into our rx buffer and sent ask back
} //
else //
Socket->Flags |= TCP_ACK; // tell them seq-num we were expecting
}
// *******************
// Send any packets back that need sending
SendNow:
if (Socket->Flags)
{
TCP_SendPacket(Socket, Socket->Flags); // send a packet back
}
return;
// *******************
// reject the packet completely
RefuseConnection: //
// if (IP_FireWalled()) //
// { //
// #ifdef Debug //
// SendDebugRStr(tcp_str21); //
// #endif //
// return; // firewalled - just don't bother with them
// } //
if (TCP_Header->ControlBits & TCP_RST) return; // we don't send RST in responce to RST rx'ed
// //
// swap the packet round and send it back //
//
dw = IP_Header->DestIP.ip32; //
IP_Header->DestIP.ip32 = IP_Header->SourceIP.ip32; //
IP_Header->SourceIP.ip32 = dw; //
//
len = TCP_Header->SourcePort; //
TCP_Header->SourcePort = TCP_Header->DestPort; //
TCP_Header->DestPort = len; //
//
dw = TCP_Header->SequenceNum; //
TCP_Header->SequenceNum = TCP_Header->AckNum; //
TCP_Header->AckNum = dw; //
//
TCP_Header->DataOffset = sizeof(T_TCP_Header) >> 2; //
TCP_Header->DataOffset <<= 4; //
//
TCP_Header->ControlBits = TCP_RST | TCP_ACK; // set the tx packet control bits
//
TCP_Header->Checksum = 0; //
TCP_Header->WindowSize = 0; //
TCP_Header->UrgentPointer = 0; //
//
MainBufferWr_Tx = sizeof(T_PPP_Header1) + sizeof(T_IP_Header) + sizeof(T_TCP_Header); // update index
//
len = IP_Checksum2((char*)TCP_Header, sizeof(T_TCP_Header)); // update the TCP header checksum
// if (!len) len = 0xffff; //
TCP_Header->Checksum = htons(len); //
//
IP_Header->ID = htons(IP_ID++); //
IP_Header->Checksum = 0; // update the IP header
IP_Header->TotalLength = sizeof(T_IP_Header) + sizeof(T_TCP_Header); // update the IP header
IP_Header->TotalLength = htons(IP_Header->TotalLength); //
//
len = (u16)(IP_Header->VerLen & 0x0f); // number of 32-bit words to the ip header
len <<= 2; // now number of bytes
len = IP_Checksum1((char*)IP_Header, len); // update the IP header checksum
// if (!len) len = 0xffff; //
IP_Header->Checksum = htons(len); //
//
len = MainBufferWr_Tx; //
//
if (!PPP_SendPacket(false)) return; // send it
#ifdef Debug
IP_DisplayProtocol(true, (int)len); //
IP_DisplayHeader(sizeof(T_PPP_Header1), (int)len); //
TCP_DisplayHeader(sizeof(T_PPP_Header1) + sizeof(T_IP_Header), (int)len); //
#endif
return;
}
// ******************************************************************************************
// this is called from the ip module - every 10ms
void TCP_10ms_Timer(void)
{
u16 w;
T_TCP_Socket *Socket;
Socket = TCP_Socket; // we only have the one - for now
if (Socket == NULL) return; // no socket to update
//
if (Socket->Stage == TCP_ESTABLISHED) //
{ //
if (Socket->ConnectTime < 4294967195) Socket->ConnectTime += 10; //
if (Socket->LastRxData < 4294967195) Socket->LastRxData += 10; //
//
if (Socket->AckDelay < 65000) //
{ //
w = Socket->AckDelay + 10; //
if ((Socket->AckDelay < TCP_AckDelay) && (w >= TCP_AckDelay)) Socket->SendAck = true; // time to send ack back
Socket->AckDelay = w; //
} //
} //
//
if ((Socket->Stage == TCP_CLOSED) || (Socket->Stage == TCP_LISTEN)) return; //
//
if (Socket->Retry_Timer < 65000) Socket->Retry_Timer += 10; // ms since last packet sent
}
// ******************************************************************************************
// this is called from the ip module
// - it takes care of the TCP link for you
void TCP_Process(void)
{
T_TCP_Socket *Socket;
Socket = TCP_Socket; // we only have the one - for now
if (Socket == NULL) return; // no socket to update
//
if (Socket->Stage == TCP_CLOSED) //
{ //
#ifndef StaticTCPSocket
realloc(Socket, 0); // free the socket memory
Socket = 0; //
#endif
Socket = TCP_SocketListen(TCP_Port); // re-open it for listening
return; //
} //
if (Socket->Stage == TCP_LISTEN) return; // waiting for an incoming connection
if (Socket->Stage == TCP_ESTABLISHED) //
{ //
if ((TCP_DataTimeOut) && (u32_Get(&Socket->LastRxData) >= TCP_DataTimeOut)) // tcp no-data timeout
{ // disconnect
TCP_CloseSocket(Socket); //
return; //
} //
} //
if (u16_Get(&Socket->Retry_Timer) < (Socket->RoundTripTime * TCP_Retry_Time)) return; // not time to retry a packet send
if (Socket->Retries >= TCP_Retries) //
{ // give up with the link
TCP_SocketStage(Socket, TCP_CLOSED); //
TCP_SendPacket(Socket, TCP_ACK | TCP_RST); //
return; //
} //
//
if (MainBufferWr_Rx > 0) return; // something else is using the buffer atm
if (MainBufferWr_Tx > 0) return; // "
switch (Socket->Stage)
{
case TCP_CLOSED : break;
case TCP_LISTEN : break;
case TCP_SYN_SENT :
case TCP_SYN_RECEIVED : TCP_SendPacket(Socket, TCP_SYN);
break;
case TCP_ESTABLISHED : // send any data that needs sending
if (Socket->TxBufferRd != Socket->TxBufferWr) TCP_SendPacket(Socket, TCP_ACK | TCP_PSH); // send some data
else //
if (Socket->SendAck) TCP_SendPacket(Socket, TCP_ACK); // send ack back
break;
case TCP_FIN_WAIT_1 : TCP_SendPacket(Socket, TCP_FIN | TCP_ACK);
break;
case TCP_FIN_WAIT_2 : // waiting for their FIN packet
break;
case TCP_CLOSE_WAIT : TCP_SendPacket(Socket, TCP_FIN | TCP_ACK);
TCP_SocketStage(Socket, TCP_LAST_ACK);
u16_Put(&Socket->Retry_Timer, 0);
break;
case TCP_CLOSING :
break;
case TCP_LAST_ACK : TCP_SendPacket(Socket, TCP_FIN | TCP_ACK);
break;
case TCP_TIME_WAIT : TCP_SocketStage(Socket, TCP_CLOSED);
break;
default : TCP_SocketStage(Socket, TCP_CLOSED);
break;
}
}
// ******************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -