PERFORCE change 122856 for review

Alexey Tarasov taleks at FreeBSD.org
Wed Jul 4 14:58:31 UTC 2007


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

Change 122856 by taleks at taleks_th on 2007/07/04 14:57:42

	Updated TCP code, adding pxe_core_recv_packets() in read and finish segment functions.
	pce_buffer: fixed cyclic buffer issue with writing and reading in one of the cases.
	pxe_core: removed packet array, now only one packet structure is used, related code in other modules will be updated later (total removing of pxe_alloc_packet() func).. Some other functions seems to be candidate to be removed from this module.
	pxe_connection: added stats function, main changes in write/read functions.
	pxe_http: new module, implements pxe_fetch() to get data via http. Now generates header requests and outputs raw received data to console.
	Small changes in other modules.

Affected files ...

.. //depot/projects/soc2007/taleks-pxe_http/Makefile#8 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_buffer.c#3 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_connection.c#4 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_connection.h#3 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#17 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_http.c#3 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_http.h#1 add
.. //depot/projects/soc2007/taleks-pxe_http/pxe_ip.c#8 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_segment.c#4 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_sock.c#11 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_tcp.c#6 edit

Differences ...

==== //depot/projects/soc2007/taleks-pxe_http/Makefile#8 (text+ko) ====

@@ -5,7 +5,7 @@
 
 SRCS= pxe_conv.c pxe_isr.S pxe_mem.c pxe_buffer.c pxe_await.c pxe_arp.c pxe_ip.c pxe_mutex.c \
 	pxe_core.c pxe_icmp.c pxe_udp.c pxe_filter.c pxe_dns.c pxe_dhcp.c pxe_segment.c pxe_tcp.c pxe_sock.c \
-	pxe_connection.c
+	pxe_connection.c pxe_http.c
 
 CFLAGS+=	-I${.CURDIR}/../../common -I${.CURDIR}/../btx/lib \
 		-I${.CURDIR}/../../../contrib/dev/acpica \
@@ -14,7 +14,7 @@
 CFLAGS+=	-I${.CURDIR}/../../../../lib/libstand/
 
 #debug flag
-CFLAGS+=	-DPXE_DEBUG
+#CFLAGS+=	-DPXE_DEBUG
 #CFLAGS+=	-DPXE_DEBUG_HELL
 
 .include <bsd.lib.mk>

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

@@ -24,19 +24,34 @@
 		pxe_memcpy(from, buf->data + buf->fstart, to_write);
 		buf->fstart += to_write;
 			
-	} else { /* need to place, using two memcpy operations */
+	} else {/* may be need to place, using two memcpy operations */
+		
 		/* right part of space */
 		uint16_t part1 = buf->bufsize - buf->fstart;
-		pxe_memcpy(from, buf->data + buf->fstart, part1);
-		/* left part of space */
-		uint16_t part2 = to_write - part1;
-		pxe_memcpy(from + part1, buf->data, part2);
+		uint16_t part2 = 0;
 		
-		buf->fstart = part2;
+		if (part1 >= to_write) {
+			pxe_memcpy(from, buf->data + buf->fstart, to_write);
+			buf->fstart += to_write;
+		} else {
+			pxe_memcpy(from, buf->data + buf->fstart, part1);
+			/* left part of space */
+			part2 = to_write - part1;
+			pxe_memcpy(from + part1, buf->data, part2);
+			buf->fstart = part2;			
+		}
+#ifdef PXE_DEBUG_HELL
+		printf("pxe_buffer_write(): fstart %d, fend %d, bufleft %d (of %d)\n\tpart1 %d, part2 %d, to_write %d (%d)\n",
+		    buf->fstart, buf->fend, buf->bufleft, buf->bufsize, part1, part2, to_write, size);
+#endif		
 	}
 
+
 	buf->bufleft -= to_write;
-	
+
+#ifdef PXE_DEBUG_HELL			
+	printf("bufleft %d (-%d)\n", buf->bufleft, to_write);
+#endif	
 	return (to_write);
 }
 
@@ -81,8 +96,8 @@
 		
 			if (to != NULL)
 				pxe_memcpy(buf->data, to, to_read);
