예제 #1
0
        private async void UpnpClient_OnDeviceFound(object Sender, DeviceLocationEventArgs e)
        {
            try
            {
                lock (this.ipAddressesFound)
                {
                    if (this.ipAddressesFound.ContainsKey(e.RemoteEndPoint.Address))
                    {
                        return;
                    }

                    this.ipAddressesFound[e.RemoteEndPoint.Address] = true;
                }

                DeviceDescriptionDocument Doc = await e.Location.GetDeviceAsync();

                if (Doc != null)
                {
                    UPnPService Service = Doc.GetService("urn:schemas-upnp-org:service:WANIPConnection:1");
                    if (Service == null)
                    {
                        Service = Doc.GetService("urn:schemas-upnp-org:service:WANIPConnection:2");
                        if (Service == null)
                        {
                            return;
                        }
                    }

                    ServiceDescriptionDocument Scpd = await Service.GetServiceAsync();

                    this.ServiceRetrieved(Scpd, e.LocalEndPoint);
                }
            }
            catch (Exception ex)
            {
                this.exception = ex;
                this.State     = PeerToPeerNetworkState.Error;
            }
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
 /// <summary>
 /// Generated from SCPD
 /// </summary>
 public ContentDirectory(ServiceDescriptionDocument Service)
 {
     this.service = Service;
 }
예제 #4
0
 public ConnectionManager(ServiceDescriptionDocument Service)
 {
     this.service = Service;
 }
예제 #5
0
		public WFAWLANConfig(ServiceDescriptionDocument Service)
		{
			this.service = Service;
		}
        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;
            }
        }
예제 #7
0
		public ContentDirectory(ServiceDescriptionDocument Service)
		{
			this.service = Service;
		}
 /// <summary>
 /// Generated from SCPD
 /// </summary>
 public WANEthernetLinkConfigV1(ServiceDescriptionDocument Service)
 {
     this.service = Service;
 }
 public WANCommonInterfaceConfig(ServiceDescriptionDocument Service)
 {
     this.service = Service;
 }
예제 #10
0
		public WANIPConnectionV1(ServiceDescriptionDocument Service)
		{
			this.service = Service;
		}
		public X_MS_MediaReceiverRegistrar(ServiceDescriptionDocument Service)
		{
			this.service = Service;
		}
예제 #12
0
		public ConnectionManager(ServiceDescriptionDocument Service)
		{
			this.service = Service;
		}
		public WANCommonInterfaceConfig(ServiceDescriptionDocument Service)
		{
			this.service = Service;
		}
예제 #14
0
 /// <summary>
 /// Generated from SCPD
 /// </summary>
 public WANIPConnectionV1(ServiceDescriptionDocument Service)
 {
     this.service = Service;
 }
예제 #15
0
 public WFAWLANConfig(ServiceDescriptionDocument Service)
 {
     this.service = Service;
 }
예제 #16
0
 public Layer3Forwarding(ServiceDescriptionDocument Service)
 {
     this.service = Service;
 }
 /// <summary>
 /// Generated from SCPD
 /// </summary>
 public X_MS_MediaReceiverRegistrar(ServiceDescriptionDocument Service)
 {
     this.service = Service;
 }
예제 #18
0
		public Layer3Forwarding(ServiceDescriptionDocument Service)
		{
			this.service = Service;
		}
		public WANEthernetLinkConfigV1(ServiceDescriptionDocument Service)
		{
			this.service = Service;
		}