net_sockets: some TCP fixups
authorAdam Turowski <adam.turowski@inf.ethz.ch>
Mon, 10 Jul 2017 15:18:51 +0000 (17:18 +0200)
committerAdam Turowski <adam.turowski@inf.ethz.ch>
Mon, 10 Jul 2017 15:18:51 +0000 (17:18 +0200)
Signed-off-by: Adam Turowski <adam.turowski@inf.ethz.ch>

12 files changed:
if/net_sockets.if
include/net_sockets/net_sockets.h
include/net_sockets/net_sockets_types.h
lib/debug_log/debug_log.c
lib/net_sockets/Hakefile
lib/net_sockets/net_sockets.c
lib/nfs/rpc.c
lib/tftp/client.c
tools/harness/tests/webserver.py
usr/drivers/net_socket_server/Hakefile
usr/drivers/net_socket_server/e1000_net_sockets_server.c
usr/webserver/http_server.c

index 4bfffb5..ed24ce1 100644 (file)
@@ -12,13 +12,10 @@ interface net_sockets "Interface for network sockets" {
 
     rpc new_udp_socket(out uint32 descriptor);
     rpc new_tcp_socket(out uint32 descriptor);
-    rpc delete_socket(in uint32 descriptor, out errval error);
 
     rpc bind(in uint32 descriptor, in uint32 host_address, in uint16 port, out errval error, out uint16 bound_port);
     rpc listen(in uint32 descriptor, in uint8 backlog, out errval error);
 
     rpc connect(in uint32 descriptor, in uint32 host_address, in uint16 port, out errval error);
     message connected(uint32 descriptor, errval error, uint32 connected_address, uint16 connected_port);
-
-//    message accepted(uint32 descriptor, uint32 new_descriptor, uint32 host_address, uint16 port, errval error);
 };
index 91cf541..0b58e7b 100644 (file)
@@ -8,10 +8,12 @@ void net_free(void *buffer);
 
 struct net_socket {
     uint32_t descriptor;
+    bool is_closing;
     net_received_callback_t received;
     net_sent_callback_t sent;
     net_connected_callback_t connected;
     net_accepted_callback_t accepted;
+    net_closed_callback_t closed;
     void *user_state;
 
     struct in_addr bound_address;
@@ -34,10 +36,12 @@ errval_t net_listen(struct net_socket *socket, uint8_t backlog);
 errval_t net_send(struct net_socket *socket, void *data, size_t size);
 errval_t net_send_to(struct net_socket *socket, void *data, size_t size, struct in_addr ip_address, uint16_t port);
 
-void net_recv(struct net_socket *socket, net_received_callback_t cb);
-void net_set_sent(struct net_socket *socket, net_sent_callback_t cb);
 errval_t net_connect(struct net_socket *socket, struct in_addr ip_address, uint16_t port, net_connected_callback_t cb);
-void net_accept(struct net_socket *socket, net_accepted_callback_t cb);
+
+void net_set_on_received(struct net_socket *socket, net_received_callback_t cb);
+void net_set_on_sent(struct net_socket *socket, net_sent_callback_t cb);
+void net_set_on_accepted(struct net_socket *socket, net_accepted_callback_t cb);
+void net_set_on_closed(struct net_socket *socket, net_closed_callback_t cb);
 
 
 errval_t net_sockets_init(void);
index 99168a3..5e55a40 100644 (file)
@@ -10,6 +10,17 @@ typedef void (*net_received_callback_t)(void *user_state, struct net_socket *soc
 typedef void (*net_sent_callback_t)(void *user_state, struct net_socket *socket, void *data, size_t size);
 typedef void (*net_connected_callback_t)(void *user_state, struct net_socket *socket);
 typedef void (*net_accepted_callback_t)(void *user_state, struct net_socket *accepted_socket);
+typedef void (*net_closed_callback_t)(void *user_state, struct net_socket *socket);
+
+typedef enum {
+    NET_EVENT_RECEIVE = 1,  // to a server to receive data
+    NET_EVENT_RECEIVED, // to a client with received data
+    NET_EVENT_SEND, // to a server with data to send
+    NET_EVENT_SENT, // to a client with sent data
+    NET_EVENT_ACCEPT, // to a client with a new accepted descriptor
+    NET_EVENT_CLOSE, // to a server requesting closing, no more frames will be sent to a server
+    NET_EVENT_CLOSED // to a client confirming closing, no more frames will be sent to a client
+} net_buffer_event_t;
 
 struct net_buffer {
     uint32_t size;
index 2bb581c..f577db4 100644 (file)
@@ -26,9 +26,11 @@ void debug_printf_to_log(const char *fmt, ...)
                    DISP_NAME_LEN, disp_name(), disp_get_core_id(), id);
     if (len < sizeof(log[0])) {
         va_start(argptr, fmt);
-        vsnprintf(str + len, sizeof(log[0]) - len, fmt, argptr);
+        len += vsnprintf(str + len, sizeof(log[0]) - len, fmt, argptr);
         va_end(argptr);
     }
+    if (str[len - 1] == '\n')
+        str[len - 1] = 0;
 }
 
 // #define DEBUG_SHOW
index 0501ae6..de86644 100644 (file)
@@ -15,6 +15,6 @@
                   flounderDefs = [ "net_sockets" ],
                   flounderBindings = [ "net_sockets" ],
                   addIncludes  = [ "include", "/lib/lwip-2.0.2/src/include/" ],
-                  addLibraries = libDeps [ "lwip2", "devif", "devif_backend_idc" ]
+                  addLibraries = libDeps [ "lwip2", "devif", "devif_backend_idc", "debug_log" ]
                 }
 ]
index 546565d..9103ace 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <devif/queue_interface.h>
 #include <devif/backends/descq.h>
-
+#include <debug_log/debug_log.h>
 
 static struct net_sockets_binding *binding;
 static bool bound_done = false;
@@ -71,6 +71,7 @@ static struct net_socket * allocate_socket(uint32_t descriptor)
     assert(socket);
 
     socket->descriptor = descriptor;
+    socket->is_closing = false;
     socket->received = NULL;
     socket->connected = NULL;
     socket->accepted = NULL;
@@ -120,8 +121,6 @@ static struct net_socket * get_socket(uint32_t descriptor)
         if (socket == sockets)
             break;
     }
-    debug_printf("%s: socket not found %d %p\n", __func__, descriptor, __builtin_return_address(0));
-    assert(0);
     return NULL;
 }
 
@@ -130,17 +129,30 @@ void net_set_user_state(struct net_socket *socket, void *user_state)
     socket->user_state = user_state;
 }
 
