Beispiel #1
0
        public static ScenePresence AddChildClient(
            Scene scene, LLUDPServer udpServer, UUID agentId, UUID sessionId, uint circuitCode)
        {
            IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);

            UseCircuitCodePacket uccp = new UseCircuitCodePacket();

            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code      = circuitCode;
            uccpCcBlock.ID        = agentId;
            uccpCcBlock.SessionID = sessionId;
            uccp.CircuitCode      = uccpCcBlock;

            byte[]          uccpBytes = uccp.ToBytes();
            UDPPacketBuffer upb       = new UDPPacketBuffer(testEp, uccpBytes.Length);

            upb.DataLength = uccpBytes.Length;  // God knows why this isn't set by the constructor.
            Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);

            AgentCircuitData acd = new AgentCircuitData();

            acd.AgentID   = agentId;
            acd.SessionID = sessionId;

            scene.AuthenticateHandler.AddNewCircuit(circuitCode, acd);

            udpServer.PacketReceived(upb);

            return(scene.GetScenePresence(agentId));
        }
Beispiel #2
0
        /// <summary>
        /// Add a new client circuit.  We assume that is has already passed an authorization check
        /// </summary>
        /// <param name="epSender"></param>
        /// <param name="useCircuit"></param>
        /// <param name="assetCache"></param>
        /// <param name="sessionInfo"></param>
        /// <param name="proxyEP"></param>
        /// <returns>
        /// true if a new circuit was created, false if a circuit with the given circuit code already existed
        /// </returns>
        public virtual bool AddNewClient(
            EndPoint epSender, UseCircuitCodePacket useCircuit, IAssetCache assetCache,
            AuthenticateResponse sessionInfo, EndPoint proxyEP)
        {
            IClientAPI newuser;
            uint       circuitCode = useCircuit.CircuitCode.Code;

            if (m_scene.ClientManager.TryGetClient(circuitCode, out newuser))
            {
                // The circuit is already known to the scene.  This not actually a problem since this will currently
                // occur if a client is crossing borders (hence upgrading its circuit).  However, we shouldn't
                // really by trying to add a new client if this is the case.
                return(false);
            }

            UUID agentId   = useCircuit.CircuitCode.ID;
            UUID sessionId = useCircuit.CircuitCode.SessionID;

            newuser
                = CreateNewCircuit(
                      epSender, m_scene, assetCache, this, sessionInfo, agentId, sessionId, circuitCode, proxyEP);

            m_scene.ClientManager.Add(circuitCode, newuser);

            newuser.OnViewerEffect     += m_scene.ClientManager.ViewerEffectHandler;
            newuser.OnLogout           += LogoutHandler;
            newuser.OnConnectionClosed += CloseClient;

            newuser.Start();

            return(true);
        }
        /// <summary>
        /// Used by tests that aren't testing this stage.
        /// </summary>
        private ScenePresence AddClient()
        {
            UUID       myAgentUuid   = TestHelpers.ParseTail(0x1);
            UUID       mySessionUuid = TestHelpers.ParseTail(0x2);
            uint       myCircuitCode = 123456;
            IPEndPoint testEp        = new IPEndPoint(IPAddress.Loopback, 999);

            UseCircuitCodePacket uccp = new UseCircuitCodePacket();

            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code      = myCircuitCode;
            uccpCcBlock.ID        = myAgentUuid;
            uccpCcBlock.SessionID = mySessionUuid;
            uccp.CircuitCode      = uccpCcBlock;

            byte[]          uccpBytes = uccp.ToBytes();
            UDPPacketBuffer upb       = new UDPPacketBuffer(testEp, uccpBytes.Length);

            upb.DataLength = uccpBytes.Length;  // God knows why this isn't set by the constructor.
            Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);

            AgentCircuitData acd = new AgentCircuitData();

            acd.AgentID   = myAgentUuid;
            acd.SessionID = mySessionUuid;

            m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);

            m_udpServer.PacketReceived(upb);

            return(m_scene.GetScenePresence(myAgentUuid));
        }
Beispiel #4
0
        private void HandleUseCircuitCode(UDPPacketBuffer buffer, UseCircuitCodePacket packet, int now)
        {
            IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;

            LLAgent agent;

            if (m_clients.TryGetValue(packet.CircuitCode.ID, out agent))
            {
                // Update the remoteEndPoint for this agent
                m_clients.UpdateKey2(agent.ID, agent.RemoteEndPoint, remoteEndPoint);
                agent.RemoteEndPoint = remoteEndPoint;

                // Acknowledge the UseCircuitCode packet
                SendAckImmediate(remoteEndPoint, packet.Header.Sequence);

                // Fire any callbacks registered for this packet
                IncomingPacket incomingPacket = new IncomingPacket(agent, packet, now);
                incomingPacket.StartedHandling = now;
                PacketEvents.BeginRaiseEvent(incomingPacket);
            }
            else
            {
                m_log.Error("Failed to add new client " + packet.CircuitCode.ID + " connecting from " + remoteEndPoint);
            }
        }
        private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
        {
            UUID agentID     = useCircuitCode.CircuitCode.ID;
            UUID sessionID   = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            if (m_scene.RegionStatus != RegionStatus.SlaveScene)
            {
                AuthenticateResponse sessionInfo;
                if (IsClientAuthorized(useCircuitCode, out sessionInfo))
                {
                    AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
                }
                else
                {
                    // Don't create circuits for unauthorized clients
                    m_log.WarnFormat(
                        "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
                        useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
                }
            }
            else
            {
                // Slave regions don't accept new clients
                m_log.Debug("[LLUDPSERVER]: Slave region " + m_scene.RegionInfo.RegionName + " ignoring UseCircuitCode packet");
            }
        }
Beispiel #6
0
        public void RestoreClient(AgentCircuitData circuit, EndPoint userEP, EndPoint proxyEP)
        {
            //MainLog.Instance.Verbose("UDPSERVER", "RestoreClient");

            UseCircuitCodePacket useCircuit = new UseCircuitCodePacket();

            useCircuit.CircuitCode.Code      = circuit.circuitcode;
            useCircuit.CircuitCode.ID        = circuit.AgentID;
            useCircuit.CircuitCode.SessionID = circuit.SessionID;

            AuthenticateResponse sessionInfo;

            if (!m_packetServer.IsClientAuthorized(useCircuit, m_circuitManager, out sessionInfo))
            {
                m_log.WarnFormat(
                    "[CLIENT]: Restore request denied to avatar {0} connecting with unauthorized circuit code {1}",
                    useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code);

                return;
            }

            lock (clientCircuits)
            {
                if (!clientCircuits.ContainsKey(userEP))
                {
                    clientCircuits.Add(userEP, useCircuit.CircuitCode.Code);
                }
                else
                {
                    m_log.Error("[CLIENT]: clientCircuits already contains entry for user " + useCircuit.CircuitCode.Code + ". NOT adding.");
                }
            }

            // This data structure is synchronized, so we don't need the lock
            if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code))
            {
                clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, userEP);
            }
            else
            {
                m_log.Error("[CLIENT]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code + ". NOT adding.");
            }

            lock (proxyCircuits)
            {
                if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
                {
                    proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
                }
                else
                {
                    // re-set proxy endpoint
                    proxyCircuits.Remove(useCircuit.CircuitCode.Code);
                    proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
                }
            }

            m_packetServer.AddNewClient(userEP, useCircuit, m_assetCache, sessionInfo, proxyEP);
        }
