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

📄 tcp.c

📁 opentcp_mcf5282原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			return(-1);
	}


}


/********************************************************************************
Function:		tcp_poll

Parameters:		void

Return val:		void

Date:			19.7.2002

Desc:			Poll TCP sockets for timeout
*********************************************************************************/

void tcp_poll (void)
{
	struct tcb* soc;
	static UINT8 handle = 0;
	UINT8 i;
	INT32 temp;
	UINT8 old_retries;

	if(handle >= NO_OF_TCPSOCKETS)
		handle = 0;

	for(i=0; i < NO_OF_TCPSOCKETS; i++ )
	{
		if(handle >= NO_OF_TCPSOCKETS)
			handle = 0;

		soc = &TCPSocket[handle];

		switch(soc->state)
		{
			case TCP_STATE_FREE:
			case TCP_STATE_RESERVED:
			case TCP_STATE_CLOSED:
			case TCP_STATE_LISTENING:

				break;

			case TCP_STATE_CONNECTED:

				/* In CONNECTED State we have					*/
				/* something to do only if we have unacked data	*/
				/* or if connection has been IDLE too long or 	*/
				/* unserved close is isuued by user				*/
				/* or we want to keep lower layer alive 		*/

			/*	if(soc->send_next > soc->send_unacked)
					temp = soc->send_next - soc->send_unacked;
				else
					temp = soc->send_unacked - soc->send_next;

			*/
				temp = soc->send_next - soc->send_unacked;

				/* Unserved Close?			*/

				if(soc->flags & TCP_INTFLAGS_CLOSEPENDING)
				{
					/* Can we send the close now	*/

					if(temp == 0)
					{
						soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
						soc->send_next++;
						tcp_sendcontrol(handle);
						tcp_newstate(soc, TCP_STATE_FINW1);
						soc->flags ^= TCP_INTFLAGS_CLOSEPENDING;

						handle++;

						return;

					}
				}

				/* Socket timeout?			*/

				if(check_timer(soc->persist_timerh) == 0)
				{

					soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
					soc->send_next++;
					tcp_sendcontrol(handle);
					tcp_newstate(soc, TCP_STATE_FINW1);

					/* Inform application	*/

					soc->event_listener(handle, TCP_EVENT_CLOSE, soc->rem_ip, soc->remport);

					handle++;

					return;
				}

				/* Is there unacked data?	*/

				if(temp == 0)
				{
					/* Make sure we do not enter to retransmit imidiately when data */
					/* But if ARP is not ready ensure fast retransmit				*/

					if( arp_keepcache(soc->rem_ip) < 0 )
						init_timer(soc->retransmit_timerh, TCP_INIT_RETRY_TOUT);
					else
						init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT);

					break;
				}

				/* Is there timeout?					*/

				if( check_timer(soc->retransmit_timerh) != 0 )
					break;

				DEBUGOUT("Timeout on CONNECTED State\r\n");

				/* De we have retries left				*/

				if(soc->retries_left == 0)
				{
					/* No retries, must reset	*/

					DEBUGOUT("Retries used up, resetting\r\n");

					soc->myflags = TCP_FLAG_RESET;
					tcp_sendcontrol(handle);

					/* Inform application	*/

					soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);

					if(soc->type & TCP_TYPE_SERVER )
						tcp_newstate(soc, TCP_STATE_LISTENING);
					else
						tcp_newstate(soc, TCP_STATE_CLOSED);

					handle++;

					return;

				}

				soc->retries_left--;
				init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT);

				/* Yep, there is unacked data			*/
				/* Application should send the old data	*/

				if(temp>soc->send_mtu)
					temp = soc->send_mtu;

				/* Rewind Send Next because the send process will adjust it			*/
				/* So cheat the tcp_send to think there is no unacked data			*/

				soc->send_next = soc->send_unacked;

				/* tcp_send will set the retries_left to maximum but this is		*/
				/* retransmitting already so we need to retain it in order to 		*/
				/* avoid dead-lock													*/

				old_retries = soc->retries_left;

				temp = soc->event_listener(handle, TCP_EVENT_REGENERATE, (UINT32)temp, 0);

				soc->retries_left = old_retries;

				if(temp <= 0)
				{
					/* No data by application, must be something wrong	*/

					soc->myflags = TCP_FLAG_RESET;
					tcp_sendcontrol(handle);

					/* Inform application	*/

					soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);

					if(soc->type & TCP_TYPE_SERVER )
						tcp_newstate(soc, TCP_STATE_LISTENING);
					else
						tcp_newstate(soc, TCP_STATE_CLOSED);

					handle++;

					return;

				}

				/* Application has send data	*/

				handle++;

				return;


			case TCP_STATE_SYN_SENT:
			case TCP_STATE_SYN_RECEIVED:

				/* Is there timeout?	*/
				if( check_timer(soc->retransmit_timerh) != 0 )
					break;

				DEBUGOUT("Timeout\r\n");

				/* Yep, timeout. Is there reties left?	*/
				if( soc->retries_left )
				{
					soc->retries_left--;

					if(soc->state == TCP_STATE_SYN_SENT)
						init_timer(soc->retransmit_timerh, TCP_SYN_RETRY_TOUT);
					else
						init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT);

					tcp_sendcontrol(handle);

					handle++;

					return;
				}
				else
				{
					/* Retries used up	*/
					DEBUGOUT("Retries used up, resetting\r\n");

					if(soc->type & TCP_TYPE_SERVER )
						tcp_newstate(soc, TCP_STATE_LISTENING);
					else
						tcp_newstate(soc, TCP_STATE_CLOSED);

					soc->myflags = TCP_FLAG_RESET;
					tcp_sendcontrol(handle);

					/* Inform application	*/

					soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);

					handle++;

					return;
				}

				break;

			case TCP_STATE_TIMED_WAIT:

				/* Is there timeout?	*/

				if( check_timer(soc->retransmit_timerh) != 0 )
					break;

				DEBUGOUT("Timeout\r\n");

				if(soc->retries_left)
				{
					soc->retries_left--;
					init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT);
					break;
				}

				if(soc->type & TCP_TYPE_SERVER )
					tcp_newstate(soc, TCP_STATE_LISTENING);
				else
					tcp_newstate(soc, TCP_STATE_CLOSED);

				break;

			case TCP_STATE_LAST_ACK:
			case TCP_STATE_FINW1:
			case TCP_STATE_CLOSING:

				/* Is there timeout?	*/

				if( check_timer(soc->retransmit_timerh) != 0 )
					break;

				DEBUGOUT("Timeout\r\n");

				/* Yep, timeout. Is there reties left?	*/

				if( soc->retries_left )
				{
					soc->retries_left--;
					init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT);
					soc->myflags = TCP_FLAG_FIN | TCP_FLAG_ACK;
					tcp_sendcontrol(handle);

					handle++;

					return;
				}
				else
				{
					/* Retries used up	*/
					DEBUGOUT("Retries used up, resetting\r\n");

					if(soc->type & TCP_TYPE_SERVER )
						tcp_newstate(soc, TCP_STATE_LISTENING);
					else
						tcp_newstate(soc, TCP_STATE_CLOSED);

					soc->myflags = TCP_FLAG_RESET;
					tcp_sendcontrol(handle);

					/* Inform application	*/

					soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);

					handle++;

					return;
				}

				break;

			case TCP_STATE_FINW2:

				/* Is there timeout?	*/

				if( check_timer(soc->retransmit_timerh) != 0 )
					break;

				DEBUGOUT("Timeout\r\n");

				/* Yep, timeout. Is there reties left?	*/

				if( soc->retries_left )
				{
					/* Still keep waiting for FIN	*/

					soc->retries_left--;
					init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT);
					break;
				}
				else
				{
					/* Retries used up	*/
					DEBUGOUT("Retries used up, resetting\r\n");

					if(soc->type & TCP_TYPE_SERVER )
						tcp_newstate(soc, TCP_STATE_LISTENING);
					else
						tcp_newstate(soc, TCP_STATE_CLOSED);

					soc->myflags = TCP_FLAG_RESET;
					tcp_sendcontrol(handle);

					/* Inform application	*/

					soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);

					handle++;

					return;
				}

				break;

			default:
				break;

		}

		/* Go to next socket if there was no event	*/

		handle++;

	}

}


