mirror of https://github.com/dswd/vpncloud.git
Implemented IPv6
This commit is contained in:
parent
12b5b17c3b
commit
8e34acb5de
|
@ -29,7 +29,6 @@ use cloud::GenericCloud;
|
||||||
use udpmessage::VERSION;
|
use udpmessage::VERSION;
|
||||||
use crypto::Crypto;
|
use crypto::Crypto;
|
||||||
|
|
||||||
//TODO: Implement IPv6
|
|
||||||
//TODO: Call close
|
//TODO: Call close
|
||||||
|
|
||||||
struct SimpleLogger;
|
struct SimpleLogger;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::{mem, ptr, fmt};
|
use std::{mem, ptr, fmt};
|
||||||
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};
|
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr, SocketAddrV6, Ipv6Addr};
|
||||||
use std::u16;
|
use std::u16;
|
||||||
|
|
||||||
use super::types::{Error, NetworkId, Range, Address};
|
use super::types::{Error, NetworkId, Range, Address};
|
||||||
|
@ -109,13 +109,13 @@ pub fn decode<'a>(data: &'a mut [u8], crypto: &mut Crypto) -> Result<(Options, M
|
||||||
if end < pos + 1 {
|
if end < pos + 1 {
|
||||||
return Err(Error::ParseError("Empty peers"));
|
return Err(Error::ParseError("Empty peers"));
|
||||||
}
|
}
|
||||||
|
let mut peers = Vec::new();
|
||||||
let count = data[pos];
|
let count = data[pos];
|
||||||
pos += 1;
|
pos += 1;
|
||||||
let len = count as usize * 6;
|
let len = count as usize * 6;
|
||||||
if end < pos + len {
|
if end < pos + len {
|
||||||
return Err(Error::ParseError("Peer data too short"));
|
return Err(Error::ParseError("Peer data too short"));
|
||||||
}
|
}
|
||||||
let mut peers = Vec::with_capacity(count as usize);
|
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
let (ip, port) = unsafe {
|
let (ip, port) = unsafe {
|
||||||
let ip = as_obj::<[u8; 4]>(&data[pos..]);
|
let ip = as_obj::<[u8; 4]>(&data[pos..]);
|
||||||
|
@ -128,6 +128,26 @@ pub fn decode<'a>(data: &'a mut [u8], crypto: &mut Crypto) -> Result<(Options, M
|
||||||
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]), port));
|
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]), port));
|
||||||
peers.push(addr);
|
peers.push(addr);
|
||||||
}
|
}
|
||||||
|
let count = data[pos];
|
||||||
|
pos += 1;
|
||||||
|
let len = count as usize * 18;
|
||||||
|
if end < pos + len {
|
||||||
|
return Err(Error::ParseError("Peer data too short"));
|
||||||
|
}
|
||||||
|
for _ in 0..count {
|
||||||
|
let (ip, port) = unsafe {
|
||||||
|
let ip = as_obj::<[u16; 8]>(&data[pos..]);
|
||||||
|
pos += 16;
|
||||||
|
let port = *as_obj::<u16>(&data[pos..]);
|
||||||
|
let port = u16::from_be(port);
|
||||||
|
pos += 2;
|
||||||
|
(ip, port)
|
||||||
|
};
|
||||||
|
let addr = SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(u16::from_be(ip[0]),
|
||||||
|
u16::from_be(ip[1]), u16::from_be(ip[2]), u16::from_be(ip[3]), u16::from_be(ip[4]),
|
||||||
|
u16::from_be(ip[5]), u16::from_be(ip[6]), u16::from_be(ip[7])), port, 0, 0));
|
||||||
|
peers.push(addr);
|
||||||
|
}
|
||||||
Message::Peers(peers)
|
Message::Peers(peers)
|
||||||
},
|
},
|
||||||
2 => {
|
2 => {
|
||||||
|
@ -192,30 +212,46 @@ pub fn encode(options: &Options, msg: &Message, buf: &mut [u8], crypto: &mut Cry
|
||||||
pos += data.len();
|
pos += data.len();
|
||||||
},
|
},
|
||||||
&Message::Peers(ref peers) => {
|
&Message::Peers(ref peers) => {
|
||||||
let count_pos = pos;
|
let mut v4addrs = Vec::new();
|
||||||
pos += 1;
|
let mut v6addrs = Vec::new();
|
||||||
assert!(buf.len() >= 2 + peers.len() * mem::size_of::<SocketAddrV4>());
|
|
||||||
let mut count = 0;
|
|
||||||
for p in peers {
|
for p in peers {
|
||||||
match p {
|
match p {
|
||||||
&SocketAddr::V4(addr) => {
|
&SocketAddr::V4(addr) => v4addrs.push(addr),
|
||||||
let ip = addr.ip().octets();
|
&SocketAddr::V6(addr) => v6addrs.push(addr)
|
||||||
let port = addr.port();
|
|
||||||
unsafe {
|
|
||||||
ptr::copy_nonoverlapping(ip.as_ptr(), buf[pos..].as_mut_ptr(), ip.len());
|
|
||||||
pos += ip.len();
|
|
||||||
let port = mem::transmute::<u16, [u8; 2]>(port.to_be());
|
|
||||||
ptr::copy_nonoverlapping(port.as_ptr(), buf[pos..].as_mut_ptr(), port.len());
|
|
||||||
pos += port.len();
|
|
||||||
}
|
|
||||||
count += 1;
|
|
||||||
},
|
|
||||||
&SocketAddr::V6(_addr) => unimplemented!()
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
buf[count_pos] = count;
|
assert!(v4addrs.len() <= 255);
|
||||||
buf[pos] = 0;
|
assert!(v6addrs.len() <= 255);
|
||||||
|
assert!(buf.len() >= pos + 2 + v4addrs.len() * 6 + v6addrs.len() * 18);
|
||||||
|
buf[pos] = v4addrs.len() as u8;
|
||||||
pos += 1;
|
pos += 1;
|
||||||
|
for addr in v4addrs {
|
||||||
|
let ip = addr.ip().octets();
|
||||||
|
let port = addr.port();
|
||||||
|
unsafe {
|
||||||
|
ptr::copy_nonoverlapping(ip.as_ptr(), buf[pos..].as_mut_ptr(), ip.len());
|
||||||
|
pos += ip.len();
|
||||||
|
let port = mem::transmute::<u16, [u8; 2]>(port.to_be());
|
||||||
|
ptr::copy_nonoverlapping(port.as_ptr(), buf[pos..].as_mut_ptr(), port.len());
|
||||||
|
pos += port.len();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
buf[pos] = v6addrs.len() as u8;
|
||||||
|
pos += 1;
|
||||||
|
for addr in v6addrs {
|
||||||
|
let mut ip = addr.ip().segments();
|
||||||
|
for i in 0..ip.len() {
|
||||||
|
ip[i] = ip[i].to_be();
|
||||||
|
}
|
||||||
|
let port = addr.port();
|
||||||
|
unsafe {
|
||||||
|
ptr::copy_nonoverlapping(ip.as_ptr() as *const u8, buf[pos..].as_mut_ptr(), 16);
|
||||||
|
pos += ip.len();
|
||||||
|
let port = mem::transmute::<u16, [u8; 2]>(port.to_be());
|
||||||
|
ptr::copy_nonoverlapping(port.as_ptr(), buf[pos..].as_mut_ptr(), port.len());
|
||||||
|
pos += port.len();
|
||||||
|
}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
&Message::Init(ref ranges) => {
|
&Message::Init(ref ranges) => {
|
||||||
assert!(buf.len() >= pos + 1);
|
assert!(buf.len() >= pos + 1);
|
||||||
|
|
Loading…
Reference in New Issue