Beispiel #7
0
        private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint, out AgentCircuitData sessionInfo)
        {
            UUID agentID     = useCircuitCode.CircuitCode.ID;
            UUID sessionID   = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            sessionInfo = m_circuitManager.AuthenticateSession(sessionID, agentID, circuitCode, remoteEndPoint);
            return(sessionInfo != null);
        }
        private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
        {
            UUID agentID     = useCircuitCode.CircuitCode.ID;
            UUID sessionID   = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            sessionInfo = m_circuitManager.AuthenticateSession(sessionID, agentID, circuitCode);
            return(sessionInfo.Authorised);
        }
        public void TestAddClient()
        {
            TestHelpers.InMethod();
            //            TestHelpers.EnableLogging();

            AddUdpServer();

            UUID       myAgentUuid   = TestHelpers.ParseTail(0x1);
            UUID       mySessionUuid = TestHelpers.ParseTail(0x2);
            uint       myCircuitCode = 123456;
            IPEndPoint testEp        = new IPEndPoint(IPAddress.Loopback, 999);

            UseCircuitCodePacket uccp = new UseCircuitCodePacket();

            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code      = myCircuitCode;
            uccpCcBlock.ID        = myAgentUuid;
            uccpCcBlock.SessionID = mySessionUuid;
            uccp.CircuitCode      = uccpCcBlock;

            byte[]          uccpBytes = uccp.ToBytes();
            UDPPacketBuffer upb       = new UDPPacketBuffer(testEp, uccpBytes.Length);

            upb.DataLength = uccpBytes.Length;  // God knows why this isn't set by the constructor.
            Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);

            m_udpServer.PacketReceived(upb);

            // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
            Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);

            AgentCircuitData acd = new AgentCircuitData();

            acd.AgentID   = myAgentUuid;
            acd.SessionID = mySessionUuid;

            m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);

            m_udpServer.PacketReceived(upb);

            // Should succeed now
            ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);

            Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));

            Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1));

            Packet packet = m_udpServer.PacketsSent[0];

            Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));

            PacketAckPacket ackPacket = packet as PacketAckPacket;

            Assert.That(ackPacket.Packets.Length, Is.EqualTo(1));
            Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
        }
        protected override void AddNewClient(Packet packet)
        {
            UseCircuitCodePacket useCircuit = (UseCircuitCodePacket)packet;

            this.clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);
            bool isChildAgent = false;

            SweeperSimClient newuser = new SweeperSimClient(); //epSender, useCircuit, m_localWorld, _packetServer.ClientThreads, m_assetCache, m_gridServers.GridServer, this, m_inventoryCache, m_sandbox, isChildAgent, this.m_regionData, m_authenticateSessionsClass);

            this._sweeperPacketServer.SweeperClientThreads.Add(useCircuit.CircuitCode.Code, newuser);
        }
Beispiel #11
0
        /// <summary>
        /// Initiates connection to the simulator
        /// </summary>
        public void UseCircuitCode()
        {
            // Send the UseCircuitCode packet to initiate the connection
            UseCircuitCodePacket use = new UseCircuitCodePacket();

            use.CircuitCode.Code      = Network.CircuitCode;
            use.CircuitCode.ID        = Client.Self.AgentID;
            use.CircuitCode.SessionID = Client.Self.SessionID;

            // Send the initial packet out
            SendPacket(use);
        }
Beispiel #12
0
        private void HandleUseCircuitCode(object o)
        {
            object[]             array  = (object[])o;
            UDPPacketBuffer      buffer = (UDPPacketBuffer)array[0];
            UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1];

            IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;

            // Begin the process of adding the client to the simulator
            AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);

            // Acknowledge the UseCircuitCode packet
            SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
        }
Beispiel #13
0
        /// <summary>
        /// Check whether a given client is authorized to connect.
        /// </summary>
        /// <param name="useCircuit"></param>
        /// <param name="circuitManager"></param>
        /// <param name="sessionInfo"></param>
        /// <returns></returns>
        public virtual bool IsClientAuthorized(
            UseCircuitCodePacket useCircuit, AgentCircuitManager circuitManager, out AuthenticateResponse sessionInfo)
        {
            UUID agentId     = useCircuit.CircuitCode.ID;
            UUID sessionId   = useCircuit.CircuitCode.SessionID;
            uint circuitCode = useCircuit.CircuitCode.Code;

            sessionInfo = circuitManager.AuthenticateSession(sessionId, agentId, circuitCode);

            if (!sessionInfo.Authorised)
            {
                return(false);
            }

            return(true);
        }
        protected virtual void AddNewClient(Packet packet)
        {
            UseCircuitCodePacket useCircuit = (UseCircuitCodePacket)packet;

            this.clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);
            bool isChildAgent = false;

            SimClient newuser = new SimClient(epSender, useCircuit, LocalWorld, _packetServer.ClientThreads, AssetCache, GridServers.GridServer, this, InventoryCache, m_sandbox, isChildAgent, this.regionData);

            if ((this.GridServers.UserServer != null) && (user_accounts))
            {
                newuser.UserServer = this.GridServers.UserServer;
            }
            //OpenSimRoot.Instance.ClientThreads.Add(epSender, newuser);
            this._packetServer.ClientThreads.Add(useCircuit.CircuitCode.Code, newuser);
        }
        public void TestAddClient()
        {
            TestHelper.InMethod();

            uint myCircuitCode = 123456;
            UUID myAgentUuid   = UUID.Parse("00000000-0000-0000-0000-000000000001");
            UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");

            TestLLUDPServer     testLLUDPServer;
            TestLLPacketServer  testLLPacketServer;
            AgentCircuitManager acm;

            SetupStack(new MockScene(), out testLLUDPServer, out testLLPacketServer, out acm);

            AgentCircuitData acd = new AgentCircuitData();

            acd.AgentID   = myAgentUuid;
            acd.SessionID = mySessionUuid;

            UseCircuitCodePacket uccp = new UseCircuitCodePacket();

            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code      = myCircuitCode;
            uccpCcBlock.ID        = myAgentUuid;
            uccpCcBlock.SessionID = mySessionUuid;
            uccp.CircuitCode      = uccpCcBlock;

            EndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);

            testLLUDPServer.LoadReceive(uccp, testEp);
            testLLUDPServer.ReceiveData(null);

            // Circuit shouildn't exist since the circuit manager doesn't know about this circuit for authentication yet
            Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode));

            acm.AddNewCircuit(myCircuitCode, acd);

            testLLUDPServer.LoadReceive(uccp, testEp);
            testLLUDPServer.ReceiveData(null);

            // Should succeed now
            Assert.IsTrue(testLLUDPServer.HasCircuit(myCircuitCode));
            Assert.IsFalse(testLLUDPServer.HasCircuit(101));
        }
Beispiel #16
0
        private void HandleUseCircuitCode(object o)
        {
            DateTime startTime = DateTime.Now;

            object[]             array  = (object[])o;
            UDPPacketBuffer      buffer = (UDPPacketBuffer)array[0];
            UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1];

            IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;

            // Begin the process of adding the client to the simulator
            if (AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint))
            {
                // Acknowledge the UseCircuitCode packet
                SendAckImmediate(remoteEndPoint, packet.Header.Sequence);

                m_log.InfoFormat(
                    "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
                    remoteEndPoint, (DateTime.Now - startTime).Milliseconds);
            }
        }
