diff options
-rw-r--r-- | src/fastd.h | 28 | ||||
-rw-r--r-- | src/receive.c | 26 | ||||
-rw-r--r-- | src/send.c | 40 | ||||
-rw-r--r-- | src/tuntap.c | 2 |
4 files changed, 35 insertions, 61 deletions
diff --git a/src/fastd.h b/src/fastd.h index 8a11a41..8e57338 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -301,8 +301,7 @@ extern fastd_config_t conf; /**< The global configuration */ void fastd_send(const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer, size_t stat_size); void fastd_send_handshake(const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer); -void fastd_send_all(fastd_peer_t *source_peer, fastd_buffer_t buffer); -void fastd_send_data(fastd_buffer_t buffer); +void fastd_send_data(fastd_buffer_t buffer, fastd_peer_t *source); void fastd_receive(fastd_socket_t *sock); void fastd_handle_receive(fastd_peer_t *peer, fastd_buffer_t buffer); @@ -390,31 +389,6 @@ static inline size_t fastd_max_inner_packet(void) { } } -/** Returns the source address of an ethernet packet */ -static inline fastd_eth_addr_t fastd_get_source_address(const fastd_buffer_t buffer) { - fastd_eth_addr_t ret; - - switch (conf.mode) { - case MODE_TAP: - memcpy(&ret, buffer.data+offsetof(struct ethhdr, h_source), ETH_ALEN); - return ret; - default: - exit_bug("invalid mode"); - } -} - -/** Returns the destination address of an ethernet packet */ -static inline fastd_eth_addr_t fastd_get_dest_address(const fastd_buffer_t buffer) { - fastd_eth_addr_t ret; - switch (conf.mode) { - case MODE_TAP: - memcpy(&ret, buffer.data+offsetof(struct ethhdr, h_dest), ETH_ALEN); - return ret; - default: - exit_bug("invalid mode"); - } -} - /** Returns the packet size (payload + overhead) \em fastd is configured to transport */ static inline size_t fastd_max_outer_packet(void) { return 1 + fastd_max_inner_packet() + conf.max_overhead; diff --git a/src/receive.c b/src/receive.c index e5c1aeb..6009030 100644 --- a/src/receive.c +++ b/src/receive.c @@ -223,23 +223,11 @@ void fastd_receive(fastd_socket_t *sock) { handle_socket_receive(sock, &local_addr, &recvaddr, buffer); } -static inline void handle_forward(fastd_peer_t *source_peer, fastd_buffer_t buffer) { - fastd_eth_addr_t dest_addr = fastd_get_dest_address(buffer); - - if (fastd_eth_addr_is_unicast(dest_addr)) { - fastd_peer_t *dest_peer = fastd_peer_find_by_eth_addr(dest_addr); - - if (dest_peer) { - if (dest_peer != source_peer) - conf.protocol->send(dest_peer, buffer); - else - fastd_buffer_free(buffer); - - return; - } - } - - fastd_send_all(source_peer, buffer); +/** Returns the source address of an ethernet packet */ +static inline fastd_eth_addr_t get_source_address(const fastd_buffer_t buffer) { + fastd_eth_addr_t ret; + memcpy(&ret, buffer.data+offsetof(struct ethhdr, h_source), ETH_ALEN); + return ret; } /** Handles a received and decrypted payload packet */ @@ -251,7 +239,7 @@ void fastd_handle_receive(fastd_peer_t *peer, fastd_buffer_t buffer) { return; } - fastd_eth_addr_t src_addr = fastd_get_source_address(buffer); + fastd_eth_addr_t src_addr = get_source_address(buffer); if (fastd_eth_addr_is_unicast(src_addr)) fastd_peer_eth_addr_add(peer, src_addr); @@ -263,7 +251,7 @@ void fastd_handle_receive(fastd_peer_t *peer, fastd_buffer_t buffer) { fastd_tuntap_write(buffer); if (conf.mode == MODE_TAP && conf.forward) { - handle_forward(peer, buffer); + fastd_send_data(buffer, peer); return; } @@ -179,52 +179,64 @@ void fastd_send_handshake(const fastd_socket_t *sock, const fastd_peer_address_t } /** Encrypts and sends a payload packet to all peers */ -void fastd_send_all(fastd_peer_t *source_peer, fastd_buffer_t buffer) { +static inline void send_all(fastd_buffer_t buffer, fastd_peer_t *source) { size_t i; for (i = 0; i < VECTOR_LEN(ctx.peers); i++) { - fastd_peer_t *dest_peer = VECTOR_INDEX(ctx.peers, i); - if (dest_peer == source_peer || !fastd_peer_is_established(dest_peer)) + fastd_peer_t *dest = VECTOR_INDEX(ctx.peers, i); + if (dest == source || !fastd_peer_is_established(dest)) continue; /* optimization, primarily for TUN mode: don't duplicate the buffer for the last (or only) peer */ if (i == VECTOR_LEN(ctx.peers)-1) { - conf.protocol->send(dest_peer, buffer); + conf.protocol->send(dest, buffer); return; } - conf.protocol->send(dest_peer, fastd_buffer_dup(buffer, conf.min_encrypt_head_space, conf.min_encrypt_tail_space)); + conf.protocol->send(dest, fastd_buffer_dup(buffer, conf.min_encrypt_head_space, conf.min_encrypt_tail_space)); } fastd_buffer_free(buffer); } -static inline bool send_data_tap_single(fastd_buffer_t buffer) { +/** Returns the destination address of an ethernet packet */ +static inline fastd_eth_addr_t get_dest_address(const fastd_buffer_t buffer) { + fastd_eth_addr_t ret; + memcpy(&ret, buffer.data+offsetof(struct ethhdr, h_dest), ETH_ALEN); + return ret; +} + +static inline bool send_data_tap_single(fastd_buffer_t buffer, fastd_peer_t *source) { if (conf.mode != MODE_TAP) return false; if (buffer.len < ETH_HLEN) { - pr_debug("truncated packet on tap interface"); + pr_debug("truncated ethernet packet"); fastd_buffer_free(buffer); return true; } - fastd_eth_addr_t dest_addr = fastd_get_dest_address(buffer); + fastd_eth_addr_t dest_addr = get_dest_address(buffer); if (!fastd_eth_addr_is_unicast(dest_addr)) return false; - fastd_peer_t *peer = fastd_peer_find_by_eth_addr(dest_addr); + fastd_peer_t *dest = fastd_peer_find_by_eth_addr(dest_addr); - if (!peer) + if (!dest) return false; - conf.protocol->send(peer, buffer); + if (dest == source) { + fastd_buffer_free(buffer); + return true; + } + + conf.protocol->send(dest, buffer); return true; } -void fastd_send_data(fastd_buffer_t buffer) { - if (send_data_tap_single(buffer)) +void fastd_send_data(fastd_buffer_t buffer, fastd_peer_t *source) { + if (send_data_tap_single(buffer, source)) return; /* TUN mode or multicast packet */ - fastd_send_all(NULL, buffer); + send_all(buffer, source); } diff --git a/src/tuntap.c b/src/tuntap.c index 53cbccd..9cf5f15 100644 --- a/src/tuntap.c +++ b/src/tuntap.c @@ -320,7 +320,7 @@ void fastd_tuntap_handle(void) { if (multiaf_tun && conf.mode == MODE_TUN) fastd_buffer_push_head(&buffer, 4); - fastd_send_data(buffer); + fastd_send_data(buffer, NULL); } /** Writes a packet to the TUN/TAP device */ |