예제 #1
0
        private static async Task <IPAddress[]> GetIPAddressesAsync(Uri uri)
        {
            if (uri.HostNameType == UriHostNameType.IPv4 ||
                uri.HostNameType == UriHostNameType.IPv6)
            {
                IPAddress ipAddress = IPAddress.Parse(uri.DnsSafeHost);
                return(new IPAddress[] { ipAddress });
            }

            IPAddress[] addresses = null;

            try
            {
                addresses = await DnsCache.ResolveAsync(uri);
            }
            catch (SocketException socketException)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new EndpointNotFoundException(SR.Format(SR.UnableToResolveHost, uri.Host), socketException));
            }

            if (addresses.Length == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new EndpointNotFoundException(SR.Format(SR.UnableToResolveHost, uri.Host)));
            }

            return(addresses);
        }
예제 #2
0
 protected override Uri PostVerify(Uri uri)
 {
     if (0 == String.Compare(uri.Host, "localhost", StringComparison.OrdinalIgnoreCase))
     {
         return(uri);
     }
     try
     {
         if (0 == String.Compare(DnsCache.MachineName, DnsCache.Resolve(uri).HostName, StringComparison.OrdinalIgnoreCase))
         {
             return(new UriBuilder(Scheme, "localhost", -1, uri.PathAndQuery).Uri);
         }
     }
     catch (EndpointNotFoundException ex)
     {
         MsmqDiagnostics.ExpectedException(ex);
     }
     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqDLQNotLocal), "uri"));
 }
        private static IPAddress[] GetIPAddresses(Uri uri)
        {
            if ((uri.HostNameType == UriHostNameType.IPv4) || (uri.HostNameType == UriHostNameType.IPv6))
            {
                IPAddress address = IPAddress.Parse(uri.DnsSafeHost);
                return(new IPAddress[] { address });
            }
            IPHostEntry entry = null;

            try
            {
                entry = DnsCache.Resolve(uri.Host);
            }
            catch (SocketException exception)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new EndpointNotFoundException(System.ServiceModel.SR.GetString("UnableToResolveHost", new object[] { uri.Host }), exception));
            }
            if (entry.AddressList.Length == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new EndpointNotFoundException(System.ServiceModel.SR.GetString("UnableToResolveHost", new object[] { uri.Host })));
            }
            return(entry.AddressList);
        }