Beispiel #17
0
        private bool AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
        {
            UUID agentID     = useCircuitCode.CircuitCode.ID;
            UUID sessionID   = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            AgentCircuitData sessionInfo;

            if (IsClientAuthorized(useCircuitCode, remoteEndPoint, out sessionInfo))
            {
                return(AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo));
            }
            else
            {
                // Don't create circuits for unauthorized clients
                m_log.WarnFormat(
                    "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
                    useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
            }
            return(false);
        }
        /// <summary>
        /// Set up a client for tests which aren't concerned with this process itself
        /// </summary>
        /// <param name="circuitCode"></param>
        /// <param name="epSender"></param>
        /// <param name="agentId"></param>
        /// <param name="sessionId"></param>
        /// <param name="testLLUDPServer"></param>
        /// <param name="acm"></param>
        protected void AddClient(
            uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
            TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
        {
            AgentCircuitData acd = new AgentCircuitData();

            acd.AgentID   = agentId;
            acd.SessionID = sessionId;

            UseCircuitCodePacket uccp = new UseCircuitCodePacket();

            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code      = circuitCode;
            uccpCcBlock.ID        = agentId;
            uccpCcBlock.SessionID = sessionId;
            uccp.CircuitCode      = uccpCcBlock;

            acm.AddNewCircuit(circuitCode, acd);

            testLLUDPServer.LoadReceive(uccp, epSender);
            testLLUDPServer.ReceiveData(null);
        }
Beispiel #19
0
        public SimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, World world, Dictionary <uint, SimClient> clientThreads, AssetCache assetCache, IGridServer gridServer, OpenSimNetworkHandler application, InventoryCache inventoryCache, bool sandboxMode, bool child, RegionInfo regionDat)
        {
            m_world          = world;
            m_clientThreads  = clientThreads;
            m_assetCache     = assetCache;
            m_gridServer     = gridServer;
            m_application    = application;
            m_inventoryCache = inventoryCache;
            m_sandboxMode    = sandboxMode;
            m_child          = child;
            m_regionData     = regionDat;

            OpenSim.Framework.Console.MainConsole.Instance.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request");
            cirpack = initialcirpack;
            userEP  = remoteEP;
            if (m_gridServer.GetName() == "Remote")
            {
                this.startpos = ((RemoteGridBase)m_gridServer).agentcircuits[initialcirpack.CircuitCode.Code].startpos;
            }
            else
            {
                this.startpos = new LLVector3(128, 128, m_world.Terrain[(int)128, (int)128] + 15.0f); // new LLVector3(128.0f, 128.0f, 60f);
            }
            PacketQueue = new BlockingQueue <QueItem>();

            this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache);
            AckTimer          = new System.Timers.Timer(500);
            AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
            AckTimer.Start();

            this.RegisterLocalPacketHandlers();

            ClientThread = new Thread(new ThreadStart(AuthUser));
            ClientThread.IsBackground = true;
            ClientThread.Start();
        }
        public void RestoreClient(AgentCircuitData circuit, EndPoint userEP, EndPoint proxyEP)
        {
            //MainLog.Instance.Verbose("UDPSERVER", "RestoreClient");

            UseCircuitCodePacket useCircuit = new UseCircuitCodePacket();
            useCircuit.CircuitCode.Code = circuit.circuitcode;
            useCircuit.CircuitCode.ID = circuit.AgentID;
            useCircuit.CircuitCode.SessionID = circuit.SessionID;
            
            AuthenticateResponse sessionInfo;
            
            if (!m_packetServer.IsClientAuthorized(useCircuit, m_circuitManager, out sessionInfo))
            {
                m_log.WarnFormat(
                    "[CLIENT]: Restore request denied to avatar {0} connecting with unauthorized circuit code {1}",
                    useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code);
                
                return;
            }               

            lock (clientCircuits)
            {
                if (!clientCircuits.ContainsKey(userEP))
                    clientCircuits.Add(userEP, useCircuit.CircuitCode.Code);
                else
                    m_log.Error("[CLIENT]: clientCircuits already contains entry for user " + useCircuit.CircuitCode.Code + ". NOT adding.");
            }

            // This data structure is synchronized, so we don't need the lock
            if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code))
                clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, userEP);
            else
                m_log.Error("[CLIENT]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code + ". NOT adding.");

            lock (proxyCircuits)
            {
                if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
                {
                    proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
                }
                else
                {
                    // re-set proxy endpoint
                    proxyCircuits.Remove(useCircuit.CircuitCode.Code);
                    proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
                }
            }

            m_packetServer.AddNewClient(userEP, useCircuit, sessionInfo, proxyEP);
        }
Beispiel #21
0
        /// <summary>
        /// Attempt to connect to this simulator
        /// </summary>
        /// <param name="moveToSim">Whether to move our agent in to this sim or not</param>
        /// <returns>True if the connection succeeded or connection status is
        /// unknown, false if there was a failure</returns>
        public bool Connect(bool moveToSim)
        {
            if (connected)
            {
                Client.Self.CompleteAgentMovement(this);
                return true;
            }

            // Start the timers
            AckTimer.Start();
            StatsTimer.Start();
            PingTimer.Enabled = Client.Settings.SEND_PINGS;

            Client.Log("Connecting to " + this.ToString(), Helpers.LogLevel.Info);

            try
            {
                // Create the UDP connection
                Start();

                // Mark ourselves as connected before firing everything else up
                connected = true;

                // Send the UseCircuitCode packet to initiate the connection
                UseCircuitCodePacket use = new UseCircuitCodePacket();
                use.CircuitCode.Code = Network.CircuitCode;
                use.CircuitCode.ID = Client.Self.AgentID;
                use.CircuitCode.SessionID = Client.Self.SessionID;

                // Send the initial packet out
                SendPacket(use, true);

                Stats.ConnectTime = Environment.TickCount;

                // Move our agent in to the sim to complete the connection
                if (moveToSim) Client.Self.CompleteAgentMovement(this);

                if (Client.Settings.SEND_AGENT_UPDATES)
                    Client.Self.Movement.SendUpdate(true, this);

                if (!ConnectedEvent.WaitOne(Client.Settings.SIMULATOR_TIMEOUT, false))
                {
                    Client.Log("Giving up on waiting for RegionHandshake for " + this.ToString(),
                        Helpers.LogLevel.Warning);
                }

                return true;
            }
            catch (Exception e)
            {
                Client.Log(e.ToString(), Helpers.LogLevel.Error);
            }

            return false;
        }
Beispiel #22
0
        /// <summary>
        /// Attempt to connect to this simulator
        /// </summary>
        /// <param name="moveToSim">Whether to move our agent in to this sim or not</param>
        /// <returns>True if the connection succeeded or connection status is
        /// unknown, false if there was a failure</returns>
        public bool Connect(bool moveToSim)
        {
            if (connected)
            {
                Client.Self.CompleteAgentMovement(this);
                return(true);
            }

            #region Start Timers

            // Destroy the timers
            if (AckTimer != null)
            {
                AckTimer.Dispose();
            }
            if (StatsTimer != null)
            {
                StatsTimer.Dispose();
            }
            if (PingTimer != null)
            {
                PingTimer.Dispose();
            }

            // Timer for sending out queued packet acknowledgements
            AckTimer = new Timer(new TimerCallback(AckTimer_Elapsed), null, Settings.NETWORK_TICK_INTERVAL,
                                 Settings.NETWORK_TICK_INTERVAL);
            // Timer for recording simulator connection statistics
            StatsTimer = new Timer(new TimerCallback(StatsTimer_Elapsed), null, 1000, 1000);
            // Timer for periodically pinging the simulator
            if (Client.Settings.SEND_PINGS)
            {
                PingTimer = new Timer(new TimerCallback(PingTimer_Elapsed), null, Settings.PING_INTERVAL,
                                      Settings.PING_INTERVAL);
            }

            #endregion Start Timers

            Logger.Log("Connecting to " + this.ToString(), Helpers.LogLevel.Info, Client);

            try
            {
                // Create the UDP connection
                Start();

                // Mark ourselves as connected before firing everything else up
                connected = true;

                // Send the UseCircuitCode packet to initiate the connection
                UseCircuitCodePacket use = new UseCircuitCodePacket();
                use.CircuitCode.Code      = Network.CircuitCode;
                use.CircuitCode.ID        = Client.Self.AgentID;
                use.CircuitCode.SessionID = Client.Self.SessionID;

                // Send the initial packet out
                SendPacket(use, true);

                Stats.ConnectTime = Environment.TickCount;

                // Move our agent in to the sim to complete the connection
                if (moveToSim)
                {
                    Client.Self.CompleteAgentMovement(this);
                }

                if (Client.Settings.SEND_AGENT_UPDATES)
                {
                    Client.Self.Movement.SendUpdate(true, this);
                }

                if (!ConnectedEvent.WaitOne(Client.Settings.SIMULATOR_TIMEOUT, false))
                {
                    Logger.Log("Giving up on waiting for RegionHandshake for " + this.ToString(),
                               Helpers.LogLevel.Warning, Client);
                }

                return(true);
            }
            catch (Exception e)
            {
                Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e);
            }

            return(false);
        }
