From 29c8d5636fb7b86e4f9a47a93b2324a53e271a17 Mon Sep 17 00:00:00 2001 From: Jake McGinty Date: Thu, 5 Apr 2018 00:54:12 -0700 Subject: udp: only convert 'mapped', not 'compatible' adddresses, to IPv4 internally --- src/udp/frame.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/udp/frame.rs b/src/udp/frame.rs index 7f38e57..1f4feaf 100644 --- a/src/udp/frame.rs +++ b/src/udp/frame.rs @@ -7,6 +7,7 @@ use futures::{Async, Future, Poll, Stream, Sink, StartSend, AsyncSink, future, s use nix::sys::socket::{sockopt, setsockopt}; use udp::{ConnectedUdpSocket, UdpSocket}; use tokio_core::reactor::Handle; +use std::net::Ipv6Addr; pub enum Socket { Unconnected(UdpSocket), @@ -154,13 +155,23 @@ impl UdpFramed { } } +fn v6_mapped_to_v4(addr: Ipv6Addr) -> Option { + match addr.segments() { + [0, 0, 0, 0, 0, f, g, h] if f == 0xffff => { + Some(Ipv4Addr::new((g >> 8) as u8, g as u8, + (h >> 8) as u8, h as u8)) + }, + _ => None + } +} + pub type PeerServerMessage = (SocketAddr, Vec); pub struct VecUdpCodec; impl VecUdpCodec { fn decode(&mut self, src: &SocketAddr, buf: &[u8]) -> io::Result { let unmapped_ip = match src.ip() { IpAddr::V6(v6addr) => { - if let Some(v4addr) = v6addr.to_ipv4() { + if let Some(v4addr) = v6_mapped_to_v4(v6addr) { IpAddr::V4(v4addr) } else { IpAddr::V6(v6addr) -- cgit v1.2.3-59-g8ed1b