selectPeerStrategy static method
Selects the appropriate traversal strategy for a connection between two peers
Implementation
static TraversalStrategy selectPeerStrategy(NatBehavior localBehavior, NatBehavior remoteBehavior) {
// If either behavior is unknown, use the strategy for the known behavior
if (localBehavior.mappingBehavior == NatMappingBehavior.unknown ||
localBehavior.filteringBehavior == NatFilteringBehavior.unknown) {
return selectStrategy(remoteBehavior);
}
if (remoteBehavior.mappingBehavior == NatMappingBehavior.unknown ||
remoteBehavior.filteringBehavior == NatFilteringBehavior.unknown) {
return selectStrategy(localBehavior);
}
// If both are endpoint-independent mapping and filtering, direct connection may work
if (localBehavior.mappingBehavior == NatMappingBehavior.endpointIndependent &&
localBehavior.filteringBehavior == NatFilteringBehavior.endpointIndependent &&
remoteBehavior.mappingBehavior == NatMappingBehavior.endpointIndependent &&
remoteBehavior.filteringBehavior == NatFilteringBehavior.endpointIndependent) {
return TraversalStrategy.direct;
}
// If both have endpoint-independent mapping, UDP hole punching is likely to work
if (localBehavior.mappingBehavior == NatMappingBehavior.endpointIndependent &&
remoteBehavior.mappingBehavior == NatMappingBehavior.endpointIndependent) {
return TraversalStrategy.udpHolePunching;
}
// If either has address-and-port-dependent mapping (symmetric NAT), TCP hole punching might be needed
if (localBehavior.mappingBehavior == NatMappingBehavior.addressAndPortDependent ||
remoteBehavior.mappingBehavior == NatMappingBehavior.addressAndPortDependent) {
return TraversalStrategy.tcpHolePunching;
}
// For other combinations, UDP hole punching might work but is less reliable
return TraversalStrategy.udpHolePunching;
}