예제 #4
0
        //will only return > 1 socket when both of the following are true:
        // 1) multicast
        // 2) sending on all interfaces
        UdpSocket[] GetSockets(Uri via, out IPEndPoint remoteEndPoint, out bool isMulticast)
        {
            UdpSocket[] results = null;

            remoteEndPoint = null;
            IPAddress[] remoteAddressList;
            isMulticast = false;

            UdpUtility.ThrowIfNoSocketSupport();

            if (via.HostNameType == UriHostNameType.IPv6 || via.HostNameType == UriHostNameType.IPv4)
            {
                UdpUtility.ThrowOnUnsupportedHostNameType(via);

                IPAddress address = IPAddress.Parse(via.DnsSafeHost);
                isMulticast = UdpUtility.IsMulticastAddress(address);

                remoteAddressList = new IPAddress[] { address };
            }
            else
            {
                remoteAddressList = DnsCache.Resolve(via).AddressList;
            }

            if (remoteAddressList.Length < 1)
            {
                // System.Net.Dns shouldn't ever allow this to happen, but...
                Fx.Assert("DnsCache returned a HostEntry with zero length address list");
                throw FxTrace.Exception.AsError(new EndpointNotFoundException(SR.DnsResolveFailed(via.DnsSafeHost)));
            }

            remoteEndPoint = new IPEndPoint(remoteAddressList[0], via.Port);

            IPAddress localAddress;

            if (via.IsLoopback)
            {
                localAddress = (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback);
            }
            else
            {
                localAddress = (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any);
            }

            int port = 0;

            if (isMulticast)
            {
                List <UdpSocket>   socketList = new List <UdpSocket>();
                NetworkInterface[] adapters   = UdpUtility.GetMulticastInterfaces(this.udpTransportBindingElement.MulticastInterfaceId);

                //if listening on a specific adapter, don't disable multicast loopback on that adapter.
                bool allowMulticastLoopback = !string.IsNullOrEmpty(this.udpTransportBindingElement.MulticastInterfaceId);

                for (int i = 0; i < adapters.Length; i++)
                {
                    if (adapters[i].OperationalStatus == OperationalStatus.Up)
                    {
                        IPInterfaceProperties properties = adapters[i].GetIPProperties();
                        bool isLoopbackAdapter           = adapters[i].NetworkInterfaceType == NetworkInterfaceType.Loopback;

                        if (isLoopbackAdapter)
                        {
                            int interfaceIndex;
                            if (UdpUtility.TryGetLoopbackInterfaceIndex(adapters[i], localAddress.AddressFamily == AddressFamily.InterNetwork, out interfaceIndex))
                            {
                                socketList.Add(UdpUtility.CreateListenSocket(localAddress, ref port, this.udpTransportBindingElement.SocketReceiveBufferSize, this.udpTransportBindingElement.TimeToLive,
                                                                             interfaceIndex, allowMulticastLoopback, isLoopbackAdapter));
                            }
                        }
                        else if (localAddress.AddressFamily == AddressFamily.InterNetworkV6)
                        {
                            if (adapters[i].Supports(NetworkInterfaceComponent.IPv6))
                            {
                                IPv6InterfaceProperties v6Properties = properties.GetIPv6Properties();

                                if (v6Properties != null)
                                {
                                    socketList.Add(UdpUtility.CreateListenSocket(localAddress, ref port, this.udpTransportBindingElement.SocketReceiveBufferSize,
                                                                                 this.udpTransportBindingElement.TimeToLive, v6Properties.Index, allowMulticastLoopback, isLoopbackAdapter));
                                }
                            }
                        }
                        else
                        {
                            if (adapters[i].Supports(NetworkInterfaceComponent.IPv4))
                            {
                                IPv4InterfaceProperties v4Properties = properties.GetIPv4Properties();
                                if (v4Properties != null)
                                {
                                    socketList.Add(UdpUtility.CreateListenSocket(localAddress, ref port, this.udpTransportBindingElement.SocketReceiveBufferSize,
                                                                                 this.udpTransportBindingElement.TimeToLive, v4Properties.Index, allowMulticastLoopback, isLoopbackAdapter));
                                }
                            }
                        }
                    }

                    //CreateListenSocket sets the port, but since we aren't listening
                    //on multicast, each socket can't share the same port.
                    port = 0;
                }

                if (socketList.Count == 0)
                {
                    throw FxTrace.Exception.AsError(new ArgumentException(SR.UdpFailedToFindMulticastAdapter(via)));
                }

                results = socketList.ToArray();
            }
            else
            {
                UdpSocket socket = UdpUtility.CreateUnicastListenSocket(localAddress, ref port, this.udpTransportBindingElement.SocketReceiveBufferSize,
                                                                        this.udpTransportBindingElement.TimeToLive);

                results = new UdpSocket[] { socket };
            }


            Fx.Assert(results != null, "GetSockets(...) return results should never be null. An exception should have been thrown but wasn't.");
            return(results);
        }
