net_sockets: e1000 server
authorAdam Turowski <adam.turowski@inf.ethz.ch>
Mon, 26 Jun 2017 13:51:00 +0000 (15:51 +0200)
committerAdam Turowski <adam.turowski@inf.ethz.ch>
Mon, 3 Jul 2017 15:06:08 +0000 (17:06 +0200)
Signed-off-by: Adam Turowski <adam.turowski@inf.ethz.ch>

19 files changed:
if/net_sockets.if
include/lwip2/lwip/arch.h
include/net/net.h
include/net_sockets/net_sockets_types.h
lib/lwip2/src/sys_arch.c
lib/net/Hakefile
lib/net_sockets/net_sockets.c
lib/nfs/rpc.c
usr/drivers/e10k/e10k_cdriver.c
usr/drivers/net_socket_server/Hakefile [new file with mode: 0644]
usr/drivers/net_socket_server/e1000_net_sockets_server.c [moved from lib/net/net_sockets_server.c with 70% similarity]
usr/skb/programs/device_db.pl
usr/tests/net_tests/nfs_throughput/nfs_cat.c
usr/webserver/http_cache.c
usr/webserver/http_cache.h
usr/webserver/http_server.c
usr/webserver/main.c
usr/webserver/webserver_network.h
usr/webserver/webserver_session.h

index db54040..19ac47f 100644 (file)
@@ -20,5 +20,5 @@ interface net_sockets "Interface for network sockets" {
     rpc connect(in uint32 descriptor, in uint32 host_address, in uint16 port, out errval error);
     message connected(uint32 descriptor, errval error);
 
-    message accepted(uint32 descriptor, uint32 new_descriptor, uint32 host_address, uint16 port, errval error);
+//    message accepted(uint32 descriptor, uint32 new_descriptor, uint32 host_address, uint16 port, errval error);
 };
index 7c2c11c..b5405e1 100644 (file)
 #ifndef LWIP_HDR_ARCH_H
 #define LWIP_HDR_ARCH_H
 
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#endif
+// #ifndef LITTLE_ENDIAN
+// #define LITTLE_ENDIAN 1234
+// #endif
+//
+// #ifndef BIG_ENDIAN
+// #define BIG_ENDIAN 4321
+// #endif
 
 #include "arch/cc.h"
 
@@ -72,7 +72,7 @@
 
 /** Platform specific diagnostic output.\n
  * Note the default implementation pulls in printf, which may
- * in turn pull in a lot of standard libary code. In resource-constrained 
+ * in turn pull in a lot of standard libary code. In resource-constrained
  * systems, this should be defined to something less resource-consuming.
  */
 #ifndef LWIP_PLATFORM_DIAG
@@ -83,7 +83,7 @@
 
 /** Platform specific assertion handling.\n
  * Note the default implementation pulls in printf, fflush and abort, which may
- * in turn pull in a lot of standard libary code. In resource-constrained 
+ * in turn pull in a lot of standard libary code. In resource-constrained
  * systems, this should be defined to something less resource-consuming.
  */
 #ifndef LWIP_PLATFORM_ASSERT
index ec25530..6e68f4f 100644 (file)
@@ -17,6 +17,7 @@
 #define LIB_NET_INCLUDE_NETWORKING_H_
 
 #include <netinet/in.h>
+#include <errors/errno.h>
 
 // forward declarations
 struct devq;
index aac7e26..b64c0b7 100644 (file)
@@ -7,15 +7,13 @@
 struct net_socket;
 
 typedef void (*net_received_callback_t)(void *user_state, struct net_socket *socket, void *data, size_t size, struct in_addr ip_address, uint16_t port);
-typedef void (*net_sent_callback_t)(void *user_state, struct net_socket *socket, void *data);
+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, struct in_addr ip_address, uint16_t port);
 
 struct net_buffer {
-    net_received_callback_t user_callback;
-    uint64_t user_state;
     uint32_t size;
-    uint32_t descriptor;
+    uint32_t descriptor, accepted_descriptor;
     struct in_addr host_address;
     uint16_t port;
 };