+void net_set_on_closed(struct net_socket *socket, net_closed_callback_t cb)
+{
+    socket->closed = cb;
+}
+
 void net_close(struct net_socket *socket)
 {
-    errval_t err, error;
+    errval_t err;
+
+// debug_printf_to_log("%s(%d): %ld:%p  %ld:%p", __func__, socket->descriptor, next_free, buffers[next_free], next_used, buffers[next_used]);
+// debug_printf("%s(%d): %d\n", __func__, socket->descriptor, socket->is_closing);
+    if (socket->is_closing)
+        debug_print_log();
+    assert(!socket->is_closing);
 
-    // debug_printf("%s(%d):\n", __func__, socket->descriptor);
-    err = binding->rpc_tx_vtbl.delete_socket(binding, socket->descriptor, &error);
+    struct net_buffer *nb = net_alloc(0) - sizeof(struct net_buffer);
+    nb->descriptor = socket->descriptor;
+    socket->is_closing = true;
+// debug_printf_to_log("%s(%d): enqueue %lx:%ld", __func__, socket->descriptor, (void *)nb - buffer_start, sizeof(struct net_buffer));
+    err = devq_enqueue((struct devq *)descq_queue, regionid, (void *)nb - buffer_start, sizeof(struct net_buffer),
+                       0, 0, NET_EVENT_CLOSE);
+    assert(err_is_ok(err));
+    err = devq_notify((struct devq *)descq_queue);
     assert(err_is_ok(err));
-    assert(err_is_ok(error));
-    dequeue(&sockets, socket);
-    free(socket);
-    // debug_printf("%s: %ld:%p  %ld:%p\n", __func__, next_free, buffers[next_free], next_used, buffers[next_used]);
 }
 
 errval_t net_bind(struct net_socket *socket, struct in_addr ip_address, uint16_t port)
@@ -168,7 +180,15 @@ errval_t net_listen(struct net_socket *socket, uint8_t backlog)
 
 void * net_alloc(size_t size)
 {
+    assert(size < (BUFFER_SIZE - sizeof(struct net_buffer)));
     void *buffer = buffers[next_free];
+    if (!buffer) {
+        // debug_printf_to_log("%s: %ld:%p  %ld:%p", __func__, next_free, buffers[next_free], next_used, buffers[next_used]);
+        errval_t err, error;
+        err = binding->rpc_tx_vtbl.listen(binding, -1, 0, &error);
+        debug_print_log();
+        assert(0);
+    }
     assert(buffer);
     buffers[next_free] = NULL;
     next_free = (next_free + 1) % NO_OF_BUFFERS;
@@ -191,14 +211,17 @@ errval_t net_send(struct net_socket *socket, void *data, size_t size)
     void *buffer = data - sizeof(struct net_buffer);
     struct net_buffer *nb = buffer;
     // debug_printf("%s(%d): %ld -> %p\n", __func__, socket->descriptor, size, buffer);
+    if (socket->is_closing)
+        debug_print_log();
+    assert(!socket->is_closing);
 
     nb->size = size;
     nb->descriptor = socket->descriptor;
     nb->host_address.s_addr = INADDR_NONE;
     nb->port = 0;
-    // debug_printf("%s: enqueue 2 %lx:%ld\n", __func__, buffer - buffer_start, sizeof(struct net_buffer) + size);
+// debug_printf_to_log("%s(%d): enqueue %lx:%ld", __func__, socket->descriptor, buffer - buffer_start, sizeof(struct net_buffer) + size);
     err = devq_enqueue((struct devq *)descq_queue, regionid, buffer - buffer_start, sizeof(struct net_buffer) + size,
-                       0, 0, 2);
+                       0, 0, NET_EVENT_SEND);
     assert(err_is_ok(err));
     err = devq_notify((struct devq *)descq_queue);
     assert(err_is_ok(err));
@@ -221,7 +244,7 @@ errval_t net_send_to(struct net_socket *socket, void *data, size_t size, struct
     nb->port = port;
     // debug_printf("%s: enqueue 2 %lx:%ld\n", __func__, buffer - buffer_start, sizeof(struct net_buffer) + size);
     err = devq_enqueue((struct devq *)descq_queue, regionid, buffer - buffer_start, sizeof(struct net_buffer) + size,
-                       0, 0, 2);
+                       0, 0, NET_EVENT_SEND);
     assert(err_is_ok(err));
     err = devq_notify((struct devq *)descq_queue);
     assert(err_is_ok(err));