/********************************************************************************
Function:		tcp_init

Parameters:		-

Return val:		INT8 - (-1) = Error
					 - >0 = Number of sockets initialized

Date:			14.6.2002

Desc:			Set TCP sockets to known values.
				Called once when processor starts!
*********************************************************************************/

INT8 tcp_init (void)
{
	UINT16 i;
	INT16 h;
	struct tcb* soc;

	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);

	if( NO_OF_TCPSOCKETS == 0 )
		return(0);

	DEBUGOUT("Initializing TCP");

	for(i=0; i < NO_OF_TCPSOCKETS; i++)
	{
		soc = &TCPSocket[i];			/* Get Socket	*/
		h = -1;

		soc->state = TCP_STATE_FREE;
		soc->type = TCP_TYPE_NONE;
		soc->flags = 0;
		soc->rem_ip = 0;
		soc->remport = 0;
		soc->locport = 0;
		soc->myflags = 0;
		soc->send_mtu = TCP_DEF_MTU;
		soc->tos = 0;
		soc->tout = 0;
		soc->event_listener = 0;

		/* Reserve Timers	*/

		h = get_timer();

		if( h < 0 )
		{
			DEBUGOUT("\n\rERROR:Error getting timer for TCP Socket!\n\r");
			return(-1);
		}

		init_timer(h,0);					/* No timeout	*/

		soc->persist_timerh = h;

		h = get_timer();

		if( h < 0 )
		{
			DEBUGOUT("\n\rERROR:Error getting timer for TCP Socket!\n\r");
			return(-1);
		}

		init_timer(h,0);					/* No timeout	*/

		soc->retransmit_timerh = h;

		soc->retries_left = 0;

		DEBUGOUT(".");


	}

	DEBUGOUT("\n\rTCP Initialized\n\r");

	/* Return number of sockets initialized	*/

	return(i+1);


}




