mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 10:14:35 +00:00
nat4-nat4 punch (#388)
this patch optimize the udp hole punch logic: 1. allow start punch hole before stun test complete. 2. add lock to symmetric punch, avoid conflict between concurrent hole punching task. 3. support punching hole for predictable nat4-nat4. 4. make backoff of retry reasonable
This commit is contained in:
@@ -42,6 +42,8 @@ message RpcPacket {
|
||||
int32 trace_id = 9;
|
||||
}
|
||||
|
||||
message Void {}
|
||||
|
||||
message UUID {
|
||||
uint64 high = 1;
|
||||
uint64 low = 2;
|
||||
@@ -57,6 +59,8 @@ enum NatType {
|
||||
PortRestricted = 5;
|
||||
Symmetric = 6;
|
||||
SymUdpFirewall = 7;
|
||||
SymmetricEasyInc = 8;
|
||||
SymmetricEasyDec = 9;
|
||||
}
|
||||
|
||||
message Ipv4Addr { uint32 addr = 1; }
|
||||
|
||||
@@ -93,27 +93,78 @@ service DirectConnectorRpc {
|
||||
rpc GetIpList(GetIpListRequest) returns (GetIpListResponse);
|
||||
}
|
||||
|
||||
message TryPunchHoleRequest { common.SocketAddr local_mapped_addr = 1; }
|
||||
|
||||
message TryPunchHoleResponse { common.SocketAddr remote_mapped_addr = 1; }
|
||||
|
||||
message TryPunchSymmetricRequest {
|
||||
common.SocketAddr listener_addr = 1;
|
||||
uint32 port = 2;
|
||||
repeated common.Ipv4Addr public_ips = 3;
|
||||
uint32 min_port = 4;
|
||||
uint32 max_port = 5;
|
||||
uint32 transaction_id = 6;
|
||||
uint32 round = 7;
|
||||
uint32 last_port_index = 8;
|
||||
message SelectPunchListenerRequest {
|
||||
bool force_new = 1;
|
||||
}
|
||||
|
||||
message TryPunchSymmetricResponse { uint32 last_port_index = 1; }
|
||||
message SelectPunchListenerResponse {
|
||||
common.SocketAddr listener_mapped_addr = 1;
|
||||
}
|
||||
|
||||
message SendPunchPacketConeRequest {
|
||||
common.SocketAddr listener_mapped_addr = 1;
|
||||
common.SocketAddr dest_addr = 2;
|
||||
uint32 transaction_id = 3;
|
||||
// send this many packets in a batch
|
||||
uint32 packet_count_per_batch = 4;
|
||||
// send total this batch count, total packet count = packet_batch_size * packet_batch_count
|
||||
uint32 packet_batch_count = 5;
|
||||
// interval between each batch
|
||||
uint32 packet_interval_ms = 6;
|
||||
}
|
||||
|
||||
message SendPunchPacketHardSymRequest {
|
||||
common.SocketAddr listener_mapped_addr = 1;
|
||||
|
||||
repeated common.Ipv4Addr public_ips = 2;
|
||||
uint32 transaction_id = 3;
|
||||
uint32 port_index = 4;
|
||||
uint32 round = 5;
|
||||
}
|
||||
|
||||
message SendPunchPacketHardSymResponse { uint32 next_port_index = 1; }
|
||||
|
||||
message SendPunchPacketEasySymRequest {
|
||||
common.SocketAddr listener_mapped_addr = 1;
|
||||
repeated common.Ipv4Addr public_ips = 2;
|
||||
uint32 transaction_id = 3;
|
||||
|
||||
uint32 base_port_num = 4;
|
||||
uint32 max_port_num = 5;
|
||||
bool is_incremental = 6;
|
||||
}
|
||||
|
||||
message SendPunchPacketBothEasySymRequest {
|
||||
uint32 udp_socket_count = 1;
|
||||
common.Ipv4Addr public_ip = 2;
|
||||
uint32 transaction_id = 3;
|
||||
|
||||
uint32 dst_port_num = 4;
|
||||
uint32 wait_time_ms = 5;
|
||||
}
|
||||
|
||||
message SendPunchPacketBothEasySymResponse {
|
||||
// is doing punch with other peer
|
||||
bool is_busy = 1;
|
||||
common.SocketAddr base_mapped_addr = 2;
|
||||
}
|
||||
|
||||
service UdpHolePunchRpc {
|
||||
rpc TryPunchHole(TryPunchHoleRequest) returns (TryPunchHoleResponse);
|
||||
rpc TryPunchSymmetric(TryPunchSymmetricRequest)
|
||||
returns (TryPunchSymmetricResponse);
|
||||
rpc SelectPunchListener(SelectPunchListenerRequest)
|
||||
returns (SelectPunchListenerResponse);
|
||||
|
||||
// send packet to one remote_addr, used by nat1-3 to nat1-3
|
||||
rpc SendPunchPacketCone(SendPunchPacketConeRequest) returns (common.Void);
|
||||
|
||||
// send packet to multiple remote_addr (birthday attack), used by nat4 to nat1-3
|
||||
rpc SendPunchPacketHardSym(SendPunchPacketHardSymRequest)
|
||||
returns (SendPunchPacketHardSymResponse);
|
||||
rpc SendPunchPacketEasySym(SendPunchPacketEasySymRequest)
|
||||
returns (common.Void);
|
||||
|
||||
// nat4 to nat4 (both predictably)
|
||||
rpc SendPunchPacketBothEasySym(SendPunchPacketBothEasySymRequest)
|
||||
returns (SendPunchPacketBothEasySymResponse);
|
||||
}
|
||||
|
||||
message DirectConnectedPeerInfo { int32 latency_ms = 1; }
|
||||
|
||||
@@ -146,7 +146,7 @@ impl Server {
|
||||
async fn handle_rpc_request(packet: RpcPacket, reg: Arc<ServiceRegistry>) -> Result<Bytes> {
|
||||
let rpc_request = RpcRequest::decode(Bytes::from(packet.body))?;
|
||||
let timeout_duration = std::time::Duration::from_millis(rpc_request.timeout_ms as u64);
|
||||
let ctrl = RpcController {};
|
||||
let ctrl = RpcController::default();
|
||||
Ok(timeout(
|
||||
timeout_duration,
|
||||
reg.call_method(
|
||||
|
||||
@@ -13,6 +13,34 @@ pub trait Controller: Send + Sync + 'static {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BaseController {}
|
||||
pub struct BaseController {
|
||||
pub timeout_ms: i32,
|
||||
pub trace_id: i32,
|
||||
}
|
||||
|
||||
impl Controller for BaseController {}
|
||||
impl Controller for BaseController {
|
||||
fn timeout_ms(&self) -> i32 {
|
||||
self.timeout_ms
|
||||
}
|
||||
|
||||
fn set_timeout_ms(&mut self, timeout_ms: i32) {
|
||||
self.timeout_ms = timeout_ms;
|
||||
}
|
||||
|
||||
fn set_trace_id(&mut self, trace_id: i32) {
|
||||
self.trace_id = trace_id;
|
||||
}
|
||||
|
||||
fn trace_id(&self) -> i32 {
|
||||
self.trace_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BaseController {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
timeout_ms: 5000,
|
||||
trace_id: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,14 +121,14 @@ async fn rpc_basic_test() {
|
||||
|
||||
// small size req and resp
|
||||
|
||||
let ctrl = RpcController {};
|
||||
let ctrl = RpcController::default();
|
||||
let input = SayHelloRequest {
|
||||
name: "world".to_string(),
|
||||
};
|
||||
let ret = out.say_hello(ctrl, input).await;
|
||||
assert_eq!(ret.unwrap().greeting, "Hello world!");
|
||||
|
||||
let ctrl = RpcController {};
|
||||
let ctrl = RpcController::default();
|
||||
let input = SayGoodbyeRequest {
|
||||
name: "world".to_string(),
|
||||
};
|
||||
@@ -136,7 +136,7 @@ async fn rpc_basic_test() {
|
||||
assert_eq!(ret.unwrap().greeting, "Goodbye, world!");
|
||||
|
||||
// large size req and resp
|
||||
let ctrl = RpcController {};
|
||||
let ctrl = RpcController::default();
|
||||
let name = random_string(20 * 1024 * 1024);
|
||||
let input = SayGoodbyeRequest { name: name.clone() };
|
||||
let ret = out.say_goodbye(ctrl, input).await;
|
||||
@@ -160,7 +160,7 @@ async fn rpc_timeout_test() {
|
||||
.client
|
||||
.scoped_client::<GreetingClientFactory<RpcController>>(1, 1, "test".to_string());
|
||||
|
||||
let ctrl = RpcController {};
|
||||
let ctrl = RpcController::default();
|
||||
let input = SayHelloRequest {
|
||||
name: "world".to_string(),
|
||||
};
|
||||
@@ -199,7 +199,7 @@ async fn standalone_rpc_test() {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let ctrl = RpcController {};
|
||||
let ctrl = RpcController::default();
|
||||
let input = SayHelloRequest {
|
||||
name: "world".to_string(),
|
||||
};
|
||||
@@ -211,7 +211,7 @@ async fn standalone_rpc_test() {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let ctrl = RpcController {};
|
||||
let ctrl = RpcController::default();
|
||||
let input = SayGoodbyeRequest {
|
||||
name: "world".to_string(),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user