@@ -245,16 +268,22 @@ errval_t net_connect(struct net_socket *socket, struct in_addr ip_address, uint1
 static void net_connected(struct net_sockets_binding *b, uint32_t descriptor, errval_t error, uint32_t connected_address, uint16_t connected_port)
 {
     struct net_socket *socket = get_socket(descriptor);
+    if (!socket) {
+        debug_printf("%s: socket not found %d\n", __func__, descriptor);
+        // debug_print_log();
+        assert(0);
+    }
     assert(socket->descriptor == descriptor);
     assert(err_is_ok(error));
 
     socket->connected_address.s_addr = connected_address;
     socket->connected_port = connected_port;
     assert(socket->connected);
+// debug_printf_to_log("%s: %ld:%p  %ld:%p", __func__, next_free, buffers[next_free], next_used, buffers[next_used]);
     socket->connected(socket->user_state, socket);
 }
 
-void net_accept(struct net_socket *socket, net_accepted_callback_t cb)
+void net_set_on_accepted(struct net_socket *socket, net_accepted_callback_t cb)
 {
     socket->accepted = cb;
 }
@@ -262,21 +291,27 @@ void net_accept(struct net_socket *socket, net_accepted_callback_t cb)
 static void net_accepted(uint32_t descriptor, uint32_t accepted_descriptor, struct in_addr host_address, uint16_t port)
 {
     struct net_socket *socket = get_socket(descriptor);
+    if (!socket) {
+        debug_printf("%s: socket not found %d\n", __func__, descriptor);
+        // debug_print_log();
+        assert(0);
+    }
     assert(socket->descriptor == descriptor);
 
     struct net_socket *accepted_socket = allocate_socket(accepted_descriptor);
     accepted_socket->connected_address = host_address;
     accepted_socket->connected_port = port;
+// debug_printf_to_log("%s(%d): %ld:%p  %ld:%p", __func__, accepted_descriptor, next_free, buffers[next_free], next_used, buffers[next_used]);
     socket->accepted(socket->user_state, accepted_socket);
 }
 
 
-void net_recv(struct net_socket *socket, net_received_callback_t cb)
+void net_set_on_received(struct net_socket *socket, net_received_callback_t cb)
 {
     socket->received = cb;
 }
 
-void net_set_sent(struct net_socket *socket, net_sent_callback_t cb)
+void net_set_on_sent(struct net_socket *socket, net_sent_callback_t cb)
 {
     socket->sent = cb;
 }
@@ -312,51 +347,72 @@ static errval_t q_notify(struct descq* q)
     genoffset_t length;
     genoffset_t valid_data;
     genoffset_t valid_length;
-    uint64_t flags;
+    uint64_t event;
     bool notify = 0;
 
     // debug_printf("%s: \n", __func__);
     for (;;) {
         err = devq_dequeue((struct devq *)descq_queue, &rid, &offset, &length,
-                           &valid_data, &valid_length, &flags);
+                           &valid_data, &valid_length, &event);
         if (err_is_fail(err)) {
             break;
         } else {
-            // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
             void *buffer = buffer_start + offset;
             struct net_buffer *nb = buffer;
-            // debug_printf("%s: dequeue %lx:%ld %ld  %p socket:%d asocket:%d\n", __func__, offset, length, flags, nb, nb->descriptor, nb->accepted_descriptor);
-            struct net_socket *socket = get_socket(nb->descriptor);
+            // debug_printf_to_log("%s: dequeue %lx:%ld %ld  %d:%d", __func__, offset, length, event, nb->descriptor, nb->size);
+            // debug_printf("%s: dequeue %lx:%ld %ld  %p socket:%d asocket:%d\n", __func__, offset, length, event, nb, nb->descriptor, nb->accepted_descriptor);
             void *shb_data = buffer + sizeof(struct net_buffer);
 
-            if (flags == 1) { // receiving buffer
+            if (event == NET_EVENT_RECEIVED) { // receiving buffer
                 // debug_printf("%s: enqueue 1> %lx:%d\n", __func__, offset, nb->size);
-                if (nb->accepted_descriptor) { // accept
-                    net_accepted(nb->descriptor, nb->accepted_descriptor, nb->host_address, nb->port);
-
-                    err = devq_enqueue((struct devq *)descq_queue, rid, offset, length, 0, 0, 1);
-                    assert(err_is_ok(err));
-                    notify = 1;
-                } else {  // receive
+                struct net_socket *socket = get_socket(nb->descriptor);
+                if (socket && !socket->is_closing) {
                     if (socket->received) {
                         // debug_printf("net_received(%d): %d\n", nb->descriptor, nb->size);
                         socket->received(socket->user_state, socket, shb_data, nb->size, nb->host_address, nb->port);
                     // debug_printf("%s: enqueue 1< %lx:%d\n", __func__, offset, 2048);
                     }
-
-                    err = devq_enqueue((struct devq *)descq_queue, rid, offset, length, 0, 0, 1);
-                    assert(err_is_ok(err));
-                    notify = 1;
                 }
-            } else if (flags == 2) { // transmitting buffer
+                err = devq_enqueue((struct devq *)descq_queue, rid, offset, length, 0, 0, NET_EVENT_RECEIVE);
+                assert(err_is_ok(err));
+                notify = 1;
+            } else if (event == NET_EVENT_ACCEPT) {
+                uint32_t descriptor = nb->descriptor;
+                uint32_t accepted_descriptor = nb->accepted_descriptor;
+                struct in_addr host_address = nb->host_address;
+                uint16_t port = nb->port;
+
+                // debug_printf("%s(%d): accept\n", __func__, accepted_descriptor);
+                err = devq_enqueue((struct devq *)descq_queue, rid, offset, length, 0, 0, NET_EVENT_RECEIVE);
+                assert(err_is_ok(err));
+                notify = 1;
+                net_accepted(descriptor, accepted_descriptor, host_address, port);
+            } else if (event == NET_EVENT_SENT) { // transmitting buffer
+                struct net_socket *socket = get_socket(nb->descriptor);
+                assert(socket);
+
+                    // debug_printf_to_log("%s(%d): dequeue sent %lx:%ld %p  %p", __func__, socket->descriptor, offset, length, shb_data, socket->sent);
                 if (socket->sent) {
-                    // debug_printf("%s: dequeue %lx:%ld %p\n", __func__, offset, length, shb_data);
                     socket->sent(socket->user_state, socket, shb_data, nb->size);
                 }
-    // debug_printf("%s: %ld:%p  %ld:%p\n", __func__, next_free, buffers[next_free], next_used, buffers[next_used]);
                 // assert(!buffers[next_used]);
                 // buffers[next_used] = buffer_start + offset;
                 // next_used = (next_used + 1) % NO_OF_BUFFERS;
+            } else if (event == NET_EVENT_CLOSED) {
+                struct net_socket *socket = get_socket(nb->descriptor);
+                
+                net_free(shb_data);
+                // debug_printf("%s(%d): closed\n", __func__, nb->descriptor);
+                // debug_printf_to_log("%s(%d): closed %ld:%p  %ld:%p", __func__, nb->descriptor, next_free, buffers[next_free], next_used, buffers[next_used]);
+
+                if (socket->closed) {
+                    socket->closed(socket->user_state, socket);
+                }
+                dequeue(&sockets, socket);
+                free(socket);
+            } else {
+                debug_printf("%s: unknown event %ld!", __func__, event);
+                assert(0);
             }
         }
     }
@@ -400,7 +456,6 @@ errval_t net_sockets_init(void)
     }
     debug_printf("%s: initialized\n", __func__);
     binding->rx_vtbl.connected = net_connected;
-    // binding->rx_vtbl.accepted = net_accepted;
 
     err = binding->rpc_tx_vtbl.register_queue(binding, queue_id);
     assert(err_is_ok(err));
@@ -410,7 +465,7 @@ errval_t net_sockets_init(void)
 
     for (int i = 0; i < NO_OF_BUFFERS; i++) {
         err = devq_enqueue((struct devq *)descq_queue, regionid, i * BUFFER_SIZE, BUFFER_SIZE,
-                           0, 0, 1);
+                           0, 0, NET_EVENT_RECEIVE);
         if (!err_is_ok(err))
             debug_printf("%s: %d:%d\n", __func__, i, NO_OF_BUFFERS);
         assert(err_is_ok(err));
index d67d6f7..6079f99 100644 (file)
@@ -285,7 +285,7 @@ static void traverse_hash_bucket(int hid, struct rpc_client *client)
                 //                       -UDP_HLEN - IP_HLEN - PBUF_LINK_HLEN);
                 // assert(e == SYS_ERR_OK);
 
-                errval_t e = net_send(client->socket, call->data, call->size);
+                errval_t e = net_send_to(client->socket, call->data, call->size, client->connected_address, client->connected_port);
                 if (e != SYS_ERR_OK) {
                     /* XXX: assume that this is a transient condition, retry */
                     fprintf(stderr, "RPC: retransmit failed! will retry...\n");
@@ -329,7 +329,7 @@ errval_t rpc_init(struct rpc_client *client, struct in_addr server)
     client->socket = net_udp_socket();
     assert(client->socket);
     net_set_user_state(client->socket, client);
-    net_recv(client->socket, rpc_recv_handler);
+    net_set_on_received(client->socket, rpc_recv_handler);
 
     net_debug_state = 0;
 
@@ -426,16 +426,8 @@ errval_t rpc_call(struct rpc_client *client, uint16_t port, uint32_t prog,
 
     RPC_DEBUGP("rpc_call: RPC call for xid %u x0%x\n", xid, xid);
     RPC_DEBUGP("rpc_call: calling UPD_connect\n");
-    if (client->server.s_addr != client->connected_address.s_addr || port != client->connected_port) {
-        r = net_connect(client->socket, client->server, port, NULL);
-        if (r != SYS_ERR_OK) {
-            XDR_DESTROY(&xdr);
-            free(call);
-            return r;
-        }
-        client->connected_address = client->server;
-        client->connected_port = port;
-    }
+    client->connected_address = client->server;
+    client->connected_port = port;
 
     /* enqueue */
     int hid = hash_function(xid);
@@ -443,7 +435,7 @@ errval_t rpc_call(struct rpc_client *client, uint16_t port, uint32_t prog,
     client->call_hash[hid] = call;
 
     RPC_DEBUGP("rpc_call: calling UPD_send\n");
-    r = net_send(client->socket, call->data, call->size);
+    r = net_send_to(client->socket, call->data, call->size, client->connected_address, client->connected_port);
     if (r != SYS_ERR_OK) {
         /* dequeue */
         assert(client->call_hash[hid] == call);
index 0d05ba7..b23913e 100644 (file)
@@ -357,7 +357,7 @@ errval_t tftp_client_connect(char *ip, uint16_t port)
     // }
 
     TFTP_DEBUG("registering recv handler\n");
-    net_recv(tftp_client.pcb, tftp_client_recv_handler);
+    net_set_on_received(tftp_client.pcb, tftp_client_recv_handler);
 
     tftp_client.state = TFTP_ST_IDLE;
     tftp_client.mode = TFTP_MODE_OCTET;
index 45662b0..bf820c5 100644 (file)
@@ -112,7 +112,7 @@ class WebserverTest(WebCommon):
                 if (r.status / 100) != 2 :
                     print "HTTP request failed for %d" % (i)
                 assert((r.status / 100) == 2) # check for success response
-
+                data = r.read()
                 # Reset failure count after sucessful retrival
                 failure_count = 0
                 c.close()
index 5267d36..652df42 100644 (file)
@@ -14,6 +14,6 @@
     target       = "e1000_net_sockets_server",
     cFiles       = [ "e1000_net_sockets_server.c" ],
     flounderBindings = [ "net_sockets" ],
-    addLibraries = libDeps [ "net", "lwip2" ]
+    addLibraries = libDeps [ "net", "lwip2", "debug_log" ]
   }
 ]
index 4d9759f..366ae32 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <if/net_sockets_defs.h>
 #include <net_sockets/net_sockets_types.h>
+#include <debug_log/debug_log.h>
 
 #include <lwip/ip.h>
 #include <lwip/udp.h>
@@ -81,6 +82,19 @@ struct socket_connection {
 
 static struct network_connection *network_connections = NULL;
 
+static struct socket_connection * find_socket_connection(struct network_connection *nc, uint32_t descriptor)
+{
+    struct socket_connection *socket;
+
+    socket = nc->sockets;
+    while (socket) {
+        if (socket->descriptor == descriptor)
+            break;
+        socket = socket->next;
+    }
+    return socket;
+}
+
 static struct socket_connection * allocate_socket(struct network_connection *nc)
 {
     struct socket_connection *last, *socket;
@@ -162,7 +176,7 @@ static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, cons
     pbuf_free(p);
     // debug_printf("%s.%d: enqueue 1 %lx:%ld\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length);
     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
-                       0, 0, 1);
+                       0, 0, NET_EVENT_RECEIVED);
     assert(err_is_ok(err));
     err = devq_notify((struct devq *)nc->queue);
     assert(err_is_ok(err));
@@ -182,7 +196,7 @@ static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err
     void *buffer = nc->buffers[nc->next_free];
     struct net_buffer *nb = buffer;
 
-    // debug_printf("%s: pcb:%p  p:%p\n", __func__, pcb, p);
+    // debug_printf("%s(%d): pcb:%p  p:%p\n", __func__, socket->descriptor, pcb, p);
     if (p) {
         // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
         assert(p->len == p->tot_len);
@@ -212,6 +226,9 @@ static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err
         nb->host_address.s_addr = 0;
         nb->port = 0;
         // debug_printf("%s(%d): close\n", __func__, socket->descriptor);
+        // debug_printf_to_log("%s(%d): close", __func__, socket->descriptor);
+        tcp_err(socket->tcp_socket, NULL);
+        // debug_printf("%s(%d): close\n", __func__, socket->descriptor);
         // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
     }
     nc->buffers[nc->next_free] = NULL;
@@ -220,7 +237,7 @@ static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err
     
     // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
-                       0, 0, 1);
+                       0, 0, NET_EVENT_RECEIVED);
     assert(err_is_ok(err));
     err = devq_notify((struct devq *)nc->queue);
     assert(err_is_ok(err));
@@ -231,14 +248,38 @@ static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err
     return ERR_OK;
 }
 