Beispiel #23
0
        /// <summary>
        /// Initiates connection to the simulator
        /// </summary>
        /// <param name="waitForAck">Should we block until ack for this packet is recieved</param>
        public void UseCircuitCode(bool waitForAck)
        {
            // Send the UseCircuitCode packet to initiate the connection
            UseCircuitCodePacket use = new UseCircuitCodePacket();
            use.CircuitCode.Code = Network.CircuitCode;
            use.CircuitCode.ID = Client.Self.AgentID;
            use.CircuitCode.SessionID = Client.Self.SessionID;

            if (waitForAck)
            {
                GotUseCircuitCodeAck.Reset();
            }

            // Send the initial packet out
            SendPacket(use);

            if (waitForAck)
            {
                if (!GotUseCircuitCodeAck.WaitOne(Client.Settings.LOGIN_TIMEOUT, false))
                {
                    Logger.Log("Failed to get ACK for UseCircuitCode packet", Helpers.LogLevel.Error, Client);
                }
            }
        }
Beispiel #24
0
        public void TestAddClient()
        {            
            TestHelper.InMethod();

            uint myCircuitCode = 123456;
            UUID myAgentUuid   = UUID.Parse("00000000-0000-0000-0000-000000000001");
            UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
            
            TestLLUDPServer testLLUDPServer;
            TestLLPacketServer testLLPacketServer;
            AgentCircuitManager acm;
            SetupStack(new MockScene(), out testLLUDPServer, out testLLPacketServer, out acm);
            
            AgentCircuitData acd = new AgentCircuitData();
            acd.AgentID = myAgentUuid;
            acd.SessionID = mySessionUuid;
            
            UseCircuitCodePacket uccp = new UseCircuitCodePacket();
            
            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock 
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code = myCircuitCode;
            uccpCcBlock.ID = myAgentUuid;
            uccpCcBlock.SessionID = mySessionUuid;
            uccp.CircuitCode = uccpCcBlock;
            
            EndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
            
            testLLUDPServer.LoadReceive(uccp, testEp);            
            testLLUDPServer.ReceiveData(null);
            
            // Circuit shouildn't exist since the circuit manager doesn't know about this circuit for authentication yet
            Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode));
                        
            acm.AddNewCircuit(myCircuitCode, acd);
            
            testLLUDPServer.LoadReceive(uccp, testEp);            
            testLLUDPServer.ReceiveData(null);            
            
            // Should succeed now
            Assert.IsTrue(testLLUDPServer.HasCircuit(myCircuitCode));
            Assert.IsFalse(testLLUDPServer.HasCircuit(101));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="client"></param>
        /// <param name="callbacks"></param>
        /// <param name="circuit"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public Simulator(SecondLife client, Dictionary<PacketType,List<PacketCallback>> callbacks, uint circuit, 
			IPAddress ip, int port)
        {
            Client = client;
            Network = client.Network;
            Callbacks = callbacks;
            Region = new Region(client);
            circuitCode = circuit;
            Sequence = 0;
            RecvBuffer = new byte[2048];
            Connection = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            connected = false;
            DisconnectCandidate = false;
            AckTimer = new System.Timers.Timer(500);
            AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);

            // Initialize the dictionary for reliable packets waiting on ACKs from the server
            NeedAck = new Dictionary<int, Packet>();

            // Initialize the lists of sequence numbers we've received so far
            Inbox = new Queue<ushort>(INBOX_SIZE);
            PendingAcks = new List<uint>();

            Client.Log("Connecting to " + ip.ToString() + ":" + port, Helpers.LogLevel.Info);

            try
            {
                // Setup the callback
                ReceivedData = new AsyncCallback(OnReceivedData);

                // Create an endpoint that we will be communicating with (need it in two
                // types due to .NET weirdness)
                ipEndPoint = new IPEndPoint(ip, port);
                endPoint = (EndPoint)ipEndPoint;

                // Associate this simulator's socket with the given ip/port and start listening
                Connection.Connect(endPoint);
                Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref endPoint, ReceivedData, null);

                // Send the UseCircuitCode packet to initiate the connection
                UseCircuitCodePacket use = new UseCircuitCodePacket();
                use.CircuitCode.Code = circuitCode;
                use.CircuitCode.ID = Network.AgentID;
                use.CircuitCode.SessionID = Network.SessionID;

                // Start the ACK timer
                AckTimer.Start();

                // Send the initial packet out
                SendPacket(use, true);

                // Track the current time for timeout purposes
                int start = Environment.TickCount;

                while (true)
                {
                    if (connected || Environment.TickCount - start > 8000)
                    {
                        return;
                    }
                    System.Threading.Thread.Sleep(10);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Client.Log(e.ToString(), Helpers.LogLevel.Error);
            }
        }
Beispiel #26
0
        /// <summary>
        /// Attempt to connect to this simulator
        /// </summary>
        /// <param name="moveToSim">Whether to move our agent in to this sim or not</param>
        /// <returns>True if the connection succeeded or connection status is
        /// unknown, false if there was a failure</returns>
        public bool Connect(bool moveToSim)
        {
            if (connected)
            {
                Client.Self.CompleteAgentMovement(this);
                return true;
            }

            // Start the timers
            AckTimer.Start();
            StatsTimer.Start();
            PingTimer.Enabled = Client.Settings.SEND_PINGS;

            Client.Log("Connecting to " + this.ToString(), Helpers.LogLevel.Info);

            try
            {
                ConnectedEvent.Reset();

                // Associate this simulator's socket with the given ip/port and start listening
                Connection.Connect(endPoint);
                Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref endPoint, ReceivedData, null);

                // Mark ourselves as connected before firing everything else up
                connected = true;

                // Send the UseCircuitCode packet to initiate the connection
                UseCircuitCodePacket use = new UseCircuitCodePacket();
                use.CircuitCode.Code = Network.CircuitCode;
                use.CircuitCode.ID = Network.AgentID;
                use.CircuitCode.SessionID = Network.SessionID;

                // Send the initial packet out
                SendPacket(use, true);

                ConnectTime = Environment.TickCount;

                // Move our agent in to the sim to complete the connection
                if (moveToSim) Client.Self.CompleteAgentMovement(this);

                if (Client.Settings.SEND_AGENT_UPDATES)
                    Client.Self.Status.SendUpdate(true, this);

                if (!ConnectedEvent.WaitOne(Client.Settings.SIMULATOR_TIMEOUT, false))
                {
                    Client.Log("Giving up on waiting for RegionHandshake for " + this.ToString(), 
                        Helpers.LogLevel.Warning);
                }

                return true;
            }
            catch (Exception e)
            {
                Client.Log(e.ToString(), Helpers.LogLevel.Error);
            }

            return false;
        }