-				buf->fend = to_read;	
-		
+
+			buf->fend = to_read;	
 		}
 	
 	} else { /* third case: |..e**s...|*/
@@ -92,8 +107,14 @@
 		buf->fend += to_read;	
 	}
 	
+
 	buf->bufleft += to_read;
-	
+
+#ifdef PXE_DEBUG_HELL		
+	printf("pxe_buffer_read(): bufleft %d (+%d), fstart %d, fend %d\n",
+	    buf->bufleft, to_read, buf->fstart, buf->fend
+	);
+#endif	
 	return (to_read);
 }
 
@@ -147,6 +168,10 @@
 	if (buffer->data == NULL) { /* already released */
 		return;
 	}
-	
+#ifdef PXE_DEBUG
+	printf("pxe_buffer_memfree(): buffer 0x%x, data 0x%x, bufleft: %d.\n",
+	    buffer, buffer->data, buffer->bufleft
+	);
+#endif	
 	pxe_free(buffer->data);
 }

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

@@ -195,6 +195,9 @@
 int
 pxe_tcp_disconnect(PXE_SOCKET *sock)
 {
+#ifdef PXE_DEBUG
+	printf("pxe_tcp_disconnect(): started.\n");
+#endif
 	PXE_FILTER_ENTRY	*filter = sock->filter;	
 	
 	if (filter == NULL) {
@@ -208,19 +211,27 @@
 		return (0);
 	}
 
-	if ( (connection->state == PXE_TCP_CLOSED) || 
-	     (connection->state >= PXE_TCP_CLOSE_WAIT) )
-	{	/* already closing */
+	/* process recieved,  queued but not processed packets.
+	 * This is useful if server requested breaking of connection
+	 * (passive closing) and our disconnect just finishes initiated
+	 * by server sequence, no need to send initial FIN (active closing)
+	 */
+	pxe_core_recv_packets();
+	
+	if (connection->state == PXE_TCP_CLOSED) { /* already  closed */
 #ifdef PXE_DEBUG
 		printf("pxe_tcp_disconnect(): connection already is closing.\n");
 #endif		
 		return (1);
 	}
 	
-	if (!pxe_tcp_syssend(connection, PXE_TCP_FIN | PXE_TCP_ACK)) {
-		printf("pxe_tcp_disconnect(): failed to send FIN.\n");
-		free_connection(connection);
-		return (0);
+	/* if connection in established state - initiate active close */
+	if (connection->state == PXE_TCP_ESTABLISHED) {
+		if (!pxe_tcp_syssend(connection, PXE_TCP_FIN | PXE_TCP_ACK)) {
+			printf("pxe_tcp_disconnect(): failed to send FIN.\n");
+			free_connection(connection);
+			return (0);
+		}
 	}
 
 	/* update sequence number */	
@@ -241,9 +252,15 @@
 	 */
 	if (!pxe_await(tcp_await, 5, PXE_TCP_MSL / 5, &wait_data)) { /* failed to get to TIME_WAIT state */
 	    	free_connection(connection);
-		return (0);
+		
+		if (connection->state != PXE_TCP_CLOSED)
+			return (0);
 	}
 
+	if (connection->state == PXE_TCP_CLOSED) {
+		pxe_filter_remove(filter);
+	}
+			
 	pxe_resend_free(connection);
 	
 #ifdef PXE_DEBUG
@@ -295,7 +312,7 @@
 	void	 *segment_data = (void *)(segment + 1);
 	
 	while (sent_data < size_to_send) {
-	
+		
 		/* have no allocated segment for writing data, try allocate it */
 		if (segment == NULL) {
 			/* allocating new segment */
@@ -314,10 +331,10 @@
 		
 		/* calculating free space in segment packet */
 		bufleft = connection->chunk_size * PXE_TCP_CHUNK_COUNT;
-		bufleft -= sizeof(PXE_TCP_QUEUED_SEGMENT) - segment->size;
+		bufleft -= sizeof(PXE_TCP_QUEUED_SEGMENT) + segment->size;
 		/* how much left to send */
 		send_now = size_to_send - sent_data;
-		
+
 		if (send_now < bufleft) {
 			/* copy data to segment space, actually there is no send, till
 			 * segment is fully filled or called pxe_tcp_push()
@@ -337,6 +354,8 @@
 		
 		/* finish segment */
 		tcp_finish_segment(connection, segment, PXE_TCP_ACK);
+		/* updating next_send counter */
+		connection->next_send += segment->size - sizeof(PXE_TCP_PACKET);
 
 		segment->resend_at = pxe_get_secs() + PXE_RESEND_TIME;
     
@@ -345,6 +364,7 @@
 			/* this segment will be resent later, so continue normal processing */
 		}
 		
+		pxe_core_recv_packets();
 		segment = NULL;
 		connection->segment = NULL;
 	}
@@ -379,8 +399,26 @@
 		return (-1);	/* connection closed and no data in buffer */
 	}
 
+	int result = pxe_buffer_read(recv_buffer, data, size_to_read);
 
-	return (pxe_buffer_read(recv_buffer, data, size_to_read));
+	if (result != 0) { 
+
+		/* if receive window was zero and now is big enough, notify remote host */
+		if ( (recv_buffer->bufleft > PXE_DEFAULT_RECV_BUFSIZE / 4) &&
+		     (connection->winlock == 1) )
+		{
+			if (!pxe_tcp_syssend(connection, PXE_TCP_ACK)) {
+				printf("pxe_tcp_read(): failed to notify remote host about window.\n");
+			} else {
+				connection->winlock = 0;
+			}
+		}
+	}
+	
+	/* process new packets if there are any */
+	pxe_core_recv_packets();
+	
+	return (result);
 }
 
 /* pxe_tcp_push() - flushes send buffer (actually current send segment)
@@ -400,7 +438,10 @@
 		return (0);
 	}
 
-	if ( connection->state != PXE_TCP_ESTABLISHED ){
+	if (connection->state != PXE_TCP_ESTABLISHED) {
+		printf("pxe_tcp_push(): connection 0x%x is not in established state(%d).\n",
+		    connection, connection->state
+		);
 		return (0);	/* connection not in established state, ignore available data */
 	}
 	
@@ -414,14 +455,34 @@
 	tcp_finish_segment(connection, segment, PXE_TCP_ACK | PXE_TCP_PSH);
 
 	segment->resend_at = pxe_get_secs() + PXE_RESEND_TIME;
-    
+    	connection->next_send += segment->size - sizeof(PXE_TCP_PACKET);
+	
 	if (!pxe_tcp_send_segment(connection, segment)) {
 		printf("pxe_tcp_push(): failed to send segment.\n");
 		/* this segment will be resent later, so continue normal processing */
 	}
-		
+
 	segment = NULL;
 	connection->segment = NULL;
 
 	return (1);
 }
