diff --git a/GNUmakefile b/GNUmakefile
index c4bfe41..e760621 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -133,8 +133,9 @@ libuhub_SOURCES := \
src/commands.c \
src/config.c \
src/eventqueue.c \
- src/hubevent.c \
src/hub.c \
+ src/hubevent.c \
+ src/hubio.c \
src/inf.c \
src/ipcalc.c \
src/list.c \
@@ -161,8 +162,9 @@ uhub_HEADERS := \
src/config.h \
src/eventid.h \
src/eventqueue.h \
- src/hubevent.h \
src/hub.h \
+ src/hubevent.h \
+ src/hubio.h \
src/inf.h \
src/ipcalc.h \
src/list.h \
diff --git a/src/hubio.c b/src/hubio.c
new file mode 100644
index 0000000..964d915
--- /dev/null
+++ b/src/hubio.c
@@ -0,0 +1,91 @@
+/*
+ * 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 .
+ *
+ */
+
+#include "uhub.h"
+#include "hubio.h"
+
+
+struct hub_iobuf* hub_iobuf_create(size_t max_size)
+{
+ struct hub_iobuf* buf = hub_malloc_zero(sizeof(struct hub_iobuf));
+ if (buf)
+ {
+ buf->buf = hub_malloc(max_size);
+ buf->capacity = max_size;
+ }
+ return buf;
+}
+
+void hub_iobuf_destroy(struct hub_iobuf* buf)
+{
+ if (buf)
+ {
+ hub_free(buf->buf);
+ hub_free(buf);
+ }
+}
+
+int hub_iobuf_recv(struct hub_iobuf* buf, hub_iobuf_read r, void* data)
+{
+ int size = r(data, &buf->buf[buf->offset], buf->capacity - buf->offset);
+ if (size > 0)
+ {
+ buf->size += size;
+ }
+ return size;
+}
+
+int hub_iobuf_send(struct hub_iobuf* buf, hub_iobuf_write w, void* data)
+{
+ int size = w(data, &buf->buf[buf->offset], buf->size - buf->offset);
+ if (size > 0)
+ {
+ buf->offset += size;
+ }
+ return size;
+}
+
+char* hub_iobuf_getline(struct hub_iobuf* buf, size_t* offset, size_t* len, size_t max_size)
+{
+ size_t x = *offset;
+ char* pos = memchr(&buf->buf[x], '\n', (buf->size - x));
+
+ if (pos)
+ {
+ *len = &pos[0] - &buf->buf[x];
+ pos[0] = '\0';
+ pos = &buf->buf[x];
+ (*offset) += (*len + 1);
+ }
+ return pos;
+}
+
+void hub_iobuf_remove(struct hub_iobuf* buf, size_t n)
+{
+ assert(buf);
+ assert(n <= buf->size);
+
+ buf->offset = 0;
+
+ if (n == buf->size)
+ {
+ buf->size = 0;
+ }
+
+}
diff --git a/src/hubio.h b/src/hubio.h
new file mode 100644
index 0000000..ab7a4b3
--- /dev/null
+++ b/src/hubio.h
@@ -0,0 +1,71 @@
+/*
+ * 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 .
+ *
+ */
+
+#ifndef HAVE_UHUB_HUB_IO_H
+#define HAVE_UHUB_HUB_IO_H
+
+/*
+ * Used as a basis for receive queue, and send queue.
+ */
+struct hub_iobuf
+{
+ char* buf;
+ size_t offset;
+ size_t size;
+ size_t capacity;
+};
+
+typedef int (*hub_iobuf_write)(void* desc, const void* buf, size_t len);
+typedef int (*hub_iobuf_read)(void* desc, void* buf, size_t len);
+
+
+/**
+ * Create and initialize a io buffer
+ */
+extern struct hub_iobuf* hub_iobuf_create(size_t max_size);
+
+/**
+ * Destroy an io buffer.
+ */
+extern void hub_iobuf_destroy(struct hub_iobuf*);
+
+/**
+ * net_read() from a socket descriptor into a buffer.
+ * @return value from net_recv()
+ */
+extern int hub_iobuf_recv(struct hub_iobuf*, hub_iobuf_read, void* data);
+
+/**
+ * net_send() data from a buffer to a socket descriptor.
+ * @return value from net_send()
+ */
+extern int hub_iobuf_send(struct hub_iobuf*, hub_iobuf_write, void* data);
+
+/**
+ * Get a line from the buffer
+ */
+extern char* hub_iobuf_getline(struct hub_iobuf*, size_t* offset, size_t* length, size_t max_size);
+
+/**
+ * Removes the first 'n' bytes from the buffer.
+ * This will reset the offset and size parameters.
+ */
+extern void hub_iobuf_remove(struct hub_iobuf* buf, size_t n);
+
+#endif /* HAVE_UHUB_HUB_IO_H */
\ No newline at end of file
diff --git a/src/netevent.c b/src/netevent.c
index 13d881c..f7f396e 100644
--- a/src/netevent.c
+++ b/src/netevent.c
@@ -18,18 +18,40 @@
*/
#include "uhub.h"
+#include "hubio.h"
/* FIXME: This should not be needed! */
extern struct hub_info* g_hub;
+int net_user_send(void* ptr, const void* buf, size_t len)
+{
+ struct user* user = (struct user*) ptr;
+ int ret = net_send(user->sd, buf, len, UHUB_SEND_SIGNAL);
+ printf("net_user_send: %d/%d bytes\n", ret, (int) len);
+ if (ret == -1)
+ {
+ printf(" errno: %d - %s\n", errno, strerror(errno));
+ }
+
+ return ret;
+}
+
+int net_user_recv(void* ptr, void* buf, size_t len)
+{
+ struct user* user = (struct user*) ptr;
+ int ret = net_recv(user->sd, buf, len, 0);
+ printf("net_user_recv: %d/%d bytes\n", ret, (int) len);
+ if (ret == -1)
+ {
+ printf(" errno: %d - %s\n", errno, strerror(errno));
+ }
+ return ret;
+}
+
+
void net_on_read(int fd, short ev, void *arg)
{
- static char buf[MAX_RECV_BUF];
struct user* user = (struct user*) arg;
- char* pos;
- size_t offset;
- size_t buflen;
- ssize_t size;
int more = 1;
int flag_close = 0;
@@ -49,16 +71,9 @@ void net_on_read(int fd, short ev, void *arg)
}
}
- while (more)
+ for (;;)
{
- offset = 0;
- if (user->recv_buf)
- {
- memcpy(buf, user->recv_buf, user->recv_buf_offset);
- offset = user->recv_buf_offset;
- }
-
- size = net_recv(fd, &buf[offset], MAX_RECV_BUF - offset, 0);
+ ssize_t size = hub_iobuf_recv(user->recv_buf, net_user_recv, user);
if (size == -1)
{
if (net_error() != EWOULDBLOCK)
@@ -72,76 +87,19 @@ void net_on_read(int fd, short ev, void *arg)
}
else
{
- buflen = offset + size;
- ssize_t handled = 0;
-
- while ((pos = memchr(&buf[handled], '\n', (buflen - handled))))
+ size_t offset = 0;
+ size_t length;
+ char* line = 0;
+
+ while ((line = hub_iobuf_getline(user->recv_buf, &offset, &length, g_hub->config->max_recv_buffer)))
{
- pos[0] = '\0';
- size_t msglen = &pos[0] - &buf[handled];
-
- if (user_flag_get(user, flag_maxbuf))
+ if (hub_handle_message(g_hub, user, line, length) == -1)
{
- user_flag_unset(user, flag_maxbuf);
- }
- else
- {
- if (msglen < g_hub->config->max_recv_buffer)
- {
- // FIXME: hub is not set????
- if (hub_handle_message(g_hub, user, &buf[handled], msglen) == -1)
- {
- flag_close = quit_protocol_error;
- more = 0;
- break;
- }
- }
- }
- handled += msglen;
- handled++;
- }
-
- if (handled == 0 && user_flag_get(user, flag_maxbuf))
- handled = buflen;
-
- if (!more)
- break;
-
- if (handled < buflen)
- {
- if ((buflen - handled) > g_hub->config->max_recv_buffer)
- {
- user_flag_set(user, flag_maxbuf);
- hub_free(user->recv_buf);
- user->recv_buf = 0;
- user->recv_buf_offset = 0;
- }
- else
- {
- if (!user->recv_buf)
- user->recv_buf = hub_malloc(g_hub->config->max_recv_buffer);
-
- if (user->recv_buf)
- {
- memcpy(user->recv_buf, &buf[handled], buflen - handled);
- user->recv_buf_offset = buflen - handled;
- }
- else
- {
- flag_close = quit_memory_error;
- break;
- }
- }
- }
- else
- {
- if (user->recv_buf)
- {
- hub_free(user->recv_buf);
- user->recv_buf = 0;
- user->recv_buf_offset = 0;
+ flag_close = quit_protocol_error;
+ break;
}
}
+ hub_iobuf_remove(user->recv_buf, offset);
}
}
diff --git a/src/route.c b/src/route.c
index ace68f9..92a7e83 100644
--- a/src/route.c
+++ b/src/route.c
@@ -19,7 +19,6 @@
#include "uhub.h"
-
int route_message(struct hub_info* hub, struct user* u, struct adc_message* msg)
{
struct user* target = NULL;
diff --git a/src/uhub.h b/src/uhub.h
index 459c78c..2363b5f 100644
--- a/src/uhub.h
+++ b/src/uhub.h
@@ -122,6 +122,7 @@
#define TIGERSIZE 24
#define MAX_RECV_BUF 65535
+#define MAX_SEND_BUF 65535
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
@@ -145,6 +146,7 @@ extern "C" {
#include "sid.h"
#include "network.h"
#include "netevent.h"
+#include "hubio.h"
#include "auth.h"
#include "tiger.h"
#include "config.h"
diff --git a/src/user.c b/src/user.c
index 05385e0..cdfbae8 100644
--- a/src/user.c
+++ b/src/user.c
@@ -43,14 +43,11 @@ struct user* user_create(struct hub_info* hub, int sd)
user->sd = sd;
user->tm_connected = time(NULL);
-// user->hub = hub;
- user->feature_cast = 0;
user->send_queue = list_create();
- user->send_queue_offset = 0;
- user->send_queue_size = 0;
- user->recv_buf_offset = 0;
- user->recv_buf = 0;
+
+ user->send_buf = hub_iobuf_create(MAX_SEND_BUF);
+ user->recv_buf = hub_iobuf_create(MAX_RECV_BUF);
user_set_state(user, state_protocol);
return user;
@@ -95,6 +92,9 @@ void user_destroy(struct user* user)
list_destroy(user->send_queue);
}
+ user->send_buf = hub_iobuf_create(MAX_SEND_BUF);
+ user->recv_buf = hub_iobuf_create(MAX_RECV_BUF);
+
hub_free(user);
}
diff --git a/src/user.h b/src/user.h
index 1c296fa..4a0b9ab 100644
--- a/src/user.h
+++ b/src/user.h
@@ -20,9 +20,8 @@
#ifndef HAVE_UHUB_USER_H
#define HAVE_UHUB_USER_H
-
struct hub_info;
-
+struct hub_iobuf;
enum user_state
{
@@ -111,12 +110,14 @@ struct user
time_t tm_last_write; /** time the user last sent something to the hub */
struct linked_list* feature_cast; /** Features supported by feature cast */
struct adc_message* info; /** ADC 'INF' message (broadcasted to everyone joining the hub) */
+
+ struct hub_iobuf* send_buf;
+ struct hub_iobuf* recv_buf;
+
size_t send_queue_offset; /** Send queue byte offset */
struct linked_list* send_queue; /** Send queue */
int send_queue_size; /** Size of send queue (in bytes, not messages) */
- int send_queue_esize; /** Effective send queue size */
- char* recv_buf; /** Recv buffer */
- size_t recv_buf_offset; /** Recv buffer offset */
+
struct hub_info* hub; /** The hub instance this user belong to */
int quit_reason; /** Quit reason (see user_quit_reason) */
struct ip_addr_encap ipaddr; /** IP address of connected user */