-static void net_tcp_error(void *arg, err_t err)
+static void net_tcp_error(void *arg, err_t tcp_err)
 {
     struct socket_connection *socket = arg;
-    // struct network_connection *nc = socket->connection;
-    
-    // debug_printf("%s(%d): error %d\n", __func__, socket->descriptor, err);
+    struct network_connection *nc = socket->connection;
+    errval_t err;
+
+    // debug_printf("%s(%d): error %d\n", __func__, socket->descriptor, tcp_err);
+    // debug_printf_to_log("%s(%d): error %d", __func__, socket->descriptor, tcp_err);
+    tcp_sent(socket->tcp_socket, NULL);
+    tcp_recv(socket->tcp_socket, NULL);
     socket->tcp_socket = NULL; // invalidate
 
+    void *buffer = nc->buffers[nc->next_free];
+    assert(buffer);
+    struct net_buffer *nb = buffer;
+    nb->size = 0;
+    nb->descriptor = socket->descriptor;
+    nb->accepted_descriptor = 0;
+    nb->host_address.s_addr = 0;
+    nb->port = 0;
+    nc->buffers[nc->next_free] = NULL;
+    nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
+    
+    err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer),
+                       0, 0, NET_EVENT_RECEIVED);
+    assert(err_is_ok(err));
+    // debug_printf_to_log("%s(%d): close", __func__, socket->descriptor);
+    
+    err = devq_notify((struct devq *)nc->queue);
+    assert(err_is_ok(err));
+
+
     // uint32_t length = 0;
     // void *buffer = nc->buffers[nc->next_free];
     // struct net_buffer *nb = buffer;