index e5b6089..f6ada52 100644 (file)
@@ -10,6 +10,7 @@
 #include <lwip/sys.h>
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/deferred.h>
+#include <barrelfish/systime.h>
 
 /*
  * TODO:
 
 unsigned char debug_flags;
 
-#include <barrelfish/sys_debug.h>
-static cycles_t tsc_per_ms = 0;
 u32_t sys_now(void)
 {
-    if (tsc_per_ms == 0) {
-        sys_debug_get_tsc_per_ms(&tsc_per_ms);
-    }
-
-    return rdtsc() / tsc_per_ms;
+    uint64_t ns = systime_to_ns(systime_now());
+    return ns / 1000;
 }
 
 #if 0
index 177b9b7..8214e6d 100644 (file)
     target       = "net_arp",
     cFiles       = [ "test/arp.c" ],
     addLibraries = libDeps [ "net", "lwip2" ]
-  },
-  build application {
-    target       = "net_sockets_server",
-    cFiles       = [ "net_sockets_server.c" ],
-    flounderBindings = [ "net_sockets" ],
-    addLibraries = libDeps [ "net", "lwip2" ]
   }
 ]
index b371a65..bb7302b 100644 (file)
@@ -116,6 +116,7 @@ static struct net_socket * get_socket(uint32_t descriptor)
         if (socket == sockets)
             break;
     }
+    debug_printf("%s: %d %p\n", __func__, descriptor, __builtin_return_address(0));
     assert(0);
     return NULL;
 }
@@ -129,11 +130,13 @@ void net_close(struct net_socket *socket)
 {
     errval_t err, error;
 
+    debug_printf("%s(%d):\n", __func__, socket->descriptor);
     err = binding->rpc_tx_vtbl.delete_socket(binding, socket->descriptor, &error);
     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)
@@ -162,7 +165,7 @@ void * net_alloc(size_t size)
     assert(buffer);
     buffers[next_free] = NULL;
     next_free = (next_free + 1) % NO_OF_BUFFERS;
-    // debug_printf("%s: %ld:%p  %ld:%p\n", __func__, next_free, buffers[next_free], next_used, buffers[next_used]);
+    // debug_printf("%s: %p:%zd  %ld:%p  %ld:%p  %p\n", __func__, buffer + sizeof(struct net_buffer), size, next_free, buffers[next_free], next_used, buffers[next_used], __builtin_return_address(0));
     return buffer + sizeof(struct net_buffer);
 }
 
@@ -171,7 +174,7 @@ void net_free(void *buffer)
     assert(!buffers[next_used]);
     buffers[next_used] = buffer - sizeof(struct net_buffer);
     next_used = (next_used + 1) % NO_OF_BUFFERS;
-    // debug_printf("%s: %ld:%p  %ld:%p\n", __func__, next_free, buffers[next_free], next_used, buffers[next_used]);
+    // debug_printf("%s: %p  %ld:%p  %ld:%p  %p\n", __func__, buffer, next_free, buffers[next_free], next_used, buffers[next_used], __builtin_return_address(0));
 }
 
 errval_t net_send(struct net_socket *socket, void *data, size_t size)
@@ -180,7 +183,7 @@ 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__, descriptor, size, buffer);
+    // debug_printf("%s(%d): %ld -> %p\n", __func__, socket->descriptor, size, buffer);
 
     nb->size = size;
     nb->descriptor = socket->descriptor;
@@ -247,12 +250,10 @@ void net_accept(struct net_socket *socket, net_accepted_callback_t cb)
     socket->accepted = cb;
 }
 
-static void net_accepted(struct net_sockets_binding *b, uint32_t descriptor,
-    uint32_t accepted_descriptor, uint32_t host_address, uint16_t port, errval_t error)
+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);
     assert(socket->descriptor == descriptor);
-    assert(err_is_ok(error));
 
     struct net_socket *accepted_socket = malloc(sizeof(struct net_socket));
     assert(accepted_socket);
@@ -266,7 +267,7 @@ static void net_accepted(struct net_sockets_binding *b, uint32_t descriptor,
     enqueue(&sockets, accepted_socket);
 
     assert(socket->accepted);
-    socket->accepted(socket->user_state, accepted_socket, (struct in_addr){(host_address)}, port);
+    socket->accepted(socket->user_state, accepted_socket, host_address, port);
 }
 
 
@@ -321,24 +322,37 @@ static errval_t q_notify(struct descq* q)
         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);
             void *shb_data = buffer + sizeof(struct net_buffer);
 
-            // debug_printf("%s: dequeue %lx:%ld %ld  %p socket:%p\n", __func__, offset, length, flags, nb, socket);
             if (flags == 1) { // receiving buffer
                 // debug_printf("%s: enqueue 1> %lx:%d\n", __func__, offset, nb->size);
-                if (socket->received)
-                    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, 2048, 0, 0, 1);
-                assert(err_is_ok(err));
-                notify = 1;
+                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
+                    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
-                if (socket->sent)
-                    socket->sent(socket->user_state, socket, shb_data);
+                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;
@@ -386,7 +400,7 @@ errval_t net_sockets_init(void)
     }
     debug_printf("%s: initialized\n", __func__);
     binding->rx_vtbl.connected = net_connected;
-    binding->rx_vtbl.accepted = net_accepted;
+    // binding->rx_vtbl.accepted = net_accepted;
 
     err = binding->rpc_tx_vtbl.register_queue(binding, queue_id);
     assert(err_is_ok(err));
index 74245df..d67d6f7 100644 (file)
@@ -234,7 +234,7 @@ out:
     if (call != NULL) {
         // We got reply, so there is not need for keeping TX packet saved
         // here for retransmission.  Lets free it up.
-        XDR_DESTROY(&xdr);
+        net_free(call->data);
         free(call);
     }
 }
index 49ab0c9..2a295d7 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <net/net.h>
 
 #include <net_device_manager/net_device_manager.h>
 #include <pci/pci.h>
@@ -18,7 +19,6 @@
 #include <barrelfish/debug.h>
 #include <barrelfish/deferred.h>
 #include <lwip/ip.h>
-#include <net/net.h>
 #ifdef LIBRARY
 #       include <netif/e1000.h>
 #endif
diff --git a/usr/drivers/net_socket_server/Hakefile b/usr/drivers/net_socket_server/Hakefile
new file mode 100644 (file)
index 0000000..5267d36
--- /dev/null
@@ -0,0 +1,19 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2007-2012, ETH Zurich.
+-- All rights reserved.
+--
+-- This file is distributed under the terms in the attached LICENSE file.
+-- If you do not find this file, copies can be found by writing to:
+-- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for /lib/net
+--
+--------------------------------------------------------------------------
+
+[  build application {
+    target       = "e1000_net_sockets_server",
+    cFiles       = [ "e1000_net_sockets_server.c" ],
+    flounderBindings = [ "net_sockets" ],
+    addLibraries = libDeps [ "net", "lwip2" ]
+  }
+]
similarity index 70%
rename from lib/net/net_sockets_server.c
rename to usr/drivers/net_socket_server/e1000_net_sockets_server.c
index 9262aa1..36a14e8 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * @brief
- *  udp_echo.c
+ *  E1000 net socket server
  */
 
 /*
@@ -42,7 +42,7 @@ struct network_connection {
     struct capref buffer_cap;
     struct descq *queue;
     uint64_t queue_id;
-    regionid_t regionid;
+    regionid_t region_id;
     void *buffer_start;
     uint64_t buffer_size;
 
@@ -55,10 +55,18 @@ struct network_connection {
     struct socket_connection *sockets;
 };
 
+#define MAX_SEND_FRAMES 2
+
+struct send_frame {
+    genoffset_t offset;
+    genoffset_t sent, length;
+};
+
 struct socket_connection {
     struct socket_connection *next;
     struct network_connection *connection;
     uint32_t descriptor;
+    struct send_frame send_frames[MAX_SEND_FRAMES];
 
     struct udp_pcb *udp_socket;
     struct tcp_pcb *tcp_socket;
@@ -98,6 +106,8 @@ static struct socket_connection * allocate_socket(struct network_connection *nc)
     socket->udp_socket = NULL;
     socket->tcp_socket = NULL;
 
+    memset(socket->send_frames, 0, sizeof(socket->send_frames));
+
     return socket;
 }
 
@@ -143,8 +153,8 @@ static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, cons
         it = it->next;
     }
     pbuf_free(p);
-    // debug_printf("%s: enqueue 1 %lx:%ld\n", __func__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length);
-    err = devq_enqueue((struct devq *)nc->queue, nc->regionid, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
+    // 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);
     assert(err_is_ok(err));
     err = devq_notify((struct devq *)nc->queue);
@@ -165,8 +175,9 @@ 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);
     if (p) {
-        debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
+        // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
         assert(p->len == p->tot_len);
         length = p->tot_len;
         if (!buffer) {
@@ -177,9 +188,10 @@ static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err
         assert(buffer);
         nb->size = length;
         nb->descriptor = socket->descriptor;
+        nb->accepted_descriptor = 0;
         nb->host_address.s_addr = 0;
         nb->port = 0;
-        // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
+        // debug_printf("%s(%d): %p -> %d\n", __func__, socket->descriptor, buffer, nb->size);
 
         void *shb_data = buffer + sizeof(struct net_buffer);
         memcpy((void *)shb_data, p->payload, length);
@@ -189,6 +201,7 @@ static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err
         assert(buffer);
         nb->size = 0;
         nb->descriptor = socket->descriptor;
+        nb->accepted_descriptor = 0;
         nb->host_address.s_addr = 0;
         nb->port = 0;
         debug_printf("%s(%d): close\n", __func__, socket->descriptor);
@@ -198,8 +211,8 @@ static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err
     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
     
-    // debug_printf("%s: enqueue 1 %lx:%ld\n", __func__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length);
-    err = devq_enqueue((struct devq *)nc->queue, nc->regionid, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
+    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);
     assert(err_is_ok(err));
     err = devq_notify((struct devq *)nc->queue);
@@ -211,21 +224,114 @@ 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)
+{
+    struct socket_connection *socket = arg;
+    // struct network_connection *nc = socket->connection;
+    
+    debug_printf("%s(%d): error %d\n", __func__, socket->descriptor, err);
+    socket->tcp_socket = NULL; // invalidate
+
+    // uint32_t length = 0;
+    // void *buffer = nc->buffers[nc->next_free];
+    // struct net_buffer *nb = buffer;
+    //
+    // assert(buffer);
+    // nb->size = 0;
+    // nb->descriptor = socket->descriptor;
+    // nb->accepted_descriptor = 0;
+    // nb->host_address.s_addr = 0;
+    // nb->port = 0;
+    // debug_printf("%s(%d): close on error\n", __func__, socket->descriptor);
+    // nc->buffers[nc->next_free] = NULL;
+    // nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
+    // assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
+    //
+    // // 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);
+    // assert(err_is_ok(err));
+    // err = devq_notify((struct devq *)nc->queue);
+    // assert(err_is_ok(err));
+}
+
+static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
+{
+    struct socket_connection *socket = arg;
+    struct network_connection *nc = socket->connection;
+    bool notify = false;
+    errval_t err;
+
+    while (len > 0) {
+        // 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);
+        assert(socket->send_frames[0].length);
+        if (len < (socket->send_frames[0].length - socket->send_frames[0].sent)) {
+            socket->send_frames[0].sent += len;
+            len = 0;
+        } else {
+            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);
+            if (!err_is_ok(err))
+                debug_printf("%s: err %zd\n", __func__, err);
+            assert(err_is_ok(err));
+            notify = true;
+            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;
+        }
+    }
+    if (notify) {
+        err = devq_notify((struct devq *)nc->queue);
+        assert(err_is_ok(err));
+    }
+    return ERR_OK;
+}
+
 static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
 {
     struct socket_connection *socket = arg;
     struct network_connection *nc = socket->connection;
     struct socket_connection *accepted_socket;
 
-    tcp_accepted(newpcb);
     accepted_socket = allocate_socket(nc);
     accepted_socket->udp_socket = NULL;
     accepted_socket->tcp_socket = newpcb;
     tcp_arg(accepted_socket->tcp_socket, accepted_socket);
     tcp_recv(accepted_socket->tcp_socket, net_tcp_receive);
+    tcp_err(accepted_socket->tcp_socket, net_tcp_error);
+    tcp_sent(accepted_socket->tcp_socket, net_tcp_sent);
 
     debug_printf("%s(%d): -> %d\n", __func__, socket->descriptor, accepted_socket->descriptor);
-    errval_t err = nc->binding->tx_vtbl.accepted(nc->binding, BLOCKING_CONT, socket->descriptor, accepted_socket->descriptor, 0, 0, SYS_ERR_OK);
+    // errval_t err = nc->binding->tx_vtbl.accepted(nc->binding, BLOCKING_CONT, socket->descriptor, accepted_socket->descriptor, 0, 0, SYS_ERR_OK);
+    // assert(err_is_ok(err));
+
+    errval_t err;
+    uint32_t length = 0;
+    void *buffer = nc->buffers[nc->next_free];
+    struct net_buffer *nb = buffer;
+
+    nb->size = 0;
+    nb->descriptor = socket->descriptor;
+    nb->accepted_descriptor = accepted_socket->descriptor;
+    nb->host_address.s_addr = 0;
+    nb->port = 0;
+    debug_printf("%s(%d): accepted %p\n", __func__, socket->descriptor, newpcb);
+
+    nc->buffers[nc->next_free] = NULL;
+    nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
+    assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
+    
+    // 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);
+    assert(err_is_ok(err));
+    err = devq_notify((struct devq *)nc->queue);
     assert(err_is_ok(err));
 
     return ERR_OK;
@@ -337,9 +443,10 @@ static errval_t net_listen(struct net_sockets_binding *binding, uint32_t descrip
     }
     assert(socket);
     assert(socket->tcp_socket);
-    debug_printf("%s(%d):\n", __func__, descriptor);
     socket->tcp_socket = tcp_listen(socket->tcp_socket);
+    debug_printf("%s(%d): listen %p\n", __func__, descriptor, socket->tcp_socket);
     tcp_accept(socket->tcp_socket, net_tcp_accepted);
+    tcp_err(socket->tcp_socket, net_tcp_error);
     // socket->tcp_socket = tcp_listen_with_backlog(socket->tcp_socket, backlog);
     assert(socket->tcp_socket);
 
@@ -375,16 +482,12 @@ static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descri
     if (socket->udp_socket) {
         ip_addr_t addr;
         addr.addr = ip_address;
-        debug_printf("%s(%d):\n", __func__, descriptor);
         assert(udp_connect(socket->udp_socket, &addr, port) == ERR_OK);
-        debug_printf("%s(%d)#\n", __func__, descriptor);
         *error = SYS_ERR_OK;
     } else if (socket->tcp_socket) {
         ip_addr_t addr;
         addr.addr = ip_address;
-        debug_printf("%s(%d):\n", __func__, descriptor);
         assert(tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected) == ERR_OK);
-        debug_printf("%s(%d)#\n", __func__, descriptor);
         *error = SYS_ERR_OK;
     }
 
@@ -410,12 +513,16 @@ static errval_t net_delete_socket(struct net_sockets_binding *binding, uint32_t
         udp_recv(socket->udp_socket, NULL, NULL);
         udp_remove(socket->udp_socket);
     } else if (socket->tcp_socket) {
-        // tcp_recv(socket->tcp_socket, NULL);
+        tcp_recv(socket->tcp_socket, NULL); // you can receive packets after you close the socket
         // tcp_accept(socket->tcp_socket, NULL);
-        tcp_close(socket->tcp_socket);
+        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("%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)
         last->next = socket->next;
     else
@@ -478,6 +585,7 @@ static errval_t q_notify(struct descq* q)
         } 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);
                 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;
@@ -511,8 +619,8 @@ static errval_t q_notify(struct descq* q)
                     uint16_t port;
                     port = nb->port;
                     addr.addr = nb->host_address.s_addr;
-                    // debug_printf("%s: enqueue 2 %lx:%d\n", __func__, offset, BUFFER_SIZE);
-                    err = devq_enqueue(queue, rid, offset, BUFFER_SIZE, 0, 0, 2);
+                    // debug_printf("%s.%d: enqueue 2 %lx:%d\n", __func__, __LINE__, offset, nb->size);
+                    err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
                     assert(err_is_ok(err));
                     notify = 1;
                     // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
@@ -524,11 +632,32 @@ 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);
                     
+                    if (socket->send_frames[0].length == 0) {
+                        
+                    } else {
+                        assert(socket->send_frames[1].length == 0);
+                    }
+                    // debug_printf("%s: tcp_write %d %d\n", __func__, tcp_sndbuf(socket->tcp_socket), nb->size);
                     e = tcp_write(socket->tcp_socket, shb_data, nb->size, TCP_WRITE_FLAG_COPY);
+                    if (e != ERR_OK)
+                        debug_printf("%s: e=%d\n", __func__, e);
                     assert(e == ERR_OK);
                     e = tcp_output(socket->tcp_socket);
                     assert(e == ERR_OK);
+                    
+                    if (socket->send_frames[0].length == 0) {
+                        socket->send_frames[0].offset = offset;
+                        socket->send_frames[0].length = length - sizeof(struct net_buffer);
+                    } else {
+                        socket->send_frames[1].offset = offset;
+                        socket->send_frames[1].length = length - sizeof(struct net_buffer);
+                    }
+                    // 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;
                 }
             }
         }
@@ -555,7 +684,7 @@ static errval_t q_reg(struct descq* q, struct capref cap,
     errval_t err = frame_identify(cap, &pa);
     assert(err_is_ok(err));
     nc->buffer_cap = cap;
-    nc->regionid = rid;
+    nc->region_id = rid;
 
     nc->buffer_size = pa.bytes;
     err = vspace_map_one_frame(&nc->buffer_start, pa.bytes, cap, NULL, NULL);
@@ -606,7 +735,7 @@ int main(int argc, char *argv[])
 {
     errval_t err;
 
-    debug_printf("UDP ECHO started.\n");
+    debug_printf("Net socket server started for e1000 %s.\n", argv[2]);
 
     char servicename[64];
     snprintf(servicename, sizeof(servicename), "e1000:%s", argv[2]);
index 6414b8f..5f76a17 100644 (file)
@@ -37,7 +37,7 @@
 %
 
 pci_driver{
-    binary: "e1000n",
+    binary: "e1000_net_sockets_server",
     supported_cards:
     [ pci_card{ vendor: 16'8086, device: 16'1521, function: _, subvendor: _, subdevice: _ },
       pci_card{ vendor: 16'8086, device: 16'107d, function: _, subvendor: _, subdevice: _ },
index 1615f00..3cd3b96 100644 (file)
@@ -99,6 +99,7 @@ int main(int argc, char**argv)
         exit(EXIT_FAILURE);
     }
 
+// don't have to do this, MOUNT_DIR is already there
 //    err = vfs_mkdir(MOUNT_DIR);
 //    if (err_is_fail(err)) {
 //        DEBUG_ERR(err, "vfs_mount");
index 0ca45f8..64d0be9 100644 (file)
@@ -639,7 +639,7 @@ static void mount_callback(void *arg, struct nfs_client *client,
 #endif // PRELOAD_WEB_CACHE
 } /* end function: mount_callback */
 
