diff --git a/GNUmakefile b/GNUmakefile
index eacb1c1..1f21a37 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -9,7 +9,6 @@ MV := mv
RANLIB := ranlib
CFLAGS += -pipe -Wall
USE_SSL ?= NO
-USE_LIBEVENT ?= NO
USE_BIGENDIAN ?= AUTO
BITS ?= AUTO
SILENT ?= YES
@@ -63,9 +62,6 @@ else
MSG_CLEAN="Clean as a whistle"
endif
-# CFLAGS += -I/source/libevent
-# LDFLAGS += -L/source/libevent
-
ifeq ($(RELEASE),YES)
CFLAGS += -O3 -DNDEBUG
GIT_REVISION ?= NO
@@ -116,15 +112,6 @@ CFLAGS += -DSSL_SUPPORT
LDLIBS += -lssl
endif
-ifeq ($(USE_LIBEVENT),YES)
-CFLAGS += -DUSE_LIBEVENT
-LDLIBS += -levent
-ifneq ($(LIBEVENT_PATH),)
-CFLAGS += -I$(LIBEVENT_PATH)
-LDFLAGS += -L$(LIBEVENT_PATH)
-endif
-endif
-
ifeq ($(GIT_REVISION),YES)
CFLAGS += -DGIT_REVISION=\"$(shell git show --abbrev-commit | head -n 1 | cut -f 2 -d " ")\"
endif
@@ -146,8 +133,9 @@ libuhub_SOURCES := \
src/core/usermanager.c \
src/network/connection.c \
src/network/epoll.c \
- src/network/libevent.c \
src/network/network.c \
+ src/network/select.c \
+ src/network/timer.c \
src/util/ipcalc.c \
src/util/list.c \
src/util/log.c \
diff --git a/src/core/hub.c b/src/core/hub.c
index 171f40a..8b7ee15 100644
--- a/src/core/hub.c
+++ b/src/core/hub.c
@@ -622,9 +622,6 @@ void hub_shutdown_service(struct hub_info* hub)
LOG_DEBUG("hub_shutdown_service()");
event_queue_shutdown(hub->queue);
-#ifdef USE_LIBEVENT
- event_del(&hub->ev_accept);
-#endif
net_con_close(hub->server);
hub_free(hub->server);
uman_shutdown(hub);
diff --git a/src/core/hub.h b/src/core/hub.h
index c66e27f..8eab77b 100644
--- a/src/core/hub.h
+++ b/src/core/hub.h
@@ -91,10 +91,6 @@ struct hub_logout_info
struct hub_info
{
struct net_connection* server;
-#ifdef USE_LIBEVENT
- struct event ev_accept;
- struct event ev_timer;
-#endif
struct hub_stats stats;
struct event_queue* queue;
struct hub_config* config;
diff --git a/src/core/usermanager.c b/src/core/usermanager.c
index 1db3b78..3c0eb36 100644
--- a/src/core/usermanager.c
+++ b/src/core/usermanager.c
@@ -70,28 +70,9 @@ void uman_print_stats(struct hub_info* hub)
(int) hub->stats.net_rx_peak / 1024);
}
-#ifdef USERMANAGER_TIMER
-#ifdef USE_LIBEVENT
-static void timer_statistics(int fd, short ev, void *arg)
-{
- struct hub_info* hub = (struct hub_info*) arg;
- struct timeval timeout = { TIMEOUT_STATS, 0 };
- uman_update_stats(hub);
- evtimer_set(&hub->ev_timer, timer_statistics, hub);
- evtimer_add(&hub->ev_timer, &timeout);
-}
-#endif
-#endif
-
-
int uman_init(struct hub_info* hub)
{
struct hub_user_manager* users = NULL;
-#ifdef USERMANAGER_TIMER
-#ifdef USE_LIBEVENT
- struct timeval timeout = { TIMEOUT_STATS, 0 };
-#endif
-#endif
if (!hub)
return -1;
@@ -110,16 +91,6 @@ int uman_init(struct hub_info* hub)
}
hub->users = users;
-
-#ifdef USERMANAGER_TIMER
-#ifdef USE_LIBEVENT
- if (net_get_evbase())
- {
- evtimer_set(&hub->ev_timer, timer_statistics, hub);
- evtimer_add(&hub->ev_timer, &timeout);
- }
-#endif
-#endif // 0
return 0;
}
@@ -129,13 +100,6 @@ int uman_shutdown(struct hub_info* hub)
if (!hub || !hub->users)
return -1;
-#ifdef USERMANAGER_TIMER
-#ifdef USE_LIBEVENT
- if (evtimer_pending(&hub->ev_timer, 0))
- evtimer_del(&hub->ev_timer);
-#endif
-#endif
-
if (hub->users->list)
{
list_clear(hub->users->list, &clear_user_list_callback);
@@ -144,7 +108,6 @@ int uman_shutdown(struct hub_info* hub)
sid_pool_destroy(hub->users->sids);
hub_free(hub->users);
hub->users = 0;
-
return 0;
}
diff --git a/src/network/backend.h b/src/network/backend.h
index 550ef37..d3bf105 100644
--- a/src/network/backend.h
+++ b/src/network/backend.h
@@ -36,4 +36,6 @@ extern void net_backend_shutdown();
*/
extern int net_backend_process();
+extern struct timeout_queue* net_backend_get_timeout_queue();
+
#endif /* HAVE_UHUB_NETWORK_BACKEND_H */
diff --git a/src/network/common.h b/src/network/common.h
index c60a46f..33fa2a9 100644
--- a/src/network/common.h
+++ b/src/network/common.h
@@ -1,7 +1,7 @@
#define NET_WANT_READ NET_EVENT_READ
#define NET_WANT_WRITE NET_EVENT_WRITE
-#define NET_WANT_ACCEPT 0x0008
+#define NET_WANT_ACCEPT NET_EVENT_READ
#define NET_WANT_SSL_READ 0x0010
#define NET_WANT_SSL_WRITE 0x0020
#define NET_WANT_SSL_ACCEPT 0x0040
@@ -13,14 +13,12 @@
#define NET_INITIALIZED 0x2000
#define NET_TIMER_ENABLED 0x1000
-/* FIXME: Meant for debugging */
-#define NET_EVENT_SET 0x0800
-
#define NET_CON_STRUCT_BASIC \
int sd; /** socket descriptor */ \
uint32_t flags; /** Connection flags */ \
void* ptr; /** data pointer */ \
net_connection_cb callback; /** Callback function */ \
+ struct timeout_evt* timeout; /** timeout event handler */
#define NET_CON_STRUCT_SSL \
SSL* ssl; /** SSL handle */ \
diff --git a/src/network/connection.c b/src/network/connection.c
index cf8d381..744f248 100644
--- a/src/network/connection.c
+++ b/src/network/connection.c
@@ -25,7 +25,7 @@ static int handle_openssl_error(struct net_connection* con, int ret)
{
uhub_assert(con);
- int error = SSL_get_error(net_con_get_ssl(con), ret);
+ int error = SSL_get_error(con->ssl, ret);
switch (error)
{
case SSL_ERROR_ZERO_RETURN:
@@ -77,7 +77,7 @@ ssize_t net_con_ssl_accept(struct net_connection* con)
{
uhub_assert(con);
- ssize_t ret = SSL_accept(net_con_get_ssl(con));
+ ssize_t ret = SSL_accept(con->ssl);
#ifdef NETWORK_DUMP_DEBUG
LOG_PROTO("SSL_accept() ret=%d", ret);
#endif
@@ -96,7 +96,7 @@ ssize_t net_con_ssl_connect(struct net_connection* con)
{
uhub_assert(con);
- ssize_t ret = SSL_connect(net_con_get_ssl(con));
+ ssize_t ret = SSL_connect(con->ssl);
#ifdef NETWORK_DUMP_DEBUG
LOG_PROTO("SSL_connect() ret=%d", ret);
#endif
@@ -119,14 +119,14 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode
if (ssl_mode == net_con_ssl_mode_server)
{
ssl = SSL_new(ssl_ctx);
- SSL_set_fd(ssl, net_con_get_sd(con));
+ SSL_set_fd(ssl, con->sd);
net_con_set_ssl(con, ssl);
return net_con_ssl_accept(con);
}
else
{
ssl = SSL_new(SSL_CTX_new(TLSv1_method()));
- SSL_set_fd(ssl, net_con_get_sd(con));
+ SSL_set_fd(ssl, con->sd);
net_con_set_ssl(con, ssl);
return net_con_ssl_connect(con);
}
@@ -136,7 +136,7 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode
ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
{
- int ret = net_send(net_con_get_sd(con), buf, len, UHUB_SEND_SIGNAL);
+ int ret = net_send(con->sd, buf, len, UHUB_SEND_SIGNAL);
if (ret == -1)
{
if (net_error() == EWOULDBLOCK || net_error() == EINTR)
@@ -154,7 +154,7 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
if (!net_con_is_ssl(con))
{
#endif
- int ret = net_recv(net_con_get_sd(con), buf, len, 0);
+ int ret = net_recv(con->sd, buf, len, 0);
#ifdef NETWORK_DUMP_DEBUG
LOG_PROTO("net_recv: ret=%d", ret);
#endif
@@ -174,7 +174,7 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
}
else
{
- int ret = SSL_read(net_con_get_ssl(con), buf, len);
+ int ret = SSL_read(con->ssl, buf, len);
#ifdef NETWORK_DUMP_DEBUG
LOG_PROTO("net_recv: ret=%d", ret);
#endif
@@ -193,7 +193,7 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len)
{
- int ret = net_recv(net_con_get_sd(con), buf, len, MSG_PEEK);
+ int ret = net_recv(con->sd, buf, len, MSG_PEEK);
if (ret == -1)
{
if (net_error() == EWOULDBLOCK || net_error() == EINTR)
@@ -205,6 +205,39 @@ ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len)
return ret;
}
+#ifdef SSL_SUPPORT
+int net_con_is_ssl(struct net_connection* con)
+{
+ return con->ssl != 0;
+}
+SSL* net_con_get_ssl(struct net_connection* con)
+{
+ return con->ssl;
+}
+void net_con_set_ssl(struct net_connection* con, SSL* ssl)
+{
+ con->ssl = ssl;
+}
+#endif /* SSL_SUPPORT */
+
+int net_con_get_sd(struct net_connection* con)
+{
+ return con->sd;
+}
+
+void* net_con_get_ptr(struct net_connection* con)
+{
+ return con->ptr;
+}
+
+void net_con_callback(struct net_connection* con, int events)
+{
+ if (!(con->flags & NET_CLEANUP))
+ {
+ LOG_TRACE("net_con_callback(%p, %s%s%s)", con, (events & NET_EVENT_READ ? "R" : ""), (events & NET_EVENT_WRITE ? "W" : ""), events == NET_EVENT_TIMEOUT ? "TIMEOUT" : "");
+ con->callback(con, events, con->ptr);
+ }
+}
diff --git a/src/network/connection.h b/src/network/connection.h
index 7ec602e..3f5fbf9 100644
--- a/src/network/connection.h
+++ b/src/network/connection.h
@@ -21,6 +21,7 @@
#define HAVE_UHUB_NETWORK_CONNECTION_H
#include "uhub.h"
+#include "network/common.h"
#include "network/backend.h"
#define NET_EVENT_TIMEOUT 0x0001
@@ -30,8 +31,14 @@
#define NET_EVENT_CLOSED 0x2000 /* Socket closed */
struct net_connection;
+
typedef void (*net_connection_cb)(struct net_connection*, int event, void* ptr);
+struct net_connection
+{
+ NET_CON_STRUCT_COMMON
+};
+
extern int net_con_get_sd(struct net_connection* con);
extern void* net_con_get_ptr(struct net_connection* con);
@@ -40,6 +47,7 @@ extern void net_con_destroy(struct net_connection*);
extern void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int events);
extern void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events);
extern void net_con_update(struct net_connection* con, int events);
+extern void net_con_callback(struct net_connection* con, int events);
/**
* Close the connection.
diff --git a/src/network/epoll.c b/src/network/epoll.c
index 4df8c0f..b58f680 100644
--- a/src/network/epoll.c
+++ b/src/network/epoll.c
@@ -27,18 +27,10 @@
#define EPOLL_EVBUFFER 512
-struct net_connection
+struct net_connection_epoll
{
- int sd;
- uint32_t flags;
- net_connection_cb callback;
- void* ptr;
- struct epoll_event ev;
- struct timeout_evt* timeout;
-#ifdef SSL_SUPPORT
- SSL* ssl;
- size_t write_len; /** Length of last SSL_write(), only used if flags is NET_WANT_SSL_READ. */
-#endif
+ NET_CON_STRUCT_COMMON
+ struct epoll_event ev;
};
struct net_backend
@@ -46,7 +38,7 @@ struct net_backend
int epfd;
size_t num;
size_t max;
- struct net_connection** conns;
+ struct net_connection_epoll** conns;
struct epoll_event events[EPOLL_EVBUFFER];
time_t now;
struct timeout_queue timeout_queue;
@@ -54,7 +46,7 @@ struct net_backend
static struct net_backend* g_backend = 0;
-static void net_con_print(const char* prefix, struct net_connection* con)
+static void net_con_print(const char* prefix, struct net_connection_epoll* con)
{
char buf[512];
int off = snprintf(buf, 512, "%s: net_connection={ sd=%d, flags=%u, callback=%p, ptr=%p, ev={ events=%s%s, data.ptr=%p }",
@@ -87,7 +79,7 @@ int net_backend_initialize()
g_backend->num = 0;
g_backend->max = max;
- g_backend->conns = hub_malloc_zero(sizeof(struct net_connection*) * max);
+ g_backend->conns = hub_malloc_zero(sizeof(struct net_connection_epoll*) * max);
memset(g_backend->events, 0, sizeof(g_backend->events));
g_backend->now = time(0);
@@ -121,19 +113,23 @@ int net_backend_process()
for (n = 0; n < res; n++)
{
- struct net_connection* con = (struct net_connection*) g_backend->events[n].data.ptr;
+ struct net_connection_epoll* con = (struct net_connection_epoll*) g_backend->events[n].data.ptr;
int ev = 0;
if (g_backend->events[n].events & EPOLLIN) ev |= NET_EVENT_READ;
if (g_backend->events[n].events & EPOLLOUT) ev |= NET_EVENT_WRITE;
- con->callback(con, ev, con->ptr);
+ net_con_callback((struct net_connection*) con, ev);
}
return 1;
}
+struct timeout_queue* net_backend_get_timeout_queue()
+{
+ return &g_backend->timeout_queue;
+}
struct net_connection* net_con_create()
{
- struct net_connection* con = (struct net_connection*) hub_malloc_zero(sizeof(struct net_connection));
+ struct net_connection* con = (struct net_connection*) hub_malloc_zero(sizeof(struct net_connection_epoll));
con->sd = -1;
return con;
}
@@ -143,8 +139,9 @@ void net_con_destroy(struct net_connection* con)
hub_free(con);
}
-void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int events)
+void net_con_initialize(struct net_connection* con_, int sd, net_connection_cb callback, const void* ptr, int events)
{
+ struct net_connection_epoll* con = (struct net_connection_epoll*) con_;
con->sd = sd;
con->flags = NET_INITIALIZED;
con->callback = callback;
@@ -176,10 +173,11 @@ void net_con_reinitialize(struct net_connection* con, net_connection_cb callback
net_con_update(con, events);
}
-void net_con_update(struct net_connection* con, int events)
+void net_con_update(struct net_connection* con_, int events)
{
+ struct net_connection_epoll* con = (struct net_connection_epoll*) con_;
con->ev.events = 0;
- if (events & NET_EVENT_READ) con->ev.events |= EPOLLIN;
+ if (events & NET_EVENT_READ) con->ev.events |= EPOLLIN;
if (events & NET_EVENT_WRITE) con->ev.events |= EPOLLOUT;
#ifdef SSL_SUPPORT
@@ -211,8 +209,9 @@ void net_con_update(struct net_connection* con, int events)
net_con_print("MOD", con);
}
-int net_con_close(struct net_connection* con)
+int net_con_close(struct net_connection* con_)
{
+ struct net_connection_epoll* con = (struct net_connection_epoll*) con_;
if (!(con->flags & NET_INITIALIZED))
return 0;
@@ -239,68 +238,4 @@ int net_con_close(struct net_connection* con)
return 0;
}
-#ifdef SSL_SUPPORT
-int net_con_is_ssl(struct net_connection* con)
-{
-
- return con->ssl != 0;
-}
-
-SSL* net_con_get_ssl(struct net_connection* con)
-{
- return con->ssl;
-}
-
-void net_con_set_ssl(struct net_connection* con, SSL* ssl)
-{
- con->ssl = ssl;
-}
-#endif
-
-int net_con_get_sd(struct net_connection* con)
-{
- return con->sd;
-}
-
-void* net_con_get_ptr(struct net_connection* con)
-{
- return con->ptr;
-}
-
-
-void timeout_evt_initialize(struct timeout_evt*, timeout_evt_cb, void* ptr);
-void timeout_evt_reset(struct timeout_evt*);
-int timeout_evt_is_scheduled(struct timeout_evt*);
-
-static void timeout_callback(struct timeout_evt* evt)
-{
- struct net_connection* con = (struct net_connection*) evt->ptr;
- con->callback(con, NET_EVENT_TIMEOUT, con->ptr);
-}
-
-
-void net_con_set_timeout(struct net_connection* con, int seconds)
-{
- if (!con->timeout)
- {
- con->timeout = hub_malloc_zero(sizeof(struct timeout_evt));
- timeout_evt_initialize(con->timeout, timeout_callback, con);
- timeout_queue_insert(&g_backend->timeout_queue, con->timeout, seconds);
- }
- else
- {
- timeout_queue_reschedule(&g_backend->timeout_queue, con->timeout, seconds);
- }
-}
-
-void net_con_clear_timeout(struct net_connection* con)
-{
- if (con->timeout && timeout_evt_is_scheduled(con->timeout))
- {
- timeout_queue_remove(&g_backend->timeout_queue, con->timeout);
- hub_free(con->timeout);
- con->timeout = 0;
- }
-}
-
#endif /* USE_EPOLL */
diff --git a/src/network/libevent.c b/src/network/libevent.c
deleted file mode 100644
index 4d27015..0000000
--- a/src/network/libevent.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * uhub - A tiny ADC p2p connection hub
- * Copyright (C) 2007-2009, Jan Vidar Krey
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-#ifdef USE_LIBEVENT
-
-struct net_connection
-{
- NET_CON_STRUCT_COMMON
- struct event event; /** libevent struct for read/write events */
- struct event timeout; /** Used for internal timeout handling */
-};
-
-struct net_timer
-{
- unsigned int initialized;
- struct event timeout;
- net_timeout_cb callback;
- void* ptr;
-};
-
-int net_con_get_sd(struct net_connection* con)
-{
- return con->sd;
-}
-
-void* net_con_get_ptr(struct net_connection* con)
-{
- return con->ptr;
-}
-
-struct net_connection* net_con_create()
-{
- struct net_connection* con = (struct net_connection*) hub_malloc(sizeof(struct net_connection));
- return con;
-}
-
-static inline int net_con_flag_get(struct net_connection* con, unsigned int flag)
-{
- return con->flags & flag;
-}
-
-static inline void net_con_flag_set(struct net_connection* con, unsigned int flag)
-{
- con->flags |= flag;
-}
-
-static inline void net_con_flag_unset(struct net_connection* con, unsigned int flag)
-{
- con->flags &= ~flag;
-}
-
-void net_con_destroy(struct net_connection* con)
-{
- hub_free(con);
-}
-
-static inline int net_con_convert_to_libevent_mask(int ev)
-{
- int events = 0;
- if (ev & NET_EVENT_READ) events |= EV_READ;
- if (ev & NET_EVENT_WRITE) events |= EV_WRITE;
- return events;
-}
-
-static inline int net_con_convert_from_libevent_mask(int ev)
-{
- int events = 0;
- if (ev & EV_TIMEOUT) events |= NET_EVENT_TIMEOUT;
- if (ev & EV_READ) events |= NET_EVENT_READ;
- if (ev & EV_WRITE) events |= NET_EVENT_WRITE;
- return events;
-}
-
-static void net_con_event(int fd, short ev, void *arg);
-
-
-int net_con_close(struct net_connection* con)
-{
- uhub_assert(con);
-
- con->ptr = 0;
-
- if (net_con_flag_get(con, NET_CLEANUP))
- return 0;
-
- if (net_con_flag_get(con, NET_PROCESSING_BUSY))
- {
- net_con_flag_set(con, NET_CLEANUP);
- return 0;
- }
-
- net_con_after_close(con);
- return 1;
-}
-
-static void net_con_set(struct net_connection* con)
-{
- uhub_assert(con);
-
- int ev = 0;
- if (net_con_flag_get(con, NET_WANT_READ | NET_WANT_SSL_READ)) ev |= EV_READ;
- if (net_con_flag_get(con, NET_WANT_WRITE | NET_WANT_SSL_WRITE)) ev |= EV_WRITE;
-
- if (net_con_flag_get(con, NET_EVENT_SET) != 0)
- {
- event_del(&con->event);
- }
- net_con_flag_set(con, NET_EVENT_SET);
-
- LOG_MEMORY("SET: set+add: CON={ %p, %p, %d, %d}", con, &con->event, con->sd, ev);
- event_set(&con->event, con->sd, ev, net_con_event, con);
- event_add(&con->event, 0);
-
- net_con_flag_set(con, NET_INITIALIZED);
-}
-
-static void net_con_after_close(struct net_connection* con)
-{
- if (net_con_flag_get(con, NET_INITIALIZED))
- {
- LOG_MEMORY("DEL: close: CON={ %p, %p, %d, %d}", con, &con->event, con->sd, -1);
- net_con_flag_unset(con, NET_EVENT_SET);
-
- event_del(&con->event);
- net_con_flag_unset(con, NET_INITIALIZED);
- }
-
- net_con_clear_timeout(con);
- net_close(con->sd);
- con->sd = -1;
-
- hub_free(con);
-}
-
-void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int ev)
-{
- uhub_assert(con);
-
- int events = net_con_convert_to_libevent_mask(ev);
- if (ev & NET_EVENT_READ) net_con_flag_set(con, NET_WANT_READ);
- if (ev & NET_EVENT_WRITE) net_con_flag_set(con, NET_WANT_WRITE);
-
- con->sd = sd;
- con->flags = 0;
- con->ptr = (void*) ptr;
- con->callback = callback;
- con->last_send = time(0);
- con->last_recv = con->last_send;
-
- if (ev)
- {
- uhub_assert(net_con_flag_get(con, NET_EVENT_SET) == 0);
- net_con_flag_set(con, NET_EVENT_SET);
-
- LOG_MEMORY("SET: init: CON={ %p, %p, %d, %d}", con, &con->event, con->sd, ev);
- event_set(&con->event, con->sd, events, net_con_event, con);
- event_add(&con->event, 0);
- net_con_flag_set(con, NET_INITIALIZED);
- }
-
- net_set_nonblocking(sd, 1);
- net_set_nosigpipe(sd, 1);
-
-#ifdef SSL_SUPPORT
- con->ssl = NULL;
- con->write_len = 0;
-#endif
-}
-
-void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events)
-{
- uhub_assert(con);
- con->callback = callback;
- con->ptr = (void*) ptr;
- net_con_update(con, events);
-}
-
-void net_con_update(struct net_connection* con, int ev)
-{
- uhub_assert(con);
-
- if (ev & NET_EVENT_READ)
- net_con_flag_set(con, NET_EVENT_READ);
- else
- net_con_flag_unset(con, NET_EVENT_READ);
-
- if (ev & NET_EVENT_WRITE)
- net_con_flag_set(con, NET_EVENT_WRITE);
- else
- net_con_flag_unset(con, NET_EVENT_WRITE);
-
- if (!net_con_flag_get(con, NET_PROCESSING_BUSY))
- {
- net_con_set(con);
- }
-}
-
-#define CALLBACK(CON, EVENTS) \
- if (CON->callback) \
- CON->callback(con, EVENTS, CON->ptr);
-
-static void net_con_event(int fd, short ev, void *arg)
-{
- struct net_connection* con = (struct net_connection*) arg;
- int events = net_con_convert_from_libevent_mask(ev);
-
- if (!net_con_flag_get(con, NET_INITIALIZED))
- {
- return;
- }
-
- if (net_con_flag_get(con, NET_CLEANUP))
- {
- net_con_after_close(con);
- return;
- }
-
- net_con_flag_set(con, NET_PROCESSING_BUSY);
-
-// uhub_assert(net_con_flag_get(con, NET_EVENT_SET) != 0);
- net_con_flag_unset(con, NET_EVENT_SET);
-
- LOG_MEMORY("EVT: process: CON={ %p, %p, %d, %d}", con, &con->event, con->sd, (int) ev);
-
-#ifdef SSL_SUPPORT
- if (!con->ssl)
- {
-#endif
- CALLBACK(con, events);
-#ifdef SSL_SUPPORT
- }
- else
- {
-#ifdef NETWORK_DUMP_DEBUG
- LOG_PROTO("net_con_event: events=%d, con=%p", ev, con);
-#endif
- if (ev & (EV_READ | EV_WRITE))
- {
- if (net_con_flag_get(con, NET_WANT_SSL_ACCEPT))
- {
- if (net_con_ssl_accept(con) < 0)
- CALLBACK(con, NET_EVENT_SOCKERROR);
- }
- else if (net_con_flag_get(con, NET_WANT_SSL_CONNECT))
- {
- if (net_con_ssl_connect(con) < 0)
- CALLBACK(con, NET_EVENT_SOCKERROR);
- }
- else if (ev == EV_READ && net_con_flag_get(con, NET_WANT_SSL_READ))
- {
- CALLBACK(con, NET_EVENT_WRITE);
- }
- else if (ev == EV_WRITE && net_con_flag_get(con, NET_WANT_SSL_WRITE))
- {
- CALLBACK(con, events & NET_EVENT_READ);
- }
- else
- {
- CALLBACK(con, events);
- }
- }
- else
- {
- CALLBACK(con, events);
- }
- }
-#endif
- net_con_flag_unset(con, NET_PROCESSING_BUSY);
-
- if (net_con_flag_get(con, NET_CLEANUP))
- {
- net_con_after_close(con);
- }
- else
- {
- net_con_set(con);
- }
-}
-
-
-static void net_timer_event(int fd, short ev, void *arg)
-{
- struct net_timer* timer = (struct net_timer*) arg;
- timer->callback(timer, timer->ptr);
-}
-
-void net_timer_initialize(struct net_timer* timer, net_timeout_cb callback, void* ptr)
-{
- timer->initialized = 0;
- timer->callback = callback;
- timer->ptr = ptr;
-}
-
-void net_timer_reset(struct net_timer* timer, int seconds)
-{
- struct timeval timeout = { seconds, 0 };
- if (timer->initialized)
- {
- evtimer_del(&timer->timeout);
- timer->initialized = 0;
- }
- evtimer_set(&timer->timeout, net_timer_event, timer);
- evtimer_add(&timer->timeout, &timeout);
-}
-
-void net_timer_shutdown(struct net_timer* timer)
-{
- if (timer->initialized)
- {
- evtimer_del(&timer->timeout);
- timer->initialized = 0;
- }
- timer->callback = 0;
- timer->ptr = 0;
-}
-
-
-void net_con_set_timeout(struct net_connection* con, int seconds)
-{
- uhub_assert(con);
-
- struct timeval timeout = { seconds, 0 };
- net_con_clear_timeout(con);
-
- evtimer_set(&con->timeout, net_con_event, con);
- evtimer_add(&con->timeout, &timeout);
- net_con_flag_set(con, NET_TIMER_ENABLED);
-}
-
-void net_con_clear_timeout(struct net_connection* con)
-{
- uhub_assert(con);
-
- if (net_con_flag_get(con, NET_TIMER_ENABLED))
- {
- evtimer_del(&con->timeout);
- net_con_flag_unset(con, NET_TIMER_ENABLED);
- }
-}
-
-static struct event_base g_evbase = 0;
-
-/**
- * Initialize the network backend.
- * Returns 1 on success, or 0 on failure.
- */
-int net_backend_initialize()
-{
- g_evbase = event_init();
- if (!g_evbase)
- {
- LOG_ERROR("Unable to initialize libevent.");
- return 0;
- }
- LOG_DEBUG("Using libevent %s, backend: %s", event_get_version(), event_get_method());
- return 1;
-}
-
-/**
- * Shutdown the network connection backend.
- */
-void net_backend_shutdown()
-{
- event_base_free(g_evbase);
-}
-
-/**
- * Process the network backend.
- */
-int net_backend_process()
-{
- int ret = event_base_loop(g_evbase, EVLOOP_ONCE);
- if (ret != 0)
- {
- LOG_DEBUG("event_base_loop returned: %d", (int) ret);
- }
- if (ret < 0)
- return 0;
- return 1;
-}
-
-
-#endif /* USE_LIBEVENT */
diff --git a/src/network/select.c b/src/network/select.c
new file mode 100644
index 0000000..989ba39
--- /dev/null
+++ b/src/network/select.c
@@ -0,0 +1,208 @@
+/*
+ * uhub - A tiny ADC p2p connection hub
+ * Copyright (C) 2007-2010, Jan Vidar Krey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "uhub.h"
+
+#ifdef USE_SELECT
+
+#include "network/connection.h"
+#include "network/common.h"
+#include "network/backend.h"
+
+struct net_connection_select
+{
+ NET_CON_STRUCT_COMMON
+};
+
+struct net_backend
+{
+ size_t num;
+ size_t max;
+ struct net_connection_select** conns;
+ fd_set rfds;
+ fd_set wfds;
+ time_t now;
+ struct timeout_queue timeout_queue;
+};
+
+static struct net_backend* g_backend = 0;
+
+static void net_con_print(const char* prefix, struct net_connection_select* con)
+{
+ char buf[512];
+ int off = snprintf(buf, 512, "%s: net_connection={ sd=%d, flags=%u, callback=%p, ptr=%p, events=%s%s",
+ prefix, con->sd, con->flags, con->callback, con->ptr, (con->flags & NET_EVENT_READ ? "R" : ""),(con->flags & NET_EVENT_WRITE ? "W" : ""));
+ if (con->timeout)
+ {
+ sprintf(buf + off, ", timeout={ %d seconds left }", (int) (con->timeout->timestamp - g_backend->now));
+ }
+ else
+ {
+ sprintf(buf + off, ", timeout=NULL");
+ }
+ LOG_TRACE(buf);
+}
+
+/**
+ * Initialize the network backend.
+ * Returns 1 on success, or 0 on failure.
+ */
+int net_backend_initialize()
+{
+ size_t max = net_get_max_sockets();
+ g_backend = hub_malloc(sizeof(struct net_backend));
+ g_backend->num = 0;
+ g_backend->max = max;
+ g_backend->conns = hub_malloc_zero(sizeof(struct net_connection_select*) * max);
+ FD_ZERO(&g_backend->rfds);
+ FD_ZERO(&g_backend->wfds);
+ g_backend->now = time(0);
+ timeout_queue_initialize(&g_backend->timeout_queue, g_backend->now, 600); /* look max 10 minutes into the future. */
+ return 1;
+}
+
+/**
+ * Shutdown the network connection backend.
+ */
+void net_backend_shutdown()
+{
+ hub_free(g_backend->conns);
+ hub_free(g_backend);
+}
+
+/**
+ * Process the network backend.
+ */
+int net_backend_process()
+{
+ int n, found, maxfd;
+ struct timeval tval = { 1, 0 };
+ FD_ZERO(&g_backend->rfds);
+ FD_ZERO(&g_backend->wfds);
+ for (n = 0, found = 0; found < g_backend->num && n < g_backend->max; n++)
+ {
+ struct net_connection_select* con = g_backend->conns[n];
+ if (con)
+ {
+ if (con->flags & NET_EVENT_READ) FD_SET(con->sd, &g_backend->rfds);
+ if (con->flags & NET_EVENT_WRITE) FD_SET(con->sd, &g_backend->wfds);
+ found++;
+ maxfd = con->sd;
+ }
+ }
+
+ int res = select(maxfd+1, &g_backend->rfds, &g_backend->wfds, 0, &tval);
+ if (res == -1)
+ {
+ LOG_WARN("select returned -1");
+ return 0;
+ }
+
+ for (n = 0, found = 0; found < res && n < (maxfd+1); n++)
+ {
+ struct net_connection_select* con = g_backend->conns[n];
+ if (con)
+ {
+ int ev = 0;
+ if (FD_ISSET(con->sd, &g_backend->rfds)) ev |= NET_EVENT_READ;
+ if (FD_ISSET(con->sd, &g_backend->wfds)) ev |= NET_EVENT_WRITE;
+
+ if (ev)
+ {
+ net_con_callback((struct net_connection*) con, ev);
+ found++;
+ }
+ }
+ }
+ return 1;
+}
+
+struct timeout_queue* net_backend_get_timeout_queue()
+{
+ return &g_backend->timeout_queue;
+}
+
+struct net_connection* net_con_create()
+{
+ struct net_connection* con = (struct net_connection*) hub_malloc_zero(sizeof(struct net_connection_select));
+ con->sd = -1;
+ return con;
+}
+
+void net_con_destroy(struct net_connection* con)
+{
+ hub_free(con);
+}
+
+void net_con_initialize(struct net_connection* con_, int sd, net_connection_cb callback, const void* ptr, int events)
+{
+ struct net_connection_select* con = (struct net_connection_select*) con_;
+ con->sd = sd;
+ con->flags = NET_INITIALIZED;
+ con->flags |= events;
+ con->callback = callback;
+ con->ptr = (void*) ptr;
+
+ net_set_nonblocking(con->sd, 1);
+ net_set_nosigpipe(con->sd, 1);
+
+ g_backend->conns[sd] = con;
+ g_backend->num++;
+ net_con_print("ADD", con);
+}
+
+void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events)
+{
+ con->callback = callback;
+ con->ptr = (void*) ptr;
+ net_con_update(con, events);
+}
+
+void net_con_update(struct net_connection* con, int events)
+{
+ con->flags = NET_INITIALIZED;
+ con->flags |= events;
+ net_con_print("MOD", (struct net_connection_select*) con);
+}
+
+int net_con_close(struct net_connection* con)
+{
+ if (!(con->flags & NET_INITIALIZED))
+ return 0;
+
+ con->flags &= ~NET_INITIALIZED;
+
+ if (con->sd != -1)
+ {
+ g_backend->conns[con->sd] = 0;
+ g_backend->num--;
+ }
+
+ if (timeout_evt_is_scheduled(con->timeout))
+ {
+ timeout_queue_remove(&g_backend->timeout_queue, con->timeout);
+ hub_free(con->timeout);
+ con->timeout = 0;
+ }
+
+ net_con_print("DEL", (struct net_connection_select*) con);
+ return 0;
+}
+
+#endif /* USE_SELECT */
diff --git a/src/network/timer.c b/src/network/timer.c
new file mode 100644
index 0000000..9400cb7
--- /dev/null
+++ b/src/network/timer.c
@@ -0,0 +1,50 @@
+/*
+ * uhub - A tiny ADC p2p connection hub
+ * Copyright (C) 2007-2010, Jan Vidar Krey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "uhub.h"
+#include "network/connection.h"
+
+static void timeout_callback(struct timeout_evt* evt)
+{
+ net_con_callback((struct net_connection*) evt->ptr, NET_EVENT_TIMEOUT);
+}
+
+void net_con_set_timeout(struct net_connection* con, int seconds)
+{
+ if (!con->timeout)
+ {
+ con->timeout = hub_malloc_zero(sizeof(struct timeout_evt));
+ timeout_evt_initialize(con->timeout, timeout_callback, con);
+ timeout_queue_insert(net_backend_get_timeout_queue(), con->timeout, seconds);
+ }
+ else
+ {
+ timeout_queue_reschedule(net_backend_get_timeout_queue(), con->timeout, seconds);
+ }
+}
+
+void net_con_clear_timeout(struct net_connection* con)
+{
+ if (timeout_evt_is_scheduled(con->timeout))
+ {
+ timeout_queue_remove(net_backend_get_timeout_queue(), con->timeout);
+ hub_free(con->timeout);
+ con->timeout = 0;
+ }
+}
diff --git a/src/system.h b/src/system.h
index 2af2ff5..affc91b 100644
--- a/src/system.h
+++ b/src/system.h
@@ -102,13 +102,12 @@
#define uhub_assert assert
-#ifdef USE_LIBEVENT
-#include
-#else
#ifdef __linux__
#define USE_EPOLL
#include
-#endif
+#else
+#define USE_SELECT
+#include
#endif
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__sun__)
diff --git a/src/tools/adcrush.c b/src/tools/adcrush.c
index eb72450..e54f502 100644
--- a/src/tools/adcrush.c
+++ b/src/tools/adcrush.c
@@ -330,7 +330,7 @@ void runloop(size_t clients)
while (running)
{
- event_base_loop(net_get_evbase(), EVLOOP_ONCE);
+ net_backend_process();
}
for (n = 0; n < clients; n++)
@@ -413,63 +413,17 @@ void parse_command_line(int argc, char** argv)
}
}
-#ifndef WIN32
-static void handle_signal(int signal, short events, void* arg)
-{
- switch (signal)
- {
- case SIGINT:
- case SIGTERM:
- running = 0;
- break;
- default:
- break;
- }
-}
-
-static struct event signal_events[10];
-static int signals[] =
-{
- SIGINT, /* Interrupt the application */
- SIGTERM, /* Terminate the application */
- 0
-};
-
-void setup_signal_handlers()
-{
- int i = 0;
- for (i = 0; signals[i]; i++)
- {
- signal_set(&signal_events[i], signals[i], handle_signal, NULL);
- signal_add(&signal_events[i], NULL);
- }
-}
-
-void shutdown_signal_handlers()
-{
- int i = 0;
- for (i = 0; signals[i]; i++)
- {
- signal_del(&signal_events[i]);
- }
-}
-#endif /* WIN32 */
-
-
int main(int argc, char** argv)
{
parse_command_line(argc, argv);
net_initialize();
- setup_signal_handlers();
hub_log_initialize(NULL, 0);
hub_set_log_verbosity(1000);
runloop(cfg_clients);
- shutdown_signal_handlers();
net_destroy();
-
return 0;
}
diff --git a/src/tools/admin.c b/src/tools/admin.c
index 113e770..225cbb2 100644
--- a/src/tools/admin.c
+++ b/src/tools/admin.c
@@ -63,6 +63,7 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
return 1;
}
+static int running = 1;
int main(int argc, char** argv)
{
@@ -79,7 +80,10 @@ int main(int argc, char** argv)
ADC_client_set_callback(&client, handle);
ADC_client_connect(&client, argv[1]);
- event_dispatch();
+ while (running)
+ {
+ net_backend_process();
+ }
ADC_client_destroy(&client);
net_destroy();
diff --git a/src/util/timeout.c b/src/util/timeout.c
index 1009e70..b2daaa0 100644
--- a/src/util/timeout.c
+++ b/src/util/timeout.c
@@ -99,7 +99,7 @@ void timeout_queue_remove(struct timeout_queue* t, struct timeout_evt* evt)
size_t pos = (evt->timestamp % t->max);
struct timeout_evt* first = t->events[pos];
- if (!first)
+ if (!first || !evt)
return;
if (first == evt)