summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fastd.c11
-rw-r--r--src/fastd.h72
-rw-r--r--src/handshake.c1
-rw-r--r--src/packet.h56
-rw-r--r--src/peer.h33
-rw-r--r--src/queue.c20
-rw-r--r--src/queue.h10
-rw-r--r--src/task.c10
-rw-r--r--src/task.h3
-rw-r--r--src/types.h71
10 files changed, 166 insertions, 121 deletions
diff --git a/src/fastd.c b/src/fastd.c
index fdd3f5c..e0a03ad 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -317,7 +317,8 @@ static void configure(fastd_context *ctx, fastd_config *conf, int argc, char *ar
}
}
- if (conf->bind_addr_in.sin_family == AF_UNSPEC && conf->bind_addr_in6.sin6_family == AF_UNSPEC) {
+ if (conf->n_floating && conf->bind_addr_in.sin_family == AF_UNSPEC
+ && conf->bind_addr_in6.sin6_family == AF_UNSPEC) {
conf->bind_addr_in.sin_family = AF_INET;
conf->bind_addr_in6.sin6_family = AF_INET6;
}
@@ -347,6 +348,10 @@ static void init_peers(fastd_context *ctx) {
fastd_peer_add(ctx, peer_conf);
}
+static void update_time(fastd_context *ctx) {
+ clock_gettime(CLOCK_MONOTONIC, &ctx->now);
+}
+
static void handle_tasks(fastd_context *ctx) {
fastd_task *task;
while ((task = fastd_task_get(ctx)) != NULL) {
@@ -565,6 +570,8 @@ static void handle_input(fastd_context *ctx) {
if (ret < 0)
exit_errno(ctx, "poll");
+ update_time(ctx);
+
if (fds[0].revents & POLLIN)
handle_tun(ctx);
if (fds[1].revents & POLLIN)
@@ -582,6 +589,8 @@ int main(int argc, char *argv[]) {
configure(&ctx, &conf, argc, argv);
ctx.conf = &conf;
+ update_time(&ctx);
+
init_peers(&ctx);
init_tuntap(&ctx);
diff --git a/src/fastd.h b/src/fastd.h
index bd0d633..c8cad39 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -28,6 +28,7 @@
#ifndef _FASTD_FASTD_H_
#define _FASTD_FASTD_H_
+#include "types.h"
#include "queue.h"
#include <errno.h>
@@ -40,77 +41,18 @@
#include <string.h>
#include <sys/uio.h>
#include <sys/socket.h>
+#include <time.h>
-typedef enum _fastd_loglevel {
- LOG_FATAL = 0,
- LOG_ERROR,
- LOG_WARN,
- LOG_INFO,
- LOG_DEBUG,
-} fastd_loglevel;
-
-typedef enum _fastd_packet_type {
- PACKET_DATA = 0,
- PACKET_HANDSHAKE,
-} fastd_packet_type;
-
-typedef struct _fastd_buffer {
+struct _fastd_buffer {
void *base;
size_t base_len;
void *data;
size_t len;
-} fastd_buffer;
-
-typedef enum _fastd_protocol {
- PROTOCOL_ETHERNET,
- PROTOCOL_IP,
-} fastd_protocol;
-
-typedef union _fastd_peer_address {
- struct sockaddr sa;
- struct sockaddr_in in;
- struct sockaddr_in6 in6;
-} fastd_peer_address;
-
-typedef struct _fastd_peer_config {
- struct _fastd_peer_config *next;
-
- fastd_peer_address address;
-} fastd_peer_config;
-
-typedef enum _fastd_peer_state {
- STATE_WAIT,
- STATE_ESTABLISHED,
- STATE_TEMP,
- STATE_TEMP_ESTABLISHED,
-} fastd_peer_state;
-
-typedef struct _fastd_eth_addr {
- uint8_t data[ETH_ALEN];
-} fastd_eth_addr;
-
-typedef struct _fastd_peer {
- struct _fastd_peer *next;
-
- const fastd_peer_config *config;
-
- fastd_peer_address address;
-
- fastd_peer_state state;
- uint8_t last_req_id;
-} fastd_peer;
-
-typedef struct _fastd_peer_eth_addr {
- fastd_eth_addr addr;
- fastd_peer *peer;
-} fastd_peer_eth_addr;
-
-typedef struct _fastd_config fastd_config;
-typedef struct _fastd_context fastd_context;
+};
-typedef struct _fastd_method {
+struct _fastd_method {
const char *name;
bool (*check_config)(fastd_context *ctx, const fastd_config *conf);
@@ -121,7 +63,7 @@ typedef struct _fastd_method {
void (*handle_recv)(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
void (*send)(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
-} fastd_method;
+};
struct _fastd_config {
fastd_loglevel loglevel;
@@ -143,6 +85,8 @@ struct _fastd_config {
struct _fastd_context {
const fastd_config *conf;
+ struct timespec now;
+
fastd_peer *peers;
fastd_queue task_queue;
diff --git a/src/handshake.c b/src/handshake.c
index f9dec71..991d994 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -27,6 +27,7 @@
#include "handshake.h"
#include "packet.h"
+#include "peer.h"
#include "task.h"
#include <string.h>
diff --git a/src/packet.h b/src/packet.h
index b014f2b..12d15fc 100644
--- a/src/packet.h
+++ b/src/packet.h
@@ -32,40 +32,40 @@
#include <stdint.h>
+typedef enum _fastd_packet_type {
+ PACKET_UNKNOWN = 0,
+ PACKET_HANDSHAKE,
+ PACKET_DATA,
+} fastd_packet_type;
+
typedef enum _fastd_reply_code {
REPLY_SUCCESS = 0,
} fastd_reply_code;
-typedef struct __attribute__ ((__packed__)) _fastd_packet_any {
+
#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned req_id : 6;
- unsigned cp : 1;
- unsigned reply : 1;
+#define FASTD_PACKET_COMMON \
+ unsigned req_id : 6; \
+ unsigned cp : 1; \
+ unsigned reply : 1; \
+ uint8_t rsv
#elif defined (__BIG_ENDIAN_BITFIELD)
- unsigned reply : 1;
- unsigned cp : 1;
- unsigned req_id : 6;
+#define FASTD_PACKET_COMMON \
+ unsigned reply : 1; \
+ unsigned cp : 1; \
+ unsigned req_id : 6; \
+ uint8_t rsv
#else
#error "Bitfield endianess not defined."
#endif
- uint8_t rsv;
+
+typedef struct __attribute__ ((__packed__)) _fastd_packet_any {
+ FASTD_PACKET_COMMON;
} fastd_packet_any;
typedef struct __attribute__ ((__packed__)) _fastd_packet_request {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned req_id : 6;
- unsigned cp : 1;
- unsigned reply : 1;
-#elif defined (__BIG_ENDIAN_BITFIELD)
- unsigned reply : 1;
- unsigned cp : 1;
- unsigned req_id : 6;
-#else
-#error "Bitfield endianess not defined."
-#endif
-
- uint8_t rsv;
+ FASTD_PACKET_COMMON;
uint8_t flags;
uint8_t proto;
uint8_t method_len;
@@ -73,19 +73,7 @@ typedef struct __attribute__ ((__packed__)) _fastd_packet_request {
} fastd_packet_request;
typedef struct __attribute__ ((__packed__)) _fastd_packet_reply {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned req_id : 6;
- unsigned cp : 1;
- unsigned reply : 1;
-#elif defined (__BIG_ENDIAN_BITFIELD)
- unsigned reply : 1;
- unsigned cp : 1;
- unsigned req_id : 6;
-#else
-#error "Bitfield endianess not defined."
-#endif
-
- uint8_t rsv;
+ FASTD_PACKET_COMMON;
uint8_t reply_code;
} fastd_packet_reply;
diff --git a/src/peer.h b/src/peer.h
index 46cdca9..64cb912 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -31,6 +31,39 @@
#include "fastd.h"
+union _fastd_peer_address {
+ struct sockaddr sa;
+ struct sockaddr_in in;
+ struct sockaddr_in6 in6;
+};
+
+struct _fastd_peer {
+ fastd_peer *next;
+
+ const fastd_peer_config *config;
+
+ fastd_peer_address address;
+
+ fastd_peer_state state;
+ uint8_t last_req_id;
+};
+
+struct _fastd_peer_config {
+ fastd_peer_config *next;
+
+ fastd_peer_address address;
+};
+
+struct _fastd_eth_addr {
+ uint8_t data[ETH_ALEN];
+};
+
+struct _fastd_peer_eth_addr {
+ fastd_eth_addr addr;
+ fastd_peer *peer;
+};
+
+
const fastd_eth_addr* fastd_get_source_address(const fastd_context *ctx, fastd_buffer buffer);
const fastd_eth_addr* fastd_get_dest_address(const fastd_context *ctx, fastd_buffer buffer);
diff --git a/src/queue.c b/src/queue.c
index e0e25e1..77533f9 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -26,6 +26,7 @@
#include "queue.h"
+#include "fastd.h"
#include <stdint.h>
@@ -35,14 +36,12 @@ static inline int after(const struct timespec *tp1, const struct timespec *tp2)
(tp1->tv_sec == tp2->tv_sec && tp1->tv_nsec > tp2->tv_nsec));
}
-void fastd_queue_put(fastd_queue *queue, void *data, int timeout) {
+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;
- entry->timeout = (struct timespec){ 0, 0 };
+ entry->timeout = ctx->now;
if (timeout) {
- clock_gettime(CLOCK_MONOTONIC, &entry->timeout);
-
entry->timeout.tv_sec += timeout/1000;
entry->timeout.tv_nsec += (timeout%1000)*1e6;
@@ -62,8 +61,8 @@ void fastd_queue_put(fastd_queue *queue, void *data, int timeout) {
}
}
-void* fastd_queue_get(fastd_queue *queue) {
- if (!queue->head || fastd_queue_timeout(queue) > 0)
+void* 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;
@@ -74,21 +73,18 @@ void* fastd_queue_get(fastd_queue *queue) {
return data;
}
-int fastd_queue_timeout(fastd_queue *queue) {
+int fastd_queue_timeout(fastd_context *ctx, fastd_queue *queue) {
if (!queue->head)
return -1;
- struct timespec tp;
- clock_gettime(CLOCK_MONOTONIC, &tp);
-
- int64_t diff_msec = ((int64_t)(queue->head->timeout.tv_sec-tp.tv_sec))*1000 + (queue->head->timeout.tv_nsec-tp.tv_nsec)/1e6;
+ 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;
if (diff_msec < 0)
return 0;
else
return (int)diff_msec;
}
-void fastd_queue_filter(fastd_queue *queue, bool (*pred)(void*, void*), void *extra) {
+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)) {
diff --git a/src/queue.h b/src/queue.h
index f132d1d..320df9f 100644
--- a/src/queue.h
+++ b/src/queue.h
@@ -28,6 +28,8 @@
#ifndef _FASTD_QUEUE_H_
#define _FASTD_QUEUE_H_
+#include "types.h"
+
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
@@ -46,9 +48,9 @@ typedef struct _fastd_queue {
} fastd_queue;
-void fastd_queue_put(fastd_queue *queue, void *data, int timeout);
-void* fastd_queue_get(fastd_queue *queue);
-int fastd_queue_timeout(fastd_queue *queue);
-void fastd_queue_filter(fastd_queue *queue, bool (*pred)(void*, void*), void *extra);
+void fastd_queue_put(fastd_context *ctx, fastd_queue *queue, void *data, int timeout);
+void* 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);
#endif /* _FASTD_QUEUE_H_ */
diff --git a/src/task.c b/src/task.c
index b565f1b..04b8cb1 100644
--- a/src/task.c
+++ b/src/task.c
@@ -30,7 +30,7 @@
fastd_task* fastd_task_get(fastd_context *ctx) {
- return fastd_queue_get(&ctx->task_queue);
+ return fastd_queue_get(ctx, &ctx->task_queue);
}
static void fastd_task_put_send_type(fastd_context *ctx, fastd_peer *peer, uint8_t packet_type, fastd_buffer buffer) {
@@ -41,7 +41,7 @@ static void fastd_task_put_send_type(fastd_context *ctx, fastd_peer *peer, uint8
task->packet_type = packet_type;
task->buffer = buffer;
- fastd_queue_put(&ctx->task_queue, task, 0);
+ fastd_queue_put(ctx, &ctx->task_queue, task, 0);
}
void fastd_task_put_send_handshake(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) {
@@ -59,7 +59,7 @@ void fastd_task_put_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buff
task->peer = peer;
task->buffer = buffer;
- fastd_queue_put(&ctx->task_queue, task, 0);
+ fastd_queue_put(ctx, &ctx->task_queue, task, 0);
}
void fastd_task_schedule_handshake(fastd_context *ctx, fastd_peer *peer, int timeout) {
@@ -68,7 +68,7 @@ void fastd_task_schedule_handshake(fastd_context *ctx, fastd_peer *peer, int tim
task->type = TASK_HANDSHAKE;
task->peer = peer;
- fastd_queue_put(&ctx->task_queue, task, timeout);
+ fastd_queue_put(ctx, &ctx->task_queue, task, timeout);
}
static bool delete_task(void *data, void *extra) {
@@ -97,5 +97,5 @@ static bool delete_task(void *data, void *extra) {
}
void fastd_task_delete_peer(fastd_context *ctx, fastd_peer *peer) {
- fastd_queue_filter(&ctx->task_queue, delete_task, peer);
+ fastd_queue_filter(ctx, &ctx->task_queue, delete_task, peer);
}
diff --git a/src/task.h b/src/task.h
index b65e992..733b671 100644
--- a/src/task.h
+++ b/src/task.h
@@ -29,6 +29,7 @@
#define _FASTD_TASK_H_
#include "fastd.h"
+#include "packet.h"
#include <sys/uio.h>
@@ -73,7 +74,7 @@ typedef union _fastd_task {
fastd_task* fastd_task_get(fastd_context *ctx);
static inline int fastd_task_timeout(fastd_context *ctx) {
- return fastd_queue_timeout(&ctx->task_queue);
+ return fastd_queue_timeout(ctx, &ctx->task_queue);
}
void fastd_task_put_send_handshake(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
diff --git a/src/types.h b/src/types.h
new file mode 100644
index 0000000..af577e3
--- /dev/null
+++ b/src/types.h
@@ -0,0 +1,71 @@
+/*
+ Copyright (c) 2012, Matthias Schiffer <mschiffer@universe-factory.net>
+ Partly based on QuickTun Copyright (c) 2010, Ivo Smits <Ivo@UCIS.nl>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ types.h
+
+ Basic enums and typedefs for common types
+*/
+
+
+#ifndef _FASTD_TYPES_H_
+#define _FASTD_TYPES_H_
+
+typedef enum _fastd_loglevel {
+ LOG_FATAL = 0,
+ LOG_ERROR,
+ LOG_WARN,
+ LOG_INFO,
+ LOG_DEBUG,
+} fastd_loglevel;
+
+typedef enum _fastd_protocol {
+ PROTOCOL_ETHERNET,
+ PROTOCOL_IP,
+} fastd_protocol;
+
+typedef enum _fastd_peer_state {
+ STATE_WAIT,
+ STATE_ESTABLISHED,
+ STATE_TEMP,
+ STATE_TEMP_ESTABLISHED,
+} fastd_peer_state;
+
+
+typedef struct _fastd_buffer fastd_buffer;
+
+typedef union _fastd_peer_address fastd_peer_address;
+typedef struct _fastd_peer_config fastd_peer_config;
+typedef struct _fastd_eth_addr fastd_eth_addr;
+typedef struct _fastd_peer fastd_peer;
+typedef struct _fastd_peer_eth_addr fastd_peer_eth_addr;
+
+typedef struct _fastd_config fastd_config;
+typedef struct _fastd_context fastd_context;
+
+typedef struct _fastd_method fastd_method;
+
+#endif /* _FASTD_TYPES_H_ */