Beispiel #27
0
        protected override void PacketReceived(UDPPacketBuffer buffer)
        {
            UDPClient  client    = null;
            Packet     packet    = null;
            int        packetEnd = buffer.DataLength - 1;
            IPEndPoint address   = (IPEndPoint)buffer.RemoteEndPoint;

            // Decoding
            try
            {
                packet = Packet.BuildPacket(buffer.Data, ref packetEnd, buffer.ZeroData);
            }
            catch (MalformedDataException)
            {
                Logger.Log(String.Format("Malformed data, cannot parse packet:\n{0}",
                                         Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)), Helpers.LogLevel.Error);
            }

            // Fail-safe check
            if (packet == null)
            {
                Logger.Log("Couldn't build a message from the incoming data", Helpers.LogLevel.Warning);
                return;
            }

            //Stats.RecvBytes += (ulong)buffer.DataLength;
            //++Stats.RecvPackets;

            if (packet.Type == PacketType.UseCircuitCode)
            {
                UseCircuitCodePacket useCircuitCode = (UseCircuitCodePacket)packet;

                Agent agent;
                if (CompleteAgentConnection(useCircuitCode.CircuitCode.Code, out agent))
                {
                    AddClient(agent, address);
                    if (clients.TryGetValue(agent.AgentID, out client))
                    {
                        Logger.Log("Activated UDP circuit " + useCircuitCode.CircuitCode.Code, Helpers.LogLevel.Info);
                    }
                    else
                    {
                        Logger.Log("Failed to locate newly created UDPClient", Helpers.LogLevel.Error);
                        return;
                    }
                }
                else
                {
                    Logger.Log("Received a UseCircuitCode packet for an unrecognized circuit: " +
                               useCircuitCode.CircuitCode.Code.ToString(), Helpers.LogLevel.Warning);
                    return;
                }
            }
            else
            {
                // Determine which agent this packet came from
                if (!clients.TryGetValue(address, out client))
                {
                    Logger.Log("Received UDP packet from an unrecognized source: " + address.ToString(),
                               Helpers.LogLevel.Warning);
                    return;
                }
            }

            client.Agent.TickLastPacketReceived = Environment.TickCount;

            // Reliable handling
            if (packet.Header.Reliable)
            {
                // Queue up this sequence number for acknowledgement
                QueueAck(client, (uint)packet.Header.Sequence);
                //if (packet.Header.Resent) ++Stats.ReceivedResends;
            }

            // Inbox insertion
            IncomingPacket incomingPacket;

            incomingPacket.Client = client;
            incomingPacket.Packet = packet;

            // TODO: Prioritize the queue
            packetInbox.Enqueue(incomingPacket);
        }
Beispiel #28
0
        /// <summary>
        /// Used by tests that aren't testing this stage.
        /// </summary>
        private ScenePresence AddClient()
        {
            UUID myAgentUuid   = TestHelpers.ParseTail(0x1);
            UUID mySessionUuid = TestHelpers.ParseTail(0x2);
            uint myCircuitCode = 123456;
            IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);

            UseCircuitCodePacket uccp = new UseCircuitCodePacket();

            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code = myCircuitCode;
            uccpCcBlock.ID = myAgentUuid;
            uccpCcBlock.SessionID = mySessionUuid;
            uccp.CircuitCode = uccpCcBlock;

            byte[] uccpBytes = uccp.ToBytes();
            UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
            upb.DataLength = uccpBytes.Length;  // God knows why this isn't set by the constructor.
            Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);

            AgentCircuitData acd = new AgentCircuitData();
            acd.AgentID = myAgentUuid;
            acd.SessionID = mySessionUuid;

            m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);

            m_udpServer.PacketReceived(upb);

            return m_scene.GetScenePresence(myAgentUuid);
        }
Beispiel #29
0
        private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint, out AgentCircuitData sessionInfo)
        {
            UUID agentID = useCircuitCode.CircuitCode.ID;
            UUID sessionID = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            sessionInfo = m_circuitManager.AuthenticateSession(sessionID, agentID, circuitCode, remoteEndPoint);
            return sessionInfo != null;
        }
Beispiel #30
0
        private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
        {
            UUID agentID = useCircuitCode.CircuitCode.ID;
            UUID sessionID = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            AuthenticateResponse sessionInfo;
            if (IsClientAuthorized(useCircuitCode, remoteEndPoint, out sessionInfo))
            {
                AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
            }
            else
            {
                // Don't create circuits for unauthorized clients
                m_log.WarnFormat(
                    "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
                    useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
            }
        }
        /// <summary>
        /// Constructor for Simulator
        /// </summary>
        /// <param name="client"></param>
        /// <param name="callbacks"></param>
        /// <param name="circuit"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public Simulator(SecondLife client, Dictionary<PacketType, List<NetworkManager.PacketCallback>> callbacks,
            uint circuit, IPAddress ip, int port)
        {
            Client = client;
            Network = client.Network;
            Callbacks = callbacks;
            Region = new Region(client);
            circuitCode = circuit;
            Inbox = new Queue<uint>(Client.Settings.INBOX_SIZE);
            AckTimer = new System.Timers.Timer(Client.Settings.NETWORK_TICK_LENGTH);
            AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);

            // Initialize the callback for receiving a new packet
            ReceivedData = new AsyncCallback(OnReceivedData);

            Client.Log("Connecting to " + ip.ToString() + ":" + port, Helpers.LogLevel.Info);

            try
            {
                // Create an endpoint that we will be communicating with (need it in two
                // types due to .NET weirdness)
                ipEndPoint = new IPEndPoint(ip, port);
                endPoint = (EndPoint)ipEndPoint;

                // Associate this simulator's socket with the given ip/port and start listening
                Connection.Connect(endPoint);
                Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref endPoint, ReceivedData, null);

                // Send the UseCircuitCode packet to initiate the connection
                UseCircuitCodePacket use = new UseCircuitCodePacket();
                use.CircuitCode.Code = circuitCode;
                use.CircuitCode.ID = Network.AgentID;
                use.CircuitCode.SessionID = Network.SessionID;

                // Start the ACK timer
                AckTimer.Start();

                // Send the initial packet out
                SendPacket(use, true);

                // Track the current time for timeout purposes
                int start = Environment.TickCount;

                while (true)
                {
                    if (connected || Environment.TickCount - start > Client.Settings.SIMULATOR_TIMEOUT)
                    {
                        return;
                    }
                    System.Threading.Thread.Sleep(10);
                }
            }
            catch (Exception e)
            {
                Client.Log(e.ToString(), Helpers.LogLevel.Error);
            }
        }
