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)); }
/// <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)); }
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"); } }
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); }
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); }
/// <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); }
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); }
/// <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)); }
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); } }
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); }
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); }
/// <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; }
/// <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); }
/// <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); } } }
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); } }
/// <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; }
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); }
/// <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); }
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 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); } }
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); }
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; } } }
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(); }
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); } }
/// <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); }
/// <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); }
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"); } }
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)); }
/// <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); }
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; }
/// <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); } }