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