PERFORCE change 124082 for review

Alexey Tarasov taleks at FreeBSD.org
Wed Jul 25 13:01:15 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=124082

Change 124082 by taleks at taleks_th on 2007/07/25 13:00:43

	pxe_tcp: Rewrote TCP code to make it simplier. All states, except SYN_SEN, are handled in one function.
	pxe_core: now don't check if interrupt occured (__pxe_isr_occured flag), just start PXE API to get new packets. Need to find out why interrupt doesn't occur sometimes. Most probably, incorrect code of end of interrupt.

Affected files ...

.. //depot/projects/soc2007/taleks-pxe_http/pxe_arp.c#13 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_arp.h#9 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#23 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#19 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_filter.c#6 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_segment.c#8 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_tcp.c#11 edit

Differences ...

==== //depot/projects/soc2007/taleks-pxe_http/pxe_arp.c#13 (text+ko) ====

@@ -325,11 +325,11 @@
 	switch (function) {
 
 	case PXE_AWAIT_STARTTRY:	/* handle start of new try */
-		if (pxe_arp_send_whois(wait_data->ip) != 1) {	
+		if (!pxe_arp_send_whois(wait_data->ip)) {	
 			/* failed to send request, try once more
 			 * after waiting a little
 			 */
-			delay(10000);				
+			delay(10000);		
 		        return (PXE_AWAIT_NEXTTRY);
 		}
 		break;
@@ -377,7 +377,7 @@
 	if (res != NULL)
 		return (res);
 
-	pxe_core_exclusive(PXE_PROTOCOL_ARP);
+/*	pxe_core_exclusive(PXE_PROTOCOL_ARP); */
 	
 	PXE_ARP_WAIT_DATA	wait_data;
 	
@@ -386,7 +386,7 @@
 	
 	pxe_await(pxe_arp_await, PXE_MAX_ARP_TRY, PXE_TIME_TO_DIE, &wait_data);
 
-	pxe_core_exclusive(0);
+/*	pxe_core_exclusive(0); */
 	
 	return (wait_data.mac);
 }

==== //depot/projects/soc2007/taleks-pxe_http/pxe_arp.h#9 (text+ko) ====

@@ -46,7 +46,7 @@
 /* max try count to send/recieve ARP request/reply */
 #define PXE_MAX_ARP_TRY	3
 /* max timeout in millyseconds */
-#define PXE_TIME_TO_DIE 15000
+#define PXE_TIME_TO_DIE 5000
 
 /* define to enable caching incoming ARP packet sender information */
 #define PXE_ARP_SNIFF

==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#23 (text+ko) ====

@@ -74,6 +74,8 @@
 static uint32_t			packets_sent = 0;
 static uint32_t			packets_received = 0;
 
+static int			pxe_state = PXE_DOWN;
+
 /* pxe_core_undi_startup() - performs UNDI startup call during pxe_core_init()
  * in:
  *	none
@@ -236,7 +238,9 @@
 	/* setting entry point in tramp code */
 	__pxe_entry_seg = pxe->EntryPointSP.segment;
 	__pxe_entry_off = pxe->EntryPointSP.offset;
-	
+
+	pxe_state = PXE_INITING;
+		
 	/* 2. getting cached info */
 	gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer;
 	pxe_memset(gci_p, 0, sizeof(*gci_p)); 
@@ -254,6 +258,7 @@
 	    	printf("pxe_core_init(): error status = 0x%x\n", gci_p->Status);
 #endif		
 		pxe_p = NULL;
+		pxe_state = PXE_DOWN;
 		return (0);
 	}
 
@@ -264,6 +269,7 @@
 
 	/* 3. install isr */
 	pxe_core_install_isr();
+	pxe_state = PXE_READY;
 	
 	/* 4. open connection to network */
 	t_PXENV_UNDI_OPEN *undi_open = (t_PXENV_UNDI_OPEN *)scratch_buffer;
@@ -320,7 +326,7 @@
 #ifdef PXE_CORE_DEBUG
 	printf("pxe_core_init(): ended.\n");
 #endif	
-
+	
 	return (1);
 }
 