@@ -270,9 +311,14 @@ static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
     errval_t err;
 
     while (len > 0) {
+        // debug_printf_to_log("%s(%d): %d  %lx:%ld:%ld  %lx:%ld:%ld", __func__, socket->descriptor, len,
+            // socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
+            // socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
         // debug_printf("%s(%d): %d  %zx:%zd:%zd %zx:%zd:%zd\n", __func__, socket->descriptor, len,
         //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
         //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
+        if (!socket->send_frames[0].length)
+            debug_print_log();
         assert(socket->send_frames[0].length);
         if (len < (socket->send_frames[0].length - socket->send_frames[0].sent)) {
             socket->send_frames[0].sent += len;
@@ -281,8 +327,8 @@ static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
             len -= socket->send_frames[0].length - socket->send_frames[0].sent;
             
             socket->send_frames[0].length += sizeof(struct net_buffer);
-            // debug_printf("%s.%d: enqueue 2 %lx:%zd\n", __func__, __LINE__, socket->send_frames[0].offset, socket->send_frames[0].length);
-            err = devq_enqueue((struct devq *)nc->queue, nc->region_id, socket->send_frames[0].offset, socket->send_frames[0].length, 0, 0, 2);
+            // debug_printf_to_log("%s.%d: enqueue %lx:%zd\n", __func__, __LINE__, socket->send_frames[0].offset, socket->send_frames[0].length);
+            err = devq_enqueue((struct devq *)nc->queue, nc->region_id, socket->send_frames[0].offset, socket->send_frames[0].length, 0, 0, NET_EVENT_SENT);
             if (!err_is_ok(err))
                 debug_printf("%s: err %zd\n", __func__, err);
             assert(err_is_ok(err));
@@ -328,7 +374,7 @@ static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
     nb->accepted_descriptor = accepted_socket->descriptor;
     nb->host_address.s_addr = newpcb->remote_ip.addr;
     nb->port = newpcb->remote_port;
-    // debug_printf("%s(%d): accepted %p\n", __func__, socket->descriptor, newpcb);
+    // debug_printf_to_log("%s(%d): accepted", __func__, accepted_socket->descriptor);
 
     nc->buffers[nc->next_free] = NULL;
     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
@@ -336,7 +382,7 @@ static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
     
     // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
-                       0, 0, 1);
+                       0, 0, NET_EVENT_ACCEPT);
     assert(err_is_ok(err));
     err = devq_notify((struct devq *)nc->queue);
     assert(err_is_ok(err));
