* Added a mutex to the LoginService allowing only a single login simultaneously. (queues)

* This is a temporary fix to prevent an issue with adjohn reported when attempting to login large numbers of users in a short period of time.
* A rewritten login service is on the cards.
afrisby
Adam Frisby 2007-11-09 01:59:18 +00:00
parent b01e309414
commit c93f7188c7
1 changed files with 96 additions and 85 deletions

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Threading;
using libsecondlife; using libsecondlife;
using Nwc.XmlRpc; using Nwc.XmlRpc;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
@ -38,6 +39,7 @@ namespace OpenSim.Framework.UserManagement
{ {
protected string m_welcomeMessage = "Welcome to OpenSim"; protected string m_welcomeMessage = "Welcome to OpenSim";
protected UserManagerBase m_userManager = null; protected UserManagerBase m_userManager = null;
protected Mutex m_loginMutex = new Mutex(false);
public LoginService(UserManagerBase userManager, string welcomeMess) public LoginService(UserManagerBase userManager, string welcomeMess)
{ {
@ -55,104 +57,113 @@ namespace OpenSim.Framework.UserManagement
/// <returns>The response to send</returns> /// <returns>The response to send</returns>
public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request)
{ {
MainLog.Instance.Verbose("LOGIN", "Attempting login now..."); // Temporary fix
XmlRpcResponse response = new XmlRpcResponse(); m_loginMutex.WaitOne();
Hashtable requestData = (Hashtable) request.Params[0]; try
bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") &&
requestData.Contains("passwd"));
bool GoodLogin = false;
UserProfileData userProfile;
LoginResponse logResponse = new LoginResponse();
if (GoodXML)
{ {
string firstname = (string) requestData["first"]; MainLog.Instance.Verbose("LOGIN", "Attempting login now...");
string lastname = (string) requestData["last"]; XmlRpcResponse response = new XmlRpcResponse();
string passwd = (string) requestData["passwd"]; Hashtable requestData = (Hashtable)request.Params[0];
userProfile = GetTheUser(firstname, lastname); bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") &&
if (userProfile == null) requestData.Contains("passwd"));
return logResponse.CreateLoginFailedResponse(); bool GoodLogin = false;
GoodLogin = AuthenticateUser(userProfile, passwd); UserProfileData userProfile;
} LoginResponse logResponse = new LoginResponse();
else
{
return logResponse.CreateGridErrorResponse();
}
if (!GoodLogin) if (GoodXML)
{
return logResponse.CreateLoginFailedResponse();
}
else
{
// If we already have a session...
if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline)
{ {
// Reject the login string firstname = (string)requestData["first"];
return logResponse.CreateAlreadyLoggedInResponse(); string lastname = (string)requestData["last"];
string passwd = (string)requestData["passwd"];
userProfile = GetTheUser(firstname, lastname);
if (userProfile == null)
return logResponse.CreateLoginFailedResponse();
GoodLogin = AuthenticateUser(userProfile, passwd);
} }
// Otherwise... else
// Create a new agent session
CreateAgent(userProfile, request);
try
{ {
LLUUID agentID = userProfile.UUID; return logResponse.CreateGridErrorResponse();
}
// Inventory Library Section if (!GoodLogin)
InventoryData inventData = CreateInventoryData(agentID); {
ArrayList AgentInventoryArray = inventData.InventoryArray; return logResponse.CreateLoginFailedResponse();
}
Hashtable InventoryRootHash = new Hashtable(); else
InventoryRootHash["folder_id"] = inventData.RootFolderID.ToStringHyphenated(); {
ArrayList InventoryRoot = new ArrayList(); // If we already have a session...
InventoryRoot.Add(InventoryRootHash); if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline)
userProfile.rootInventoryFolderID = inventData.RootFolderID; {
// Reject the login
// Circuit Code return logResponse.CreateAlreadyLoggedInResponse();
uint circode = (uint) (Util.RandomClass.Next()); }
// Otherwise...
logResponse.Lastname = userProfile.surname; // Create a new agent session
logResponse.Firstname = userProfile.username; CreateAgent(userProfile, request);
logResponse.AgentID = agentID.ToStringHyphenated();
logResponse.SessionID = userProfile.currentAgent.sessionID.ToStringHyphenated();
logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToStringHyphenated();
logResponse.InventoryRoot = InventoryRoot;
logResponse.InventorySkeleton = AgentInventoryArray;
logResponse.InventoryLibrary = GetInventoryLibrary();
logResponse.InventoryLibraryOwner = GetLibraryOwner();
logResponse.CircuitCode = (Int32) circode;
//logResponse.RegionX = 0; //overwritten
//logResponse.RegionY = 0; //overwritten
logResponse.Home = "!!null temporary value {home}!!"; // Overwritten
//logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n";
//logResponse.SimAddress = "127.0.0.1"; //overwritten
//logResponse.SimPort = 0; //overwritten
logResponse.Message = GetMessage();
try try
{ {
CustomiseResponse(logResponse, userProfile); LLUUID agentID = userProfile.UUID;
}
catch (Exception e)
{
MainLog.Instance.Verbose(e.ToString());
return logResponse.CreateDeadRegionResponse();
//return logResponse.ToXmlRpcResponse();
}
CommitAgent(ref userProfile);
return logResponse.ToXmlRpcResponse();
}
catch (Exception E) // Inventory Library Section
{ InventoryData inventData = CreateInventoryData(agentID);
MainLog.Instance.Verbose(E.ToString()); ArrayList AgentInventoryArray = inventData.InventoryArray;
Hashtable InventoryRootHash = new Hashtable();
InventoryRootHash["folder_id"] = inventData.RootFolderID.ToStringHyphenated();
ArrayList InventoryRoot = new ArrayList();
InventoryRoot.Add(InventoryRootHash);
userProfile.rootInventoryFolderID = inventData.RootFolderID;
// Circuit Code
uint circode = (uint)(Util.RandomClass.Next());
logResponse.Lastname = userProfile.surname;
logResponse.Firstname = userProfile.username;
logResponse.AgentID = agentID.ToStringHyphenated();
logResponse.SessionID = userProfile.currentAgent.sessionID.ToStringHyphenated();
logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToStringHyphenated();
logResponse.InventoryRoot = InventoryRoot;
logResponse.InventorySkeleton = AgentInventoryArray;
logResponse.InventoryLibrary = GetInventoryLibrary();
logResponse.InventoryLibraryOwner = GetLibraryOwner();
logResponse.CircuitCode = (Int32)circode;
//logResponse.RegionX = 0; //overwritten
//logResponse.RegionY = 0; //overwritten
logResponse.Home = "!!null temporary value {home}!!"; // Overwritten
//logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n";
//logResponse.SimAddress = "127.0.0.1"; //overwritten
//logResponse.SimPort = 0; //overwritten
logResponse.Message = GetMessage();
try
{
CustomiseResponse(logResponse, userProfile);
}
catch (Exception e)
{
MainLog.Instance.Verbose(e.ToString());
return logResponse.CreateDeadRegionResponse();
//return logResponse.ToXmlRpcResponse();
}
CommitAgent(ref userProfile);
return logResponse.ToXmlRpcResponse();
}
catch (Exception E)
{
MainLog.Instance.Verbose(E.ToString());
}
//}
} }
//} }
finally
{
m_loginMutex.ReleaseMutex();
} }
return response; return response;
} }