aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/HypergridService
diff options
context:
space:
mode:
authorDiva Canto2013-07-14 14:31:20 -0700
committerDiva Canto2013-07-14 14:31:20 -0700
commite33ac50388b5b9d6d06c58c45e2ea6f17e9b987f (patch)
tree72a0ab317066805e8e022ecca790aa23ce29bd02 /OpenSim/Services/HypergridService
parentMinor typo in log message (diff)
downloadopensim-SC-e33ac50388b5b9d6d06c58c45e2ea6f17e9b987f.zip
opensim-SC-e33ac50388b5b9d6d06c58c45e2ea6f17e9b987f.tar.gz
opensim-SC-e33ac50388b5b9d6d06c58c45e2ea6f17e9b987f.tar.bz2
opensim-SC-e33ac50388b5b9d6d06c58c45e2ea6f17e9b987f.tar.xz
HG UAS: Moved hg-session data from memory to DB storage. This makes it so that traveling info survives Robust resets. It should also eliminate the cause of empty IP addresses in agent circuit data that we saw in CC grid. MySQL only.
Diffstat (limited to 'OpenSim/Services/HypergridService')
-rw-r--r--OpenSim/Services/HypergridService/UserAgentService.cs205
-rw-r--r--OpenSim/Services/HypergridService/UserAgentServiceBase.cs84
2 files changed, 199 insertions, 90 deletions
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index 733993f..b597cb9 100644
--- a/OpenSim/Services/HypergridService/UserAgentService.cs
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using System.Reflection; 31using System.Reflection;
32 32
33using OpenSim.Data;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Services.Connectors.Friends; 35using OpenSim.Services.Connectors.Friends;
35using OpenSim.Services.Connectors.Hypergrid; 36using OpenSim.Services.Connectors.Hypergrid;
@@ -50,14 +51,14 @@ namespace OpenSim.Services.HypergridService
50 /// needs to do it for them. 51 /// needs to do it for them.
51 /// Once we have better clients, this shouldn't be needed. 52 /// Once we have better clients, this shouldn't be needed.
52 /// </summary> 53 /// </summary>
53 public class UserAgentService : IUserAgentService 54 public class UserAgentService : UserAgentServiceBase, IUserAgentService
54 { 55 {
55 private static readonly ILog m_log = 56 private static readonly ILog m_log =
56 LogManager.GetLogger( 57 LogManager.GetLogger(
57 MethodBase.GetCurrentMethod().DeclaringType); 58 MethodBase.GetCurrentMethod().DeclaringType);
58 59
59 // This will need to go into a DB table 60 // This will need to go into a DB table
60 static Dictionary<UUID, TravelingAgentInfo> m_TravelingAgents = new Dictionary<UUID, TravelingAgentInfo>(); 61 //static Dictionary<UUID, TravelingAgentInfo> m_Database = new Dictionary<UUID, TravelingAgentInfo>();
61 62
62 static bool m_Initialized = false; 63 static bool m_Initialized = false;
63 64
@@ -86,6 +87,7 @@ namespace OpenSim.Services.HypergridService
86 } 87 }
87 88
88 public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector) 89 public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector)
90 : base(config)
89 { 91 {
90 // Let's set this always, because we don't know the sequence 92 // Let's set this always, because we don't know the sequence
91 // of instantiations 93 // of instantiations
@@ -260,7 +262,8 @@ namespace OpenSim.Services.HypergridService
260 262
261 // Generate a new service session 263 // Generate a new service session
262 agentCircuit.ServiceSessionID = region.ServerURI + ";" + UUID.Random(); 264 agentCircuit.ServiceSessionID = region.ServerURI + ";" + UUID.Random();
263 TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region); 265 TravelingAgentInfo old = null;
266 TravelingAgentInfo travel = CreateTravelInfo(agentCircuit, region, fromLogin, out old);
264 267
265 bool success = false; 268 bool success = false;
266 string myExternalIP = string.Empty; 269 string myExternalIP = string.Empty;
@@ -282,23 +285,21 @@ namespace OpenSim.Services.HypergridService
282 m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}", 285 m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}",
283 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); 286 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason);
284 287
285 // restore the old travel info 288 if (old != null)
286 lock (m_TravelingAgents) 289 StoreTravelInfo(old);
287 { 290 else
288 if (old == null) 291 m_Database.Delete(agentCircuit.SessionID);
289 m_TravelingAgents.Remove(agentCircuit.SessionID);
290 else
291 m_TravelingAgents[agentCircuit.SessionID] = old;
292 }
293 292
294 return false; 293 return false;
295 } 294 }
296 295
296 // Everything is ok
297
298 // Update the perceived IP Address of our grid
297 m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP); 299 m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP);
298 // else set the IP addresses associated with this client 300 travel.MyIpAddress = myExternalIP;
299 if (fromLogin) 301
300 m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = agentCircuit.IPAddress; 302 StoreTravelInfo(travel);
301 m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP;
302 303
303 return true; 304 return true;
304 } 305 }
@@ -309,57 +310,39 @@ namespace OpenSim.Services.HypergridService
309 return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, false, out reason); 310 return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, false, out reason);
310 } 311 }
311 312
312 private void SetClientIP(UUID sessionID, string ip) 313 TravelingAgentInfo CreateTravelInfo(AgentCircuitData agentCircuit, GridRegion region, bool fromLogin, out TravelingAgentInfo existing)
313 { 314 {
314 if (m_TravelingAgents.ContainsKey(sessionID)) 315 HGTravelingData hgt = m_Database.Get(agentCircuit.SessionID);
315 { 316 existing = null;
316 m_log.DebugFormat("[USER AGENT SERVICE]: Setting IP {0} for session {1}", ip, sessionID);
317 m_TravelingAgents[sessionID].ClientIPAddress = ip;
318 }
319 }
320 317
321 TravelingAgentInfo UpdateTravelInfo(AgentCircuitData agentCircuit, GridRegion region) 318 if (hgt != null)
322 {
323 TravelingAgentInfo travel = new TravelingAgentInfo();
324 TravelingAgentInfo old = null;
325 lock (m_TravelingAgents)
326 { 319 {
327 if (m_TravelingAgents.ContainsKey(agentCircuit.SessionID)) 320 // Very important! Override whatever this agent comes with.
328 { 321 // UserAgentService always sets the IP for every new agent
329 // Very important! Override whatever this agent comes with. 322 // with the original IP address.
330 // UserAgentService always sets the IP for every new agent 323 existing = new TravelingAgentInfo(hgt);
331 // with the original IP address. 324 agentCircuit.IPAddress = existing.ClientIPAddress;
332 agentCircuit.IPAddress = m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress;
333
334 old = m_TravelingAgents[agentCircuit.SessionID];
335 }
336
337 m_TravelingAgents[agentCircuit.SessionID] = travel;
338 } 325 }
326
327 TravelingAgentInfo travel = new TravelingAgentInfo(existing);
328 travel.SessionID = agentCircuit.SessionID;
339 travel.UserID = agentCircuit.AgentID; 329 travel.UserID = agentCircuit.AgentID;
340 travel.GridExternalName = region.ServerURI; 330 travel.GridExternalName = region.ServerURI;
341 travel.ServiceToken = agentCircuit.ServiceSessionID; 331 travel.ServiceToken = agentCircuit.ServiceSessionID;
342 if (old != null)
343 travel.ClientIPAddress = old.ClientIPAddress;
344 332
345 return old; 333 if (fromLogin)
334 travel.ClientIPAddress = agentCircuit.IPAddress;
335
336 StoreTravelInfo(travel);
337
338 return travel;
346 } 339 }
347 340
348 public void LogoutAgent(UUID userID, UUID sessionID) 341 public void LogoutAgent(UUID userID, UUID sessionID)
349 { 342 {
350 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID); 343 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID);
351 344
352 lock (m_TravelingAgents) 345 m_Database.Delete(sessionID);
353 {
354 List<UUID> travels = new List<UUID>();
355 foreach (KeyValuePair<UUID, TravelingAgentInfo> kvp in m_TravelingAgents)
356 if (kvp.Value == null) // do some clean up
357 travels.Add(kvp.Key);
358 else if (kvp.Value.UserID == userID)
359 travels.Add(kvp.Key);
360 foreach (UUID session in travels)
361 m_TravelingAgents.Remove(session);
362 }
363 346
364 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString()); 347 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
365 if (guinfo != null) 348 if (guinfo != null)
@@ -369,10 +352,11 @@ namespace OpenSim.Services.HypergridService
369 // We need to prevent foreign users with the same UUID as a local user 352 // We need to prevent foreign users with the same UUID as a local user
370 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName) 353 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName)
371 { 354 {
372 if (!m_TravelingAgents.ContainsKey(sessionID)) 355 HGTravelingData hgt = m_Database.Get(sessionID);
356 if (hgt == null)
373 return false; 357 return false;
374 358
375 TravelingAgentInfo travel = m_TravelingAgents[sessionID]; 359 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
376 360
377 return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower(); 361 return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower();
378 } 362 }
@@ -385,31 +369,32 @@ namespace OpenSim.Services.HypergridService
385 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.", 369 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.",
386 sessionID, reportedIP); 370 sessionID, reportedIP);
387 371
388 if (m_TravelingAgents.ContainsKey(sessionID)) 372 HGTravelingData hgt = m_Database.Get(sessionID);
389 { 373 if (hgt == null)
390 bool result = m_TravelingAgents[sessionID].ClientIPAddress == reportedIP || 374 return false;
391 m_TravelingAgents[sessionID].MyIpAddress == reportedIP; // NATed
392 375
393 m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}", 376 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
394 reportedIP, m_TravelingAgents[sessionID].ClientIPAddress, m_TravelingAgents[sessionID].MyIpAddress, result);
395 377
396 return result; 378 bool result = travel.ClientIPAddress == reportedIP || travel.MyIpAddress == reportedIP; // NATed
397 }
398 379
399 return false; 380 m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}",
381 reportedIP, travel.ClientIPAddress, travel.MyIpAddress, result);
382
383 return result;
400 } 384 }
401 385
402 public bool VerifyAgent(UUID sessionID, string token) 386 public bool VerifyAgent(UUID sessionID, string token)
403 { 387 {
404 if (m_TravelingAgents.ContainsKey(sessionID)) 388 HGTravelingData hgt = m_Database.Get(sessionID);
389 if (hgt == null)
405 { 390 {
406 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, m_TravelingAgents[sessionID].ServiceToken); 391 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID);
407 return m_TravelingAgents[sessionID].ServiceToken == token; 392 return false;
408 } 393 }
409 394
410 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID); 395 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
411 396 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, travel.ServiceToken);
412 return false; 397 return travel.ServiceToken == token;
413 } 398 }
414 399
415 [Obsolete] 400 [Obsolete]
@@ -472,17 +457,17 @@ namespace OpenSim.Services.HypergridService
472 } 457 }
473 } 458 }
474 459
475 // Lastly, let's notify the rest who may be online somewhere else 460 //// Lastly, let's notify the rest who may be online somewhere else
476 foreach (string user in usersToBeNotified) 461 //foreach (string user in usersToBeNotified)
477 { 462 //{
478 UUID id = new UUID(user); 463 // UUID id = new UUID(user);
479 if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName) 464 // if (m_Database.ContainsKey(id) && m_Database[id].GridExternalName != m_GridName)
480 { 465 // {
481 string url = m_TravelingAgents[id].GridExternalName; 466 // string url = m_Database[id].GridExternalName;
482 // forward 467 // // forward
483 m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url); 468 // m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url);
484 } 469 // }
485 } 470 //}
486 471
487 // and finally, let's send the online friends 472 // and finally, let's send the online friends
488 if (online) 473 if (online)
@@ -609,16 +594,13 @@ namespace OpenSim.Services.HypergridService
609 594
610 public string LocateUser(UUID userID) 595 public string LocateUser(UUID userID)
611 { 596 {
612 foreach (TravelingAgentInfo t in m_TravelingAgents.Values) 597 HGTravelingData[] hgts = m_Database.GetSessions(userID);
613 { 598 if (hgts == null)
614 if (t == null) 599 return string.Empty;
615 { 600
616 m_log.ErrorFormat("[USER AGENT SERVICE]: Oops! Null TravelingAgentInfo. Please report this on mantis"); 601 foreach (HGTravelingData t in hgts)
617 continue; 602 if (t.Data.ContainsKey("GridExternalName") && !m_GridName.Equals(t.Data["GridExternalName"]))
618 } 603 return t.Data["GridExternalName"];
619 if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName))
620 return t.GridExternalName;
621 }
622 604
623 return string.Empty; 605 return string.Empty;
624 } 606 }
@@ -689,17 +671,60 @@ namespace OpenSim.Services.HypergridService
689 return exception; 671 return exception;
690 } 672 }
691 673
674 private void StoreTravelInfo(TravelingAgentInfo travel)
675 {
676 if (travel == null)
677 return;
678
679 HGTravelingData hgt = new HGTravelingData();
680 hgt.SessionID = travel.SessionID;
681 hgt.UserID = travel.UserID;
682 hgt.Data = new Dictionary<string, string>();
683 hgt.Data["GridExternalName"] = travel.GridExternalName;
684 hgt.Data["ServiceToken"] = travel.ServiceToken;
685 hgt.Data["ClientIPAddress"] = travel.ClientIPAddress;
686 hgt.Data["MyIPAddress"] = travel.MyIpAddress;
687
688 m_Database.Store(hgt);
689 }
692 #endregion 690 #endregion
693 691
694 } 692 }
695 693
696 class TravelingAgentInfo 694 class TravelingAgentInfo
697 { 695 {
696 public UUID SessionID;
698 public UUID UserID; 697 public UUID UserID;
699 public string GridExternalName = string.Empty; 698 public string GridExternalName = string.Empty;
700 public string ServiceToken = string.Empty; 699 public string ServiceToken = string.Empty;
701 public string ClientIPAddress = string.Empty; // as seen from this user agent service 700 public string ClientIPAddress = string.Empty; // as seen from this user agent service
702 public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper 701 public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper
702
703 public TravelingAgentInfo(HGTravelingData t)
704 {
705 if (t.Data != null)
706 {
707 SessionID = new UUID(t.SessionID);
708 UserID = new UUID(t.UserID);
709 GridExternalName = t.Data["GridExternalName"];
710 ServiceToken = t.Data["ServiceToken"];
711 ClientIPAddress = t.Data["ClientIPAddress"];
712 MyIpAddress = t.Data["MyIPAddress"];
713 }
714 }
715
716 public TravelingAgentInfo(TravelingAgentInfo old)
717 {
718 if (old != null)
719 {
720 SessionID = old.SessionID;
721 UserID = old.UserID;
722 GridExternalName = old.GridExternalName;
723 ServiceToken = old.ServiceToken;
724 ClientIPAddress = old.ClientIPAddress;
725 MyIpAddress = old.MyIpAddress;
726 }
727 }
703 } 728 }
704 729
705} 730}
diff --git a/OpenSim/Services/HypergridService/UserAgentServiceBase.cs b/OpenSim/Services/HypergridService/UserAgentServiceBase.cs
new file mode 100644
index 0000000..a00e5a6
--- /dev/null
+++ b/OpenSim/Services/HypergridService/UserAgentServiceBase.cs
@@ -0,0 +1,84 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using Nini.Config;
31using OpenSim.Framework;
32using OpenSim.Data;
33using OpenSim.Services.Interfaces;
34using OpenSim.Services.Base;
35
36namespace OpenSim.Services.HypergridService
37{
38 public class UserAgentServiceBase : ServiceBase
39 {
40 protected IHGTravelingData m_Database = null;
41
42 public UserAgentServiceBase(IConfigSource config)
43 : base(config)
44 {
45 string dllName = String.Empty;
46 string connString = String.Empty;
47 string realm = "hg_traveling_data";
48
49 //
50 // Try reading the [DatabaseService] section, if it exists
51 //
52 IConfig dbConfig = config.Configs["DatabaseService"];
53 if (dbConfig != null)
54 {
55 if (dllName == String.Empty)
56 dllName = dbConfig.GetString("StorageProvider", String.Empty);
57 if (connString == String.Empty)
58 connString = dbConfig.GetString("ConnectionString", String.Empty);
59 }
60
61 //
62 // [UserAgentService] section overrides [DatabaseService], if it exists
63 //
64 IConfig gridConfig = config.Configs["UserAgentService"];
65 if (gridConfig != null)
66 {
67 dllName = gridConfig.GetString("StorageProvider", dllName);
68 connString = gridConfig.GetString("ConnectionString", connString);
69 realm = gridConfig.GetString("Realm", realm);
70 }
71
72 //
73 // We tried, but this doesn't exist. We can't proceed.
74 //
75 if (dllName.Equals(String.Empty))
76 throw new Exception("No StorageProvider configured");
77
78 m_Database = LoadPlugin<IHGTravelingData>(dllName, new Object[] { connString, realm });
79 if (m_Database == null)
80 throw new Exception("Could not find a storage interface in the given module");
81
82 }
83 }
84}