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); }
//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); }
// 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); }