public void RawOpen(int timeout) { // Keep track of time remaining; Even though there may be multiple timeout-able calls, // this allows us to still respect the caller's timeout expectation. var attemptStart = DateTime.Now; var result = Dns.BeginGetHostAddresses(Host, null, null); if (!result.AsyncWaitHandle.WaitOne(timeout, true)) { // Timeout was used up attempting the Dns lookup throw new TimeoutException(L10N.DnsLookupTimeout); } timeout -= Convert.ToInt32((DateTime.Now - attemptStart).TotalMilliseconds); var ips = Dns.EndGetHostAddresses(result); Socket socket = null; Exception lastSocketException = null; // try every ip address of the given hostname, use the first reachable one // make sure not to exceed the caller's timeout expectation by splitting the // time we have left between all the remaining ip's in the list. for (var i = 0; i < ips.Length; i++) { _log.Trace("Attempting to connect to " + ips[i]); var ep = new IPEndPoint(ips[i], Port); socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); attemptStart = DateTime.Now; try { result = socket.BeginConnect(ep, null, null); if (!result.AsyncWaitHandle.WaitOne(timeout / (ips.Length - i), true)) { throw new TimeoutException(L10N.ConnectionTimeout); } socket.EndConnect(result); // connect was successful, leave the loop break; } catch (Exception e) { _log.Warn("Failed to connect to " + ips[i]); timeout -= Convert.ToInt32((DateTime.Now - attemptStart).TotalMilliseconds); lastSocketException = e; socket.Close(); socket = null; } } if (socket == null) { throw lastSocketException; } var baseStream = new NpgsqlNetworkStream(socket, true); Stream sslStream = null; // If the PostgreSQL server has SSL connectors enabled Open SslClientStream if (response == 'S') { if (SSL || (SslMode == SslMode.Require) || (SslMode == SslMode.Prefer)) { baseStream .WriteInt32(8) .WriteInt32(80877103); // Receive response var response = (Char)baseStream.ReadByte(); if (response != 'S') { if (SslMode == SslMode.Require) { throw new InvalidOperationException(L10N.SslRequestError); } } else { //create empty collection var clientCertificates = new X509CertificateCollection(); //trigger the callback to fetch some certificates DefaultProvideClientCertificatesCallback(clientCertificates); //if (context.UseMonoSsl) if (!UseSslStream) { var sslStreamPriv = new SslClientStream(baseStream, Host, true, SecurityProtocolType.Default, clientCertificates) { ClientCertSelectionDelegate = DefaultCertificateSelectionCallback, ServerCertValidationDelegate = DefaultCertificateValidationCallback, PrivateKeyCertSelectionDelegate = DefaultPrivateKeySelectionCallback }; sslStream = sslStreamPriv; IsSecure = true; } else { var sslStreamPriv = new SslStream(baseStream, true, DefaultValidateRemoteCertificateCallback); sslStreamPriv.AuthenticateAsClient(Host, clientCertificates, System.Security.Authentication.SslProtocols.Default, false); sslStream = sslStreamPriv; IsSecure = true; } } } Socket = socket; BaseStream = baseStream; //Stream = new BufferedStream(sslStream ?? baseStream, 8192); Stream = BaseStream; Buffer = new NpgsqlBuffer(Stream, BufferSize, PGUtil.UTF8Encoding); _log.DebugFormat("Connected to {0}:{1 }", Host, Port); }
public override void Open(NpgsqlConnector context, Int32 timeout) { try { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open"); IAsyncResult result; // Keep track of time remaining; Even though there may be multiple timeout-able calls, // this allows us to still respect the caller's timeout expectation. DateTime attemptStart; attemptStart = DateTime.Now; result = Dns.BeginGetHostAddresses(context.Host, null, null); if (!result.AsyncWaitHandle.WaitOne(timeout, true)) { // Timeout was used up attempting the Dns lookup throw new TimeoutException(resman.GetString("Exception_DnsLookupTimeout")); } timeout -= Convert.ToInt32((DateTime.Now - attemptStart).TotalMilliseconds); IPAddress[] ips = Dns.EndGetHostAddresses(result); Socket socket = null; Exception lastSocketException = null; // try every ip address of the given hostname, use the first reachable one // make sure not to exceed the caller's timeout expectation by splitting the // time we have left between all the remaining ip's in the list. for (int i = 0; i < ips.Length; i++) { NpgsqlEventLog.LogMsg(resman, "Log_ConnectingTo", LogLevel.Debug, ips[i]); IPEndPoint ep = new IPEndPoint(ips[i], context.Port); socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); attemptStart = DateTime.Now; try { result = socket.BeginConnect(ep, null, null); if (!result.AsyncWaitHandle.WaitOne(timeout / (ips.Length - i), true)) { throw new TimeoutException(resman.GetString("Exception_ConnectionTimeout")); } socket.EndConnect(result); // connect was successful, leave the loop break; } catch (Exception e) { NpgsqlEventLog.LogMsg(resman, "Log_FailedConnection", LogLevel.Normal, ips[i]); timeout -= Convert.ToInt32((DateTime.Now - attemptStart).TotalMilliseconds); lastSocketException = e; socket.Close(); socket = null; } } if (socket == null) { throw lastSocketException; } NpgsqlNetworkStream baseStream = new NpgsqlNetworkStream(socket, true); Stream sslStream = null; // If the PostgreSQL server has SSL connectors enabled Open SslClientStream if (response == 'S') { if (context.SSL || (context.SslMode == SslMode.Require) || (context.SslMode == SslMode.Prefer)) { baseStream .WriteInt32(8) .WriteInt32(80877103); // Receive response Char response = (Char)baseStream.ReadByte(); if (response == 'S') { //create empty collection X509CertificateCollection clientCertificates = new X509CertificateCollection(); //trigger the callback to fetch some certificates context.DefaultProvideClientCertificatesCallback(clientCertificates); //if (context.UseMonoSsl) if (!NpgsqlConnector.UseSslStream) { SslClientStream sslStreamPriv; sslStreamPriv = new SslClientStream( baseStream, context.Host, true, SecurityProtocolType.Default, clientCertificates); sslStreamPriv.ClientCertSelectionDelegate = new CertificateSelectionCallback(context.DefaultCertificateSelectionCallback); sslStreamPriv.ServerCertValidationDelegate = new CertificateValidationCallback(context.DefaultCertificateValidationCallback); sslStreamPriv.PrivateKeyCertSelectionDelegate = new PrivateKeySelectionCallback(context.DefaultPrivateKeySelectionCallback); sslStream = sslStreamPriv; } else { SslStream sslStreamPriv; sslStreamPriv = new SslStream(baseStream, true, context.DefaultValidateRemoteCertificateCallback); sslStreamPriv.AuthenticateAsClient(context.Host, clientCertificates, System.Security.Authentication.SslProtocols.Default, false); sslStream = sslStreamPriv; } } else if (context.SslMode == SslMode.Require) { throw new InvalidOperationException(resman.GetString("Exception_Ssl_RequestError")); } } context.Socket = socket; context.BaseStream = baseStream; context.Stream = new BufferedStream(sslStream == null ? baseStream : sslStream, 8192); NpgsqlEventLog.LogMsg(resman, "Log_ConnectedTo", LogLevel.Normal, context.Host, context.Port); ChangeState(context, NpgsqlConnectedState.Instance); } catch (Exception e) { throw new NpgsqlException(string.Format(resman.GetString("Exception_FailedConnection"), context.Host), e); } }
public override void Open(NpgsqlConnector context) { try { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open"); /*TcpClient tcpc = new TcpClient(); tcpc.Connect(new IPEndPoint(ResolveIPHost(context.Host), context.Port)); Stream stream = tcpc.GetStream();*/ /*socket.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.SendTimeout, context.ConnectionTimeout*1000);*/ //socket.Connect(new IPEndPoint(ResolveIPHost(context.Host), context.Port)); /*Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); IAsyncResult result = socket.BeginConnect(new IPEndPoint(ResolveIPHost(context.Host), context.Port), null, null); if (!result.AsyncWaitHandle.WaitOne(context.ConnectionTimeout*1000, true)) { socket.Close(); throw new Exception(resman.GetString("Exception_ConnectionTimeout")); } try { socket.EndConnect(result); } catch (Exception) { socket.Close(); throw; } */ IPAddress[] ips = ResolveIPHost(context.Host); Socket socket = null; // try every ip address of the given hostname, use the first reachable one foreach (IPAddress ip in ips) { NpgsqlEventLog.LogMsg(resman, "Log_ConnectingTo", LogLevel.Debug, ip); IPEndPoint ep = new IPEndPoint(ip, context.Port); socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { IAsyncResult result = socket.BeginConnect(ep, null, null); if (!result.AsyncWaitHandle.WaitOne(context.ConnectionTimeout*1000, true)) { socket.Close(); throw new Exception(resman.GetString("Exception_ConnectionTimeout")); } socket.EndConnect(result); // connect was successful, leave the loop break; } catch (Exception) { NpgsqlEventLog.LogMsg(resman, "Log_FailedConnection", LogLevel.Normal, ip); socket.Close(); } } if (socket == null || !socket.Connected) { throw new Exception(string.Format(resman.GetString("Exception_FailedConnection"), context.Host)); } //Stream stream = new NetworkStream(socket, true); Stream stream = new NpgsqlNetworkStream(context, socket, true); // If the PostgreSQL server has SSL connectors enabled Open SslClientStream if (response == 'S') { if (context.SSL || (context.SslMode == SslMode.Require) || (context.SslMode == SslMode.Prefer)) { PGUtil.WriteInt32(stream, 8); PGUtil.WriteInt32(stream, 80877103); // Receive response Char response = (Char) stream.ReadByte(); if (response == 'S') { //create empty collection X509CertificateCollection clientCertificates = new X509CertificateCollection(); //trigger the callback to fetch some certificates context.DefaultProvideClientCertificatesCallback(clientCertificates); stream = new SslClientStream( stream, context.Host, true, SecurityProtocolType.Default, clientCertificates); ((SslClientStream) stream).ClientCertSelectionDelegate = new CertificateSelectionCallback(context.DefaultCertificateSelectionCallback); ((SslClientStream) stream).ServerCertValidationDelegate = new CertificateValidationCallback(context.DefaultCertificateValidationCallback); ((SslClientStream) stream).PrivateKeyCertSelectionDelegate = new PrivateKeySelectionCallback(context.DefaultPrivateKeySelectionCallback); } else if (context.SslMode == SslMode.Require) { throw new InvalidOperationException(resman.GetString("Exception_Ssl_RequestError")); } } context.Stream = new BufferedStream(stream); context.Socket = socket; NpgsqlEventLog.LogMsg(resman, "Log_ConnectedTo", LogLevel.Normal, context.Host, context.Port); ChangeState(context, NpgsqlConnectedState.Instance); } //FIXME: Exceptions that come from what we are handling should be wrapped - e.g. an error connecting to //the server should definitely be presented to the uesr as an NpgsqlError. Exceptions from userland should //be passed untouched - e.g. ThreadAbortException because the user started this in a thread they created and //then aborted should be passed through. //Are there any others that should be pass through? Alternatively, are there a finite number that should //be wrapped? catch (ThreadAbortException) { throw; } catch (Exception e) { throw new NpgsqlException(e.Message, e); } }
public override void Open(NpgsqlConnector context) { try { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open"); IPAddress[] ips = ResolveIPHost(context.Host); Socket socket = null; // try every ip address of the given hostname, use the first reachable one foreach (IPAddress ip in ips) { NpgsqlEventLog.LogMsg(resman, "Log_ConnectingTo", LogLevel.Debug, ip); IPEndPoint ep = new IPEndPoint(ip, context.Port); socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { IAsyncResult result = socket.BeginConnect(ep, null, null); if (!result.AsyncWaitHandle.WaitOne(context.ConnectionTimeout * 1000, true)) { socket.Close(); throw new Exception(resman.GetString("Exception_ConnectionTimeout")); } socket.EndConnect(result); // connect was successful, leave the loop break; } catch (Exception) { NpgsqlEventLog.LogMsg(resman, "Log_FailedConnection", LogLevel.Normal, ip); socket.Close(); } } if (socket == null || !socket.Connected) { throw new Exception(string.Format(resman.GetString("Exception_FailedConnection"), context.Host)); } Stream stream = new NpgsqlNetworkStream(context, socket, true); // If the PostgreSQL server has SSL connectors enabled Open SslClientStream if (response == 'S') { if (context.SSL || (context.SslMode == SslMode.Require) || (context.SslMode == SslMode.Prefer)) { PGUtil.WriteInt32(stream, 8); PGUtil.WriteInt32(stream, 80877103); // Receive response Char response = (Char)stream.ReadByte(); if (response == 'S') { //create empty collection X509CertificateCollection clientCertificates = new X509CertificateCollection(); //trigger the callback to fetch some certificates context.DefaultProvideClientCertificatesCallback(clientCertificates); stream = new SslClientStream( stream, context.Host, true, SecurityProtocolType.Default, clientCertificates); ((SslClientStream)stream).ClientCertSelectionDelegate = new CertificateSelectionCallback(context.DefaultCertificateSelectionCallback); ((SslClientStream)stream).ServerCertValidationDelegate = new CertificateValidationCallback(context.DefaultCertificateValidationCallback); ((SslClientStream)stream).PrivateKeyCertSelectionDelegate = new PrivateKeySelectionCallback(context.DefaultPrivateKeySelectionCallback); } else if (context.SslMode == SslMode.Require) { throw new InvalidOperationException(resman.GetString("Exception_Ssl_RequestError")); } } context.Stream = new NpgsqlBufferedStream(stream); context.Socket = socket; NpgsqlEventLog.LogMsg(resman, "Log_ConnectedTo", LogLevel.Normal, context.Host, context.Port); ChangeState(context, NpgsqlConnectedState.Instance); } //FIXME: Exceptions that come from what we are handling should be wrapped - e.g. an error connecting to //the server should definitely be presented to the uesr as an NpgsqlError. Exceptions from userland should //be passed untouched - e.g. ThreadAbortException because the user started this in a thread they created and //then aborted should be passed through. //Are there any others that should be pass through? Alternatively, are there a finite number that should //be wrapped? catch (ThreadAbortException) { throw; } catch (Exception e) { throw new NpgsqlException(e.Message, e); } }
public override void Open(NpgsqlConnector context, Int32 timeout) { try { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open"); /*TcpClient tcpc = new TcpClient(); tcpc.Connect(new IPEndPoint(ResolveIPHost(context.Host), context.Port)); Stream stream = tcpc.GetStream();*/ /*socket.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.SendTimeout, context.ConnectionTimeout*1000);*/ //socket.Connect(new IPEndPoint(ResolveIPHost(context.Host), context.Port)); /*Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); IAsyncResult result = socket.BeginConnect(new IPEndPoint(ResolveIPHost(context.Host), context.Port), null, null); if (!result.AsyncWaitHandle.WaitOne(context.ConnectionTimeout*1000, false)) { socket.Close(); throw new Exception(resman.GetString("Exception_ConnectionTimeout")); } try { socket.EndConnect(result); } catch (Exception) { socket.Close(); throw; } */ IAsyncResult result; // Keep track of time remaining; Even though there may be multiple timeout-able calls, // this allows us to still respect the caller's timeout expectation. DateTime attemptStart; attemptStart = DateTime.Now; result = Dns.BeginGetHostAddresses(context.Host, null, null); if (!result.AsyncWaitHandle.WaitOne(timeout, true)) { // Timeout was used up attempting the Dns lookup throw new TimeoutException(resman.GetString("Exception_DnsLookupTimeout")); } timeout -= Convert.ToInt32((DateTime.Now - attemptStart).TotalMilliseconds); IPAddress[] ips = Dns.EndGetHostAddresses(result); Socket socket = null; Exception lastSocketException = null; // try every ip address of the given hostname, use the first reachable one // make sure not to exceed the caller's timeout expectation by splitting the // time we have left between all the remaining ip's in the list. for (int i = 0 ; i < ips.Length ; i++) { NpgsqlEventLog.LogMsg(resman, "Log_ConnectingTo", LogLevel.Debug, ips[i]); IPEndPoint ep = new IPEndPoint(ips[i], context.Port); socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); attemptStart = DateTime.Now; try { result = socket.BeginConnect(ep, null, null); if (!result.AsyncWaitHandle.WaitOne(timeout / (ips.Length - i), true)) { throw new TimeoutException(resman.GetString("Exception_ConnectionTimeout")); } socket.EndConnect(result); // connect was successful, leave the loop break; } catch (Exception e) { NpgsqlEventLog.LogMsg(resman, "Log_FailedConnection", LogLevel.Normal, ips[i]); timeout -= Convert.ToInt32((DateTime.Now - attemptStart).TotalMilliseconds); lastSocketException = e; socket.Close(); socket = null; } } if (socket == null) { throw lastSocketException; } //Stream stream = new NetworkStream(socket, true); Stream stream = new NpgsqlNetworkStream(context, socket, true); // If the PostgreSQL server has SSL connectors enabled Open SslClientStream if (response == 'S') { if (context.SSL || (context.SslMode == SslMode.Require) || (context.SslMode == SslMode.Prefer)) { PGUtil.WriteInt32(stream, 8); PGUtil.WriteInt32(stream, 80877103); // Receive response Char response = (Char) stream.ReadByte(); if (response == 'S') { //create empty collection X509CertificateCollection clientCertificates = new X509CertificateCollection(); //trigger the callback to fetch some certificates context.DefaultProvideClientCertificatesCallback(clientCertificates); if (context.UseMonoSsl) { stream = new SslClientStream( stream, context.Host, true, SecurityProtocolType.Default, clientCertificates); ((SslClientStream)stream).ClientCertSelectionDelegate = new CertificateSelectionCallback(context.DefaultCertificateSelectionCallback); ((SslClientStream)stream).ServerCertValidationDelegate = new CertificateValidationCallback(context.DefaultCertificateValidationCallback); ((SslClientStream)stream).PrivateKeyCertSelectionDelegate = new PrivateKeySelectionCallback(context.DefaultPrivateKeySelectionCallback); } else { SslStream sstream = new SslStream(stream, true, delegate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors) { return context.DefaultValidateRemoteCertificateCallback(cert, chain, errors); }); sstream.AuthenticateAsClient(context.Host, clientCertificates, System.Security.Authentication.SslProtocols.Default, false); stream = sstream; } } else if (context.SslMode == SslMode.Require) { throw new InvalidOperationException(resman.GetString("Exception_Ssl_RequestError")); } } context.Stream = new BufferedStream(stream); context.Socket = socket; NpgsqlEventLog.LogMsg(resman, "Log_ConnectedTo", LogLevel.Normal, context.Host, context.Port); ChangeState(context, NpgsqlConnectedState.Instance); } catch (Exception e) { throw new NpgsqlException(string.Format(resman.GetString("Exception_FailedConnection"), context.Host), e); } }