net_sockets: converting nfs
authorAdam Turowski <adam.turowski@inf.ethz.ch>
Wed, 7 Jun 2017 10:54:18 +0000 (12:54 +0200)
committerAdam Turowski <adam.turowski@inf.ethz.ch>
Mon, 3 Jul 2017 15:05:19 +0000 (17:05 +0200)
Signed-off-by: Adam Turowski <adam.turowski@inf.ethz.ch>

38 files changed:
if/Hakefile
if/net_sockets.if [new file with mode: 0644]
include/barrelfish/dispatcher.h
include/barrelfish/notificator.h [new file with mode: 0644]
include/debug_log/debug_log.h [new file with mode: 0644]
include/net_sockets/net_sockets.h [new file with mode: 0644]
include/net_sockets/net_sockets_types.h [new file with mode: 0644]
include/nfs/nfs.h
include/nfs/xdr.h
lib/barrelfish/Hakefile
lib/barrelfish/dispatch.c
lib/barrelfish/include/threads_priv.h
lib/barrelfish/notificator.c [new file with mode: 0644]
lib/debug_log/Hakefile [new file with mode: 0644]
lib/debug_log/debug_log.c [new file with mode: 0644]
lib/devif/backends/idc/desc_queue.c
lib/devif/region_pool.c
lib/net/Hakefile
lib/net/net_sockets_server.c [new file with mode: 0644]
lib/net_sockets/Hakefile [new file with mode: 0644]
lib/net_sockets/net_sockets.c [new file with mode: 0644]
lib/nfs/Hakefile
lib/nfs/nfs.c
lib/nfs/rpc.c
lib/nfs/rpc.h
lib/nfs/xdr.c
lib/nfs/xdr_pbuf.c
lib/nfs/xdr_pbuf.h
lib/vfs/Hakefile
lib/vfs/vfs_nfs.c
usr/tests/net_tests/nfs_throughput/Hakefile
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 5bdb504..56832e8 100644 (file)
@@ -95,7 +95,8 @@
                "descq",
                "ddomain",
                "dcontrol",
-               "net_filter"
+               "net_filter",
+               "net_sockets"
            ],
              arch <- allArchitectures
 ] ++
diff --git a/if/net_sockets.if b/if/net_sockets.if
new file mode 100644 (file)
index 0000000..db54040
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+interface net_sockets "Interface for network sockets" {
+    rpc register_queue(in uint64 queue_id);
+
+    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);
+    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);
+
+    message accepted(uint32 descriptor, uint32 new_descriptor, uint32 host_address, uint16 port, errval error);
+};
index 845b0e6..8a5f34d 100644 (file)
@@ -23,6 +23,7 @@
 struct lmp_chan;
 struct ump_chan;
 struct deferred_event;
+struct notificator;
 
 // Architecture generic user only dispatcher struct
 struct dispatcher_generic {
@@ -89,6 +90,8 @@ struct dispatcher_generic {
 
     /// list of polled channels
     struct waitset_chanstate *polled_channels;
+    
+    struct notificator *notificators;
 };
 
 #endif // BARRELFISH_DISPATCHER_H
diff --git a/include/barrelfish/notificator.h b/include/barrelfish/notificator.h
new file mode 100644 (file)
index 0000000..fabd0aa
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef NOTIFICATOR_H
+#define NOTIFICATOR_H
+
+
+#include <barrelfish/waitset.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/dispatch.h>
+
+typedef bool (*check_notification_fn_type)(void *object);
+
+struct notificator
+{
+    struct notificator *prev, *next;
+    void *object;
+    check_notification_fn_type can_read, can_write;
+    struct waitset_chanstate ready_to_read, ready_to_write;
+};
+
+
+void notificator_init(struct notificator *notificator, void *object,
+    check_notification_fn_type can_read, check_notification_fn_type can_write);
+
+void check_notificators_disabled(dispatcher_handle_t handle);
+
+#endif
diff --git a/include/debug_log/debug_log.h b/include/debug_log/debug_log.h
new file mode 100644 (file)
index 0000000..a0422a0
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef DEBUG_LOG_H
+#define DEBUG_LOG_H
+
+void debug_printf_to_log(const char *fmt, ...);
+void debug_print_to_log(const char *fmt, ...);
+void debug_print_log(void);
+unsigned int debug_print_log_to_buffer(char *buffer, int max_size);
+
+#endif
diff --git a/include/net_sockets/net_sockets.h b/include/net_sockets/net_sockets.h
new file mode 100644 (file)
index 0000000..9af03d5
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef NET_SOCKETS_H
+#define NET_SOCKETS_H
+
+#include <net_sockets/net_sockets_types.h>
+
+void * net_alloc(size_t size);
+void net_free(void *buffer);
+
+struct net_socket {
+    uint32_t descriptor;
+    net_received_callback_t received;
+    net_sent_callback_t sent;
+    net_connected_callback_t connected;
+    net_accepted_callback_t accepted;
+    void *user_state;
+    struct net_socket *prev, *next;
+};
+
+// synchronous calls
+struct net_socket * net_udp_socket(void);
+struct net_socket * net_tcp_socket(void);
+void net_set_user_state(struct net_socket *socket, void *user_state);
+void net_close(struct net_socket *socket);
+
+errval_t net_bind(struct net_socket *socket, host_address_t ip_address, uint16_t port);
+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, host_address_t 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, host_address_t ip_address, uint16_t port, net_connected_callback_t cb);
+void net_accept(struct net_socket *socket, net_accepted_callback_t cb);
+
+
+errval_t net_sockets_init(void);
+
+#endif
diff --git a/include/net_sockets/net_sockets_types.h b/include/net_sockets/net_sockets_types.h
new file mode 100644 (file)
index 0000000..def4028
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef NET_SOCKETS_TYPES_H
+#define NET_SOCKETS_TYPES_H
+
+#include <barrelfish/barrelfish.h>
+
+typedef uint32_t host_address_t;
+
+struct net_socket;
+
+typedef void (*net_received_callback_t)(void *user_state, struct net_socket *socket, void *data, size_t size, host_address_t ip_address, uint16_t port);
+typedef void (*net_sent_callback_t)(void *user_state, struct net_socket *socket, void *data);
+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, host_address_t ip_address, uint16_t port);
+
+struct net_buffer {
+    net_received_callback_t user_callback;
+    uint64_t user_state;
+    uint32_t size;
+    uint32_t descriptor;
+    host_address_t host_address;
+    uint16_t port;
+};
+
+#endif
index a61cfdb..1148572 100644 (file)
@@ -17,8 +17,7 @@
 
 #include <sys/cdefs.h>
 
-#include <lwip/err.h> // for err_t
-#include <lwip/ip_addr.h> // for struct ip_addr
+#include <net_sockets/net_sockets.h>
 #include <errors/errno.h>
 
 #include <nfs/xdr.h>