예제 #5
0
        // Must return non-null/non-empty array unless exceptionToBeThrown is has been set
        protected override UdpSocket[] GetSendSockets(Message message, out IPEndPoint remoteEndPoint, out Exception exceptionToBeThrown)
        {
            Fx.Assert(message != null, "message can't be null");

            UdpSocket[] socketList = null;
            exceptionToBeThrown = null;

            remoteEndPoint = null;
            Uri  destination;
            bool isVia = false;

            if (message.Properties.Via != null)
            {
                destination = message.Properties.Via;
                isVia       = true;
            }
            else if (message.Headers.To != null)
            {
                destination = message.Headers.To;
            }
            else
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ToOrViaRequired));
            }

            this.ValidateDestinationUri(destination, isVia);

            if (destination.HostNameType == UriHostNameType.IPv4 || destination.HostNameType == UriHostNameType.IPv6)
            {
                remoteEndPoint = new IPEndPoint(IPAddress.Parse(destination.DnsSafeHost), destination.Port);

                if (this.IsMulticast)
                {
                    UdpSocket socket = this.GetSendSocketUsingInterfaceIndex(message.Properties, out exceptionToBeThrown);

                    if (socket != null)
                    {
                        if (socket.AddressFamily == remoteEndPoint.AddressFamily)
                        {
                            socketList = new UdpSocket[] { socket };
                        }
                        else
                        {
                            exceptionToBeThrown = new InvalidOperationException(SR.RemoteAddressUnreachableDueToIPVersionMismatch(destination.DnsSafeHost));
                        }
                    }
                }
                else
                {
                    UdpSocket socket = this.GetSendSocket(remoteEndPoint.Address, destination, out exceptionToBeThrown);
                    if (socket != null)
                    {
                        socketList = new UdpSocket[] { socket };
                    }
                }
            }
            else
            {
                IPAddress[] remoteAddresses = DnsCache.Resolve(destination).AddressList;

                if (this.IsMulticast)
                {
                    UdpSocket socket = this.GetSendSocketUsingInterfaceIndex(message.Properties, out exceptionToBeThrown);

                    if (socket != null)
                    {
                        socketList = new UdpSocket[] { socket };

                        for (int i = 0; i < remoteAddresses.Length; i++)
                        {
                            if (remoteAddresses[i].AddressFamily == socket.AddressFamily)
                            {
                                remoteEndPoint = new IPEndPoint(remoteAddresses[i], destination.Port);
                                break;
                            }
                        }

                        if (remoteEndPoint == null)
                        {
                            // for multicast, we only listen on either IPv4 or IPv6 (not both).
                            // if we didn't find a matching remote endpoint, then it would indicate that
                            // the remote host didn't resolve to an address we can use...
                            exceptionToBeThrown = new InvalidOperationException(SR.RemoteAddressUnreachableDueToIPVersionMismatch(destination.DnsSafeHost));
                        }
                    }
                }
                else
                {
                    bool useIPv4 = true;
                    bool useIPv6 = true;

                    for (int i = 0; i < remoteAddresses.Length; i++)
                    {
                        IPAddress address = remoteAddresses[i];

                        if (address.AddressFamily == AddressFamily.InterNetwork && useIPv4)
                        {
                            UdpSocket socket = this.GetSendSocket(address, destination, out exceptionToBeThrown);
                            if (socket == null)
                            {
                                if (this.State != CommunicationState.Opened)
                                {
                                    // time to exit, the channel is closing down.
                                    break;
                                }
                                else
                                {
                                    // no matching socket on IPv4, so ignore future IPv4 addresses
                                    // in the remoteAddresses list
                                    useIPv4 = false;
                                }
                            }
                            else
                            {
                                remoteEndPoint = new IPEndPoint(address, destination.Port);
                                socketList     = new UdpSocket[] { socket };
                                break;
                            }
                        }
                        else if (address.AddressFamily == AddressFamily.InterNetworkV6 && useIPv6)
                        {
                            UdpSocket socket = this.GetSendSocket(address, destination, out exceptionToBeThrown);
                            if (socket == null)
                            {
                                if (this.State != CommunicationState.Opened)
                                {
                                    // time to exit, the channel is closing down.
                                    break;
                                }
                                else
                                {
                                    // no matching socket on IPv6, so ignore future IPv6 addresses
                                    // in the remoteAddresses list
                                    useIPv6 = false;
                                }
                            }
                            else
                            {
                                remoteEndPoint = new IPEndPoint(address, destination.Port);
                                socketList     = new UdpSocket[] { socket };
                                break;
                            }
                        }
                    }
                }
            }

            return(socketList);
        }