兼容纯ipv4
This commit is contained in:
+17
-21
@@ -28,6 +28,7 @@ impl Context {
|
|||||||
is_tcp: bool,
|
is_tcp: bool,
|
||||||
packet_loss_rate: Option<f64>,
|
packet_loss_rate: Option<f64>,
|
||||||
packet_delay: u32,
|
packet_delay: u32,
|
||||||
|
use_ipv6: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let channel_num = main_udp_socket.len();
|
let channel_num = main_udp_socket.len();
|
||||||
assert_ne!(channel_num, 0, "not channel");
|
assert_ne!(channel_num, 0, "not channel");
|
||||||
@@ -51,6 +52,7 @@ impl Context {
|
|||||||
packet_loss_rate,
|
packet_loss_rate,
|
||||||
packet_delay,
|
packet_delay,
|
||||||
main_index: AtomicUsize::new(0),
|
main_index: AtomicUsize::new(0),
|
||||||
|
use_ipv6,
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
inner: Arc::new(inner),
|
inner: Arc::new(inner),
|
||||||
@@ -70,7 +72,7 @@ impl Deref for Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 对称网络增加的udp socket数目,有助于增加打洞成功率
|
/// 对称网络增加的udp socket数目,有助于增加打洞成功率
|
||||||
pub const SYMMETRIC_CHANNEL_NUM: usize = 64;
|
pub const SYMMETRIC_CHANNEL_NUM: usize = 100;
|
||||||
const PACKET_LOSS_RATE_DENOMINATOR: u32 = 100_0000;
|
const PACKET_LOSS_RATE_DENOMINATOR: u32 = 100_0000;
|
||||||
pub struct ContextInner {
|
pub struct ContextInner {
|
||||||
// 核心udp socket
|
// 核心udp socket
|
||||||
@@ -90,6 +92,7 @@ pub struct ContextInner {
|
|||||||
//控制延迟
|
//控制延迟
|
||||||
packet_delay: u32,
|
packet_delay: u32,
|
||||||
main_index: AtomicUsize,
|
main_index: AtomicUsize,
|
||||||
|
use_ipv6: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextInner {
|
impl ContextInner {
|
||||||
@@ -172,15 +175,16 @@ impl ContextInner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn send_main_udp(&self, index: usize, buf: &[u8], mut addr: SocketAddr) -> io::Result<()> {
|
pub fn send_main_udp(&self, index: usize, buf: &[u8], mut addr: SocketAddr) -> io::Result<()> {
|
||||||
//核心udp socket都是ipv6模式,如果是v4地址则需要转换成v6
|
if self.use_ipv6 {
|
||||||
//只有服务器地址可能需要这样转换
|
//如果是v4地址则需要转换成v6
|
||||||
if let SocketAddr::V4(ipv4) = addr {
|
if let SocketAddr::V4(ipv4) = addr {
|
||||||
addr = SocketAddr::V6(SocketAddrV6::new(
|
addr = SocketAddr::V6(SocketAddrV6::new(
|
||||||
ipv4.ip().to_ipv6_mapped(),
|
ipv4.ip().to_ipv6_mapped(),
|
||||||
ipv4.port(),
|
ipv4.port(),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
));
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.main_udp_socket[index].send_to(buf, addr)?;
|
self.main_udp_socket[index].send_to(buf, addr)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -208,17 +212,9 @@ impl ContextInner {
|
|||||||
thread::sleep(Duration::from_millis(1));
|
thread::sleep(Duration::from_millis(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn try_send_all_main(&self, buf: &[u8], mut addr: SocketAddr) {
|
pub fn try_send_all_main(&self, buf: &[u8], addr: SocketAddr) {
|
||||||
if let SocketAddr::V4(ipv4) = addr {
|
for index in 0..self.channel_num() {
|
||||||
addr = SocketAddr::V6(SocketAddrV6::new(
|
if let Err(e) = self.send_main_udp(index, buf, addr) {
|
||||||
ipv4.ip().to_ipv6_mapped(),
|
|
||||||
ipv4.port(),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
for udp in &self.main_udp_socket {
|
|
||||||
if let Err(e) = udp.send_to(buf, addr) {
|
|
||||||
log::warn!("{:?},add={:?}", e, addr);
|
log::warn!("{:?},add={:?}", e, addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-11
@@ -154,13 +154,31 @@ pub fn init_context(
|
|||||||
) -> io::Result<(Context, mio::net::TcpListener)> {
|
) -> io::Result<(Context, mio::net::TcpListener)> {
|
||||||
assert!(!ports.is_empty(), "not channel");
|
assert!(!ports.is_empty(), "not channel");
|
||||||
let mut udps = Vec::with_capacity(ports.len());
|
let mut udps = Vec::with_capacity(ports.len());
|
||||||
|
//检查系统是否支持ipv6
|
||||||
|
let use_ipv6 = match socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::DGRAM, None) {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("{:?}", e);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
for port in &ports {
|
for port in &ports {
|
||||||
//监听v6+v4双栈
|
//监听v6+v4双栈
|
||||||
let address: SocketAddr = format!("[::]:{}", port).parse().unwrap();
|
let (socket, address) = if use_ipv6 {
|
||||||
let socket = socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::DGRAM, None)?;
|
let address: SocketAddr = format!("[::]:{}", port).parse().unwrap();
|
||||||
io_convert(socket.set_only_v6(false), |_| {
|
let socket = socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::DGRAM, None)?;
|
||||||
format!("set_only_v6 failed: {}", &address)
|
io_convert(socket.set_only_v6(false), |_| {
|
||||||
})?;
|
format!("set_only_v6 failed: {}", &address)
|
||||||
|
})?;
|
||||||
|
(socket, address)
|
||||||
|
} else {
|
||||||
|
let address: SocketAddr = format!("0.0.0.0:{}", port).parse().unwrap();
|
||||||
|
(
|
||||||
|
socket2::Socket::new(socket2::Domain::IPV4, socket2::Type::DGRAM, None)?,
|
||||||
|
address,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
io_convert(socket.set_reuse_address(true), |_| {
|
io_convert(socket.set_reuse_address(true), |_| {
|
||||||
format!("set_reuse_address failed: {}", &address)
|
format!("set_reuse_address failed: {}", &address)
|
||||||
})?;
|
})?;
|
||||||
@@ -184,15 +202,24 @@ pub fn init_context(
|
|||||||
is_tcp,
|
is_tcp,
|
||||||
packet_loss_rate,
|
packet_loss_rate,
|
||||||
packet_delay,
|
packet_delay,
|
||||||
|
use_ipv6,
|
||||||
);
|
);
|
||||||
|
|
||||||
let port = context.main_local_udp_port()?[0];
|
let port = context.main_local_udp_port()?[0];
|
||||||
//监听v6+v4双栈,tcp通道使用异步io
|
//监听v6+v4双栈,tcp通道使用异步io
|
||||||
let address: SocketAddr = format!("[::]:{}", port).parse().unwrap();
|
let (socket, address) = if use_ipv6 {
|
||||||
let socket = socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::STREAM, None)?;
|
let address: SocketAddr = format!("[::]:{}", port).parse().unwrap();
|
||||||
io_convert(socket.set_only_v6(false), |_| {
|
let socket = socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::STREAM, None)?;
|
||||||
format!("set_only_v6 failed: {}", &address)
|
io_convert(socket.set_only_v6(false), |_| {
|
||||||
})?;
|
format!("set_only_v6 failed: {}", &address)
|
||||||
|
})?;
|
||||||
|
(socket, address)
|
||||||
|
} else {
|
||||||
|
let address: SocketAddr = format!("0.0.0.0:{}", port).parse().unwrap();
|
||||||
|
let socket = socket2::Socket::new(socket2::Domain::IPV4, socket2::Type::STREAM, None)?;
|
||||||
|
(socket, address)
|
||||||
|
};
|
||||||
|
|
||||||
io_convert(socket.set_reuse_address(true), |_| {
|
io_convert(socket.set_reuse_address(true), |_| {
|
||||||
format!("set_reuse_address failed: {}", &address)
|
format!("set_reuse_address failed: {}", &address)
|
||||||
})?;
|
})?;
|
||||||
@@ -200,7 +227,11 @@ pub fn init_context(
|
|||||||
if ports[0] == 0 {
|
if ports[0] == 0 {
|
||||||
//端口可能冲突,则使用任意端口
|
//端口可能冲突,则使用任意端口
|
||||||
log::warn!("监听tcp端口失败 {:?},重试一次", address);
|
log::warn!("监听tcp端口失败 {:?},重试一次", address);
|
||||||
let address: SocketAddr = format!("[::]:{}", 0).parse().unwrap();
|
let address: SocketAddr = if use_ipv6 {
|
||||||
|
format!("[::]:{}", 0).parse().unwrap()
|
||||||
|
} else {
|
||||||
|
format!("0.0.0.0:{}", port).parse().unwrap()
|
||||||
|
};
|
||||||
io_convert(socket.bind(&address.into()), |_| {
|
io_convert(socket.bind(&address.into()), |_| {
|
||||||
format!("bind failed: {}", &address)
|
format!("bind failed: {}", &address)
|
||||||
})?;
|
})?;
|
||||||
|
|||||||
Reference in New Issue
Block a user