protected void RaiseDeviceFound(NatRouterDevice device) { CurrentSearchCancellationTokenSource?.Cancel(); _deviceFound(device); }
async void Configure(NatRouterDevice device, int[] localUdpPorts) { try { Log_deepDetail($">> NatUtility.Configure(localUdpPorts={String.Join(";", localUdpPorts.Select(x=>x.ToString()))}) device={device}"); var externalIP = await device.GetExternalIPAsync(); Log_deepDetail($"device={device}, externalIP={externalIP}"); if (externalIP == null) { return; } if (externalIP.ToString() == "0.0.0.0") { return; } if (externalIP.ToString() == "127.0.0.1") { return; } var localUdpPortsHS = new HashSet <int>(localUdpPorts); var existingMappings = await device.GetAllMappingsAsync(); foreach (var existingMapping in existingMappings) { if (existingMapping.Protocol == IpProtocol.Udp) { if (localUdpPortsHS.Contains(existingMapping.PrivatePort)) { Log_deepDetail($"mapping already exists at router: {existingMapping.Description} {existingMapping.PrivatePort}-{existingMapping.PublicPort} {existingMapping.Protocol}"); localUdpPortsHS.Remove(existingMapping.PrivatePort); } else { try { Log_deepDetail($"deleting unused existing mapping: {existingMapping.Description} {existingMapping.PrivatePort}-{existingMapping.PublicPort} {existingMapping.Protocol}"); await device.DeletePortMappingAsync(existingMapping); } catch (Exception exc) { Log_deepDetail($"could not delete existing unused mapping to UDP port {existingMapping.PrivatePort} at {device}: {exc.Message}"); } } } } if (localUdpPortsHS.Count == 0) { Log_higherLevelDetail($"no new mappings to create"); _succeeded = true; return; } foreach (var localUdpPort in localUdpPortsHS) { try { var mapping2 = new Mapping(IpProtocol.Udp, localUdpPort, localUdpPort); // todo use public port = * (0) try { await device.CreatePortMappingAsync(mapping2); Log_higherLevelDetail($"successfully created mapping: externalIP={externalIP}, protocol={mapping2.Protocol}, publicPort={mapping2.PublicPort}, privatePort={mapping2.PrivatePort}"); _succeeded = true; } catch (MappingException exc) { Log_deepDetail($"first-trial error when adding port mapping to {device}: {exc.Message}. trying again..."); try { await device.DeletePortMappingAsync(mapping2); await device.CreatePortMappingAsync(mapping2); Log_higherLevelDetail($"successfully created mapping (2nd trial): externalIP={externalIP}, protocol={mapping2.Protocol}, publicPort={mapping2.PublicPort}, privatePort={mapping2.PrivatePort}"); _succeeded = true; } catch (MappingException exc2) { Log_mediumPain($"second-trial error when adding port {localUdpPort} mapping to {device}: {exc2.Message}"); } } } catch (Exception exc) { Log_mediumPain($"error when creating mapping for port {localUdpPort} at NAT device {device}: {exc}"); } } // Try to retrieve confirmation on the port map we just created: //try //{ // var m = await device.GetSpecificMappingAsync(Dcomms.NAT.Protocol.Udp, 6020); // WriteToLog_drpGeneral_guiActivity($"Verified Mapping: externalIP={externalIP}, protocol={m.Protocol}, publicPort={m.PublicPort}, privatePort={m.PrivatePort}"); //} //catch (Exception exc) //{ // WriteToLog_drpGeneral_guiActivity($"Couldn't verify mapping (GetSpecificMappingAsync failed): {exc}"); //} } catch (Exception exc) { Log_mediumPain($"error when configuring NAT device {device}: {exc}"); } }