summaryrefslogtreecommitdiff
path: root/cs/src/IceSSL/ConnectorI.cs
blob: 0284bba29955dab21f43ab17662f870c6f740965 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// **********************************************************************
//
// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************

namespace IceSSL
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;

    sealed class ConnectorI : IceInternal.Connector
    {
        internal const short TYPE = 2;

        public IceInternal.Transceiver connect()
        {
            //
            // The plug-in may not be fully initialized.
            //
            if(!_instance.initialized())
            {
                Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
                ex.reason = "IceSSL: plug-in is not initialized";
                throw ex;
            }

            if(_instance.networkTraceLevel() >= 2)
            {
                string s = "trying to establish ssl connection to " + ToString();
                _logger.trace(_instance.networkTraceCategory(), s);
            }

            try
            {
                Socket fd = IceInternal.Network.createSocket(false, _addr.AddressFamily);
                IceInternal.Network.setBlock(fd, true); // SSL requires a blocking socket.

                //
                // Windows XP has an IPv6 bug that makes a socket appear to be unconnected if you
                // set the socket's receive buffer size, and this in turn causes .NET to raise an
                // exception that would prevent us from using SSL.
                //
                if(_addr.AddressFamily != AddressFamily.InterNetworkV6 || !IceInternal.AssemblyUtil.xp_)
                {
                    IceInternal.Network.setTcpBufSize(fd, _instance.communicator().getProperties(), _logger);
                }

                //
                // Nonblocking connect is handled by the transceiver.
                //
                return new TransceiverI(_instance, fd, _addr, _host, false, null);
            }
            catch(Ice.LocalException ex)
            {
                if(_instance.networkTraceLevel() >= 2)
                {
                    string s = "failed to establish ssl connection to " + ToString() + "\n" + ex;
                    _logger.trace(_instance.networkTraceCategory(), s);
                }
                throw;
            }
        }

        public short type()
        {
            return TYPE;
        }

        //
        // Only for use by EndpointI.
        //
        internal ConnectorI(Instance instance, string host, IPEndPoint addr, int timeout, string connectionId)
        {
            _instance = instance;
            _host = host;
            _logger = instance.communicator().getLogger();
            _addr = addr;
            _timeout = timeout;
            _connectionId = connectionId;

            _hashCode = _addr.GetHashCode();
            _hashCode = 5 * _hashCode + _timeout;
            _hashCode = 5 * _hashCode + _connectionId.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            ConnectorI p = null;

            try
            {
                p = (ConnectorI)obj;
            }
            catch(System.InvalidCastException)
            {
                return false;
            }

            if(this == p)
            {
                return true;
            }

            if(_timeout != p._timeout)
            {
                return false;
            }

            if(!_connectionId.Equals(p._connectionId))
            {
                return false;
            }

            return IceInternal.Network.compareAddress(_addr, p._addr) == 0;
        }

        public override string ToString()
        {
            return IceInternal.Network.addrToString(_addr);
        }

        public override int GetHashCode()
        {
            return _hashCode;
        }

        private Instance _instance;
        private Ice.Logger _logger;
        private string _host;
        private IPEndPoint _addr;
        private int _timeout;
        private string _connectionId;
        private int _hashCode;
    }
}