Example #1
0
        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);
        }
Example #2
0
        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);
            }
        }
Example #4
0
        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);
            }
        }
Example #5
0
        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);
            }
        }