+
+void
+pxe_connection_stats()
+{
+	printf("pxe_connection_stats():\n");
+
+	int con_index = 0;
+	PXE_TCP_CONNECTION *connection = NULL;
+	
+	for ( ; con_index < PXE_MAX_TCP_CONNECTIONS; ++con_index) {
+
+		connection = &tcp_connections[con_index];
+		
+		printf("%d: filter: 0x%x, state: %d\n  nxt_snd: %d, nxt_rcv: %d, iss: %d, irs: %d\n",
+		    con_index, connection->filter, connection->state,
+		    connection->next_send, connection->next_recv
+		);
+	}
+}

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

@@ -34,7 +34,7 @@
     uint8_t     state_out;      /* show latest acked packet flags (e.g. we sent FIN and it was ACKed,
 				 * here will be PXE_TCP_FIN. Currently used but ACKing not checked.
 				 */
-	
+    uint8_t	winlock;	/* flag to becomes 1 when recieve window is zero*/
     uint32_t    next_recv;      /* next sequence number to accept */
     uint32_t    next_send;      /* next sequence number to send */
     uint32_t    una;            /* unaccepted sequence number */
@@ -68,6 +68,9 @@
 /* initialisztion routine */
 void pxe_connection_init();
 
+/* statistics */
+void pxe_connection_stats();
+
 /* returns associated connection by filter */
 PXE_TCP_CONNECTION * filter_to_connection(PXE_FILTER_ENTRY *filter);
 

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

@@ -31,7 +31,7 @@
  */
  
 /* pxe core structures*/
-PXE_PACKET          core_packets[PXE_MAX_PACKETS];  /* buffered packets */
+PXE_PACKET          core_packet;	   /* current processing packet */
 pxe_protocol_call   core_protocol[256];    /* protocol's  callback fuctions */
 PXE_MUTEX           core_mutex = {0, 0};   /* mutex used in packet allocation */
 
