Пример #1
0
        /// <overloads>this method has 2 overloads</overloads>
        /// <summary>
        /// Connects to the specified server and port, when the connection fails
        /// the next server in the list will be used.
        /// </summary>
        /// <param name="addresslist">List of servers to connect to</param>
        /// <param name="port">Portnumber to connect to</param>
        /// <exception cref="CouldNotConnectException">The connection failed</exception>
        /// <exception cref="AlreadyConnectedException">If there is already an active connection</exception>
        public void Connect(string[] addresslist, int port)
        {
            if (_IsConnected) {
                throw new AlreadyConnectedException("Already connected to: " + Address + ":" + Port);
            }

            _AutoRetryAttempt++;
            #if LOG4NET
            Logger.Connection.Info(String.Format("connecting... (attempt: {0})",
                                                 _AutoRetryAttempt));
            #endif

            _AddressList = (string[])addresslist.Clone();
            _Port = port;

            if (OnConnecting != null) {
                OnConnecting(this, EventArgs.Empty);
            }
            try {
                _TcpClient = new TcpClient();
                _TcpClient.NoDelay = true;
                _TcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1);
                // set timeout, after this the connection will be aborted
                _TcpClient.ReceiveTimeout = _SocketReceiveTimeout * 1000;
                _TcpClient.SendTimeout = _SocketSendTimeout * 1000;

                if (_ProxyType != ProxyType.None) {
                    IProxyClient proxyClient = null;
                    ProxyClientFactory proxyFactory = new ProxyClientFactory();
                    // HACK: map our ProxyType to Starksoft's ProxyType
                    Starksoft.Aspen.Proxy.ProxyType proxyType =
                        (Starksoft.Aspen.Proxy.ProxyType) Enum.Parse(
                            typeof(ProxyType), _ProxyType.ToString(), true
                        );

                    if (_ProxyUsername == null && _ProxyPassword == null) {
                        proxyClient = proxyFactory.CreateProxyClient(
                            proxyType
                        );
                    } else {
                        proxyClient = proxyFactory.CreateProxyClient(
                            proxyType,
                            _ProxyHost,
                            _ProxyPort,
                            _ProxyUsername,
                            _ProxyPassword
                        );
                    }

                    _TcpClient.Connect(_ProxyHost, _ProxyPort);
                    proxyClient.TcpClient = _TcpClient;
                    proxyClient.CreateConnection(Address, port);
                } else {
                    _TcpClient.Connect(Address, port);
                }

                Stream stream = _TcpClient.GetStream();
                if (_UseSsl) {
                    RemoteCertificateValidationCallback certValidation;
                    if (_ValidateServerCertificate) {
                        certValidation = ServicePointManager.ServerCertificateValidationCallback;
                        if (certValidation == null) {
                            certValidation = delegate(object sender,
                                X509Certificate certificate,
                                X509Chain chain,
                                SslPolicyErrors sslPolicyErrors) {
                                if (sslPolicyErrors == SslPolicyErrors.None) {
                                    return true;
                                }

            #if LOG4NET
                                Logger.Connection.Error(
                                    "Connect(): Certificate error: " +
                                    sslPolicyErrors
                                );
            #endif
                                return false;
                            };
                        }
                    } else {
                        certValidation = delegate { return true; };
                    }
                    RemoteCertificateValidationCallback certValidationWithIrcAsSender =
                        delegate(object sender, X509Certificate certificate,
                                 X509Chain chain, SslPolicyErrors sslPolicyErrors) {
                        return certValidation(this, certificate, chain, sslPolicyErrors);
                    };
                    SslStream sslStream = new SslStream(stream, false,
                                                        certValidationWithIrcAsSender);
                    try {
                        if (_SslClientCertificate != null) {
                            var certs = new X509Certificate2Collection();
                            certs.Add(_SslClientCertificate);
                            sslStream.AuthenticateAsClient(Address, certs,
                                                           SslProtocols.Default,
                                                           false);
                        } else {
                            sslStream.AuthenticateAsClient(Address);
                        }
                    } catch (IOException ex) {
            #if LOG4NET
                        Logger.Connection.Error(
                            "Connect(): AuthenticateAsClient() failed!"
                        );
            #endif
                        throw new CouldNotConnectException("Could not connect to: " + Address + ":" + Port + " " + ex.Message, ex);
                    }
                    stream = sslStream;
                }
                if (EnableUTF8Recode) {
                    _Reader = new StreamReader(stream, new PrimaryOrFallbackEncoding(new UTF8Encoding(false, true), _Encoding));
                    _Writer = new StreamWriter(stream, new UTF8Encoding(false, false));
                } else {
                    _Reader = new StreamReader(stream, _Encoding);
                    _Writer = new StreamWriter(stream, _Encoding);

                    if (_Encoding.GetPreamble().Length > 0) {
                        // HACK: we have an encoding that has some kind of preamble
                        // like UTF-8 has a BOM, this will confuse the IRCd!
                        // Thus we send a \r\n so the IRCd can safely ignore that
                        // garbage.
                        _Writer.WriteLine();
                        // make sure we flush the BOM+CRLF correctly
                        _Writer.Flush();
                    }
                }

                // Connection was succeful, reseting the connect counter
                _AutoRetryAttempt = 0;

                // updating the connection error state, so connecting is possible again
                IsConnectionError = false;
                _IsConnected = true;

                // lets power up our threads
                _ReadThread.Start();
                _WriteThread.Start();
                _IdleWorkerThread.Start();

            #if LOG4NET
                Logger.Connection.Info("connected");
            #endif
                if (OnConnected != null) {
                    OnConnected(this, EventArgs.Empty);
                }
            } catch (AuthenticationException ex) {
            #if LOG4NET
                Logger.Connection.Error("Connect(): Exception", ex);
            #endif
                throw new CouldNotConnectException("Could not connect to: " + Address + ":" + Port + " " + ex.Message, ex);
            } catch (Exception e) {
                if (_Reader != null) {
                    try {
                        _Reader.Close();
                    } catch (ObjectDisposedException) {
                    }
                }
                if (_Writer != null) {
                    try {
                        _Writer.Close();
                    } catch (ObjectDisposedException) {
                    }
                }
                if (_TcpClient != null) {
                    _TcpClient.Close();
                }
                _IsConnected = false;
                IsConnectionError = true;

            #if LOG4NET
                Logger.Connection.Info("connection failed: "+e.Message, e);
            #endif
                if (e is CouldNotConnectException) {
                    // error was fatal, bail out
                    throw;
                }

                if (_AutoRetry &&
                    (_AutoRetryLimit == -1 ||
                     _AutoRetryLimit == 0 ||
                     _AutoRetryLimit <= _AutoRetryAttempt)) {
                    if (OnAutoConnectError != null) {
                        OnAutoConnectError(this, new AutoConnectErrorEventArgs(Address, Port, e));
                    }
            #if LOG4NET
                    Logger.Connection.Debug("delaying new connect attempt for "+_AutoRetryDelay+" sec");
            #endif
                    Thread.Sleep(_AutoRetryDelay * 1000);
                    _NextAddress();
                    // FIXME: this is recursion
                    Connect(_AddressList, _Port);
                } else {
                    throw new CouldNotConnectException("Could not connect to: "+Address+":"+Port+" "+e.Message, e);
                }
            }
        }
Пример #2
0
 public TorProxy(string target_host, int target_port, string proxy_host, int proxy_port, ProxyType type)
 {
     if (InputProxyMessage != null) InputProxyMessage.Invoke("Socket allocated.");
     proxy_connection = new connection();
     proxy_connection.proxy_config(target_host, target_port, proxy_host, proxy_port, type);
     ProxyClientFactory factory = new ProxyClientFactory();
     proxy_connection.Proxy = factory.CreateProxyClient(type, proxy_host, proxy_port);
     proxy_connection.Proxy.CreateConnectionAsyncCompleted += new EventHandler<CreateConnectionAsyncCompletedEventArgs>(proxy_connected);
 }