]> Zhao Yanbai Git Server - minix.git/commitdiff
LWIP,NETSOCK - lwip uses asynchronous protocol
authorTomas Hruby <tom@minix3.org>
Fri, 24 Feb 2012 18:02:32 +0000 (18:02 +0000)
committerTomas Hruby <tom@minix3.org>
Fri, 2 Mar 2012 15:44:48 +0000 (15:44 +0000)
- libnetsock - internal implementation of a socket on the lwip
  server side. it encapsulates the asynchronous protocol

- lwip server - uses libnetsock to work with the asynchronous
  protocol

13 files changed:
etc/usr/rc
include/Makefile.minix.inc
include/minix/netsock.h [moved from servers/lwip/socket.h with 76% similarity]
lib/Makefile
lib/libnetsock/Makefile [new file with mode: 0644]
lib/libnetsock/socket.c [moved from servers/lwip/socket.c with 54% similarity]
servers/lwip/Makefile
servers/lwip/driver.c
servers/lwip/inet_config.c
servers/lwip/lwip.c
servers/lwip/raw_ip.c
servers/lwip/tcp.c
servers/lwip/udp.c

index 71042a13cf9cb1ddb9c38e22c0b3fe4220e06178..ed154cbd6971366fda57b0463a6131186f0c2c85 100644 (file)
@@ -138,7 +138,7 @@ start)
     done
     if [ X`/bin/sysenv lwip` = Xyes ]
     then
-       up lwip -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
+       up lwip -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE_A
     else
        up inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
     fi
index a9bd5d6e4225571ae52ce5844fece008f785ff65..03d3cc2e1c726f8b0e4efb48fe9440cc965900f3 100644 (file)
@@ -18,7 +18,8 @@ INCS+=        minix/acpi.h minix/ansi.h minix/audio_fw.h minix/bitmap.h \
        minix/sound.h minix/spin.h minix/sys_config.h minix/sysinfo.h \
        minix/syslib.h minix/sysutil.h minix/timers.h minix/type.h \
        minix/tty.h minix/u64.h minix/usb.h minix/usb_ch9.h minix/vm.h \
-       minix/vfsif.h minix/vtreefs.h minix/libminixfs.h
+       minix/vfsif.h minix/vtreefs.h minix/libminixfs.h \
+       minix/netsock.h
 
 INCS+= net/gen/arp_io.h net/gen/dhcp.h net/gen/ether.h \
        net/gen/eth_hdr.h net/gen/eth_io.h net/gen/icmp.h \
similarity index 76%
rename from servers/lwip/socket.h
rename to include/minix/netsock.h
index bddcd656a456d2b7715fbd9a008d3e88291b131a..c341cc2fd1b2adf3f4d4fbb5fdc0acacf0470b5b 100644 (file)
@@ -1,11 +1,16 @@
-#ifndef __LWIP_SERVER_SOCKET_H__
-#define __LWIP_SERVER_SOCKET_H__
+#ifndef __NET_SERVER_SOCKET_H__
+#define __NET_SERVER_SOCKET_H__
+
+#include <stdlib.h>
 
 #include <minix/ipc.h>
 #include <minix/endpoint.h>
 
-#include "inet_config.h"
-#include "proto.h"
+/*
+ * User can set this variable to make the debugging output differ between
+ * various users, e.g. "TCP" or "UDP"
+ */
+extern char * netsock_user_name;
 
 #define SOCK_TYPE_IP   0
 #define SOCK_TYPE_TCP  1
 struct socket;
 
 typedef void (* sock_op_t)(struct socket *, message *);
+typedef void (* sock_op_io_t)(struct socket *, message *, int blk);
 typedef int (* sock_op_open_t)(struct socket *, message *);
 
 struct sock_ops {
        sock_op_open_t  open;
        sock_op_t       close;
-       sock_op_t       read;
-       sock_op_t       write;
-       sock_op_t       ioctl;
+       sock_op_io_t    read;
+       sock_op_io_t    write;
+       sock_op_io_t    ioctl;
        sock_op_t       select;
        sock_op_t       select_reply;
 };
@@ -33,8 +39,7 @@ struct recv_q {
 };
 
 #define SOCK_FLG_OP_PENDING    0x1
-#define SOCK_FLG_OP_REVIVING   0x2
-#define SOCK_FLG_OP_SUSPENDED  0x4     /* set when processing a suspended op */
+#define SOCK_FLG_OP_IOCTL      0x10
 #define SOCK_FLG_OP_LISTENING  0x100   /* tcp socket is in a listening mode */
 #define        SOCK_FLG_OP_CONNECTING  0x200   /* set when waiting for a connect */
 #define SOCK_FLG_OP_READING    0x400   /* reading operation in progress */
@@ -45,7 +50,6 @@ struct recv_q {
 #define SOCK_FLG_SEL_WRITE     0x100000
 #define SOCK_FLG_SEL_READ      0x200000
 #define SOCK_FLG_SEL_ERROR     0x400000
-#define SOCK_FLG_SEL_CHECK     0x800000 /* select satisfied, go and check it */
 
 #define sock_select_set(sock)  ((sock)->flags & (SOCK_FLG_SEL_WRITE |  \
                                SOCK_FLG_SEL_READ | SOCK_FLG_SEL_ERROR))
@@ -54,10 +58,9 @@ struct recv_q {
 #define sock_select_rw_set(sock)       ((sock)->flags & (SOCK_FLG_SEL_READ | \
                                                        SOCK_FLG_SEL_WRITE))
 #define sock_select_error_set(sock)    ((sock)->flags & SOCK_FLG_SEL_ERROR)