-errval_t http_cache_init(host_address_t server, const char *path,
+errval_t http_cache_init(struct in_addr server, const char *path,
                      void (*callback)(void))
 {
     struct timer *cache_timer;      /* timer for triggering cache timeouts */
index 1bbd798..180d212 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef HTTP_CACHE_H
 #define HTTP_CACHE_H
 #include "webserver_session.h"
-errval_t http_cache_init (host_address_t server, const char *path,
+errval_t http_cache_init (struct in_addr server, const char *path,
                      void (*callback)(void));
 errval_t http_cache_lookup (const char *name, struct http_conn *cs);
 long decrement_buff_holder_ref (struct buff_holder *bh);
index 5aa6cc4..3b6abb3 100644 (file)
@@ -210,7 +210,8 @@ more)
 
     for (sendlen = 0; sendlen < *len;) {
         void *buffer;
-        size_t s = *len > 1500 ? 1500: *len;
+        size_t s = *len - sendlen;
+        s = s > 16000 ? 16000: s;
 
         buffer = net_alloc(s);
         if (!buffer)
@@ -248,6 +249,8 @@ static void http_send_data(struct net_socket *tpcb, struct http_conn *conn)
                 conn->request_no, conn->header_pos, conn->header_length);
         if (conn->header_pos == conn->header_length) {
             conn->state = HTTP_STATE_SENDFILE; // fall through below
+            conn->reply_pos = 0;
+            conn->reply_sent = 0;
         } else {
             break;
         }
@@ -257,8 +260,12 @@ static void http_send_data(struct net_socket *tpcb, struct http_conn *conn)
             conn->state = HTTP_STATE_CLOSING;
             break;
         }
-        data = conn->hbuff->data +conn->reply_pos; /* pointer arithmatic */
+        data = conn->hbuff->data + conn->reply_pos; /* pointer arithmatic */
         len = conn->hbuff->len - conn->reply_pos;
+        size_t maxlen = 16000 - (conn->reply_pos - conn->reply_sent);
+        // debug_printf("%s: %zd %zd\n", __func__, len, maxlen);
+        if (len > maxlen)
+            len = maxlen;
         err = trysend(tpcb, data, &len, false);
         if (err != SYS_ERR_OK) {
             DEBUGPRINT("http_send_data(): Error %d sending payload\n", err);
@@ -321,13 +328,19 @@ static void http_send_data(struct net_socket *tpcb, struct http_conn *conn)
 // } /* end function: http_poll */
 
 /* called when data is successfully sent */
-static void http_server_sent(void *arg, struct net_socket *socket, void *buffer)
+static void http_server_sent(void *arg, struct net_socket *socket, void *buffer, size_t size)
 {
     struct http_conn *conn = arg;
 
     assert(conn);
     net_free(buffer);
 
+    // debug_printf("%s: %zd  %zd:%zd  %zd:%zd\n", __func__, size, conn->header_pos, conn->header_sent, conn->reply_pos, conn->reply_sent);
+    if (conn->header_sent < conn->header_pos)
+        conn->header_sent += size;
+    else
+        conn->reply_sent += size;
+
     switch(conn->state) {
     case HTTP_STATE_SENDHEADER:
     case HTTP_STATE_SENDFILE:
@@ -341,7 +354,9 @@ static void http_server_sent(void *arg, struct net_socket *socket, void *buffer)
     case HTTP_STATE_CLOSING:
         DEBUGPRINT("%d: http_server_sent closing the connection\n",
                     conn->request_no);
-        http_server_close(socket, conn);
+// 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);
         break;
 
     default:
@@ -392,7 +407,7 @@ static void send_response(struct http_conn *cs)
 
         cs->header = error_reply;
         cs->header_length = sizeof(error_reply) - 1;
-
+        cs->header_sent = 0;
     } else {
         DEBUGPRINT ("%d: Sending the response back of size %lu\n",
                 cs->request_no, cs->reply_pos);
@@ -409,9 +424,11 @@ static void send_response(struct http_conn *cs)
 
             cs->header = notfound_reply;
             cs->header_length = sizeof(notfound_reply) - 1;
+            cs->header_sent = 0;
         } else {
             /* found, send static header */
             cs->header = make_header(cs->filename, &cs->header_length);
+            cs->header_sent = 0;
         }
     } /* end else: internal error */
 
@@ -424,7 +441,8 @@ static void send_response(struct http_conn *cs)
     if (cs->state == HTTP_STATE_CLOSING) {
         DEBUGPRINT("%d: send_response closing the connection\n",
                 cs->request_no);
-        http_server_close(cs->pcb, cs);
+// debug_printf("%s.%d:\n", __func__, __LINE__);
+                                // http_server_close(cs->pcb, cs);
     } else {
         // tcp_output(cs->pcb);
     }
@@ -433,7 +451,7 @@ static void send_response(struct http_conn *cs)
 // static errval_t http_server_recv(void *arg, struct net_socket *tpcb, struct pbuf *p,
 //                               errval_t err);
 //
-static void http_server_recv(void *arg, struct net_socket *tpcb, void *data, size_t size, host_address_t ip_address, uint16_t port)
+static void http_server_recv(void *arg, struct net_socket *tpcb, void *data, size_t size, struct in_addr ip_address, uint16_t port)
 {
     struct http_conn *conn = arg;
 
@@ -444,6 +462,7 @@ static void http_server_recv(void *arg, struct net_socket *tpcb, void *data, siz
     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);
         return;
     }
@@ -529,11 +548,12 @@ 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);
     return;
 }
 