@@ -45,7 +45,6 @@
 uint32_t   	    packets_sent = 0;
 uint32_t   	    packets_received = 0;
 
-
 /* pxe_core_undi_startup() - performs UNDI startup call during pxe_core_init()
  * in:
  *	none
@@ -123,7 +122,7 @@
 #endif
 	t_PXENV_GET_CACHED_INFO	*gci_p = NULL;
 
-	pxe_memset(core_packets, 0, sizeof(core_packets));
+	pxe_memset(&core_packet, 0, sizeof(core_packet));
 	pxe_memset(core_protocol, 0, sizeof(core_protocol));
 	pxe_memset(core_ips, 0, sizeof(core_ips));
 	
@@ -397,12 +396,9 @@
 {
 	int i = 1;
 
-	for (; i < PXE_MAX_PACKETS; ++i) {
+	if (core_packet.data)
+		pxe_free(core_packet.data);
 
-		if (core_packets[i].data)
-			pxe_free(core_packets[i].data);
-	}
-
 	/* 1. uninstall isr */
 	pxe_core_remove_isr();
 
@@ -537,30 +533,6 @@
 	return (status);
 }
 
-/* TODO: think about removing of this function
- * flushes pending, aborted, wrong and etc packets 
- */
-int
-pxe_core_flush_packets()
-{
-	int i = 0;
-
-	for (; i < PXE_MAX_PACKETS; ++i) {
-		PXE_IP_HDR *iphdr=(PXE_IP_HDR *)(core_packets[i].data);
-
-		if (iphdr == NULL) {   /* dummy packet */
-			continue;
-		}
-
-		if (core_protocol[iphdr->protocol]) { /* protocol registered */
-			core_protocol[iphdr->protocol](&core_packets[i],
-			    PXE_CORE_CHECK, NULL);
-		}
-	}
-
-	return (1);
-}
-
 /* pxe_core_get_packet() - checks, if there are any new pacjets in receive queue
  * in:
  *	func	- function to fill in FuncFlag of t_PXENV_UND_ISR structure
@@ -765,28 +737,15 @@
 			pack = pxe_core_alloc_packet(buffer_size);
 
 			if (pack == NULL) {
-				pxe_core_flush_packets();
+				++packets_dropped;
+				drop_flag = 1;
+			} else {
 
-				/* trying to get free packets by sending and dropping */
-				pack = pxe_core_alloc_packet(buffer_size);
-
-				/* failed to alloc packet, dropping packet
-				 * NOTE: may be good idea, simply abort current receive cycle,
-				 *       and wait if some protocol will free packet 
+				/* pointing user_data to beginning of data.
+				 * It's used by pxe_core_receive() during receiving packet.
 				 */
-				if (pack == NULL) {
-					++packets_dropped;
-					drop_flag = 1;
-				}
+				pack->user_data = pack->data;
 			}
-
-
-	/*  pointing user_data to beginning of data.
-	 * It's used by pxe_core_receive() during receiving packet.
-	 */
-
-			if (pack != NULL)
-				pack->user_data = pack->data;
 		}
 	}
 
