]> jfr.im git - irc/DALnet/libd.git/commitdiff
Integrate socket handling with the rest of the system and
authorepiphani <redacted>
Thu, 5 Mar 2009 01:55:42 +0000 (20:55 -0500)
committerepiphani <redacted>
Thu, 5 Mar 2009 01:55:42 +0000 (20:55 -0500)
begin to fill out the listener handling to a more complete
form.

include/sockeng.h
src/listener.c
src/mfd.c
src/socketengine_devpoll.c
src/socketengine_epoll.c
src/socketengine_kqueue.c
src/socketengine_poll.c
src/socketengine_select.c

index 823af2a557bb320611d28ce3caa80fb044b8e102..a9e9e6526b438581462705ef8c8d1b48db4efc66 100644 (file)
@@ -125,10 +125,12 @@ struct _listener {
        int             (*qopts)();             /* function to set options */
        int             (*set_packeter)();      /* function to set packeter */
        int             (*set_parser)();        /* function to set parser */
+       int             (*set_onconnect)();     /* function to set the onconnect handler */
 
 
        char            *(*packeter)();         /* the packeter */
        int             (*parser)();            /* the parser */
+       int             (*onconnect)(Client *c); /* on-connect client handler */
 };
 
 
index c88978341622a7ae5c26989b65003c6d244c4dd8..a9c8f90426cb94166804f9e09988e5a219430f92 100644 (file)
@@ -32,6 +32,15 @@ static int listener_setparser(Listener *l, int (*func)())
        return -1;
 }
 
+static int listener_setonconnect(Listener *l, int (*func)())
+{
+       if(l) {
+               l->onconnect = func;
+               return 0;
+       }
+       return -1;
+}
+
 static int listener_setsockopts(myfd fdp)
 {
        int opt, ret;
@@ -77,6 +86,60 @@ static int listener_listen(myfd fdp)
        return 0;
 }
 
