public static async Task ReadHtmlAsync(string url) { using (var client = new TcpClient()) { Console.WriteLine($"Start get {url}"); Uri uri = new Uri(url); var hostAdress = await Dns.GetHostAddressesAsync(uri.Host); IPAddress ipaddrress = hostAdress[0]; Console.WriteLine($"Host: {uri.Host}, IP: {ipaddrress}"); await client.ConnectAsync(ipaddrress.MapToIPv4(), uri.Port); Console.WriteLine("Connected"); Console.WriteLine(); Stream stream; // stream để đọc - gửi HTTP Message if (uri.Scheme == "https") { // SslStream stream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); (stream as SslStream).AuthenticateAsClient(uri.Host); } else { // NetworkStream stream = client.GetStream(); } // Xem: /psr-7-chuan-giao-dien-thong-diep-http.html#HTTPRequest StringBuilder header = new StringBuilder(); header.Append($"GET {uri.PathAndQuery} HTTP/1.1\r\n"); header.Append($"Host: {uri.Host}\r\n"); header.Append($"\r\n"); Console.WriteLine("Request:"); Console.WriteLine(header); byte[] bsend = Encoding.UTF8.GetBytes(header.ToString()); await stream.WriteAsync(bsend, 0, bsend.Length); await stream.FlushAsync(); var ms = new MemoryStream(); byte [] buffer = new byte[2048]; int bytes = -1; do { bytes = await stream.ReadAsync(buffer, 0, buffer.Length); ms.Write(buffer, 0, bytes); Array.Clear(buffer, 0, buffer.Length); } while (bytes > 0); ms.Seek(0, SeekOrigin.Begin); var reader = new StreamReader(ms); string html = reader.ReadToEnd(); Console.WriteLine("Response:"); Console.WriteLine(html); } }
private async Task StartContainerAsync(Application application, Service service, DockerRunInfo docker, string?dockerNetwork) { var serviceDescription = service.Description; var environmentArguments = ""; var volumes = ""; var workingDirectory = docker.WorkingDirectory != null ? $"-w {docker.WorkingDirectory}" : ""; var hostname = "host.docker.internal"; var dockerImage = docker.Image ?? service.Description.Name; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { // See: https://github.com/docker/for-linux/issues/264 // // host.docker.internal is making it's way into linux docker but doesn't work yet // instead we use the machine IP var addresses = await Dns.GetHostAddressesAsync(Dns.GetHostName()); hostname = addresses[0].ToString(); } async Task RunDockerContainer(IEnumerable <(int ExternalPort, int Port, int?ContainerPort, string?Protocol)> ports, CancellationToken cancellationToken) { var hasPorts = ports.Any(); var replica = service.Description.Name.ToLower() + "_" + Guid.NewGuid().ToString().Substring(0, 10).ToLower(); var status = new DockerStatus(service, replica); service.Replicas[replica] = status; service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Added, status)); var environment = new Dictionary <string, string>(); var portString = ""; if (hasPorts) { status.Ports = ports.Select(p => p.Port); status.Bindings = ports.Select(p => new ReplicaBinding() { Port = p.Port, ExternalPort = p.ExternalPort, Protocol = p.Protocol }).ToList(); // These are the ports that the application should use for binding // 1. Tell the docker container what port to bind to portString = docker.Private ? "" : string.Join(" ", ports.Select(p => $"-p {p.Port}:{p.ContainerPort ?? p.Port}")); if (docker.IsAspNet) { // 2. Configure ASP.NET Core to bind to those same ports environment["ASPNETCORE_URLS"] = string.Join(";", ports.Select(p => $"{p.Protocol ?? "http"}://*:{p.ContainerPort ?? p.Port}")); // Set the HTTPS port for the redirect middleware foreach (var p in ports) { if (string.Equals(p.Protocol, "https", StringComparison.OrdinalIgnoreCase)) { // We need to set the redirect URL to the exposed port so the redirect works cleanly environment["HTTPS_PORT"] = p.ExternalPort.ToString(); } } } // 3. For non-ASP.NET Core apps, pass the same information in the PORT env variable as a semicolon separated list. environment["PORT"] = string.Join(";", ports.Select(p => $"{p.ContainerPort ?? p.Port}")); // This the port for the container proxy (containerport:externalport) environment["PROXY_PORT"] = string.Join(";", ports.Select(p => $"{p.ContainerPort ?? p.Port}:{p.ExternalPort}")); } // See: https://github.com/docker/for-linux/issues/264 // // The way we do proxying here doesn't really work for multi-container scenarios on linux // without some more setup. application.PopulateEnvironment(service, (key, value) => environment[key] = value, hostname !); environment["APP_INSTANCE"] = replica; environment["CONTAINER_HOST"] = hostname !; status.Environment = environment; foreach (var pair in environment) { environmentArguments += $"-e \"{pair.Key}={pair.Value}\" "; } foreach (var volumeMapping in docker.VolumeMappings) { if (volumeMapping.Source != null) { var sourcePath = Path.GetFullPath(Path.Combine(application.ContextDirectory, volumeMapping.Source)); volumes += $"-v \"{sourcePath}:{volumeMapping.Target}\" "; } else if (volumeMapping.Name != null) { volumes += $"-v \"{volumeMapping.Name}:{volumeMapping.Target}\" "; } } var command = $"run -d {workingDirectory} {volumes} {environmentArguments} {portString} --name {replica} --restart=unless-stopped {dockerImage} {docker.Args ?? ""}"; _logger.LogInformation("Running image {Image} for {Replica}", docker.Image, replica); service.Logs.OnNext($"[{replica}]: docker {command}"); status.DockerCommand = command; status.DockerNetwork = dockerNetwork; WriteReplicaToStore(replica); var result = await ProcessUtil.RunAsync( "docker", command, throwOnError : false, cancellationToken : cancellationToken, outputDataReceived : data => service.Logs.OnNext($"[{replica}]: {data}"), errorDataReceived : data => service.Logs.OnNext($"[{replica}]: {data}")); if (result.ExitCode != 0) { _logger.LogError("docker run failed for {ServiceName} with exit code {ExitCode}:" + result.StandardError, service.Description.Name, result.ExitCode); service.Replicas.TryRemove(replica, out var _); service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Removed, status)); PrintStdOutAndErr(service, replica, result); return; } var containerId = (string?)result.StandardOutput.Trim(); // There's a race condition that sometimes makes us miss the output // so keep trying to get the container id while (string.IsNullOrEmpty(containerId)) { // Try to get the ID of the container result = await ProcessUtil.RunAsync("docker", $"ps --no-trunc -f name={replica} --format " + "{{.ID}}"); containerId = result.ExitCode == 0 ? result.StandardOutput.Trim() : null; } var shortContainerId = containerId.Substring(0, Math.Min(12, containerId.Length)); status.ContainerId = shortContainerId; _logger.LogInformation("Running container {ContainerName} with ID {ContainerId}", replica, shortContainerId); if (!string.IsNullOrEmpty(dockerNetwork)) { status.DockerNetworkAlias = docker.NetworkAlias ?? serviceDescription !.Name; var networkCommand = $"network connect {dockerNetwork} {replica} --alias {status.DockerNetworkAlias}"; service.Logs.OnNext($"[{replica}]: docker {networkCommand}"); _logger.LogInformation("Running docker command {Command}", networkCommand); result = await ProcessUtil.RunAsync("docker", networkCommand); PrintStdOutAndErr(service, replica, result); } var sentStartedEvent = false; while (!cancellationToken.IsCancellationRequested) { if (sentStartedEvent) { using var restartCts = new CancellationTokenSource(DockerStopTimeout); result = await ProcessUtil.RunAsync("docker", $"restart {containerId}", throwOnError : false, cancellationToken : restartCts.Token); if (restartCts.IsCancellationRequested) { _logger.LogWarning($"Failed to restart container after {DockerStopTimeout.Seconds} seconds.", replica, shortContainerId); break; // implement retry mechanism? } else if (result.ExitCode != 0) { _logger.LogWarning($"Failed to restart container due to exit code {result.ExitCode}.", replica, shortContainerId); break; } service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Stopped, status)); } using var stoppingCts = new CancellationTokenSource(); status.StoppingTokenSource = stoppingCts; service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Started, status)); sentStartedEvent = true; await using var _ = cancellationToken.Register(() => status.StoppingTokenSource.Cancel()); _logger.LogInformation("Collecting docker logs for {ContainerName}.", replica); var backOff = TimeSpan.FromSeconds(5); while (!status.StoppingTokenSource.Token.IsCancellationRequested) { var logsRes = await ProcessUtil.RunAsync("docker", $"logs -f {containerId}", outputDataReceived : data => service.Logs.OnNext($"[{replica}]: {data}"), errorDataReceived : data => service.Logs.OnNext($"[{replica}]: {data}"), throwOnError : false, cancellationToken : status.StoppingTokenSource.Token); if (logsRes.ExitCode != 0) { break; } if (!status.StoppingTokenSource.IsCancellationRequested) { try { // Avoid spamming logs if restarts are happening await Task.Delay(backOff, status.StoppingTokenSource.Token); } catch (OperationCanceledException) { break; } } backOff *= 2; } _logger.LogInformation("docker logs collection for {ContainerName} complete with exit code {ExitCode}", replica, result.ExitCode); status.StoppingTokenSource = null; } // Docker has a tendency to get stuck so we're going to timeout this shutdown process var timeoutCts = new CancellationTokenSource(DockerStopTimeout); _logger.LogInformation("Stopping container {ContainerName} with ID {ContainerId}", replica, shortContainerId); result = await ProcessUtil.RunAsync("docker", $"stop {containerId}", throwOnError : false, cancellationToken : timeoutCts.Token); if (timeoutCts.IsCancellationRequested) { _logger.LogWarning($"Failed to stop container after {DockerStopTimeout.Seconds} seconds, container will most likely be running.", replica, shortContainerId); } PrintStdOutAndErr(service, replica, result); if (sentStartedEvent) { service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Stopped, status)); } _logger.LogInformation("Stopped container {ContainerName} with ID {ContainerId} exited with {ExitCode}", replica, shortContainerId, result.ExitCode); result = await ProcessUtil.RunAsync("docker", $"rm {containerId}", throwOnError : false, cancellationToken : timeoutCts.Token); if (timeoutCts.IsCancellationRequested) { _logger.LogWarning($"Failed to remove container after {DockerStopTimeout.Seconds} seconds, container will most likely still exist.", replica, shortContainerId); } PrintStdOutAndErr(service, replica, result); _logger.LogInformation("Removed container {ContainerName} with ID {ContainerId} exited with {ExitCode}", replica, shortContainerId, result.ExitCode); service.Replicas.TryRemove(replica, out var _); service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Removed, status)); }; async Task DockerBuildAsync(CancellationToken cancellationToken) { if (docker.DockerFile != null) { _logger.LogInformation("Building docker image {Image} from docker file", dockerImage); void Log(string data) { _logger.LogInformation("[" + serviceDescription !.Name + "]:" + data); service.Logs.OnNext(data); } var arguments = new StringBuilder($"build \"{docker.DockerFileContext?.FullName}\" -t {dockerImage} -f \"{docker.DockerFile}\""); foreach (var buildArg in docker.BuildArgs) { arguments.Append($" --build-arg {buildArg.Key}={buildArg.Value}"); } var dockerBuildResult = await ProcessUtil.RunAsync( $"docker", arguments.ToString(), outputDataReceived : Log, errorDataReceived : Log, workingDirectory : docker.WorkingDirectory, cancellationToken : cancellationToken, throwOnError : false); if (dockerBuildResult.ExitCode != 0) { throw new CommandException("'docker build' failed."); } } } Task DockerRunAsync(CancellationToken cancellationToken) { var tasks = new Task[serviceDescription !.Replicas]; if (serviceDescription.Bindings.Count > 0) { // Each replica is assigned a list of internal ports, one mapped to each external // port for (var i = 0; i < serviceDescription.Replicas; i++) { var ports = new List <(int, int, int?, string?)>(); foreach (var binding in serviceDescription.Bindings) { if (binding.Port == null) { continue; } ports.Add((binding.Port.Value, binding.ReplicaPorts[i], binding.ContainerPort, binding.Protocol)); } tasks[i] = RunDockerContainer(ports, cancellationToken); } } else { for (var i = 0; i < service.Description.Replicas; i++) { tasks[i] = RunDockerContainer(Enumerable.Empty <(int, int, int?, string?)>(), cancellationToken); } } return(Task.WhenAll(tasks)); }
protected override async Task ProcessMessage(string json) { await base.ProcessMessage(json).ConfigureAwait(false); var msg = JsonConvert.DeserializeObject <WebSocketMessage>(json); var opCode = (OpCodes)msg.Operation; switch (opCode) { case OpCodes.Ready: { if (State != ConnectionState.Connected) { var payload = (msg.Payload as JToken).ToObject <ReadyEvent>(_serializer); _heartbeatInterval = payload.HeartbeatInterval; _ssrc = payload.SSRC; var address = (await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault(); _endpoint = new IPEndPoint(address, payload.Port); if (_config.EnableEncryption) { if (payload.Modes.Contains(EncryptedMode)) { _encryptionMode = EncryptedMode; _isEncrypted = true; } else { throw new InvalidOperationException("Unexpected encryption format."); } } else { _encryptionMode = UnencryptedMode; _isEncrypted = false; } _udp.Connect(_endpoint); _sequence = 0; // (ushort)_rand.Next(0, ushort.MaxValue); //No thread issue here because SendAsync doesn't start until _isReady is true byte[] packet = new byte[70]; packet[0] = (byte)((_ssrc >> 24) & 0xFF); packet[1] = (byte)((_ssrc >> 16) & 0xFF); packet[2] = (byte)((_ssrc >> 8) & 0xFF); packet[3] = (byte)((_ssrc >> 0) & 0xFF); await _udp.SendAsync(packet, 70).ConfigureAwait(false); } } break; case OpCodes.Heartbeat: { long time = EpochTime.GetMilliseconds(); var payload = (long)msg.Payload; _ping = (int)(payload - time); //TODO: Use this to estimate latency } break; case OpCodes.SessionDescription: { var payload = (msg.Payload as JToken).ToObject <SessionDescriptionEvent>(_serializer); _secretKey = payload.SecretKey; SendSetSpeaking(true); await EndConnect(); } break; case OpCodes.Speaking: { var payload = (msg.Payload as JToken).ToObject <SpeakingEvent>(_serializer); RaiseIsSpeaking(payload.UserId, payload.IsSpeaking); } break; default: Logger.Warning($"Unknown Opcode: {opCode}"); break; } }
internal static async Task <IPAddress> ResolveIPAddress(string addrOrHost, byte[] subnet, AddressFamily family) { var loopback = family == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback; IList <IPAddress> nodeIps; // if the address is an empty string, just enumerate all ip addresses available // on this node if (string.IsNullOrEmpty(addrOrHost)) { nodeIps = NetworkInterface.GetAllNetworkInterfaces() .SelectMany(iface => iface.GetIPProperties().UnicastAddresses) .Select(addr => addr.Address) .Where(addr => addr.AddressFamily == family && !IPAddress.IsLoopback(addr)) .ToList(); } else { // Fix StreamFilteringTests_SMS tests if (addrOrHost.Equals("loopback", StringComparison.OrdinalIgnoreCase)) { return(loopback); } // check if addrOrHost is a valid IP address including loopback (127.0.0.0/8, ::1) and any (0.0.0.0/0, ::) addresses IPAddress address; if (IPAddress.TryParse(addrOrHost, out address)) { return(address); } // Get IP address from DNS. If addrOrHost is localhost will // return loopback IPv4 address (or IPv4 and IPv6 addresses if OS is supported IPv6) nodeIps = await Dns.GetHostAddressesAsync(addrOrHost); } var candidates = new List <IPAddress>(); foreach (var nodeIp in nodeIps.Where(x => x.AddressFamily == family)) { // If the subnet does not match - we can't resolve this address. // If subnet is not specified - pick smallest address deterministically. if (subnet == null) { candidates.Add(nodeIp); } else { var ip = nodeIp; if (subnet.Select((b, i) => ip.GetAddressBytes()[i] == b).All(x => x)) { candidates.Add(nodeIp); } } } if (candidates.Count > 0) { return(PickIPAddress(candidates)); } var subnetStr = Utils.EnumerableToString(subnet, null, ".", false); throw new ArgumentException("Hostname '" + addrOrHost + "' with subnet " + subnetStr + " and family " + family + " is not a valid IP address or DNS name"); }
/// <summary> /// Connects to an endpoint. /// </summary> public async Task <bool> BeginConnect(Uri endpointUrl, EventHandler <SocketAsyncEventArgs> callback, object state) { if (endpointUrl == null) { throw new ArgumentNullException("endpointUrl"); } if (m_socket != null) { throw new InvalidOperationException("The socket is already connected."); } // Get DNS host information. IPAddress[] hostAdresses = await Dns.GetHostAddressesAsync(endpointUrl.DnsSafeHost); // try IPv4 and IPv6 address IPAddress addressV4 = null; IPAddress addressV6 = null; foreach (IPAddress address in hostAdresses) { if (address.AddressFamily == AddressFamily.InterNetworkV6) { if (addressV6 == null) { addressV6 = address; } } if (address.AddressFamily == AddressFamily.InterNetwork) { if (addressV4 == null) { addressV4 = address; } } if ((addressV4 != null) && (addressV6 != null)) { break; } } SocketError error = SocketError.NotInitialized; TaskCompletionSource <SocketError> tcs = new TaskCompletionSource <SocketError>(); SocketAsyncEventArgs argsV4 = null; SocketAsyncEventArgs argsV6 = null; m_socketResponses = 0; lock (m_socketLock) { // ensure a valid port. int port = endpointUrl.Port; if (port <= 0 || port > UInt16.MaxValue) { port = Utils.UaTcpDefaultPort; } // create sockets if IP address was provided if (addressV6 != null) { argsV6 = new SocketAsyncEventArgs(); argsV6.UserToken = state; m_socketV6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); argsV6.RemoteEndPoint = new IPEndPoint(addressV6, port); m_socketResponses++; argsV6.Completed += (o, e) => { lock (m_socketLock) { m_socketResponses--; if (m_socketV6 != null) { if (m_socket == null && (m_socketResponses == 0 || e.SocketError == SocketError.Success)) { m_socket = m_socketV6; tcs.SetResult(e.SocketError); } else { m_socketV6.Dispose(); e.UserToken = null; } m_socketV6 = null; } else { e.UserToken = null; } } }; argsV6.Completed += callback; } if (addressV4 != null) { argsV4 = new SocketAsyncEventArgs(); argsV4.UserToken = state; m_socketV4 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); argsV4.RemoteEndPoint = new IPEndPoint(addressV4, port); m_socketResponses++; argsV4.Completed += (o, e) => { lock (m_socketLock) { m_socketResponses--; if (m_socketV4 != null) { if (m_socket == null && (m_socketResponses == 0 || e.SocketError == SocketError.Success)) { m_socket = m_socketV4; tcs.SetResult(e.SocketError); } else { m_socketV4.Dispose(); e.UserToken = null; } m_socketV4 = null; } else { e.UserToken = null; } } }; argsV4.Completed += callback; } bool connectV6Sync = true; bool connectV4Sync = true; if (m_socketV6 != null) { connectV6Sync = !m_socketV6.ConnectAsync(argsV6); if (connectV6Sync) { // I/O completed synchronously callback(this, argsV6); error = argsV6.SocketError; } } if (m_socketV4 != null && error != SocketError.Success) { connectV4Sync = !m_socketV4.ConnectAsync(argsV4); if (connectV4Sync) { // I/O completed synchronously callback(this, argsV4); error = argsV4.SocketError; } } if (connectV4Sync && connectV6Sync) { return((error == SocketError.Success) ? true : false); } } error = await tcs.Task; return((error == SocketError.Success) ? true : false); }
private async Task <string> GetIpAddressFromHostName() { IPAddress[] addresslist = await Dns.GetHostAddressesAsync(RemoteHostName); return(addresslist[0].ToString()); }
public Task <IPAddress[]> Lookup(string hostname) { return(Dns.GetHostAddressesAsync(hostname)); }
public async Task <IpAddressInfo[]> GetHostAddressesAsync(string host) { var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); return(addresses.Select(ToIpAddressInfo).ToArray()); }
public static void Main(string[] args) { string community = "public"; bool showHelp = false; bool showVersion = false; VersionCode version = VersionCode.V1; int timeout = 1000; int retry = 0; Levels level = Levels.Reportable; string user = string.Empty; string contextName = string.Empty; string authentication = string.Empty; string authPhrase = string.Empty; string privacy = string.Empty; string privPhrase = string.Empty; bool dump = false; OptionSet p = new OptionSet() .Add("c:", "Community name, (default is public)", delegate(string v) { if (v != null) { community = v; } }) .Add("l:", "Security level, (default is noAuthNoPriv)", delegate(string v) { if (v.ToUpperInvariant() == "NOAUTHNOPRIV") { level = Levels.Reportable; } else if (v.ToUpperInvariant() == "AUTHNOPRIV") { level = Levels.Authentication | Levels.Reportable; } else if (v.ToUpperInvariant() == "AUTHPRIV") { level = Levels.Authentication | Levels.Privacy | Levels.Reportable; } else { throw new ArgumentException("no such security mode: " + v); } }) .Add("a:", "Authentication method (MD5 or SHA)", delegate(string v) { authentication = v; }) .Add("A:", "Authentication passphrase", delegate(string v) { authPhrase = v; }) .Add("x:", "Privacy method", delegate(string v) { privacy = v; }) .Add("X:", "Privacy passphrase", delegate(string v) { privPhrase = v; }) .Add("u:", "Security name", delegate(string v) { user = v; }) .Add("C:", "Context name", delegate(string v) { contextName = v; }) .Add("h|?|help", "Print this help information.", delegate(string v) { showHelp = v != null; }) .Add("V", "Display version number of this application.", delegate(string v) { showVersion = v != null; }) .Add("d", "Display message dump", delegate(string v) { dump = true; }) .Add("t:", "Timeout value (unit is second).", delegate(string v) { timeout = int.Parse(v) * 1000; }) .Add("r:", "Retry count (default is 0)", delegate(string v) { retry = int.Parse(v); }) .Add("v|version:", "SNMP version (1, 2, and 3 are currently supported)", delegate(string v) { if (v == "2c") { v = "2"; } switch (int.Parse(v)) { case 1: version = VersionCode.V1; break; case 2: version = VersionCode.V2; break; case 3: version = VersionCode.V3; break; default: throw new ArgumentException("no such version: " + v); } }); if (args.Length == 0) { ShowHelp(p); return; } List <string> extra; try { extra = p.Parse(args); } catch (OptionException ex) { Console.WriteLine(ex.Message); return; } if (showHelp) { ShowHelp(p); return; } if (extra.Count < 2) { Console.WriteLine("invalid variable number: " + extra.Count); return; } if (showVersion) { Console.WriteLine(Assembly.GetEntryAssembly().GetCustomAttribute <AssemblyVersionAttribute>().Version); return; } IPAddress ip; bool parsed = IPAddress.TryParse(extra[0], out ip); if (!parsed) { var addresses = Dns.GetHostAddressesAsync(extra[0]); addresses.Wait(); foreach (IPAddress address in addresses.Result.Where(address => address.AddressFamily == AddressFamily.InterNetwork)) { ip = address; break; } if (ip == null) { Console.WriteLine("invalid host or wrong IP address found: " + extra[0]); return; } } try { List <Variable> vList = new List <Variable>(); for (int i = 1; i < extra.Count; i++) { Variable test = new Variable(new ObjectIdentifier(extra[i])); vList.Add(test); } IPEndPoint receiver = new IPEndPoint(ip, 161); if (version != VersionCode.V3) { foreach ( Variable variable in Messenger.Get(version, receiver, new OctetString(community), vList, timeout)) { Console.WriteLine(variable); } return; } if (string.IsNullOrEmpty(user)) { Console.WriteLine("User name need to be specified for v3."); return; } IAuthenticationProvider auth = (level & Levels.Authentication) == Levels.Authentication ? GetAuthenticationProviderByName(authentication, authPhrase) : DefaultAuthenticationProvider.Instance; IPrivacyProvider priv; if ((level & Levels.Privacy) == Levels.Privacy) { if (DESPrivacyProvider.IsSupported) { priv = new DESPrivacyProvider(new OctetString(privPhrase), auth); } else { Console.WriteLine("DES (ECB) is not supported by .NET Core."); return; } } else { priv = new DefaultPrivacyProvider(auth); } Discovery discovery = Messenger.GetNextDiscovery(SnmpType.GetRequestPdu); ReportMessage report = discovery.GetResponse(timeout, receiver); GetRequestMessage request = new GetRequestMessage(VersionCode.V3, Messenger.NextMessageId, Messenger.NextRequestId, new OctetString(user), new OctetString(string.IsNullOrWhiteSpace(contextName) ? string.Empty : contextName), vList, priv, Messenger.MaxMessageSize, report); ISnmpMessage reply = request.GetResponse(timeout, receiver); if (dump) { Console.WriteLine("Request message bytes:"); Console.WriteLine(ByteTool.Convert(request.ToBytes())); Console.WriteLine("Response message bytes:"); Console.WriteLine(ByteTool.Convert(reply.ToBytes())); } if (reply is ReportMessage) { if (reply.Pdu().Variables.Count == 0) { Console.WriteLine("wrong report message received"); return; } var id = reply.Pdu().Variables[0].Id; if (id != Messenger.NotInTimeWindow) { var error = id.GetErrorMessage(); Console.WriteLine(error); return; } // according to RFC 3414, send a second request to sync time. request = new GetRequestMessage(VersionCode.V3, Messenger.NextMessageId, Messenger.NextRequestId, new OctetString(user), new OctetString(string.IsNullOrWhiteSpace(contextName) ? string.Empty : contextName), vList, priv, Messenger.MaxMessageSize, reply); reply = request.GetResponse(timeout, receiver); } else if (reply.Pdu().ErrorStatus.ToInt32() != 0) // != ErrorCode.NoError { throw ErrorException.Create( "error in response", receiver.Address, reply); } foreach (Variable v in reply.Pdu().Variables) { Console.WriteLine(v); } } catch (SnmpException ex) { Console.WriteLine(ex); } catch (SocketException ex) { Console.WriteLine(ex); } }
/// <summary> /// Creates a TCP connection to server /// </summary> /// <param name="remoteHostName">The remote hostname.</param> /// <param name="remotePort">The remote port.</param> /// <param name="httpVersion">The http version to use.</param> /// <param name="isHttps">Is this a HTTPS request.</param> /// <param name="sslProtocol">The SSL protocol.</param> /// <param name="applicationProtocols">The list of HTTPS application level protocol to negotiate if needed.</param> /// <param name="isConnect">Is this a CONNECT request.</param> /// <param name="proxyServer">The current ProxyServer instance.</param> /// <param name="sessionArgs">The http session.</param> /// <param name="upStreamEndPoint">The local upstream endpoint to make request via.</param> /// <param name="externalProxy">The external proxy to make request via.</param> /// <param name="cacheKey">The connection cache key</param> /// <param name="prefetch">if set to <c>true</c> [prefetch].</param> /// <param name="cancellationToken">The cancellation token for this async task.</param> /// <returns></returns> private async Task <TcpServerConnection?> createServerConnection(string remoteHostName, int remotePort, Version httpVersion, bool isHttps, SslProtocols sslProtocol, List <SslApplicationProtocol>?applicationProtocols, bool isConnect, ProxyServer proxyServer, SessionEventArgsBase sessionArgs, IPEndPoint?upStreamEndPoint, IExternalProxy?externalProxy, string cacheKey, bool prefetch, CancellationToken cancellationToken) { // deny connection to proxy end points to avoid infinite connection loop. if (Server.ProxyEndPoints.Any(x => x.Port == remotePort) && NetworkHelper.IsLocalIpAddress(remoteHostName)) { throw new Exception($"A client is making HTTP request to one of the listening ports of this proxy {remoteHostName}:{remotePort}"); } if (externalProxy != null) { if (Server.ProxyEndPoints.Any(x => x.Port == externalProxy.Port) && NetworkHelper.IsLocalIpAddress(externalProxy.HostName)) { throw new Exception($"A client is making HTTP request via external proxy to one of the listening ports of this proxy {remoteHostName}:{remotePort}"); } } if (isHttps && sslProtocol == SslProtocols.None) { sslProtocol = proxyServer.SupportedSslProtocols; } bool useUpstreamProxy1 = false; // check if external proxy is set for HTTP/HTTPS if (externalProxy != null && !(externalProxy.HostName == remoteHostName && externalProxy.Port == remotePort)) { useUpstreamProxy1 = true; // check if we need to ByPass if (externalProxy.BypassLocalhost && NetworkHelper.IsLocalIpAddress(remoteHostName, externalProxy.ProxyDnsRequests)) { useUpstreamProxy1 = false; } } if (!useUpstreamProxy1) { externalProxy = null; } Socket? tcpServerSocket = null; HttpServerStream?stream = null; SslApplicationProtocol negotiatedApplicationProtocol = default; bool retry = true; var enabledSslProtocols = sslProtocol; retry: try { bool socks = externalProxy != null && externalProxy.ProxyType != ExternalProxyType.Http; string hostname = remoteHostName; int port = remotePort; if (externalProxy != null) { hostname = externalProxy.HostName; port = externalProxy.Port; } var ipAddresses = await Dns.GetHostAddressesAsync(hostname); if (ipAddresses == null || ipAddresses.Length == 0) { if (prefetch) { return(null); } throw new Exception($"Could not resolve the hostname {hostname}"); } if (sessionArgs != null) { sessionArgs.TimeLine["Dns Resolved"] = DateTime.UtcNow; } Array.Sort(ipAddresses, (x, y) => x.AddressFamily.CompareTo(y.AddressFamily)); Exception?lastException = null; for (int i = 0; i < ipAddresses.Length; i++) { try { var ipAddress = ipAddresses[i]; var addressFamily = upStreamEndPoint?.AddressFamily ?? ipAddress.AddressFamily; if (socks) { var proxySocket = new ProxySocket.ProxySocket(addressFamily, SocketType.Stream, ProtocolType.Tcp); proxySocket.ProxyType = externalProxy !.ProxyType == ExternalProxyType.Socks4 ? ProxyTypes.Socks4 : ProxyTypes.Socks5; proxySocket.ProxyEndPoint = new IPEndPoint(ipAddress, port); if (!string.IsNullOrEmpty(externalProxy.UserName) && externalProxy.Password != null) { proxySocket.ProxyUser = externalProxy.UserName; proxySocket.ProxyPass = externalProxy.Password; } tcpServerSocket = proxySocket; } else { tcpServerSocket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); } if (upStreamEndPoint != null) { tcpServerSocket.Bind(upStreamEndPoint); } tcpServerSocket.NoDelay = proxyServer.NoDelay; tcpServerSocket.ReceiveTimeout = proxyServer.ConnectionTimeOutSeconds * 1000; tcpServerSocket.SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000; tcpServerSocket.LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds); if (proxyServer.ReuseSocket && RunTime.IsSocketReuseAvailable) { tcpServerSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } Task connectTask; if (socks) { if (externalProxy !.ProxyDnsRequests) { connectTask = ProxySocketConnectionTaskFactory.CreateTask((ProxySocket.ProxySocket)tcpServerSocket, remoteHostName, remotePort); } else { // todo: resolve only once when the SOCKS proxy has multiple addresses (and the first address fails) var remoteIpAddresses = await Dns.GetHostAddressesAsync(remoteHostName); if (remoteIpAddresses == null || remoteIpAddresses.Length == 0) { throw new Exception($"Could not resolve the SOCKS remote hostname {remoteHostName}"); } // todo: use the 2nd, 3rd... remote addresses when first fails connectTask = ProxySocketConnectionTaskFactory.CreateTask((ProxySocket.ProxySocket)tcpServerSocket, remoteIpAddresses[0], remotePort); } } else { connectTask = SocketConnectionTaskFactory.CreateTask(tcpServerSocket, ipAddress, port); } await Task.WhenAny(connectTask, Task.Delay(proxyServer.ConnectTimeOutSeconds * 1000, cancellationToken)); if (!connectTask.IsCompleted || !tcpServerSocket.Connected) { // here we can just do some cleanup and let the loop continue since // we will either get a connection or wind up with a null tcpClient // which will throw try { connectTask.Dispose(); } catch { // ignore } try { #if NET45 tcpServerSocket?.Close(); #else tcpServerSocket?.Dispose(); #endif tcpServerSocket = null; } catch { // ignore } continue; } break; } catch (Exception e) { // dispose the current TcpClient and try the next address lastException = e; #if NET45 tcpServerSocket?.Close(); #else tcpServerSocket?.Dispose(); #endif tcpServerSocket = null; } }
public async Task ConnectAsync_DnsEndPoint_Success(int mode) { using (var client = new DerivedTcpClient()) { Assert.False(client.Connected); Assert.False(client.Active); string host = System.Net.Test.Common.Configuration.Sockets.SocketServer.IdnHost; int port = System.Net.Test.Common.Configuration.Sockets.SocketServer.Port; IPAddress[] addresses; switch (mode) { case 0: await client.ConnectAsync(host, port); break; case 1: addresses = await Dns.GetHostAddressesAsync(host); await client.ConnectAsync(addresses[0], port); break; case 2: addresses = await Dns.GetHostAddressesAsync(host); await client.ConnectAsync(addresses, port); break; case 3: await Task.Factory.FromAsync(client.BeginConnect, client.EndConnect, host, port, null); break; case 4: addresses = await Dns.GetHostAddressesAsync(host); await Task.Factory.FromAsync(client.BeginConnect, client.EndConnect, addresses[0], port, null); break; case 5: addresses = await Dns.GetHostAddressesAsync(host); await Task.Factory.FromAsync(client.BeginConnect, client.EndConnect, addresses, port, null); break; case 6: await client.ConnectAsync(host, port, CancellationToken.None); break; case 7: addresses = await Dns.GetHostAddressesAsync(host); await client.ConnectAsync(addresses[0], port, CancellationToken.None); break; case 8: addresses = await Dns.GetHostAddressesAsync(host); await client.ConnectAsync(new IPEndPoint(addresses[0], port)); break; case 9: addresses = await Dns.GetHostAddressesAsync(host); await client.ConnectAsync(new IPEndPoint(addresses[0], port), CancellationToken.None); break; case 10: addresses = await Dns.GetHostAddressesAsync(host); await client.ConnectAsync(addresses, port, CancellationToken.None); break; } Assert.True(client.Active); Assert.True(client.Connected); Assert.NotNull(client.Client); Assert.Same(client.Client, client.Client); using (NetworkStream s = client.GetStream()) { byte[] getRequest = "GET / HTTP/1.1\r\n\r\n" u8.ToArray(); await s.WriteAsync(getRequest, 0, getRequest.Length); Assert.NotEqual(-1, s.ReadByte()); // just verify we successfully get any data back } } }
public static async Task <Socket> ConnectAsync(string host, int port, IPEndPoint localEndPoint, bool doAsync, CancellationToken cancellationToken) { IPAddress[] ipAddresses; cancellationToken.ThrowIfCancellationRequested(); if (doAsync) { ipAddresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); } else { ipAddresses = Dns.GetHostAddressesAsync(host).GetAwaiter().GetResult(); } for (int i = 0; i < ipAddresses.Length; i++) { cancellationToken.ThrowIfCancellationRequested(); var socket = new Socket(ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { if (localEndPoint != null) { socket.Bind(localEndPoint); } #if NETSTANDARD_2_0 || NET_4_5 || __MOBILE__ if (doAsync || cancellationToken.CanBeCanceled) { var tcs = new TaskCompletionSource <bool> (); using (var registration = cancellationToken.Register(() => tcs.TrySetCanceled(), false)) { var ar = socket.BeginConnect(ipAddresses[i], port, e => tcs.TrySetResult(true), null); if (doAsync) { await tcs.Task.ConfigureAwait(false); } else { tcs.Task.GetAwaiter().GetResult(); } socket.EndConnect(ar); } } else { socket.Connect(ipAddresses[i], port); } #else socket.Connect(ipAddresses[i], port); #endif return(socket); } catch (OperationCanceledException) { socket.Dispose(); throw; } catch { socket.Dispose(); if (i + 1 == ipAddresses.Length) { throw; } } } throw new IOException(string.Format("Failed to resolve host: {0}", host)); }
/// <summary> /// Creates a new Listener obejct from a given listener name and a given listener parameter string. /// </summary> /// <param name="type">The type of object to instantiate.</param> /// <param name="cpars"></param> /// <returns></returns> public Listener CreateListener(string type, string cpars) { try { string[] parts = cpars.Split(';'); object[] pars = new object[parts.Length]; string oval = null, otype = null; int ret; // Start instantiating the objects to give to the constructor for (int i = 0; i < parts.Length; i++) { ret = parts[i].IndexOf(':'); if (ret >= 0) { otype = parts[i].Substring(0, ret); oval = parts[i].Substring(ret + 1); } else { otype = parts[i]; } switch (otype.ToLower()) { case "int": pars[i] = int.Parse(oval); break; case "host": if (oval == "0.0.0.0") { pars[i] = IPAddress.Any; } else { pars[i] = Dns.GetHostAddressesAsync(oval).Result[0]; } break; case "authlist": pars[i] = Config.UserList; break; case "null": pars[i] = null; break; case "string": pars[i] = oval; break; case "ip": pars[i] = IPAddress.Parse(oval); break; default: pars[i] = null; break; } } return((Listener)Activator.CreateInstance(Type.GetType(type), pars)); } catch (Exception ex) { Console.WriteLine("[WARN] " + ex.Message + "\r\n" + ex.StackTrace); return(null); } }
public static async Task ForwardPortAsync(int port, ProtocolType protocol, string description) { if (string.IsNullOrEmpty(_serviceUrl)) { throw new Exception("No UPnP service available or Discover() has not been called"); } XmlDocument xdoc = await SOAPRequestAsync(_serviceUrl, "<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" + "<NewRemoteHost></NewRemoteHost><NewExternalPort>" + port.ToString() + "</NewExternalPort><NewProtocol>" + protocol.ToString().ToUpper() + "</NewProtocol>" + "<NewInternalPort>" + port.ToString() + "</NewInternalPort><NewInternalClient>" + (await Dns.GetHostAddressesAsync(Dns.GetHostName())).First(p => p.AddressFamily == AddressFamily.InterNetwork).ToString() + "</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>" + description + "</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping>", "AddPortMapping"); }
/// <summary> /// Creates a TCP connection to server /// </summary> /// <param name="remoteHostName">The remote hostname.</param> /// <param name="remotePort">The remote port.</param> /// <param name="httpVersion">The http version to use.</param> /// <param name="isHttps">Is this a HTTPS request.</param> /// <param name="applicationProtocols">The list of HTTPS application level protocol to negotiate if needed.</param> /// <param name="isConnect">Is this a CONNECT request.</param> /// <param name="proxyServer">The current ProxyServer instance.</param> /// <param name="session">The http session.</param> /// <param name="upStreamEndPoint">The local upstream endpoint to make request via.</param> /// <param name="externalProxy">The external proxy to make request via.</param> /// <param name="cancellationToken">The cancellation token for this async task.</param> /// <returns></returns> private async Task <TcpServerConnection> createServerConnection(string remoteHostName, int remotePort, Version httpVersion, bool isHttps, List <SslApplicationProtocol> applicationProtocols, bool isConnect, ProxyServer proxyServer, SessionEventArgsBase session, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy, CancellationToken cancellationToken) { //deny connection to proxy end points to avoid infinite connection loop. if (server.ProxyEndPoints.Any(x => x.Port == remotePort) && NetworkHelper.IsLocalIpAddress(remoteHostName)) { throw new Exception($"A client is making HTTP request to one of the listening ports of this proxy {remoteHostName}:{remotePort}"); } if (externalProxy != null) { if (server.ProxyEndPoints.Any(x => x.Port == externalProxy.Port) && NetworkHelper.IsLocalIpAddress(externalProxy.HostName)) { throw new Exception($"A client is making HTTP request via external proxy to one of the listening ports of this proxy {remoteHostName}:{remotePort}"); } } bool useUpstreamProxy = false; // check if external proxy is set for HTTP/HTTPS if (externalProxy != null && !(externalProxy.HostName == remoteHostName && externalProxy.Port == remotePort)) { useUpstreamProxy = true; // check if we need to ByPass if (externalProxy.BypassLocalhost && NetworkHelper.IsLocalIpAddress(remoteHostName)) { useUpstreamProxy = false; } } TcpClient tcpClient = null; CustomBufferedStream stream = null; SslApplicationProtocol negotiatedApplicationProtocol = default; try { tcpClient = new TcpClient(upStreamEndPoint) { ReceiveTimeout = proxyServer.ConnectionTimeOutSeconds * 1000, SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000, SendBufferSize = proxyServer.BufferSize, ReceiveBufferSize = proxyServer.BufferSize, LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds) }; //linux has a bug with socket reuse in .net core. if (proxyServer.ReuseSocket && RunTime.IsWindows || RunTime.IsRunningOnMono) { tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } var hostname = useUpstreamProxy ? externalProxy.HostName : remoteHostName; var port = useUpstreamProxy ? externalProxy.Port : remotePort; var ipAddresses = await Dns.GetHostAddressesAsync(hostname); if (ipAddresses == null || ipAddresses.Length == 0) { throw new Exception($"Could not resolve the hostname {hostname}"); } if (session != null) { session.TimeLine["Dns Resolved"] = DateTime.Now; } for (int i = 0; i < ipAddresses.Length; i++) { try { await tcpClient.ConnectAsync(ipAddresses[i], port); break; } catch (Exception e) { if (i == ipAddresses.Length - 1) { throw new Exception($"Could not establish connection to {hostname}", e); } } } if (session != null) { session.TimeLine["Connection Established"] = DateTime.Now; } await proxyServer.InvokeConnectionCreateEvent(tcpClient, false); stream = new CustomBufferedStream(tcpClient.GetStream(), proxyServer.BufferPool, proxyServer.BufferSize); if (useUpstreamProxy && (isConnect || isHttps)) { var writer = new HttpRequestWriter(stream, proxyServer.BufferPool, proxyServer.BufferSize); var connectRequest = new ConnectRequest { OriginalUrl = $"{remoteHostName}:{remotePort}", HttpVersion = httpVersion }; connectRequest.Headers.AddHeader(KnownHeaders.Connection, KnownHeaders.ConnectionKeepAlive); if (!string.IsNullOrEmpty(externalProxy.UserName) && externalProxy.Password != null) { connectRequest.Headers.AddHeader(HttpHeader.ProxyConnectionKeepAlive); connectRequest.Headers.AddHeader( HttpHeader.GetProxyAuthorizationHeader(externalProxy.UserName, externalProxy.Password)); } await writer.WriteRequestAsync(connectRequest, cancellationToken : cancellationToken); string httpStatus = await stream.ReadLineAsync(cancellationToken); Response.ParseResponseLine(httpStatus, out _, out int statusCode, out string statusDescription); if (statusCode != 200 && !statusDescription.EqualsIgnoreCase("OK") && !statusDescription.EqualsIgnoreCase("Connection Established")) { throw new Exception("Upstream proxy failed to create a secure tunnel"); } await stream.ReadAndIgnoreAllLinesAsync(cancellationToken); } if (isHttps) { var sslStream = new SslStream(stream, false, proxyServer.ValidateServerCertificate, proxyServer.SelectClientCertificate); stream = new CustomBufferedStream(sslStream, proxyServer.BufferPool, proxyServer.BufferSize); var options = new SslClientAuthenticationOptions { ApplicationProtocols = applicationProtocols, TargetHost = remoteHostName, ClientCertificates = null, EnabledSslProtocols = proxyServer.SupportedSslProtocols, CertificateRevocationCheckMode = proxyServer.CheckCertificateRevocation }; await sslStream.AuthenticateAsClientAsync(options, cancellationToken); #if NETCOREAPP2_1 negotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol; #endif if (session != null) { session.TimeLine["HTTPS Established"] = DateTime.Now; } } } catch (Exception) { stream?.Dispose(); tcpClient?.Close(); throw; } return(new TcpServerConnection(proxyServer, tcpClient) { UpStreamProxy = externalProxy, UpStreamEndPoint = upStreamEndPoint, HostName = remoteHostName, Port = remotePort, IsHttps = isHttps, NegotiatedApplicationProtocol = negotiatedApplicationProtocol, UseUpstreamProxy = useUpstreamProxy, StreamWriter = new HttpRequestWriter(stream, proxyServer.BufferPool, proxyServer.BufferSize), Stream = stream, Version = httpVersion }); }
private async Task <RegistrationOperationStatus> ProvisionOverTcpCommonAsync( ProvisioningTransportRegisterMessage message, ClientTlsSettings tlsSettings, CancellationToken cancellationToken) { var tcs = new TaskCompletionSource <RegistrationOperationStatus>(); Bootstrap bootstrap = new Bootstrap() .Group(s_eventLoopGroup) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { ch.Pipeline.AddLast( new ReadTimeoutHandler(ReadTimeoutSeconds), new TlsHandler(tlsSettings), MqttEncoder.Instance, new MqttDecoder(isServer: false, maxMessageSize: MaxMessageSize), new LoggingHandler(LogLevel.DEBUG), new ProvisioningChannelHandlerAdapter(message, tcs, cancellationToken)); })); if (Logging.IsEnabled) { Logging.Associate(bootstrap, this); } IPAddress[] addresses = await Dns.GetHostAddressesAsync(message.GlobalDeviceEndpoint).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Info(this, $"DNS resolved {addresses.Length} addresses."); } IChannel channel = null; Exception lastException = null; foreach (IPAddress address in addresses) { cancellationToken.ThrowIfCancellationRequested(); try { if (Logging.IsEnabled) { Logging.Info(this, $"Connecting to {address.ToString()}."); } channel = await bootstrap.ConnectAsync(address, Port).ConfigureAwait(false); break; } catch (AggregateException ae) { ae.Handle((ex) => { if (ex is ConnectException) // We will handle DotNetty.Transport.Channels.ConnectException { lastException = ex; if (Logging.IsEnabled) { Logging.Info( this, $"ConnectException trying to connect to {address.ToString()}: {ex.ToString()}"); } return(true); } return(false); // Let anything else stop the application. }); } } if (channel == null) { string errorMessage = "Cannot connect to Provisioning Service."; if (Logging.IsEnabled) { Logging.Error(this, errorMessage); } ExceptionDispatchInfo.Capture(lastException).Throw(); } return(await tcs.Task.ConfigureAwait(false)); }
private async Task <bool> OpenTcpSocketAsync(ConnectionSettings cs, IOBehavior ioBehavior, CancellationToken cancellationToken) { foreach (var hostname in cs.Hostnames) { IPAddress[] ipAddresses; try { #if NETSTANDARD1_3 // Dns.GetHostAddresses isn't available until netstandard 2.0: https://github.com/dotnet/corefx/pull/11950 ipAddresses = await Dns.GetHostAddressesAsync(hostname).ConfigureAwait(false); #else if (ioBehavior == IOBehavior.Asynchronous) { ipAddresses = await Dns.GetHostAddressesAsync(hostname).ConfigureAwait(false); } else { ipAddresses = Dns.GetHostAddresses(hostname); } #endif } catch (SocketException) { // name couldn't be resolved continue; } // need to try IP Addresses one at a time: https://github.com/dotnet/corefx/issues/5829 foreach (var ipAddress in ipAddresses) { TcpClient tcpClient = null; try { tcpClient = new TcpClient(ipAddress.AddressFamily); using (cancellationToken.Register(() => tcpClient?.Client?.Dispose())) { try { if (ioBehavior == IOBehavior.Asynchronous) { await tcpClient.ConnectAsync(ipAddress, cs.Port).ConfigureAwait(false); } else { #if NETSTANDARD1_3 await tcpClient.ConnectAsync(ipAddress, cs.Port).ConfigureAwait(false); #else if (Utility.IsWindows()) { tcpClient.Connect(ipAddress, cs.Port); } else { // non-windows platforms block on synchronous connect, use send/receive timeouts: https://github.com/dotnet/corefx/issues/20954 var originalSendTimeout = tcpClient.Client.SendTimeout; var originalReceiveTimeout = tcpClient.Client.ReceiveTimeout; tcpClient.Client.SendTimeout = cs.ConnectionTimeoutMilliseconds; tcpClient.Client.ReceiveTimeout = cs.ConnectionTimeoutMilliseconds; tcpClient.Connect(ipAddress, cs.Port); tcpClient.Client.SendTimeout = originalSendTimeout; tcpClient.Client.ReceiveTimeout = originalReceiveTimeout; } #endif } } catch (ObjectDisposedException ex) when(cancellationToken.IsCancellationRequested) { throw new MySqlException("Connect Timeout expired.", ex); } } } catch (SocketException) { tcpClient?.Client?.Dispose(); continue; } m_hostname = hostname; m_tcpClient = tcpClient; m_socket = m_tcpClient.Client; m_networkStream = m_tcpClient.GetStream(); SerializationUtility.SetKeepalive(m_socket, cs.Keepalive); lock (m_lock) m_state = State.Connected; return(true); } } return(false); }
public async Task <IPEndPoint> ResolveAsync(string endpoint, int port, IPVersion ipVersion = IPVersion.IPV4, CancellationToken token = default(CancellationToken)) { string cacheKey = $"{endpoint}:{port}:{ipVersion}"; if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort) { throw new ArgumentOutOfRangeException(nameof(port)); } if (cache.HasKey(cacheKey)) { return(cache.Get <IPEndPoint>(cacheKey)); } var addressFamily = ipVersion.HasFlag(IPVersion.IPV4) ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6; token.ThrowIfCancellationRequested(); IPEndPoint ipEndpoint; var ipAddress = TryGetIpAddress(endpoint); if (ipAddress != null) { ipEndpoint = new IPEndPoint(ipAddress, port); cache.Add(cacheKey, ipEndpoint, TimeSpan.FromMinutes(60)); return(ipEndpoint); } try { var allAddresses = await Dns.GetHostAddressesAsync(endpoint); var firstAddressInFamily = allAddresses.FirstOrDefault(x => x.AddressFamily == addressFamily); if (firstAddressInFamily != null) { ipEndpoint = new IPEndPoint(firstAddressInFamily, port); cache.Add(cacheKey, ipEndpoint, TimeSpan.FromMinutes(60)); return(ipEndpoint); } if (addressFamily == AddressFamily.InterNetwork && ipVersion.HasFlag(IPVersion.IPV6)) { ipEndpoint = await ResolveAsync(endpoint, port, IPVersion.IPV6, token); if (ipEndpoint != null) { cache.Add(cacheKey, ipEndpoint, TimeSpan.FromMinutes(60)); return(ipEndpoint); } } var firstAddress = allAddresses.FirstOrDefault(); if (firstAddress == null) { return(null); } switch (firstAddress.AddressFamily) { case AddressFamily.InterNetwork: ipEndpoint = new IPEndPoint(firstAddress.MapToIPv6(), port); break; case AddressFamily.InterNetworkV6: ipEndpoint = new IPEndPoint(firstAddress.MapToIPv4(), port); break; default: return(null); } cache.Add(cacheKey, ipEndpoint, TimeSpan.FromMinutes(60)); return(ipEndpoint); } catch { return(null); } }
/// <summary> /// Resolves a hostname to an IP-Address. /// If an IP-Address is given the IP-Address will be returned. /// </summary> public static string ResolveToIp(string hostOrIp) { return(Dns.GetHostAddressesAsync(hostOrIp).Result.First().ToString()); }
private void InitEnvorimentAndVerify() { if (Entities == null || Entities.Count == 0) { this.Log("Count of entity is 0.", LogLevel.Error); throw new SpiderException("Count of entity is 0."); } if (EntityPipelines == null || EntityPipelines.Count == 0) { this.Log("Need at least one entity pipeline.", LogLevel.Error); throw new SpiderException("Need at least one entity pipeline."); } if (RedialExecutor != null) { RedialExecutor.Init(); NetworkCenter.Current.Executor = RedialExecutor; } if (string.IsNullOrEmpty(RedisHost)) { RedisHost = Configuration.GetValue("redisHost"); RedisPassword = Configuration.GetValue("redisPassword"); int port; RedisPort = int.TryParse(Configuration.GetValue("redisPort"), out port) ? port : 6379; } if (!string.IsNullOrEmpty(RedisHost)) { var confiruation = new ConfigurationOptions() { ServiceName = "DotnetSpider", Password = RedisPassword, ConnectTimeout = 65530, KeepAlive = 8, ConnectRetry = 3, ResponseTimeout = 3000 }; #if NET_CORE if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Lewis: This is a Workaround for .NET CORE can't use EndPoint to create Socket. var address = Dns.GetHostAddressesAsync(RedisHost).Result.FirstOrDefault(); if (address == null) { this.Log($"Can't resovle host: {RedisHost}", LogLevel.Error); throw new SpiderException($"Can't resovle host: {RedisHost}"); } confiruation.EndPoints.Add(new IPEndPoint(address, RedisPort)); } else { confiruation.EndPoints.Add(new DnsEndPoint(RedisHost, RedisPort)); } #else confiruation.EndPoints.Add(new DnsEndPoint(RedisHost, RedisPort)); #endif Redis = ConnectionMultiplexer.Connect(confiruation); Db = Redis.GetDatabase(1); } }
public async Task <IActionResult> Maintenance(MaintenanceViewModel vm, string command) { if (!ModelState.IsValid) { return(View(vm)); } vm.SetConfiguredSSH(_Options.SSHSettings); if (command == "changedomain") { if (string.IsNullOrWhiteSpace(vm.DNSDomain)) { ModelState.AddModelError(nameof(vm.DNSDomain), $"Required field"); return(View(vm)); } vm.DNSDomain = vm.DNSDomain.Trim().ToLowerInvariant(); if (vm.DNSDomain.Equals(this.Request.Host.Host, StringComparison.OrdinalIgnoreCase)) { return(View(vm)); } if (IPAddress.TryParse(vm.DNSDomain, out var unused)) { ModelState.AddModelError(nameof(vm.DNSDomain), $"This should be a domain name"); return(View(vm)); } if (vm.DNSDomain.Equals(this.Request.Host.Host, StringComparison.InvariantCultureIgnoreCase)) { ModelState.AddModelError(nameof(vm.DNSDomain), $"The server is already set to use this domain"); return(View(vm)); } var builder = new UriBuilder(); using (var client = new HttpClient(new HttpClientHandler() { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator })) { try { builder.Scheme = this.Request.Scheme; builder.Host = vm.DNSDomain; var addresses1 = Dns.GetHostAddressesAsync(this.Request.Host.Host); var addresses2 = Dns.GetHostAddressesAsync(vm.DNSDomain); await Task.WhenAll(addresses1, addresses2); var addressesSet = addresses1.GetAwaiter().GetResult().Select(c => c.ToString()).ToHashSet(); var hasCommonAddress = addresses2.GetAwaiter().GetResult().Select(c => c.ToString()).Any(s => addressesSet.Contains(s)); if (!hasCommonAddress) { ModelState.AddModelError(nameof(vm.DNSDomain), $"Invalid host ({vm.DNSDomain} is not pointing to this BTCPay instance)"); return(View(vm)); } } catch (Exception ex) { var messages = new List <object>(); messages.Add(ex.Message); if (ex.InnerException != null) { messages.Add(ex.InnerException.Message); } ModelState.AddModelError(nameof(vm.DNSDomain), $"Invalid domain ({string.Join(", ", messages.ToArray())})"); return(View(vm)); } } var error = RunSSH(vm, $"changedomain.sh {vm.DNSDomain}"); if (error != null) { return(error); } builder.Path = null; builder.Query = null; StatusMessage = $"Domain name changing... the server will restart, please use \"{builder.Uri.AbsoluteUri}\""; } else if (command == "update") { var error = RunSSH(vm, $"btcpay-update.sh"); if (error != null) { return(error); } StatusMessage = $"The server might restart soon if an update is available..."; } else { return(NotFound()); } return(RedirectToAction(nameof(Maintenance))); }
private static Task <IPAddress[]> GetIpAddresses(string hostName) { return(Dns.GetHostAddressesAsync(hostName)); }
/// <summary> /// This is called when client is aware of proxy /// So for HTTPS requests client would send CONNECT header to negotiate a secure tcp tunnel via proxy /// </summary> /// <param name="endPoint">The explicit endpoint.</param> /// <param name="clientConnection">The client connection.</param> /// <returns>The task.</returns> private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnection clientConnection) { var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; var clientStream = new HttpClientStream(clientConnection, clientConnection.GetStream(), BufferPool, cancellationToken); Task <TcpServerConnection>?prefetchConnectionTask = null; bool closeServerConnection = false; try { TunnelConnectSessionEventArgs?connectArgs = null; var method = await HttpHelper.GetMethod(clientStream, BufferPool, cancellationToken); if (clientStream.IsClosed) { return; } // Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request) if (method == KnownMethod.Connect) { // read the first line HTTP command var requestLine = await clientStream.ReadRequestLine(cancellationToken); if (requestLine.IsEmpty()) { return; } var connectRequest = new ConnectRequest(requestLine.RequestUri) { RequestUriString8 = requestLine.RequestUri, HttpVersion = requestLine.Version }; await HeaderParser.ReadHeaders(clientStream, connectRequest.Headers, cancellationToken); connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest, clientStream, cancellationTokenSource); clientStream.DataRead += (o, args) => connectArgs.OnDataSent(args.Buffer, args.Offset, args.Count); clientStream.DataWrite += (o, args) => connectArgs.OnDataReceived(args.Buffer, args.Offset, args.Count); await endPoint.InvokeBeforeTunnelConnectRequest(this, connectArgs, ExceptionFunc); // filter out excluded host names bool decryptSsl = endPoint.DecryptSsl && connectArgs.DecryptSsl; bool sendRawData = !decryptSsl; if (connectArgs.DenyConnect) { if (connectArgs.HttpClient.Response.StatusCode == 0) { connectArgs.HttpClient.Response = new Response { HttpVersion = HttpHeader.Version11, StatusCode = (int)HttpStatusCode.Forbidden, StatusDescription = "Forbidden" }; } // send the response await clientStream.WriteResponseAsync(connectArgs.HttpClient.Response, cancellationToken); return; } if (await checkAuthorization(connectArgs) == false) { await endPoint.InvokeBeforeTunnelConnectResponse(this, connectArgs, ExceptionFunc); // send the response await clientStream.WriteResponseAsync(connectArgs.HttpClient.Response, cancellationToken); return; } // write back successful CONNECT response var response = ConnectResponse.CreateSuccessfulConnectResponse(connectRequest.HttpVersion); // Set ContentLength explicitly to properly handle HTTP 1.0 response.ContentLength = 0; response.Headers.FixProxyHeaders(); connectArgs.HttpClient.Response = response; await clientStream.WriteResponseAsync(response, cancellationToken); var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken); if (clientStream.IsClosed) { return; } bool isClientHello = clientHelloInfo != null; if (clientHelloInfo != null) { connectRequest.TunnelType = TunnelType.Https; connectRequest.ClientHelloInfo = clientHelloInfo; } await endPoint.InvokeBeforeTunnelConnectResponse(this, connectArgs, ExceptionFunc, isClientHello); if (decryptSsl && clientHelloInfo != null) { connectRequest.IsHttps = true; // todo: move this line to the previous "if" clientStream.Connection.SslProtocol = clientHelloInfo.SslProtocol; bool http2Supported = false; if (EnableHttp2) { var alpn = clientHelloInfo.GetAlpn(); if (alpn != null && alpn.Contains(SslApplicationProtocol.Http2)) { // test server HTTP/2 support try { // todo: this is a hack, because Titanium does not support HTTP protocol changing currently var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs, true, SslExtensions.Http2ProtocolAsList, true, cancellationToken); http2Supported = connection.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2; // release connection back to pool instead of closing when connection pool is enabled. await tcpConnectionFactory.Release(connection, true); } catch (Exception) { // ignore } } } if (EnableTcpServerConnectionPrefetch) { IPAddress[]? ipAddresses = null; try { // make sure the host can be resolved before creating the prefetch task ipAddresses = await Dns.GetHostAddressesAsync(connectArgs.HttpClient.Request.RequestUri.Host); } catch (SocketException) { } if (ipAddresses != null && ipAddresses.Length > 0) { // don't pass cancellation token here // it could cause floating server connections when client exits prefetchConnectionTask = tcpConnectionFactory.GetServerConnection(this, connectArgs, true, null, false, CancellationToken.None); } } string connectHostname = requestLine.RequestUri.GetString(); int idx = connectHostname.IndexOf(":"); if (idx >= 0) { connectHostname = connectHostname.Substring(0, idx); } X509Certificate2?certificate = null; SslStream? sslStream = null; try { sslStream = new SslStream(clientStream, false); string certName = HttpHelper.GetWildCardDomainName(connectHostname); certificate = endPoint.GenericCertificate ?? await CertificateManager.CreateServerCertificate(certName); // Successfully managed to authenticate the client using the fake certificate var options = new SslServerAuthenticationOptions(); if (EnableHttp2 && http2Supported) { options.ApplicationProtocols = clientHelloInfo.GetAlpn(); if (options.ApplicationProtocols == null || options.ApplicationProtocols.Count == 0) { options.ApplicationProtocols = SslExtensions.Http11ProtocolAsList; } } options.ServerCertificate = certificate; options.ClientCertificateRequired = false; options.EnabledSslProtocols = SupportedSslProtocols; options.CertificateRevocationCheckMode = X509RevocationMode.NoCheck; await sslStream.AuthenticateAsServerAsync(options, cancellationToken); #if NETSTANDARD2_1 clientStream.Connection.NegotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol; #endif // HTTPS server created - we can now decrypt the client's traffic clientStream = new HttpClientStream(clientStream.Connection, sslStream, BufferPool, cancellationToken); sslStream = null; // clientStream was created, no need to keep SSL stream reference clientStream.DataRead += (o, args) => connectArgs.OnDecryptedDataSent(args.Buffer, args.Offset, args.Count); clientStream.DataWrite += (o, args) => connectArgs.OnDecryptedDataReceived(args.Buffer, args.Offset, args.Count); } catch (Exception e) { sslStream?.Dispose(); var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false); throw new ProxyConnectException( $"Couldn't authenticate host '{connectHostname}' with certificate '{certName}'.", e, connectArgs); } method = await HttpHelper.GetMethod(clientStream, BufferPool, cancellationToken); if (clientStream.IsClosed) { return; } if (method == KnownMethod.Invalid) { sendRawData = true; await tcpConnectionFactory.Release(prefetchConnectionTask, true); prefetchConnectionTask = null; } } else if (clientHelloInfo == null) { method = await HttpHelper.GetMethod(clientStream, BufferPool, cancellationToken); if (clientStream.IsClosed) { return; } } if (cancellationTokenSource.IsCancellationRequested) { throw new Exception("Session was terminated by user."); } if (method == KnownMethod.Invalid) { sendRawData = true; } // Hostname is excluded or it is not an HTTPS connect if (sendRawData) { // create new connection to server. // If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then // this connection should not be HTTPS. var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs, true, null, true, cancellationToken); try { if (isClientHello) { int available = clientStream.Available; if (available > 0) { // send the buffered data var data = BufferPool.GetBuffer(); try { // clientStream.Available should be at most BufferSize because it is using the same buffer size int read = await clientStream.ReadAsync(data, 0, available, cancellationToken); if (read != available) { throw new Exception("Internal error."); } await connection.Stream.WriteAsync(data, 0, available, true, cancellationToken); } finally { BufferPool.ReturnBuffer(data); } } var serverHelloInfo = await SslTools.PeekServerHello(connection.Stream, BufferPool, cancellationToken); ((ConnectResponse)connectArgs.HttpClient.Response).ServerHelloInfo = serverHelloInfo; } if (!clientStream.IsClosed && !connection.Stream.IsClosed) { await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, null, null, connectArgs.CancellationTokenSource, ExceptionFunc); } } finally { await tcpConnectionFactory.Release(connection, true); } return; } } if (connectArgs != null && method == KnownMethod.Pri) { // todo string?httpCmd = await clientStream.ReadLineAsync(cancellationToken); if (httpCmd == "PRI * HTTP/2.0") { connectArgs.HttpClient.ConnectRequest !.TunnelType = TunnelType.Http2; // HTTP/2 Connection Preface string?line = await clientStream.ReadLineAsync(cancellationToken); if (line != string.Empty) { throw new Exception($"HTTP/2 Protocol violation. Empty string expected, '{line}' received"); } line = await clientStream.ReadLineAsync(cancellationToken); if (line != "SM") { throw new Exception($"HTTP/2 Protocol violation. 'SM' expected, '{line}' received"); } line = await clientStream.ReadLineAsync(cancellationToken); if (line != string.Empty) { throw new Exception($"HTTP/2 Protocol violation. Empty string expected, '{line}' received"); } var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs, true, SslExtensions.Http2ProtocolAsList, true, cancellationToken); try { #if NETSTANDARD2_1 var connectionPreface = new ReadOnlyMemory <byte>(Http2Helper.ConnectionPreface); await connection.Stream.WriteAsync(connectionPreface, cancellationToken); await Http2Helper.SendHttp2(clientStream, connection.Stream, () => new SessionEventArgs(this, endPoint, clientStream, connectArgs?.HttpClient.ConnectRequest, cancellationTokenSource) { UserData = connectArgs?.UserData }, async args => { await onBeforeRequest(args); }, async args => { await onBeforeResponse(args); }, connectArgs.CancellationTokenSource, clientStream.Connection.Id, ExceptionFunc); #endif } finally { await tcpConnectionFactory.Release(connection, true); } } } var prefetchTask = prefetchConnectionTask; prefetchConnectionTask = null; // Now create the request await handleHttpSessionRequest(endPoint, clientStream, cancellationTokenSource, connectArgs, prefetchTask); } catch (ProxyException e) { closeServerConnection = true; onException(clientStream, e); } catch (IOException e) { closeServerConnection = true; onException(clientStream, new Exception("Connection was aborted", e)); } catch (SocketException e) { closeServerConnection = true; onException(clientStream, new Exception("Could not connect", e)); } catch (Exception e) { closeServerConnection = true; onException(clientStream, new Exception("Error occured in whilst handling the client", e)); } finally { if (!cancellationTokenSource.IsCancellationRequested) { cancellationTokenSource.Cancel(); } await tcpConnectionFactory.Release(prefetchConnectionTask, closeServerConnection); clientStream.Dispose(); } }
protected async Task EnsureConnected() { try { if (IsConnected()) { return; } // Recreate the TCP client this.stream?.Dispose(); this.client?.Close(); // Allow connections to be made via IPv4 or IPv6. With just the default constructor, // only IPv4 can be used. To support both, we must specify the AddressFamily.InterNetworkV6 // and set the DualMode property on the underlying socket to true. The DualMode property // can only be set to true when the AddressFamily is set to InterNetworkV6. // // But there is another caveat. If you call the .Connect() method overload that takes in a // DNS host name and port number, that method's code will first make a call to resolve the // DNS host name to an IP address (or addresses). It then validates that one of the resolved // IP addresses' AddressFamily type matches the AddressFamily type that was specified when // the TcpClient was constructed. If it doesn't find a match, for example, because we specify // AddressFamily.InterNetworkV6 and the DNS host name only resolves to an IPv4 address, it // will throw an error. Essentially, the .Connect() method that takes in a DNS host name and // port does not take into consideration the DualMode property that we set to true. // // All other .Connect() methods take in some form of IPAddress/IPEndPoint, which gets passed // directly down to the underlying socket, which is where the DualMode property exists. // Therefore, it is properly utilized and will work with either IPv4 or IPv6. // // So, we will make a call to resolve the DNS host name ourselves and call the .Connect() // method that takes in the array of IP addresses. That way, it will try each of them and will // work regardless of if the DNS host name resolved to an IPv4 or IPv6. this.client = new TcpClient(AddressFamily.InterNetworkV6); this.client.Client.DualMode = true; // If the Host name specified is already an IP address, then that is what will be returned. var hostAddresses = await Dns.GetHostAddressesAsync(this.Host).ConfigureAwait(false); // If we're running on Linux, only try to set keep-alives if they are wanted (in // that case we resolved the hostname to an IP in the ctor) // See https://github.com/dotnet/corefx/issues/26840 if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || this.enableKeepAlive) { this.client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, this.enableKeepAlive); } // Reduce latency to a minimum this.client.NoDelay = true; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Windows can support multiple connection attempts, thereby allowing us to pass in an // array of addresses. See: // https://github.com/dotnet/runtime/blob/release/5.0/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs#L5071 await this.client.ConnectAsync(hostAddresses, this.Port).ConfigureAwait(false); } else { // However, multiple connection attempts is not guaranteed on other platforms. So we'll // be cautious and only use the first IP address. If for whatever reason the caller was // hoping that the second or some other IP address would be used, then they will just // have to change their DNS so that the IP address they want will be resolved with the // highest priority. await this.client.ConnectAsync(hostAddresses.First(), this.Port).ConfigureAwait(false); } this.stream = await GetStream(this.client.GetStream()).ConfigureAwait(false); } catch (Exception ex) { // Attempt to provide meaningful diagnostic messages for common connection problems HandleConnectError(ex); throw; } }
/// <summary> /// Constructor /// </summary> /// <param name="serverName">Server name</param> /// <param name="port">TCP port number</param> /// <param name="timerExpire">Connection timer expiration</param> /// <param name="callbackObject">Callback object</param> public SNITCPHandle(string serverName, int port, long timerExpire, object callbackObject, bool parallel) { _writeScheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler; _writeTaskFactory = new TaskFactory(_writeScheduler); _callbackObject = callbackObject; _targetServer = serverName; try { TimeSpan ts = default(TimeSpan); // In case the Timeout is Infinite, we will receive the max value of Int64 as the tick count // The infinite Timeout is a function of ConnectionString Timeout=0 bool isInfiniteTimeOut = long.MaxValue == timerExpire; if (!isInfiniteTimeOut) { ts = DateTime.FromFileTime(timerExpire) - DateTime.Now; ts = ts.Ticks < 0 ? TimeSpan.FromTicks(0) : ts; } Task <Socket> connectTask; if (parallel) { Task <IPAddress[]> serverAddrTask = Dns.GetHostAddressesAsync(serverName); serverAddrTask.Wait(ts); IPAddress[] serverAddresses = serverAddrTask.Result; if (serverAddresses.Length > MaxParallelIpAddresses) { // Fail if above 64 to match legacy behavior ReportTcpSNIError(0, SNICommon.MultiSubnetFailoverWithMoreThan64IPs, string.Empty); return; } connectTask = ParallelConnectAsync(serverAddresses, port); } else { connectTask = ConnectAsync(serverName, port); } if (!(isInfiniteTimeOut ? connectTask.Wait(-1) : connectTask.Wait(ts))) { ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty); return; } _socket = connectTask.Result; if (_socket == null || !_socket.Connected) { if (_socket != null) { _socket.Dispose(); _socket = null; } ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty); return; } _socket.NoDelay = true; _tcpStream = new NetworkStream(_socket, true); _sslOverTdsStream = new SslOverTdsStream(_tcpStream); _sslStream = new SslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); } catch (SocketException se) { ReportTcpSNIError(se); return; } catch (Exception e) { ReportTcpSNIError(e); return; } _stream = _tcpStream; _status = TdsEnums.SNI_SUCCESS; }
private async Task InitializeOnceAsync(CancellationToken cancellationToken) { // Build the options for our Redis client. var redisOptions = new ConfigurationOptions { ResolveDns = true, Password = configuration.RedisPassword }; // Resolve the IPs for all the Redis servers. var resolveServersTasks = this.configuration.RedisServers.Select(kv => new KeyValuePair <Task <IPAddress[]>, int>(Dns.GetHostAddressesAsync(kv.Key), kv.Value)).ToList(); await Task.WhenAll(resolveServersTasks.Select(kv => kv.Key)); // Add them to the Redis options. var ipRedisServers = resolveServersTasks .Where(t => t.Key.Result != null) .SelectMany(kv => kv.Key.Result .Where(ip => ip.AddressFamily == AddressFamily.InterNetwork) .Select(ip => new KeyValuePair <IPAddress, int>(ip, kv.Value))) .ToList(); foreach (var kv in ipRedisServers) { redisOptions.EndPoints.Add(kv.Key, kv.Value); } // Try to connect to the redis instance. var connection = await ConnectionMultiplexer.ConnectAsync(redisOptions); this.database = connection.GetDatabase(); // Create the resource store based on that connection. this.Users = new RedisCacheStore <CacheUser>(this.jsonHelpers, this.configuration, this.database); }
public Task <IPAddress[]> GetHostAddressesAsync(string hostNameOrAddress) { return(Dns.GetHostAddressesAsync(hostNameOrAddress)); }
/// <summary> /// Connect to the specified host /// </summary> /// <param name="host">The host to connect to</param> /// <param name="port">The port to connect to</param> /// <param name="ipVersions">Internet Protocol versions to support during the connection phase</param> /// <param name="token">Cancellation Token</param> public async Task ConnectAsync(string host, int port, FtpIpVersion ipVersions, CancellationToken token) { IPAddress[] addresses = await Dns.GetHostAddressesAsync(host); if (ipVersions == 0) { throw new ArgumentException("The ipVersions parameter must contain at least 1 flag."); } for (int i = 0; i < addresses.Length; i++) { // we don't need to do this check unless // a particular version of IP has been // omitted so we won't. if (ipVersions != FtpIpVersion.ANY) { switch (addresses[i].AddressFamily) { case AddressFamily.InterNetwork: if ((ipVersions & FtpIpVersion.IPv4) != FtpIpVersion.IPv4) { #if DEBUG this.Client.LogStatus(FtpTraceLevel.Verbose, "Skipped IPV4 address : " + addresses[i].ToString()); #endif continue; } break; case AddressFamily.InterNetworkV6: if ((ipVersions & FtpIpVersion.IPv6) != FtpIpVersion.IPv6) { #if DEBUG this.Client.LogStatus(FtpTraceLevel.Verbose, "Skipped IPV6 address : " + addresses[i].ToString()); #endif continue; } break; } } if (FtpTrace.LogIP) { this.Client.LogStatus(FtpTraceLevel.Info, "Connecting to " + addresses[i].ToString() + ":" + port); } else { this.Client.LogStatus(FtpTraceLevel.Info, "Connecting to ***:" + port); } m_socket = new Socket(addresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp); #if CORE await EnableCancellation(m_socket.ConnectAsync(addresses[i], port), token, () => m_socket.Dispose()); break; #else var connectResult = m_socket.BeginConnect(addresses[i], port, null, null); await EnableCancellation(Task.Factory.FromAsync(connectResult, m_socket.EndConnect), token, () => m_socket.Close()); break; #endif } // make sure that we actually connected to // one of the addresses returned from GetHostAddresses() if (m_socket == null || !m_socket.Connected) { Close(); throw new IOException("Failed to connect to host."); } m_netStream = new NetworkStream(m_socket); m_netStream.ReadTimeout = m_readTimeout; m_lastActivity = DateTime.Now; }
/// <summary> /// Connect to the specified host /// </summary> /// <param name="host">The host to connect to</param> /// <param name="port">The port to connect to</param> /// <param name="ipVersions">Internet Protocol versions to support during the connection phase</param> public void Connect(string host, int port, FtpIpVersion ipVersions) { #if CORE IPAddress[] addresses = Dns.GetHostAddressesAsync(host).Result; #else IAsyncResult ar = null; IPAddress[] addresses = Dns.GetHostAddresses(host); #endif if (ipVersions == 0) { throw new ArgumentException("The ipVersions parameter must contain at least 1 flag."); } for (int i = 0; i < addresses.Length; i++) { // we don't need to do this check unless // a particular version of IP has been // omitted so we won't. if (ipVersions != FtpIpVersion.ANY) { switch (addresses[i].AddressFamily) { case AddressFamily.InterNetwork: if ((ipVersions & FtpIpVersion.IPv4) != FtpIpVersion.IPv4) { #if DEBUG FtpTrace.WriteStatus(FtpTraceLevel.Verbose, "Skipped IPV4 address : " + addresses[i].ToString()); #endif continue; } break; case AddressFamily.InterNetworkV6: if ((ipVersions & FtpIpVersion.IPv6) != FtpIpVersion.IPv6) { #if DEBUG FtpTrace.WriteStatus(FtpTraceLevel.Verbose, "Skipped IPV6 address : " + addresses[i].ToString()); #endif continue; } break; } } if (FtpTrace.LogIP) { FtpTrace.WriteStatus(FtpTraceLevel.Info, "Connecting to " + addresses[i].ToString() + ":" + port); } else { FtpTrace.WriteStatus(FtpTraceLevel.Info, "Connecting to ***:" + port); } m_socket = new Socket(addresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp); #if CORE m_socket.ConnectAsync(addresses[i], port).Wait(); break; #else ar = m_socket.BeginConnect(addresses[i], port, null, null); if (!ar.AsyncWaitHandle.WaitOne(m_connectTimeout, true)) { Close(); // check to see if we're out of addresses, and throw a TimeoutException if ((i + 1) == addresses.Length) { throw new TimeoutException("Timed out trying to connect!"); } } else { m_socket.EndConnect(ar); // we got a connection, break out // of the loop. break; } #endif } // make sure that we actually connected to // one of the addresses returned from GetHostAddresses() if (m_socket == null || !m_socket.Connected) { Close(); throw new IOException("Failed to connect to host."); } m_netStream = new NetworkStream(m_socket); m_netStream.ReadTimeout = m_readTimeout; m_lastActivity = DateTime.Now; }
public async Task Dns_GetHostAddressesAsync_NullHost_Fail() { await Assert.ThrowsAsync <ArgumentNullException>(() => Dns.GetHostAddressesAsync(null)); }