Example #1
0
        public override async Task <Mapping> GetSpecificMappingAsync(Protocol protocol, int publicPort)
        {
            Guard.IsTrue(protocol == Protocol.Tcp || protocol == Protocol.Udp, "protocol");
            Guard.IsInRange(publicPort, 0, ushort.MaxValue, "port");

            NatDiscoverer.TraceSource.LogInfo("GetSpecificMappingAsync - Getting mapping for protocol: {0} port: {1}", Enum.GetName(typeof(Protocol), protocol), publicPort);

            try
            {
                var message      = new GetSpecificPortMappingEntryRequestMessage(protocol, publicPort);
                var responseData = await _soapClient
                                   .InvokeAsync("GetSpecificPortMappingEntry", message.ToXml())
                                   .TimeoutAfter(TimeSpan.FromSeconds(4));

                var messageResponse = new GetPortMappingEntryResponseMessage(responseData, DeviceInfo.ServiceType, false);

                if (messageResponse.Protocol != protocol)
                {
                    NatDiscoverer.TraceSource.LogWarn("Router responded to a protocol {0} query with a protocol {1} answer, work around applied.", protocol, messageResponse.Protocol);
                }

                return(new Mapping(protocol
                                   , IPAddress.Parse(messageResponse.InternalClient)
                                   , messageResponse.InternalPort
                                   , publicPort // messageResponse.ExternalPort is short.MaxValue
                                   , messageResponse.LeaseDuration
                                   , messageResponse.PortMappingDescription));
            }
            catch (MappingException e)
            {
                // there are no more mappings
                if (e.ErrorCode == UpnpConstants.SpecifiedArrayIndexInvalid ||
                    e.ErrorCode == UpnpConstants.NoSuchEntryInArray
                    // DD-WRT Linux base router (and others probably) fails with 402-InvalidArgument when index is out of range
                    || e.ErrorCode == UpnpConstants.InvalidArguments
                    // LINKSYS WRT1900AC AC1900 it returns errocode 501-PAL_UPNP_SOAP_E_ACTION_FAILED
                    || e.ErrorCode == UpnpConstants.ActionFailed)
                {
                    NatDiscoverer.TraceSource.LogWarn("Router failed with {0}-{1}. No more mappings is assumed.", e.ErrorCode, e.ErrorText);
                    return(null);
                }
                throw;
            }
        }
Example #2
0
        public override async Task <Mapping> GetSpecificMappingAsync(Protocol protocol, int port)
        {
            Guard.IsTrue(protocol == Protocol.Tcp || protocol == Protocol.Udp, "protocol");
            Guard.IsInRange(port, 0, ushort.MaxValue, "port");

            NatDiscoverer.TraceSource.LogInfo("GetSpecificMappingAsync - Getting mapping for protocol: {0} port: {1}", Enum.GetName(typeof(Protocol), protocol), port);

            try
            {
                var message      = new GetSpecificPortMappingEntryRequestMessage(protocol, port);
                var responseData = await _soapClient
                                   .InvokeAsync("GetSpecificPortMappingEntry", message.ToXml())
                                   .TimeoutAfter(TimeSpan.FromSeconds(4)).ConfigureAwait(false);

                var messageResponse = new GetPortMappingEntryResponseMessage(responseData, DeviceInfo.ServiceType, false);

                return(new Mapping(messageResponse.Protocol
                                   , IPAddress.Parse(messageResponse.InternalClient)
                                   , messageResponse.InternalPort
                                   , messageResponse.ExternalPort
                                   , messageResponse.LeaseDuration
                                   , messageResponse.PortMappingDescription));
            }
            catch (MappingException e)
            {
                if (e.ErrorCode == UpnpConstants.NoSuchEntryInArray)
                {
                    return(null);
                }

                // DD-WRT Linux base router (and others probably) fails with 402-InvalidArgument
                // when no mapping is found in the mappings table
                if (e.ErrorCode == UpnpConstants.InvalidArguments)
                {
                    NatDiscoverer.TraceSource.LogWarn("Router failed with 402-InvalidArgument. Mapping not found is assumed.");
                    return(null);
                }
                throw;
            }
        }