private void CreateUPnPMapping() { try { var discoverer = new NatDiscoverer(); var cts = new CancellationTokenSource(3000); NatDevice device = Task.Run(async() => await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts)).Result; // set nat device to ipaddr so that we can our external ip elsewhere in the application IpAddr.Set(device); // int.MaxValue so that a Session object is created internally in the lib, only session objects // are properly renewed, lib has bug (10min intervals)... _ = Task.Run(async() => await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 18910, 18910, int.MaxValue, "sc.Nat"))); Log.NewLine("Successfully created UPnP port mapping."); } catch { Log.NewLine("Could not create UPnP port mapping. Decreased network connectivity."); } }
private async Task <int> GetNatPunchthroughPort(int millisecondsToTry) { NatDiscoverer discoverer = new NatDiscoverer(); CancellationTokenSource cts = new CancellationTokenSource(millisecondsToTry); NatDevice device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp | PortMapper.Pmp, cts); int externalPort = this.externalPortRangeStart; while (externalPort <= this.externalPortRangeEnd) { try { await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, this.internalPort, externalPort, "Main server port")); return(externalPort); } catch (MappingException e) { externalPort++; } } throw new Exception("Failed to punchthrough any ports."); }
private bool acquireRouterDevice() { if (routerDevice != null) { return(true); } try { CancellationTokenSource cts = new CancellationTokenSource(); cts.CancelAfter(4500); Task <NatDevice> devicesDiscoveryTask = natDiscoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts); if (devicesDiscoveryTask.Wait(5000) == true) { NatDevice device = devicesDiscoveryTask.Result; Logging.info(String.Format("Found UPnP device: {0}", device.ToString())); routerDevice = device; return(true); } } catch (AggregateException) { } return(false); }
public static async Task DiscoverNatDevices(int timeout) { NatDiscoverer.TraceSource.Switch.Level = SourceLevels.Verbose; var logChannel = Log.Channel("nat"); NatDiscoverer.TraceSource.Listeners.Add(new TextWriterTraceListener(logChannel.Writer)); var natDiscoverer = new NatDiscoverer(); var token = new CancellationTokenSource(timeout); natDevice = await natDiscoverer.DiscoverDeviceAsync(PortMapper.Upnp, token); try { ExternalIP = await natDevice.GetExternalIPAsync(); } catch (Exception e) { Console.WriteLine("Getting the external IP from NAT device failed: {0}", e.Message); Log.Write("nat", e.StackTrace); } }
private async void checkBox_UseUPnP_CheckedChanged(object sender, EventArgs e) { if (checkBox_UseUPnP.Checked) { label_Status.Text = @"Starting UPnP..."; var discoverer = new NatDiscoverer(); _device = await discoverer.DiscoverDeviceAsync(); await _device.CreatePortMapAsync(_currentMapping = new Mapping(Protocol.Udp, Convert.ToInt32(numeric_Port.Value), Convert.ToInt32(numeric_Port.Value), "Touhou 7")); textBox_upnpIP.Text = (await _device.GetExternalIPAsync()).ToString(); label_Status.Text = @"UPnP started."; } else { label_Status.Text = @"Stopping UPnP..."; await _device.DeletePortMapAsync(_currentMapping); textBox_upnpIP.Text = @"UPnP Disabled"; label_Status.Text = @"UpnP disabled."; } }
/// <summary> /// Creates a new port mapping on the UPnP device. /// </summary> /// <param name="port">The port to map.</param> public async void CreatePortMapAsync(int port) { try { var cts = new CancellationTokenSource(10000); _device = await _discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts); Mapping mapping = new Mapping(Protocol.Tcp, port, port); await _device.CreatePortMapAsync(mapping); if (_mappings.ContainsKey(mapping.PrivatePort)) { _mappings[mapping.PrivatePort] = mapping; } else { _mappings.Add(mapping.PrivatePort, mapping); } } catch (Exception ex) when(ex is MappingException || ex is NatDeviceNotFoundException) { } }
public static void Main(string[] args) { var nat = new NatDiscoverer(); var cts = new CancellationTokenSource(); cts.CancelAfter(5000); NatDevice device = null; var sb = new StringBuilder(); IPAddress ip = null; var t = nat.DiscoverDeviceAsync(PortMapper.Pmp, cts); t.ContinueWith(tt => { device = tt.Result; device.GetExternalIPAsync() .ContinueWith(task => { ip = task.Result; sb.AppendFormat("\nYour IP: {0}", ip); return(device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 1600, 1700, "Open.Nat (temporary)"))); }) .Unwrap() .ContinueWith(task => { return(device.CreatePortMapAsync( new Mapping(Protocol.Tcp, 1601, 1701, "Open.Nat (Session lifetime)"))); }) .Unwrap() .ContinueWith(task => { return(device.CreatePortMapAsync( new Mapping(Protocol.Tcp, 1602, 1702, 0, "Open.Nat (Permanent lifetime)"))); }) .Unwrap() .ContinueWith(task => { return(device.CreatePortMapAsync( new Mapping(Protocol.Tcp, 1603, 1703, 20, "Open.Nat (Manual lifetime)"))); }) .Unwrap() .ContinueWith(task => { sb.AppendFormat("\nAdded mapping: {0}:1700 -> 127.0.0.1:1600\n", ip); sb.AppendFormat( "\n+------+-------------------------------+--------------------------------+------------------------------------+-------------------------+"); sb.AppendFormat("\n| PROT | PUBLIC (Reacheable) | PRIVATE (Your computer) | Descriptopn | |"); sb.AppendFormat( "\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+"); sb.AppendFormat("\n| | IP Address | Port | IP Address | Port | | Expires |"); sb.AppendFormat( "\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+"); return(device.GetAllMappingsAsync()); }) .Unwrap() .ContinueWith(task => { foreach (var mapping in task.Result) { sb.AppendFormat("\n| {5} | {0,-20} | {1,6} | {2,-21} | {3,6} | {4,-35}|{6,25}|", ip, mapping.PublicPort, mapping.PrivateIP, mapping.PrivatePort, mapping.Description, mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP", mapping.Expiration.ToLocalTime()); } sb.AppendFormat( "\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+"); sb.AppendFormat("\n[Removing TCP mapping] {0}:1700 -> 127.0.0.1:1600", ip); return(device.DeletePortMapAsync(new Mapping(Protocol.Tcp, 1600, 1700))); }) .Unwrap() .ContinueWith(task => { sb.AppendFormat("\n[Done]"); Console.WriteLine(sb.ToString()); Console.WriteLine(""); Console.WriteLine("Socket listening on port 1602. Remember, it is mapped to external port 1702!!!"); Console.WriteLine("Test it with http://www.canyouseeme.org/ online tool"); var endPoint = new IPEndPoint(IPAddress.Any, 1602); var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Bind(endPoint); socket.Listen(4); socket.Close(); Console.WriteLine("Press any key to exit..."); }); }, TaskContinuationOptions.OnlyOnRanToCompletion); try { t.Wait(); } catch (AggregateException e) { if (e.InnerException is NatDeviceNotFoundException) { Console.WriteLine("Not found"); Console.WriteLine("Press any key to exit..."); } } Console.ReadKey(); }
private void RaiseDeviceFound(NatDevice device) { _devices.Add(device); var handler = DeviceFound; if(handler!=null) handler(this, new DeviceEventArgs(device)); }
public static void ForwardPorts() { var webServerPort = (int)Settings.Get("WebServer").WebServerPort; var apiPort = (int)Settings.Get("TaskServer").TaskServerPort; var terminalPort = 22008; var screenSharePort = (int)Settings.Get("ScreenShareService").ScreenSharePort; var nat = new NatDiscoverer(); var cts = new CancellationTokenSource(); cts.CancelAfter(5000); NatDevice device = null; var sb = new StringBuilder(); IPAddress ip = null; var t = nat.DiscoverDeviceAsync(PortMapper.Upnp, cts); t.ContinueWith(tt => { device = tt.Result; device.GetExternalIPAsync() .ContinueWith(task => { ; return(device.CreatePortMapAsync( new Mapping(Protocol.Tcp, webServerPort, webServerPort, 0, "Ulterius Web Server"))); }) .Unwrap() .ContinueWith(task => { return(device.CreatePortMapAsync( new Mapping(Protocol.Tcp, screenSharePort, screenSharePort, 0, "Ulterius Screen Share"))); }) .Unwrap() .ContinueWith(task => { return(device.CreatePortMapAsync( new Mapping(Protocol.Tcp, apiPort, apiPort, 0, "Ulterius Api"))); }) .Unwrap() .ContinueWith(task => { return(device.CreatePortMapAsync( new Mapping(Protocol.Tcp, terminalPort, terminalPort, 0, "Ulterius Terminal"))); }) .Unwrap() .ContinueWith(task => { Console.WriteLine("Ports forwarded!"); }); }, TaskContinuationOptions.OnlyOnRanToCompletion); try { t.Wait(); } catch (AggregateException e) { if (e.InnerException is NatDeviceNotFoundException) { Console.WriteLine("No NAT Device Found"); } } }
public DeviceEventArgs(NatDevice device) { Device = device; }
private void AddPortOnDevice(NatDevice device, int port) { device.MapAsync(MappingProtocol.TCP, port, TimeSpan.FromSeconds(7200), cancelSource.Token); device.MapAsync(MappingProtocol.UDP, port, TimeSpan.FromSeconds(7200), cancelSource.Token); }
void deviceFound(object sender, DeviceEventArgs e) { device = e.Device; upnpSem.Release(); }
internal static IPEndPoint GetEndpoint(this NatDevice myDevice) { //TODO backup for when reflection is not available. return(GetDeviceIPAddress(GetDeviceInfo(myDevice))); }
internal static IPAddress GetLocalIPAddress(this NatDevice myDevice) { //TODO backup for when reflection is not available. return(GetPrivateIPAddress(GetDeviceInfo(myDevice))); }
/// <summary> /// Gestion de l'ouverture automatique des ports UDP pour le P2P /// </summary> /// <param name="flag"></param> private void InitUPNP(bool flag) { if (flag) { if (m_bUPNP) { return; } var t = Task.Run(async() => { var nat = new NatDiscoverer(); var cts = new CancellationTokenSource(); try { Device = await nat.DiscoverDeviceAsync(PortMapper.Upnp, cts); #if DEBUG Log.LogMessage("P2PManager: Routeur UPNP détecté", Color.DarkBlue, 1); #endif await Device.CreatePortMapAsync(new Mapping(Open.Nat.Protocol.Udp, m_Port, m_Port, 0, "ffs2playP3D")); #if DEBUG Log.LogMessage("P2PManager: Ouverture du port UPNP ok", Color.DarkBlue, 1); #endif } catch (AggregateException ae) { ae.Handle((x) => { if (x is NatDeviceNotFoundException) { Log.LogMessage("P2PManager: Routeur UPNP introuvable", Color.DarkViolet); return(true); } if (x is MappingException) { Log.LogMessage("P2PManager: Erreur lors de l'ouverture du port " + m_Port.ToString() + " : " + x.Message, Color.DarkViolet); return(true); } return(false); }); } m_bUPNP = true; }); } else { if ((!m_bUPNP) || (Device == null)) { return; } var t = Task.Run(async() => { try { await Device.DeletePortMapAsync(new Mapping(Open.Nat.Protocol.Udp, m_Port, m_Port)); #if DEBUG Log.LogMessage("P2PManager: Fermeture du port UPNP ok", Color.DarkBlue, 1); #endif } catch (AggregateException ae) { ae.Handle((x) => { if (x is MappingException) { Log.LogMessage("P2PManager: Erreur lors de la fermetur du port", Color.DarkViolet); return(true); } return(false); }); } m_bUPNP = false; }); } }
async void StartServer() { if (Settings.Instance.Server.TryUPnP) { Logger.Instance.Log($"Trying to open port {Settings.Instance.Server.Port} using UPnP..."); try { NatDiscoverer discoverer = new NatDiscoverer(); CancellationTokenSource cts = new CancellationTokenSource(2500); NatDevice device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts); await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, Settings.Instance.Server.Port, Settings.Instance.Server.Port, "BeatSaber Multiplayer Server")); Logger.Instance.Log($"Port {Settings.Instance.Server.Port} is open!"); } catch (Exception) { Logger.Instance.Warning($"Can't open port {Settings.Instance.Server.Port} using UPnP!"); } } Logger.Instance.Log("Starting server..."); _listener = new TcpListener(IPAddress.Any, Settings.Instance.Server.Port); _listener.Start(); Logger.Instance.Log("Waiting for clients..."); ServerLoopThread = new Thread(ServerLoop) { IsBackground = true }; ServerLoopThread.Start(); AcceptClientThread(); if (Settings.Instance.Server.WSEnabled) { if (Settings.Instance.Server.TryUPnP) { Logger.Instance.Log($"Trying to open port {Settings.Instance.Server.WSPort} using UPnP..."); try { NatDiscoverer discoverer = new NatDiscoverer(); CancellationTokenSource cts = new CancellationTokenSource(2500); NatDevice device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts); await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, Settings.Instance.Server.WSPort, Settings.Instance.Server.WSPort, "BeatSaber Multiplayer WebSocket Server")); Logger.Instance.Log($"Port {Settings.Instance.Server.WSPort} is open!"); } catch (Exception) { Logger.Instance.Warning($"Can't open port {Settings.Instance.Server.WSPort} using UPnP!"); } } wss = new WebSocketServer(Settings.Instance.Server.WSPort); wss.AddWebSocketService <Broadcast>("/"); wss.Start(); Logger.Instance.Log($"WebSocket Server started @ {Settings.Instance.Server.IP}:{Settings.Instance.Server.WSPort}"); } Dictionary <string, int> _serverHubs = new Dictionary <string, int>(); for (int i = 0; i < Settings.Instance.Server.ServerHubIPs.Length; i++) { if (Settings.Instance.Server.ServerHubPorts.Length <= i) { _serverHubs.Add(Settings.Instance.Server.ServerHubIPs[i], 3700); } else { _serverHubs.Add(Settings.Instance.Server.ServerHubIPs[i], Settings.Instance.Server.ServerHubPorts[i]); } } _serverHubs.AsParallel().ForAll(x => { ServerHubClient client = new ServerHubClient(); _serverHubClients.Add(client); client.Connect(x.Key, x.Value); } ); }
/// <summary> /// /// </summary> /// <param name="cancelTime">Cancellation time in milliseconds</param> /// <returns></returns> private async Task ForwardPort(int internalPort, int externalPort, int cancelTime, Protocol protocol = Protocol.Udp) { var nat = new NatDiscoverer(); var cts = new CancellationTokenSource(); cts.CancelAfter(cancelTime); NatDevice device = null; var sb = new StringBuilder(); IPAddress ip = null; await nat.DiscoverDeviceAsync(PortMapper.Upnp | PortMapper.Pmp, cts) .ContinueWith(task => { device = task.Result; return(device.GetExternalIPAsync()); }) .Unwrap() .ContinueWith(task => { ip = task.Result; this.ip = ip; sb.AppendFormat("\nYour IP: {0}", ip); this.mapping = new Mapping(Protocol.Udp, internalPort, externalPort, lifeTime, "Game Server (Udp)"); return(device.CreatePortMapAsync(mapping)); }) .Unwrap() .ContinueWith(task => { sb.AppendFormat("\nAdded mapping: {0}:{1} -> 127.0.0.1:{2}\n", ip, externalPort, internalPort); sb.AppendFormat("\n+------+-------------------------------+--------------------------------+------------------------------------+-------------------------+"); sb.AppendFormat("\n| PORT | PUBLIC (Reacheable) | PRIVATE (Your computer) | Description | |"); sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+"); sb.AppendFormat("\n| | IP Address | Port | IP Address | Port | | Expires |"); sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+"); return(device.GetAllMappingsAsync()); }) .Unwrap() .ContinueWith(task => { foreach (var mapping in task.Result) { sb.AppendFormat("\n| {5} | {0,-20} | {1,6} | {2,-21} | {3,6} | {4,-35}|{6,25}|", ip, mapping.PublicPort, mapping.PrivateIP, mapping.PrivatePort, mapping.Description, mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP", mapping.Expiration.ToLocalTime()); } sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+"); Found = true; sb.AppendFormat("\n[Done]"); if (logAll) { Debug.Log(sb.ToString()); } return(device.GetAllMappingsAsync()); }) .Unwrap() .ContinueWith(task => { }); }
public async Task Connect() #endif { _server.WhenDiscoveryRequest = () => "HTTP/1.1 200 OK\r\n" + "Server: Custom/1.0 UPnP/1.0 Proc/Ver\r\n" + "EXT:\r\n" + "Location: http://[::1]:5431/dyndev/uuid:0000e068-20a0-00e0-20a0-48a8000808e0\r\n" + "Cache-Control:max-age=1800\r\n" + "ST:urn:schemas-upnp-org:service:WANIPConnection:1\r\n" + "USN:uuid:0000e068-20a0-00e0-20a0-48a802086048::urn:schemas-upnp-org:service:WANIPConnection:1"; _server.WhenGetExternalIpAddress = (ctx) => { var responseXml = "<?xml version=\"1.0\"?>" + "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " + "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + "<s:Body>" + "<m:GetExternalIPAddressResponse xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" + "<NewExternalIPAddress>FE80::0202:B3FF:FE1E:8329</NewExternalIPAddress>" + "</m:GetExternalIPAddressResponse>" + "</s:Body>" + "</s:Envelope>"; var bytes = Encoding.UTF8.GetBytes(responseXml); var response = ctx.Response; response.OutputStream.Write(bytes, 0, bytes.Length); response.OutputStream.Flush(); response.StatusCode = 200; response.StatusDescription = "OK"; response.Close(); }; var nat = new NatDiscoverer(); #if NET35 var cts = new CancellationTokenSource(); cts.CancelAfter(5000); NatDevice device = null; nat.DiscoverDeviceAsync(PortMapper.Upnp, cts) .ContinueWith(tt => { device = tt.Result; Assert.IsNotNull(device); }); device.GetExternalIPAsync() .ContinueWith(tt => { var ip = tt.Result; Assert.AreEqual(IPAddress.Parse("FE80::0202:B3FF:FE1E:8329"), ip); }); #else var cts = new CancellationTokenSource(5000); var device = await nat.DiscoverDeviceAsync(PortMapper.Upnp, cts); Assert.IsNotNull(device); var ip = await device.GetExternalIPAsync(); Assert.AreEqual(IPAddress.Parse("FE80::0202:B3FF:FE1E:8329"), ip); #endif }
public static async Task <IPAddress> GetLocalIP() { NatDevice natDevice = await GetNatDeviceAsync(10000).ConfigureAwait(false); return(natDevice.GetLocalIP()); }
private void AddPortOnDevice(NatDevice device, int port) { device.MapAsync(MappingProtocol.TCP, port, TimeSpan.FromSeconds(7200), cancelSource.Token); device.MapAsync(MappingProtocol.UDP, port, TimeSpan.FromSeconds(7200), cancelSource.Token); }
private void RemovePortOnDevice(NatDevice device, int port) { device.UnmapAsync(MappingProtocol.TCP, port, cancelSource.Token); device.UnmapAsync(MappingProtocol.UDP, port, cancelSource.Token); }
private void RemovePortOnDevice(NatDevice device, int port) { device.UnmapAsync(MappingProtocol.TCP, port, cancelSource.Token); device.UnmapAsync(MappingProtocol.UDP, port, cancelSource.Token); }
public DeviceEventArgs(NatDevice device) { Device = device; }
public static void Set(NatDevice Device) { IpAddr.Device = Device; }