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;
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;
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:
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:
/* data */
+ new->sockeng = s;
new->fdp.fd = -1;
new->fdp.owner = new;
new->port = port;
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;
*/
#include "sockeng.h"
+#include "engine.h"
static void fd_assert(SockEng *s, myfd *fd)
{
fd->state = 0;
s->local[fd->fd] = fd;
+ engine_add_fd(s, fd->fd);
+
return 0;
}
{
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)
#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)
#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
{