From d52f208d9fb6381f3c3656c5916866a4b779fa82 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 20 Aug 2013 16:16:55 +0200 Subject: Use v4-mapped addresses for IPv4 peers on IPv6 sockets This is needed at least on FreeBSD --- src/peer.c | 13 +++++++++++++ src/peer.h | 1 + src/send.c | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/src/peer.c b/src/peer.c index dae8141..fc22a50 100644 --- a/src/peer.c +++ b/src/peer.c @@ -324,6 +324,19 @@ void fastd_peer_address_simplify(fastd_peer_address_t *addr) { } } +void fastd_peer_address_widen(fastd_peer_address_t *addr) { + if (addr->sa.sa_family == AF_INET) { + struct sockaddr_in addr4 = addr->in; + + memset(addr, 0, sizeof(fastd_peer_address_t)); + addr->in6.sin6_family = AF_INET6; + addr->in6.sin6_port = addr4.sin_port; + addr->in6.sin6_addr.s6_addr[10] = 0xff; + addr->in6.sin6_addr.s6_addr[11] = 0xff; + memcpy(&addr->in6.sin6_addr.s6_addr[12], &addr4.sin_addr.s_addr, 4); + } +} + static inline void reset_peer_address(fastd_context_t *ctx, fastd_peer_t *peer) { if (fastd_peer_is_established(peer)) diff --git a/src/peer.h b/src/peer.h index 7d85c39..1c939b5 100644 --- a/src/peer.h +++ b/src/peer.h @@ -100,6 +100,7 @@ struct fastd_remote_config { bool fastd_peer_address_equal(const fastd_peer_address_t *addr1, const fastd_peer_address_t *addr2); void fastd_peer_address_simplify(fastd_peer_address_t *addr); +void fastd_peer_address_widen(fastd_peer_address_t *addr); static inline uint16_t fastd_peer_address_get_port(const fastd_peer_address_t *addr) { switch (addr->sa.sa_family) { diff --git a/src/send.c b/src/send.c index 8707e31..3a990d2 100644 --- a/src/send.c +++ b/src/send.c @@ -70,6 +70,7 @@ static void send_type(fastd_context_t *ctx, const fastd_socket_t *sock, const fa struct msghdr msg = {}; char cbuf[1024] = {}; + fastd_peer_address_t remote_addr6; switch (remote_addr->sa.sa_family) { case AF_INET: @@ -86,6 +87,14 @@ static void send_type(fastd_context_t *ctx, const fastd_socket_t *sock, const fa exit_bug(ctx, "unsupported address family"); } + if (sock->bound_addr->sa.sa_family == AF_INET6) { + remote_addr6 = *remote_addr; + fastd_peer_address_widen(&remote_addr6); + + msg.msg_name = (void*)&remote_addr6.in6; + msg.msg_namelen = sizeof(struct sockaddr_in6); + } + struct iovec iov[2] = { { .iov_base = &packet_type, .iov_len = 1 }, { .iov_base = buffer.data, .iov_len = buffer.len } -- cgit v1.2.3