From e2bcecad821f841ac40d0e0939f5805f8d142700 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 27 Feb 2012 21:28:40 +0100 Subject: Use custom buffers instead of struct iovec --- src/fastd.c | 38 +++++++++++++++++++++----------------- src/fastd.h | 23 +++++++++++++++++++++-- src/handshake.c | 42 ++++++++++++++++++++---------------------- src/handshake.h | 2 +- src/method_null.c | 6 +++--- src/task.c | 8 ++++---- src/task.h | 10 +++++----- 7 files changed, 75 insertions(+), 54 deletions(-) diff --git a/src/fastd.c b/src/fastd.c index b0cf3b4..0d4f1c1 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -152,21 +152,24 @@ static void handle_tasks(fastd_context *ctx) { msg.msg_name = &sendaddr; msg.msg_namelen = sizeof(sendaddr); - struct iovec vec[2] = { { .iov_base = &task->send.packet_type, .iov_len = 1 }, task->send.buffer }; + struct iovec vec[2] = { + { .iov_base = &task->send.packet_type, .iov_len = 1 }, + { .iov_base = task->send.buffer.base, .iov_len = task->send.buffer.len } + }; msg.msg_iov = vec; - msg.msg_iovlen = 2; + msg.msg_iovlen = task->send.buffer.len ? 2 : 1; sendmsg(ctx->sockfd, &msg, 0); } - free(task->send.buffer.iov_base); + fastd_buffer_free(task->send.buffer); break; case TASK_HANDLE_RECV: // TODO Handle source address - writev(ctx->tunfd, &task->handle_recv.buffer, 1); - free(task->handle_recv.buffer.iov_base); + write(ctx->tunfd, task->handle_recv.buffer.base, task->handle_recv.buffer.len); + fastd_buffer_free(task->handle_recv.buffer); break; default: @@ -190,14 +193,14 @@ static void handle_input(fastd_context *ctx) { if (fds[0].revents & POLLIN) { size_t max_len = fastd_max_packet_size(ctx); - void *buffer = malloc(max_len); + fastd_buffer buffer = fastd_buffer_alloc(max_len, 0); - ssize_t len = read(ctx->tunfd, buffer, max_len); + ssize_t len = read(ctx->tunfd, buffer.base, max_len); if (len < 0) exit_errno(ctx, "read"); - uint8_t *src_addr = get_source_address(ctx, buffer); - uint8_t *dest_addr = get_dest_address(ctx, buffer); + uint8_t *src_addr = get_source_address(ctx, buffer.base); + uint8_t *dest_addr = get_dest_address(ctx, buffer.base); pr_debug(ctx, "A packet with length %u is to be sent from %02x:%02x:%02x:%02x:%02x:%02x to %02x:%02x:%02x:%02x:%02x:%02x", (unsigned)len, src_addr[0], src_addr[1], src_addr[2], src_addr[3], src_addr[4], src_addr[5], @@ -205,16 +208,18 @@ static void handle_input(fastd_context *ctx) { // TODO find correct peer - struct iovec vec = { .iov_base = buffer, .iov_len = len }; - ctx->conf->method->method_send(ctx, ctx->peers, vec); + ctx->conf->method->method_send(ctx, ctx->peers, buffer); } if (fds[1].revents & POLLIN) { - size_t max_len = ctx->conf->method->method_max_packet_size(ctx); // 1 is the packet type header - void *buffer = malloc(max_len); + size_t max_len = ctx->conf->method->method_max_packet_size(ctx); + fastd_buffer buffer = fastd_buffer_alloc(max_len, 0); uint8_t packet_type; - struct iovec vec[2] = {{ .iov_base = &packet_type, .iov_len = 1 }, { .iov_base = buffer, .iov_len = max_len }}; + struct iovec vec[2] = { + { .iov_base = &packet_type, .iov_len = 1 }, + { .iov_base = buffer.base, .iov_len = max_len } + }; struct sockaddr_in recvaddr; struct msghdr msg; @@ -234,12 +239,11 @@ static void handle_input(fastd_context *ctx) { switch (packet_type) { case 0: vec[1].iov_len = len - 1; - ctx->conf->method->method_handle_recv(ctx, NULL, vec[1]); + ctx->conf->method->method_handle_recv(ctx, NULL, buffer); break; default: - fastd_handshake_handle(ctx, NULL, packet_type, vec[1]); - free(buffer); + fastd_handshake_handle(ctx, NULL, packet_type, buffer); break; } } diff --git a/src/fastd.h b/src/fastd.h index 16be512..db0190d 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -48,6 +48,13 @@ typedef enum _fastd_loglevel { LOG_DEBUG, } fastd_loglevel; +typedef struct _fastd_buffer { + void *base; + size_t len; + + void (*free)(void *free_p); + void *free_p; +} fastd_buffer; typedef enum _fastd_protocol { PROTOCOL_ETHERNET, @@ -90,8 +97,8 @@ typedef struct _fastd_method { void (*method_init)(fastd_context *ctx, const fastd_peer *peer); - void (*method_handle_recv)(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer); - void (*method_send)(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer); + void (*method_handle_recv)(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer); + void (*method_send)(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer); } fastd_method; typedef struct _fastd_config { @@ -134,6 +141,18 @@ struct _fastd_context { #define exit_errno(context, message) exit_fatal(context, "%s: %s", message, strerror(errno)) +static inline fastd_buffer fastd_buffer_alloc(size_t len, size_t head_space) { + uint8_t *ptr = malloc(head_space+len); + return (fastd_buffer){ .base = ptr, .len = len, .free = free, .free_p = ptr+head_space }; +} + +static inline void fastd_buffer_free(fastd_buffer buffer) { + if (buffer.free) { + buffer.free(buffer.free_p); + } +} + + static inline size_t fastd_max_packet_size(const fastd_context *ctx) { switch (ctx->conf->protocol) { case PROTOCOL_ETHERNET: diff --git a/src/handshake.c b/src/handshake.c index f9a1734..5f4645d 100644 --- a/src/handshake.c +++ b/src/handshake.c @@ -35,7 +35,8 @@ void fastd_handshake_send(fastd_context *ctx, const fastd_peer *peer) { size_t method_len = strlen(ctx->conf->method->name); size_t len = sizeof(fastd_packet_request)+method_len; - fastd_packet_request *request = malloc(len); + fastd_buffer buffer = fastd_buffer_alloc(len, 0); + fastd_packet_request *request = buffer.base; request->reply = 0; request->cp = 0; @@ -46,38 +47,37 @@ void fastd_handshake_send(fastd_context *ctx, const fastd_peer *peer) { request->method_len = method_len; strncpy(request->method_name, ctx->conf->method->name, method_len); - struct iovec buffer = { .iov_base = request, .iov_len = len }; fastd_task_put_send_handshake(ctx, peer, buffer); } -void fastd_handshake_handle(fastd_context *ctx, const fastd_peer *peer, uint8_t packet_type, struct iovec buffer) { +void fastd_handshake_handle(fastd_context *ctx, const fastd_peer *peer, uint8_t packet_type, fastd_buffer buffer) { if (packet_type != 1) - return; // TODO + goto end_free; // TODO - if (buffer.iov_len < sizeof(fastd_packet_any)) - return; + if (buffer.len < sizeof(fastd_packet_any)) + goto end_free; - fastd_packet *packet = buffer.iov_base; + fastd_packet *packet = buffer.base; if (!packet->any.reply && !packet->any.cp) { - if (buffer.iov_len < sizeof(fastd_packet_request)) - return; + if (buffer.len < sizeof(fastd_packet_request)) + goto end_free; - if (buffer.iov_len < sizeof(fastd_packet_request) + packet->request.method_len) - return; + if (buffer.len < sizeof(fastd_packet_request) + packet->request.method_len) + goto end_free; if (packet->request.flags) - return; // TODO + goto end_free; // TODO if (packet->request.proto != ctx->conf->protocol) - return; // TODO + goto end_free; // TODO if (packet->request.method_len != strlen(ctx->conf->method->name) || strncmp(packet->request.method_name, ctx->conf->method->name, packet->request.method_len)) - return; // TODO + goto end_free; // TODO - - fastd_packet_reply *reply = malloc(sizeof(fastd_packet_reply)); + fastd_buffer reply_buffer = fastd_buffer_alloc(sizeof(fastd_packet_reply), 0); + fastd_packet_reply *reply = reply_buffer.base; reply->reply = 1; reply->cp = 0; @@ -85,11 +85,9 @@ void fastd_handshake_handle(fastd_context *ctx, const fastd_peer *peer, uint8_t reply->rsv = 0; reply->reply_code = REPLY_SUCCESS; - free(packet); - - buffer.iov_base = reply; - buffer.iov_len = sizeof(fastd_packet_reply); - - fastd_task_put_send_handshake(ctx, peer, buffer); + fastd_task_put_send_handshake(ctx, peer, reply_buffer); } + + end_free: + fastd_buffer_free(buffer); } diff --git a/src/handshake.h b/src/handshake.h index 7fbc549..503d558 100644 --- a/src/handshake.h +++ b/src/handshake.h @@ -31,6 +31,6 @@ #include "fastd.h" void fastd_handshake_send(fastd_context *ctx, const fastd_peer *peer); -void fastd_handshake_handle(fastd_context *ctx, const fastd_peer *peer, uint8_t packet_type, struct iovec buffer); +void fastd_handshake_handle(fastd_context *ctx, const fastd_peer *peer, uint8_t packet_type, fastd_buffer buffer); #endif /* _FASTD_HANDSHAKE_H_ */ diff --git a/src/method_null.c b/src/method_null.c index dea84d4..34d1cce 100644 --- a/src/method_null.c +++ b/src/method_null.c @@ -33,15 +33,15 @@ static size_t null_max_packet_size(fastd_context *ctx) { } static void null_init(fastd_context *ctx, const fastd_peer *peer) { - struct iovec buffer = { .iov_base = NULL, .iov_len = 0 }; + fastd_buffer buffer = { .base = NULL, .len = 0, .free = NULL, .free_p = NULL }; fastd_task_put_send(ctx, peer, buffer); } -static void null_handle_recv(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer) { +static void null_handle_recv(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer) { fastd_task_put_handle_recv(ctx, peer, buffer); } -static void null_send(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer) { +static void null_send(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer) { fastd_task_put_send(ctx, peer, buffer); } diff --git a/src/task.c b/src/task.c index e2c4e99..f3ccfd7 100644 --- a/src/task.c +++ b/src/task.c @@ -33,7 +33,7 @@ fastd_task* fastd_task_get(fastd_context *ctx) { return fastd_queue_get(&ctx->task_queue); } -static void fastd_task_put_send_type(fastd_context *ctx, const fastd_peer *peer, uint8_t packet_type, struct iovec buffer) { +static void fastd_task_put_send_type(fastd_context *ctx, const fastd_peer *peer, uint8_t packet_type, fastd_buffer buffer) { fastd_task_send *task = malloc(sizeof(fastd_task_send)); task->type = TASK_SEND; @@ -44,15 +44,15 @@ static void fastd_task_put_send_type(fastd_context *ctx, const fastd_peer *peer, fastd_queue_put(&ctx->task_queue, task); } -void fastd_task_put_send_handshake(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer) { +void fastd_task_put_send_handshake(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer) { fastd_task_put_send_type(ctx, peer, 1, buffer); } -void fastd_task_put_send(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer) { +void fastd_task_put_send(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer) { fastd_task_put_send_type(ctx, peer, 0, buffer); } -void fastd_task_put_handle_recv(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer) { +void fastd_task_put_handle_recv(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer) { fastd_task_handle_recv *task = malloc(sizeof(fastd_task_handle_recv)); task->type = TASK_HANDLE_RECV; diff --git a/src/task.h b/src/task.h index 4c7bd65..d816de7 100644 --- a/src/task.h +++ b/src/task.h @@ -42,14 +42,14 @@ typedef struct _fastd_task_send { fastd_task_type type; const fastd_peer *peer; uint8_t packet_type; - struct iovec buffer; + fastd_buffer buffer; } fastd_task_send; typedef struct _fastd_task_handle_recv { fastd_task_type type; const fastd_peer *peer; uint8_t packet_type; - struct iovec buffer; + fastd_buffer buffer; } fastd_task_handle_recv; typedef union _fastd_task { @@ -61,9 +61,9 @@ typedef union _fastd_task { fastd_task* fastd_task_get(fastd_context *ctx); -void fastd_task_put_send_handshake(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer); +void fastd_task_put_send_handshake(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer); -void fastd_task_put_send(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer); -void fastd_task_put_handle_recv(fastd_context *ctx, const fastd_peer *peer, struct iovec buffer); +void fastd_task_put_send(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer); +void fastd_task_put_handle_recv(fastd_context *ctx, const fastd_peer *peer, fastd_buffer buffer); #endif /* _FASTD_TASK_H_ */ -- cgit v1.2.3