Beispiel #32
0
        private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
        {
            UUID agentID = useCircuitCode.CircuitCode.ID;
            UUID sessionID = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            sessionInfo = m_circuitManager.AuthenticateSession(sessionID, agentID, circuitCode);
            return sessionInfo.Authorised;
        }
        /// <summary>
        /// Check whether a given client is authorized to connect.
        /// </summary>
        /// <param name="useCircuit"></param>
        /// <param name="circuitManager"></param>
        /// <param name="sessionInfo"></param>
        /// <returns></returns>
        public virtual bool IsClientAuthorized(
            UseCircuitCodePacket useCircuit, AgentCircuitManager circuitManager, out AuthenticateResponse sessionInfo)
        {
            UUID agentId = useCircuit.CircuitCode.ID;
            UUID sessionId = useCircuit.CircuitCode.SessionID;
            uint circuitCode = useCircuit.CircuitCode.Code;

            sessionInfo = circuitManager.AuthenticateSession(sessionId, agentId, circuitCode); 

            if (!sessionInfo.Authorised)
                return false;  
            
            return true;
        }
        /// <summary>
        /// Add a new client circuit.
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="epSender"></param>
        /// <param name="epProxy"></param>
        protected virtual void AddNewClient(UseCircuitCodePacket useCircuit, EndPoint epSender, EndPoint epProxy)
        {            
            //Slave regions don't accept new clients
            if (m_localScene.RegionStatus != RegionStatus.SlaveScene)
            {                
                AuthenticateResponse sessionInfo;
                bool isNewCircuit = false;
                
                if (!m_packetServer.IsClientAuthorized(useCircuit, m_circuitManager, out sessionInfo))
                {
                    m_log.WarnFormat(
                        "[CONNECTION FAILURE]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
                        useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code, epSender);
                    
                    return;
                }
                
                lock (clientCircuits)
                {
                    if (!clientCircuits.ContainsKey(epSender))
                    {                        
                        clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);                        
                        isNewCircuit = true;
                    }
                }

                if (isNewCircuit)
                {
                    // This doesn't need locking as it's synchronized data
                    clientCircuits_reverse[useCircuit.CircuitCode.Code] = epSender;

                    lock (proxyCircuits)
                    {
                        proxyCircuits[useCircuit.CircuitCode.Code] = epProxy;
                    }
                    
                    m_packetServer.AddNewClient(epSender, useCircuit, sessionInfo, epProxy);
                                    
                    //m_log.DebugFormat(
                    //    "[CONNECTION SUCCESS]: Incoming client {0} (circuit code {1}) received and authenticated for {2}", 
                    //    useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code, m_localScene.RegionInfo.RegionName);                    
                }                
            }            
            
            // Ack the UseCircuitCode packet
            PacketAckPacket ack_it = (PacketAckPacket)PacketPool.Instance.GetPacket(PacketType.PacketAck);
            // TODO: don't create new blocks if recycling an old packet
            ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
            ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
            ack_it.Packets[0].ID = useCircuit.Header.Sequence;
            // ((useCircuit.Header.Sequence < uint.MaxValue) ? useCircuit.Header.Sequence : 0) is just a failsafe to ensure that we don't overflow.
            ack_it.Header.Sequence = ((useCircuit.Header.Sequence < uint.MaxValue) ? useCircuit.Header.Sequence : 0) + 1;
            ack_it.Header.Reliable = false;

            byte[] ackmsg = ack_it.ToBytes();

            // Need some extra space in case we need to add proxy
            // information to the message later
            byte[] msg = new byte[4096];
            Buffer.BlockCopy(ackmsg, 0, msg, 0, ackmsg.Length);

            SendPacketTo(msg, ackmsg.Length, SocketFlags.None, useCircuit.CircuitCode.Code);

            PacketPool.Instance.ReturnPacket(useCircuit);
        }
Beispiel #35
0
        private bool AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
        {
            UUID agentID = useCircuitCode.CircuitCode.ID;
            UUID sessionID = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            try
            {
                m_log.InfoFormat(
                        "[LLUDPSERVER]: UCC Received for client {0} circuit code {1}",
                        useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code);

                LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
                LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, agentID, sessionID, circuitCode);

                m_scene.ConnectionManager.TryAttachUdpCircuit(client);
                client.Start();

                return true;
            }
            catch (OpenSim.Region.Framework.Connection.AttachUdpCircuitException e)
            {
                if (e.CircuitAlreadyExisted)
                {
                    m_log.WarnFormat("[LLUDPSERVER]: Ignoring duplicate UDP connection request. {0}", e.Message);

                    //if the circuit matches, we can ACK the UCC since the client should be
                    //able to communicate with the current circuit
                    if (e.ExistingCircuitMatched)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    m_log.ErrorFormat("[LLUDPSERVER]: Unable to start new connection: {0}", e);
                    return false;
                }
            }
        }
Beispiel #36
0
        public SimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, World world, Dictionary<uint, SimClient> clientThreads, AssetCache assetCache, IGridServer gridServer, OpenSimNetworkHandler application, InventoryCache inventoryCache, bool sandboxMode, bool child, RegionInfo regionDat)
        {
            m_world = world;
            m_clientThreads = clientThreads;
            m_assetCache = assetCache;
            m_gridServer = gridServer;
            m_application = application;
            m_inventoryCache = inventoryCache;
            m_sandboxMode = sandboxMode;
            m_child = child;
            m_regionData = regionDat;

            OpenSim.Framework.Console.MainConsole.Instance.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request");
            cirpack = initialcirpack;
            userEP = remoteEP;
            if (m_gridServer.GetName() == "Remote")
            {
                this.startpos = ((RemoteGridBase)m_gridServer).agentcircuits[initialcirpack.CircuitCode.Code].startpos;
            }
            else
            {
                this.startpos = new LLVector3(128, 128, m_world.Terrain[(int)128, (int)128] + 15.0f); // new LLVector3(128.0f, 128.0f, 60f);
            }
            PacketQueue = new BlockingQueue<QueItem>();

            this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache);
            AckTimer = new System.Timers.Timer(500);
            AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
            AckTimer.Start();

            this.RegisterLocalPacketHandlers();

            ClientThread = new Thread(new ThreadStart(AuthUser));
            ClientThread.IsBackground = true;
            ClientThread.Start();
        }
Beispiel #37
0
        private void HandleUseCircuitCode(UDPPacketBuffer buffer, UseCircuitCodePacket packet, int now)
        {
            IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;

            LLAgent agent;
            if (m_clients.TryGetValue(packet.CircuitCode.ID, out agent))
            {
                // Update the remoteEndPoint for this agent
                m_clients.UpdateKey2(agent.ID, agent.RemoteEndPoint, remoteEndPoint);
                agent.RemoteEndPoint = remoteEndPoint;

                // Acknowledge the UseCircuitCode packet
                SendAckImmediate(remoteEndPoint, packet.Header.Sequence);

                // Fire any callbacks registered for this packet
                IncomingPacket incomingPacket = new IncomingPacket(agent, packet, now);
                incomingPacket.StartedHandling = now;
                PacketEvents.BeginRaiseEvent(incomingPacket);
            }
            else
            {
                m_log.Error("Failed to add new client " + packet.CircuitCode.ID + " connecting from " + remoteEndPoint);
            }
        }
Beispiel #38
0
        /// <summary>
        /// Set up a client for tests which aren't concerned with this process itself
        /// </summary>
        /// <param name="circuitCode"></param>
        /// <param name="epSender"></param>
        /// <param name="agentId"></param>
        /// <param name="sessionId"></param>
        /// <param name="testLLUDPServer"></param>
        /// <param name="acm"></param>
        protected void AddClient(
            uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId, 
            TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
        {
            AgentCircuitData acd = new AgentCircuitData();
            acd.AgentID = agentId;
            acd.SessionID = sessionId; 
            
            UseCircuitCodePacket uccp = new UseCircuitCodePacket();
            
            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock 
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code = circuitCode;
            uccpCcBlock.ID = agentId;
            uccpCcBlock.SessionID = sessionId;
            uccp.CircuitCode = uccpCcBlock;

            acm.AddNewCircuit(circuitCode, acd);
            
            testLLUDPServer.LoadReceive(uccp, epSender);            
            testLLUDPServer.ReceiveData(null);
        }
Beispiel #39
0
        /// <summary>
        /// Initiates connection to the simulator
        /// </summary>
        public void UseCircuitCode()
        {
            // Send the UseCircuitCode packet to initiate the connection
            UseCircuitCodePacket use = new UseCircuitCodePacket();
            use.CircuitCode.Code = Network.CircuitCode;
            use.CircuitCode.ID = Client.Self.AgentID;
            use.CircuitCode.SessionID = Client.Self.SessionID;

            // Send the initial packet out
            SendPacket(use);
        }
Beispiel #40
0
        private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
        {
            UUID agentID = useCircuitCode.CircuitCode.ID;
            UUID sessionID = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            if (m_scene.RegionStatus != RegionStatus.SlaveScene)
            {
                AuthenticateResponse sessionInfo;
                if (IsClientAuthorized(useCircuitCode, out sessionInfo))
                {
                    AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
                }
                else
                {
                    // Don't create circuits for unauthorized clients
                    m_log.WarnFormat(
                        "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
                        useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
                }
            }
            else
            {
                // Slave regions don't accept new clients
                m_log.Debug("[LLUDPSERVER]: Slave region " + m_scene.RegionInfo.RegionName + " ignoring UseCircuitCode packet");
            }
        }
Beispiel #41
0
        public void TestAddClient()
        {
            TestHelpers.InMethod();
//            TestHelpers.EnableLogging();

            AddUdpServer();

            UUID myAgentUuid   = TestHelpers.ParseTail(0x1);
            UUID mySessionUuid = TestHelpers.ParseTail(0x2);
            uint myCircuitCode = 123456;
            IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);

            UseCircuitCodePacket uccp = new UseCircuitCodePacket();

            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code = myCircuitCode;
            uccpCcBlock.ID = myAgentUuid;
            uccpCcBlock.SessionID = mySessionUuid;
            uccp.CircuitCode = uccpCcBlock;

            byte[] uccpBytes = uccp.ToBytes();
            UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
            upb.DataLength = uccpBytes.Length;  // God knows why this isn't set by the constructor.
            Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);

            m_udpServer.PacketReceived(upb);

            // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
            Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);

            AgentCircuitData acd = new AgentCircuitData();
            acd.AgentID = myAgentUuid;
            acd.SessionID = mySessionUuid;

            m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);

            m_udpServer.PacketReceived(upb);

            // Should succeed now
            ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);
            Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));

            Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1));

            Packet packet = m_udpServer.PacketsSent[0];
            Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));

            PacketAckPacket ackPacket = packet as PacketAckPacket;
            Assert.That(ackPacket.Packets.Length, Is.EqualTo(1));
            Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
        }