@@ -373,15 +379,9 @@
 	v86.ctl  = V86_FLAGS;
 	
 	printf("\tchained handler @ 0x%x:0x%x\n", v86.ebx, v86.edx);
-
-/*	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
- 	v86.addr = (VTOPSEG(__mask_irq) << 16) | VTOPOFF(__mask_irq);
- 	v86.ebx = __pxe_nic_irq;
- 	v86int();
- 	v86.ctl  = V86_FLAGS;
 	
-	printf("enabled irq.\n");
-*/
+	__chained_irq_seg = v86.ebx;
+	__chained_irq_off = v86.edx;
 
 #ifdef PXE_CORE_DEBUG
 	printf("pxe_core_install_isr(): success (isr @ 0x%x:0x%x)\n",
@@ -428,7 +428,15 @@
 	pxe_memset(&v86, 0, sizeof(v86));
 
 	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
-	v86.addr = (VTOPSEG(__isr_remove) << 16) | VTOPOFF(__isr_remove);
+/*	v86.addr = (VTOPSEG(__isr_remove) << 16) | VTOPOFF(__isr_remove); */
+	v86.addr = (VTOPSEG(__isr_install) << 16) | VTOPOFF(__isr_install);
+
+	uint8_t int_num = (__pxe_nic_irq < 8) ?
+			   __pxe_nic_irq + 0x08 : __pxe_nic_irq + 0x68;	
+	
+	v86.eax = int_num;
+	v86.ebx = __chained_irq_seg;
+	v86.edx = __chained_irq_off;
 	v86int();
 	v86.ctl  = V86_FLAGS;
 }
@@ -459,9 +467,12 @@
 	t_PXENV_UNDI_SHUTDOWN *undi_shutdown_p =
 	    (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer;
 
-	pxe_core_call(PXENV_UNDI_SHUTDOWN);
+/*	pxe_core_call(PXENV_UNDI_SHUTDOWN);
 	pxe_core_call(PXENV_UNLOAD_STACK);
-
+*/
+	/* make pxe_core_call() unavailable */
+	pxe_state = PXE_DOWN;
+	
 	return (1);
 }
 
@@ -480,6 +491,11 @@
 #ifdef PXE_CORE_DEBUG_HELL
 	printf("pxe_core_call(): func = 0x%x...", func);
 #endif
+	if (pxe_state == PXE_DOWN) {
+		printf("pxe_core_call(): internal error, PXE shutdowned.\n");
+		return (0);
+	}
+	
 	pxe_memset(&v86, 0, sizeof(v86));
 
 	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
@@ -496,7 +512,6 @@
 #ifdef PXE_CORE_DEBUG_HELL
 	printf("%s (0x%x)\n", (call_status == 0) ? "?OK" : "?NOK", status );
 #endif
-
 	return (status == 0) ? 1 : 0;
 }
 
@@ -689,9 +704,9 @@
 				 * real packet struct
 				 */
 
-	if (__pxe_isr_occured == 0) /* there are no packets for us to handle */
-		return (0);
-
+/*	if (__pxe_isr_occured == 0) /* there are no packets for us to handle */
+/*		return (0);
+*/
 	__pxe_isr_occured = 0; /* reset flag */
 
 	t_PXENV_UNDI_ISR *undi_isr =
@@ -735,14 +750,14 @@
 	}
 	
 	/* experimental: to avoid resendings of ip packets for unknown MAC*/
