summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Dressler <danieru.dressler@gmail.com>2014-07-17 16:27:08 -0600
committerDaniel Dressler <danieru.dressler@gmail.com>2014-07-17 16:27:08 -0600
commitd4cb96065695aec45f02ee97e6bc865f84e42878 (patch)
tree2b7efc3cd0706305c8c0cbf5b89c833e6a66f18f /src
parent98b2e3c59727101531418bb7f88001dbb069c213 (diff)
Make tcp close connection when client closes it
Diffstat (limited to 'src')
-rw-r--r--src/http.c19
-rw-r--r--src/ippusbxd.c10
-rw-r--r--src/tcp.c26
-rw-r--r--src/usb.c24
4 files changed, 60 insertions, 19 deletions
diff --git a/src/http.c b/src/http.c
index 7c12bdf..1041b0e 100644
--- a/src/http.c
+++ b/src/http.c
@@ -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)
diff --git a/src/tcp.c b/src/tcp.c
index a736fb3..4c316c8 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -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);
}
diff --git a/src/usb.c b/src/usb.c
index db61b2f..87d7b26 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -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;