+static void accept_tcp6_connect(SockEng *s, Listener *l, int rr, int rw)
+{
+       int i, newfd;
+       struct sockaddr_in6 addr;
+       unsigned int addrlen = sizeof(struct sockaddr_in6);
+       Client *new;
+
+       for(i = 0; i < 100; i++) {
+               if((newfd = accept(l->fdp.fd, (struct sockaddr *) &addr, &addrlen)) < 0) {
+                       /* FIXME:  error reporting */
+                       return;
+               }
+               new = create_client_t(l);
+               new->fdp.fd = newfd;
+               new->addr.type = TYPE_IPV6;
+               memcpy(new->addr.ip.v6, &addr.sin6_addr, sizeof(struct in6_addr));
+               new->port = ntohs(addr.sin6_port);
+               if(l->onconnect != NULL && (*l->onconnect)(new)) {
+                       new->close(new);
+                       continue;
+               }
+               /* FIXME: set new client socket options */
+               mfd_add(s, &new->fdp, NULL);
+               mfd_read(s, &new->fdp);
+       }
+}
+
+static void accept_tcp4_connect(SockEng *s, Listener *l, int rr, int rw)
+{
+       int i, newfd;
+       struct sockaddr_in addr;
+       unsigned int addrlen = sizeof(struct sockaddr_in);
+       Client *new;
+
+       for(i = 0; i < 100; i++) {
+               if((newfd = accept(l->fdp.fd, (struct sockaddr *) &addr, &addrlen)) < 0) {
+                       /* FIXME:  error reporting */
+                       return;
+               }
+               new = create_client_t(l);
+               new->fdp.fd = newfd;
+               new->addr.type = TYPE_IPV4;
+               memcpy(new->addr.ip.v4, &addr.sin_addr, sizeof(struct in_addr));
+               new->port = ntohs(addr.sin_port);
+               if(l->onconnect != NULL && (*l->onconnect)(new)) {
+                       new->close(new);
+                       continue;
+               }
+               /* FIXME:  set new client socket options */
+               mfd_add(s, &new->fdp, NULL);
+               mfd_read(s, &new->fdp);
+       }
+}
+
 static int create_tcp6_listener(Listener *l)
 {
        struct sockaddr_in6 s;
@@ -104,7 +167,8 @@ static int create_tcp6_listener(Listener *l)
        if(listener_listen(l->fdp))
                goto out_err;
 
-       /* FIXME:  set want read */
+       mfd_add(l->sockeng, &l->fdp, l, accept_tcp6_connect);
+       mfd_read(l->sockeng, &l->fdp);
        return 0;
 
 out_err:
@@ -141,7 +205,8 @@ static int create_tcp4_listener(Listener *l)
        if(listener_listen(l->fdp))
                goto out_err;
 
-       /* FIXME:  set want read */
+       mfd_add(l->sockeng, &l->fdp, l, accept_tcp4_connect);
+       mfd_read(l->sockeng, &l->fdp);
        return 0;
 
 out_err:
@@ -163,6 +228,7 @@ Listener *create_listener(SockEng *s, unsigned short port, ipvx *address)
 
        /* data */
 
+       new->sockeng = s;
        new->fdp.fd = -1;
        new->fdp.owner = new;
        new->port = port;
@@ -179,6 +245,7 @@ Listener *create_listener(SockEng *s, unsigned short port, ipvx *address)
        new->qopts = listener_qopts;
        new->set_packeter = listener_setpacketer;
        new->set_parser = listener_setparser;
+       new->set_onconnect = listener_setonconnect;
 
        /* FIXME:  egg problem possible here.. must fix */
        new->packeter = NULL;
index c6b28b62b7211d0bae87f3fa06355cd744bceb76..20633d4b2dc0adba0bdd50962b75504ba69b86bb 100644 (file)
--- a/src/mfd.c
+++ b/src/mfd.c
@@ -3,6 +3,7 @@
  */
 
 #include "sockeng.h"
+#include "engine.h"
 
 static void fd_assert(SockEng *s, myfd *fd)
 {
@@ -28,6 +29,8 @@ int mfd_add(SockEng *s, myfd *fd, void *owner, void (*cb)())
        fd->state = 0;
        s->local[fd->fd] = fd;
 
+       engine_add_fd(s, fd->fd);
+
        return 0;
 }
 
@@ -35,18 +38,21 @@ void mfd_del(SockEng *s, myfd *fd)
 {
        fd_assert(s, fd);
        s->local[fd->fd] = NULL;
+       engine_del_fd(s, fd->fd);
 }
 
 void mfd_read(SockEng *s, myfd *fd)
 {
        fd_assert(s, fd);
        fd->state |= MFD_READ;
+       engine_change_fd_state(s, fd->fd, MFD_READ);
 }
 
 void mfd_write(SockEng *s, myfd *fd)
 {
        fd_assert(s, fd);
        fd->state |= MFD_WRITE;
+       engine_change_fd_state(s, fd->fd, MFD_WRITE);
 }
 
 void mfd_set_internal(SockEng *s, int fd, void *ptr)
index f5186fea99000358d28b708ef4b9cd1d7d262383..042217ff9d17fab70de14a72ca5f2dc44ac72b32 100644 (file)
@@ -8,11 +8,12 @@
 
 #include "sockeng.h"
 
-#include <unistd.h>
-#include <fcntl.h>
 #include <sys/devpoll.h>
 #include <sys/poll.h>
 
+extern void mfd_set_internal(SockEng *s, int fd, void *ptr);
+extern void *mfd_get_internal(SockEng *s, int fd);
+
 static int devpoll_id = -1, numfds = 0;
 
 void engine_init(SockEng *s)
index 029c36cbc49e7c94a2b53afeecea661de177a280..cedb8070df5b583c8cef09da517335d6fcf8bc20 100644 (file)
@@ -11,7 +11,6 @@
 #include <sys/epoll.h>
 
 #ifdef NEED_EPOLL_DEFS
-#include <asm/unistd.h>
 
 _syscall1(int, epoll_create, int, size)
 _syscall4(int, epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event*, event)
@@ -19,6 +18,9 @@ _syscall4(int, epoll_wait, int, epfd, struct epoll_event*, pevents, int, maxeven
 
 #endif
 
+extern void mfd_set_internal(SockEng *s, int fd, void *ptr);
+extern void *mfd_get_internal(SockEng *s, int fd);
+
 static int epoll_id = -1, numfds = 0;
 static struct epoll_fd
 {
index f396946c39245970522f646b65e485ab3bdbac24..a44b73a62ba72e6dbbe728513d4968337d92730e 100644 (file)
@@ -11,6 +11,9 @@
 #include <sys/event.h>
 #include <sys/time.h>
 
+extern void mfd_set_internal(SockEng *s, int fd, void *ptr);
+extern void *mfd_get_internal(SockEng *s, int fd);
+
 #define MAX_EVENT_QUEUE 64
 
 static int kqueue_id = -1;
index b54bb405f468f8dc76747b9e95928e7e4ff697ef..f1c7bc66839611454164613414ce97ab3fe5288c 100644 (file)
@@ -10,6 +10,9 @@
 
 #include <sys/poll.h>
 
+extern void mfd_set_internal(SockEng *s, int fd, void *ptr);
+extern void *mfd_get_internal(SockEng *s, int fd);
+
 struct pollfd poll_fds[MAX_FDS];
 int last_pfd = -1;
 
@@ -58,7 +61,7 @@ void engine_del_fd(SockEng *s, int fd)
 
 void engine_change_fd_state(SockEng *s, int fd, unsigned int stateplus)
 {
-       int arrayidx = (int) mfd_get_internal(fd);
+       int arrayidx = (int) mfd_get_internal(s, fd);
        struct pollfd *pfd = &poll_fds[arrayidx];
 
        pfd->events = 0;
index d3cbd6bb2bd0046b43fc701d3a7f292d42797aea..57b7104060a9c4221c09dfb683c968dbf2d9c3fb 100644 (file)
@@ -10,6 +10,9 @@
 
 #include <sys/select.h>
 
+extern void mfd_set_internal(SockEng *s, int fd, void *ptr);
+extern void *mfd_get_internal(SockEng *s, int fd);
+
 static fd_set g_read_set, g_write_set;
 
 void engine_init(SockEng *s)