summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fastd.c38
-rw-r--r--src/fastd.h23
-rw-r--r--src/handshake.c42
-rw-r--r--src/handshake.h2
-rw-r--r--src/method_null.c6
-rw-r--r--src/task.c8
-rw-r--r--src/task.h10
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_ */