diff options
-rw-r--r-- | src/fastd.c | 20 | ||||
-rw-r--r-- | src/fastd.h | 5 | ||||
-rw-r--r-- | src/queue.c | 39 | ||||
-rw-r--r-- | src/queue.h | 7 | ||||
-rw-r--r-- | src/task.c | 29 | ||||
-rw-r--r-- | src/task.h | 25 |
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_ */ @@ -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; @@ -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); |