Beispiel #42
0
        /// <summary>
        /// Add a new client circuit.
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="epSender"></param>
        /// <param name="epProxy"></param>
        protected virtual void AddNewClient(UseCircuitCodePacket useCircuit, EndPoint epSender, EndPoint epProxy)
        {
            //Slave regions don't accept new clients
            if (m_localScene.RegionStatus != RegionStatus.SlaveScene)
            {
                AuthenticateResponse sessionInfo;
                bool isNewCircuit = false;

                if (!m_packetServer.IsClientAuthorized(useCircuit, m_circuitManager, out sessionInfo))
                {
                    m_log.WarnFormat(
                        "[CONNECTION FAILURE]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
                        useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code, epSender);

                    return;
                }

                lock (clientCircuits)
                {
                    if (!clientCircuits.ContainsKey(epSender))
                    {
                        clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);
                        isNewCircuit = true;
                    }
                }

                if (isNewCircuit)
                {
                    // This doesn't need locking as it's synchronized data
                    clientCircuits_reverse[useCircuit.CircuitCode.Code] = epSender;

                    lock (proxyCircuits)
                    {
                        proxyCircuits[useCircuit.CircuitCode.Code] = epProxy;
                    }

                    m_packetServer.AddNewClient(epSender, useCircuit, m_assetCache, sessionInfo, epProxy);

                    //m_log.DebugFormat(
                    //    "[CONNECTION SUCCESS]: Incoming client {0} (circuit code {1}) received and authenticated for {2}",
                    //    useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code, m_localScene.RegionInfo.RegionName);
                }
            }

            // Ack the UseCircuitCode packet
            PacketAckPacket ack_it = (PacketAckPacket)PacketPool.Instance.GetPacket(PacketType.PacketAck);

            // TODO: don't create new blocks if recycling an old packet
            ack_it.Packets       = new PacketAckPacket.PacketsBlock[1];
            ack_it.Packets[0]    = new PacketAckPacket.PacketsBlock();
            ack_it.Packets[0].ID = useCircuit.Header.Sequence;
            // ((useCircuit.Header.Sequence < uint.MaxValue) ? useCircuit.Header.Sequence : 0) is just a failsafe to ensure that we don't overflow.
            ack_it.Header.Sequence = ((useCircuit.Header.Sequence < uint.MaxValue) ? useCircuit.Header.Sequence : 0) + 1;
            ack_it.Header.Reliable = false;

            byte[] ackmsg = ack_it.ToBytes();

            // Need some extra space in case we need to add proxy
            // information to the message later
            byte[] msg = new byte[4096];
            Buffer.BlockCopy(ackmsg, 0, msg, 0, ackmsg.Length);

            SendPacketTo(msg, ackmsg.Length, SocketFlags.None, useCircuit.CircuitCode.Code);

            PacketPool.Instance.ReturnPacket(useCircuit);
        }