-static void http_server_accept(void *arg, struct net_socket *tpcb, host_address_t ip_address, uint16_t port)
+static void http_server_accept(void *arg, struct net_socket *tpcb, struct in_addr ip_address, uint16_t port)
 {
 // #if TCP_LISTEN_BACKLOG
 //     /* Decrease the listen backlog counter */
@@ -560,7 +580,7 @@ static void realinit(void)
     uint64_t ts = rdtsc();
     struct net_socket *pcb = net_tcp_socket();
 //    err_t e = tcp_bind(pcb, IP_ADDR_ANY, (HTTP_PORT + disp_get_core_id()));
-    errval_t e = net_bind(pcb, 0, HTTP_PORT);
+    errval_t e = net_bind(pcb, (struct in_addr){(INADDR_ANY)}, HTTP_PORT);
     assert(e == SYS_ERR_OK);
 
     e = net_listen(pcb, 100);
@@ -574,7 +594,7 @@ static void realinit(void)
 
 }
 
-void http_server_init(host_address_t server, const char *path)
+void http_server_init(struct in_addr server, const char *path)
 {
     http_cache_init(server, path, realinit);
 }
index 83a12c4..1a926e4 100644 (file)
 #include <barrelfish/waitset.h>
 #include <barrelfish/nameservice_client.h>
 #include <stdio.h>