@@ -193,34 +192,34 @@ typedef void (*nfs_mkdir_callback_t)(void *arg, struct nfs_client *client,
 typedef void (*nfs_remove_callback_t)(void *arg, struct nfs_client *client,
                                       REMOVE3res *result);
 
-struct nfs_client *nfs_mount(struct ip_addr server, const char *path,
+struct nfs_client *nfs_mount(host_address_t server, const char *path,
                              nfs_mount_callback_t callback, void *cbarg);
-err_t nfs_getattr(struct nfs_client *client, struct nfs_fh3 fh,
+errval_t nfs_getattr(struct nfs_client *client, struct nfs_fh3 fh,
                   nfs_getattr_callback_t callback, void *cbarg);
-err_t nfs_setattr(struct nfs_client *client, struct nfs_fh3 fh,
+errval_t nfs_setattr(struct nfs_client *client, struct nfs_fh3 fh,
                   sattr3 new_attributes, bool guarded,
                   nfs_setattr_callback_t callback, void *cbarg);
-err_t nfs_readdir(struct nfs_client *client, struct nfs_fh3 fh,
+errval_t nfs_readdir(struct nfs_client *client, struct nfs_fh3 fh,
                   cookie3 cookie, cookieverf3 cookieverf,
                   nfs_readdir_callback_t callback, void *cbarg);
-err_t nfs_readdirplus(struct nfs_client *client, struct nfs_fh3 fh,
+errval_t nfs_readdirplus(struct nfs_client *client, struct nfs_fh3 fh,
                       cookie3 cookie, cookieverf3 cookieverf,
                       nfs_readdirplus_callback_t callback, void *cbarg);
-err_t nfs_lookup(struct nfs_client *client, struct nfs_fh3 dirfh,
+errval_t nfs_lookup(struct nfs_client *client, struct nfs_fh3 dirfh,
                  const char *name, nfs_lookup_callback_t callback, void *cbarg);
-err_t nfs_access(struct nfs_client *client, struct nfs_fh3 fh, uint32_t access,
+errval_t nfs_access(struct nfs_client *client, struct nfs_fh3 fh, uint32_t access,
                  nfs_access_callback_t callback, void *cbarg);
-err_t nfs_read(struct nfs_client *client, struct nfs_fh3 fh, offset3 offset,
+errval_t nfs_read(struct nfs_client *client, struct nfs_fh3 fh, offset3 offset,
                count3 count, nfs_read_callback_t callback, void *cbarg);
-err_t nfs_write(struct nfs_client *client, struct nfs_fh3 fh, offset3 offset,
+errval_t nfs_write(struct nfs_client *client, struct nfs_fh3 fh, offset3 offset,
                 const void *data, count3 count, stable_how stable,
                 nfs_write_callback_t callback, void *cbarg);
-err_t nfs_create(struct nfs_client *client, struct nfs_fh3 dir,
+errval_t nfs_create(struct nfs_client *client, struct nfs_fh3 dir,
                  const char *name, bool guarded, sattr3 attributes,
                  nfs_create_callback_t callback, void *cbarg);
-err_t nfs_mkdir(struct nfs_client *client, struct nfs_fh3 dir, const char *name,
+errval_t nfs_mkdir(struct nfs_client *client, struct nfs_fh3 dir, const char *name,
                 sattr3 attributes, nfs_mkdir_callback_t callback, void *cbarg);
-err_t nfs_remove(struct nfs_client *client, struct nfs_fh3 dir,
+errval_t nfs_remove(struct nfs_client *client, struct nfs_fh3 dir,
                  const char *name, nfs_remove_callback_t callback,
                  void *cbarg);
 void nfs_destroy(struct nfs_client *client);
index 4956a8f..cb13f15 100644 (file)
@@ -45,7 +45,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <stddef.h>
-#include <lwip/inet.h> /* for ntohl/htonl */
+#include <arpa/inet.h> /* for ntohl/htonl */
 #include <sys/types.h>
 #include <sys/cdefs.h>
 
@@ -136,6 +136,7 @@ typedef struct __rpc_xdr {
     //void *    x_public;   /* users' data (unused) */
     void *      x_private;  /* pointer to private data */
     void *      x_base;     /* private used for position info */
+    size_t      size;
     uintptr_t   x_handy;    /* extra private word */
 } XDR;
 
index 6d2d4e2..f4c0e54 100644 (file)
@@ -27,7 +27,8 @@ let common_srcs = [ "capabilities.c", "init.c", "dispatch.c", "threads.c",
                     "slot_alloc/single_slot_alloc.c", "slot_alloc/slot_alloc.c",
                     "slot_alloc/range_slot_alloc.c", "slot_alloc/twolevel_slot_alloc.c",
                     "bulk_transfer.c", "trace.c", "resource_ctrl.c", "coreset.c",
-                    "inthandler.c", "deferred.c", "syscalls.c", "sys_debug.c", "systime.c"
+                    "inthandler.c", "deferred.c", "syscalls.c", "sys_debug.c", "systime.c",
+                    "notificator.c"
                   ]
 in
 [(let arch_dir = "arch" </> archFamily arch
index c36aea3..8d0bef8 100644 (file)
@@ -25,7 +25,7 @@
 #include <barrelfish/deferred.h>
 #include <barrelfish_kpi/cpu_arch.h>
 #include "threads_priv.h"
-
+#include <barrelfish/notificator.h>
 
 #include <trace/trace.h>
 #include <trace_definitions/trace_defs.h>
@@ -114,6 +114,8 @@ void disp_run(dispatcher_handle_t handle)
     poll_channels_disabled(handle);
     ump_channels_retry_send_disabled(handle);
 
+    check_notificators_disabled(handle);
+
     // Run, saving state of previous thread if required
     thread_run_disabled(handle);
 
index 1928353..afad998 100644 (file)
@@ -106,6 +106,7 @@ static inline bool havework_disabled(dispatcher_handle_t handle)
             || disp->lmp_send_events_list != NULL
 #endif
             || disp->polled_channels != NULL
+            || disp->notificators != NULL
             || disp->ump_send_events_list != NULL
             ;
 }
diff --git a/lib/barrelfish/notificator.c b/lib/barrelfish/notificator.c
new file mode 100644 (file)
index 0000000..29b51b0
--- /dev/null
@@ -0,0 +1,83 @@
+#include <barrelfish/notificator.h>
+#include <barrelfish/dispatch.h>
+#include <barrelfish/dispatcher_arch.h>
+#include <barrelfish/waitset_chan.h>
+#include <include/waitset_chan_priv.h>
+
+/// Dequeue the element from the notificator queue
+// static void dequeue(struct notificator **queue,
+//                             struct notificator *element)
+// {
+//     if (element->next == element) {
+//         assert(element->prev == element);
+//         assert(*queue == element);
+//         *queue = NULL;
+//     } else {
+//         element->prev->next = element->next;
+//         element->next->prev = element->prev;
+//         if (*queue == element) {
+//             *queue = element->next;
+//         }
+//     }
+//     element->prev = element->next = NULL;
+// }
+
+/// Enqueue the element on the notificator queue
+static void enqueue(struct notificator **queue,
+                            struct notificator *element)
+{
+    if (*queue == NULL) {
+        *queue = element;
+        element->next = element->prev = element;
+    } else {
+        element->next = *queue;
+        element->prev = (*queue)->prev;
+        element->next->prev = element;
+        element->prev->next = element;
+    }
+}
+
+void notificator_init(struct notificator *notificator, void *object,
+    check_notification_fn_type can_read, check_notification_fn_type can_write)
+{
+    notificator->prev = NULL;
+    notificator->next = NULL;
+    notificator->object = object;
+    notificator->can_read = can_read;
+    notificator->can_write = can_write;
+
+    waitset_chanstate_init(&notificator->ready_to_read, CHANTYPE_OTHER);
+    notificator->ready_to_read.persistent = true;
+    waitset_chanstate_init(&notificator->ready_to_write, CHANTYPE_OTHER);
+    notificator->ready_to_write.persistent = true;
+
+    dispatcher_handle_t handle = disp_disable();
+    enqueue(&get_dispatcher_generic(handle)->notificators, notificator);
+    disp_enable(handle);
+}
+
+void check_notificators_disabled(dispatcher_handle_t handle)
+{
+    struct dispatcher_generic *dp = get_dispatcher_generic(handle);
+    struct notificator *n;
+
+    if (!dp->notificators)
+        return;
+    n = dp->notificators;
+    do {
+        if (n->can_read(n->object)) {
+            if (waitset_chan_is_registered(&n->ready_to_read)) {
+                // debug_printf("triggering\n");
+                errval_t err = waitset_chan_trigger_disabled(&n->ready_to_read, handle);
+                assert(err_is_ok(err)); // should not fail
+            }
+        }
+        if (n->can_write(n->object)) {
+            if (waitset_chan_is_registered(&n->ready_to_write)) {
+                // debug_printf("triggering\n");
+                errval_t err = waitset_chan_trigger_disabled(&n->ready_to_write, handle);
+                assert(err_is_ok(err)); // should not fail
+            }
+        }
+    } while (n != dp->notificators);
+}
diff --git a/lib/debug_log/Hakefile b/lib/debug_log/Hakefile
new file mode 100644 (file)
index 0000000..4688166
--- /dev/null
@@ -0,0 +1,15 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2007-2009, 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.
+--
+--
+--
+--------------------------------------------------------------------------
+
+[ build library { target = "debug_log",
+                  cFiles = [ "debug_log.c" ] }
+]
diff --git a/lib/debug_log/debug_log.c b/lib/debug_log/debug_log.c
new file mode 100644 (file)
index 0000000..2bb581c
--- /dev/null
@@ -0,0 +1,151 @@
+#include <barrelfish/debug.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <barrelfish/threads.h>
+#include <debug_log/debug_log.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/systime.h>
+
+#define LOG_SIZE 2048
+static char log[LOG_SIZE][256];
+static unsigned long int timestamp[LOG_SIZE];
+static unsigned int log_size = 0;
+
+void debug_printf_to_log(const char *fmt, ...)
+{
+    timestamp[log_size & (LOG_SIZE - 1)] = systime_now();
+    struct thread *me = thread_self();
+    va_list argptr;
+    char id[32] = "-";
+    char *str = log[log_size++ & (LOG_SIZE - 1)];
+    size_t len;
+    
+    if (me)
+        snprintf(id, sizeof(id), "%"PRIuPTR, thread_get_id(me));
+    len = snprintf(str, sizeof(log[0]), "\033[34m%.*s.\033[31m%u.%s\033[0m: ",
+                   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);
+        va_end(argptr);
+    }
+}
+
+// #define DEBUG_SHOW
+
+void debug_print_to_log(const char *format, ...)
+{
+#ifdef DEBUG_SHOW
+    struct thread *me = thread_self();
+    va_list argptr;
+    char id[32] = "-";
+    char str[256];
+    size_t len;
+    
+    if (me)
+        snprintf(id, sizeof(id), "%"PRIuPTR, thread_get_id(me));
+    len = snprintf(str, sizeof(str), "\033[34m%.*s.\033[31m%u.%s\033[0m: ",
+                   DISP_NAME_LEN, disp_name(), disp_get_core_id(), id);
+    if (len < sizeof(str)) {
+        va_start(argptr, format);
+        len += vsnprintf(str + len, sizeof(log[0]) - len, format, argptr);
+        va_end(argptr);
+    }
+    str[len++] = '\n';
+    sys_print(str, len);
+#else
+    timestamp[log_size & (LOG_SIZE - 1)] = systime_now();
+    char *str = log[log_size++ & (LOG_SIZE - 1)];
+    va_list argptr;
+    char hex[16] = "0123456789ABCDEF";
+    char buff[32];
+    int i, j, k;
+    
+    va_start(argptr, format);
+    j = 0;
+    for (i = 0; format[i]; i++) {
+        if (format[i] != '%') {
+            str[j++] = format[i];
+        } else if (format[i + 1] == 'x') {
+            uint64_t ts = va_arg(argptr, uint64_t);
+            for (k = 15; k >= 0; k--) {
+                buff[k] = hex[(ts & 15)];
+                ts >>= 4;
+                if (!ts)
+                    break;
+            }
+            for(; k < 16; k++)
+                str[j++] = buff[k];
+            i++;
+        } else if (format[i + 1] == 'd') {
+            uint64_t ts = va_arg(argptr, uint64_t);
+            for (k = 31; k >= 0; k--) {
+                buff[k] = '0' + ts % 10;
+                ts /= 10;
+                if (!ts)
+                    break;
+            }
+            for(; k < 32; k++)
+                str[j++] = buff[k];
+            i++;
+        }
+    }
+    va_end(argptr);
+    str[j] = 0;
+#endif
+}
+
+void debug_print_log(void)
+{
+    unsigned int i;
+    unsigned long lastts = 0;
+    int j;
+
+    if (log_size < LOG_SIZE) {
+        i = 0;
+        j = log_size;
+    } else {
+        i = log_size & (LOG_SIZE - 1);
+        j = LOG_SIZE;
+    }
+    
+    char line[256];
+    int s = snprintf(line, sizeof(line), "\nLog:%d %d:%d\n", log_size, i, j);
+    sys_print(line, s);
+    
+    for (; j > 0; j--) {
+        s = snprintf(line, sizeof(line), "\033[36;1m(%ld,%ld)\033[0m:\t%s\n",
+                   systime_to_ns(timestamp[i]), systime_to_ns(timestamp[i] - lastts), log[i]);
+        sys_print(line, s);
+        lastts = timestamp[i];
+        i = (i + 1) & (LOG_SIZE - 1);
+    }
+}
+
+unsigned int debug_print_log_to_buffer(char *buffer, int max_size)
+{
+    unsigned int i, size;
+    unsigned long lastts = 0;
+    int j;
+
+    if (log_size < LOG_SIZE) {
+        i = 0;
+        j = log_size;
+    } else {
+        i = log_size & (LOG_SIZE - 1);
+        j = LOG_SIZE;
+    }
+
+    size = 0;
+    int s = snprintf(buffer + size, max_size - size, "\nLog:%d %d:%d\n", log_size, i, j);
+    size += s;
+
+    for (; j > 0; j--) {
+        s = snprintf(buffer + size, max_size - size, "\033[36;1m(%ld,%ld)\033[0m:\t%s\n",
+                   systime_to_ns(timestamp[i]), systime_to_ns(timestamp[i] - lastts), log[i]);
+        size += s;
+        lastts = timestamp[i];
+        i = (i + 1) & (LOG_SIZE - 1);
+    }
+    return size;
+}
index d272ad1..1b25f75 100644 (file)
@@ -14,7 +14,9 @@
 #include <if/descq_defs.h>
 #include "../../queue_interface_internal.h"
 #include "descq_debug.h"
-
+#include <barrelfish/systime.h>
+#include <barrelfish/notificator.h>
+#include <barrelfish/waitset_chan.h>
 
 struct __attribute__((aligned(DESCQ_ALIGNMENT))) desc {
     genoffset_t offset; // 8
@@ -55,14 +57,13 @@ struct descq {
     // Flounder
     struct descq_binding* binding;
     bool local_bind;
-    bool lmp_bind;
-    bool ump_bind;
     uint64_t resend_args;
   
     // linked list
     struct descq* next;
     uint64_t qid;
     
+    struct notificator notificator;
     bool notifications;
 };
 
@@ -75,6 +76,29 @@ struct descq_endpoint_state {
     uint64_t qid;
 };
 
+// Check if there's anything to read from the queue
+static bool descq_can_read(void *arg)
+{
+    struct descq *q = arg;
+    uint64_t seq = q->rx_descs[q->rx_seq % q->slots].seq;
+
+    if (q->rx_seq > seq) { // the queue is empty
+        return false;
+    }
+    return true;
+}
+
+// Check if we can write to the queue
+static bool descq_can_write(void *arg)
+{
+    struct descq *q = arg;
+
+    if ((q->tx_seq - q->tx_seq_ack->value) >= q->slots) { // the queue is full
+        return false;
+    }
+    return true;
+}
+
 
 /**
  * @brief Enqueue a descriptor (as seperate fields)
@@ -101,12 +125,10 @@ static errval_t descq_enqueue(struct devq* queue,
 {
     struct descq* q = (struct descq*) queue;
     size_t head = q->tx_seq % q->slots;
-    if ((q->tx_seq - q->tx_seq_ack->value) > (q->slots-1)) {
+
+    if (!descq_can_write(queue)) {
         return DEVQ_ERR_QUEUE_FULL;
     }
-    
-    //assert(length > 0);
 
     q->tx_descs[head].rid = region_id;
     q->tx_descs[head].offset = offset;
@@ -124,9 +146,6 @@ static errval_t descq_enqueue(struct devq* queue,
 
     DESCQ_DEBUG("tx_seq=%lu tx_seq_ack=%lu \n",
                     q->tx_seq, q->tx_seq_ack->value);
-    // if (q->local_bind) {
-    //q->binding->tx_vtbl.notify(q->binding, NOP_CONT);
-    // }
     return SYS_ERR_OK;
 }
 
@@ -157,9 +176,8 @@ static errval_t descq_dequeue(struct devq* queue,
                               uint64_t* misc_flags)
 {
     struct descq* q = (struct descq*) queue;
-    uint64_t seq = q->rx_descs[q->rx_seq % q->slots].seq;
-    
-    if (!(q->rx_seq == seq)) {
+
+    if (!descq_can_read(queue)) {
         return DEVQ_ERR_QUEUE_EMPTY;
     }
 
@@ -171,7 +189,7 @@ static errval_t descq_dequeue(struct devq* queue,
     *valid_length = q->rx_descs[tail].valid_length;
     *misc_flags = q->rx_descs[tail].flags;
 
-    //assert(*length > 0);       
+    //assert(*length > 0);
 
     q->rx_seq++;
     q->rx_seq_ack->value = q->rx_seq;
@@ -180,32 +198,25 @@ static errval_t descq_dequeue(struct devq* queue,
     return SYS_ERR_OK;
 }
 
-static void resend_notify(void* a)
-{
-    errval_t err;
-    struct descq* queue = (struct descq*) a;
-    err = queue->binding->tx_vtbl.notify(queue->binding, NOP_CONT);
-}
-
 static errval_t descq_notify(struct devq* q)
 {
-    errval_t err;
+    // errval_t err;
     //errval_t err2;
-    struct descq* queue = (struct descq*) q;
-
-    err = queue->binding->tx_vtbl.notify(queue->binding, NOP_CONT);
-    if (err_is_fail(err)) {
-        
-        err = queue->binding->register_send(queue->binding, get_default_waitset(),
-                                            MKCONT(resend_notify, queue));
-        if (err == LIB_ERR_CHAN_ALREADY_REGISTERED) {
-            // dont care about this failure since there is an oustanding message
-            // anyway if this fails 
-            return SYS_ERR_OK;
-        } else {
-            return err;     
-        }
-    }
+    // struct descq* queue = (struct descq*) q;
+    //
+    // err = queue->binding->tx_vtbl.notify(queue->binding, NOP_CONT);
+    // if (err_is_fail(err)) {
+    //
+    //     err = queue->binding->register_send(queue->binding, get_default_waitset(),
+    //                                         MKCONT(resend_notify, queue));
+    //     if (err == LIB_ERR_CHAN_ALREADY_REGISTERED) {
+    //         // dont care about this failure since there is an oustanding message
+    //         // anyway if this fails
+    //         return SYS_ERR_OK;
+    //     } else {
+    //         return err;
+    //     }
+    // }
     return SYS_ERR_OK;
 }
 
@@ -240,7 +251,7 @@ static void try_deregister(void* a)
     errval_t err, err2;
     struct descq* queue = (struct descq*) a;
     
-    err = queue->binding->rpc_tx_vtbl.deregister_region(queue->binding, queue->resend_args, 
+    err = queue->binding->rpc_tx_vtbl.deregister_region(queue->binding, queue->resend_args,
                                                         &err2);
     assert(err_is_ok(err2) && err_is_ok(err));
 }
@@ -270,10 +281,10 @@ static errval_t descq_deregister(struct devq* q, regionid_t rid)
  * Flounder interface implementation
  */
 
-static void mp_notify(struct descq_binding* b) {
+static void mp_notify(void *arg) {
     DESCQ_DEBUG("start \n");
     errval_t err;
-    struct descq* q = (struct descq*) b->st;
+    struct descq* q = arg;
 
     DESCQ_DEBUG("%p \n",q->f.notify);
     err = q->f.notify(q);
@@ -359,8 +370,8 @@ static errval_t mp_create(struct descq_binding* b, uint32_t slots,
     q->tx_descs++;
     q->rx_descs++;
     q->slots = slots-1;
-    q->rx_seq = 0;
-    q->tx_seq = 0;
+    q->rx_seq = 1;
+    q->tx_seq = 1;
 
     devq_init(&q->q, true);
 
@@ -370,7 +381,11 @@ static errval_t mp_create(struct descq_binding* b, uint32_t slots,
     q->q.f.reg = descq_register;
     q->q.f.dereg = descq_deregister;
     q->q.f.ctrl = descq_control;
-     
+
+    notificator_init(&q->notificator, q, descq_can_read, descq_can_write);
+    *err = waitset_chan_register(get_default_waitset(), &q->notificator.ready_to_read, MKCLOSURE(mp_notify, q));
+    assert(err_is_ok(*err));
+
     *err = q->f.create(q, notifications, role, queue_id);
     if (err_is_ok(*err)) {
         goto end2;
@@ -392,10 +407,6 @@ static struct descq_rpc_rx_vtbl rpc_rx_vtbl = {
     .control_call = mp_control,
 };
 
-static struct descq_rx_vtbl rx_vtbl = {
-    .notify = mp_notify,
-};
-
 static void export_cb(void *st, errval_t err, iref_t iref)
 {
     struct descq_endpoint_state* q = (struct descq_endpoint_state*) st;
@@ -439,16 +450,8 @@ static errval_t connect_cb(void *st, struct descq_binding* b)
     }
 
     b->rpc_rx_vtbl = rpc_rx_vtbl;
-    b->rx_vtbl = rx_vtbl;
     b->st = q;
     q->local_bind = b->local_binding != NULL;
-    // if (q->local_bind) {
-        q->ump_bind = false;
-        q->lmp_bind = false;
-    // } else {
-    //     q->ump_bind = b->get_receiving_chanstate(b)->chantype == CHANTYPE_UMP_IN;
-    //     q->lmp_bind = !q->ump_bind;
-    // }
 
     return SYS_ERR_OK;
 }
@@ -457,11 +460,9 @@ static errval_t connect_cb(void *st, struct descq_binding* b)
 static void bind_cb(void *st, errval_t err, struct descq_binding* b)
 
 {
-
     struct descq* q = (struct descq*) st;
     DESCQ_DEBUG("Interface bound \n");
     q->binding = b;
-    b->rx_vtbl = rx_vtbl;
     descq_rpc_client_init(q->binding);
 
     q->bound_done = true;
@@ -575,14 +576,7 @@ errval_t descq_create(struct descq** q,
         }
 
         tmp->local_bind = tmp->binding->local_binding != NULL;
-        // if (tmp->local_bind) {
-            tmp->ump_bind = false;
-            tmp->lmp_bind = false;
-        // } else {
-        //     tmp->ump_bind = tmp->binding->get_receiving_chanstate(tmp->binding)->chantype == CHANTYPE_UMP_IN;
-        //     tmp->lmp_bind = !tmp->ump_bind;
-        // }
-        
+
         errval_t err2;
         err = tmp->binding->rpc_tx_vtbl.create_queue(tmp->binding, slots, rx, tx,
             notifications, role, &err2, queue_id);
@@ -598,9 +592,9 @@ errval_t descq_create(struct descq** q,
         tmp->tx_descs++;
         tmp->rx_descs++;
         tmp->slots = slots-1;
-        tmp->rx_seq = 0;
-        tmp->tx_seq = 0;
-        
+        tmp->rx_seq = 1;
+        tmp->tx_seq = 1;
+
         devq_init(&tmp->q, false);
 
         tmp->q.f.enq = descq_enqueue;
@@ -609,8 +603,12 @@ errval_t descq_create(struct descq** q,
         tmp->q.f.reg = descq_register;
         tmp->q.f.dereg = descq_deregister;
         tmp->q.f.ctrl = descq_control;
-        
+
         tmp->notifications = notifications;
+
+        notificator_init(&tmp->notificator, tmp, descq_can_read, descq_can_write);
+        err = waitset_chan_register(get_default_waitset(), &tmp->notificator.ready_to_read, MKCLOSURE(mp_notify, tmp));
+        assert(err_is_ok(err));
     }
 
 
index ca84572..eb2fa6f 100644 (file)
@@ -55,7 +55,7 @@ errval_t region_pool_init(struct region_pool** pool)
 
     // Initialize region id offset
     (*pool)->region_offset = (rand() >> 12) ;
-    (*pool)->size = INIT_POOL_SIZE;    
+    (*pool)->size = INIT_POOL_SIZE;
 
     (*pool)->pool = calloc(INIT_POOL_SIZE, sizeof(struct region*));
     if ((*pool)->pool == NULL) {
@@ -152,12 +152,12 @@ static errval_t region_pool_grow(struct region_pool* pool)
  *
  * @param pool          The pool to add the region to
  * @param cap           The cap of the region
- * @param region_id     Return pointer to the region id 
+ * @param region_id     Return pointer to the region id
  *                      that is assigned by the pool
  *
  * @returns error on failure or SYS_ERR_OK on success
  */
-errval_t region_pool_add_region(struct region_pool* pool, 
+errval_t region_pool_add_region(struct region_pool* pool,
                                 struct capref cap,
                                 regionid_t* region_id)
 {
@@ -173,7 +173,7 @@ errval_t region_pool_add_region(struct region_pool* pool,
     // for now just loop over all entries
     for (int i = 0; i < pool->size; i++) {
         struct region* tmp;
-        tmp = pool->pool[i]; 
+        tmp = pool->pool[i];
    
         if (tmp == NULL) {
             continue;
@@ -243,7 +243,7 @@ errval_t region_pool_add_region(struct region_pool* pool,
  *
  * @returns error on failure or SYS_ERR_OK on success
  */
-errval_t region_pool_add_region_with_id(struct region_pool* pool, 
+errval_t region_pool_add_region_with_id(struct region_pool* pool,
                                         struct capref cap,
                                         regionid_t region_id)
 {
@@ -282,7 +282,7 @@ errval_t region_pool_add_region_with_id(struct region_pool* pool,
  *
  * @returns error on failure or SYS_ERR_OK on success
  */
-errval_t region_pool_remove_region(struct region_pool* pool, 
+errval_t region_pool_remove_region(struct region_pool* pool,
                                    regionid_t region_id,
                                    struct capref* cap)
 {
@@ -366,5 +366,3 @@ bool region_pool_buffer_check_bounds(struct region_pool* pool,
 
     return true;
 }
-
-
index c946d51..177b9b7 100644 (file)
@@ -19,7 +19,7 @@
     flounderExtraDefs = [ ("net_filter",["rpcclient"]) ],
     addLibraries = libDeps [ "lwip2", "devif", "devif_backend_idc",
                              "devif_backend_solarflare", "devif_backend_e10k",
-                             "devif_backend_loopback",  "devif_backend_e1000",
+                             "devif_backend_loopback",  "devif_backend_e1000", "debug_log",
                              "octopus", "octopus_parser" ]
   },
 
     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" ]
   }
 ]
diff --git a/lib/net/net_sockets_server.c b/lib/net/net_sockets_server.c
new file mode 100644 (file)
index 0000000..686ddcb
--- /dev/null
@@ -0,0 +1,650 @@
+/**
+ * @brief
+ *  udp_echo.c
+ */
+
+/*
+ * Copyright (c) 2017, 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, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/deferred.h>
+#include <barrelfish/nameservice_client.h>
+
+#include <lwip/ip.h>
+#include <lwip/udp.h>
+#include <lwip/tcp.h>
+#include <lwip/pbuf.h>
+#include <net/net.h>
+
+#include <barrelfish/waitset_chan.h>
+
+#include <devif/queue_interface.h>
+#include <devif/backends/descq.h>
+
+#include <if/net_sockets_defs.h>
+#include <net_sockets/net_sockets_types.h>
+
+typedef uint32_t host_address_t;
+
+#define NO_OF_BUFFERS 128
+#define BUFFER_SIZE 16384
+
+struct socket_connection;
+
+struct network_connection {
+    struct network_connection *next;
+
+    struct capref buffer_cap;
+    struct descq *queue;
+    uint64_t queue_id;
+    regionid_t regionid;
+    void *buffer_start;
+    uint64_t buffer_size;
+
+    void *buffers[NO_OF_BUFFERS];
+    uint64_t next_free, next_used;
+
+    struct net_sockets_binding *binding;
+
+    struct descq *buffer_queue;
+    struct socket_connection *sockets;
+};
+
+struct socket_connection {
+    struct socket_connection *next;
+    struct network_connection *connection;
+    uint32_t descriptor;
+
+    struct udp_pcb *udp_socket;
+    struct tcp_pcb *tcp_socket;
+};
+
+static struct network_connection *network_connections = NULL;
+
+static struct socket_connection * allocate_socket(struct network_connection *nc)
+{
+    struct socket_connection *last, *socket;
+    uint32_t last_descriptor = 0;
+
+    last = NULL;
+    socket = nc->sockets;
+    while (socket) {
+        if (socket->descriptor != last_descriptor + 1)
+            break;
+        last = socket;
+        last_descriptor = last->descriptor;
+        socket = socket->next;
+    }
+
+    socket = malloc(sizeof(struct socket_connection));
+    assert(socket);
+    memset(socket, 0, sizeof(struct socket_connection));
+
+    if (last) {
+        socket->next = last->next;
+        last->next = socket;
+    } else {
+        nc->sockets = socket;
+    }
+
+    socket->descriptor = last_descriptor + 1;
+    
+    socket->connection = nc;
+    socket->udp_socket = NULL;
+    socket->tcp_socket = NULL;
+
+    return socket;
+}
+
+static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+{
+    struct socket_connection *connection = arg;
+    struct network_connection *nc = connection->connection;
+    errval_t err;
+
+    assert(p->tot_len + sizeof(struct net_buffer) <= BUFFER_SIZE);
+
+    uint32_t length = p->tot_len;
+    void *buffer = nc->buffers[nc->next_free];
+
+    if (!buffer) {
+        debug_printf("%s: drop\n", __func__);
+        pbuf_free(p);
+        return;
+    }
+
+    assert(buffer);
+    nc->buffers[nc->next_free] = NULL;
+    nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
+    assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
+    struct net_buffer *nb = buffer;
+
+    nb->size = length;
+    nb->descriptor = connection->descriptor;
+    nb->host_address = addr->addr;
+    nb->port = port;
+    // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
+
+    void *shb_data = buffer + sizeof(struct net_buffer);
+    
+    struct pbuf *it;
+    uint32_t pos;
+    
+    it = p;
+    for (pos = 0; pos < length; ) {
+        assert(it);
+        memcpy((void *)shb_data + pos, it->payload, it->len);
+        pos += it->len;
+        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,
+                       0, 0, 1);
+    assert(err_is_ok(err));
+    err = devq_notify((struct devq *)nc->queue);
+    assert(err_is_ok(err));
+
+    // debug_printf("%s: notifing\n", __func__);
+    // struct net_sockets_binding *binding = connection->connection->binding;
+    // debug_printf("%s: done\n", __func__);
+}
+
+
+static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t error)
+{
+    struct socket_connection *socket = arg;
+    struct network_connection *nc = socket->connection;
+    errval_t err;
+    uint32_t length = 0;
+    void *buffer = nc->buffers[nc->next_free];
+    struct net_buffer *nb = buffer;
+
+    if (p) {
+        debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
+        assert(p->len == p->tot_len);
+        length = p->tot_len;
+        if (!buffer) {
+            debug_printf("%s: drop\n", __func__);
+            pbuf_free(p);
+            return ERR_OK;
+        }
+        assert(buffer);
+        nb->size = length;
+        nb->descriptor = socket->descriptor;
+        nb->host_address = 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);
+
+        void *shb_data = buffer + sizeof(struct net_buffer);
+        memcpy((void *)shb_data, p->payload, length);
+        tcp_recved(pcb, p->tot_len);
+        pbuf_free(p);
+    } else {
+        assert(buffer);
+        nb->size = 0;
+        nb->descriptor = socket->descriptor;
+        nb->host_address = 0;
+        nb->port = 0;
+        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;
+    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,
+                       0, 0, 1);
+    assert(err_is_ok(err));
+    err = devq_notify((struct devq *)nc->queue);
+    assert(err_is_ok(err));
+
+    // debug_printf("%s: notifing\n", __func__);
+    // struct net_sockets_binding *binding = connection->connection->binding;
+    // debug_printf("%s: done\n", __func__);
+    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);
+
+    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);
+    assert(err_is_ok(err));
+
+    return ERR_OK;
+}
+
+
+static errval_t net_register_queue(struct net_sockets_binding *binding, uint64_t queue_id)
+{
+    struct network_connection *nc;
+
+    nc = network_connections;
+    while (nc) {
+        if (nc->queue_id == queue_id)
+            break;
+        nc = nc->next;
+    }
+    assert(nc);
+
+    binding->st = nc;
+    nc->binding = binding;
+    devq_set_state((struct devq *)nc->queue, nc);
+
+    return SYS_ERR_OK;
+}
+
+static errval_t net_udp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
+{
+    struct network_connection *nc;
+    struct socket_connection *socket;
+
+    nc = binding->st;
+    socket = allocate_socket(nc);
+    *descriptor = socket->descriptor;
+
+    struct udp_pcb *pcb = udp_new();
+    assert(pcb);
+    socket->udp_socket = pcb;
+    udp_recv(socket->udp_socket, net_udp_receive, socket);
+
+    return SYS_ERR_OK;
+}
+
+static errval_t net_tcp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
+{
+    struct network_connection *nc;
+    struct socket_connection *socket;
+
+    nc = binding->st;
+    socket = allocate_socket(nc);
+    *descriptor = socket->descriptor;
+
+    struct tcp_pcb *pcb = tcp_new();
+    assert(pcb);
+    socket->tcp_socket = pcb;
+    tcp_arg(pcb, socket);
+    tcp_recv(socket->tcp_socket, net_tcp_receive);
+
+    return SYS_ERR_OK;
+}
+
+static errval_t net_bind(struct net_sockets_binding *binding, uint32_t descriptor, host_address_t ip_address, uint16_t port, errval_t *error)
+{
+    struct network_connection *nc;
+    struct socket_connection *socket;
+
+    nc = binding->st;
+    socket = nc->sockets;
+    while (socket) {
+        if (socket->descriptor == descriptor)
+            break;
+        socket = socket->next;
+    }
+    assert(socket);
+
+    if (socket->udp_socket) {
+        ip_addr_t ip;
+
+        ip.addr = ip_address;
+        *error = udp_bind(socket->udp_socket, &ip, port);
+        assert(err_is_ok(*error));
+        *error = SYS_ERR_OK;
+
+        debug_printf("UDP ECHO bind done.\n");
+    } else if (socket->tcp_socket) {
+        ip_addr_t ip;
+
+        ip.addr = ip_address;
+        debug_printf("%s(%d): %x %d\n", __func__, socket->descriptor, ip.addr, port);
+        *error = tcp_bind(socket->tcp_socket, &ip, port);
+        assert(err_is_ok(*error));
+        *error = SYS_ERR_OK;
+
+        debug_printf("TCP ECHO bind done.\n");
+    }
+    return SYS_ERR_OK;
+}
+
+static errval_t net_listen(struct net_sockets_binding *binding, uint32_t descriptor, uint8_t backlog, errval_t *error)
+{
+    struct network_connection *nc;
+    struct socket_connection *socket;
+
+    nc = binding->st;
+    socket = nc->sockets;
+    while (socket) {
+        if (socket->descriptor == descriptor)
+            break;
+        socket = socket->next;
+    }
+    assert(socket);
+    assert(socket->tcp_socket);
+    debug_printf("%s(%d):\n", __func__, descriptor);
+    socket->tcp_socket = tcp_listen(socket->tcp_socket);
+    tcp_accept(socket->tcp_socket, net_tcp_accepted);
+    // socket->tcp_socket = tcp_listen_with_backlog(socket->tcp_socket, backlog);
+    assert(socket->tcp_socket);
+
+    *error = SYS_ERR_OK;
+    return SYS_ERR_OK;
+}
+
+static err_t net_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t error)
+{
+    struct socket_connection *socket = arg;
+    struct network_connection *nc = socket->connection;
+
+    errval_t err = nc->binding->tx_vtbl.connected(nc->binding, BLOCKING_CONT, socket->descriptor, SYS_ERR_OK);
+    assert(err_is_ok(err));
+
+    return SYS_ERR_OK;
+}
+
+static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descriptor, host_address_t ip_address, uint16_t port, errval_t *error)
+{
+    struct network_connection *nc;
+    struct socket_connection *socket;
+
+    nc = binding->st;
+    socket = nc->sockets;
+    while (socket) {
+        if (socket->descriptor == descriptor)
+            break;
+        socket = socket->next;
+    }
+    assert(socket);
+
+    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;
+    }
+
+    return SYS_ERR_OK;
+}
+
+static errval_t net_delete_socket(struct net_sockets_binding *binding, uint32_t descriptor, errval_t *error)
+{
+    struct network_connection *nc;
+    struct socket_connection *socket, *last;
+
+    nc = binding->st;
+    socket = nc->sockets;
+    last = NULL;
+    while (socket) {
+        if (socket->descriptor == descriptor)
+            break;
+        last = socket;
+        socket = socket->next;
+    }
+    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);
+        // tcp_accept(socket->tcp_socket, NULL);
+        tcp_close(socket->tcp_socket);
+    }
+
+    debug_printf("%s(%d):\n", __func__, descriptor);
+    if (last)
+        last->next = socket->next;
+    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,
+                       uint64_t* queue_id)
+{
+    struct network_connection *nc;
+    static uint64_t qid = 1;
+
+    nc = malloc(sizeof(struct network_connection));
+    assert(nc);
+    nc->next = network_connections;
+    network_connections = nc;
+
+    nc->sockets = NULL;
+    nc->binding = NULL;
+    nc->queue = q;
+    *queue_id = qid++;
+    nc->queue_id = *queue_id;
+    memset(nc->buffers, 0, sizeof(nc->buffers));
+    nc->next_free = 0;
+    nc->next_used = 0;
+    return SYS_ERR_OK;
+}
+
+static errval_t q_destroy(struct descq* q)
+{
+    return SYS_ERR_OK;
+}
+
+
+static errval_t q_notify(struct descq* q)
+{
+    struct devq* queue = (struct devq *)q;
+    errval_t err = SYS_ERR_OK;
+    //errval_t err2 = SYS_ERR_OK;
+    regionid_t rid;
+    genoffset_t offset;
+    genoffset_t length;
+    genoffset_t valid_data;
+    genoffset_t valid_length;
+    uint64_t flags;
+    struct network_connection *nc;
+    bool notify = 0;
+
+    // debug_printf("%s: \n", __func__);
+    nc = devq_get_state(queue);
+    for (;;) {
+        err = devq_dequeue(queue, &rid, &offset, &length,
+                           &valid_data, &valid_length, &flags);
+        if (err_is_fail(err)) {
+            break;
+        } else {
+            // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
+            if (flags == 1) { // receiving buffer
+                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
+                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;
+                }
+                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);
+                if (socket->udp_socket) {
+                    struct udp_pcb *pcb = socket->udp_socket;
+                    struct pbuf *p;
+
+                    p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
+                    assert(p);
+                    memcpy(p->payload, shb_data, nb->size);
+
+                    ip_addr_t addr;
+                    uint16_t port;
+                    port = nb->port;
+                    addr.addr = nb->host_address;
+                    // debug_printf("%s: enqueue 2 %lx:%d\n", __func__, offset, BUFFER_SIZE);
+                    err = devq_enqueue(queue, rid, offset, BUFFER_SIZE, 0, 0, 2);
+                    assert(err_is_ok(err));
+                    notify = 1;
+                    // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
+                    if (port && addr.addr) {
+                        assert(udp_sendto(pcb, p, &addr, port) == ERR_OK);
+                    } else {
+                        assert(udp_send(pcb, p) == ERR_OK);
+                    }
+                    pbuf_free(p);
+                } else if (socket->tcp_socket) {
+                    err_t e;
+                    
+                    e = tcp_write(socket->tcp_socket, shb_data, nb->size, TCP_WRITE_FLAG_COPY);
+                    assert(e == ERR_OK);
+                    e = tcp_output(socket->tcp_socket);
+                    assert(e == ERR_OK);
+                }
+            }
+        }
+    }
+
+    if (notify) {
+        // debug_printf("notify>\n");
+        err = devq_notify(queue);
+        // debug_printf("notify<\n");
+        assert(err_is_ok(err));
+    }
+
+    return SYS_ERR_OK;
+}
+
+static errval_t q_reg(struct descq* q, struct capref cap,
+                    regionid_t rid)
+{
+    struct frame_identity pa;
+    struct network_connection *nc;
+
+    nc = devq_get_state((struct devq *)q);
+
+    errval_t err = frame_identify(cap, &pa);
+    assert(err_is_ok(err));
+    nc->buffer_cap = cap;
+    nc->regionid = rid;
+
+    nc->buffer_size = pa.bytes;
+    err = vspace_map_one_frame(&nc->buffer_start, pa.bytes, cap, NULL, NULL);
+    assert(err_is_ok(err));
+
+    return SYS_ERR_OK;
+}
+
+
+static errval_t q_dereg(struct descq* q, regionid_t rid)
+{
+    return SYS_ERR_OK;
+}
+    
+
+static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
+{
+    return SYS_ERR_OK;
+}
+
+
+static struct net_sockets_rpc_rx_vtbl rpc_rx_vtbl = {
+    .register_queue_call = net_register_queue,
+    .new_udp_socket_call = net_udp_socket,
+    .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,
+};
+
+
+static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
+{
+    binding->rpc_rx_vtbl = rpc_rx_vtbl;
+    return SYS_ERR_OK;
+}
+
+
+static void export_cb(void *st, errval_t err, iref_t iref)
+{
+    assert(err_is_ok(err));
+    err = nameservice_register("net_sockets", iref);
+    assert(err_is_ok(err));
+}
+
+int main(int argc, char *argv[])
+{
+    errval_t err;
+
+    debug_printf("UDP ECHO started.\n");
+
+    char servicename[64];
+    snprintf(servicename, sizeof(servicename), "e1000:%s", argv[2]);
+
+    /* connect to the network */
+    err = networking_init(servicename, 0);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Failed to initialize the network");
+    }
+
+
+    struct descq *exp_queue;
+    struct descq_func_pointer f;
+
+    f.notify = q_notify;
+    f.create = q_create;
+    f.destroy = q_destroy;
+    f.reg = q_reg;
+    f.dereg = q_dereg;
+    f.control = q_control;
+
+    err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, "net_sockets_queue",
+                       true, true, 0, NULL, &f);
+    assert(err_is_ok(err));
+
+
+    err = net_sockets_export(NULL, export_cb, connect_cb, get_default_waitset(),
+                            IDC_EXPORT_FLAGS_DEFAULT);
+    assert(err_is_ok(err));
+
+    while(1) {
+        event_dispatch(get_default_waitset());
+
+        // networking_poll();
+    }
+
+    debug_printf("UDP ECHO termiated.\n");
+
+    return 0;
+}
diff --git a/lib/net_sockets/Hakefile b/lib/net_sockets/Hakefile
new file mode 100644 (file)
index 0000000..0501ae6
--- /dev/null
@@ -0,0 +1,20 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2017, 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_sockets
+--
+--------------------------------------------------------------------------
+
+[ build library { target = "net_sockets",
+                  cFiles = [ "net_sockets.c" ],
+                  flounderDefs = [ "net_sockets" ],
+                  flounderBindings = [ "net_sockets" ],
+                  addIncludes  = [ "include", "/lib/lwip-2.0.2/src/include/" ],
+                  addLibraries = libDeps [ "lwip2", "devif", "devif_backend_idc" ]
+                }
+]
diff --git a/lib/net_sockets/net_sockets.c b/lib/net_sockets/net_sockets.c
new file mode 100644 (file)
index 0000000..cb66819
--- /dev/null
@@ -0,0 +1,410 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/nameservice_client.h>
+#include <if/net_sockets_defs.h>
+#include <net_sockets/net_sockets.h>
+
+#include <barrelfish/waitset_chan.h>
+#include <barrelfish/waitset.h>
+
+#include <devif/queue_interface.h>
+#include <devif/backends/descq.h>
+
+
+static struct net_sockets_binding *binding;
+static bool bound_done = false;
+
+static struct capref buffer_frame;
+struct descq* descq_queue;
+static void *buffer_start;
+static regionid_t regionid;
+static uint64_t queue_id;
+
+#define NO_OF_BUFFERS 128
+#define BUFFER_SIZE 16384
+
+void *buffers[NO_OF_BUFFERS];
+uint64_t next_free, next_used;
+struct net_socket *sockets = NULL;
+
+/// Dequeue the element from the net_socket queue
+static void dequeue(struct net_socket **queue,
+                            struct net_socket *element)
+{
+    if (element->next == element) {
+        assert(element->prev == element);
+        assert(*queue == element);
+        *queue = NULL;
+    } else {
+        element->prev->next = element->next;
+        element->next->prev = element->prev;
+        if (*queue == element) {
+            *queue = element->next;
+        }
+    }
+    element->prev = element->next = NULL;
+}
+
+/// Enqueue the element on the net_socket queue
+static void enqueue(struct net_socket **queue,
+                            struct net_socket *element)
+{
+    if (*queue == NULL) {
+        *queue = element;
+        element->next = element->prev = element;
+    } else {
+        element->next = *queue;
+        element->prev = (*queue)->prev;
+        element->next->prev = element;
+        element->prev->next = element;
+    }
+}
+
+struct net_socket * net_udp_socket(void)
+{
+    errval_t err;
+    struct net_socket *socket;
+    uint32_t descriptor;
+
+    err = binding->rpc_tx_vtbl.new_udp_socket(binding, &descriptor);
+    assert(err_is_ok(err));
+
+    socket = malloc(sizeof(struct net_socket));
+    assert(socket);
+
+    socket->descriptor = descriptor;
+    socket->received = NULL;
+    socket->connected = NULL;
+    socket->accepted = NULL;
+    socket->user_state = NULL;
+    enqueue(&sockets, socket);
+    return socket;
+}
+
+struct net_socket * net_tcp_socket(void)
+{
+    errval_t err;
+    struct net_socket *socket;
+    uint32_t descriptor;
+
+    err = binding->rpc_tx_vtbl.new_tcp_socket(binding, &descriptor);
+    assert(err_is_ok(err));
+
+    socket = malloc(sizeof(struct net_socket));
+    assert(socket);
+
+    socket->descriptor = descriptor;
+    socket->received = NULL;
+    socket->sent = NULL;
+    socket->connected = NULL;
+    socket->accepted = NULL;
+    socket->user_state = NULL;
+    enqueue(&sockets, socket);
+    return socket;
+}
+
+static struct net_socket * get_socket(uint32_t descriptor)
+{
+    struct net_socket *socket = sockets;
+    
+    while (socket) {
+        if (socket->descriptor == descriptor)
+            return socket;
+        socket = socket->next;
+        if (socket == sockets)
+            break;
+    }
+    assert(0);
+    return NULL;
+}
+
+void net_set_user_state(struct net_socket *socket, void *user_state)
+{
+    socket->user_state = user_state;
+}
+
+void net_close(struct net_socket *socket)
+{
+    errval_t err, error;
+
+    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);
+}
+
+errval_t net_bind(struct net_socket *socket, host_address_t ip_address, uint16_t port)
+{
+    errval_t err, error;
+
+    err = binding->rpc_tx_vtbl.bind(binding, socket->descriptor, ip_address, port, &error);
+    assert(err_is_ok(err));
+
+    return error;
+}
+
+errval_t net_listen(struct net_socket *socket, uint8_t backlog)
+{
+    errval_t err, error;
+
+    err = binding->rpc_tx_vtbl.listen(binding, socket->descriptor, backlog, &error);
+    assert(err_is_ok(err));
+
+    return error;
+}
+
+void * net_alloc(size_t size)
+{
+    void *buffer = buffers[next_free];
+    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]);
+    return buffer + sizeof(struct net_buffer);
+}
+
+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]);
+}
+
+errval_t net_send(struct net_socket *socket, void *data, size_t size)
+{
+    errval_t err, error;
+
+    void *buffer = data - sizeof(struct net_buffer);
+    struct net_buffer *nb = buffer;
+    // debug_printf("%s(%d): %ld -> %p\n", __func__, descriptor, size, buffer);
+
+    nb->size = size;
+    nb->descriptor = socket->descriptor;
+    nb->host_address = 0;
+    nb->port = 0;
+    // 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);
+    assert(err_is_ok(err));
+    err = devq_notify((struct devq *)descq_queue);
+    assert(err_is_ok(err));
+
+    error = SYS_ERR_OK;
+    return error;
+}
+
+errval_t net_send_to(struct net_socket *socket, void *data, size_t size, host_address_t ip_address, uint16_t port)
+{
+    errval_t err, error;
+
+    void *buffer = data - sizeof(struct net_buffer);
+    struct net_buffer *nb = buffer;
+    // debug_printf("%s(%d): %ld -> %p\n", __func__, descriptor, size, buffer);
+
+    nb->size = size;
+    nb->descriptor = socket->descriptor;
+    nb->host_address = ip_address;
+    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);
+    assert(err_is_ok(err));
+    err = devq_notify((struct devq *)descq_queue);
+    assert(err_is_ok(err));
+
+    error = SYS_ERR_OK;
+    return error;
+}
+
+errval_t net_connect(struct net_socket *socket, host_address_t ip_address, uint16_t port, net_connected_callback_t cb)
+{
+    errval_t err, error;
+
+    socket->connected = cb;
+    err = binding->rpc_tx_vtbl.connect(binding, socket->descriptor, ip_address, port, &error);
+    assert(err_is_ok(err));
+    assert(err_is_ok(error));
+
+    return error;
+}
+
+static void net_connected(struct net_sockets_binding *b, uint32_t descriptor, errval_t error)
+{
+    struct net_socket *socket = get_socket(descriptor);
+    assert(socket->descriptor == descriptor);
+    assert(err_is_ok(error));
+
+    assert(socket->connected);
+    socket->connected(socket->user_state, socket);
+}
+
+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)
+{
+    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);
+
+    accepted_socket->descriptor = accepted_descriptor;
+    accepted_socket->received = NULL;
+    accepted_socket->sent = NULL;
+    accepted_socket->connected = NULL;
+    accepted_socket->accepted = NULL;
+    accepted_socket->user_state = NULL;
+    enqueue(&sockets, accepted_socket);
+
+    assert(socket->accepted);
+    socket->accepted(socket->user_state, accepted_socket, host_address, port);
+}
+
+
+void net_recv(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)
+{
+    socket->sent = cb;
+}
+
+static void bind_cb(void *st, errval_t err, struct net_sockets_binding *b)
+{
+    binding = b;
+    net_sockets_rpc_client_init(binding);
+    bound_done = true;
+}
+
+static void alloc_mem(struct capref *frame, void** virt, size_t size)
+{
+    errval_t r;
+    vregion_flags_t flags;
+
+    r = frame_alloc(frame, size, NULL);
+    assert(err_is_ok(r));
+
+    flags = VREGION_FLAGS_READ_WRITE;
+    r = vspace_map_one_frame_attr(virt, size, *frame, flags, NULL, NULL);
+    assert(err_is_ok(r));
+    memset(*virt, 0, size);
+}
+
+static errval_t q_notify(struct descq* q)
+{
+    assert(descq_queue == q);
+    errval_t err = SYS_ERR_OK;
+    //errval_t err2 = SYS_ERR_OK;
+    regionid_t rid;
+    genoffset_t offset;
+    genoffset_t length;
+    genoffset_t valid_data;
+    genoffset_t valid_length;
+    uint64_t flags;
+    bool notify = 0;
+
+    // debug_printf("%s: \n", __func__);
+    for (;;) {
+        err = devq_dequeue((struct devq *)descq_queue, &rid, &offset, &length,
+                           &valid_data, &valid_length, &flags);
+        if (err_is_fail(err)) {
+            break;
+        } else {
+            void *buffer = buffer_start + offset;
+            struct net_buffer *nb = buffer;
+            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;
+            } else if (flags == 2) { // transmitting buffer
+                if (socket->sent)
+                    socket->sent(socket->user_state, socket, shb_data);
+    // 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;
+            }
+        }
+    }
+
+    if (notify) {
+        // debug_printf("notify>\n");
+        err = devq_notify((struct devq *)descq_queue);
+        assert(err_is_ok(err));
+        // debug_printf("notify<\n");
+    }
+
+    return SYS_ERR_OK;
+}
+
+errval_t net_sockets_init(void)
+{
+    errval_t err;
+    iref_t iref;
+
+    memset(buffers, 0, sizeof(buffers));
+    next_free = 0;
+    next_used = 0;
+
+    alloc_mem(&buffer_frame, &buffer_start, 2 * BUFFER_SIZE * NO_OF_BUFFERS);
+    struct descq_func_pointer f;
+    f.notify = q_notify;
+
+    debug_printf("Descriptor queue test started \n");
+    err = descq_create(&descq_queue, DESCQ_DEFAULT_SIZE, "net_sockets_queue",
+                       false, true, true, &queue_id, &f);
+    assert(err_is_ok(err));
+
+    err = nameservice_blocking_lookup("net_sockets", &iref);
+    assert(err_is_ok(err));
+    err = net_sockets_bind(iref, bind_cb, NULL, get_default_waitset(), IDC_BIND_FLAGS_DEFAULT);
+    assert(err_is_ok(err));
+
+    while (!bound_done) {
+        event_dispatch(get_default_waitset());
+    }
+    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));
+
+    err = devq_register((struct devq *)descq_queue, buffer_frame, &regionid);
+    assert(err_is_ok(err));
+
+    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);
+        if (!err_is_ok(err))
+            debug_printf("%s: %d:%d\n", __func__, i, NO_OF_BUFFERS);
+        assert(err_is_ok(err));
+        buffers[i] = i * BUFFER_SIZE + buffer_start + BUFFER_SIZE * NO_OF_BUFFERS;
+    }
+
+    err = devq_notify((struct devq *)descq_queue);
+    assert(err_is_ok(err));
+
+    return SYS_ERR_OK;
+}
index 14aa8c0..c3e497d 100644 (file)
@@ -1,4 +1,4 @@
---------------------------------------------------------------------------
+    --------------------------------------------------------------------------
 -- Copyright (c) 2007-2009, ETH Zurich.
 -- All rights reserved.
 --
@@ -13,6 +13,6 @@
 [ build library { target = "nfs",
                   cFiles = [ "rpc.c", "xdr.c", "mount_xdr.c", "nfs_xdr.c",
                              "portmap_xdr.c", "xdr_pbuf.c", "nfs.c" ],
-                  addLibraries = [ "lwip" ]
+                  addLibraries = [ "net_sockets" ]
                 }
 ]
index a0eb869..bbbe26e 100644 (file)
@@ -20,7 +20,7 @@
 #include "portmap_rpc.h"
 
 
-static err_t portmap_lookup(struct nfs_client *client, u_int prog, u_int vers);
+static errval_t portmap_lookup(struct nfs_client *client, u_int prog, u_int vers);
 
 /// What state are we at in initialising this mount?
 enum nfs_mount_state {
@@ -51,7 +51,7 @@ static void mount_reply_handler(struct rpc_client *rpc_client, void *arg1,
     uint32_t port;
     mountstat3 mountstat;
     struct nfs_fh3 fh = { .data_len = 0, .data_val = NULL };
-    err_t r;
+    errval_t r;
     bool rb;
 
     if (replystat != RPC_MSG_ACCEPTED || acceptstat != RPC_SUCCESS) {
@@ -72,8 +72,8 @@ static void mount_reply_handler(struct rpc_client *rpc_client, void *arg1,
 
         // lookup NFS port
         r = portmap_lookup(client, NFS_PROGRAM, NFS_V3);
-        assert(r == ERR_OK);
-        if (r != ERR_OK) {
+        assert(r == SYS_ERR_OK);
+        if (r != SYS_ERR_OK) {
             goto error;
         }
         client->mount_state = NFS_INIT_GETPORT_NFS;
@@ -90,8 +90,8 @@ static void mount_reply_handler(struct rpc_client *rpc_client, void *arg1,
                     (void *)&client->mount_path,
                     RNDUP(strlen(client->mount_path)) + BYTES_PER_XDR_UNIT,
                     mount_reply_handler, NULL, NULL);
-        assert(r == ERR_OK);
-        if (r != ERR_OK) {
+        assert(r == SYS_ERR_OK);
+        if (r != SYS_ERR_OK) {
             goto error;
         }
         client->mount_state = NFS_INIT_MOUNT;
@@ -131,7 +131,7 @@ error:
 
 
 /// Initiates a portmap GETPORT call, calling mount_reply_handler with the reply
-static err_t portmap_lookup(struct nfs_client *client, u_int prog, u_int vers)
+static errval_t portmap_lookup(struct nfs_client *client, u_int prog, u_int vers)
 {
     struct mapping mount_map = {
         .prog = prog,
@@ -141,7 +141,7 @@ static err_t portmap_lookup(struct nfs_client *client, u_int prog, u_int vers)
     };
 
     NFSDEBUGPRINT("portmap_lookup: portmap_lookup calling rpc_call\n");
-    err_t err = rpc_call(&client->rpc_client, PMAP_PORT, PMAP_PROG, PMAP_VERS,
+    errval_t err = rpc_call(&client->rpc_client, PMAP_PORT, PMAP_PROG, PMAP_VERS,
                     PMAPPROC_GETPORT, (xdrproc_t) xdr_mapping, &mount_map,
                     sizeof(mount_map), mount_reply_handler, NULL, NULL);
     NFSDEBUGPRINT("portmap_lookup: portmap_lookup done with rpc_call returned %d \n",
@@ -160,7 +160,7 @@ static err_t portmap_lookup(struct nfs_client *client, u_int prog, u_int vers)
  *   call succeeds, the returned client instance must be freed by a later call
  *   to nfs_destroy().
  */
-struct nfs_client *nfs_mount(struct ip_addr server, const char *path,
+struct nfs_client *nfs_mount(host_address_t server, const char *path,
                              nfs_mount_callback_t callback, void *cbarg)
 {
     struct nfs_client *client;
@@ -170,8 +170,8 @@ struct nfs_client *nfs_mount(struct ip_addr server, const char *path,
         return NULL;
     }
     NFSDEBUGPRINT("nfs_mount: calling rpc_init\n");
-    err_t r = rpc_init(&client->rpc_client, server);
-    if (r != ERR_OK) {
+    errval_t r = rpc_init(&client->rpc_client, server);
+    if (r != SYS_ERR_OK) {
         free(client);
         return NULL;
     }
@@ -185,7 +185,7 @@ struct nfs_client *nfs_mount(struct ip_addr server, const char *path,
     NFSDEBUGPRINT("nfs_mount: calling portmap_lookup\n");
     r = portmap_lookup(client, MOUNT_PROGRAM, MOUNT_V3);
     NFSDEBUGPRINT("nfs_mount: portmap_lookup done \n");
-    if (r != ERR_OK) {
+    if (r != SYS_ERR_OK) {
         nfs_destroy(client);
         return NULL;
     }
@@ -240,9 +240,9 @@ static void getattr_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_getattr(struct nfs_client *client, struct nfs_fh3 fh,
+errval_t nfs_getattr(struct nfs_client *client, struct nfs_fh3 fh,
                   nfs_getattr_callback_t callback, void *cbarg)
 {
     assert(client->mount_state == NFS_INIT_COMPLETE);
@@ -295,9 +295,9 @@ static void setattr_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_setattr(struct nfs_client *client, struct nfs_fh3 fh,
+errval_t nfs_setattr(struct nfs_client *client, struct nfs_fh3 fh,
                   sattr3 new_attributes, bool guarded,
                   nfs_setattr_callback_t callback, void *cbarg)
 {
@@ -356,9 +356,9 @@ static void readdir_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_readdir(struct nfs_client *client, struct nfs_fh3 fh,
+errval_t nfs_readdir(struct nfs_client *client, struct nfs_fh3 fh,
                   cookie3 cookie, cookieverf3 cookieverf,
                   nfs_readdir_callback_t callback, void *cbarg)
 {
@@ -417,9 +417,9 @@ static void readdirplus_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_readdirplus(struct nfs_client *client, struct nfs_fh3 fh,
+errval_t nfs_readdirplus(struct nfs_client *client, struct nfs_fh3 fh,
                       cookie3 cookie, cookieverf3 cookieverf,
                       nfs_readdirplus_callback_t callback, void *cbarg)
 {
@@ -480,9 +480,9 @@ static void lookup_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_lookup(struct nfs_client *client, struct nfs_fh3 dirfh,
+errval_t nfs_lookup(struct nfs_client *client, struct nfs_fh3 dirfh,
                  const char *name, nfs_lookup_callback_t callback, void *cbarg)
 {
     assert(client->mount_state == NFS_INIT_COMPLETE);
@@ -537,9 +537,9 @@ static void access_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_access(struct nfs_client *client, struct nfs_fh3 fh, uint32_t access,
+errval_t nfs_access(struct nfs_client *client, struct nfs_fh3 fh, uint32_t access,
                  nfs_access_callback_t callback, void *cbarg)
 {
     assert(client->mount_state == NFS_INIT_COMPLETE);
@@ -592,9 +592,9 @@ static void read_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_read(struct nfs_client *client, struct nfs_fh3 fh, offset3 offset,
+errval_t nfs_read(struct nfs_client *client, struct nfs_fh3 fh, offset3 offset,
                count3 count, nfs_read_callback_t callback, void *cbarg)
 {
     NFSDEBUGPRINT("nfs read called on offset %"PRIu32" and size %d\n",
@@ -607,7 +607,7 @@ err_t nfs_read(struct nfs_client *client, struct nfs_fh3 fh, offset3 offset,
         .count = count
     };
 
-    err_t errval = rpc_call(&client->rpc_client, client->nfs_port, NFS_PROGRAM,
+    errval_t errval = rpc_call(&client->rpc_client, client->nfs_port, NFS_PROGRAM,
                     NFS_V3, NFSPROC3_READ, (xdrproc_t) xdr_READ3args,
                     &args, sizeof(args) + RNDUP(fh.data_len),
                     read_reply_handler, callback, cbarg);
@@ -654,9 +654,9 @@ static void write_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_write(struct nfs_client *client, struct nfs_fh3 fh, offset3 offset,
+errval_t nfs_write(struct nfs_client *client, struct nfs_fh3 fh, offset3 offset,
                 const void *data, count3 count, stable_how stable,
                 nfs_write_callback_t callback, void *cbarg)
 {
@@ -719,9 +719,9 @@ static void create_reply_handler(struct rpc_client *rpc_client, void *arg1,
  *
  * \todo Exclusive create will be implemented by a different call.
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_create(struct nfs_client *client, struct nfs_fh3 dir,
+errval_t nfs_create(struct nfs_client *client, struct nfs_fh3 dir,
                  const char *name, bool guarded, sattr3 attributes,
                  nfs_create_callback_t callback, void *cbarg)
 {
@@ -781,9 +781,9 @@ static void mkdir_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_mkdir(struct nfs_client *client, struct nfs_fh3 dir, const char *name,
+errval_t nfs_mkdir(struct nfs_client *client, struct nfs_fh3 dir, const char *name,
                 sattr3 attributes, nfs_mkdir_callback_t callback, void *cbarg)
 {
     assert(client->mount_state == NFS_INIT_COMPLETE);
@@ -838,9 +838,9 @@ static void remove_reply_handler(struct rpc_client *rpc_client, void *arg1,
  * \param callback Callback function to call when operation returns
  * \param cbarg Opaque argument word passed to callback function
  *
- * \returns ERR_OK on success, error code on failure
+ * \returns SYS_ERR_OK on success, error code on failure
  */
-err_t nfs_remove(struct nfs_client *client, struct nfs_fh3 dir,
+errval_t nfs_remove(struct nfs_client *client, struct nfs_fh3 dir,
                  const char *name, nfs_remove_callback_t callback,
                  void *cbarg)
 {
index 8bf24fb..07929a5 100644 (file)
  */
 
 #include <nfs/xdr.h>
-#include <lwip/pbuf.h>
-#include <lwip/udp.h>
 #include <assert.h>
-#include <lwip/init.h>
+#include <net_sockets/net_sockets.h>
 
 #include <barrelfish/barrelfish.h>
 #include <bench/bench.h>
@@ -63,10 +61,6 @@ enum rpc_msg_type {
 /// bytes needed for full RPC call header
 #define RPC_CALL_HEADER_LEN (10 * BYTES_PER_XDR_UNIT + AUTH_SIZE)
 
-// XXX: lwip synchronisation kludges
-extern struct thread_mutex *lwip_mutex;
-extern struct waitset *lwip_waitset;
-
 static uint8_t net_debug_state = 0;
 
 static int hash_function(uint32_t xid)
@@ -78,14 +72,15 @@ static int hash_function(uint32_t xid)
 struct rpc_call {
     uint32_t xid;               ///< Transaction ID (XID)
     uint16_t timers, retries;   ///< Number of timer expiries and retries
-    struct pbuf *pbuf;          ///< LWIP pbuf pointer for packet data
+    uint8_t *data;              ///< Pointer for packet data
+    size_t size;
     rpc_callback_t callback;    ///< Callback function pointer
     void *cbarg1, *cbarg2;      ///< Callback function opaque arguments
     struct rpc_call *next;      ///< Next call in queue
 };
 
 /// Utility function to prepare an outgoing packet buffer with the RPC call header
-static err_t rpc_call_init(XDR *xdr, uint32_t xid, uint32_t prog, uint32_t vers,
+static errval_t rpc_call_init(XDR *xdr, uint32_t xid, uint32_t prog, uint32_t vers,
                            uint32_t proc)
 {
     int32_t *buf;
@@ -93,7 +88,7 @@ static err_t rpc_call_init(XDR *xdr, uint32_t xid, uint32_t prog, uint32_t vers,
 
     /* reserve space for the first part of the header */
     if ((buf = XDR_INLINE(xdr, 9 * BYTES_PER_XDR_UNIT)) == NULL) {
-        return ERR_BUF;
+        return LWIP_ERR_BUF;
     }
 
     // XID comes first
@@ -119,12 +114,12 @@ static err_t rpc_call_init(XDR *xdr, uint32_t xid, uint32_t prog, uint32_t vers,
     char *machname = AUTH_MACHINE_NAME;
     rb = xdr_string(xdr, &machname, AUTH_MACHINE_NAME_LEN);
     if (!rb) {
-        return ERR_BUF;
+        return LWIP_ERR_BUF;
     }
 
     /* reserve some more space for the rest, which is done inline again */
     if ((buf = XDR_INLINE(xdr, 5 * BYTES_PER_XDR_UNIT)) == NULL) {
-        return ERR_BUF;
+        return LWIP_ERR_BUF;
     }
 
     // Rest of the CRED
@@ -136,16 +131,16 @@ static err_t rpc_call_init(XDR *xdr, uint32_t xid, uint32_t prog, uint32_t vers,
     IXDR_PUT_UINT32(buf, RPC_AUTH_NULL);
     IXDR_PUT_UINT32(buf, 0);
 
-    return ERR_OK;
+    return SYS_ERR_OK;
 }
 
 /// Utility function to skip over variable-sized authentication data in a reply
-static err_t xdr_skip_auth(XDR *xdr)
+static errval_t xdr_skip_auth(XDR *xdr)
 {
     int32_t *buf;
 
     if ((buf = XDR_INLINE(xdr, 2 * BYTES_PER_XDR_UNIT)) == NULL) {
-        return ERR_BUF;
+        return LWIP_ERR_BUF;
     }
 
     (void) IXDR_GET_UINT32(buf); // skip auth flavour
@@ -156,29 +151,28 @@ static err_t xdr_skip_auth(XDR *xdr)
     if (auth_size > 0) {
         buf = XDR_INLINE(xdr, auth_size);
         if (buf == NULL) {
-            return ERR_BUF;
+            return LWIP_ERR_BUF;
         }
     }
 
-    return ERR_OK;
+    return SYS_ERR_OK;
 }
 
 /// Generic handler for all incoming RPC messages. Finds the appropriate call
 /// instance, checks arguments, and notifies the callback.
-static void rpc_recv_handler(void *arg, struct udp_pcb *pcb, struct pbuf *pbuf,
-                             struct ip_addr *addr, u16_t port)
+static void rpc_recv_handler(void *user_state, struct net_socket *socket,
+    void *data, size_t size, host_address_t ip_address, uint16_t port)
 {
 
 //    uint64_t ts = rdtsc();
     uint32_t replystat, acceptstat;
     XDR xdr;
-    err_t r;
+    errval_t r;
     bool rb;
-
-    struct rpc_client *client = arg;
+    struct rpc_client *client = user_state;
     struct rpc_call *call = NULL;
 
-    xdr_pbuf_create_recv(&xdr, pbuf);
+    xdr_create_recv(&xdr, data, size);
 
     int32_t *buf;
     if ((buf = XDR_INLINE(&xdr, 3 * BYTES_PER_XDR_UNIT)) == NULL) {
@@ -219,7 +213,7 @@ static void rpc_recv_handler(void *arg, struct udp_pcb *pcb, struct pbuf *pbuf,
     replystat = IXDR_GET_UINT32(buf);
     if (replystat == RPC_MSG_ACCEPTED) {
         r = xdr_skip_auth(&xdr);
-        if (r != ERR_OK) {
+        if (r != SYS_ERR_OK) {
             fprintf(stderr, "RPC: Error in incoming auth data, dropped\n");
             goto out;
         }
@@ -233,22 +227,16 @@ static void rpc_recv_handler(void *arg, struct udp_pcb *pcb, struct pbuf *pbuf,
         acceptstat = -1;
     }
 
-//    lwip_record_event_simple(RPC_RECV_T, ts);
-//    ts = rdtsc();
     call->callback(client, call->cbarg1, call->cbarg2, replystat, acceptstat,
                    &xdr);
-//    lwip_record_event_simple(RPC_CALLBACK_T, ts);
 
 out:
-//    ts = rdtsc();
-    pbuf_free(pbuf); // freeing the pbuf from RX packet
     if (call != NULL) {
         // We got reply, so there is not need for keeping TX packet saved
         // here for retransmission.  Lets free it up.
-        pbuf_free(call->pbuf);
+        XDR_DESTROY(&xdr);
         free(call);
     }
-//    lwip_record_event_simple(RPC_RECV_OUT_T, ts);
 }
 
 static void traverse_hash_bucket(int hid, struct rpc_client *client)
@@ -264,7 +252,7 @@ static void traverse_hash_bucket(int hid, struct rpc_client *client)
                 printf("##### [%d][%"PRIuDOMAINID"] "
                        "RPC: timeout for XID 0x%"PRIu32"\n",
                        disp_get_core_id(), disp_get_domain_id(), call->xid);
-                pbuf_free(call->pbuf);
+                free(call->data);
                 if (prev == NULL) {
                     client->call_hash[hid] = call->next;
                 } else {
@@ -293,12 +281,12 @@ static void traverse_hash_bucket(int hid, struct rpc_client *client)
                        disp_get_core_id(), disp_get_domain_id(), call->xid);
 
                 // throw away (hide) UDP/IP/ARP headers from previous transmission
-                err_t e = pbuf_header(call->pbuf,
-                                      -UDP_HLEN - IP_HLEN - PBUF_LINK_HLEN);
-                assert(e == ERR_OK);
+                // err_t e = pbuf_header(call->pbuf,
+                //                       -UDP_HLEN - IP_HLEN - PBUF_LINK_HLEN);
+                // assert(e == SYS_ERR_OK);
 
-                e = udp_send(client->pcb, call->pbuf);
-                if (e != ERR_OK) {
+                errval_t e = net_send(client->socket, call->data, call->size);
+                if (e != SYS_ERR_OK) {
                     /* XXX: assume that this is a transient condition, retry */
                     fprintf(stderr, "RPC: retransmit failed! will retry...\n");
                     call->timers--;
@@ -318,17 +306,11 @@ static void rpc_timer(void *arg)
 {
     struct rpc_client *client = arg;
     RPC_DEBUGP("rpc_timer fired\n");
-    if (lwip_mutex != NULL) {
-        thread_mutex_lock(lwip_mutex);
-    }
     for (int i = 0; i < RPC_HTABLE_SIZE; ++i) {
        if (client->call_hash[i] != NULL) {
             traverse_hash_bucket(i, client);
        }
     }
-    if (lwip_mutex != NULL) {
-        thread_mutex_unlock(lwip_mutex);
-    }
 }
 
 
@@ -338,19 +320,22 @@ static void rpc_timer(void *arg)
  * \param client Pointer to memory for RPC client data, to be initialised
  * \param server IP address of server to be called
  *
- * \returns Error code (ERR_OK on success)
+ * \returns Error code (SYS_ERR_OK on success)
  */
-err_t rpc_init(struct rpc_client *client, struct ip_addr server)
+errval_t rpc_init(struct rpc_client *client, host_address_t server)
 {
     errval_t err;
-    client->pcb = udp_new();
-    if (client->pcb == NULL) {
-        return ERR_MEM;
-    }
+    
+    client->socket = net_udp_socket();
+    assert(client->socket);
+    net_set_user_state(client->socket, client);
+    net_recv(client->socket, rpc_recv_handler);
 
     net_debug_state = 0;
 
     client->server = server;
+    client->connected_address = 0;
+    client->connected_port = 0;
 
     for (int i = 0; i < RPC_HTABLE_SIZE; ++i) {
        client->call_hash[i] = NULL;
@@ -361,19 +346,17 @@ err_t rpc_init(struct rpc_client *client, struct ip_addr server)
 
     RPC_DEBUGP("###### Initial sequence no. is %"PRIu32" 0x%"PRIx32"\n",
                client->nextxid, client->nextxid);
-    udp_recv(client->pcb, rpc_recv_handler, client);
-
-    err = periodic_event_create(&client->timer, lwip_waitset,
+    err = periodic_event_create(&client->timer, get_default_waitset(),
                                 RPC_TIMER_PERIOD, MKCLOSURE(rpc_timer, client));
     assert(err_is_ok(err));
     if (err_is_fail(err)) {
        printf("rpc timer creation failed\n");
-        udp_remove(client->pcb);
-        return ERR_MEM;
+        net_close(client->socket);
+        return LWIP_ERR_MEM;
     }
     RPC_DEBUGP("rpc timer created\n");
 
-    return ERR_OK;
+    return SYS_ERR_OK;
 }
 
 
@@ -392,38 +375,30 @@ err_t rpc_init(struct rpc_client *client, struct ip_addr server)
  * \param callback Callback function to be invoked when call either completes or fails
  * \param cbarg1,cbarg2 Opaque arguments to be passed to callback function
  *
- * \returns Error code (ERR_OK on success)
+ * \returns Error code (SYS_ERR_OK on success)
  */
-err_t rpc_call(struct rpc_client *client, uint16_t port, uint32_t prog,
+errval_t rpc_call(struct rpc_client *client, uint16_t port, uint32_t prog,
                uint32_t vers, uint32_t proc, xdrproc_t args_xdrproc, void *args,
                size_t args_size, rpc_callback_t callback, void *cbarg1,
                void *cbarg2)
 {
 
-    uint64_t ts = rdtsc();
     XDR xdr;
-    err_t r;
+    errval_t r;
     bool rb;
     uint32_t xid;
-    RPC_DEBUGP("rpc_call: started, trying to get a lock\n");
-    if (lwip_mutex != NULL) {
-        if(thread_mutex_trylock(lwip_mutex)) {
-           printf("rpc_call: thread_mutex_trylock failed\n");
-           abort();
-        }
-    }
 
-    RPC_DEBUGP("rpc_call:  calling xdr_pbuf_create_send\n");
-    rb = xdr_pbuf_create_send(&xdr, args_size + RPC_CALL_HEADER_LEN);
+    RPC_DEBUGP("rpc_call:  calling xdr_create_send\n");
+    rb = xdr_create_send(&xdr, args_size + RPC_CALL_HEADER_LEN);
     if (!rb) {
-        return ERR_MEM;
+        return LWIP_ERR_MEM;
     }
 
     xid = client->nextxid++;
 
     RPC_DEBUGP("rpc_call: calling rpc_call_init\n");
     r = rpc_call_init(&xdr, xid, prog, vers, proc);
-    if (r != ERR_OK) {
+    if (r != SYS_ERR_OK) {
         XDR_DESTROY(&xdr);
         return r;
     }
@@ -432,35 +407,34 @@ err_t rpc_call(struct rpc_client *client, uint16_t port, uint32_t prog,
     rb = args_xdrproc(&xdr, args);
     if (!rb) {
         XDR_DESTROY(&xdr);
-        return ERR_BUF;
+        return LWIP_ERR_BUF;
     }
 
     struct rpc_call *call = malloc(sizeof(struct rpc_call));
     if (call == NULL) {
         XDR_DESTROY(&xdr);
-        return ERR_MEM;
+        return LWIP_ERR_MEM;
     }
     call->xid = xid;
     call->retries = call->timers = 0;
-    call->pbuf = (struct pbuf *)xdr.x_private;
+    call->data = xdr.x_private;
+    call->size = xdr.size;
     call->callback = callback;
     call->cbarg1 = cbarg1;
     call->cbarg2 = cbarg2;
     call->next = NULL;
 
     RPC_DEBUGP("rpc_call: RPC call for xid %u x0%x\n", xid, xid);
-    /* XXX: fix size on pbuf in case the buffer was too big */
-    if (((struct pbuf *)xdr.x_base)->len > xdr.x_handy) {
-        /* FIXME: intermediate pbufs will have the wrong tot_len */
-        call->pbuf->tot_len -= ((struct pbuf *)xdr.x_base)->len - xdr.x_handy;
-        ((struct pbuf *)xdr.x_base)->len = xdr.x_handy;
-    }
     RPC_DEBUGP("rpc_call: calling UPD_connect\n");
-    r = udp_connect(client->pcb, &client->server, port);
-    if (r != ERR_OK) {
-        XDR_DESTROY(&xdr);
-        free(call);
-        return r;
+    if (client->server != client->connected_address || 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;
     }
 
     /* enqueue */
@@ -469,8 +443,8 @@ err_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 = udp_send(client->pcb, call->pbuf);
-    if (r != ERR_OK) {
+    r = net_send(client->socket, call->data, call->size);
+    if (r != SYS_ERR_OK) {
         /* dequeue */
         assert(client->call_hash[hid] == call);
         client->call_hash[hid] = call->next;
@@ -480,7 +454,6 @@ err_t rpc_call(struct rpc_client *client, uint16_t port, uint32_t prog,
     }
 
     RPC_DEBUGP("rpc_call: rpc_call done\n");
-    lwip_record_event_simple(RPC_CALL_T, ts);
     return r;
 }
 
@@ -493,12 +466,11 @@ void rpc_destroy(struct rpc_client *client)
     struct rpc_call *call, *next;
     for(int i = 0; i < RPC_HTABLE_SIZE; ++i) {
         for (call = client->call_hash[i]; call != NULL; call = next) {
-            pbuf_free(call->pbuf);
+            free(call->data);
             next = call->next;
             free(call);
         }
         client->call_hash[i] = NULL;
     }
-
-    udp_remove(client->pcb);
+    net_close(client->socket);
 }
index 45674e8..4877a2a 100644 (file)
@@ -15,7 +15,9 @@
 #ifndef _RPC_H
 #define _RPC_H
 
+#include <nfs/xdr.h>
 #include <barrelfish/deferred.h>
+#include <net_sockets/net_sockets.h>
 
 /**
  * A reply to a call message can take on two forms: The message was
@@ -57,8 +59,9 @@ enum rpc_auth_stat {
 
 /// RPC client instance data
 struct rpc_client {
-    struct udp_pcb *pcb;    ///< UDP connection data in LWIP
-    struct ip_addr server;  ///< Server IP
+    struct net_socket *socket;    ///< UDP socket
+    host_address_t connected_address, connected_port;
+    host_address_t server;  ///< Server IP
     struct rpc_call *call_hash[RPC_HTABLE_SIZE];
 
     uint32_t nextxid;       ///< Next transaction ID
@@ -82,9 +85,9 @@ typedef void (*rpc_callback_t)(struct rpc_client *rpc_client, void *arg1,
                                void *arg2, uint32_t replystat,
                                uint32_t acceptstat, XDR *reply_xdr);
 
-err_t rpc_init(struct rpc_client *client, struct ip_addr server);
+errval_t rpc_init(struct rpc_client *client, host_address_t server);
 void rpc_destroy(struct rpc_client *client);
-err_t rpc_call(struct rpc_client *client, uint16_t port, uint32_t prog,
+errval_t rpc_call(struct rpc_client *client, uint16_t port, uint32_t prog,
                uint32_t vers, uint32_t proc, xdrproc_t args_xdrproc, void *args,
                size_t args_size, rpc_callback_t callback, void *cbarg1,
                void *cbarg2);
index db43454..b2a3dfb 100644 (file)
@@ -449,8 +449,8 @@ xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
     return false;
 }
 
-/* 
- * Wrapper for xdr_string that can be called directly from 
+/*
+ * Wrapper for xdr_string that can be called directly from
  * routines like clnt_call
  */
 bool
index 0e1288f..9b336e8 100644 (file)
  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
  */
 
-#include <lwip/pbuf.h>
 #include <assert.h>
 #include <nfs/xdr.h>
 #include "xdr_pbuf.h"
-
-/* move to the next pbuf in the chain */
-static bool nextbuf(XDR *xdr)
-{
-    // shouldn't leave anything behind in previous pbuf
-    assert(xdr->x_handy == ((struct pbuf *)xdr->x_base)->len);
-
-    struct pbuf *nextpbuf;
-    if ((nextpbuf = ((struct pbuf *)xdr->x_base)->next) != NULL) {
-        assert(nextpbuf->len % BYTES_PER_XDR_UNIT == 0);
-        xdr->x_base = nextpbuf;
-        xdr->x_handy = 0;
-        return true;
-    } else {
-        return false;
-    }
-}
+#include <net_sockets/net_sockets.h>
 
 /* make space within the buffer, returns NULL if it won't fit */
 static inline int32_t *make_space(XDR *xdr, size_t size)
 {
-    if (((struct pbuf *)xdr->x_base)->len == xdr->x_handy) {
-        if (!nextbuf(xdr)) {
-            return NULL;
-        }
-    }
-    if (xdr->x_handy + size > ((struct pbuf *)xdr->x_base)->len) {
+    if (xdr->x_handy + size > xdr->size) {
         fprintf(stderr, "xdr_pbuf: make_space(%zu) failing (%zu available)\n",
-                size, ((size_t)((struct pbuf *)xdr->x_base)->len) - (size_t)xdr->x_handy);
+                size, xdr->size - (size_t)xdr->x_handy);
         return NULL;
     } else {
-        int32_t *ret = (int32_t *)((char *)((struct pbuf *)xdr->x_base)->payload + xdr->x_handy);
+        int32_t *ret = (int32_t *)((char *)xdr->x_base + xdr->x_handy);
         xdr->x_handy += size;
         return ret;
     }
@@ -86,13 +64,7 @@ static bool xdr_pbuf_putint32(XDR *xdr, const int32_t *val)
 static bool movebytes(bool copyin, XDR *xdr, char *callerbuf, size_t nbytes)
 {
     while (nbytes > 0) {
-        if (xdr->x_handy == ((struct pbuf *)xdr->x_base)->len) {
-            if (!nextbuf(xdr)) {
-                return false;
-            }
-        }
-
-        size_t space = ((struct pbuf *)xdr->x_base)->len - xdr->x_handy;
+        size_t space = xdr->size - xdr->x_handy;
         if (space > nbytes) {
             space = nbytes;
         }
@@ -124,27 +96,16 @@ static bool xdr_pbuf_putbytes(XDR *xdr, const char *inbuf, size_t nbytes)
 /* returns bytes off from beginning */
 static size_t xdr_pbuf_getpostn(XDR *xdr)
 {
-    struct pbuf *pbuf = xdr->x_private;
-    size_t len = 0;
-    while (xdr->x_base != pbuf) {
-        len += pbuf->len;
-        pbuf = pbuf->next;
-    }
-    return len + xdr->x_handy;
+    return xdr->x_handy;
 }
 
 /* lets you reposition the stream */
 static bool xdr_pbuf_setpostn(XDR *xdr, size_t pos)
 {
-    struct pbuf *pbuf = xdr->x_private;
-    if (pos > pbuf->tot_len) {
+    if (pos > xdr->size) {
         return false;
     } else {
-        for (; pos > pbuf->len; pbuf=pbuf->next) {
-            assert(pbuf != NULL); // or tot_len is wrong!
-            pos -= pbuf->len;
-        }
-        xdr->x_base = pbuf;
+        xdr->x_base = xdr->x_private;
         xdr->x_handy = pos;
         return true;
     }
@@ -160,7 +121,7 @@ static int32_t *xdr_pbuf_inline(XDR *xdr, size_t nbytes)
 /* free privates of this xdr_stream */
 static void xdr_pbuf_destroy(XDR *xdr)
 {
-    pbuf_free((struct pbuf *)xdr->x_private);
+    net_free(xdr->x_private);
 }
 
 /// XDR operations table
@@ -183,16 +144,13 @@ static struct xdr_ops xdr_pbuf_ops = {
  *
  * \returns True on success, false on error
  */
-bool xdr_pbuf_create_send(XDR *xdr, size_t size)
+bool xdr_create_send(XDR *xdr, size_t size)
 {
     assert(xdr != NULL);
-    struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
-    if (pbuf == NULL) {
-        return false;
-    }
     assert(size % BYTES_PER_XDR_UNIT == 0);
-    assert(pbuf->len % BYTES_PER_XDR_UNIT == 0);
-    xdr->x_base = xdr->x_private = pbuf;
+    xdr->x_base = xdr->x_private = net_alloc(size);
+    xdr->size = size;
+    assert(xdr->x_private);
     xdr->x_op = XDR_ENCODE;
     xdr->x_ops = &xdr_pbuf_ops;
     xdr->x_handy = 0;
@@ -207,12 +165,14 @@ bool xdr_pbuf_create_send(XDR *xdr, size_t size)
  *
  * \returns True on success, false on error
  */
-void xdr_pbuf_create_recv(XDR *xdr, struct pbuf *pbuf)
+void xdr_create_recv(XDR *xdr, void *data, size_t size)
 {
     assert(xdr != NULL);
-    assert(pbuf->len % BYTES_PER_XDR_UNIT == 0);
-    assert(pbuf->tot_len % BYTES_PER_XDR_UNIT == 0);
-    xdr->x_private = xdr->x_base = pbuf;
+    assert(size % BYTES_PER_XDR_UNIT == 0);
+    xdr->x_base = xdr->x_private = data;
+    xdr->size = size;
+    assert(xdr->x_private);
+    memcpy(xdr->x_private, data, size);
     xdr->x_op = XDR_DECODE;
     xdr->x_ops = &xdr_pbuf_ops;
     xdr->x_handy = 0;
index f98cbee..f6224ea 100644 (file)
@@ -15,8 +15,7 @@
 #ifndef _XDR_PBUF_H
 #define _XDR_PBUF_H
 
-struct pbuf;
-bool xdr_pbuf_create_send(XDR *xdr, size_t size);
-void xdr_pbuf_create_recv(XDR *xdr, struct pbuf *pbuf);
+bool xdr_create_send(XDR *xdr, size_t size);
+void xdr_create_recv(XDR *xdr, void *data, size_t size);
 
 #endif
index fb1938e..0533aef 100644 (file)
                              "vfs_fat_conv.c", "fdtab.c", "vfs_fd.c",
                              "vfs_blockdevfs_megaraid.c"
                            ],
+                  addLibraries = [ "nfs", "net_sockets" ],
                   mackerelDevices = [ "ata_identify", "fat_bpb", "fat16_ebpb",
                                       "fat32_ebpb", "fat_direntry", "ahci_port",
                                       "ahci_hba"
                                     ],
-                  addLibraries = [ "lwip" ],
                   flounderBindings = [ "trivfs", "bcache", "ahci_mgmt", "ata_rw28" ],
                   flounderExtraBindings = [ ("trivfs", ["rpcclient"]),
                                             ("bcache", ["rpcclient"]),
index 68cc03c..6b230be 100644 (file)
 #include <sys/param.h>
 
 // networking stuff
-#include <lwip/netif.h>
-#include <lwip/dhcp.h>
-#include <netif/etharp.h>
-#include <lwip/init.h>
-#include <lwip/tcp.h>
-#include <netif/bfeth.h>
-#include <lwip/ip_addr.h>
+#include <net_sockets/net_sockets.h>
+// #include <lwip/netif.h>
+// #include <lwip/dhcp.h>
+// #include <netif/etharp.h>
+// #include <lwip/init.h>
+// #include <lwip/tcp.h>
+// #include <netif/bfeth.h>
+// #include <lwip/ip_addr.h>
 
 #include "vfs_backends.h"
 
@@ -55,75 +56,19 @@ do {                        \
 
 // condition used to singal controlling code to wait for a condition
 static bool wait_flag;
-static struct thread_cond wait_cond = THREAD_COND_INITIALIZER;
-
-// XXX: lwip idc_barrelfish.c
-extern struct waitset *lwip_waitset;
-
-/*static void check_and_handle_other_events(void)
-{
-    if (lwip_mutex == NULL) { // single-threaded
-        while (true) {
-            errval_t err = event_dispatch_non_block(lwip_waitset);
-            if (err == LIB_ERR_NO_EVENT) {
-                return;
-            }
-            if (err_is_fail(err)) {
-                DEBUG_ERR(err, "in event_dispatch_non_block");
-                break;
-            }
-        }
-    } else {
-        assert(!"NYI: ");
-    }
-}*/
 
 static void wait_for_condition(void)
 {
-    if (lwip_mutex == NULL) { // single-threaded
-        while (!wait_flag) {
-            errval_t err = event_dispatch(lwip_waitset);
-            assert(err_is_ok(err));
-        }
-        wait_flag = false;
-    } else {
-        thread_cond_wait(&wait_cond, lwip_mutex);
+    while (!wait_flag) {
+        errval_t err = event_dispatch(get_default_waitset());
+        assert(err_is_ok(err));
     }
+    wait_flag = false;
 }
 
-// NOTE: just like above function, but it checks all events instead of
-// blocking on any perticular event
-// Above function was blocking on waiting for timer event even when there
-// are incoming packets to be processed. (only in the case of UMP)
-// FIXME: this is used only in read function and other functions are still
-// using above function. But this function should replace above function.
-/*static void wait_for_condition_fair(void)
-{
-    if (lwip_mutex == NULL) { // single-threaded
-        while (!wait_flag) {
-            check_and_handle_other_events();
-            wrapper_perform_lwip_work();
-            if (wait_flag) {
-                break;
-            }
-            errval_t err = event_dispatch(lwip_waitset);
-            assert(err_is_ok(err));
-        }
-        wait_flag = false;
-    } else {
-        thread_cond_wait(&wait_cond, lwip_mutex);
-    }
-}*/
-
-
 static void signal_condition(void)
 {
-    if (lwip_mutex == NULL) { // single-threaded
-        wait_flag = true;
-    } else {
-        assert(!thread_mutex_trylock(lwip_mutex));
-        thread_cond_signal(&wait_cond);
-    }
+    wait_flag = true;
 }
 
 typedef void resolve_cont_fn(void *st, errval_t err, struct nfs_fh3 fh,
@@ -188,9 +133,9 @@ out:
     pathbuf[nextlen] = '\0';
     st->path_pos += nextlen + 1;
 
-    err_t e = nfs_lookup(st->nfs->client, st->curfh, pathbuf, resolve_lookup_cb,
+    errval_t e = nfs_lookup(st->nfs->client, st->curfh, pathbuf, resolve_lookup_cb,
                          st);
-    assert(e == ERR_OK);
+    assert(e == SYS_ERR_OK);
 
     // free arguments
     xdr_LOOKUP3res(&xdr_free, result);
@@ -238,8 +183,8 @@ static void initiate_resolve(struct nfs_state *nfs, const char *path,
     st->path_pos += nextlen + 1;
 
     // initiate the first lookup
-    err_t e = nfs_lookup(nfs->client, st->curfh, pathbuf, resolve_lookup_cb, st);
-    assert(e == ERR_OK);
+    errval_t e = nfs_lookup(nfs->client, st->curfh, pathbuf, resolve_lookup_cb, st);
+    assert(e == SYS_ERR_OK);
 }
 
 struct nfs_file_io_handle {
@@ -266,7 +211,6 @@ static void read_callback(void *arg, struct nfs_client *client, READ3res *result
     struct nfs_file_parallel_io_handle *pfh = arg;
 
     assert(result != NULL);
-    uint64_t ts = rdtsc();
     // error
     if (result->status != NFS3_OK) {
         pfh->fh->status = result->status;
@@ -298,10 +242,10 @@ static void read_callback(void *arg, struct nfs_client *client, READ3res *result
         pfh->chunk_start += res->data.data_len;
         pfh->chunk_size -= res->data.data_len;
 
-        err_t e = nfs_read(client, pfh->fh->handle,
+        errval_t e = nfs_read(client, pfh->fh->handle,
                            pfh->fh->offset + pfh->chunk_start,
                            pfh->chunk_size, read_callback, pfh);
-        assert(e == ERR_OK);
+        assert(e == SYS_ERR_OK);
 
         goto out;
     }
@@ -318,10 +262,10 @@ static void read_callback(void *arg, struct nfs_client *client, READ3res *result
         pfh->chunk_size = MIN(MAX_NFS_READ_BYTES, pfh->fh->size - pfh->chunk_start);
         pfh->fh->chunk_pos += pfh->chunk_size;
         pfh->fh->chunks_in_progress++;
-        err_t r = nfs_read(client, pfh->fh->handle,
+        errval_t r = nfs_read(client, pfh->fh->handle,
                            pfh->fh->offset + pfh->chunk_start,
                            pfh->chunk_size, read_callback, pfh);
-        assert(r == ERR_OK);
+        assert(r == SYS_ERR_OK);
     } else {
         free(pfh);
     }
@@ -335,7 +279,6 @@ out:
     }
     // free arguments
     xdr_READ3res(&xdr_free, result);
-    lwip_record_event_simple(NFS_READCB_T, ts);
 }
 
 static void write_callback(void *arg, struct nfs_client *client, WRITE3res *result)
@@ -383,11 +326,11 @@ static void write_callback(void *arg, struct nfs_client *client, WRITE3res *resu
         pfh->chunk_start = pfh->fh->chunk_pos;
         pfh->chunk_size = MIN(MAX_NFS_WRITE_BYTES, pfh->fh->size - pfh->chunk_start);
         pfh->fh->chunk_pos += pfh->chunk_size;
-        err_t r = nfs_write(client, pfh->fh->handle,
+        errval_t r = nfs_write(client, pfh->fh->handle,
                             pfh->fh->offset + pfh->chunk_start,
                             (char *)pfh->fh->data + pfh->chunk_start, pfh->chunk_size,
                             NFS_WRITE_STABILITY, write_callback, pfh);
-        assert(r == ERR_OK);
+        assert(r == SYS_ERR_OK);
     } else {
         free(pfh);
     }
@@ -431,10 +374,10 @@ static errval_t open(void *st, const char *path, vfs_handle_t *rethandle)
     h->cached_filesize = 0;
 #endif
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
     initiate_resolve(nfs, path, open_resolve_cont, h);
     wait_for_condition();
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     if (h->fh.data_len > 0 && h->type != NF3DIR) {
         *rethandle = h;
@@ -484,9 +427,9 @@ static void create_resolve_cont(void *st, errval_t err, struct nfs_fh3 fh,
     }
 
     static struct sattr3 nulattr;
-    err_t r = nfs_create(h->nfs->client, fh, h->st, false, nulattr,
+    errval_t r = nfs_create(h->nfs->client, fh, h->st, false, nulattr,
                          create_callback, h);
-    assert(r == ERR_OK);
+    assert(r == SYS_ERR_OK);
 }
 
 static errval_t create(void *st, const char *path, vfs_handle_t *rethandle)
@@ -525,10 +468,10 @@ static errval_t create(void *st, const char *path, vfs_handle_t *rethandle)
     h->cached_filesize = 0;
 #endif
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
     initiate_resolve(nfs, dir, create_resolve_cont, h);
     wait_for_condition();
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     free(dir);
 
@@ -570,10 +513,10 @@ static errval_t opendir(void *st, const char *path, vfs_handle_t *rethandle)
         return SYS_ERR_OK;
     }
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
     initiate_resolve(nfs, path, open_resolve_cont, h);
     wait_for_condition();
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     if (h->fh.data_len > 0 && h->type == NF3DIR) {
         *rethandle = h;
@@ -587,11 +530,10 @@ static errval_t opendir(void *st, const char *path, vfs_handle_t *rethandle)
 static errval_t read(void *st, vfs_handle_t inhandle, void *buffer,
         size_t bytes, size_t *bytes_read)
 {
-    uint64_t ts = rdtsc();
     struct nfs_state *nfs = st;
     struct nfs_handle *h = inhandle;
     assert(h != NULL);
-    err_t e;
+    errval_t e;
 
     assert(!h->isdir);
 
@@ -606,7 +548,7 @@ static errval_t read(void *st, vfs_handle_t inhandle, void *buffer,
     fh.handle = h->fh;
     fh.chunks_in_progress = 0;
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
 
     // start a parallel load of the file, wait for it to complete
     int chunks = 0;
@@ -624,7 +566,7 @@ static errval_t read(void *st, vfs_handle_t inhandle, void *buffer,
         e = nfs_read(nfs->client, fh.handle, fh.offset + pfh->chunk_start,
                      pfh->chunk_size, read_callback, pfh);
 
-        if (e == ERR_MEM) { // internal resource limit in lwip?
+        if (e == LWIP_ERR_MEM) { // internal resource limit in lwip?
             printf("read: error in nfs_read ran out of mem!!!\n");
             printf("read: error chunks %d in progress %d!!!\n",
                     chunks, (int)fh.chunks_in_progress);
@@ -632,18 +574,15 @@ static errval_t read(void *st, vfs_handle_t inhandle, void *buffer,
             free(pfh);
             break;
         }
-        assert(e == ERR_OK);
+        assert(e == SYS_ERR_OK);
         chunks++;
 #ifdef NONBLOCKING_NFS_READ
         check_and_handle_other_events();
 #endif // NONBLOCKING_NFS_READ
     }
-    lwip_record_event_simple(NFS_READ_1_T, ts);
-    uint64_t ts1 = rdtsc();
     wait_for_condition();
-    lwip_record_event_simple(NFS_READ_w_T, ts1);
 
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     // check result
     if (fh.status != NFS3_OK) {
@@ -655,7 +594,6 @@ static errval_t read(void *st, vfs_handle_t inhandle, void *buffer,
     h->u.file.pos += fh.size;
     *bytes_read = fh.size;
 
-    lwip_record_event_simple(NFS_READ_T, ts);
     if (fh.size == 0) {
         /* XXX: assuming this means EOF, but we really do know from NFS */
 /*        printf("read:vfs_nfs: EOF marking %"PRIuPTR" < %"PRIuPTR","
@@ -674,7 +612,7 @@ static errval_t write(void *st, vfs_handle_t handle, const void *buffer,
     struct nfs_state *nfs = st;
     struct nfs_handle *h = handle;
     assert(h != NULL);
-    err_t e;
+    errval_t e;
 
     #if 0
     if((__builtin_return_address(2) < (void *)fclose ||
@@ -717,7 +655,7 @@ static errval_t write(void *st, vfs_handle_t handle, const void *buffer,
     fh->handle = h->fh;
     fh->back_fh = h;
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
 
     // start a parallel write of the file, wait for it to complete
     int chunks = 0;
@@ -732,14 +670,14 @@ static errval_t write(void *st, vfs_handle_t handle, const void *buffer,
         e = nfs_write(nfs->client, fh->handle, fh->offset + pfh->chunk_start,
                       (char *)fh->data + pfh->chunk_start, pfh->chunk_size,
                       NFS_WRITE_STABILITY, write_callback, pfh);
-        assert(e == ERR_OK);
+        assert(e == SYS_ERR_OK);
         chunks++;
     } while (fh->chunk_pos < fh->size && chunks < MAX_NFS_WRITE_CHUNKS);
 #ifndef ASYNC_WRITES
     wait_for_condition();
 #endif
 
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
 #ifndef ASYNC_WRITES
     // check result
@@ -781,9 +719,9 @@ static errval_t nfs_truncate(void *st, vfs_handle_t handle, size_t bytes)
 
     struct nfs_state *nfs = st;
     assert(h != NULL);
-    err_t e;
+    errval_t e;
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
     // We only set the size field for now
 
     sattr3 new_attributes;
@@ -799,9 +737,9 @@ static errval_t nfs_truncate(void *st, vfs_handle_t handle, size_t bytes)
     e = nfs_setattr(nfs->client, h->fh,
                     new_attributes, false,
                     setattr_callback, NULL);
-    assert(e == ERR_OK);
+    assert(e == SYS_ERR_OK);
     wait_for_condition();
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     return SYS_ERR_OK;
 }
@@ -854,13 +792,13 @@ static errval_t stat(void *st, vfs_handle_t inhandle, struct vfs_fileinfo *info)
     struct nfs_state *nfs = st;
     struct nfs_handle *h = inhandle;
     assert(h != NULL);
-    err_t e;
+    errval_t e;
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
     e = nfs_getattr(nfs->client, h->fh, getattr_callback, info);
-    assert(e == ERR_OK);
+    assert(e == SYS_ERR_OK);
     wait_for_condition();
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     assert(h->isdir == (info->type == VFS_DIRECTORY));
 
@@ -930,7 +868,7 @@ static void get_info_lookup_cb(void *arg, struct nfs_client *client,
 
     LOOKUP3resok *resok = &result->LOOKUP3res_u.resok;
 
-    err_t e = nfs_getattr(client, resok->object, getattr_callback, arg);
+    errval_t e = nfs_getattr(client, resok->object, getattr_callback, arg);
     assert(err_is_ok(e));
 
     xdr_LOOKUP3res(&xdr_free, result);
@@ -942,11 +880,11 @@ static errval_t dir_read_next(void *st, vfs_handle_t inhandle,
     struct nfs_state *nfs = st;
     struct nfs_handle *h = inhandle;
     struct entry3 *entry;
-    err_t e;
+    errval_t e;
 
     assert(h->isdir);
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
 
 top:
     // do we have a cached result?
@@ -956,7 +894,7 @@ top:
         h->u.dir.readdir_next = entry->nextentry;
     } else if (h->u.dir.readdir_result != NULL
                && h->u.dir.readdir_result->READDIR3res_u.resok.reply.eof) {
-        lwip_mutex_unlock();
+        // lwip_mutex_unlock();
         return FS_ERR_INDEX_BOUNDS; // end of list
     } else {
 
@@ -968,14 +906,14 @@ top:
             e = nfs_readdir(nfs->client, h->fh, oldentry->cookie,
                             oldresult->READDIR3res_u.resok.cookieverf,
                             readdir_callback, h);
-            assert(e == ERR_OK);
+            assert(e == SYS_ERR_OK);
 
             xdr_READDIR3res(&xdr_free, oldresult);
             free(oldresult);
         } else { // first call
             e = nfs_readdir(nfs->client, h->fh, NFS_READDIR_COOKIE,
                             NFS_READDIR_COOKIEVERF, readdir_callback, h);
-            assert(e == ERR_OK);
+            assert(e == SYS_ERR_OK);
         }
 
         wait_for_condition();
@@ -987,7 +925,7 @@ top:
 
     if (entry == NULL) {
         assert(h->u.dir.readdir_result->READDIR3res_u.resok.reply.eof);
-        lwip_mutex_unlock();
+        // lwip_mutex_unlock();
         return FS_ERR_INDEX_BOUNDS;
     } else {
         assert(entry->name != NULL);
@@ -1002,10 +940,10 @@ top:
             // initiate a lookup/getattr call to find out this information
             e = nfs_lookup(nfs->client, h->fh, entry->name, get_info_lookup_cb,
                            info);
-            assert(e == ERR_OK);
+            assert(e == SYS_ERR_OK);
             wait_for_condition();
         }
-        lwip_mutex_unlock();
+        // lwip_mutex_unlock();
         return SYS_ERR_OK;
     }
 }
@@ -1065,8 +1003,8 @@ static void remove_resolve_cont(void *st, errval_t err, struct nfs_fh3 fh,
         return;
     }
 
-    err_t r = nfs_remove(h->nfs->client, fh, h->st, remove_callback, h);
-    assert(r == ERR_OK);
+    errval_t r = nfs_remove(h->nfs->client, fh, h->st, remove_callback, h);
+    assert(r == SYS_ERR_OK);
 }
 
 static errval_t vfs_nfs_remove(void *st, const char *path)
@@ -1101,10 +1039,10 @@ static errval_t vfs_nfs_remove(void *st, const char *path)
     h->inflight = 0;
 #endif
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
     initiate_resolve(nfs, dir, remove_resolve_cont, h);
     wait_for_condition();
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     size_t err = h->fh.data_len;
     free(dir);
@@ -1158,11 +1096,11 @@ static void mkdir_resolve_cont(void *st, errval_t err, struct nfs_fh3 fh,
     }
 
     static struct sattr3 nulattr;
-    err_t r = nfs_mkdir(s->client, fh, s->dirname, nulattr, mkdir_callback, s);
-    if (r != ERR_OK) { // XXX: proper error handling
-        debug_printf("error in mkdir_resolve_cont %d\n", r);
+    errval_t r = nfs_mkdir(s->client, fh, s->dirname, nulattr, mkdir_callback, s);
+    if (r != SYS_ERR_OK) { // XXX: proper error handling
+        debug_printf("error in mkdir_resolve_cont %zd\n", r);
     }
-    assert(r == ERR_OK);
+    assert(r == SYS_ERR_OK);
 }
 
 static errval_t mkdir(void *st, const char *path)
@@ -1190,10 +1128,10 @@ static errval_t mkdir(void *st, const char *path)
         .err = SYS_ERR_OK,
     };
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
     initiate_resolve(nfs, parent, mkdir_resolve_cont, &state);
     wait_for_condition();
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     free(parent);
 
@@ -1243,7 +1181,7 @@ static errval_t read_block(void *st, vfs_handle_t inhandle, void *buffer,
     struct nfs_state *nfs = st;
     struct nfs_handle *h = inhandle;
     assert(h != NULL);
-    err_t e;
+    errval_t e;
 
     assert(!h->isdir);
 
@@ -1258,7 +1196,7 @@ static errval_t read_block(void *st, vfs_handle_t inhandle, void *buffer,
     fh.handle = h->fh;
     fh.chunks_in_progress = 0;
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
 
     // start a parallel load of the file, wait for it to complete
     int chunks = 0;
@@ -1279,12 +1217,12 @@ static errval_t read_block(void *st, vfs_handle_t inhandle, void *buffer,
             free(pfh);
             break;
         }
-        assert(e == ERR_OK);
+        assert(e == SYS_ERR_OK);
         chunks++;
     } // end while
     wait_for_condition();
 
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     // check result
     if (fh.status != NFS3_OK && fh.status != NFS3ERR_STALE) {
@@ -1309,7 +1247,7 @@ static errval_t write_block(void *st, vfs_handle_t handle, const void *buffer,
     struct nfs_state *nfs = st;
     struct nfs_handle *h = handle;
     assert(h != NULL);
-    err_t e;
+    errval_t e;
 
     assert(!h->isdir);
 
@@ -1339,7 +1277,7 @@ static errval_t write_block(void *st, vfs_handle_t handle, const void *buffer,
         e = nfs_write(nfs->client, fh.handle, fh.offset + pfh->chunk_start,
                       (char *)fh.data + pfh->chunk_start, pfh->chunk_size,
                       NFS_WRITE_STABILITY, write_callback, pfh);
-        assert(e == ERR_OK);
+        assert(e == SYS_ERR_OK);
         chunks++;
     } while (fh.chunk_pos < fh.size && chunks < MAX_NFS_WRITE_CHUNKS);
     wait_for_condition();
@@ -1423,23 +1361,24 @@ errval_t vfs_nfs_mount(const char *uri, void **retst, struct vfs_ops **retops)
         printf("Invalid host IP: %s\n", host_copy);
         return VFS_ERR_BAD_URI;
     }
-    struct ip_addr server2 = { .addr = server1.s_addr }; // XXX
+    host_address_t server2 = server1.s_addr;
 
     // init stack if needed
     static bool stack_inited;
     if (!stack_inited) {
-        lwip_init_auto();
+        // lwip_init_auto();
+        net_sockets_init();
         stack_inited = true;
     }
 
     struct nfs_state *st = malloc(sizeof(struct nfs_state));
     assert(st != NULL);
 
-    lwip_mutex_lock();
+    // lwip_mutex_lock();
     st->client = nfs_mount(server2, path, mount_callback, st);
     assert(st->client != NULL);
     wait_for_condition();
-    lwip_mutex_unlock();
+    // lwip_mutex_unlock();
 
     if (st->mountstat == MNT3_OK) {
         *retst = st;
index 2039829..97f0f27 100644 (file)
@@ -12,6 +12,6 @@
 
 [ build application { target = "netthroughput",
                       cFiles = [ "nfs_cat.c"],
-                      addLibraries = libDeps ["vfs", "lwip"]
+                      addLibraries = libDeps ["vfs"]
                     }
 ]
index ab6c826..4beac7b 100644 (file)
@@ -49,20 +49,23 @@ static int cat(char *path)
        printf("Could not stat file %s\n", path);
     }
     printf("Reading %d bytes from %s.\n", (int)info.size, path);
-    void *buf = malloc(info.size);
+    void *buf = malloc(10485760);
     assert(buf);
 
     uint64_t start = rdtsc();
     lwip_benchmark_control(1, BMS_START_REQUEST, 0, 0);
 
-       err = vfs_read(vh, buf, info.size, &size);
-       if (err_is_fail(err)) {
-               // XXX: Close any files that might be open
-               DEBUG_ERR(err, "error reading file");
-               return 0;
-       }
-       assert(info.size == size);
-       filesize += size;
+    for (; filesize != info.size;) {
+       err = vfs_read(vh, buf, 10485760, &size);
+       if (err_is_fail(err)) {
+               // XXX: Close any files that might be open
+               DEBUG_ERR(err, "error reading file");
+               return 0;
+       }
+        debug_printf("%s: %ld:%ld\n", __func__, filesize, info.size);
+       filesize += size;
+    }
+    assert(info.size == filesize);
 
     // record stop time
     uint64_t stop = rdtsc();
@@ -96,7 +99,7 @@ int main(int argc, char**argv)
     }
 
     errval_t err = vfs_mkdir(MOUNT_DIR);
-    if(err_is_fail(err)) {
+    if (err_is_fail(err)) {
         DEBUG_ERR(err, "vfs_mount");
     }
 
index bca0540..0ca45f8 100644 (file)
@@ -19,8 +19,7 @@
 #include <stdio.h>
 #include <barrelfish/barrelfish.h>
 #include <nfs/nfs.h>
-#include <lwip/init.h>
-#include <lwip/ip_addr.h>
+#include <net_sockets/net_sockets.h>
 #include <trace/trace.h>
 #include <trace_definitions/trace_defs.h>
 #include <timer/timer.h>
@@ -290,9 +289,9 @@ static void read_callback (void *arg, struct nfs_client *client,
 
     if (!res->eof) {
         // more data to come, read the next chunk
-        err_t err = nfs_read(client, e->file_handle, e->copied, MAX_NFS_READ,
+        errval_t err = nfs_read(client, e->file_handle, e->copied, MAX_NFS_READ,
                         read_callback, e);
-        assert(err == ERR_OK);
+        assert(err == SYS_ERR_OK);
         return;
     }
 
@@ -323,7 +322,7 @@ static void lookup_callback (void *arg, struct nfs_client *client,
                             LOOKUP3res *result)
 {
     LOOKUP3resok *resok = &result->LOOKUP3res_u.resok;
-    err_t r;
+    errval_t r;
     struct http_cache_entry *e = arg;
 
     DEBUGPRINT ("inside lookup_callback_file for file %s\n", e->name);
@@ -362,7 +361,7 @@ static void lookup_callback (void *arg, struct nfs_client *client,
 
         r = nfs_read (client, e->file_handle, 0, MAX_NFS_READ,
                 read_callback, e);
-        assert (r == ERR_OK);
+        assert (r == SYS_ERR_OK);
 
         // free arguments
         xdr_LOOKUP3res(&xdr_free, result);
@@ -402,9 +401,9 @@ static void lookup_callback (void *arg, struct nfs_client *client,
     return;
 } /* end function: lookup_callback_file */
 
-static err_t async_load_cache_entry(struct http_cache_entry *e)
+static errval_t async_load_cache_entry(struct http_cache_entry *e)
 {
-    err_t r;
+    errval_t r;
     assert(e != NULL);
 
     // FIXME: currently only works for files in root directory.
@@ -412,12 +411,12 @@ static err_t async_load_cache_entry(struct http_cache_entry *e)
     DEBUGPRINT ("pageloading starting with nfs_lookup\n");
     r = nfs_lookup(my_nfs_client, nfs_root_fh, e->name,
                 lookup_callback, e);
-    assert(r == ERR_OK);
-    return ERR_OK;
+    assert(r == SYS_ERR_OK);
+    return SYS_ERR_OK;
 } /* end function : async_load_cache_entry */
 
 
-err_t http_cache_lookup (const char *name, struct http_conn *cs)
+errval_t http_cache_lookup (const char *name, struct http_conn *cs)
 {
     struct http_cache_entry *e;
     assert(cs != NULL);
@@ -428,7 +427,7 @@ err_t http_cache_lookup (const char *name, struct http_conn *cs)
         DEBUGPRINT ("%d: Fresh cache-entry, returning page [%s]\n",
                 cs->request_no, name);
         trigger_callback (cs, e);
-        return ERR_OK;
+        return SYS_ERR_OK;
     } /* end if: valid cacheline */
 
     /* data not in cache */
@@ -446,7 +445,7 @@ err_t http_cache_lookup (const char *name, struct http_conn *cs)
             cs->request_no);
     }
 
-    return ERR_OK;
+    return SYS_ERR_OK;
 } /* end function: http_cache_lookup */
 
 
@@ -481,7 +480,7 @@ static void readdir_callback(void *arg, struct nfs_client *client,
     READDIR3resok *resok = &result->READDIR3res_u.resok;
     struct http_cache_entry *ce;
     entry3 *last = NULL;
-    err_t r;
+    errval_t r;
 
     DEBUGPRINT ("readdir_callback came in\n");
     assert(result != NULL && result->status == NFS3_OK);
@@ -545,7 +544,7 @@ static void readdir_callback(void *arg, struct nfs_client *client,
         assert(last != NULL);
         r = nfs_readdir(client, nfs_root_fh, last->cookie,
                         resok->cookieverf, readdir_callback, NULL);
-        assert(r == ERR_OK);
+        assert(r == SYS_ERR_OK);
     } else {
         readdir_complete = true;
         handle_cache_load_done();
@@ -611,7 +610,7 @@ static void handle_cache_load_done(void)
 
 static void initial_cache_load(struct nfs_client *client)
 {
-    err_t r;
+    errval_t r;
        cache_loading_phase = true;
        cache_lookups_started = 0;
        cache_loaded_counter = 0;
@@ -620,7 +619,7 @@ static void initial_cache_load(struct nfs_client *client)
        //my_nfs_client
     r = nfs_readdir(client, nfs_root_fh, NFS_READDIR_COOKIE,
                          NFS_READDIR_COOKIEVERF, readdir_callback, NULL);
-    assert(r == ERR_OK);
+    assert(r == SYS_ERR_OK);
 }
 
 #endif // PRELOAD_WEB_CACHE
@@ -640,7 +639,7 @@ static void mount_callback(void *arg, struct nfs_client *client,
 #endif // PRELOAD_WEB_CACHE
 } /* end function: mount_callback */
 
-err_t http_cache_init(struct ip_addr server, const char *path,
+errval_t http_cache_init(host_address_t server, const char *path,
                      void (*callback)(void))
 {
     struct timer *cache_timer;      /* timer for triggering cache timeouts */
@@ -661,11 +660,9 @@ err_t http_cache_init(struct ip_addr server, const char *path,
     assert (cache_timer != NULL);
     if (cache_timer == NULL) {
         printf ("http_cache_init failed in timer_create\n");
-        return ERR_MEM;
+        return LWIP_ERR_MEM;
     }
     timer_start(cache_timer);
     DEBUGPRINT ("http_cache_init done\n");
-    return ERR_OK;
+    return SYS_ERR_OK;
 } /* end function: http_cache_init */
-
-
index aaa3030..1bbd798 100644 (file)
@@ -15,9 +15,9 @@
 #ifndef HTTP_CACHE_H
 #define HTTP_CACHE_H
 #include "webserver_session.h"
-err_t http_cache_init (struct ip_addr server, const char *path,
+errval_t http_cache_init (host_address_t server, const char *path,
                      void (*callback)(void));
-err_t http_cache_lookup (const char *name, struct http_conn *cs);
+errval_t http_cache_lookup (const char *name, struct http_conn *cs);
 long decrement_buff_holder_ref (struct buff_holder *bh);
 long decrement_reference (struct http_conn *cs);
 #endif // HTTP_CACHE_H
index f489d6f..5aa6cc4 100644 (file)
 #include <sys/param.h>
 #include <barrelfish/barrelfish.h>
 #include <netinet/in.h>
-#include <lwip/tcp.h>
-#include <lwip/init.h>
+#include <net_sockets/net_sockets.h>
 #include <netbench/netbench.h>
 
+#define LWIP_IPV4
+#include <lwip/ip_addr.h>
+
 #include "http_cache.h"
 #include "webserver_network.h"
 #include "webserver_debug.h"
@@ -167,21 +169,21 @@ static void http_conn_invalidate (struct http_conn *conn)
 }
 
 
-static void http_server_err(void *arg, err_t err)
-{
-    struct http_conn *conn = arg;
-
-    DEBUGPRINT("http_server_err! %p %d\n", arg, err);
-    if(conn != NULL) {
-        DEBUGPRINT("%d: http_server_err! %p %d\n", conn->request_no, arg, err);
-        http_conn_invalidate (conn);
-    } else {
-        DEBUGPRINT("http_server_err! %p %d\n", arg, err);
-    }
-}
-
-
-static void http_server_close(struct tcp_pcb *tpcb, struct http_conn *cs)
+// static void http_server_err(void *arg, errval_t err)
+// {
+//     struct http_conn *conn = arg;
+//
+//     DEBUGPRINT("http_server_err! %p %d\n", arg, err);
+//     if(conn != NULL) {
+//         DEBUGPRINT("%d: http_server_err! %p %d\n", conn->request_no, arg, err);
+//         http_conn_invalidate (conn);
+//     } else {
+//         DEBUGPRINT("http_server_err! %p %d\n", arg, err);
+//     }
+// }
+//
+//
+static void http_server_close(struct net_socket *tpcb, struct http_conn *cs)
 {
 /*
     printf("%s %s %s %hu.%hu.%hu.%hu in %"PU"\n",
@@ -194,40 +196,37 @@ static void http_server_close(struct tcp_pcb *tpcb, struct http_conn *cs)
         cs->request_no);
 
     // replace TCP callbacks with NULL
-    tcp_arg(tpcb, NULL);
-    tcp_sent(tpcb, NULL);
-    tcp_recv(tpcb, NULL);
     if (cs != NULL) {
         http_conn_invalidate (cs);
     }
-    tcp_close(tpcb);
+    net_close(tpcb);
 }
 
-static err_t trysend(struct tcp_pcb *t, const void *data, size_t *len, bool
+static errval_t trysend(struct net_socket *t, const void *data, size_t *len, bool
 more)
 {
-    size_t sendlen = MIN(*len, tcp_sndbuf(t));
-    err_t err;
-
-    do {
-        err = tcp_write(t, data, sendlen,
-                        TCP_WRITE_FLAG_COPY | (more ? TCP_WRITE_FLAG_MORE : 0));
-        if (err == ERR_MEM) {
-            sendlen /= 2;
-            more = true;
-        }
-    } while (err == ERR_MEM && sendlen > 1);
+    size_t sendlen;
+    errval_t err;
 
-    if (err == ERR_OK) {
-        *len = sendlen;
-    }
+    for (sendlen = 0; sendlen < *len;) {
+        void *buffer;
+        size_t s = *len > 1500 ? 1500: *len;
 
-    return err;
+        buffer = net_alloc(s);
+        if (!buffer)
+            break;
+        memcpy(buffer, data + sendlen, s);
+        err = net_send(t, buffer, s);
+        assert(err_is_ok(err));
+        sendlen += s;
+    }
+    *len = sendlen;
+    return SYS_ERR_OK;
 }
 
-static void http_send_data(struct tcp_pcb *tpcb, struct http_conn *conn)
+static void http_send_data(struct net_socket *tpcb, struct http_conn *conn)
 {
-    err_t err;
+    errval_t err;
     const void *data;
     size_t len;
 
@@ -239,7 +238,7 @@ static void http_send_data(struct tcp_pcb *tpcb, struct http_conn *conn)
         data = &conn->header[conn->header_pos];
         len = conn->header_length - conn->header_pos;
         err = trysend(tpcb, data, &len, (conn->hbuff->data != NULL));
-        if (err != ERR_OK) {
+        if (err != SYS_ERR_OK) {
             DEBUGPRINT("http_send_data(): Error %d sending header\n", err);
             return; // will retry
         }
@@ -261,7 +260,7 @@ static void http_send_data(struct tcp_pcb *tpcb, struct http_conn *conn)
         data = conn->hbuff->data +conn->reply_pos; /* pointer arithmatic */
         len = conn->hbuff->len - conn->reply_pos;
         err = trysend(tpcb, data, &len, false);
-        if (err != ERR_OK) {
+        if (err != SYS_ERR_OK) {
             DEBUGPRINT("http_send_data(): Error %d sending payload\n", err);
             return; // will retry
         }
@@ -280,82 +279,74 @@ static void http_send_data(struct tcp_pcb *tpcb, struct http_conn *conn)
 /* This function is called periodically from TCP.
  * and is also responsible for taking care of stale connections.
 **/
-static err_t http_poll(void *arg, struct tcp_pcb *tpcb)
-{
-    struct http_conn *conn = arg;
-
-    if (conn == NULL && tpcb->state == ESTABLISHED) {
-        tcp_abort(tpcb);
-        return ERR_ABRT;
-    } else if (conn != NULL && (conn->state == HTTP_STATE_SENDHEADER
-                                || conn->state == HTTP_STATE_SENDFILE)) {
-        if (++conn->retries == 4) {
-            tcp_arg(tpcb, NULL);
-            DEBUGPRINT ("connection closed, tried too hard\n");
-            http_conn_invalidate (conn);
-            tcp_abort(tpcb);
-            return ERR_ABRT;
-        }
-        http_send_data(tpcb, conn);
-        if (conn->state == HTTP_STATE_CLOSING) {
-            DEBUGPRINT ("%d: http_poll closing the connection\n",
-                    conn->request_no);
-            http_server_close(tpcb, conn);
-        } else {
-            tcp_output(tpcb);
-        }
-    } else if (conn != NULL && (conn->state == HTTP_STATE_NEW
-                                || conn->state == HTTP_STATE_REQUEST)) {
-        /* abort connections that sit open for too long without sending a
-request */
-        if (++conn->retries == 60) {
-            DEBUGPRINT("connection in state %d too long, aborted\n",
-                         conn->state);
-            DEBUGPRINT("connection in state %d too long, aborted\n",
-                        conn->state);
-
-            tcp_arg(tpcb, NULL);
-            http_conn_invalidate (conn);
-            tcp_abort(tpcb);
-            return ERR_ABRT;
-        }
-    }
-    return ERR_OK;
-} /* end function: http_poll */
+// static errval_t http_poll(void *arg, struct net_socket *tpcb)
+// {
+//     struct http_conn *conn = arg;
+//
+//     if (conn == NULL && tpcb->state == ESTABLISHED) {
+//         tcp_abort(tpcb);
+//         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);
+//             return ERR_ABRT;
+//         }
+//         http_send_data(tpcb, conn);
+//         if (conn->state == HTTP_STATE_CLOSING) {
+//             DEBUGPRINT ("%d: http_poll closing the connection\n",
+//                     conn->request_no);
+//             http_server_close(tpcb, conn);
+//         } else {
+//             // tcp_output(tpcb);
+//         }
+//     } else if (conn != NULL && (conn->state == HTTP_STATE_NEW
+//                                 || conn->state == HTTP_STATE_REQUEST)) {
+//         /* abort connections that sit open for too long without sending a
+// request */
+//         if (++conn->retries == 60) {
+//             DEBUGPRINT("connection in state %d too long, aborted\n",
+//                          conn->state);
+//             DEBUGPRINT("connection in state %d too long, aborted\n",
+//                         conn->state);
+//
+//             http_conn_invalidate (conn);
+//             net_delete_socket(tpcb);
+//             return ERR_ABRT;
+//         }
+//     }
+//     return SYS_ERR_OK;
+// } /* end function: http_poll */
 
 /* called when data is successfully sent */
-static err_t http_server_sent(void *arg, struct tcp_pcb *tpcb, u16_t length)
+static void http_server_sent(void *arg, struct net_socket *socket, void *buffer)
 {
     struct http_conn *conn = arg;
 
-    if(conn == NULL) {
-        return ERR_OK;
-    }
-
-    conn->retries = 0;
+    assert(conn);
+    net_free(buffer);
 
     switch(conn->state) {
     case HTTP_STATE_SENDHEADER:
     case HTTP_STATE_SENDFILE:
         // Need to send more data?
-        http_send_data(tpcb, conn);
+        http_send_data(socket, conn);
         if (conn->state != HTTP_STATE_CLOSING) {
-            tcp_output(tpcb);
+            // tcp_output(tpcb);
             break;
         }
 
     case HTTP_STATE_CLOSING:
         DEBUGPRINT("%d: http_server_sent closing the connection\n",
                     conn->request_no);
-        http_server_close(tpcb, conn);
+        http_server_close(socket, conn);
         break;
 
     default:
-        DEBUGPRINT("http_server_sent(): Wrong state! (%d)\n", conn->state);
         break;
     }
-
-    return ERR_OK;
 }
 
 static const void *make_header(const char *uri, size_t *retlen)
@@ -435,29 +426,26 @@ static void send_response(struct http_conn *cs)
                 cs->request_no);
         http_server_close(cs->pcb, cs);
     } else {
-        tcp_sent(cs->pcb, http_server_sent);
-        tcp_output(cs->pcb);
+        // tcp_output(cs->pcb);
     }
 } /* end function: send_response */
 
-static err_t http_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
-                              err_t err)
+// 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)
 {
     struct http_conn *conn = arg;
 
     DEBUGPRINT("%d, http_server_recv called\n", conn->request_no);
-    if (err != ERR_OK) {
-        DEBUGPRINT("http_server_recv called with err %d\n", err);
-        return ERR_OK;
-    }
+    debug_printf("%s(%d): %ld\n", __func__, tpcb->descriptor, size);
 
     // check if connection closed
-    if(conn == NULL) {
-        return ERR_OK;
-    } else if (p == NULL) {
+    assert(conn);
+    if (size == 0) {
         DEBUGPRINT("%d, closing from http_server_recv\n", conn->request_no);
         http_server_close(tpcb, conn);
-        return ERR_OK;
+        return;
     }
 
     switch(conn->state) {
@@ -467,21 +455,17 @@ static err_t http_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
 
     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);
+        // tpcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
 
         /* accumulate the request data */
-        conn->request_length += p->tot_len;
+        conn->request_length += size;
         conn->request = realloc(conn->request, conn->request_length + 1);
-        char *d = conn->request + conn->request_length - p->tot_len;
-
-        for(struct pbuf *pb = p; pb != NULL; pb = pb->next) {
-            memcpy(d, pb->payload, pb->len);
-            tcp_recved(tpcb, pb->len);
-            d += pb->len;
-        }
+        char *d = conn->request + conn->request_length - size;
+        memcpy(d, data, size);
+        d += size;
         *d = '\0';
 
-        pbuf_free(p);
+        // pbuf_free(p);
 
         // have we seen the end of the request yet?
         if (strstr(conn->request, CRLF CRLF) == NULL) {
@@ -525,8 +509,8 @@ static err_t http_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
         conn->pcb = tpcb;
         conn->start_ts = rdtsc();
         /* for callback execution */
-        err_t e = http_cache_lookup(uri, conn);
-        if (e != ERR_OK) {
+        errval_t e = http_cache_lookup(uri, conn);
+        if (e != SYS_ERR_OK) {
             conn->error = 1;
             send_response(conn);
         }
@@ -535,63 +519,54 @@ static err_t http_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
     default:
         DEBUGPRINT("http_server_recv(): data received in wrong state (%d)!\n",
                      conn->state);
-        pbuf_free(p);
         conn->error = 1;
         send_response(conn);
         break;
     }
-    return ERR_OK;
+    return;
 
 invalid:
     DEBUGPRINT("invalid request: %s\n", conn->request);
     DEBUGPRINT("%d: invalid request: %s\n",conn->request_no, conn->request);
     conn->state = HTTP_STATE_CLOSING;
     http_server_close(tpcb, conn);
-    return ERR_OK;
+    return;
 }
 
-static err_t http_server_accept(void *arg, struct tcp_pcb *tpcb, err_t err)
+static void http_server_accept(void *arg, struct net_socket *tpcb, host_address_t ip_address, uint16_t port)
 {
-#if TCP_LISTEN_BACKLOG
-    /* Decrease the listen backlog counter */
-    struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen*)arg;
-    tcp_accepted(lpcb);
-#endif
-
-    tcp_setprio(tpcb, TCP_PRIO_MIN);
-
+// #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);
     struct http_conn *conn = http_conn_new();
-    if (conn == NULL) {
-        DEBUGPRINT("http_accept: Out of memory\n");
-        return ERR_MEM;
-    }
     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 */
 
-    tcp_arg(tpcb, conn);
+    net_set_user_state(tpcb, conn);
+    net_recv(tpcb, http_server_recv);
+    net_set_sent(tpcb, http_server_sent);
 
-    tcp_recv(tpcb, http_server_recv);
-    tcp_err(tpcb, http_server_err);
-    tcp_poll(tpcb, http_poll, 4);
-
-    return ERR_OK;
+    // tcp_err(tpcb, http_server_err);
+    // tcp_poll(tpcb, http_poll, 4);
 }
 
 
 static void realinit(void)
 {
-
     uint64_t ts = rdtsc();
-    struct tcp_pcb *pcb = tcp_new();
+    struct net_socket *pcb = net_tcp_socket();
 //    err_t e = tcp_bind(pcb, IP_ADDR_ANY, (HTTP_PORT + disp_get_core_id()));
-    err_t e = tcp_bind(pcb, IP_ADDR_ANY, HTTP_PORT);
-    assert(e == ERR_OK);
-    pcb = tcp_listen(pcb);
-    assert(pcb != NULL);
-    tcp_arg(pcb, pcb);
-    tcp_accept(pcb, http_server_accept);
+    errval_t e = net_bind(pcb, 0, HTTP_PORT);
+    assert(e == SYS_ERR_OK);
+
+    e = net_listen(pcb, 100);
+    assert(e == SYS_ERR_OK);
+
+    net_accept(pcb, http_server_accept);
     printf("HTTP setup time %"PU"\n", in_seconds(get_time_delta(&ts)));
     printf("#######################################################\n");
     printf("Starting webserver\n");
@@ -599,7 +574,7 @@ static void realinit(void)
 
 }
 
-void http_server_init(struct ip_addr server, const char *path)
+void http_server_init(host_address_t server, const char *path)
 {
     http_cache_init(server, path, realinit);
 }
index ea5f442..83a12c4 100644 (file)
 #include <barrelfish/waitset.h>
 #include <barrelfish/nameservice_client.h>
 #include <stdio.h>
-#include <lwip/netif.h>
-#include <lwip/dhcp.h>
 #include <netif/etharp.h>
-#include <lwip/init.h>
-#include <lwip/tcp.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>
+// #include <lwip/init.h>
+// #include <lwip/tcp.h>
 
 #include "webserver_network.h"
 #include "webserver_debug.h"
@@ -43,53 +45,36 @@ int main(int argc, char**argv)
     errval_t err;
 
     // Parse args
-    if (argc != 4) {
+    if (argc != 3) {
         printf("Usage: %s CardName NFSIP NFSpath\n", argv[0]);
         return 1;
     }
 //    char *card_name = argv[1];
 
     struct in_addr server1;
-    if (inet_aton(argv[2], &server1) == 0) {
-        printf("Invalid IP addr: %s\n", argv[2]);
+    if (inet_aton(argv[1], &server1) == 0) {
+        printf("Invalid IP addr: %s\n", argv[1]);
         return 1;
     }
     serverip.addr = server1.s_addr; // XXX
-    serverpath = argv[3];
+    serverpath = argv[2];
 
     // Boot up
     DEBUGPRINT("init start\n");
 
     DEBUGPRINT("lwip_demo: lwip setup\n");
     printf("webserver:%u: initializing networking \n", disp_get_core_id());
-    if (lwip_init_auto() == false) {
-        printf("ERROR: lwip_init_auto failed!\n");
-        return 1;
-    }
+    net_sockets_init();
     printf("webserver:%u: networking initialized\n", disp_get_core_id());
 
 //    lwip_benchmark_control(1, BMS_START_REQUEST, 0, 0);
-    http_server_init(serverip, serverpath);
+    http_server_init(serverip.addr, serverpath);
 
     DEBUGPRINT("Init finished.\n");
 
     uint32_t eventcount = 0;
     struct waitset *ws = get_default_waitset();
     while (1) {
-        // check for any event without blocking
-        //err = event_dispatch_non_block(ws);
-        err = event_dispatch_non_block(ws);
-        if (err != LIB_ERR_NO_EVENT) {
-            if (err_is_fail(err)) {
-                DEBUG_ERR(err, "in event_dispatch");
-                break;
-            }
-        }
-
-//        printf("webserver:%u:  dispatching next event\n", disp_get_core_id());
-
-        // Check if lwip has any pending work to finish
-        wrapper_perform_lwip_work();
         err = event_dispatch(ws);
         if (err_is_fail(err)) {
             DEBUG_ERR(err, "in event_dispatch");
index 548388e..a90b600 100644 (file)
@@ -15,6 +15,6 @@
 #ifndef WEBSERVER_NETWORK_H
 #define WEBSERVER_NETWORK_H
 
-void http_server_init(struct ip_addr server, const char *path);
+void http_server_init(host_address_t server, const char *path);
 
 #endif // WEBSERVER_NETWORK_H
index 6654654..17b7875 100644 (file)
@@ -51,7 +51,7 @@ struct http_conn {
     int                 retries;
     int                 error; /*flag for internal errors */
     char                *filename;     /* name of the requested file */
-    struct tcp_pcb      *pcb;
+    struct net_socket   *pcb;
     void (*callback) (struct http_conn *);
     int                 mark_invalid;     /* is it marked for delete? */
     long                ref_count;
@@ -59,7 +59,7 @@ struct http_conn {
 };
 
 
-err_t http_fetch_file(const char *name, struct http_conn *cs);
+errval_t http_fetch_file(const char *name, struct http_conn *cs);
 long decrement_http_conn_reference (struct http_conn *cs);
 long increment_http_conn_reference (struct http_conn *cs);
 #endif // WEBSERVER_SESSION_H