-#define sock_select_check_set(sock)    ((sock)->flags & SOCK_FLG_SEL_CHECK)
 #define sock_clear_select(sock)        do {                                    \
        (sock)->flags &= ~(SOCK_FLG_SEL_READ | SOCK_FLG_SEL_WRITE |     \
-                       SOCK_FLG_SEL_ERROR | SOCK_FLG_SEL_CHECK);       \
+                                               SOCK_FLG_SEL_ERROR);    \
 } while (0)
 
 struct socket {
@@ -71,6 +74,8 @@ struct socket {
        message                 mess; /* store the message which initiated the
                                         last operation on this socket in case
                                         we have to suspend the operation */
+       void *                  shm;
+       size_t                  shm_size;
        endpoint_t              select_ep;
        struct recv_q *         recv_head;
        struct recv_q *         recv_tail;
@@ -78,9 +83,11 @@ struct socket {
        void *                  data;
 };
 
-extern struct sock_ops sock_udp_ops;
-extern struct sock_ops sock_tcp_ops;
-extern struct sock_ops sock_raw_ip_ops;
+/*
+ * Each component needs to provide a method how to initially open a socket.
+ * The rest is handled byt the socket library.
+ */
+void socket_open(message * m);
 
 #define get_sock_num(x) ((long int) ((x) - socket))
 #define is_valid_sock_num(x) (x < MAX_SOCKETS)
@@ -101,8 +108,11 @@ struct socket * get_unused_sock(void);
 struct socket * get_nic_sock(unsigned dev);
 
 void send_reply(message * m, int status);
+void send_reply_open(message * m, int status);
+void send_reply_close(message * m, int status);
 void sock_reply(struct socket * sock, int status);
-void sock_revive(struct socket * sock, int status);
+void sock_reply_close(struct socket * sock, int status);
+void sock_reply_select(struct socket * sock, unsigned selops);
 
 typedef void (* recv_data_free_fn)(void *);
 
@@ -132,4 +142,9 @@ static inline void * debug_malloc(size_t s)
 void generic_op_select(struct socket * sock, message * m);
 void generic_op_select_reply(struct socket * sock, message * m);
 
-#endif /* __LWIP_SERVER_SOCKET_H__ */
+int mq_enqueue(message * m);
+
+/* a function thr user has to provide to reply to the posix server */
+void posix_reply(endpoint_t ep, message * m);
+
+#endif /* __NET_SERVER_SOCKET_H__ */
index 83aa2db6b50db7e7533c36827ffae1c90c3fdf85..93f203dbf98ae9c546dbfc15d108106bb0ed545c 100644 (file)
@@ -5,7 +5,8 @@ SUBDIR= csu libcompat_minix libc libblockdriver libchardriver     \
        libl libhgfs libz libfetch libvtreefs libaudiodriver libmthread   \
        libexec libdevman libusb libminlib libasyn          \
        libddekit libminixfs libbdev libelf libminc libcrypt libterminfo \
-       libcurses libvassert libutil libpuffs librefuse libbz2 libarchive libprop
+       libcurses libvassert libutil libpuffs librefuse libbz2 libarchive libprop \
+       libnetsock
 
 SUBDIR+=        ../external/public-domain/xz/lib
 
diff --git a/lib/libnetsock/Makefile b/lib/libnetsock/Makefile
new file mode 100644 (file)
index 0000000..4da9229
--- /dev/null
@@ -0,0 +1,9 @@
+LIB = netsock
+
+CPPFLAGS += -I${.CURDIR}/include/ -D_SYSTEM -D_MINIX
+CPPFLAGS+= -I${.CURDIR}/../../lib/liblwip/include
+CFLAGS += -Wall -Wextra -std=c99
+
+SRCS += socket.c
+
+.include <bsd.lib.mk>
similarity index 54%
rename from servers/lwip/socket.c
rename to lib/libnetsock/socket.c
index 75be4a275bc1e51e390638a92a5eecdb6a648e11..96f0000e724a2100fefd1adc7efdefd7b32e6038 100644 (file)
 #include <minix/com.h>
 #include <minix/callnr.h>
 #include <minix/sysutil.h>
+#include <minix/netsock.h>
 
 #include <lwip/tcp.h>
 
 #include <sys/ioc_net.h>
 
-#include "inet_config.h"
-#include "proto.h"
-#include "socket.h"
+char * netsock_user_name = NULL;
+#define NETSOCK_USER_NAME (netsock_user_name ? netsock_user_name : "NETSOCK")
+
+#define debug_print(str, ...) printf("%s : %s:%d : " str "\n", \
+               NETSOCK_USER_NAME, __func__, __LINE__, ##__VA_ARGS__)
 
 #if 0
-#define debug_sock_print(str, ...) printf("LWIP %s:%d : " str "\n", \
-               __func__, __LINE__, ##__VA_ARGS__)
+#define debug_sock_print(...)  debug_print(__VA_ARGS__)
 #else
-#define debug_sock_print(...) debug_print(__VA_ARGS__)
+#define debug_sock_print(...)
 #endif
 
+#if 0
+#define debug_sock_select_print(...)   debug_print(__VA_ARGS__)
+#else
+#define debug_sock_select_print(...)   debug_sock_print(__VA_ARGS__)
+#endif
+
+#define netsock_panic(str, ...) panic("%s : " str, NETSOCK_USER_NAME, \
+                                                       ##__VA_ARGS__)
+#define netsock_error(str, ...) printf("%s : " str, NETSOCK_USER_NAME, \
+                                                       ##__VA_ARGS__)
+
 
 struct socket socket[MAX_SOCKETS];
-static int notified;
 
 #define recv_q_alloc() debug_malloc(sizeof(struct recv_q))
 #define recv_q_free    debug_free
@@ -44,7 +56,7 @@ struct mq {
 
 static struct mq * mq_head, *mq_tail;
 
-static int mq_enqueue(message * m)
+int mq_enqueue(message * m)
 {
        struct mq * mq;
 
@@ -84,7 +96,7 @@ __unused static struct mq * mq_dequeue_head(void)
                mq_head->prev = NULL;
        } else
                mq_head = mq_tail = NULL;
-       
+
        debug_sock_print("socket %d\n", ret->m.DEVICE);
 
        return ret;
@@ -121,8 +133,10 @@ static int mq_cancel(message * m)
                }
        }
 
-       mq_dequeue(mq);
-       mq_free(mq);
+       if (mq) {
+               mq_dequeue(mq);
+               mq_free(mq);
+       }
 
        return 1;
 }
@@ -189,270 +203,141 @@ static void set_reply_msg(message * m, int status)
        m->REP_IO_GRANT= ref;
 }
 
-void send_reply(message * m, int status)
+void send_reply_type(message * m, int type, int status)
 {
        int result;
 
-       debug_sock_print("status %d", status);
        set_reply_msg(m, status);
-       
-       m->m_type = TASK_REPLY;
+
+       m->m_type = type;
        result = send(m->m_source, m);
        if (result != OK)
-               panic("LWIP : unable to send (err %d)", result);
+               netsock_panic("unable to send (err %d)", result);
 }
 