+#include <net_sockets/net_sockets.h>
 #include <netif/etharp.h>
 #include <netif/bfeth.h>
 #include <netbench/netbench.h>
 #include <trace/trace.h>
 #include <trace_definitions/trace_defs.h>
-#include <net_sockets/net_sockets.h>
 
 // #include <lwip/dhcp.h>
 // #include <netif/etharp.h>
@@ -31,7 +31,7 @@
 #include "webserver_network.h"
 #include "webserver_debug.h"
 
-static struct ip_addr serverip;
+static struct in_addr serverip;
 static const char *serverpath;
 
 /* Enable tracing only when it is globally enabled */
@@ -51,12 +51,10 @@ int main(int argc, char**argv)
     }
 //    char *card_name = argv[1];
 
-    struct in_addr server1;
-    if (inet_aton(argv[1], &server1) == 0) {
+    if (inet_aton(argv[1], &serverip) == 0) {
         printf("Invalid IP addr: %s\n", argv[1]);
         return 1;
     }
-    serverip.addr = server1.s_addr; // XXX
     serverpath = argv[2];
 
     // Boot up
@@ -68,7 +66,7 @@ int main(int argc, char**argv)
     printf("webserver:%u: networking initialized\n", disp_get_core_id());
 
 //    lwip_benchmark_control(1, BMS_START_REQUEST, 0, 0);
-    http_server_init(serverip.addr, serverpath);
+    http_server_init(serverip, serverpath);
 
     DEBUGPRINT("Init finished.\n");
 
index a90b600..e563e84 100644 (file)
@@ -15,6 +15,6 @@
 #ifndef WEBSERVER_NETWORK_H
 #define WEBSERVER_NETWORK_H
 
-void http_server_init(host_address_t server, const char *path);
+void http_server_init(struct in_addr server, const char *path);
 
 #endif // WEBSERVER_NETWORK_H
index 17b7875..6f04c89 100644 (file)
@@ -40,10 +40,11 @@ struct http_conn {
     size_t              request_length;
     /* reply header, position and length (static) */
     const char          *header;
-    size_t              header_pos, header_length;
+    size_t              header_pos, header_length, header_sent;
 
     struct buff_holder  *hbuff;      /* reply buffer holder */
     size_t              reply_pos;  /* amount of data sent from reply */
+    size_t              reply_sent;
 
     // Time taken to send reply
     uint64_t            start_ts;