From adb7453fae67c777974e1d4c1a5f80f2378c61c3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 27 May 2014 22:33:41 +0200 Subject: Merge handle_forward into fastd_send_data --- src/send.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'src/send.c') diff --git a/src/send.c b/src/send.c index 9ebccf9..ce92244 100644 --- a/src/send.c +++ b/src/send.c @@ -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); } -- cgit v1.2.3