diff options
author | Daniel Dressler <danieru.dressler@gmail.com> | 2014-07-17 16:27:08 -0600 |
---|---|---|
committer | Daniel Dressler <danieru.dressler@gmail.com> | 2014-07-17 16:27:08 -0600 |
commit | d4cb96065695aec45f02ee97e6bc865f84e42878 (patch) | |
tree | 2b7efc3cd0706305c8c0cbf5b89c833e6a66f18f /src | |
parent | 98b2e3c59727101531418bb7f88001dbb069c213 (diff) |
Make tcp close connection when client closes it
Diffstat (limited to 'src')
-rw-r--r-- | src/http.c | 19 | ||||
-rw-r--r-- | src/ippusbxd.c | 10 | ||||
-rw-r--r-- | src/tcp.c | 26 | ||||
-rw-r--r-- | src/usb.c | 24 |
4 files changed, 60 insertions, 19 deletions
@@ -309,11 +309,21 @@ size_t packet_pending_bytes(struct http_packet_t *pkt) if (HTTP_CHUNKED == msg->type) { + if (pkt->filled_size == 0) { + pending = pkt->buffer_capacity; + goto pending_known; + } + if (pkt->expected_size == 0) { ssize_t size = packet_find_chunked_size(pkt); if (size <= 0) { - ERR("Malformed chunk-transport http packer receivd"); - exit(1); + ERR("============================================="); + ERR("Malformed chunk-transport http header receivd"); + ERR("Have %d bytes", pkt->filled_size); + printf("%.*s\n", pkt->filled_size, pkt->buffer); + ERR("Malformed chunk-transport http header receivd"); + ERR("============================================="); + size = 0; } pkt->expected_size = size; } @@ -356,6 +366,11 @@ void packet_mark_received(struct http_packet_t *pkt, size_t received) { pkt->filled_size += received; + if (pkt->filled_size > pkt->buffer_capacity) { + ERR("Overflowed packet's buffer"); + exit(1); // TODO: More orderly shutdown + } + struct http_message_t *msg = pkt->parent_message; msg->received_size += received; diff --git a/src/ippusbxd.c b/src/ippusbxd.c index 7539697..0bd6ecd 100644 --- a/src/ippusbxd.c +++ b/src/ippusbxd.c @@ -36,8 +36,13 @@ static void *service_connection(void *arg_void) while (!client_msg->is_completed) { struct http_packet_t *pkt; pkt = tcp_packet_get(arg->tcp, client_msg); - if (pkt == NULL) + if (pkt == NULL) { + if (arg->tcp->is_closed) { + NOTE("Clinet closed connection"); + goto cleanup_subconn; + } break; + } if (usb == NULL) { usb = usb_conn_aquire(arg->usb_sock, 1); if (usb == NULL) { @@ -53,6 +58,8 @@ static void *service_connection(void *arg_void) } message_free(client_msg); client_msg = NULL; + NOTE("Client msg completed"); + // Server's responce server_msg = http_message_new(); @@ -70,6 +77,7 @@ static void *service_connection(void *arg_void) tcp_packet_send(arg->tcp, pkt); packet_free(pkt); } + NOTE("Server msg completed"); cleanup_subconn: if (client_msg != NULL) @@ -50,8 +50,6 @@ struct tcp_sock_t *tcp_open(uint32_t port) goto error; } - - return this; error: @@ -95,28 +93,42 @@ struct http_packet_t *tcp_packet_get(struct tcp_conn_t *tcp, struct http_packet_t *pkt = packet_new(msg); if (pkt == NULL) { ERR("failed to create packet for incoming tcp message"); - goto error; + goto cleanup; } size_t want_size = packet_pending_bytes(pkt); if (want_size == 0) - goto error; + goto cleanup; while (want_size != 0 && !msg->is_completed) { + NOTE("TCP: Getting %d bytes", want_size); uint8_t *subbuffer = pkt->buffer + pkt->filled_size; ssize_t gotten_size = recv(tcp->sd, subbuffer, want_size, 0); if (gotten_size < 0) { int errno_saved = errno; ERR("recv failed with err %d:%s", errno_saved, strerror(errno_saved)); - goto error; + goto cleanup; + } + NOTE("TCP: Got %d bytes", gotten_size); + if (gotten_size == 0) { + tcp->is_closed = 1; + if (pkt->filled_size == 0) { + // Client closed TCP conn + goto cleanup; + } else { + break; + } } + packet_mark_received(pkt, gotten_size); want_size = packet_pending_bytes(pkt); } + + NOTE("TCP: Received %lu bytes", pkt->filled_size); return pkt; -error: +cleanup: if (pkt != NULL) packet_free(pkt); return NULL; @@ -125,7 +137,7 @@ error: void tcp_packet_send(struct tcp_conn_t *conn, struct http_packet_t *pkt) { send(conn->sd, pkt->buffer, pkt->filled_size, 0); - NOTE("sent %lu bytes over tcp", pkt->filled_size); + NOTE("TCP: sent %lu bytes", pkt->filled_size); } @@ -346,24 +346,24 @@ void usb_conn_packet_send(struct usb_conn_t *conn, struct http_packet_t *pkt) int timeout = 1000; // in milliseconds size_t sent = 0; size_t pending = pkt->filled_size; - size_t portions = pkt->filled_size / 512; - portions += (pkt->filled_size % 512) > 0 ? 1 : 0; - for (size_t i = 0; i < portions; i++) { + while (pending > 0) { int to_send = 512; if (pending < 512) to_send = (int)pending; + NOTE("USB: want to send %d bytes", to_send); int status = libusb_bulk_transfer(conn->parent->printer, conn->interface->endpoint_out, pkt->buffer + sent, to_send, &size_sent, timeout); - pending -= to_send; - sent += to_send; + pending -= size_sent; + sent += size_sent; + NOTE("USB: sent %d bytes", size_sent); // TODO: check status if (status < 0) - ERR("usb data sending failed with status %d", status); + ERR("Usb send failed with status %d", status); } - NOTE("sent %d bytes over usb\n", size_sent); + NOTE("USB: sent %d bytes in total", sent); } struct http_packet_t *usb_conn_packet_get(struct usb_conn_t *conn, struct http_message_t *msg) @@ -375,16 +375,18 @@ struct http_packet_t *usb_conn_packet_get(struct usb_conn_t *conn, struct http_m } // File packet - const int timeout = 100; // in milliseconds + const int timeout = 1000; // in milliseconds ssize_t read_size_raw = packet_pending_bytes(pkt); if (read_size_raw <= 0) goto cleanup; + int max_timeouts = 30; while (read_size_raw > 0 && !msg->is_completed) { if (read_size_raw >= INT_MAX) goto cleanup; int read_size = (int)read_size_raw; + NOTE("USB: Getting %d bytes", read_size); int gotten_size = 0; int status = libusb_bulk_transfer( @@ -400,11 +402,15 @@ struct http_packet_t *usb_conn_packet_get(struct usb_conn_t *conn, struct http_m } if (gotten_size == 0) { // TODO: timeout in case printer crashed + if (max_timeouts-- < 0) + goto cleanup; } - packet_mark_received(pkt, gotten_size); + NOTE("USB: Got %d bytes", gotten_size); + packet_mark_received(pkt, gotten_size); read_size_raw = packet_pending_bytes(pkt); } + NOTE("USB: Received %d bytes of %d", pkt->filled_size, pkt->expected_size); return pkt; |