summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fastd.c20
-rw-r--r--src/fastd.h5
-rw-r--r--src/queue.c39
-rw-r--r--src/queue.h7
-rw-r--r--src/task.c29
-rw-r--r--src/task.h25
6 files changed, 61 insertions, 64 deletions
diff --git a/src/fastd.c b/src/fastd.c
index e0a03ad..6db09b6 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -355,22 +355,22 @@ static void update_time(fastd_context *ctx) {
static void handle_tasks(fastd_context *ctx) {
fastd_task *task;
while ((task = fastd_task_get(ctx)) != NULL) {
- switch (task->any.type) {
+ switch (task->type) {
case TASK_SEND:
- if (task->send.peer) {
+ if (task->peer) {
int sockfd;
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
- switch (task->send.peer->address.sa.sa_family) {
+ switch (task->peer->address.sa.sa_family) {
case AF_INET:
- msg.msg_name = &task->send.peer->address.in;
+ msg.msg_name = &task->peer->address.in;
msg.msg_namelen = sizeof(struct sockaddr_in);
sockfd = ctx->sockfd;
break;
case AF_INET6:
- msg.msg_name = &task->send.peer->address.in6;
+ msg.msg_name = &task->peer->address.in6;
msg.msg_namelen = sizeof(struct sockaddr_in6);
sockfd = ctx->sock6fd;
break;
@@ -398,7 +398,7 @@ static void handle_tasks(fastd_context *ctx) {
const fastd_eth_addr *src_addr = fastd_get_source_address(ctx, task->handle_recv.buffer);
if (fastd_eth_addr_is_unicast(src_addr))
- fastd_peer_add_eth_addr(ctx, task->handle_recv.peer, src_addr);
+ fastd_peer_add_eth_addr(ctx, task->peer, src_addr);
}
write(ctx->tunfd, task->handle_recv.buffer.data, task->handle_recv.buffer.len);
@@ -406,14 +406,14 @@ static void handle_tasks(fastd_context *ctx) {
break;
case TASK_HANDSHAKE:
- if (task->handshake.peer->state != STATE_WAIT && task->handshake.peer->state != STATE_TEMP)
+ if (task->peer->state != STATE_WAIT && task->peer->state != STATE_TEMP)
break;
pr_debug(ctx, "Sending handshake...");
- fastd_handshake_send(ctx, task->handshake.peer);
+ fastd_handshake_send(ctx, task->peer);
- if (task->handshake.peer->state == STATE_WAIT)
- fastd_task_schedule_handshake(ctx, task->handshake.peer, 20000);
+ if (task->peer->state == STATE_WAIT)
+ fastd_task_schedule_handshake(ctx, task->peer, 20000);
break;
default:
diff --git a/src/fastd.h b/src/fastd.h
index c8cad39..e4bef44 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -121,6 +121,11 @@ struct _fastd_context {
#define exit_errno(ctx, message) exit_error(ctx, "%s: %s", message, strerror(errno))
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
static inline fastd_buffer fastd_buffer_alloc(size_t len, size_t head_space, size_t tail_space) {
size_t base_len = head_space+len+tail_space;
uint8_t *ptr = malloc(head_space+len);
diff --git a/src/queue.c b/src/queue.c
index 77533f9..d950e33 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -31,14 +31,17 @@
#include <stdint.h>
-static inline int after(const struct timespec *tp1, const struct timespec *tp2) {
+/* returns (tp1 - tp2) in milliseconds */
+static inline int timespec_diff(const struct timespec *tp1, const struct timespec *tp2) {
+ return ((tp1->tv_sec - tp2->tv_sec))*1000 + (tp1->tv_nsec - tp2->tv_nsec)/1e6;
+}
+
+static inline bool after(const struct timespec *tp1, const struct timespec *tp2) {
return (tp1->tv_sec > tp2->tv_sec ||
(tp1->tv_sec == tp2->tv_sec && tp1->tv_nsec > tp2->tv_nsec));
}
-void fastd_queue_put(fastd_context *ctx, fastd_queue *queue, void *data, int timeout) {
- fastd_queue_entry *entry = malloc(sizeof(fastd_queue_entry));
- entry->data = data;
+void fastd_queue_put(fastd_context *ctx, fastd_queue *queue, fastd_queue_entry *entry, int timeout) {
entry->timeout = ctx->now;
if (timeout) {
@@ -61,39 +64,35 @@ void fastd_queue_put(fastd_context *ctx, fastd_queue *queue, void *data, int tim
}
}
-void* fastd_queue_get(fastd_context *ctx, fastd_queue *queue) {
+fastd_queue_entry* fastd_queue_get(fastd_context *ctx, fastd_queue *queue) {
if (!queue->head || fastd_queue_timeout(ctx, queue) > 0)
return NULL;
fastd_queue_entry *entry = queue->head;
queue->head = entry->next;
- void *data = entry->data;
- free(entry);
- return data;
+ return entry;
}
int fastd_queue_timeout(fastd_context *ctx, fastd_queue *queue) {
if (!queue->head)
return -1;
- int64_t diff_msec = ((int64_t)(queue->head->timeout.tv_sec-ctx->now.tv_sec))*1000 + (queue->head->timeout.tv_nsec-ctx->now.tv_nsec)/1e6;
+ int diff_msec = timespec_diff(&queue->head->timeout, &ctx->now);
if (diff_msec < 0)
return 0;
else
- return (int)diff_msec;
+ return diff_msec;
}
-void fastd_queue_filter(fastd_context *ctx, fastd_queue *queue, bool (*pred)(void*, void*), void *extra) {
- fastd_queue_entry **entry;
- for (entry = &queue->head; *entry; ) {
- if (!pred((*entry)->data, extra)) {
- fastd_queue_entry *cur = *entry;
- *entry = cur->next;
- free(cur);
- }
- else {
+void fastd_queue_filter(fastd_context *ctx, fastd_queue *queue, bool (*pred)(fastd_queue_entry*, void*), void *extra) {
+ fastd_queue_entry **entry, *next;
+ for (entry = &queue->head; *entry;) {
+ next = (*entry)->next;
+
+ if (!pred(*entry, extra))
+ *entry = next;
+ else
entry = &(*entry)->next;
- }
}
}
diff --git a/src/queue.h b/src/queue.h
index 320df9f..60e7818 100644
--- a/src/queue.h
+++ b/src/queue.h
@@ -39,7 +39,6 @@ typedef struct _fastd_queue_entry fastd_queue_entry;
struct _fastd_queue_entry {
fastd_queue_entry *next;
- void *data;
struct timespec timeout;
};
@@ -48,9 +47,9 @@ typedef struct _fastd_queue {
} fastd_queue;
-void fastd_queue_put(fastd_context *ctx, fastd_queue *queue, void *data, int timeout);
-void* fastd_queue_get(fastd_context *ctx, fastd_queue *queue);
+void fastd_queue_put(fastd_context *ctx, fastd_queue *queue, fastd_queue_entry *entry, int timeout);
+fastd_queue_entry* fastd_queue_get(fastd_context *ctx, fastd_queue *queue);
int fastd_queue_timeout(fastd_context *ctx, fastd_queue *queue);
-void fastd_queue_filter(fastd_context *ctx, fastd_queue *queue, bool (*pred)(void*, void*), void *extra);
+void fastd_queue_filter(fastd_context *ctx, fastd_queue *queue, bool (*pred)(fastd_queue_entry*, void*), void *extra);
#endif /* _FASTD_QUEUE_H_ */
diff --git a/src/task.c b/src/task.c
index 04b8cb1..2726ced 100644
--- a/src/task.c
+++ b/src/task.c
@@ -26,22 +26,21 @@
#include "task.h"
-#include "queue.h"
fastd_task* fastd_task_get(fastd_context *ctx) {
- return fastd_queue_get(ctx, &ctx->task_queue);
+ return container_of(fastd_queue_get(ctx, &ctx->task_queue), fastd_task, entry);
}
static void fastd_task_put_send_type(fastd_context *ctx, fastd_peer *peer, uint8_t packet_type, fastd_buffer buffer) {
- fastd_task_send *task = malloc(sizeof(fastd_task_send));
+ fastd_task *task = malloc(sizeof(fastd_task));
task->type = TASK_SEND;
task->peer = peer;
- task->packet_type = packet_type;
- task->buffer = buffer;
+ task->send.packet_type = packet_type;
+ task->send.buffer = buffer;
- fastd_queue_put(ctx, &ctx->task_queue, task, 0);
+ fastd_queue_put(ctx, &ctx->task_queue, &task->entry, 0);
}
void fastd_task_put_send_handshake(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) {
@@ -53,32 +52,32 @@ void fastd_task_put_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buff
}
void fastd_task_put_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) {
- fastd_task_handle_recv *task = malloc(sizeof(fastd_task_handle_recv));
+ fastd_task *task = malloc(sizeof(fastd_task));
task->type = TASK_HANDLE_RECV;
task->peer = peer;
- task->buffer = buffer;
+ task->handle_recv.buffer = buffer;
- fastd_queue_put(ctx, &ctx->task_queue, task, 0);
+ fastd_queue_put(ctx, &ctx->task_queue, &task->entry, 0);
}
void fastd_task_schedule_handshake(fastd_context *ctx, fastd_peer *peer, int timeout) {
- fastd_task_handshake *task = malloc(sizeof(fastd_task_handshake));
+ fastd_task *task = malloc(sizeof(fastd_task));
task->type = TASK_HANDSHAKE;
task->peer = peer;
- fastd_queue_put(ctx, &ctx->task_queue, task, timeout);
+ fastd_queue_put(ctx, &ctx->task_queue, &task->entry, timeout);
}
-static bool delete_task(void *data, void *extra) {
- fastd_task *task = data;
+static bool delete_task(fastd_queue_entry *data, void *extra) {
+ fastd_task *task = container_of(data, fastd_task, entry);
fastd_peer *peer = extra;
- if (task->any.peer != peer)
+ if (task->peer != peer)
return true;
- switch (task->any.type) {
+ switch (task->type) {
case TASK_SEND:
fastd_buffer_free(task->send.buffer);
break;
diff --git a/src/task.h b/src/task.h
index 733b671..367502e 100644
--- a/src/task.h
+++ b/src/task.h
@@ -41,42 +41,37 @@ typedef enum _fastd_task_type {
} fastd_task_type;
typedef struct _fastd_task_any {
- fastd_task_type type;
- fastd_peer *peer;
} fastd_task_any;
typedef struct _fastd_task_send {
- fastd_task_type type;
- fastd_peer *peer;
fastd_packet_type packet_type;
fastd_buffer buffer;
} fastd_task_send;
typedef struct _fastd_task_handle_recv {
- fastd_task_type type;
- fastd_peer *peer;
- fastd_packet_type packet_type;
fastd_buffer buffer;
} fastd_task_handle_recv;
-typedef struct _fastd_task_handshake {
+typedef struct _fastd_task {
+ fastd_queue_entry entry;
+
fastd_task_type type;
fastd_peer *peer;
-} fastd_task_handshake;
-typedef union _fastd_task {
- fastd_task_any any;
- fastd_task_send send;
- fastd_task_handle_recv handle_recv;
- fastd_task_handshake handshake;
+ union {
+ fastd_task_send send;
+ fastd_task_handle_recv handle_recv;
+ };
} fastd_task;
-fastd_task* fastd_task_get(fastd_context *ctx);
static inline int fastd_task_timeout(fastd_context *ctx) {
return fastd_queue_timeout(ctx, &ctx->task_queue);
}
+
+fastd_task* fastd_task_get(fastd_context *ctx);
+
void fastd_task_put_send_handshake(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
void fastd_task_put_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);