@@ -889,45 +848,36 @@
 {
 	int i = 1;    /* packet index */
 
-	pxe_mutex_own(&core_mutex, PXE_OWNER_CORE);
+	if (core_packet.state == PXE_PACKET_STATE_FREE) {
+		/* packet structure seems to be free */
+		/* mark it busy */
+		core_packet.state = PXE_PACKET_STATE_USING;
 
-	/* searching free packets structures */
-	for (; i < PXE_MAX_PACKETS; ++i) {
-		if (core_packets[i].state == PXE_PACKET_STATE_FREE) {
-			/* packet structure seems to be free */
-			/* mark it busy */
-			core_packets[i].state = PXE_PACKET_STATE_USING;
+		if (core_packet.data_size < packet_size) {
+			/* packet contains less memmory than needed */
 
-			if (core_packets[i].data_size < packet_size) {
-				/* packet contains less memmory than needed */
+			void *data = pxe_alloc(packet_size + MEDIAHDR_LEN_ETH);
+			pxe_free(core_packet.data);
+			core_packet.raw_data = data;
 
-				void *data = pxe_alloc(packet_size + MEDIAHDR_LEN_ETH);
-				pxe_free(core_packets[i].data);
-				core_packets[i].raw_data = data;
-
+				
+			/* failed to allocate enough memory for packet */
+			if (data == NULL) {
+				core_packet.data_size = 0;
+				core_packet.raw_size = 0;
+				core_packet.data = NULL;
 				
-				/* failed to allocate enough memory for packet */
-				if (data == NULL) {
-					core_packets[i].data_size = 0;
-					core_packets[i].raw_size = 0;
-					core_packets[i].data = NULL;
-					
-					
-					pxe_mutex_free(&core_mutex, PXE_OWNER_CORE);
-					return (NULL);
-				}
-
-				core_packets[i].data_size = packet_size;
-				core_packets[i].raw_size = packet_size + MEDIAHDR_LEN_ETH;
-				core_packets[i].data = data + MEDIAHDR_LEN_ETH;
+				return (NULL);
 			}
 
-			pxe_mutex_free(&core_mutex, PXE_OWNER_CORE);
-			return &core_packets[i];
+			core_packet.data_size = packet_size;
+			core_packet.raw_size = packet_size + MEDIAHDR_LEN_ETH;
+			core_packet.data = data + MEDIAHDR_LEN_ETH;
 		}
+
+		return &core_packet;
 	}
 
-	pxe_mutex_free(&core_mutex, PXE_OWNER_CORE);
 	return (NULL);
 }
 
@@ -938,9 +888,7 @@
 pxe_core_commit(PXE_PACKET *pack)
 {
 
-	pxe_mutex_own(&core_mutex, PXE_OWNER_CORE);
 	pack->state = PXE_PACKET_STATE_FREE;
-	pxe_mutex_free(&core_mutex, PXE_OWNER_CORE);
 }
 
 /* TODO: think if this function is useful

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

@@ -1,21 +1,84 @@
 #include <stand.h>
 
 #include "pxe_core.h"
-#include "pxe_icmp.h"
+#include "pxe_dns.h"
+#include "pxe_http.h"
 #include "pxe_ip.h"
+#include "pxe_tcp.h"
+
+char client_hdr[PXE_MAX_HTTP_HDRLEN];
 
 int
-pxe_test_main()
+pxe_fetch(char *server_name, char *filename)
 {
-    pxe_ipaddr ip;
-    ip.ip=0xC0A80001;
+	PXE_IPADDR	server;
+	
+	printf("pxe_fetch(): fetching http://%s:80/%s\n", server_name, filename);
+	server.ip = pxe_gethostbyname(server_name);
+	
+	if (server.ip == 0) {
+		printf("pxe_fetch(): cannot resolve server name.\n");
+		return (0);
+	} else {
+		printf("pxe_fetch(): resolved as: %d.%d.%d.%d\n",
+		    server.octet[0], server.octet[1], server.octet[2], server.octet[3]
+		);
+	}
+	
+	int socket = pxe_socket();
+	
+	int result = pxe_connect(socket, server.ip, 80, PXE_TCP_PROTOCOL);
+	
+	if (result == -1) {
+		printf("pxe_fetch(): failed to connect.\n");
+		return (0);
+	}
+
+	sprintf(client_hdr, "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", filename, server_name);
 
-    printf("pxe icmp dummy test.\n");
+	int len = strlen(client_hdr);
 
-    pxe_core_init();
-    pxe_icmp_init();
+	if (len != pxe_send(socket, client_hdr, len)) {
+		printf("pxe_fetch(): failed to send request.\n");
+		pxe_close(socket);
+		return (0);
+	}
 
-    pxe_ping(&ip, 0);
+	if (pxe_push(socket) == -1) {
+		printf("pxe_fetch(): failed to push request.\n");
+		pxe_close(socket);
+		return (0);
+	}
 
-    return (0);
+	int count = 0;
+	
+	while (1) {
+		result = pxe_recv(socket, client_hdr, PXE_MAX_HTTP_HDRLEN-1);
+		
+		if (result == -1) {
+			break;
+		}
+		
+		if (result == 0)
+			continue;
+		
+		count += result;
+		client_hdr[result] = '\0';
+		
+		printf("%s", client_hdr);
+		
+		if (count == 0) {
+			if (!strncmp(client_hdr, "HTTP/1.1 200 OK", result)) {
+				
+			}
+			else {
+				pxe_close(socket);
+				return (0);
+			}
+		}
+	}
+	
+	printf("\npxe_fetch(): %d byte(s) received.\n", count);
+	
+	return (1);
 }

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

@@ -27,7 +27,7 @@
 	myip.ip = pxe_get_ip32(PXE_IP_MY);
 	
 	/* make route for local network */
-	uint32_t	mask = pxe_get_ip32(PXE_IP_MASK);
+	uint32_t	mask = pxe_get_ip32(PXE_IP_NETMASK);
 	
 	if (mask == 0)	/* mask is not set via DHCP/BOOTP, setting it manually */
 		mask = pxe_ip_get_netmask(myip.ip);

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

@@ -75,6 +75,9 @@
 PXE_TCP_QUEUED_SEGMENT *
 tcp_segment_alloc(PXE_TCP_CONNECTION *connection, int allocBig)
 {
+#ifdef PXE_DEBUG
+	printf("tcp_segment_alloc(): connection 0x%x, big = %d.\n", connection, allocBig);
+#endif
 	int			block_index = 0;
 	PXE_BUFFER		*buffer = connection->send;
 	uint8_t			*buf_blocks = connection->buf_blocks;
@@ -136,6 +139,9 @@
 void
 tcp_segment_free(PXE_TCP_CONNECTION *connection, int block_index, PXE_TCP_QUEUED_SEGMENT *segment)
 {
+#ifdef PXE_DEBUG
+	printf("tcp_segment_free(): connection: 0x%x, block: %d, chunk: 0x%x\n", connection, block_index, segment);
+#endif
 	uint8_t		*block = &connection->buf_blocks[block_index];
 	
 	if (segment->status == PXE_SEGMENT_FREE) /* already released */
@@ -161,6 +167,9 @@
 void
 pxe_resend_check(PXE_TCP_CONNECTION *connection)
 {
+#ifdef PXE_DEBUG
+	printf("pxe_resend_check(): started.\n");
+#endif
         PXE_BUFFER              *buffer = connection->send;
         void                    *data = buffer->data;
         int                     block_index = 0;
@@ -187,12 +196,16 @@
 				
                         if (cur_time >= segment->resend_at) { /* time to resend */
 #ifdef PXE_DEBUG
-				printf("pxe_resend_check(): %d:%d resending...\n", segment->resend_at, cur_time);
+				printf("pxe_resend_check(): %d:%d resending (next try at: %d)\n",
+				    segment->resend_at, cur_time, segment->resend_at + PXE_RESEND_TIME * (segment->trys + 1)
+				);
 #endif				
+				segment->trys += 1;				
+				segment->resend_at += PXE_RESEND_TIME * segment->trys;
+				
 				tcp_update_segment(connection, segment);
                                 pxe_tcp_send_segment(connection, segment);
-				segment->trys += 1;				
-				segment->resend_at += PXE_RESEND_TIME * segment->trys;
+
             		}
                         continue;
                 }
@@ -206,13 +219,16 @@
 
                                 if (cur_time >= segment->resend_at) { /* time to resend */
 #ifdef PXE_DEBUG
-					printf("pxe_resend_check(): %d:%d resending...\n", segment->resend_at, cur_time);
+					printf("pxe_resend_check(): %d:%d resending (next try at: %d)\n",
+					    segment->resend_at, cur_time, segment->resend_at + PXE_RESEND_TIME * (segment->trys + 1)
+					);
 #endif
-					tcp_update_segment(connection, segment);
-	                                pxe_tcp_send_segment(connection, segment);
 					/* resend later, with more delay with every try */
 					segment->trys += 1;				
 					segment->resend_at += PXE_RESEND_TIME * segment->trys;
+					
+					tcp_update_segment(connection, segment);
+	                                pxe_tcp_send_segment(connection, segment);
 	                        }
 	                }
 
@@ -232,6 +248,9 @@
 void
 pxe_resend_update(PXE_TCP_CONNECTION *connection)
 {
+#ifdef PXE_DEBUG
+	printf("pxe_resend_update(): started.\n");
+#endif
         PXE_BUFFER              *buffer = connection->send;
         void                    *data = buffer->data;
         int                     block_index = 0;
@@ -478,7 +497,7 @@
 	
 	printf(" %d bytes.\n", length);
 #endif
-
+	/* check received packets */
         return (1);
 }
 

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

@@ -146,6 +146,13 @@
 	/* socket buffers seems not be used more */
 	pxe_buffer_memfree(&sock->send_buffer);
 	pxe_buffer_memfree(&sock->recv_buffer);
+
+	if (filter == NULL) { /* sanity check */
+#ifdef PXE_DEBUG
+		printf("pxe_close(): filter is NULL.\n");
+#endif
+		return (0);
+	}
 	
 	/* UDP socket closing is simple */	
 	if (filter->protocol == PXE_UDP_PROTOCOL) {
@@ -452,7 +459,7 @@
 {
 
 	if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) {
-		printf("pxe_recv(): invalid socket %d.\n", socket);
+		printf("pxe_send(): invalid socket %d.\n", socket);
 		return (-1);
 	}
 	
@@ -464,7 +471,6 @@
 		return pxe_udp_write(sock, buf, buflen);
 		
 	} else if (filter->protocol == PXE_TCP_PROTOCOL) {
-	
 		return pxe_tcp_write(sock, buf, buflen);
 	}	
 	

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

@@ -46,7 +46,7 @@
  *	none
  */
 static void
-check_time_to_die(PXE_TCP_CONNECTION *connection)
+tcp_check_time_to_die(PXE_TCP_CONNECTION *connection)
 {
 	/* if connection in other states - do nothing */
 	if (connection->state != PXE_TCP_TIME_WAIT)
@@ -55,6 +55,9 @@
 	time_t cur_time = pxe_get_secs();
 
 	if (cur_time - connection->last_recv > 2 * PXE_TCP_MSL) {
+#ifdef PXE_DEBUG
+		printf("tcp_check_time_to_die(): time for 0x%x connection.\n", connection);
+#endif
 		/* release filter */
 		PXE_FILTER_ENTRY *filter = connection->filter;
 		
@@ -88,6 +91,7 @@
 	
 	connection.chunk_size = PXE_TCP_SYSBUF_SIZE;
 	connection.buf_blocks[0] = PXE_TCP_BLOCK_FREE;
+	connection.send = &sysbuf;
 	
 	return pxe_tcp_syssend(&connection, flags);
 }
@@ -157,6 +161,13 @@
 		return (1);
 	}
 
+	PXE_BUFFER	*buffer = connection->recv;
+	
+	if (buffer) {
+		if (buffer->bufleft == 0)
+			connection->winlock = 1;
+	}
+
 	pxe_tcp_syssend(connection, PXE_TCP_ACK);
 
 #ifdef PXE_DEBUG_HELL
@@ -676,6 +687,7 @@
 		printf("tcp_time_wait(): new state - CLOSED\n");
 #endif
 		pxe_resend_free(connection);
+		free_connection(connection);
 		return (0);
 	}
 	
@@ -690,6 +702,9 @@
 	}
 */
 	/* ignore data processing */
+	
+	/* check TIME_WAIT time */
+	tcp_check_time_to_die(connection);
 
 	return (0);
 }
@@ -946,6 +961,9 @@
 	/* check if need to resend some segments */
 	pxe_resend_check(connection);
 	
+	/* check time to die */
+	tcp_check_time_to_die(connection);
+	
 	return (result);
 }                                                            
 
@@ -965,12 +983,13 @@
 	pxe_core_register(PXE_TCP_PROTOCOL, pxe_tcp_callback);
 
 	/* sysbuf init */
+	pxe_memset(&bufdata, 0 , PXE_TCP_SYSBUF_SIZE);
 	sysbuf.data = &bufdata;
 	/* not really need, cause not using buffer realted functions */
 	sysbuf.bufleft = PXE_TCP_SYSBUF_SIZE;
 	sysbuf.bufsize = PXE_TCP_SYSBUF_SIZE;
 	sysbuf.fstart = 0;
-	sysbuf.fend = PXE_TCP_SYSBUF_SIZE - 1;
+	sysbuf.fend = PXE_TCP_SYSBUF_SIZE;
 }
 
 /* pxe_tcp_syssend() - send system packets via TCP protocol


More information about the p4-projects mailing list