-void sock_revive(struct socket * sock, int status)
+void send_reply(message * m, int status)
+{
+       debug_sock_print("status %d", status);
+       send_reply_type(m, DEV_REVIVE, status);
+}
+
+void send_reply_open(message * m, int status)
+{
+       debug_sock_print("status %d", status);
+       send_reply_type(m, DEV_OPEN_REPL, status);
+}
+
+void send_reply_close(message * m, int status)
+{
+       debug_sock_print("status %d", status);
+       send_reply_type(m, DEV_CLOSE_REPL, status);
+}
+
+void sock_reply_select(struct socket * sock, unsigned selops)
 {
        int result;
+       message msg;
 
-       assert(!(sock->flags & SOCK_FLG_OP_REVIVING));
-       assert(sock->flags & (SOCK_FLG_OP_PENDING | SOCK_FLG_OP_SUSPENDED));
+       debug_sock_select_print("selops %d", selops);
 
-       if (notified) {
-               debug_sock_print("already notified");
-               return;
-       }
-       else {
-               assert(sock->mess.m_type != DEV_REVIVE);
-               notified = 1;
-       }
-       
-       debug_sock_print("socket num %ld, status %d",
-                       get_sock_num(sock), status);
-
-       sock->mess.m_type = DEV_REVIVE;
-       set_reply_msg(&sock->mess, status);
-       
-       result = notify(sock->mess.m_source);
-       if (result != OK)
-               panic("LWIP : unable to notify (err %d)", result);
+       msg.m_type = DEV_SEL_REPL1;
+       msg.DEV_MINOR = get_sock_num(sock);
+       msg.DEV_SEL_OPS = selops;
 
-       sock->flags |= SOCK_FLG_OP_REVIVING;
+       result = send(sock->select_ep, &msg);
+       if (result != OK)
+               netsock_panic("unable to send (err %d)", result);
 }
 
 void sock_select_notify(struct socket * sock)
 {
        int result;
+       message msg;
 
-       debug_sock_print("socket num %ld", get_sock_num(sock));
+       debug_sock_select_print("socket num %ld", get_sock_num(sock));
        assert(sock->select_ep != NONE);
 
-       sock->flags |= SOCK_FLG_SEL_CHECK;
-       if (notified) {
-               debug_sock_print("already notified");
+       msg.DEV_SEL_OPS = 0;
+       sock->ops->select_reply(sock, &msg);
+       if (msg.DEV_SEL_OPS == 0) {
+               debug_sock_select_print("called from %p sflags 0x%x TXsz %d RXsz %d\n",
+                               __builtin_return_address(0), sock->flags,
+                               sock->buf_size, sock->recv_data_size);
                return;
        }
-       else
-               notified = 1;
-       
-       result = notify(sock->select_ep);
+
+       msg.m_type = DEV_SEL_REPL2;
+       msg.DEV_MINOR = get_sock_num(sock);
+
+       debug_sock_select_print("socket num %d select result 0x%x sent",
+                       msg.DEV_MINOR, msg.DEV_SEL_OPS);
+       result = send(sock->select_ep, &msg);
        if (result != OK)
-               panic("LWIP : unable to notify (err %d)", result);
-}
+               netsock_panic("unable to send (err %d)", result);
 
-void sock_reply(struct socket * sock, int status)
-{
-       debug_sock_print("socket num %ld status %d type %d",
-                       get_sock_num(sock), status, sock->mess.m_type);
-       /*
-        * If the status is SUSPEND send the
-        * message only if this operation wasn't
-        * suspended already, e.g. by enqueing the
-        * message when the socket was busy
-        * because of another pending message
-        *
-        * If there is a pending operation or we a reprocessing a suspended
-        * operation, revive.
-        *
-        * Otherwise send a message straightaway
-        */
-       if (status == SUSPEND) {
-               if (sock->flags & SOCK_FLG_OP_SUSPENDED) {
-                       debug_sock_print("suspended before");
-                       sock->flags &= ~SOCK_FLG_OP_SUSPENDED;
-                       return;
-               }
-               message m = sock->mess;
-               debug_sock_print("SUSPEND");
-               send_reply(&m, status);
-       } else if (sock->flags & (SOCK_FLG_OP_PENDING | SOCK_FLG_OP_SUSPENDED)) {
-               sock_revive(sock, status);
-               /*
-                * From now on, we process suspended calls as any other. The
-                * status is set and will be collected
-                */
-               sock->flags &= ~SOCK_FLG_OP_SUSPENDED;
-       } else
-               send_reply(&sock->mess, status);
+       sock_clear_select(sock);
+       sock->select_ep = NONE;
 }
 
-struct socket * get_unused_sock(void)
+static void sock_reply_type(struct socket * sock, int type, int status)
 {
-       int i;
+       sock->mess.m_type = type;
 
-       for (i = SOCK_TYPES + MAX_DEVS; i < MAX_SOCKETS; i++) {
-               if (socket[i].ops == NULL) {
-                       /* clear it all */
-                       memset(&socket[i], 0, sizeof(struct socket));
-                       return &socket[i];
-               }
-       }
-
-       return NULL;
+       send_reply_type(&sock->mess, type, status);
 }
 
-struct socket * get_nic_sock(unsigned dev)
+void sock_reply_close(struct socket * sock, int status)
 {
-       if (dev < MAX_DEVS)
-               return &socket[dev + SOCK_TYPES];
-       else
-               return NULL;
+       debug_sock_print("sock %ld status %d", get_sock_num(sock), status);
+       sock_reply_type(sock, DEV_CLOSE_REPL, status);
 }
 
-static void socket_open(message * m)
+void sock_reply(struct socket * sock, int status)
 {
-       struct sock_ops * ops;
-       struct socket * sock;
-       int ret = OK;
-
-       switch (m->DEVICE) {
-       case SOCK_TYPE_TCP:
-               ops = &sock_tcp_ops;
-               break;
-       case SOCK_TYPE_UDP:
-               ops = &sock_udp_ops;
-               break;
-       case SOCK_TYPE_IP:
-               ops = &sock_raw_ip_ops;
-               break;
-       default:
-               if (m->DEVICE - SOCK_TYPES  < MAX_DEVS) {
-                       m->DEVICE -= SOCK_TYPES;
-                       nic_open(m);
-                       return;
-               }
-               printf("LWIP unknown socket type %d\n", m->DEVICE);
-               send_reply(m, EINVAL);
-               return;
-       }
-       
-       sock = get_unused_sock();
-       if (!sock) {
-               printf("LWIP : no free socket\n");
-               send_reply(m, EAGAIN);
-               return;
-       }
-
-       sock->ops = ops;
-       sock->select_ep = NONE;
-       sock->recv_data_size = 0;
-
-       if (sock->ops && sock->ops->open)
-               ret = sock->ops->open(sock, m);
-       
-       if (ret == OK) {
-               debug_sock_print("new socket %ld", get_sock_num(sock));
-               send_reply(m, get_sock_num(sock));
-       } else {
-               debug_sock_print("failed %d", ret);
-               send_reply(m, ret);
-       }
+       debug_sock_print("sock %ld status %d", get_sock_num(sock), status);
+       sock_reply_type(sock, DEV_REVIVE, status);
 }
 
-static void do_status(message * m)
+struct socket * get_unused_sock(void)
 {
        int i;
 
-       debug_sock_print("called");
-
-       notified = 0;
-
-       for (i = 0; i < MAX_SOCKETS; i++) {
-               struct socket * sock = &socket[i];
-               if (!sock->ops) {
-                       continue;
-               }
-               if (sock->flags & (SOCK_FLG_OP_REVIVING)) {
-                       /*
-                        * We send the reply and we are done with this request
-                        */
-                       debug_sock_print("status %d ep %d sent sock %ld type %d", 
-                                       sock->mess.REP_STATUS,
-                                       sock->mess.REP_ENDPT,
-                                       get_sock_num(sock),
-                                       sock->mess.m_type);
-                       send(m->m_source, &sock->mess);
-                       /*
-                        * Remove only the reviving flag, i.e. the status has
-                        * been consumed. SOCK_FLG_OP_PENDING may stay set. For
-                        * instance in case of a TCP write, the application is
-                        * already notified while the process of sending is
-                        * still going on
-                        */
-                       sock->flags &= ~SOCK_FLG_OP_REVIVING;
-                       return;
-               }
-
-               /*
-                * We check select AFTER possible reviving an operation,
-                * otherwise the select will fail as the socket is still
-                * blocking
-                */
-               if (sock_select_check_set(sock)) {
-                       if (sock->ops && sock->ops->select_reply) {
-                               message msg;
-                               msg.m_type = DEV_IO_READY;
-                               msg.DEV_MINOR = get_sock_num(sock);
-                               msg.DEV_SEL_OPS = 0;
-                               sock->ops->select_reply(sock, &msg);
-                               if (msg.DEV_SEL_OPS) {
-                                       int result;
-
-                                       debug_sock_print("socket num %d select "
-                                               "result 0x%x sent",
-                                               msg.DEV_MINOR,
-                                               msg.DEV_SEL_OPS);
-                                       result = send(sock->select_ep, &msg);
-                                       if (result != OK)
-                                               panic("LWIP : unable to send "
-                                                       "(err %d)", result);
-                                       sock_clear_select(sock);
-                                       sock->select_ep = NONE;
-                                       return;
-                               }
-                       }
+       for (i = SOCK_TYPES + MAX_DEVS; i < MAX_SOCKETS; i++) {
+               if (socket[i].ops == NULL) {
+                       /* clear it all */
+                       memset(&socket[i], 0, sizeof(struct socket));
+                       return &socket[i];
                }
        }
 
-       debug_sock_print("no status");
-       m->m_type = DEV_NO_STATUS;
-       send(m->m_source, m);
+       return NULL;
 }
 
 static void socket_request_socket(struct socket * sock, message * m)
 {
+       int blocking = m->FLAGS & FLG_OP_NONBLOCK ? 0 : 1;
+
        switch (m->m_type) {
        case DEV_READ_S:
                if (sock && sock->ops && sock->ops->read)
-                       sock->ops->read(sock, m);
+                       sock->ops->read(sock, m, blocking);
                else
                        send_reply(m, EINVAL);
                return;
        case DEV_WRITE_S:
                if (sock && sock->ops && sock->ops->write)
-                       sock->ops->write(sock, m);
+                       sock->ops->write(sock, m, blocking);
                else
                        send_reply(m, EINVAL);
                return;
        case DEV_IOCTL_S:
                if (sock && sock->ops && sock->ops->ioctl)
-                       sock->ops->ioctl(sock, m);
+                       sock->ops->ioctl(sock, m, blocking);
                else
                        send_reply(m, EINVAL);
                return;
        default:
-               panic("LWIP : cannot happen!");
+               netsock_panic("cannot happen!");
        }
 }
 
@@ -460,6 +345,7 @@ void socket_request(message * m)
 {
        struct socket * sock;
 
+       debug_sock_print("request %d", m->m_type);
        switch (m->m_type) {
        case DEV_OPEN:
                socket_open(m);
@@ -471,7 +357,7 @@ void socket_request(message * m)
                        sock->mess = *m;
                        sock->ops->close(sock, m);
                } else
-                       send_reply(m, EINVAL);
+                       send_reply_close(m, EINVAL);
                return;
        case DEV_READ_S:
        case DEV_WRITE_S:
@@ -485,7 +371,7 @@ void socket_request(message * m)
                 * If an operation is pending (blocking operation) or writing is
                 * still going and we want to read, suspend the new operation
                 */
-               if ((sock->flags & (SOCK_FLG_OP_PENDING | SOCK_FLG_OP_REVIVING)) |
+               if ((sock->flags & SOCK_FLG_OP_PENDING) ||
                                (m->m_type == DEV_READ_S &&
                                 sock->flags & SOCK_FLG_OP_WRITING)) {
                        char * o = "\0";
@@ -495,11 +381,9 @@ void socket_request(message * m)
                                o = "WRITE";
                        else
                                o = "non R/W op";
-                       debug_sock_print("socket %ld is busy by %s\n",
-                                       get_sock_num(sock), o);
-                       if (mq_enqueue(m) == 0) {
-                               send_reply(m, SUSPEND);
-                       } else {
+                       debug_sock_print("socket %ld is busy by %s flgs 0x%x\n",
+                                       get_sock_num(sock), o, sock->flags);
+                       if (mq_enqueue(m) != 0) {
                                debug_sock_print("Enqueuing suspended "
                                                        "call failed");
                                send_reply(m, ENOMEM);
@@ -511,6 +395,7 @@ void socket_request(message * m)
                return;
        case CANCEL:
                sock = get_sock(m->DEVICE);
+               printf("socket num %ld\n", get_sock_num(sock));
                debug_sock_print("socket num %ld", get_sock_num(sock));
                /* Cancel the last operation in the queue */
                if (mq_cancel(m)) {
@@ -522,37 +407,28 @@ void socket_request(message * m)
                        sock->flags &= ~SOCK_FLG_OP_PENDING;
                        send_reply(m, EINTR);
                        return;
-               /*
-                * .. or return the status of the operation which was finished
-                * before canceled
-                */
-               } else if (sock->flags & SOCK_FLG_OP_REVIVING) {
-                       sock->flags &= ~SOCK_FLG_OP_REVIVING;
-                       send_reply(m, sock->mess.REP_STATUS);
                } else
-                       panic("LWIP : no operation to cancel");
+                       netsock_panic("no operation to cancel");
 
                return;
        case DEV_SELECT:
-               /* 
+               /*
                 * Select is always executed immediately and is never suspended.
                 * Although, it sets actions which must be monitored
                 */
                sock = get_sock(m->DEVICE);
                assert(sock->select_ep == NONE || sock->select_ep == m->m_source);
-               
+
                if (sock && sock->ops && sock->ops->select) {
+                       sock->select_ep = m->m_source;
                        sock->ops->select(sock, m);
-                       if (sock_select_set(sock))
-                               sock->select_ep = m->m_source;
+                       if (!sock_select_set(sock))
+                               sock->select_ep = NONE;
                } else
                        send_reply(m, EINVAL);
                return;
-       case DEV_STATUS:
-               do_status(m);
-               return;
        default:
-               printf("LWIP : unknown message from VFS, type %d\n",
+               netsock_error("unknown message from VFS, type %d\n",
                                                        m->m_type);
        }
        send_reply(m, EGENERIC);
@@ -567,13 +443,11 @@ void mq_process(void)
 
        while(mq) {
                struct mq * next = mq->next;
-       
+
                sock = get_sock(mq->m.DEVICE);
-               if (!(sock->flags &
-                               (SOCK_FLG_OP_PENDING | SOCK_FLG_OP_REVIVING)) &&
+               if (!(sock->flags & SOCK_FLG_OP_PENDING) &&
                                !(mq->m.m_type == DEV_READ_S &&
-                                sock->flags & SOCK_FLG_OP_WRITING)) {
-                       sock->flags = SOCK_FLG_OP_SUSPENDED;
+                                       sock->flags & SOCK_FLG_OP_WRITING)) {
                        debug_sock_print("resuming op on sock %ld\n",
                                        get_sock_num(sock));
                        sock->mess = mq->m;
@@ -591,7 +465,7 @@ void generic_op_select(struct socket * sock, message * m)
 {
        int retsel = 0, sel;
 
-       debug_print("socket num %ld 0x%x", get_sock_num(sock), m->USER_ENDPT);
+       debug_sock_print("socket num %ld 0x%x", get_sock_num(sock), m->USER_ENDPT);
 
        sel = m->USER_ENDPT;
 
@@ -604,7 +478,7 @@ void generic_op_select(struct socket * sock, message * m)
                                sock->flags |= SOCK_FLG_SEL_WRITE;
                        /* FIXME we do not monitor error */
                }
-               send_reply(m, 0);
+               sock_reply_select(sock, 0);
                return;
        }
 
@@ -619,26 +493,26 @@ void generic_op_select(struct socket * sock, message * m)
                retsel |= SEL_WR;
        /* FIXME SEL_ERR is ignored, we do not generate exceptions */
 
-       send_reply(m, retsel);
+       sock_reply_select(sock, retsel);
 }
 
 void generic_op_select_reply(struct socket * sock, __unused message * m)
 {
        assert(sock->select_ep != NONE);
-       debug_print("socket num %ld", get_sock_num(sock));
+       debug_sock_print("socket num %ld", get_sock_num(sock));
 
        /* unused for generic packet socket, see generic_op_select() */
        assert((sock->flags & (SOCK_FLG_SEL_WRITE | SOCK_FLG_SEL_ERROR)) == 0);
 
-       if (sock->flags & (SOCK_FLG_OP_PENDING | SOCK_FLG_OP_REVIVING)) {
-               debug_print("WARNING socket still blocking!");
+       if (sock->flags & SOCK_FLG_OP_PENDING) {
+               debug_sock_print("WARNING socket still blocking!");
                return;
        }
 
        if (sock->flags & SOCK_FLG_SEL_READ && sock->recv_head)
                m->DEV_SEL_OPS |= SEL_RD;
-       
-       if (m->DEV_SEL_OPS) 
+
+       if (m->DEV_SEL_OPS)
                sock->flags &= ~(SOCK_FLG_SEL_WRITE | SOCK_FLG_SEL_READ |
                                                        SOCK_FLG_SEL_ERROR);
 }
index a188b417e6fae76f7731dd17c79868062f810e10..cc69124964a40711f73307533b1e406e529e11da 100644 (file)
@@ -1,7 +1,6 @@
 # Makefile for inet.
 PROG=  lwip
 SRCS=  lwip.c          \
-       socket.c        \
        driver.c        \
        udp.c           \
        tcp.c           \
@@ -11,8 +10,8 @@ SRCS= lwip.c          \
 
 .PATH: ${.CURDIR}/generic
 
-DPADD+=        ${LIBCHARDRIVER} ${LIBSYS} ${LIBTIMERS} ${LIBLWIP}
-LDADD+=        -lchardriver -lsys -ltimers -llwip
+DPADD+=        ${LIBCHARDRIVER} ${LIBSYS} ${LIBTIMERS} ${LIBLWIP} ${LIBNETSOCK}
+LDADD+=        -lchardriver -lsys -ltimers -llwip -lnetsock
 
 MAN=
 
index dd912c584a7562eb86f88755ef494f623c5485e2..a1c5a531810a6bf13963e05692a018166ebace7e 100644 (file)
@@ -9,6 +9,7 @@
 #include <minix/com.h>
 #include <minix/sysutil.h>
 #include <minix/safecopies.h>
+#include <minix/netsock.h>
 
 #include <sys/ioc_net.h>
 #include <net/gen/in.h>
@@ -22,7 +23,6 @@
 #include <netif/etharp.h>
 
 #include "proto.h"
-#include "socket.h"
 #include "driver.h"
 
 #if 0
@@ -303,11 +303,11 @@ int raw_socket_input(struct pbuf * pbuf, struct nic * nic)
                ret = raw_receive(&sock->mess, pbuf);
 
                if (ret > 0) {
-                       sock_revive(sock, ret);
+                       sock_reply(sock, ret);
                        sock->flags &= ~SOCK_FLG_OP_PENDING;
                        return 0;
                } else {
-                       sock_revive(sock, ret);
+                       sock_reply(sock, ret);
                        sock->flags &= ~SOCK_FLG_OP_PENDING;
                }
        }
@@ -456,7 +456,7 @@ static void nic_op_close(struct socket * sock, __unused message * m)
                debug_drv_print("no active raw sock at %s", nic->name);
        }
 
-       sock_reply(sock, OK);
+       sock_reply_close(sock, OK);
 }
 
 static void nic_ioctl_set_conf(__unused struct socket * sock,
@@ -643,12 +643,12 @@ void nic_default_ioctl(message *m)
        nic_do_ioctl(NULL, nic, m);
 }
 
-static void nic_op_ioctl(struct socket * sock, message * m)
+static void nic_op_ioctl(struct socket * sock, message * m, __unused int blk)
 {
        nic_do_ioctl(sock, (struct nic *)sock->data, m);
 }
 
-static void nic_op_read(struct socket * sock, message * m)
+static void nic_op_read(struct socket * sock, message * m, int blk)
 {
        debug_drv_print("sock num %d", get_sock_num(sock));
 
@@ -668,18 +668,19 @@ static void nic_op_read(struct socket * sock, message * m)
                        pbuf_free(pbuf);
                }
                sock_reply(sock, ret);
-       } else {
+       } else if (!blk)
+               send_reply(m, EAGAIN);
+       else {
                /* store the message so we know how to reply */
                sock->mess = *m;
                /* operation is being processes */
                sock->flags |= SOCK_FLG_OP_PENDING;
 
                debug_print("no data to read, suspending");
-               sock_reply(sock, SUSPEND);
        }
 }
 
-static void nic_op_write(struct socket * sock, message * m)
+static void nic_op_write(struct socket * sock, message * m, __unused int blk)
 {
        int ret;
        struct pbuf * pbuf;
@@ -730,7 +731,7 @@ void nic_open(message *m)
        debug_print("device %d", m->DEVICE);
 
        if (m->DEVICE > MAX_DEVS || devices[m->DEVICE].drv_ep == NONE) {
-               send_reply(m, ENODEV);
+               send_reply_open(m, ENODEV);
                return;
        }
 
@@ -750,7 +751,7 @@ void nic_open(message *m)
        sock->recv_data_size = 0;
        sock->data = &devices[m->DEVICE];
 
-       send_reply(m, get_sock_num(sock));
+       send_reply_open(m, get_sock_num(sock));
 }
 
 static int driver_pkt_enqueue(struct packet_q ** head,
index 475be3cab8e79e19a6b3693d81deb80b2a7ab0f5..631df1c723731a8288384630c28c0ca6cbd85812 100644 (file)
@@ -25,7 +25,7 @@ Copyright 1995 Philip Homburg
 #include "inet_config.h"
 
 #include "proto.h"
-#include "socket.h"
+#include <minix/netsock.h>
 
 
 struct eth_conf eth_conf[IP_PORT_MAX];
index 39a2487f7de90891d2119f8c640dd2221744e4d2..32fa6c41738265a197bfefbebf224260a80ca96c 100644 (file)
@@ -12,9 +12,9 @@
 #include <minix/syslib.h>
 #include <minix/sysutil.h>
 #include <minix/timers.h>
+#include <minix/netsock.h>
 
 #include "proto.h"
-#include "socket.h"
 
 #include <lwip/mem.h>
 #include <lwip/pbuf.h>
@@ -30,6 +30,10 @@ static int arp_ticks, tcp_fticks, tcp_sticks;
 
 static struct netif * netif_lo;
 
+extern struct sock_ops sock_udp_ops;
+extern struct sock_ops sock_tcp_ops;
+extern struct sock_ops sock_raw_ip_ops;
+
 void sys_init(void)
 {
 }
@@ -198,6 +202,56 @@ static void netif_poll_lo(void)
                netif_poll(netif_lo);
 }
 
+void socket_open(message * m)
+{
+        struct sock_ops * ops;
+        struct socket * sock;
+        int ret = OK;
+
+        switch (m->DEVICE) {
+        case SOCK_TYPE_TCP:
+                ops = &sock_tcp_ops;
+                break;
+        case SOCK_TYPE_UDP:
+                ops = &sock_udp_ops;
+                break;
+        case SOCK_TYPE_IP:
+                ops = &sock_raw_ip_ops;
+                break;
+        default:
+                if (m->DEVICE - SOCK_TYPES  < MAX_DEVS) {
+                        m->DEVICE -= SOCK_TYPES;
+                        nic_open(m);
+                        return;
+                }
+                printf("LWIP unknown socket type %d\n", m->DEVICE);
+                send_reply_open(m, EINVAL);
+                return;
+        }
+
+        sock = get_unused_sock();
+        if (!sock) {
+                printf("LWIP : no free socket\n");
+                send_reply_open(m, EAGAIN);
+                return;
+        }
+
+        sock->ops = ops;
+        sock->select_ep = NONE;
+        sock->recv_data_size = 0;
+
+        if (sock->ops && sock->ops->open)
+                ret = sock->ops->open(sock, m);
+
+        if (ret == OK) {
+                debug_print("new socket %ld", get_sock_num(sock));
+                send_reply_open(m, get_sock_num(sock));
+        } else {
+                debug_print("failed %d", ret);
+                send_reply_open(m, ret);
+        }
+}
+
 int main(__unused int argc, __unused char ** argv)
 {
        sef_local_startup();
index d22abb60935be5561d8de5af2f70fecaad2ddbc0..6bf4ead8992e8621d50419b6a2ad4556b8beb9b3 100644 (file)
@@ -7,7 +7,7 @@
 #include <lwip/raw.h>
 #include <lwip/ip_addr.h>
 
-#include "socket.h"
+#include <minix/netsock.h>
 #include "proto.h"
 
 #define RAW_IP_BUF_SIZE        (32 << 10)
@@ -62,7 +62,7 @@ static void raw_ip_op_close(struct socket * sock, __unused message * m)
 
        raw_ip_close(sock);
 
-       sock_reply(sock, OK);
+       sock_reply_close(sock, OK);
 }
 
 static int raw_ip_do_receive(message * m,
@@ -111,7 +111,7 @@ static u8_t raw_ip_op_receive(void *arg,
                ret = raw_ip_do_receive(&sock->mess, pbuf);
 
                if (ret > 0) {
-                       sock_revive(sock, ret);
+                       sock_reply(sock, ret);
                        sock->flags &= ~SOCK_FLG_OP_PENDING;
                        if (sock->usr_flags & NWIO_EXCL) {
                                pbuf_free(pbuf);
@@ -119,7 +119,7 @@ static u8_t raw_ip_op_receive(void *arg,
                        } else
                                return 0;
                } else {
-                       sock_revive(sock, ret);
+                       sock_reply(sock, ret);
                        sock->flags &= ~SOCK_FLG_OP_PENDING;
                }
        }
@@ -170,7 +170,7 @@ static u8_t raw_ip_op_receive(void *arg,
        return ret;
 }
 
-static void raw_ip_op_read(struct socket * sock, message * m)
+static void raw_ip_op_read(struct socket * sock, message * m, int blk)
 {
        debug_print("socket num %ld", get_sock_num(sock));
 
@@ -195,18 +195,19 @@ static void raw_ip_op_read(struct socket * sock, message * m)
                        raw_ip_recv_free(data);
                }
                sock_reply(sock, ret);
-       } else {
+       } else if (!blk)
+               sock_reply(sock, EAGAIN);
+       else {
                /* store the message so we know how to reply */
                sock->mess = *m;
                /* operation is being processes */
                sock->flags |= SOCK_FLG_OP_PENDING;
 
                debug_print("no data to read, suspending");
-               sock_reply(sock, SUSPEND);
        }
 }
 
-static void raw_ip_op_write(struct socket * sock, message * m)
+static void raw_ip_op_write(struct socket * sock, message * m, __unused int blk)
 {
        int ret;
        struct pbuf * pbuf;
@@ -332,7 +333,7 @@ static void raw_ip_get_opt(struct socket * sock, message * m)
        sock_reply(sock, OK);
 }
 
-static void raw_ip_op_ioctl(struct socket * sock, message * m)
+static void raw_ip_op_ioctl(struct socket * sock, message * m, __unused int blk)
 {
        debug_print("socket num %ld req %c %d %d",
                        get_sock_num(sock),
index f38df285efb990ca7130fd44acecbccc2ddab85b..077b964df0318cd5d77defc38f59e9765967a55d 100644 (file)
@@ -11,7 +11,7 @@
 #include <lwip/tcp_impl.h>
 #include <lwip/ip_addr.h>
 
-#include "socket.h"
+#include <minix/netsock.h>
 #include "proto.h"
 
 #define TCP_BUF_SIZE   (32 << 10)
@@ -67,7 +67,7 @@ static void tcp_error_callback(void *arg, err_t err)
        }
        
        if (sock->flags & SOCK_FLG_OP_PENDING) {
-               sock_revive(sock, perr);
+               sock_reply(sock, perr);
                sock->flags &= ~SOCK_FLG_OP_PENDING;
        } else if (sock_select_set(sock))
                sock_select_notify(sock);
@@ -173,9 +173,9 @@ static void tcp_op_close(struct socket * sock, __unused message * m)
        }
        debug_tcp_print("freed TX data");
 
-       sock_reply(sock, OK);
+       sock_reply_close(sock, OK);
        debug_tcp_print("socket unused");
-       
+
        /* mark it as unused */
        sock->ops = NULL;
 }
@@ -290,7 +290,7 @@ cp_error:
                return EFAULT;
 }
 
-static void tcp_op_read(struct socket * sock, message * m)
+static void tcp_op_read(struct socket * sock, message * m, int blk)
 {
        debug_tcp_print("socket num %ld", get_sock_num(sock));
 
@@ -313,9 +313,13 @@ static void tcp_op_read(struct socket * sock, message * m)
                        sock_reply(sock, 0);
                        return;
                }
+                if (!blk) {
+                        debug_tcp_print("reading would block -> EAGAIN");
+                        sock_reply(sock, EAGAIN);
+                        return;
+                }
                /* operation is being processed */
                debug_tcp_print("no data to read, suspending");
-               sock_reply(sock, SUSPEND);
                sock->flags |= SOCK_FLG_OP_PENDING | SOCK_FLG_OP_READING;
        }
 }
