diff options
-rw-r--r-- | src/fastd.c | 11 | ||||
-rw-r--r-- | src/fastd.h | 72 | ||||
-rw-r--r-- | src/handshake.c | 1 | ||||
-rw-r--r-- | src/packet.h | 56 | ||||
-rw-r--r-- | src/peer.h | 33 | ||||
-rw-r--r-- | src/queue.c | 20 | ||||
-rw-r--r-- | src/queue.h | 10 | ||||
-rw-r--r-- | src/task.c | 10 | ||||
-rw-r--r-- | src/task.h | 3 | ||||
-rw-r--r-- | src/types.h | 71 |
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; @@ -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_ */ @@ -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); } @@ -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_ */ |