@@ -405,12 +451,7 @@ static errval_t net_bind(struct net_sockets_binding *binding, uint32_t descripto
     struct socket_connection *socket;
 
     nc = binding->st;
-    socket = nc->sockets;
-    while (socket) {
-        if (socket->descriptor == descriptor)
-            break;
-        socket = socket->next;
-    }
+    socket = find_socket_connection(nc, descriptor);
     assert(socket);
 
     if (socket->udp_socket) {
@@ -443,13 +484,12 @@ static errval_t net_listen(struct net_sockets_binding *binding, uint32_t descrip
     struct network_connection *nc;
     struct socket_connection *socket;
 
-    nc = binding->st;
-    socket = nc->sockets;
-    while (socket) {
-        if (socket->descriptor == descriptor)
-            break;
-        socket = socket->next;
+    if (descriptor == -1) {
+        debug_print_log();
+        return SYS_ERR_OK;
     }
+    nc = binding->st;
+    socket = find_socket_connection(nc, descriptor);
     assert(socket);
     assert(socket->tcp_socket);
     socket->tcp_socket = tcp_listen(socket->tcp_socket);
@@ -480,12 +520,7 @@ static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descri
     struct socket_connection *socket;
 
     nc = binding->st;
-    socket = nc->sockets;
-    while (socket) {
-        if (socket->descriptor == descriptor)
-            break;
-        socket = socket->next;
-    }
+    socket = find_socket_connection(nc, descriptor);
     assert(socket);
 
     if (socket->udp_socket) {
@@ -509,12 +544,12 @@ static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descri
     return SYS_ERR_OK;
 }
 
-static errval_t net_delete_socket(struct net_sockets_binding *binding, uint32_t descriptor, errval_t *error)
+static void net_delete_socket(struct network_connection *nc, uint32_t descriptor)
 {
-    struct network_connection *nc;
     struct socket_connection *socket, *last;
+    errval_t err;
 
-    nc = binding->st;
+    // debug_printf_to_log("%s(%d): tcp_close", __func__, descriptor);
     socket = nc->sockets;
     last = NULL;
     while (socket) {
@@ -523,19 +558,44 @@ static errval_t net_delete_socket(struct net_sockets_binding *binding, uint32_t
         last = socket;
         socket = socket->next;
     }
+    if (!socket)
+        debug_print_log();
     assert(socket);
     if (socket->udp_socket) {
         udp_recv(socket->udp_socket, NULL, NULL);
         udp_remove(socket->udp_socket);
     } else if (socket->tcp_socket) {
         tcp_recv(socket->tcp_socket, NULL); // you can receive packets after you close the socket
+        tcp_sent(socket->tcp_socket, NULL);
         // tcp_accept(socket->tcp_socket, NULL);
         err_t e;
-        // debug_printf("%s(%d): tcp_close %p\n", __func__, descriptor, socket->tcp_socket);
         e = tcp_close(socket->tcp_socket);
         assert(e == ERR_OK);
     }
 
+    // debug_printf_to_log("%s(%d): %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor,
+        // socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
+        // socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
+    while (socket->send_frames[0].length) { // invaldate all sent frames
+        void *buffer;
+        struct net_buffer *nb;
+
+        // debug_printf_to_log("%s(%d): %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor,
+        //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
+        //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
+
+        socket->send_frames[0].length += sizeof(struct net_buffer);
+        buffer = socket->send_frames[0].offset + nc->buffer_start;
+        nb = buffer;
+        nb->descriptor = descriptor;
+        // debug_printf_to_log("%s.%d: enqueue %lx:%zd\n", __func__, __LINE__, socket->send_frames[0].offset, socket->send_frames[0].length);
+        err = devq_enqueue((struct devq *)nc->queue, nc->region_id, socket->send_frames[0].offset, socket->send_frames[0].length, 0, 0, NET_EVENT_SENT);
+        assert(err_is_ok(err));
+        socket->send_frames[0] = socket->send_frames[1];
+        socket->send_frames[1].sent = 0;
+        socket->send_frames[1].length = 0;
+        socket->send_frames[1].offset = 0;
+    }
     // debug_printf("%s(%d):\n", __func__, descriptor);
     // debug_printf("%s: %ld:%p  %ld:%p\n", __func__, nc->next_free, nc->buffers[nc->next_free], nc->next_used, nc->buffers[nc->next_used]);
     if (last)
@@ -543,9 +603,6 @@ static errval_t net_delete_socket(struct net_sockets_binding *binding, uint32_t
     else
         nc->sockets = socket->next;
     free(socket);
-
-    *error = SYS_ERR_OK;
-    return SYS_ERR_OK;
 }
 
 static errval_t q_create(struct descq* q, bool notifications, uint8_t role,
@@ -586,7 +643,7 @@ static errval_t q_notify(struct descq* q)
     genoffset_t length;
     genoffset_t valid_data;
     genoffset_t valid_length;
-    uint64_t flags;
+    uint64_t event;
     struct network_connection *nc;
     bool notify = 0;
 
@@ -594,31 +651,28 @@ static errval_t q_notify(struct descq* q)
     nc = devq_get_state(queue);
     for (;;) {
         err = devq_dequeue(queue, &rid, &offset, &length,
-                           &valid_data, &valid_length, &flags);
+                           &valid_data, &valid_length, &event);
         if (err_is_fail(err)) {
             break;
         } else {
-            // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
-            if (flags == 1) { // receiving buffer
-                // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
+            void *buffer;
+            buffer = offset + nc->buffer_start;
+            struct net_buffer *nb = buffer;
+
+            // debug_printf_to_log("%s: dequeue %lx:%ld %ld  %d:%d", __func__, offset, length, event, nb->descriptor, nb->size);
+            if (event == NET_EVENT_RECEIVE) {
                 assert(!nc->buffers[nc->next_used]);
                 nc->buffers[nc->next_used] = nc->buffer_start + offset;
                 nc->next_used = (nc->next_used + 1) % NO_OF_BUFFERS;
-            } else if (flags == 2) { // transmitting buffer
+            } else if (event == NET_EVENT_SEND) {
                 struct socket_connection *socket;
-                void *buffer;
-                buffer = offset + nc->buffer_start;
-                struct net_buffer *nb = buffer;
                 void *shb_data = (void *)buffer + sizeof(struct net_buffer);
 
                 // debug_printf("%s: %p\n", __func__, buffer);
-
-                socket = nc->sockets;
-                while (socket) {
-                    if (socket->descriptor == nb->descriptor)
-                        break;
-                    socket = socket->next;
-                }
+// find the socket
+                socket = find_socket_connection(nc, nb->descriptor);
+                if (!socket)
+                    debug_printf("%s(%d): %p\n", __func__, nb->descriptor, socket);
                 assert(socket);
 
                 // debug_printf("buffer: %d %d %x %d  %p %p\n", nb->size, nb->descriptor, nb->host_address, nb->port, socket->udp_socket, socket->tcp_socket);
@@ -635,7 +689,7 @@ static errval_t q_notify(struct descq* q)
                     port = nb->port;
                     addr.addr = nb->host_address.s_addr;
                     // debug_printf("%s.%d: enqueue 2 %lx:%d\n", __func__, __LINE__, offset, nb->size);
-                    err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
+                    err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
                     assert(err_is_ok(err));
                     notify = 1;
                     // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
@@ -657,7 +711,7 @@ static errval_t q_notify(struct descq* q)
                     pbuf_free(p);
                 } else if (socket->tcp_socket) {
                     err_t e;
-                    // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
+                    // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, event);
                     
                     if (socket->send_frames[0].length == 0) {
                         
@@ -679,11 +733,29 @@ static errval_t q_notify(struct descq* q)
                         socket->send_frames[1].offset = offset;
                         socket->send_frames[1].length = length - sizeof(struct net_buffer);
                     }
+                    // debug_printf_to_log("%s(%d): tcp_send %lx:%ld    %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor, offset, length,
+                    //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
+                    //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
                     // debug_printf("%s.%d: enqueue 2 %lx:%zd\n", __func__, __LINE__, offset, length);
                     // err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
                     // assert(err_is_ok(err));
                     // notify = 1;
+                } else {
+                    err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
+                    assert(err_is_ok(err));
+                    notify = 1;
                 }
+            } else if (event == NET_EVENT_CLOSE) {
+                // struct net_buffer *nb = offset + nc->buffer_start;
+
+                // debug_printf("%s(%d): close\n", __func__, nb->descriptor);
+                net_delete_socket(nc, nb->descriptor);
+                err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_CLOSED);
+                assert(err_is_ok(err));
+                notify = 1;
+            } else {
+                debug_printf("%s: unknown event %ld!", __func__, event);
+                assert(0);
             }
         }
     }
@@ -737,7 +809,6 @@ static struct net_sockets_rpc_rx_vtbl rpc_rx_vtbl = {
     .new_tcp_socket_call = net_tcp_socket,
     .bind_call = net_bind,
     .connect_call = net_connect,
-    .delete_socket_call = net_delete_socket,
     .listen_call = net_listen,
 };
 
@@ -765,13 +836,13 @@ int main(int argc, char *argv[])
     char servicename[64];
     snprintf(servicename, sizeof(servicename), "e1000:%s", argv[2]);
 
-    // err = oct_init();
-    // assert(err_is_ok(err));
-    // err = oct_set(NET_CONFIG_STATIC_IP_RECORD_FORMAT, inet_addr("192.168.0.36"), inet_addr("0.0.0.0"), inet_addr("255.255.255.0"));
-    // assert(err_is_ok(err));
+    err = oct_init();
+    assert(err_is_ok(err));
+    err = oct_set(NET_CONFIG_STATIC_IP_RECORD_FORMAT, inet_addr("192.168.0.36"), inet_addr("0.0.0.0"), inet_addr("255.255.255.0"));
+    assert(err_is_ok(err));
 
     /* connect to the network */
-    err = networking_init(servicename, NET_FLAGS_DO_DHCP | NET_FLAGS_NO_NET_FILTER | NET_FLAGS_BLOCKING_INIT);
+    err = networking_init(servicename, /*NET_FLAGS_DO_DHCP |*/ NET_FLAGS_NO_NET_FILTER | NET_FLAGS_BLOCKING_INIT);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Failed to initialize the network");
     }
index 1d2d4f6..93aa116 100644 (file)
@@ -23,6 +23,7 @@
 #include <netinet/in.h>
 #include <net_sockets/net_sockets.h>
 #include <netbench/netbench.h>
+#include <debug_log/debug_log.h>
 
 #define LWIP_IPV4
 #include <lwip/ip_addr.h>
@@ -183,7 +184,7 @@ static void http_conn_invalidate (struct http_conn *conn)
 // }
 //
 //
-static void http_server_close(struct net_socket *tpcb, struct http_conn *cs)
+static void http_server_close(struct net_socket *socket, struct http_conn *cs)
 {
 /*
     printf("%s %s %s %hu.%hu.%hu.%hu in %"PU"\n",
@@ -192,17 +193,23 @@ static void http_server_close(struct net_socket *tpcb, struct http_conn *cs)
            ip4_addr3(&cs->pcb->remote_ip), ip4_addr4(&cs->pcb->remote_ip),
             in_seconds(get_time_delta(&cs->start_ts)));
 */
+    // debug_printf_to_log("%s(%d): %p", __func__, socket->descriptor, __builtin_return_address(0));
     DEBUGPRINT("%d: http_server_close freeing the connection\n",
         cs->request_no);
 
-    // replace TCP callbacks with NULL
-    if (cs != NULL) {
-        http_conn_invalidate (cs);
-    }
-    net_close(tpcb);
+    assert(cs);
+    // debug_printf("%s(%d):\n", __func__, socket->descriptor);
+    net_close(socket);
+}
+
+static void http_server_closed(void *arg, struct net_socket *socket)
+{
+    // debug_printf("%s(%d):\n", __func__, socket->descriptor);
+    struct http_conn *cs = arg;
+    http_conn_invalidate(cs);
 }
 
-static errval_t trysend(struct net_socket *t, const void *data, size_t *len, bool
+static errval_t trysend(struct net_socket *socket, const void *data, size_t *len, bool
 more)
 {
     size_t sendlen;
@@ -217,7 +224,7 @@ more)
         if (!buffer)
             break;
         memcpy(buffer, data + sendlen, s);
-        err = net_send(t, buffer, s);
+        err = net_send(socket, buffer, s);
         assert(err_is_ok(err));
         sendlen += s;
     }
@@ -225,12 +232,13 @@ more)
     return SYS_ERR_OK;
 }
 
-static void http_send_data(struct net_socket *tpcb, struct http_conn *conn)
+static void http_send_data(struct net_socket *socket, struct http_conn *conn)
 {
     errval_t err;
     const void *data;
     size_t len;
 
+// debug_printf_to_log("%s(%d): %p %d", __func__, socket->descriptor, conn, conn->state);
     switch (conn->state) {
     case HTTP_STATE_SENDHEADER:
         DEBUGPRINT ("%d: http_send_data: header_pos %lu < header_len %lu\n",
@@ -238,7 +246,8 @@ static void http_send_data(struct net_socket *tpcb, struct http_conn *conn)
         assert(conn->header_pos < conn->header_length);
         data = &conn->header[conn->header_pos];
         len = conn->header_length - conn->header_pos;
-        err = trysend(tpcb, data, &len, (conn->hbuff->data != NULL));
+ // debug_printf_to_log("%s(%d): header %zd:%zd", __func__, socket->descriptor, conn->header_pos, len);
+        err = trysend(socket, data, &len, (conn->hbuff->data != NULL));
         if (err != SYS_ERR_OK) {
             DEBUGPRINT("http_send_data(): Error %d sending header\n", err);
             return; // will retry
@@ -266,14 +275,17 @@ static void http_send_data(struct net_socket *tpcb, struct http_conn *conn)
         // debug_printf("%s: %zd %zd\n", __func__, len, maxlen);
         if (len > maxlen)
             len = maxlen;
-        err = trysend(tpcb, data, &len, false);
+ // debug_printf_to_log("%s(%d): file %zd:%zd", __func__, socket->descriptor, conn->reply_pos, len);
+        err = trysend(socket, data, &len, false);
         if (err != SYS_ERR_OK) {
             DEBUGPRINT("http_send_data(): Error %d sending payload\n", err);
             return; // will retry
         }
         conn->reply_pos += len;
+// debug_printf_to_log("%s(%d): %zd %zd\n", __func__, socket->descriptor, conn->reply_pos, conn->hbuff->len);
         if (conn->reply_pos == conn->hbuff->len) {
             conn->state = HTTP_STATE_CLOSING;
+            http_server_close(socket, conn);
         }
         break;
 
@@ -286,28 +298,28 @@ static void http_send_data(struct net_socket *tpcb, struct http_conn *conn)
 /* This function is called periodically from TCP.
  * and is also responsible for taking care of stale connections.
 **/
-// static errval_t http_poll(void *arg, struct net_socket *tpcb)
+// static errval_t http_poll(void *arg, struct net_socket *socket)
 // {
 //     struct http_conn *conn = arg;
 //
-//     if (conn == NULL && tpcb->state == ESTABLISHED) {
-//         tcp_abort(tpcb);
+//     if (conn == NULL && socket->state == ESTABLISHED) {
+//         tcp_abort(socket);
 //         return ERR_ABRT;
 //     } else if (conn != NULL && (conn->state == HTTP_STATE_SENDHEADER
 //                                 || conn->state == HTTP_STATE_SENDFILE)) {
 //         if (++conn->retries == 4) {
 //             DEBUGPRINT ("connection closed, tried too hard\n");
 //             http_conn_invalidate (conn);
-//             net_delete_socket(tpcb);
+//             net_delete_socket(socket);
 //             return ERR_ABRT;
 //         }
-//         http_send_data(tpcb, conn);
+//         http_send_data(socket, conn);
 //         if (conn->state == HTTP_STATE_CLOSING) {
 //             DEBUGPRINT ("%d: http_poll closing the connection\n",
 //                     conn->request_no);
-//             http_server_close(tpcb, conn);
+//             http_server_close(socket, conn);
 //         } else {
-//             // tcp_output(tpcb);
+//             // tcp_output(socket);
 //         }
 //     } else if (conn != NULL && (conn->state == HTTP_STATE_NEW
 //                                 || conn->state == HTTP_STATE_REQUEST)) {
@@ -320,7 +332,7 @@ static void http_send_data(struct net_socket *tpcb, struct http_conn *conn)
 //                         conn->state);
 //
 //             http_conn_invalidate (conn);
-//             net_delete_socket(tpcb);
+//             net_delete_socket(socket);
 //             return ERR_ABRT;
 //         }
 //     }
@@ -332,6 +344,8 @@ static void http_server_sent(void *arg, struct net_socket *socket, void *buffer,
 {
     struct http_conn *conn = arg;
 
+    // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, conn->state == HTTP_STATE_CLOSING);
+    // debug_printf_to_log("%s(%d):", __func__, socket->descriptor);
     assert(conn);
     net_free(buffer);
 
@@ -346,17 +360,15 @@ static void http_server_sent(void *arg, struct net_socket *socket, void *buffer,
     case HTTP_STATE_SENDFILE:
         // Need to send more data?
         http_send_data(socket, conn);
-        if (conn->state != HTTP_STATE_CLOSING) {
-            // tcp_output(tpcb);
-            break;
-        }
-
+        break;
     case HTTP_STATE_CLOSING:
         DEBUGPRINT("%d: http_server_sent closing the connection\n",
                     conn->request_no);
+// debug_printf_to_log("%s(%d): %ld:%ld  %ld:%ld", __func__, socket->descriptor, conn->header_pos, conn->header_sent, conn->reply_pos, conn->reply_sent);
+        // if (conn->header_pos == conn->header_sent && conn->reply_pos == conn->reply_sent) {
 // debug_printf("%s.%d: %zd\n", __func__, __LINE__, size);
-        if (conn->header_pos == conn->header_sent && conn->reply_pos == conn->reply_sent)
-            http_server_close(socket, conn);
+            // http_server_close(socket, conn);
+        // }
         break;
 
     default:
@@ -438,32 +450,33 @@ static void send_response(struct http_conn *cs)
     http_send_data(cs->pcb, cs);
 
     /* did we send the whole page? */
-    if (cs->state == HTTP_STATE_CLOSING) {
-        DEBUGPRINT("%d: send_response closing the connection\n",
-                cs->request_no);
+    // if (cs->state == HTTP_STATE_CLOSING) {
+    //     DEBUGPRINT("%d: send_response closing the connection\n",
+    //             cs->request_no);
 // debug_printf("%s.%d:\n", __func__, __LINE__);
                                 // http_server_close(cs->pcb, cs);
-    } else {
+    // } else {
         // tcp_output(cs->pcb);
-    }
+    // }
 } /* end function: send_response */
 
-// static errval_t http_server_recv(void *arg, struct net_socket *tpcb, struct pbuf *p,
+// static errval_t http_server_recv(void *arg, struct net_socket *socket, struct pbuf *p,
 //                               errval_t err);
 //
-static void http_server_recv(void *arg, struct net_socket *tpcb, void *data, size_t size, struct in_addr ip_address, uint16_t port)
+static void http_server_recv(void *arg, struct net_socket *socket, void *data, size_t size, struct in_addr ip_address, uint16_t port)
 {
     struct http_conn *conn = arg;
 
     DEBUGPRINT("%d, http_server_recv called\n", conn->request_no);
-    // debug_printf("%s(%d): %ld\n", __func__, tpcb->descriptor, size);
+    // debug_printf_to_log("%s(%d): %ld %d\n", __func__, socket->descriptor, size, conn->state);
 
     // check if connection closed
     assert(conn);
     if (size == 0) {
         DEBUGPRINT("%d, closing from http_server_recv\n", conn->request_no);
 // debug_printf("%s.%d:\n", __func__, __LINE__);
-        http_server_close(tpcb, conn);
+        conn->state = HTTP_STATE_CLOSING;
+        http_server_close(socket, conn);
         return;
     }
 
@@ -474,7 +487,7 @@ static void http_server_recv(void *arg, struct net_socket *tpcb, void *data, siz
 
     case HTTP_STATE_REQUEST:
         /* don't send an immediate ack here, do it later with the data */
-        // tpcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
+        // socket->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
 
         /* accumulate the request data */
         conn->request_length += size;
@@ -525,7 +538,7 @@ static void http_server_recv(void *arg, struct net_socket *tpcb, void *data, siz
 
         conn->filename = (char *)uri;
         conn->callback = send_response;
-        conn->pcb = tpcb;
+        conn->pcb = socket;
         conn->start_ts = rdtsc();
         /* for callback execution */
         errval_t e = http_cache_lookup(uri, conn);
@@ -548,30 +561,30 @@ invalid:
     DEBUGPRINT("invalid request: %s\n", conn->request);
     DEBUGPRINT("%d: invalid request: %s\n",conn->request_no, conn->request);
     conn->state = HTTP_STATE_CLOSING;
-// debug_printf("%s.%d:\n", __func__, __LINE__);
-    http_server_close(tpcb, conn);
+    http_server_close(socket, conn);
     return;
 }
 
-static void http_server_accept(void *arg, struct net_socket *tpcb)
+static void http_server_accept(void *arg, struct net_socket *socket)
 {
 // #if TCP_LISTEN_BACKLOG
 //     /* Decrease the listen backlog counter */
 //     struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen*)arg;
 // #endif
-    // debug_printf("%s(%d):\n", __func__, tpcb->descriptor);
+    // debug_printf_to_log("%s(%d):", __func__, socket->descriptor);
     struct http_conn *conn = http_conn_new();
     DEBUGPRINT("accpet called: %s\n", conn->request);
     increment_http_conn_reference (conn);
     /* NOTE: This initial increment marks the basic assess and it will be
         decremented by http_server_invalidate */
 
-    net_set_user_state(tpcb, conn);
-    net_recv(tpcb, http_server_recv);
-    net_set_sent(tpcb, http_server_sent);
+    net_set_user_state(socket, conn);
+    net_set_on_received(socket, http_server_recv);
+    net_set_on_sent(socket, http_server_sent);
+    net_set_on_closed(socket, http_server_closed);
 
-    // tcp_err(tpcb, http_server_err);
-    // tcp_poll(tpcb, http_poll, 4);
+    // tcp_err(socket, http_server_err);
+    // tcp_poll(socket, http_poll, 4);
 }
 
 
@@ -586,7 +599,7 @@ static void realinit(void)
     e = net_listen(pcb, 100);
     assert(e == SYS_ERR_OK);
 
-    net_accept(pcb, http_server_accept);
+    net_set_on_accepted(pcb, http_server_accept);
     printf("HTTP setup time %"PU"\n", in_seconds(get_time_delta(&ts)));
     printf("#######################################################\n");
     printf("Starting webserver\n");