@@ -383,7 +387,7 @@ static struct wbuf * wbuf_ack_sent(struct socket * sock, unsigned sz)
        return wc->head;
 }
 
-static void tcp_op_write(struct socket * sock, message * m)
+static void tcp_op_write(struct socket * sock, message * m, __unused int blk)
 {
        int ret;
        struct wbuf * wbuf;
@@ -620,9 +624,8 @@ static err_t tcp_recv_callback(void *arg,
 
                /* wake up the reader and report EOF */
                if (sock->flags & SOCK_FLG_OP_PENDING &&
-                               sock->flags & SOCK_FLG_OP_READING &&
-                               !(sock->flags & SOCK_FLG_OP_REVIVING)) {
-                       sock_revive(sock, 0);
+                               sock->flags & SOCK_FLG_OP_READING) {
+                       sock_reply(sock, 0);
                        sock->flags &= ~(SOCK_FLG_OP_PENDING |
                                        SOCK_FLG_OP_READING);
                }
@@ -652,7 +655,7 @@ static err_t tcp_recv_callback(void *arg,
                if (sock->flags & SOCK_FLG_OP_READING) {
                        ret = read_from_tcp(sock, &sock->mess);
                        debug_tcp_print("read op finished");
-                       sock_revive(sock, ret);
+                       sock_reply(sock, ret);
                        sock->flags &= ~(SOCK_FLG_OP_PENDING |
                                        SOCK_FLG_OP_READING);
                }
@@ -792,7 +795,7 @@ static err_t tcp_connected_callback(void *arg,
 
        tcp_sent(tpcb, tcp_sent_callback);
        tcp_recv(tpcb, tcp_recv_callback);
-       sock_revive(sock, OK);
+       sock_reply(sock, OK);
        sock->flags &= ~(SOCK_FLG_OP_PENDING | SOCK_FLG_OP_CONNECTING);
 
        /* revive does the sock_select_notify() for us */
@@ -811,7 +814,6 @@ static void tcp_op_connect(struct socket * sock)
         * Connecting is going to send some packets. Unless an immediate error
         * occurs this operation is going to block
         */
-       sock_reply(sock, SUSPEND);
        sock->flags |= SOCK_FLG_OP_PENDING | SOCK_FLG_OP_CONNECTING;
 
        /* try to connect now */
@@ -874,7 +876,7 @@ static err_t tcp_accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err)
                int ret;
 
                ret = tcp_do_accept(sock, &sock->mess, newpcb);
-               sock_revive(sock, ret);
+               sock_reply(sock, ret);
                sock->flags &= ~SOCK_FLG_OP_PENDING;
                if (ret == OK) {
                        return ERR_OK;
@@ -951,7 +953,6 @@ static void tcp_op_accept(struct socket * sock, message * m)
 
        debug_tcp_print("no ready connection, suspending\n");
 
-       sock_reply(sock, SUSPEND);
        sock->flags |= SOCK_FLG_OP_PENDING;
 }
 
@@ -1040,7 +1041,7 @@ static void tcp_set_opt(struct socket * sock, message * m)
        sock_reply(sock, OK);
 }
 
-static void tcp_op_ioctl(struct socket * sock, message * m)
+static void tcp_op_ioctl(struct socket * sock, message * m, __unused int blk)
 {
        if (!sock->pcb) {
                sock_reply(sock, ENOTCONN);
@@ -1109,7 +1110,7 @@ static void tcp_op_select(struct socket * sock, __unused message * m)
                        if (sel & SEL_ERR)
                                sock->flags |= SOCK_FLG_SEL_ERROR;
                }
-               send_reply(m, 0);
+               sock_reply_select(sock, 0);
                return;
        }
 
@@ -1155,7 +1156,7 @@ static void tcp_op_select(struct socket * sock, __unused message * m)
        if (sel & SEL_ERR && sel & SEL_NOTIFY)
                sock->flags |= SOCK_FLG_SEL_ERROR;
 
-       send_reply(m, retsel);
+       sock_reply_select(sock, retsel);
 }
 
 static void tcp_op_select_reply(struct socket * sock, message * m)
@@ -1164,7 +1165,7 @@ static void tcp_op_select_reply(struct socket * sock, message * m)
        debug_tcp_print("socket num %ld", get_sock_num(sock));
 
 
-       if (sock->flags & (SOCK_FLG_OP_PENDING | SOCK_FLG_OP_REVIVING)) {
+       if (sock->flags & SOCK_FLG_OP_PENDING) {
                debug_tcp_print("WARNING socket still blocking!");
                return;
        }
index fafb0dc5838f72e82b0bb61f561eecb3f4376951..38ca29ce3883d96409cbcee003e54e8729609197 100644 (file)
@@ -11,7 +11,7 @@
 #include <lwip/udp.h>
 #include <lwip/ip_addr.h>
 
-#include "socket.h"
+#include <minix/netsock.h>
 #include "proto.h"
 
 #define UDP_BUF_SIZE   (4 << 10)
@@ -72,7 +72,7 @@ static void udp_op_close(struct socket * sock, __unused message * m)
        /* mark it as unused */
        sock->ops = NULL;
 
-       sock_reply(sock, OK);
+       sock_reply_close(sock, OK);
 }
 
 static int udp_do_receive(struct socket * sock,
@@ -151,11 +151,11 @@ static void udp_recv_callback(void *arg,
 
                if (ret > 0) {
                        pbuf_free(pbuf);
-                       sock_revive(sock, ret);
+                       sock_reply(sock, ret);
                        sock->flags &= ~SOCK_FLG_OP_PENDING;
                        return;
                } else {
-                       sock_revive(sock, ret);
+                       sock_reply(sock, ret);
                        sock->flags &= ~SOCK_FLG_OP_PENDING;
                }
        }
@@ -193,7 +193,7 @@ static void udp_recv_callback(void *arg,
                sock_select_notify(sock);
 }
 
-static void udp_op_read(struct socket * sock, message * m)
+static void udp_op_read(struct socket * sock, message * m, int blk)
 {
        debug_udp_print("socket num %ld", get_sock_num(sock));
 
@@ -214,14 +214,15 @@ static void udp_op_read(struct socket * sock, message * m)
                        udp_recv_free(data);
                }
                sock_reply(sock, ret);
-       } else {
+       } else if (!blk)
+               sock_reply(sock, EAGAIN);
+       else {
                /* store the message so we know how to reply */
                sock->mess = *m;
                /* operation is being processes */
                sock->flags |= SOCK_FLG_OP_PENDING;
 
                debug_udp_print("no data to read, suspending\n");
-               sock_reply(sock, SUSPEND);
        }
 }
 
@@ -262,7 +263,7 @@ static int udp_op_sendto(struct socket * sock, struct pbuf * pbuf, message * m)
        }
 }
 
-static void udp_op_write(struct socket * sock, message * m)
+static void udp_op_write(struct socket * sock, message * m, __unused int blk)
 {
        int ret;
        struct pbuf * pbuf;
@@ -385,7 +386,7 @@ static void udp_get_opt(struct socket * sock, message * m)
        sock_reply(sock, OK);
 }
 
-static void udp_op_ioctl(struct socket * sock, message * m)
+static void udp_op_ioctl(struct socket * sock, message * m, __unused int blk)
 {
        debug_udp_print("socket num %ld req %c %d %d",
                        get_sock_num(sock),