/// <summary> /// <see cref="IDisposable.Dispose"/> /// </summary> public void Dispose() { this.disposed = true; this.State = PeerToPeerNetworkState.Closed; NetworkChange.NetworkAddressChanged -= NetworkChange_NetworkAddressChanged; this.searchTimer?.Dispose(); this.searchTimer = null; this.tcpListener?.Stop(); this.tcpListener = null; if (this.tcpMappingAdded) { this.tcpMappingAdded = false; try { this.serviceWANIPConnectionV1.DeletePortMapping(string.Empty, (ushort)this.localEndpoint.Port, "TCP"); } catch (Exception) { // Ignore } } if (this.udpMappingAdded) { this.udpMappingAdded = false; try { this.serviceWANIPConnectionV1.DeletePortMapping(string.Empty, (ushort)this.localEndpoint.Port, "UDP"); } catch (Exception) { // Ignore } } this.serviceWANIPConnectionV1 = null; this.upnpClient?.Dispose(); this.upnpClient = null; this.ipAddressesFound?.Clear(); this.ipAddressesFound = null; this.ready?.Dispose(); this.ready = null; this.error?.Dispose(); this.error = null; }
private void ServiceRetrieved(ServiceDescriptionDocument Scpd, IPEndPoint LocalEndPoint) { try { Dictionary <ushort, bool> TcpPortMapped = new Dictionary <ushort, bool>(); Dictionary <ushort, bool> UdpPortMapped = new Dictionary <ushort, bool>(); ushort PortMappingIndex; bool TcpAlreadyRegistered = false; bool UdpAlreadyRegistered = false; this.serviceWANIPConnectionV1 = new WANIPConnectionV1(Scpd); this.State = PeerToPeerNetworkState.RegisteringApplicationInGateway; this.serviceWANIPConnectionV1.GetExternalIPAddress(out string NewExternalIPAddress); this.externalAddress = IPAddress.Parse(NewExternalIPAddress); if (!IsPublicAddress(this.externalAddress)) { return; // TODO: Handle multiple layers of gateways. } PortMappingIndex = 0; try { while (true) { this.serviceWANIPConnectionV1.GetGenericPortMappingEntry(PortMappingIndex, out string NewRemoteHost, out ushort NewExternalPort, out string NewProtocol, out ushort NewInternalPort, out string NewInternalClient, out bool NewEnabled, out string NewPortMappingDescription, out uint NewLeaseDuration); if (NewPortMappingDescription == this.applicationName && NewInternalClient == LocalEndPoint.Address.ToString()) { if (NewExternalPort == this.desiredExternalPort && this.desiredExternalPort != 0) { if (NewProtocol == "TCP") { TcpAlreadyRegistered = true; PortMappingIndex++; continue; } else if (NewProtocol == "UDP") { UdpAlreadyRegistered = true; PortMappingIndex++; continue; } } this.serviceWANIPConnectionV1.DeletePortMapping(NewRemoteHost, NewExternalPort, NewProtocol); } else { switch (NewProtocol) { case "TCP": TcpPortMapped[NewExternalPort] = true; break; case "UDP": UdpPortMapped[NewExternalPort] = true; break; } PortMappingIndex++; } } } catch (AggregateException ex) { if (!(ex.InnerException is UPnPException)) { throw; } } catch (UPnPException) { // No more entries. } this.localAddress = LocalEndPoint.Address; ushort LocalPort, ExternalPort; int i; do { this.tcpListener = new TcpListener(this.localAddress, this.desiredLocalPort); this.tcpListener.Start(this.backlog); i = ((IPEndPoint)this.tcpListener.LocalEndpoint).Port; LocalPort = (ushort)(i); ExternalPort = this.desiredExternalPort == 0 ? LocalPort : (ushort)this.desiredExternalPort; if (i < 0 || i > ushort.MaxValue || TcpPortMapped.ContainsKey(ExternalPort) || UdpPortMapped.ContainsKey(ExternalPort)) { this.tcpListener.Stop(); this.tcpListener = null; throw new ArgumentException("Port already assigned to another application in the network.", nameof(ExternalPort)); } else { try { this.udpClient = new UdpClient(this.tcpListener.LocalEndpoint.AddressFamily); this.udpClient.Client.Bind((IPEndPoint)this.tcpListener.LocalEndpoint); } catch (Exception) { this.tcpListener.Stop(); this.tcpListener = null; } } }while (this.tcpListener == null); this.localEndpoint = new IPEndPoint(this.localAddress, LocalPort); if (!TcpAlreadyRegistered) { this.serviceWANIPConnectionV1.AddPortMapping(string.Empty, ExternalPort, "TCP", LocalPort, LocalAddress.ToString(), true, this.applicationName, 0); } this.tcpMappingAdded = true; if (!UdpAlreadyRegistered) { this.serviceWANIPConnectionV1.AddPortMapping(string.Empty, ExternalPort, "UDP", LocalPort, LocalAddress.ToString(), true, this.applicationName, 0); } this.udpMappingAdded = true; this.externalEndpoint = new IPEndPoint(this.externalAddress, ExternalPort); this.State = PeerToPeerNetworkState.Ready; this.AcceptTcpClients(); this.BeginReceiveUdp(); } catch (Exception ex) { this.exception = ex; this.State = PeerToPeerNetworkState.Error; } }
/// <summary> /// <see cref="IDisposable.Dispose"/> /// </summary> public virtual void Dispose() { this.disposed = true; this.State = PeerToPeerNetworkState.Closed; NetworkChange.NetworkAddressChanged -= NetworkChange_NetworkAddressChanged; this.searchTimer?.Dispose(); this.searchTimer = null; foreach (InternetGatewayRegistration Registration in this.ports) { if (Registration.TcpRegistered) { Registration.TcpRegistered = false; try { Log.Notice("Deleting Internet Gateway port mapping.", new KeyValuePair <string, object>("Host", string.Empty), new KeyValuePair <string, object>("External Port", Registration.ExternalPort), new KeyValuePair <string, object>("Protocol", "TCP"), new KeyValuePair <string, object>("Local Port", Registration.LocalPort), new KeyValuePair <string, object>("Application", Registration.ApplicationName)); this.serviceWANIPConnectionV1.DeletePortMapping(string.Empty, Registration.LocalPort, "TCP"); } catch (Exception) { // Ignore } } if (Registration.UdpRegistered) { Registration.UdpRegistered = false; try { Log.Notice("Deleting Internet Gateway port mapping.", new KeyValuePair <string, object>("Host", string.Empty), new KeyValuePair <string, object>("External Port", Registration.ExternalPort), new KeyValuePair <string, object>("Protocol", "UDP"), new KeyValuePair <string, object>("Local Port", Registration.LocalPort), new KeyValuePair <string, object>("Application", Registration.ApplicationName)); this.serviceWANIPConnectionV1.DeletePortMapping(string.Empty, Registration.LocalPort, "UDP"); } catch (Exception) { // Ignore } } } this.serviceWANIPConnectionV1 = null; this.upnpClient?.Dispose(); this.upnpClient = null; this.ipAddressesFound?.Clear(); this.ipAddressesFound = null; this.ready?.Dispose(); this.ready = null; this.error?.Dispose(); this.error = null; }
private void ServiceRetrieved(ServiceDescriptionDocument Scpd, IPEndPoint LocalEndPoint) { try { Dictionary <ushort, bool> TcpPortMapped = new Dictionary <ushort, bool>(); Dictionary <ushort, bool> UdpPortMapped = new Dictionary <ushort, bool>(); ushort PortMappingIndex; this.serviceWANIPConnectionV1 = new WANIPConnectionV1(Scpd); this.State = PeerToPeerNetworkState.RegisteringApplicationInGateway; this.serviceWANIPConnectionV1.GetExternalIPAddress(out string NewExternalIPAddress); this.externalAddress = IPAddress.Parse(NewExternalIPAddress); Log.Informational("External IP Address: " + NewExternalIPAddress); if (!IsPublicAddress(this.externalAddress)) { Log.Warning("External IP Address not a public IP address."); return; // TODO: Handle multiple layers of gateways. } PortMappingIndex = 0; try { string LocalAddress = LocalEndPoint.Address.ToString(); while (true) { this.serviceWANIPConnectionV1.GetGenericPortMappingEntry(PortMappingIndex, out string NewRemoteHost, out ushort NewExternalPort, out string NewProtocol, out ushort NewInternalPort, out string NewInternalClient, out bool NewEnabled, out string NewPortMappingDescription, out uint NewLeaseDuration); if (NewInternalClient != LocalAddress) { PortMappingIndex++; continue; } bool Found = false; foreach (InternetGatewayRegistration Registration in this.ports) { if ((Registration.ExternalPort != 0 && NewExternalPort == Registration.ExternalPort) || (Registration.ExternalPort == 0 && NewPortMappingDescription == Registration.ApplicationName)) { if (NewProtocol == "TCP") { Found = true; Registration.TcpRegistered = true; break; } else if (NewProtocol == "UDP") { Found = true; Registration.UdpRegistered = true; break; } Log.Notice("Deleting Internet Gateway port mapping.", new KeyValuePair <string, object>("Host", NewRemoteHost), new KeyValuePair <string, object>("External Port", NewExternalPort), new KeyValuePair <string, object>("Protocol", NewProtocol), new KeyValuePair <string, object>("Local Port", NewInternalPort), new KeyValuePair <string, object>("Local Address", NewInternalClient), new KeyValuePair <string, object>("Application", NewPortMappingDescription)); this.serviceWANIPConnectionV1.DeletePortMapping(NewRemoteHost, NewExternalPort, NewProtocol); } } if (Found) { PortMappingIndex++; continue; } else { switch (NewProtocol) { case "TCP": TcpPortMapped[NewExternalPort] = true; break; case "UDP": UdpPortMapped[NewExternalPort] = true; break; } PortMappingIndex++; } } } catch (AggregateException ex) { if (!(ex.InnerException is UPnPException)) { System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex).Throw(); } } catch (UPnPException) { // No more entries. } this.localAddress = LocalEndPoint.Address; foreach (InternetGatewayRegistration Registration in this.ports) { this.BeforeRegistration(Registration, TcpPortMapped, UdpPortMapped); if ((Registration.TcpRegistered || !Registration.Tcp) && (Registration.UdpRegistered || !Registration.Udp)) { continue; } if (Registration.Tcp && !Registration.TcpRegistered) { Log.Notice("Adding Internet Gateway port mapping.", new KeyValuePair <string, object>("Host", string.Empty), new KeyValuePair <string, object>("External Port", Registration.ExternalPort), new KeyValuePair <string, object>("Protocol", "TCP"), new KeyValuePair <string, object>("Local Port", Registration.LocalPort), new KeyValuePair <string, object>("Local Address", LocalAddress.ToString()), new KeyValuePair <string, object>("Application", Registration.ApplicationName)); try { this.serviceWANIPConnectionV1.AddPortMapping(string.Empty, Registration.ExternalPort, "TCP", Registration.LocalPort, LocalAddress.ToString(), true, Registration.ApplicationName, 0); Registration.TcpRegistered = true; } catch (Exception ex) { Log.Error("Unable to register port in Internet Gateway: " + ex.Message, new KeyValuePair <string, object>("External Port", Registration.ExternalPort), new KeyValuePair <string, object>("Protocol", "TCP"), new KeyValuePair <string, object>("Local Port", Registration.LocalPort), new KeyValuePair <string, object>("Local Address", LocalAddress.ToString()), new KeyValuePair <string, object>("Application", Registration.ApplicationName)); } } if (Registration.Udp && !Registration.UdpRegistered) { Log.Notice("Adding Internet Gateway port mapping.", new KeyValuePair <string, object>("Host", string.Empty), new KeyValuePair <string, object>("External Port", Registration.ExternalPort), new KeyValuePair <string, object>("Protocol", "UDP"), new KeyValuePair <string, object>("Local Port", Registration.LocalPort), new KeyValuePair <string, object>("Local Address", LocalAddress.ToString()), new KeyValuePair <string, object>("Application", Registration.ApplicationName)); try { this.serviceWANIPConnectionV1.AddPortMapping(string.Empty, Registration.ExternalPort, "UDP", Registration.LocalPort, LocalAddress.ToString(), true, Registration.ApplicationName, 0); Registration.UdpRegistered = true; } catch (Exception ex) { Log.Error("Unable to register port in Internet Gateway: " + ex.Message, new KeyValuePair <string, object>("External Port", Registration.ExternalPort), new KeyValuePair <string, object>("Protocol", "UDP"), new KeyValuePair <string, object>("Local Port", Registration.LocalPort), new KeyValuePair <string, object>("Local Address", LocalAddress.ToString()), new KeyValuePair <string, object>("Application", Registration.ApplicationName)); } } } this.State = PeerToPeerNetworkState.Ready; } catch (Exception ex) { Log.Critical(ex); this.exception = ex; this.State = PeerToPeerNetworkState.Error; } }
/// <summary> /// <see cref="IDisposable.Dispose"/> /// </summary> public void Dispose() { this.State = PeerToPeerNetworkState.Closed; if (!(this.tcpListener is null)) { this.tcpListener.Stop(); this.tcpListener = null; } if (this.tcpMappingAdded) { this.tcpMappingAdded = false; try { this.serviceWANIPConnectionV1.DeletePortMapping(string.Empty, (ushort)this.localEndpoint.Port, "TCP"); } catch (Exception) { // Ignore } } if (this.udpMappingAdded) { this.udpMappingAdded = false; try { this.serviceWANIPConnectionV1.DeletePortMapping(string.Empty, (ushort)this.localEndpoint.Port, "UDP"); } catch (Exception) { // Ignore } } this.serviceWANIPConnectionV1 = null; if (!(this.upnpClient is null)) { this.upnpClient.Dispose(); this.upnpClient = null; } if (!(this.ipAddressesFound is null)) { this.ipAddressesFound.Clear(); this.ipAddressesFound = null; } if (!(this.ready is null)) { this.ready.Close(); this.ready = null; } if (!(this.error is null)) { this.error.Close(); this.error = null; } }
private void ServiceRetrieved(object Sender, ServiceDescriptionEventArgs e) { try { DeviceLocationEventArgs e2 = (DeviceLocationEventArgs)e.State; Dictionary <ushort, bool> TcpPortMapped = new Dictionary <ushort, bool>(); Dictionary <ushort, bool> UdpPortMapped = new Dictionary <ushort, bool>(); ushort PortMappingIndex; this.serviceWANIPConnectionV1 = new WANIPConnectionV1(e.ServiceDescriptionDocument); this.State = PeerToPeerNetworkState.RegisteringApplicationInGateway; this.serviceWANIPConnectionV1.GetExternalIPAddress(out string NewExternalIPAddress); this.externalAddress = IPAddress.Parse(NewExternalIPAddress); PortMappingIndex = 0; try { while (true) { this.serviceWANIPConnectionV1.GetGenericPortMappingEntry(PortMappingIndex, out string NewRemoteHost, out ushort NewExternalPort, out string NewProtocol, out ushort NewInternalPort, out string NewInternalClient, out bool NewEnabled, out string NewPortMappingDescription, out uint NewLeaseDuration); if (NewPortMappingDescription == this.applicationName && NewInternalClient == e2.LocalEndPoint.Address.ToString()) { this.serviceWANIPConnectionV1.DeletePortMapping(NewRemoteHost, NewExternalPort, NewProtocol); } else { switch (NewProtocol) { case "TCP": TcpPortMapped[NewExternalPort] = true; break; case "UDP": UdpPortMapped[NewExternalPort] = true; break; } PortMappingIndex++; } } } catch (UPnPException) { // No more entries. } this.localAddress = e2.LocalEndPoint.Address; ushort LocalPort; int i; do { this.tcpListener = new TcpListener(this.localAddress, this.desiredPort); this.tcpListener.Start(this.backlog); i = ((IPEndPoint)this.tcpListener.LocalEndpoint).Port; LocalPort = (ushort)(i); if (i < 0 || i > ushort.MaxValue || TcpPortMapped.ContainsKey(LocalPort) || UdpPortMapped.ContainsKey(LocalPort)) { this.tcpListener.Stop(); this.tcpListener = null; if (this.desiredPort != 0) { throw new ArgumentException("Port already assigned to another application in the network.", "Port"); } } else { try { this.udpClient = new UdpClient(this.tcpListener.LocalEndpoint.AddressFamily); this.udpClient.Client.Bind((IPEndPoint)this.tcpListener.LocalEndpoint); } catch (Exception) { this.tcpListener.Stop(); this.tcpListener = null; } } }while (this.tcpListener is null); this.localEndpoint = new IPEndPoint(this.localAddress, LocalPort); this.serviceWANIPConnectionV1.AddPortMapping(string.Empty, LocalPort, "TCP", LocalPort, LocalAddress.ToString(), true, this.applicationName, 0); this.tcpMappingAdded = true; this.serviceWANIPConnectionV1.AddPortMapping(string.Empty, LocalPort, "UDP", LocalPort, LocalAddress.ToString(), true, this.applicationName, 0); this.udpMappingAdded = true; this.externalEndpoint = new IPEndPoint(this.externalAddress, LocalPort); this.State = PeerToPeerNetworkState.Ready; this.tcpListener.BeginAcceptTcpClient(this.EndAcceptTcpClient, null); this.udpClient.BeginReceive(this.EndReceiveUdp, null); } catch (Exception ex) { this.exception = ex; this.State = PeerToPeerNetworkState.Error; } }