aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/HypergridService/UserAgentService.cs
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-11-03 21:44:39 +1000
committerDavid Walter Seikel2016-11-03 21:44:39 +1000
commit134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch)
tree216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Services/HypergridService/UserAgentService.cs
parentMore changing to production grid. Double oops. (diff)
downloadopensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to 'OpenSim/Services/HypergridService/UserAgentService.cs')
-rw-r--r--OpenSim/Services/HypergridService/UserAgentService.cs259
1 files changed, 153 insertions, 106 deletions
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index a26a922..c65122a 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
@@ -74,6 +75,7 @@ namespace OpenSim.Services.HypergridService
74 protected static string m_GridName; 75 protected static string m_GridName;
75 76
76 protected static int m_LevelOutsideContacts; 77 protected static int m_LevelOutsideContacts;
78 protected static bool m_ShowDetails;
77 79
78 protected static bool m_BypassClientVerification; 80 protected static bool m_BypassClientVerification;
79 81
@@ -86,6 +88,7 @@ namespace OpenSim.Services.HypergridService
86 } 88 }
87 89
88 public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector) 90 public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector)
91 : base(config)
89 { 92 {
90 // Let's set this always, because we don't know the sequence 93 // Let's set this always, because we don't know the sequence
91 // of instantiations 94 // of instantiations
@@ -126,20 +129,30 @@ namespace OpenSim.Services.HypergridService
126 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountService, args); 129 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountService, args);
127 130
128 m_LevelOutsideContacts = serverConfig.GetInt("LevelOutsideContacts", 0); 131 m_LevelOutsideContacts = serverConfig.GetInt("LevelOutsideContacts", 0);
132 m_ShowDetails = serverConfig.GetBoolean("ShowUserDetailsInHGProfile", true);
129 133
130 LoadTripPermissionsFromConfig(serverConfig, "ForeignTripsAllowed"); 134 LoadTripPermissionsFromConfig(serverConfig, "ForeignTripsAllowed");
131 LoadDomainExceptionsFromConfig(serverConfig, "AllowExcept", m_TripsAllowedExceptions); 135 LoadDomainExceptionsFromConfig(serverConfig, "AllowExcept", m_TripsAllowedExceptions);
132 LoadDomainExceptionsFromConfig(serverConfig, "DisallowExcept", m_TripsDisallowedExceptions); 136 LoadDomainExceptionsFromConfig(serverConfig, "DisallowExcept", m_TripsDisallowedExceptions);
133 137
134 m_GridName = serverConfig.GetString("ExternalName", string.Empty); 138 m_GridName = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
135 if (m_GridName == string.Empty) 139 new string[] { "Startup", "Hypergrid", "UserAgentService" }, String.Empty);
140 if (string.IsNullOrEmpty(m_GridName)) // Legacy. Remove soon.
136 { 141 {
137 serverConfig = config.Configs["GatekeeperService"];
138 m_GridName = serverConfig.GetString("ExternalName", string.Empty); 142 m_GridName = serverConfig.GetString("ExternalName", string.Empty);
143 if (m_GridName == string.Empty)
144 {
145 serverConfig = config.Configs["GatekeeperService"];
146 m_GridName = serverConfig.GetString("ExternalName", string.Empty);
147 }
139 } 148 }
149
140 if (!m_GridName.EndsWith("/")) 150 if (!m_GridName.EndsWith("/"))
141 m_GridName = m_GridName + "/"; 151 m_GridName = m_GridName + "/";
142 152
153 // Finally some cleanup
154 m_Database.DeleteOld();
155
143 } 156 }
144 } 157 }
145 158
@@ -204,10 +217,10 @@ namespace OpenSim.Services.HypergridService
204 return home; 217 return home;
205 } 218 }
206 219
207 public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason) 220 public bool LoginAgentToGrid(GridRegion source, AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason)
208 { 221 {
209 m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}", 222 m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}",
210 agentCircuit.firstname, agentCircuit.lastname, ((clientIP == null) ? "stored IP" : clientIP.Address.ToString()), gatekeeper.ServerURI); 223 agentCircuit.firstname, agentCircuit.lastname, (fromLogin ? agentCircuit.IPAddress : "stored IP"), gatekeeper.ServerURI);
211 224
212 string gridName = gatekeeper.ServerURI; 225 string gridName = gatekeeper.ServerURI;
213 226
@@ -254,21 +267,21 @@ namespace OpenSim.Services.HypergridService
254 267
255 // Generate a new service session 268 // Generate a new service session
256 agentCircuit.ServiceSessionID = region.ServerURI + ";" + UUID.Random(); 269 agentCircuit.ServiceSessionID = region.ServerURI + ";" + UUID.Random();
257 TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region); 270 TravelingAgentInfo old = null;
271 TravelingAgentInfo travel = CreateTravelInfo(agentCircuit, region, fromLogin, out old);
258 272
259 bool success = false; 273 bool success = false;
260 string myExternalIP = string.Empty; 274 string myExternalIP = string.Empty;
261 275
262 m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}", m_GridName, gridName); 276 m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}, desired region: {2}", m_GridName, gridName, region.RegionID);
263 277
264 if (m_GridName == gridName) 278 if (m_GridName == gridName)
265 success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); 279 {
280 success = m_GatekeeperService.LoginAgent(source, agentCircuit, finalDestination, out reason);
281 }
266 else 282 else
267 { 283 {
268 success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason); 284 success = m_GatekeeperConnector.CreateAgent(source, region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason);
269 if (success)
270 // Report them as nowhere
271 m_PresenceService.ReportAgent(agentCircuit.SessionID, UUID.Zero);
272 } 285 }
273 286
274 if (!success) 287 if (!success)
@@ -276,84 +289,64 @@ namespace OpenSim.Services.HypergridService
276 m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}", 289 m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}",
277 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); 290 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason);
278 291
279 // restore the old travel info 292 if (old != null)
280 lock (m_TravelingAgents) 293 StoreTravelInfo(old);
281 { 294 else
282 if (old == null) 295 m_Database.Delete(agentCircuit.SessionID);
283 m_TravelingAgents.Remove(agentCircuit.SessionID);
284 else
285 m_TravelingAgents[agentCircuit.SessionID] = old;
286 }
287 296
288 return false; 297 return false;
289 } 298 }
290 299
300 // Everything is ok
301
302 // Update the perceived IP Address of our grid
291 m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP); 303 m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP);
292 // else set the IP addresses associated with this client 304 travel.MyIpAddress = myExternalIP;
293 if (clientIP != null) 305
294 m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString(); 306 StoreTravelInfo(travel);
295 m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP;
296 307
297 return true; 308 return true;
298 } 309 }
299 310
300 public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason) 311 public bool LoginAgentToGrid(GridRegion source, AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason)
301 { 312 {
302 reason = string.Empty; 313 reason = string.Empty;
303 return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, null, out reason); 314 return LoginAgentToGrid(source, agentCircuit, gatekeeper, finalDestination, false, out reason);
304 } 315 }
305 316
306 private void SetClientIP(UUID sessionID, string ip) 317 TravelingAgentInfo CreateTravelInfo(AgentCircuitData agentCircuit, GridRegion region, bool fromLogin, out TravelingAgentInfo existing)
307 { 318 {
308 if (m_TravelingAgents.ContainsKey(sessionID)) 319 HGTravelingData hgt = m_Database.Get(agentCircuit.SessionID);
309 { 320 existing = null;
310 m_log.DebugFormat("[USER AGENT SERVICE]: Setting IP {0} for session {1}", ip, sessionID);
311 m_TravelingAgents[sessionID].ClientIPAddress = ip;
312 }
313 }
314 321
315 TravelingAgentInfo UpdateTravelInfo(AgentCircuitData agentCircuit, GridRegion region) 322 if (hgt != null)
316 {
317 TravelingAgentInfo travel = new TravelingAgentInfo();
318 TravelingAgentInfo old = null;
319 lock (m_TravelingAgents)
320 { 323 {
321 if (m_TravelingAgents.ContainsKey(agentCircuit.SessionID)) 324 // Very important! Override whatever this agent comes with.
322 { 325 // UserAgentService always sets the IP for every new agent
323 // Very important! Override whatever this agent comes with. 326 // with the original IP address.
324 // UserAgentService always sets the IP for every new agent 327 existing = new TravelingAgentInfo(hgt);
325 // with the original IP address. 328 agentCircuit.IPAddress = existing.ClientIPAddress;
326 agentCircuit.IPAddress = m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress;
327
328 old = m_TravelingAgents[agentCircuit.SessionID];
329 }
330
331 m_TravelingAgents[agentCircuit.SessionID] = travel;
332 } 329 }
330
331 TravelingAgentInfo travel = new TravelingAgentInfo(existing);
332 travel.SessionID = agentCircuit.SessionID;
333 travel.UserID = agentCircuit.AgentID; 333 travel.UserID = agentCircuit.AgentID;
334 travel.GridExternalName = region.ServerURI; 334 travel.GridExternalName = region.ServerURI;
335 travel.ServiceToken = agentCircuit.ServiceSessionID; 335 travel.ServiceToken = agentCircuit.ServiceSessionID;
336 if (old != null)
337 travel.ClientIPAddress = old.ClientIPAddress;
338 336
339 return old; 337 if (fromLogin)
338 travel.ClientIPAddress = agentCircuit.IPAddress;
339
340 StoreTravelInfo(travel);
341
342 return travel;
340 } 343 }
341 344
342 public void LogoutAgent(UUID userID, UUID sessionID) 345 public void LogoutAgent(UUID userID, UUID sessionID)
343 { 346 {
344 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID); 347 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID);
345 348
346 lock (m_TravelingAgents) 349 m_Database.Delete(sessionID);
347 {
348 List<UUID> travels = new List<UUID>();
349 foreach (KeyValuePair<UUID, TravelingAgentInfo> kvp in m_TravelingAgents)
350 if (kvp.Value == null) // do some clean up
351 travels.Add(kvp.Key);
352 else if (kvp.Value.UserID == userID)
353 travels.Add(kvp.Key);
354 foreach (UUID session in travels)
355 m_TravelingAgents.Remove(session);
356 }
357 350
358 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString()); 351 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
359 if (guinfo != null) 352 if (guinfo != null)
@@ -363,10 +356,11 @@ namespace OpenSim.Services.HypergridService
363 // We need to prevent foreign users with the same UUID as a local user 356 // We need to prevent foreign users with the same UUID as a local user
364 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName) 357 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName)
365 { 358 {
366 if (!m_TravelingAgents.ContainsKey(sessionID)) 359 HGTravelingData hgt = m_Database.Get(sessionID);
360 if (hgt == null)
367 return false; 361 return false;
368 362
369 TravelingAgentInfo travel = m_TravelingAgents[sessionID]; 363 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
370 364
371 return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower(); 365 return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower();
372 } 366 }
@@ -379,31 +373,32 @@ namespace OpenSim.Services.HypergridService
379 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.", 373 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.",
380 sessionID, reportedIP); 374 sessionID, reportedIP);
381 375
382 if (m_TravelingAgents.ContainsKey(sessionID)) 376 HGTravelingData hgt = m_Database.Get(sessionID);
383 { 377 if (hgt == null)
384 bool result = m_TravelingAgents[sessionID].ClientIPAddress == reportedIP || 378 return false;
385 m_TravelingAgents[sessionID].MyIpAddress == reportedIP; // NATed
386 379
387 m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}", 380 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
388 reportedIP, m_TravelingAgents[sessionID].ClientIPAddress, m_TravelingAgents[sessionID].MyIpAddress, result);
389 381
390 return result; 382 bool result = travel.ClientIPAddress == reportedIP || travel.MyIpAddress == reportedIP; // NATed
391 } 383
384 m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}",
385 reportedIP, travel.ClientIPAddress, travel.MyIpAddress, result);
392 386
393 return false; 387 return result;
394 } 388 }
395 389
396 public bool VerifyAgent(UUID sessionID, string token) 390 public bool VerifyAgent(UUID sessionID, string token)
397 { 391 {
398 if (m_TravelingAgents.ContainsKey(sessionID)) 392 HGTravelingData hgt = m_Database.Get(sessionID);
393 if (hgt == null)
399 { 394 {
400 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, m_TravelingAgents[sessionID].ServiceToken); 395 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID);
401 return m_TravelingAgents[sessionID].ServiceToken == token; 396 return false;
402 } 397 }
403 398
404 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID); 399 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
405 400 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, travel.ServiceToken);
406 return false; 401 return travel.ServiceToken == token;
407 } 402 }
408 403
409 [Obsolete] 404 [Obsolete]
@@ -466,17 +461,17 @@ namespace OpenSim.Services.HypergridService
466 } 461 }
467 } 462 }
468 463
469 // Lastly, let's notify the rest who may be online somewhere else 464 //// Lastly, let's notify the rest who may be online somewhere else
470 foreach (string user in usersToBeNotified) 465 //foreach (string user in usersToBeNotified)
471 { 466 //{
472 UUID id = new UUID(user); 467 // UUID id = new UUID(user);
473 if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName) 468 // if (m_Database.ContainsKey(id) && m_Database[id].GridExternalName != m_GridName)
474 { 469 // {
475 string url = m_TravelingAgents[id].GridExternalName; 470 // string url = m_Database[id].GridExternalName;
476 // forward 471 // // forward
477 m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url); 472 // m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url);
478 } 473 // }
479 } 474 //}
480 475
481 // and finally, let's send the online friends 476 // and finally, let's send the online friends
482 if (online) 477 if (online)
@@ -578,10 +573,22 @@ namespace OpenSim.Services.HypergridService
578 573
579 if (account != null) 574 if (account != null)
580 { 575 {
581 info.Add("user_flags", (object)account.UserFlags); 576 info.Add("user_firstname", account.FirstName);
582 info.Add("user_created", (object)account.Created); 577 info.Add("user_lastname", account.LastName);
583 info.Add("user_title", (object)account.UserTitle);
584 info.Add("result", "success"); 578 info.Add("result", "success");
579
580 if (m_ShowDetails)
581 {
582 info.Add("user_flags", account.UserFlags);
583 info.Add("user_created", account.Created);
584 info.Add("user_title", account.UserTitle);
585 }
586 else
587 {
588 info.Add("user_flags", 0);
589 info.Add("user_created", 0);
590 info.Add("user_title", string.Empty);
591 }
585 } 592 }
586 593
587 return info; 594 return info;
@@ -603,16 +610,13 @@ namespace OpenSim.Services.HypergridService
603 610
604 public string LocateUser(UUID userID) 611 public string LocateUser(UUID userID)
605 { 612 {
606 foreach (TravelingAgentInfo t in m_TravelingAgents.Values) 613 HGTravelingData[] hgts = m_Database.GetSessions(userID);
607 { 614 if (hgts == null)
608 if (t == null) 615 return string.Empty;
609 { 616
610 m_log.ErrorFormat("[USER AGENT SERVICE]: Oops! Null TravelingAgentInfo. Please report this on mantis"); 617 foreach (HGTravelingData t in hgts)
611 continue; 618 if (t.Data.ContainsKey("GridExternalName") && !m_GridName.Equals(t.Data["GridExternalName"]))
612 } 619 return t.Data["GridExternalName"];
613 if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName))
614 return t.GridExternalName;
615 }
616 620
617 return string.Empty; 621 return string.Empty;
618 } 622 }
@@ -683,17 +687,60 @@ namespace OpenSim.Services.HypergridService
683 return exception; 687 return exception;
684 } 688 }
685 689
690 private void StoreTravelInfo(TravelingAgentInfo travel)
691 {
692 if (travel == null)
693 return;
694
695 HGTravelingData hgt = new HGTravelingData();
696 hgt.SessionID = travel.SessionID;
697 hgt.UserID = travel.UserID;
698 hgt.Data = new Dictionary<string, string>();
699 hgt.Data["GridExternalName"] = travel.GridExternalName;
700 hgt.Data["ServiceToken"] = travel.ServiceToken;
701 hgt.Data["ClientIPAddress"] = travel.ClientIPAddress;
702 hgt.Data["MyIPAddress"] = travel.MyIpAddress;
703
704 m_Database.Store(hgt);
705 }
686 #endregion 706 #endregion
687 707
688 } 708 }
689 709
690 class TravelingAgentInfo 710 class TravelingAgentInfo
691 { 711 {
712 public UUID SessionID;
692 public UUID UserID; 713 public UUID UserID;
693 public string GridExternalName = string.Empty; 714 public string GridExternalName = string.Empty;
694 public string ServiceToken = string.Empty; 715 public string ServiceToken = string.Empty;
695 public string ClientIPAddress = string.Empty; // as seen from this user agent service 716 public string ClientIPAddress = string.Empty; // as seen from this user agent service
696 public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper 717 public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper
718
719 public TravelingAgentInfo(HGTravelingData t)
720 {
721 if (t.Data != null)
722 {
723 SessionID = new UUID(t.SessionID);
724 UserID = new UUID(t.UserID);
725 GridExternalName = t.Data["GridExternalName"];
726 ServiceToken = t.Data["ServiceToken"];
727 ClientIPAddress = t.Data["ClientIPAddress"];
728 MyIpAddress = t.Data["MyIPAddress"];
729 }
730 }
731
732 public TravelingAgentInfo(TravelingAgentInfo old)
733 {
734 if (old != null)
735 {
736 SessionID = old.SessionID;
737 UserID = old.UserID;
738 GridExternalName = old.GridExternalName;
739 ServiceToken = old.ServiceToken;
740 ClientIPAddress = old.ClientIPAddress;
741 MyIpAddress = old.MyIpAddress;
742 }
743 }
697 } 744 }
698 745
699} 746}