/*******************************************************************************/
/*******	TCP Internal functions										********/
/*******************************************************************************/



/********************************************************************************
Function:		ProcessTCPIn

Parameters:		struct IPFrame* frame - pointer to received IP frame structure
				UINT16 len - legth of data in bytes

Return val:		INT16 - (-1) Not OK
						>0 Packet OK


Date:			12.7.2002

Desc:			Check and process received TCP frame
*********************************************************************************/

INT16 ProcessTCPIn (struct IPFrame* frame, UINT16 len)
{
	struct tcb* soc;
	UINT16 hlen;
	UINT8 olen;
	UINT16 dlen;
	UINT16 i;
	INT8 sochandle;
	INT16 temp;

	/* Is this TCP?	*/

	DEBUGOUT("Processing TCP...\n\r");

	if( frame->protocol != IP_TCP )
	{
		DEBUGOUT("ERROR: The protocol is not TCP\n\r");
		return(-1);
	}

	/* Calculate checksum for received packet	*/


	NETWORK_RECEIVE_INITIALIZE(frame->BufIndex);

	if( TCP_CheckCS(frame, len) == 1)
	{
		DEBUGOUT("TCP Checksum OK\n\r");
	}
	else
	{
		DEBUGOUT("ERROR:TCP Checksum failed\r\n");
		return(-1);
	}

	/* Get the header	*/

	NETWORK_RECEIVE_INITIALIZE(frame->BufIndex);

	ReceivedTCPPacket.sport = RECEIVE_NETWORK_B();
	ReceivedTCPPacket.sport <<= 8;
	ReceivedTCPPacket.sport |= RECEIVE_NETWORK_B();

	ReceivedTCPPacket.dport = RECEIVE_NETWORK_B();
	ReceivedTCPPacket.dport <<= 8;
	ReceivedTCPPacket.dport |= RECEIVE_NETWORK_B();

	ReceivedTCPPacket.seqno = RECEIVE_NETWORK_B();
	ReceivedTCPPacket.seqno <<= 8;
	ReceivedTCPPacket.seqno |= RECEIVE_NETWORK_B();
	ReceivedTCPPacket.seqno <<= 8;
	ReceivedTCPPacket.seqno |= RECEIVE_NETWORK_B();
	ReceivedTCPPacket.seqno <<= 8;
	ReceivedTCPPacket.seqno |= RECEIVE_NETWORK_B();

	ReceivedTCPPacket.ackno = RECEIVE_NETWORK_B();
	ReceivedTCPPacket.ackno <<= 8;
	ReceivedTCPPacket.ackno |= RECEIVE_NETWORK_B();
	ReceivedTCPPacket.ackno <<= 8;
	ReceivedTCPPacket.ackno |= RECEIVE_NETWORK_B();
	ReceivedTCPPacket.ackno <<= 8;
	ReceivedTCPPacket.ackno |= RECEIVE_NETWORK_B();

	ReceivedTCPPacket.hlen_flags = RECEIVE_NETWORK_B();
	ReceivedTCPPacket.hlen_flags <<= 8;
	ReceivedTCPPacket.hlen_flags |= RECEIVE_NETWORK_B();

	ReceivedTCPPacket.window = RECEIVE_NETWORK_B();
	ReceivedTCPPacket.window <<= 8;
	ReceivedTCPPacket.window |= RECEIVE_NETWORK_B();

	ReceivedTCPPacket.checksum = RECEIVE_NETWORK_B();
	ReceivedTCPPacket.checksum <<= 8;
	ReceivedTCPPacket.checksum |= RECEIVE_NETWORK_B();

	ReceivedTCPPacket.urgent = RECEIVE_NETWORK_B();
	ReceivedTCPPacket.urgent <<= 8;
	ReceivedTCPPacket.urgent |= RECEIVE_NETWORK_B();

	/* Little check for options	*/

	hlen = ReceivedTCPPacket.hlen_flags & 0xF000;
	hlen >>= 10;

	if( hlen < MIN_TCP_HLEN )
	{
		DEBUGOUT("ERROR: Received TCP Header too short\r\n");
		return(-1);
	}

	if(hlen == MIN_TCP_HLEN)
		DEBUGOUT("TCP does not contain options\r\n");

	olen = hlen - MIN_TCP_HLEN;

	if( olen > MAX_TCP_OPTLEN )
	{
		DEBUGOUT("ERROR: Received TCP header contains too long option field\r\n");
		return(-1);
	}

	/* Calculate data length	*/

	if( hlen > len )
	{
		DEBUGOUT("ERROR: TCP header longer than packet\r\n");
		return(-1);
	}

	dlen = len - hlen - olen;

	/* Get options (if any)	*/

	for(i=0; i<olen;i++)
		ReceivedTCPPacket.opt[i] = RECEIVE_NETWORK_B();

	/* Try to find rigth socket to process with		*/

	sochandle = tcp_mapsocket(frame, &ReceivedTCPPacket);

	if(sochandle < 0)
	{
		DEBUGOUT("ERROR: Processing TCP packet failed\r\n");
		tcp_sendreset(&ReceivedTCPPacket, frame->sip);
		return(-1);
	}

	ReceivedTCPPacket.BufIndex = frame->BufIndex + hlen;
	NETWORK_RECEIVE_INITIALIZE(ReceivedTCPPacket.BufIndex);



	/* Get socket reference	*/

	soc = &TCPSocket[sochandle];

	/* Process the packet on TCP State Machine		*/

	switch(soc->state)
	{
		case TCP_STATE_CONNECTED:

			DEBUGOUT("CONNECTED State\r\n");

			/* Check for RESET	*/

			if(ReceivedTCPPacket.hlen_flags & TCP_FLAG_RESET)
			{
				DEBUGOUT("ERROR:Reset received\r\n");

				/* Inform application	*/

				soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);

				if(soc->type & TCP_TYPE_SERVER)
					tcp_newstate(soc, TCP_STATE_LISTENING);
				else
					tcp_newstate(soc, TCP_STATE_CLOSED);

				return(-1);
			}

			/* Check for SYN (If the peer didn't get our SYN+ACK or ACK)	*/

			if( ReceivedTCPPacket.hlen_flags & TCP_FLAG_SYN )
			{
				/* Is it the SYN+ACK we have already ACKed but maybe ACK lost?	*/

				if( ReceivedTCPPacket.hlen_flags & TCP_FLAG_ACK )
				{
					/* It's SYN+ACK but how about sequence	*/

					if( (ReceivedTCPPacket.seqno + 1) == soc->receive_next )
					{
						if( ReceivedTCPPacket.ackno == soc->send_next )
						{
							DEBUGOUT("Received SYN+ACK again\r\n");

							/* ACK the SYN	*/
							soc->myflags = TCP_FLAG_ACK;
							tcp_sendcontrol(sochandle);

⌨️ 快捷键说明

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