selectPeerStrategy static method

TraversalStrategy selectPeerStrategy(
  1. NatBehavior localBehavior,
  2. NatBehavior remoteBehavior
)

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;
}