-	if (exclusive_protocol && (protocol != exclusive_protocol)) {
+/*	if (exclusive_protocol && (protocol != exclusive_protocol)) {
 #ifdef PXE_CORE_DEBUG
 		printf("recv_packets(): not exclusive protocol (%d != %d).\n",
 			protocol, exclusive_protocol);
 #endif		
 		++packets_dropped;
 		drop_flag = 1;	/* clear queue, receiving frames of packet */
-	}
+/*	} */
 
 	/* sanity check */
 	if (frame_size < PXE_BUFFER_SIZE) {

==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#19 (text+ko) ====

@@ -43,6 +43,10 @@
 #define PXE_PACKET_STATE_FREE		0
 #define PXE_PACKET_STATE_USING		1
 
+#define PXE_DOWN			0
+#define PXE_INITING			1
+#define PXE_READY			2
+
 /* size of media header, used in allocating memmory for packet */
 #define	MEDIAHDR_LEN_ETH		14
 /* packet type: broadcast and directed */

==== //depot/projects/soc2007/taleks-pxe_http/pxe_filter.c#6 (text+ko) ====

@@ -140,16 +140,19 @@
 pxe_filter_add(uint32_t src_ip, uint16_t src_port, uint32_t dst_ip,
 	       uint16_t dst_port, void *socket, uint8_t proto)
 {
-#ifdef PXE_DEBUG	
+
 	if (socket == NULL) {
+#ifdef PXE_DEBUG		
 		printf("pxe_filter_add(): NULL socket.\n");
+#endif
 		return (NULL);
 	}
-#endif
+
 	if (free_head == NULL) {
+#ifdef PXE_DEBUG
 		printf("pxe_filter_add(): filter table is full (used = %d).\n",
 		    all_filters);
-		    
+#endif		    
 		return (NULL);	/* there is no space for filters */
 	}
 

==== //depot/projects/soc2007/taleks-pxe_http/pxe_segment.c#8 (text+ko) ====

@@ -234,14 +234,16 @@
 			/* check if it's time to resend */
                         if (cur_time >= segment->resend_at) {
 #ifdef PXE_TCP_DEBUG_HELL
-				printf("pxe_resend_check(): %d:%d resending (next try at: %d)\n",
+				printf("pxe_resend_check(): %lu:%lu "
+				       "resending (next try at: %lu)\n",
 				    segment->resend_at, cur_time,
-				    segment->resend_at +
+				    cur_time +
 				    PXE_RESEND_TIME * (segment->trys + 1));
 #endif				
 				segment->trys += 1;
 								
-				segment->resend_at +=
+/*				segment->resend_at +=*/
+				segment->resend_at = cur_time +
 				    PXE_RESEND_TIME * segment->trys;
 				
 				if (segment->trys == PXE_RESEND_TRYS) {
@@ -264,15 +266,18 @@
 				/* check time to resend */
                                 if (cur_time >= segment->resend_at) {
 #ifdef PXE_TCP_DEBUG_HELL
-					printf("pxe_resend_check(): %d:%d resending (next try at: %d)\n",
+					printf("pxe_resend_check(): %lu:%lu "
+					       "resending (next try at: %lu)\n",
 					    segment->resend_at, cur_time,
-					    segment->resend_at +
+					    cur_time +
 					    PXE_RESEND_TIME * (segment->trys + 1));
 #endif
-					/* resend later, with more delay with every try */
+					/* resend later, with more delay 
+					 * with every try */
 					segment->trys += 1;
 					
-					segment->resend_at +=
+/*					segment->resend_at += */
+					segment->resend_at = cur_time +
 					    PXE_RESEND_TIME * segment->trys;
 
 					if (segment->trys == PXE_RESEND_TRYS) {

==== //depot/projects/soc2007/taleks-pxe_http/pxe_tcp.c#11 (text+ko) ====

@@ -37,50 +37,24 @@
 #include "pxe_segment.h"
 #include "pxe_tcp.h"
 
-/* state handle functions. TODO: think about removing them */
-static int tcp_syn_sent(PXE_TCP_PACKET *tcp_packet,
-		PXE_TCP_CONNECTION *connection, uint16_t seglen);
-		
-static int tcp_established(PXE_TCP_PACKET *tcp_packet,
-		PXE_TCP_CONNECTION *connection, uint16_t seglen);
-		
-static int tcp_fin_wait1(PXE_TCP_PACKET *tcp_packet,
-		PXE_TCP_CONNECTION *connection, uint16_t seglen);
-		
-static int tcp_closing(PXE_TCP_PACKET *tcp_packet,
-		PXE_TCP_CONNECTION *connection, uint16_t seglen);
-		
-static int tcp_fin_wait2(PXE_TCP_PACKET *tcp_packet,
-		PXE_TCP_CONNECTION *connection, uint16_t seglen);
-		
-static int tcp_time_wait(PXE_TCP_PACKET *tcp_packet,
-		PXE_TCP_CONNECTION *connection, uint16_t seglen);
-		
-static int tcp_close_wait(PXE_TCP_PACKET *tcp_packet,
-		PXE_TCP_CONNECTION *connection, uint16_t seglen);
-		
-static int tcp_last_ack(PXE_TCP_PACKET *tcp_packet,
-		PXE_TCP_CONNECTION *connection, uint16_t seglen);
-
-/* pointers to appropriate state handlers */
-static pxe_tcp_state_func	state_functions[PXE_TCP_ALL_STATES] = {
-					NULL,		/* CLOSED */
-					tcp_syn_sent,	/* SYN_SENT */
-					NULL,		/* SYN_RECEIVED */
-					tcp_established,/* ESTABLISHED */
-					tcp_close_wait,	/* CLOSE_WAIT */
-					tcp_last_ack,	/* LAST_ACK */
-					tcp_fin_wait1,	/* FIN_WAIT_1 */
-					tcp_closing,	/* CLOSING */
-					tcp_fin_wait2,	/* FIN_WAIT_2 */
-					tcp_time_wait,	/* TIME_WAIT */
-				};
-
 /* used by pxe_tcp_syssend, when connection have no buffers */
 static PXE_BUFFER		sysbuf;
 /* buffer space for sysbuf */
 static uint8_t			bufdata[PXE_TCP_SYSBUF_SIZE];
-
+/* states in  human friendly */
+static char			strstates[PXE_TCP_ALL_STATES][15] = {
+				    "CLOSED",
+				    "SYN_SENT",
+				    "SYN_RECEIVED",
+				    "ESTABLISHED",
+				    "CLOSE_WAIT",
+				    "LAST_ACK",
+				    "FIN_WAIT_1",
+				    "CLOSING",
+				    "FIN_WAIT_2",
+				    "TIME_WAIT"
+				};
+				
 /* tcp_check_time_to_die() - moves to CLOSED state connections from state
  *	TIME_WAIT if last received packet (ACK for FIN in most cases)
  *	was more than 2*MSL time ago.
@@ -189,7 +163,7 @@
 
 		/* or? */	
 		if ((connection->next_recv <= seq + seglen - 1) &&
-		    (seq +seglen -1 < connection->next_recv + window) )
+		    (seq + seglen - 1 < connection->next_recv + window) )
 			return (1);
 	}
 	
@@ -370,10 +344,6 @@
 	if (tcp_packet->tcphdr.flags & (PXE_TCP_SYN | PXE_TCP_FIN) )
 		connection->next_recv += 1;
 
-/*	printf("tcp_process_7(): seq = %d, ack = %d, seglen = %d\n",
-	    connection->next_recv - connection->irs,
-	    connection->next_send - connection->iss, seglen);
-*/
 	if ( (seglen > 0) && (connection->state == PXE_TCP_ESTABLISHED)) {
 		/* write data to buffer, always enough space,
 		 * if packet is acceptable
@@ -384,7 +354,7 @@
 		pxe_buffer_write(connection->recv, data, seglen);
 	}
 
-	pxe_tcp_syssend(connection, PXE_TCP_ACK);	
+	pxe_tcp_syssend(connection, PXE_TCP_ACK);
 	connection->last_recv = pxe_get_secs();	
 }
 
@@ -497,33 +467,50 @@
 	return (0);
 }
 
-/* tcp_established() - ESTABLISHED state handler
- * in:
- *	tcp_packet - incoming packet data
- *	connection - current connection
- * out:
- *	0 - don't interested more in this packet
- *	1 - interested
- *	2 - try next state handler
- */
 static int
-tcp_established(PXE_TCP_PACKET *tcp_packet, PXE_TCP_CONNECTION *connection,
+pxe_tcp_process(PXE_TCP_PACKET *tcp_packet, PXE_TCP_CONNECTION * connection,
 		uint16_t seglen)
 {
+	uint8_t	state = connection->state;
+	uint8_t state_out = connection->state_out;
+	
 	/* first check, if acceptable at all */
 	if (!tcp_check_1(connection, tcp_packet, seglen))
 		return (0);
 
+	/* check establishing of commmunication */
+	if (state == PXE_TCP_SYN_SENT) {
+	    
+		if (tcp_packet->tcphdr.flags & PXE_TCP_SYN) {
+		
+			uint32_t	ack = tcp_packet->tcphdr.ack_next;
+			uint32_t	seq = tcp_packet->tcphdr.sequence;
+
+			connection->next_recv = seq + 1;
+			connection->irs = seq;
+			connection->una = ack;
+			pxe_resend_update(connection);
+		}
+		
+		if (pxe_tcp_syssend(connection, PXE_TCP_ACK)) {
+			connection->state = PXE_TCP_ESTABLISHED;
+			connection->last_recv = pxe_get_secs();
+		} else {
+			printf("tcp_syn_sent(): ack syn reply failed.\n");
+			return (0);
+		}
+	}
+	
 	/* check, if have RST flag, sequentially incorrect or have SYN */
 	if (( tcp_check_2(tcp_packet)) ||
-	    (!tcp_check_3(connection, tcp_packet)) || 
 	    ( tcp_check_4(connection, tcp_packet, seglen)))
 	{
 		connection->state = PXE_TCP_CLOSED;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_established(): new state - CLOSED\n");
-#endif				
 		pxe_resend_free(connection);
+		
+	/*	if (state == PXE_TCP_TIME_WAIT) */
+		free_connection(connection);
+			
 		return (0);
 	}
 
@@ -531,322 +518,109 @@
 	if (!tcp_check_5(connection, tcp_packet))
 		return (0);
 	
-	/* sixth check, if urgent */
-	if (tcp_check_6(tcp_packet)) /* ignore for now */
-		return (0);
-
-	/* seventh, process segment */
-	tcp_process_7(connection, tcp_packet, seglen);
+	switch (state) {
+	case PXE_TCP_FIN_WAIT1:
+		connection->next_send = tcp_packet->tcphdr.ack_next;
+		
+		/* if acked our FIN */
+		if (state_out == PXE_TCP_FIN) {
+			connection->state = PXE_TCP_FIN_WAIT2;
+		/*	return (0); */
+		}
+		break;
 	
-	/* eighth, check FIN */
-	if (tcp_check_8(tcp_packet)) {
-		/* remote host requested connection break */
-		connection->state = PXE_TCP_CLOSE_WAIT;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_established(): new state - CLOSE_WAIT\n");
-#endif	
-	}
-	
-	return (0);
-}
-
-/* tcp_fin_wait1() - FIN_WAIT_1 state handler
- * in:
- *	tcp_packet - incoming packet data
- *	connection - current connection
- * out:
- *	0 - don't interested more in this packet
- *	1 - interested
- *	2 - try next state handler
- */
-static int
-tcp_fin_wait1(PXE_TCP_PACKET *tcp_packet, PXE_TCP_CONNECTION *connection,
-	      uint16_t seglen)
-{
-	/* first check, if acceptable at all */
-	if (!tcp_check_1(connection, tcp_packet, seglen))
-		return (0);
-
-	/* check, if have RST or SYN flag */
-	if ((tcp_check_2(tcp_packet)) ||
-	    (tcp_check_4(connection, tcp_packet, seglen)) )
-	{
-		connection->state = PXE_TCP_CLOSED;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_fin_wait1(): new state - CLOSED\n");
-#endif				
-		pxe_resend_free(connection);
-		return (0);
-	}
-	
-	/* check if ACK */
-	if (!tcp_check_5(connection, tcp_packet))
-		return (0);
-	else
+	case PXE_TCP_FIN_WAIT2:
 		connection->next_send = tcp_packet->tcphdr.ack_next;
+		break;
 	
-	/* if acked our FIN */
-	if (connection->state_out == PXE_TCP_FIN) {
-		connection->state = PXE_TCP_FIN_WAIT2;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_fin_wait1(): new state - FIN_WAIT_2\n");
-#endif
-		return (0);
-	}
-	
-	if (tcp_check_6(tcp_packet)) /* ignore for now */
-		return (0);
-
-	tcp_process_7(connection, tcp_packet, seglen);
-	
-	/* check acked FIN */
-	if (tcp_check_8(tcp_packet)) {
-		if (connection->state_out == PXE_TCP_FIN) {
+	case PXE_TCP_CLOSING:
+		if (state_out == PXE_TCP_FIN)
 			connection->state = PXE_TCP_TIME_WAIT;
-#ifdef PXE_TCP_DEBUG
-			printf("tcp_fin_wait1(): new state - TIME_WAIT\n");
-#endif			
-			/* TODO: start TIME_WAIT timer */
-		}  else {
-			connection->state = PXE_TCP_CLOSING;
-#ifdef PXE_TCP_DEBUG
-			printf("tcp_fin_wait1(): new state - CLOSING\n");
-#endif			
+		break;
+		
+	case PXE_TCP_LAST_ACK:
+		if (state_out == PXE_TCP_FIN) {
+			connection->state = PXE_TCP_CLOSED;
+			pxe_resend_free(connection);
+			free_connection(connection);
+			return (0);
 		}
-	}
+		break;
 	
-	return (0);
-}
-
-/* tcp_closing() - CLOSING state handler
- * in:
- *	tcp_packet - incoming packet data
- *	connection - current connection
- * out:
- *	0 - don't interested more in this packet
- *	1 - interested
- *	2 - try next state handler
- */
-static int
-tcp_closing(PXE_TCP_PACKET *tcp_packet, PXE_TCP_CONNECTION *connection,
-	    uint16_t seglen)
-{
-	/* first check, if acceptable at all */
-	if (!tcp_check_1(connection, tcp_packet, seglen))
-		return (0);
-
-	/* check, if have RST OR SYN flag */
-	if ( (tcp_check_2(tcp_packet)) ||
-	     (tcp_check_4(connection, tcp_packet, seglen)) )
-	{
-		connection->state = PXE_TCP_CLOSED;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_closing(): new state - CLOSED\n");
-#endif		
-		pxe_resend_free(connection);
-		return (0);
+	case PXE_TCP_TIME_WAIT:
+		/* in that state only retransmission of FIN may arrive 
+		 * ACKing it
+		 */
+		pxe_tcp_syssend(connection, PXE_TCP_ACK);
+		break;
+		
+	default:
+		break;
 	}
 	
-	/* check ACK */
-	if (!tcp_check_5(connection, tcp_packet))
-		return (0);
-
-	if (connection->state_out = PXE_TCP_FIN) {
-		connection->state = PXE_TCP_TIME_WAIT;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_closing(): new state - TIME_WAIT\n");
-#endif		
-	}
-	
-	return (0);
-}
-
-/* tcp_fin_wait2() - FIN_WAIT_2 state handler
- * in:
- *	tcp_packet - incoming packet data
- *	connection - current connection
- * out:
- *	0 - don't interested more in this packet
- *	1 - interested
- *	2 - try next state handler
- */
-static int
-tcp_fin_wait2(PXE_TCP_PACKET *tcp_packet, PXE_TCP_CONNECTION *connection,
-	      uint16_t seglen)
-{
-	/* first check, if acceptable at all */
-	if (!tcp_check_1(connection, tcp_packet, seglen))
-		return (0);
-
-	/* check, if have RST or SYN flag */
-	if ((tcp_check_2(tcp_packet)) ||
-	    (tcp_check_4(connection, tcp_packet, seglen)) )
-	{
-		connection->state = PXE_TCP_CLOSED;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_fin_wait2(): new state - CLOSED\n");
-#endif
-		pxe_resend_free(connection);
-		return (0);
-	}
-	
-	if (!tcp_check_5(connection, tcp_packet)) {
-		return (0);
-	}
-	
-/*	
+	/* FIN_WAIT_2
 	if (tcp_queue_size(connection) == 0) {
 		connection->state = PXE_TCP_CLOSE;
 	}
-*/
-	/* check URG flag */
-	if (tcp_check_6(tcp_packet)) /* ignore for now */
+	*/
+	
+	/* sixth check, if urgent. Ignoring. */
+	/* if (tcp_check_6(tcp_packet)) 
 		return (0);
-	
-	connection->next_send = tcp_packet->tcphdr.ack_next;
-	
-	/* process data */
-	tcp_process_7(connection, tcp_packet, seglen);
-	
-	/* check acked FIN */
-	if (tcp_check_8(tcp_packet)) {
-		connection->state = PXE_TCP_TIME_WAIT;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_fin_wait2(): new state - TIME_WAIT\n");
-#endif
-		/* TODO: start TIME_WAIT timer */
-	}
-	
-	return (0);
-}
+	*/
 
-/* tcp_time_wait() - TIME_WAIT state handler
- * in:
- *	tcp_packet - incoming packet data
- *	connection - current connection
- * out:
- *	0 - don't interested more in this packet
- *	1 - interested
- *	2 - try next state handler
- */
-static int
-tcp_time_wait(PXE_TCP_PACKET *tcp_packet, PXE_TCP_CONNECTION *connection,
-	      uint16_t seglen)
-{
-	/* first check, if acceptable at all */
-	if (!tcp_check_1(connection, tcp_packet, seglen))
-		return (0);
+	/* seventh, process segment */
+	switch (state) {
+	case PXE_TCP_ESTABLISHED:
+	case PXE_TCP_FIN_WAIT1:
+	case PXE_TCP_FIN_WAIT2:
+		tcp_process_7(connection, tcp_packet, seglen);
+		break;
 
-	/* check, if have RST or SYN flag */
-	if ((tcp_check_2(tcp_packet)) ||
-	    (tcp_check_4(connection, tcp_packet, seglen)) )
-	{
+	case PXE_TCP_LAST_ACK:
+		/* if got here, means we have ACK */
 		connection->state = PXE_TCP_CLOSED;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_time_wait(): new state - CLOSED\n");
-#endif
-		pxe_resend_free(connection);
-		free_connection(connection);
 		return (0);
-	}
-	
-	if (!tcp_check_5(connection, tcp_packet))
-		return (0);
-	
-	/* ignore URG flag in this state */
+		break;
+		
+	case PXE_TCP_TIME_WAIT:
+		/* check TIME_WAIT time */
+		tcp_check_time_to_die(connection);
+		/* going to return */
 
-	/* ignore data processing */
-	
-	/* check TIME_WAIT time */
-	tcp_check_time_to_die(connection);
+	case PXE_TCP_CLOSE_WAIT:
+		/* just return */
 
-	return (0);
-}
-
-/* tcp_close_wait() - CLOSE_WAIT state handler. TODO: implement
- * in:
- *	tcp_packet - incoming packet data
- *	connection - current connection
- * out:
- *	0 - don't interested more in this packet
- *	1 - interested
- *	2 - try next state handler
- */
-static int
-tcp_close_wait(PXE_TCP_PACKET *tcp_packet, PXE_TCP_CONNECTION *connection,
-	       uint16_t seglen)
-{
-	/* first check, if acceptable at all */
-	if (!tcp_check_1(connection, tcp_packet, seglen))
+	default:
 		return (0);
-
-	/* check, if have RST or SYN flag */
-	if ((tcp_check_2(tcp_packet)) ||
-	    (tcp_check_4(connection, tcp_packet, seglen)) )
-	{
-		connection->state = PXE_TCP_CLOSED;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_close_wait(): new state - CLOSED\n");
-#endif
-		pxe_resend_free(connection);
-		return (0);
+		break;
 	}
 	
-	if (!tcp_check_5(connection, tcp_packet))
-		return (0);
+	/* eighth, check FIN */
+	if (tcp_check_8(tcp_packet)) {
 	
-	/* ignore URG flag */
+		switch (connection->state) {
+		case PXE_TCP_ESTABLISHED:
+			/* remote host requested connection break */
+			connection->state = PXE_TCP_CLOSE_WAIT;
+			break;
+			
+		case PXE_TCP_FIN_WAIT1:
+			if (state_out == PXE_TCP_FIN) {
+				connection->state = PXE_TCP_TIME_WAIT;
+			}  else {
+				connection->state = PXE_TCP_CLOSING;
+			}
+			break;
 
-	/* ignore data processing, input connection closed by remote host */
-
-	return (0);
-}
-
-/* tcp_last_ack() - LAST_ACK state handler.
- * in:
- *	tcp_packet - incoming packet data
- *	connection - current connection
- * out:
- *	0 - don't interested more in this packet
- *	1 - interested
- *	2 - try next state handler
- */
-static int
-tcp_last_ack(PXE_TCP_PACKET *tcp_packet, PXE_TCP_CONNECTION *connection,
-	     uint16_t seglen)
-{
-	/* first check, if acceptable at all */
-	if (!tcp_check_1(connection, tcp_packet, seglen))
-		return (0);
-
-	/* check, if have RST or SYN flag */
-	if ((tcp_check_2(tcp_packet)) ||
-	    (tcp_check_4(connection, tcp_packet, seglen)) )
-	{
-		connection->state = PXE_TCP_CLOSED;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_last_ack(): new state - CLOSED\n");
-#endif		
-		pxe_resend_free(connection);
-		return (0);
-	}
-	
-	if (!tcp_check_5(connection, tcp_packet))
-		return (0);
-
-	if (connection->state_out == PXE_TCP_FIN) {
-		connection->state = PXE_TCP_CLOSED;
-#ifdef PXE_TCP_DEBUG
-		printf("tcp_last_ack(): new state - CLOSED\n");
-#endif		
-		pxe_resend_free(connection);
-		return (0);
+		case PXE_TCP_FIN_WAIT2:
+			connection->state = PXE_TCP_TIME_WAIT;
+			break;
+			
+		default:
+			break;
+		}
 	}
-	
-	/* ignore URG flag */
-	
-	/* if got here, means we have ACK */
-	connection->state = PXE_TCP_CLOSED;
 
 	return (0);
 }
@@ -907,9 +681,9 @@
 				    dst_port, PXE_TCP_PROTOCOL);
 
 	if (sock == NULL) {	/* nobody is interested in this packet */
-#ifdef PXE_TCP_DEBUG
+/* #ifdef PXE_TCP_DEBUG */
 		printf("pxe_tcp_callback(): packet filtered out, sending RST.\n");
-#endif
+/* #endif */
 		if (flags & PXE_TCP_ACK)
 			tcp_send_rst_for(tcp_packet, 0,
 			    tcp_packet->tcphdr.ack_next, PXE_TCP_RST, data_size);
@@ -981,11 +755,12 @@
 		/* if we know sequence number, then check it */
 		if (seq != connection->next_recv) {
 			/* not next in order, drop it, send ACK */
-#ifdef PXE_TCP_DEBUG
+/* #ifdef PXE_TCP_DEBUG */
 			printf("pxe_tcp_callback(): got %d != awaited %d\n",
 			    seq - connection->irs,
 			    connection->next_recv - connection->irs);
-#endif
+/* #endif */
+			pxe_tcp_syssend(connection, PXE_TCP_ACK);
 			return (0);
 		}
 	} else {
@@ -999,25 +774,25 @@
 	
 		while (1) {
 #ifdef PXE_TCP_DEBUG_HELL
-			printf("pxe_tcp_callback(): connection state = 0x%x\n",
-			    connection->state);
-#endif		    
-			if (state_functions[connection->state] != NULL) {
+			printf("pxe_tcp_callback(): connection state = %s\n",
+			    strstates[connection->state]);
+#endif
 				
-				result =
-				    state_functions[connection->state](tcp_packet,
-					connection, data_size);
+			if (connection->state == PXE_TCP_SYN_SENT) {
+				result = tcp_syn_sent(tcp_packet, connection, data_size);
+			} else {
+
+				result = pxe_tcp_process(tcp_packet, connection, data_size);
+			}
 			    
-				if (result == 2)
-					continue;
+			if (result == 2)
+				continue;
 			
-				break;
-			} else 	/* state handler not registered */
-				break;    
+			break;
 		}
 	}
 	
-	/* check ACKed packets*/
+	/* check ACKed packets */
 	pxe_resend_update(connection);
 	
 	/* check if need to resend some segments */


More information about the p4-projects mailing list