Date: Sun, 22 Jul 2007 14:15:22 GMT From: Alexey Tarasov <taleks@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 123897 for review Message-ID: <200707221415.l6MEFM5e089380@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=123897 Change 123897 by taleks@taleks_th on 2007/07/22 14:15:16 pxe_sock: added pxe_socket_state() funxtion, used to get current socket state. pxe_http: added support for keep-alive connections and reestablishing of closed connections. Affected files ... .. //depot/projects/soc2007/taleks-pxe_http/Makefile#11 edit .. //depot/projects/soc2007/taleks-pxe_http/httpfs.c#4 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_connection.c#10 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_http.c#8 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_http.h#6 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_sock.c#16 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_sock.h#14 edit Differences ... ==== //depot/projects/soc2007/taleks-pxe_http/Makefile#11 (text+ko) ==== @@ -30,6 +30,7 @@ #CFLAGS+= -DPXE_ARP_DEBUG #CFLAGS+= -DPXE_ARP_DEBUG_HELL # httpfs module -#CFLAGS+= -DPXE_HTTP_DEBUG +CFLAGS+= -DPXE_HTTP_DEBUG +#CFLAGS+= -DPXE_HTTP_DEBUG_HELL .include <bsd.lib.mk> ==== //depot/projects/soc2007/taleks-pxe_http/httpfs.c#4 (text+ko) ==== @@ -124,7 +124,10 @@ } f->f_fsdata = (void *) httpfile; - + +#ifdef PXE_HTTP_DEBUG + printf("http_open(): success\n"); +#endif return (0); } @@ -138,7 +141,7 @@ return (EINVAL); } -#ifdef PXE_HTTP_DEBUG +#ifdef PXE_HTTP_DEBUG_HELL printf("http_read(): %s:%llu+%lu\n", httpfile->filename, httpfile->offset, size); #endif @@ -148,7 +151,7 @@ { if (resid) *resid = size; -#ifdef PXE_HTTP_DEBUG +#ifdef PXE_HTTP_DEBUG_HELL printf("http_read(): EOF\n"); #endif return (0); ==== //depot/projects/soc2007/taleks-pxe_http/pxe_connection.c#10 (text+ko) ==== @@ -536,6 +536,10 @@ if ( (connection->state != PXE_TCP_ESTABLISHED) && (recv_buffer->bufleft == recv_buffer->bufsize) ) { +#ifdef PXE_DEBUG + printf("pxe_tcp_read(): state %u, no data in buffer\n", + connection->state); +#endif return (-1); /* connection closed and no data in buffer */ } ==== //depot/projects/soc2007/taleks-pxe_http/pxe_http.c#8 (text+ko) ==== @@ -91,7 +91,7 @@ if (found == NULL) return (0); /* failed to parse response code */ - + found = strstr(data, "Content-Length:"); parse_data->size = PXE_HTTP_SIZE_UNKNOWN; @@ -126,8 +126,12 @@ while (count < maxsize - 1) { result = pxe_recv(socket, &data[count], maxsize - 1 - count); - if (result == -1) /* failed to recv */ + if (result == -1) { /* failed to recv */ +#ifdef PXE_HTTP_DEBUG_HELL + printf("http_get_header(): pxe_recv() failed\n"); +#endif break; + } if (result == 0) /* nothing received yet */ continue; @@ -157,6 +161,65 @@ return (result); } +/* http_get_header2() - gets from socket data related to http header + * byte by byte. + * in: + * socket - socket descriptor + * data - pointer to working buffer + * maxsize - buffer size + * found_result - if not NULL, there stored pointer to end of header + * count_result - if not NULL, received count stored + * out: + * -1 - failed + * >=0 - success + */ +int +http_get_header2(int socket, char *data, size_t maxsize, + char **found_result, size_t *count_result) +{ + int result = -1; + size_t count = 0; + char *found = NULL; + char ch = '\0'; + + while (count < maxsize - 1) { + result = pxe_recv(socket, &data[count], 1); + + if (result == -1) { /* failed to recv */ +#ifdef PXE_HTTP_DEBUG_HELL + printf("http_get_header2(): pxe_recv() failed\n"); +#endif + break; + } + + if (result == 0) /* nothing received yet */ + continue; + + /* make string ended with '\0' */ + ch = data[count + result]; + data[count + result] = '\0'; + + /* searching end of reply */ + found = strstr(&data[count], "\r\n\r\n"); + + /* restore char replaced by zero */ + data[count + result] = ch; + + count += 1; + + if (found != NULL) + break; + } + + if (found_result) + *found_result = found; + + if (count_result) + *count_result = count; + + return (result); +} + /* pxe_fetch() - testing function, if size = from = 0, retrieve full file, * otherwise partial * in: @@ -300,23 +363,45 @@ { size_t size_to_get = (size > 0) ? size : hh->size; -#ifdef PXE_DEBUG +#ifdef PXE_HTTP_DEBUG_HELL printf("pxe_get(): %s:%s:%llu+%lu(%lu:%lu) to 0x%x\n", inet_ntoa(hh->ip), hh->filename, hh->offset, size_to_get, size, hh->size, hh->buf); #endif if (hh->socket == -1) { - printf("pxe_get(): socket is not connected.\n"); + printf("pxe_get(): invalid socket.\n"); return (-1); } + + if (pxe_socket_state(hh->socket) != PXE_SOCKET_ESTABLISHED) { + /* means connection was closed, due e.g. for Apache + * - MaxKeepAliveRequests exceeds for that connection + * - Waited between read attempts more than KeepAliveTimeout + * or + * some other problem + * need to reestablish connection + */ + + /* close socket gracefully */ + pxe_close(hh->socket); + hh->socket = -1; + + if (!pxe_exists(hh)) { +#ifdef PXE_HTTP_DEBUG + printf("pxe_get(): connection breaked.\n"); +#endif + return (-1); + } + /* reestablished, continue normal work */ + } if ( (size_to_get < PXE_HTTP_SIZE_UNKNOWN) && (size_to_get > 0)) { snprintf(hh->buf, hh->bufsize, "GET %s HTTP/1.1\r\nHost: %s\r\n" "Range: bytes=%llu-%llu\r\nConnection: keep-alive\r\n" - "User-Agent: pxe_http/0\r\n\r\n", + "Keep-Alive: 300\r\nUser-Agent: pxe_http/0\r\n\r\n", hh->filename, hh->servername, hh->offset, hh->offset + size - 1); } else { @@ -345,7 +430,7 @@ &found, &count); if (found == NULL) { /* haven't found end of header */ - printf("pxe_get(): cannot find reply header\n"); + printf("pxe_get(): cannot find reply header.\n"); return (-1); } @@ -354,7 +439,7 @@ pxe_memset(&parse_data, 0, sizeof(PXE_HTTP_PARSE_DATA)); if (!http_reply_parse(hh->buf, count, &parse_data)) { - printf("pxe_get(): cannot parse reply header\n"); + printf("pxe_get(): cannot parse reply header.\n"); return (-1); } @@ -394,7 +479,7 @@ count += result; } -#ifdef PXE_DEBUG +#ifdef PXE_HTTP_DEBUG_HELL printf("\npxe_get(): %lu of %lu byte(s) received.\n", count, size); #endif @@ -470,7 +555,8 @@ char *found = NULL; /* retrieve header */ - result = http_get_header(socket, hh->buf, hh->bufsize - 1, &found, &count); + result = http_get_header(socket, hh->buf, hh->bufsize - 1, + &found, &count); if (found == NULL) { /* haven't found end of header */ printf("pxe_get_close(): cannot find reply header\n"); @@ -583,8 +669,6 @@ /* retrieve header */ result = http_get_header(socket, hh->buf, hh->bufsize, &found, &count); -/* pxe_close(socket); */ - if (found == NULL) { /* haven't found end of header */ pxe_close(socket); return (0); ==== //depot/projects/soc2007/taleks-pxe_http/pxe_http.h#6 (text+ko) ==== @@ -53,6 +53,9 @@ uint32_t ip; /* web server ip */ off_t offset; /* current offset in bytes from * beginning of file */ + + off_t cache_start; /* cached block, to reduce http requests */ + uint16_t cache_size; /* size of cached block */ size_t size; /* file size if known */ } PXE_HTTP_HANDLE; @@ -60,8 +63,8 @@ /* gets requested data from server */ int pxe_get(PXE_HTTP_HANDLE *hh, size_t size, void *buffer); -/* gets requested data from server */ -int pxe_get2(PXE_HTTP_HANDLE *hh, size_t size, void *buffer); +/* gets requested data from server, closing connection after */ +int pxe_get_close(PXE_HTTP_HANDLE *hh, size_t size, void *buffer); /* checks if file exists and fills filesize if known */ int pxe_exists(PXE_HTTP_HANDLE *hh); ==== //depot/projects/soc2007/taleks-pxe_http/pxe_sock.c#16 (text+ko) ==== @@ -170,10 +170,6 @@ /* flush data in buffers */ pxe_flush(socket); - /* 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"); @@ -777,3 +773,42 @@ return (-1); } + +/* pxe_socket_state() - returns current state of socket + * in: + * socket - socket descriptor number + * out: + * -1 - if failed + * one of PXE_SOCKET_ state flags otherwise + */ +int +pxe_socket_state(int socket) +{ + if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) { + printf("pxe_socket_state(): invalid socket %d.\n", socket); + return (-1); + } + + PXE_SOCKET *sock = &pxe_sockets[socket]; + PXE_FILTER_ENTRY *filter = sock->filter; + + if (filter == NULL) { +#ifdef PXE_DEBUG + printf("pxe_socket_state(): NULL filter\n"); +#endif + return (PXE_SOCKET_USED); + } + + if (filter->protocol == PXE_UDP_PROTOCOL) /* it's always 'established' */ + return (PXE_SOCKET_ESTABLISHED); + + else if (filter->protocol == PXE_TCP_PROTOCOL) { + /* for TCP connections need to check state */ + PXE_TCP_CONNECTION *connection = filter_to_connection(filter); + + if (connection && (connection->state == PXE_TCP_ESTABLISHED) ) + return (PXE_SOCKET_ESTABLISHED); + } + + return (PXE_SOCKET_CONNECTED); +} ==== //depot/projects/soc2007/taleks-pxe_http/pxe_sock.h#14 (text+ko) ==== @@ -88,10 +88,8 @@ /* shows socket usage statistics */ void pxe_sock_stats(); -/* returns int socket by pointer to PXE_SOCKET - * TODO: think about interfaces between pxe_filter and pxe_sock - */ -int pxe_sock_get(PXE_SOCKET *sock); +/* returns current socket state */ +int pxe_socket_state(int socket); /* pxe_listen() - creates "listening" socket * it's not the same as normal listen() system call.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707221415.l6MEFM5e089380>