Beispiel #43
0
        private bool AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
        {
            UUID agentID = useCircuitCode.CircuitCode.ID;
            UUID sessionID = useCircuitCode.CircuitCode.SessionID;
            uint circuitCode = useCircuitCode.CircuitCode.Code;

            AgentCircuitData sessionInfo;
            if (IsClientAuthorized(useCircuitCode, remoteEndPoint, out sessionInfo))
            {
                if (m_inQueueCircuitCodes.ContainsKey (agentID))
                {
                    m_inQueueCircuitCodes[agentID] = useCircuitCode.Header.Sequence;
                    return false;
                }

                m_inQueueCircuitCodes[agentID] = useCircuitCode.Header.Sequence;
                return AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
            }
            else
            {
                // Don't create circuits for unauthorized clients
                m_log.WarnFormat(
                    "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
                    useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
            }
            return false;
        }
        /// <summary>
        /// Add a new client circuit.  We assume that is has already passed an authorization check
        /// </summary>
        /// <param name="epSender"></param>
        /// <param name="useCircuit"></param>
        /// <param name="assetCache"></param>
        /// <param name="sessionInfo"></param>
        /// <param name="proxyEP"></param>
        /// <returns>
        /// true if a new circuit was created, false if a circuit with the given circuit code already existed
        /// </returns>        
        public virtual bool AddNewClient(
            EndPoint epSender, UseCircuitCodePacket useCircuit, 
            AuthenticateResponse sessionInfo, EndPoint proxyEP)
        {
            IClientAPI newuser;
            uint circuitCode = useCircuit.CircuitCode.Code;
            
            if (m_scene.ClientManager.TryGetClient(circuitCode, out newuser))
            {
                // The circuit is already known to the scene.  This not actually a problem since this will currently
                // occur if a client is crossing borders (hence upgrading its circuit).  However, we shouldn't 
                // really by trying to add a new client if this is the case.
                return false;
            }
            
            UUID agentId = useCircuit.CircuitCode.ID;
            UUID sessionId = useCircuit.CircuitCode.SessionID;
            
            newuser 
                = CreateNewCircuit(
                    epSender, m_scene, this, sessionInfo, agentId, sessionId, circuitCode, proxyEP);

            m_scene.ClientManager.Add(circuitCode, newuser);

            newuser.OnViewerEffect += m_scene.ClientManager.ViewerEffectHandler;
            newuser.OnLogout += LogoutHandler;
            newuser.OnConnectionClosed += CloseClient;
            
            newuser.Start();

            return true;
        }
Beispiel #45
0
        /// <summary>
        /// Attempt to connect to this simulator
        /// </summary>
        /// <param name="moveToSim">Whether to move our agent in to this sim or not</param>
        /// <returns>True if the connection succeeded or connection status is
        /// unknown, false if there was a failure</returns>
        public bool Connect(bool moveToSim)
        {
            if (connected)
            {
                Client.Self.CompleteAgentMovement(this);
                return true;
            }

            #region Start Timers

            // Timer for sending out queued packet acknowledgements
            if (AckTimer == null)
                AckTimer = new Timer(AckTimer_Elapsed, null, Settings.NETWORK_TICK_INTERVAL, Timeout.Infinite);

            // Timer for recording simulator connection statistics
            if (StatsTimer == null)
                StatsTimer = new Timer(StatsTimer_Elapsed, null, 1000, 1000);

            // Timer for periodically pinging the simulator
            if (PingTimer == null && Client.Settings.SEND_PINGS)
                PingTimer = new Timer(PingTimer_Elapsed, null, Settings.PING_INTERVAL, Settings.PING_INTERVAL);

            #endregion Start Timers

            Logger.Log("Connecting to " + this.ToString(), Helpers.LogLevel.Info, Client);

            try
            {
                // Create the UDP connection
                Start();

                // Mark ourselves as connected before firing everything else up
                connected = true;

                // Send the UseCircuitCode packet to initiate the connection
                UseCircuitCodePacket use = new UseCircuitCodePacket();
                use.CircuitCode.Code = Network.CircuitCode;
                use.CircuitCode.ID = Client.Self.AgentID;
                use.CircuitCode.SessionID = Client.Self.SessionID;

                // Send the initial packet out
                SendPacket(use);

                Stats.ConnectTime = Environment.TickCount;

                // Move our agent in to the sim to complete the connection
                if (moveToSim) Client.Self.CompleteAgentMovement(this);

                if (Client.Settings.SEND_AGENT_UPDATES)
                    Client.Self.Movement.SendUpdate(true, this);

                if (!ConnectedEvent.WaitOne(Client.Settings.SIMULATOR_TIMEOUT, false))
                {
                    Logger.Log("Giving up on waiting for RegionHandshake for " + this.ToString(),
                        Helpers.LogLevel.Warning, Client);
                }

                return true;
            }
            catch (Exception e)
            {
                Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e);
            }

            return false;
        }
        /// <summary>
        /// Callback handler for incomming data
        /// </summary>
        /// <param name="result"></param>
        private void OnReceivedData(IAsyncResult result)
        {
            ipeSender = new IPEndPoint(IPAddress.Any, 0);
            epSender  = (EndPoint)ipeSender;
            Packet packet = null;
            int    numBytes;

            // If we're receiving data the sim connection is open
            connected = true;

            // Update the disconnect flag so this sim doesn't time out
            DisconnectCandidate = false;
            NetworkInfo User_info = null;

            lock (RecvBuffer)
            {
                // Retrieve the incoming packet
                try
                {
                    numBytes = Connection.EndReceiveFrom(result, ref epSender);

                    //find user_agent_info

                    int packetEnd = numBytes - 1;
                    packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer);


                    //should check if login/useconnection packet first
                    if (packet.Type == PacketType.UseCircuitCode)
                    {
                        //new connection
                        //TODO check that this circuit and session is expected
                        UseCircuitCodePacket cir_pack = (UseCircuitCodePacket)packet;
                        NetworkInfo          new_user = new NetworkInfo();
                        new_user.CircuitCode        = cir_pack.CircuitCode.Code;
                        new_user.User.AgentID       = cir_pack.CircuitCode.ID;
                        new_user.User.SessionID     = cir_pack.CircuitCode.SessionID;
                        new_user.endpoint           = epSender;
                        new_user.Inbox              = new Queue <uint>(Settings.INBOX_SIZE);
                        new_user.Connection         = new ClientConnection();
                        new_user.Connection.NetInfo = new_user;
                        new_user.Connection.Start();

                        //this.CallbackObject.NewUserCallback(new_user);
                        this.User_agents.Add(new_user);
                    }

                    NetworkInfo temp_agent = null;
                    IPEndPoint  send_ip    = (IPEndPoint)epSender;
                    //	this.callback_object.error("incoming: address is "+send_ip.Address +"port number is: "+send_ip.Port.ToString());

                    for (int ii = 0; ii < this.User_agents.Count; ii++)
                    {
                        temp_agent = (NetworkInfo)this.User_agents[ii];
                        IPEndPoint ag_ip = (IPEndPoint)temp_agent.endpoint;
                        //this.callback_object.error("searching: address is "+ag_ip.Address +"port number is: "+ag_ip.Port.ToString());

                        if ((ag_ip.Address.ToString() == send_ip.Address.ToString()) && (ag_ip.Port.ToString() == send_ip.Port.ToString()))
                        {
                            //this.callback_object.error("found user");
                            User_info = temp_agent;
                            break;
                        }
                    }

                    Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
                }
                catch (SocketException)
                {
                    // Client.Log(endPoint.ToString() + " socket is closed, shutting down " + this.Region.Name,
                    //     Helpers.LogLevel.Info);

                    connected = false;
                    //Network.DisconnectSim(this);
                    return;
                }
            }
            if (User_info == null)
            {
                //error finding agent
                //this.CallbackObject.ErrorCallback("no user found");
                return;
            }

            // Fail-safe check
            if (packet == null)
            {
                //this.CallbackObject.ErrorCallback("couldn't build packet");
                // Client.Log("Couldn't build a message from the incoming data", Helpers.LogLevel.Warning);
                return;
            }
            //this.callback_object.error("past tests");
            // Track the sequence number for this packet if it's marked as reliable
            if (packet.Header.Reliable)
            {
                if (User_info.PendingAcks.Count > Settings.MAX_PENDING_ACKS)
                {
                    SendAcks(User_info);
                }

                // Check if we already received this packet
                if (User_info.Inbox.Contains(packet.Header.Sequence))
                {
                    //Client.Log("Received a duplicate " + packet.Type.ToString() + ", sequence=" +
                    //    packet.Header.Sequence + ", resent=" + ((packet.Header.Resent) ? "Yes" : "No") +
                    //    ", Inbox.Count=" + Inbox.Count + ", NeedAck.Count=" + NeedAck.Count,
                    //    Helpers.LogLevel.Info);

                    // Send an ACK for this packet immediately
                    //SendAck(packet.Header.Sequence);

                    // TESTING: Try just queuing up ACKs for resent packets instead of immediately triggering an ACK
                    lock (User_info.PendingAcks)
                    {
                        uint sequence = (uint)packet.Header.Sequence;
                        if (!User_info.PendingAcks.ContainsKey(sequence))
                        {
                            User_info.PendingAcks[sequence] = sequence;
                        }
                    }

                    // Avoid firing a callback twice for the same packet
                    // this.callback_object.error("avoiding callback");
                    return;
                }
                else
                {
                    lock (User_info.PendingAcks)
                    {
                        uint sequence = (uint)packet.Header.Sequence;
                        if (!User_info.PendingAcks.ContainsKey(sequence))
                        {
                            User_info.PendingAcks[sequence] = sequence;
                        }
                    }
                }
            }

            // Add this packet to our inbox
            lock (User_info.Inbox)
            {
                while (User_info.Inbox.Count >= Settings.INBOX_SIZE)
                {
                    User_info.Inbox.Dequeue();
                }
                User_info.Inbox.Enqueue(packet.Header.Sequence);
            }

            // Handle appended ACKs
            if (packet.Header.AppendedAcks)
            {
                lock (User_info.NeedAck)
                {
                    foreach (uint ack in packet.Header.AckList)
                    {
                        User_info.NeedAck.Remove(ack);
                    }
                }
            }

            // Handle PacketAck packets
            if (packet.Type == PacketType.PacketAck)
            {
                PacketAckPacket ackPacket = (PacketAckPacket)packet;

                lock (User_info.NeedAck)
                {
                    foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
                    {
                        User_info.NeedAck.Remove(block.ID);
                    }
                }
            }

            //if it is a ping check send return
            if ((packet.Type == PacketType.StartPingCheck))
            {
                //reply to pingcheck
                libsecondlife.Packets.StartPingCheckPacket    startPing = (libsecondlife.Packets.StartPingCheckPacket)packet;
                libsecondlife.Packets.CompletePingCheckPacket endPing   = new CompletePingCheckPacket();
                endPing.PingID.PingID = startPing.PingID.PingID;
                SendPacket(endPing, true, User_info);
            }
            else if (packet.Type != PacketType.PacketAck)
            {
                User_info.Connection.InQueue.Enqueue(packet);
            }
        }