public override void Open (ConnectionOptions options)
		{
			Socket socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			bool useRoundRobin = options.RoundRobin;
			int hostIndex = 0;
			int startIndex = 0;

	                charset_utf8 = (options.Charset != null && options.Charset.ToUpper() == "UTF-8");

			ArrayList ds_list = options.DataSourceList;
			if (ds_list != null)
			{
				if (ds_list.Count <= 1)
					useRoundRobin = false;

				if (ds_list.Count > 1 && useRoundRobin)
					startIndex = hostIndex = rnd.Next(ds_list.Count);

				while(true)
				{
			        	try {
			        		if (ds_list.Count == 0)
			        		{
							socket.Connect (GetEndPoint (null));
						}
						else
						{
							socket.Connect (GetEndPoint ((string)ds_list[hostIndex]));
						}
			        	        break;
			        	} catch (SocketException e) {
			        		hostIndex++;
			        		if (useRoundRobin)
			        		{
			        			if (ds_list.Count == hostIndex)
			        				hostIndex = 0;
			        			if (hostIndex == startIndex)
			        				throw e;
			        		}
			        		else if (ds_list.Count == hostIndex) // Failover mode last rec
			        		{
			        			throw e;
			        		}
			        	}
				}
			}

			try
			{
				session = new TcpSession (this, socket);
                		socket.NoDelay = true;

#if MONO
				Future future = new Future (Service.CallerId, new object[] { null });
#else
				Future future = new Future (Service.CallerId, (object) null); // not object[]
#endif
				future.SendRequest (session, options.ConnectionTimeout);
				object[] results = (object[]) future.GetResultSerial (session);
				peer = (string) results[1];

				object[] idOpts = null;
				if (results.Length > 2)
					idOpts = (object[]) results[2];
				int pwdClearCode = GetConnectionOption (idOpts, "SQL_ENCRYPTION_ON_PASSWORD", -1);
				Debug.WriteLineIf (Switch.Enabled, "pwdClearCode: " + pwdClearCode);

				string user = options.UserId;
				string password = null;
				if (pwdClearCode == 1)
					password = options.Password;
				else if (pwdClearCode == 2)
					password = MagicEncrypt (user, options.Password);
				else
					password = Digest (user, options.Password, peer);

				object[] info = new object[6];
				info[0] = ".NET Application";
				info[1] = 0;
				info[2] = Environment.MachineName;
				info[3] = ".NET";
				info[4] = options.Charset != null ? options.Charset.ToUpper () : "";
				info[5] = 0;
				future = new Future (Service.Connect, user, password, Values.VERSION, info);
				future.SendRequest (session, options.ConnectionTimeout);
				results = future.GetResultSerial (session) as object[];
				if (results == null)
					throw new SystemException ("Login failed.");
				switch ((AnswerTag) results[0])
				{
				case AnswerTag.QA_LOGIN:
					SetConnectionOptions (results);
					break;

				case AnswerTag.QA_ERROR:
					throw new SystemException (results[1].ToString () + " " + results[2].ToString ());

				default:
					throw new SystemException ("Bad login response.");
				}

				if (options.Database != null
					&& options.Database != String.Empty
					&& options.Database != currentCatalog)
					SetCurrentCatalog (options.Database);
			}
			catch (Exception)
			{
				Close ();
				throw;
			}
		}
Beispiel #2
0
        public override void Open(ConnectionOptions options)
        {
            Socket socket        = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            bool   useRoundRobin = options.RoundRobin;
            int    hostIndex     = 0;
            int    startIndex    = 0;

            charset_utf8 = (options.Charset != null && options.Charset.ToUpper() == "UTF-8");

            ArrayList ds_list = options.DataSourceList;

            if (ds_list != null)
            {
                if (ds_list.Count <= 1)
                {
                    useRoundRobin = false;
                }

                if (ds_list.Count > 1 && useRoundRobin)
                {
                    startIndex = hostIndex = rnd.Next(ds_list.Count);
                }

                while (true)
                {
                    try {
                        if (ds_list.Count == 0)
                        {
                            socket.Connect(GetEndPoint(null));
                        }
                        else
                        {
                            socket.Connect(GetEndPoint((string)ds_list[hostIndex]));
                        }
                        break;
                    } catch (SocketException e) {
                        hostIndex++;
                        if (useRoundRobin)
                        {
                            if (ds_list.Count == hostIndex)
                            {
                                hostIndex = 0;
                            }
                            if (hostIndex == startIndex)
                            {
                                throw e;
                            }
                        }
                        else if (ds_list.Count == hostIndex)                         // Failover mode last rec
                        {
                            throw e;
                        }
                    }
                }
            }

            try
            {
                session        = new TcpSession(this, socket);
                socket.NoDelay = true;

#if MONO
                Future future = new Future(Service.CallerId, new object[] { null });
#else
                Future future = new Future(Service.CallerId, (object)null);                   // not object[]
#endif
                future.SendRequest(session, options.ConnectionTimeout);
                object[] results = (object[])future.GetResultSerial(session);
                peer = (string)results[1];

                object[] idOpts = null;
                if (results.Length > 2)
                {
                    idOpts = (object[])results[2];
                }
                int pwdClearCode = GetConnectionOption(idOpts, "SQL_ENCRYPTION_ON_PASSWORD", -1);
                Debug.WriteLineIf(Switch.Enabled, "pwdClearCode: " + pwdClearCode);

                string user     = options.UserId;
                string password = null;
                if (pwdClearCode == 1)
                {
                    password = options.Password;
                }
                else if (pwdClearCode == 2)
                {
                    password = MagicEncrypt(user, options.Password);
                }
                else
                {
                    password = Digest(user, options.Password, peer);
                }

                object[] info = new object[6];
                info[0] = ".NET Application";
                info[1] = 0;
                info[2] = Environment.MachineName;
                info[3] = ".NET";
                info[4] = options.Charset != null?options.Charset.ToUpper() : "";

                info[5] = 0;
                future  = new Future(Service.Connect, user, password, Values.VERSION, info);
                future.SendRequest(session, options.ConnectionTimeout);
                results = future.GetResultSerial(session) as object[];
                if (results == null)
                {
                    throw new SystemException("Login failed.");
                }
                switch ((AnswerTag)results[0])
                {
                case AnswerTag.QA_LOGIN:
                    SetConnectionOptions(results);
                    break;

                case AnswerTag.QA_ERROR:
                    throw new SystemException(results[1].ToString() + " " + results[2].ToString());

                default:
                    throw new SystemException("Bad login response.");
                }

                if (options.Database != null &&
                    options.Database != String.Empty &&
                    options.Database != currentCatalog)
                {
                    SetCurrentCatalog(options.Database);
                }
            }
            catch (Exception)
            {
                Close();
                throw;
            }
        }