/// <summary> /// Converts a socket address to record /// </summary> /// <param name="address"></param> /// <returns></returns> internal static DnsServiceRecord FromSocketAddress( ProxySocketAddress address) { var record = Parse(address.Host); record._flags = address.Flags; record._interfaceIndex = address.InterfaceIndex; return(record); }
/// <summary> /// Start browsing specified item /// </summary> /// <param name="item"></param> /// <param name="ct"></param> /// <returns></returns> public async Task BrowseBeginAsync(ProxySocketAddress item, CancellationToken ct) { if (!_connected) { throw new SocketException(SocketError.Closed); } var request = new BrowseRequest { Item = item, Handle = _id, Type = _type }; var buffer = new MemoryStream(); await request.EncodeAsync(buffer, _codec, ct); await SendAsync(new Message(null, null, null, new DataMessage(buffer.ToArray())), ct).ConfigureAwait(false); }
/// <summary> /// Parse a string into a socket address /// </summary> /// <param name="address"></param> /// <param name="parsed"></param> /// <returns></returns> public static bool TryParse(string address, out SocketAddress parsed) { /**/ if (string.IsNullOrEmpty(address)) { parsed = new AnySocketAddress(); } else if (InetSocketAddress.TryParse(address, out var inet)) { parsed = inet; } else if (ProxySocketAddress.TryParse(address, out var proxy)) { parsed = proxy; } else { parsed = new AnySocketAddress(); return(false); } return(true); }
/// <summary> /// Connect to a target on first of bound proxies, or use ping based dynamic lookup /// </summary> /// <param name="address"></param> /// <param name="ct"></param> /// <returns></returns> public override async Task ConnectAsync(SocketAddress address, CancellationToken ct) { if (address.Family == AddressFamily.Bound) { // Unwrap proxy and connect address. If not bound, use local address to bind to. if (_bindList == null) { await BindAsync(((BoundSocketAddress)address).LocalAddress, ct); } address = ((BoundSocketAddress)address).RemoteAddress; } // Get the named host from the registry if it exists - there should only be one... Host = null; var hostList = await Provider.NameService.LookupAsync( address.ToString(), NameRecordType.Host, ct).ConfigureAwait(false); foreach (var host in hostList) { Host = host; break; } // If there is no host in the registry, create a fake host record for this address if (Host == null) { Host = new NameRecord(NameRecordType.Host, address.ToString()); } else if (!Host.Name.Equals(address.ToString(), StringComparison.CurrentCultureIgnoreCase)) { // Translate the address to host address address = new ProxySocketAddress(Host.Name); } // Set bind list before connecting if it is not already set during Bind bool autoBind = _bindList == null; if (autoBind) { var bindList = new HashSet <INameRecord>(); foreach (var proxyRef in Host.References) { var results = await Provider.NameService.LookupAsync( proxyRef, NameRecordType.Proxy, ct).ConfigureAwait(false); bindList.AddRange(results); } _bindList = bindList.Any() ? bindList : null; } bool connected = false; if (_bindList != null) { // Try to connect through each proxy in the bind list foreach (var proxy in _bindList) { connected = await ConnectAsync(address, proxy, ct).ConfigureAwait(false); if (connected) { break; } } // If there was a bind list and we could not connect through it, throw if (!connected && !autoBind) { throw new SocketException(SocketError.NoHost); } _bindList = null; } if (!connected) { await PingAsync(address, async (response, proxy, ct2) => { if (connected) { return(Disposition.Done); } if (response.Error == (int)SocketError.Success) { try { connected = await ConnectAsync(address, proxy, ct).ConfigureAwait(false); } catch (Exception) { return(Disposition.Retry); } } return(connected ? Disposition.Done : Disposition.Continue); }, (ex) => { if (!connected) { throw new SocketException( "Could not link socket on proxy", ex, SocketError.NoHost); } }, ct).ConfigureAwait(false); ct.ThrowIfCancellationRequested(); } await Provider.NameService.AddOrUpdateAsync(Host, ct).ConfigureAwait(false); }
internal HostEntryResolver(ProxySocketAddress host) { _host = host; }