aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2014-10-02 23:18:21 +0100
committerJustin Clark-Casey (justincc)2014-11-25 23:18:39 +0000
commit12daa3c3d9731c67ebd0459dc79b81366514c855 (patch)
treefc3b43c336ed7d1967da27214360dcaa3f2a5904 /OpenSim/Region/ClientStack
parentrefactor: rename "debug lludp throttle status" to "debug lludp throttle get" ... (diff)
downloadopensim-SC-12daa3c3d9731c67ebd0459dc79b81366514c855.zip
opensim-SC-12daa3c3d9731c67ebd0459dc79b81366514c855.tar.gz
opensim-SC-12daa3c3d9731c67ebd0459dc79b81366514c855.tar.bz2
opensim-SC-12daa3c3d9731c67ebd0459dc79b81366514c855.tar.xz
refactor: Move LLUDPServer console commands into their own class.
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs489
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs518
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs12
3 files changed, 539 insertions, 480 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index e7c8ef9..fc6fb3e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -34,7 +34,6 @@ using System.Net.Sockets;
34using System.Reflection; 34using System.Reflection;
35using System.Threading; 35using System.Threading;
36using log4net; 36using log4net;
37using NDesk.Options;
38using Nini.Config; 37using Nini.Config;
39using OpenMetaverse.Packets; 38using OpenMetaverse.Packets;
40using OpenSim.Framework; 39using OpenSim.Framework;
@@ -222,6 +221,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
222 /// </summary> 221 /// </summary>
223 public int DefaultClientPacketDebugLevel { get; set; } 222 public int DefaultClientPacketDebugLevel { get; set; }
224 223
224 /// <summary>
225 /// If set then all inbound agent updates are discarded. For debugging purposes.
226 /// discard agent update.
227 /// </summary>
228 public bool DiscardInboundAgentUpdates { get; set; }
229
225 /// <summary>The measured resolution of Environment.TickCount</summary> 230 /// <summary>The measured resolution of Environment.TickCount</summary>
226 public readonly float TickCountResolution; 231 public readonly float TickCountResolution;
227 232
@@ -458,7 +463,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
458 m_elapsedMSSinceLastStatReport = Environment.TickCount; 463 m_elapsedMSSinceLastStatReport = Environment.TickCount;
459 } 464 }
460 465
461 private void StartInbound() 466 public void StartInbound()
462 { 467 {
463 m_log.InfoFormat( 468 m_log.InfoFormat(
464 "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}", 469 "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}",
@@ -477,7 +482,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
477 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); 482 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
478 } 483 }
479 484
480 private new void StartOutbound() 485 public override void StartOutbound()
481 { 486 {
482 m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); 487 m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
483 488
@@ -501,7 +506,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
501 OqrEngine.Stop(); 506 OqrEngine.Stop();
502 } 507 }
503 508
504 protected override bool EnablePools() 509 public override bool EnablePools()
505 { 510 {
506 if (!UsePools) 511 if (!UsePools)
507 { 512 {
@@ -515,7 +520,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
515 return false; 520 return false;
516 } 521 }
517 522
518 protected override bool DisablePools() 523 public override bool DisablePools()
519 { 524 {
520 if (UsePools) 525 if (UsePools)
521 { 526 {
@@ -535,7 +540,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
535 /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene 540 /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
536 /// stats. 541 /// stats.
537 /// </summary> 542 /// </summary>
538 private void EnablePoolStats() 543 protected internal void EnablePoolStats()
539 { 544 {
540 m_poolCountStat 545 m_poolCountStat
541 = new Stat( 546 = new Stat(
@@ -569,7 +574,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
569 /// <summary> 574 /// <summary>
570 /// Disables pool stats. 575 /// Disables pool stats.
571 /// </summary> 576 /// </summary>
572 private void DisablePoolStats() 577 protected internal void DisablePoolStats()
573 { 578 {
574 StatsManager.DeregisterStat(m_poolCountStat); 579 StatsManager.DeregisterStat(m_poolCountStat);
575 m_poolCountStat = null; 580 m_poolCountStat = null;
@@ -689,472 +694,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
689 if (UsePools) 694 if (UsePools)
690 EnablePoolStats(); 695 EnablePoolStats();
691 696
692 MainConsole.Instance.Commands.AddCommand( 697 LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this);
693 "Debug", false, "debug lludp packet", 698 commands.Register();
694 "debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]",
695 "Turn on packet debugging. This logs information when the client stack hands a processed packet off to downstream code or when upstream code first requests that a certain packet be sent.",
696 "If level > 255 then all incoming and outgoing packets are logged.\n"
697 + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
698 + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
699 + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
700 + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
701 + "If level <= 0 then no packets are logged.\n"
702 + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
703 + "If --all is specified then the level becomes the default logging level for all current and subsequent agents.\n"
704 + "In these cases, you cannot also specify an avatar name.\n"
705 + "If an avatar name is given then only packets from that avatar are logged.",
706 HandlePacketCommand);
707
708 MainConsole.Instance.Commands.AddCommand(
709 "Debug", false, "debug lludp data out",
710 "debug lludp data out <level> <avatar-first-name> <avatar-last-name>\"",
711 "Turn on debugging for final outgoing data to the given user's client.",
712 "This operates at a much lower level than the packet command and prints out available details when the data is actually sent.\n"
713 + "If level > 0 then information about all outgoing UDP data for this avatar is logged.\n"
714 + "If level <= 0 then no information about outgoing UDP data for this avatar is logged.",
715 HandleDataCommand);
716
717 MainConsole.Instance.Commands.AddCommand(
718 "Debug", false, "debug lludp drop",
719 "debug lludp drop <in|out> <add|remove> <packet-name>",
720 "Drop all in or outbound packets that match the given name",
721 "For test purposes.",
722 HandleDropCommand);
723
724 MainConsole.Instance.Commands.AddCommand(
725 "Debug",
726 false,
727 "debug lludp start",
728 "debug lludp start <in|out|all>",
729 "Control LLUDP packet processing.",
730 "No effect if packet processing has already started.\n"
731 + "in - start inbound processing.\n"
732 + "out - start outbound processing.\n"
733 + "all - start in and outbound processing.\n",
734 HandleStartCommand);
735
736 MainConsole.Instance.Commands.AddCommand(
737 "Debug",
738 false,
739 "debug lludp stop",
740 "debug lludp stop <in|out|all>",
741 "Stop LLUDP packet processing.",
742 "No effect if packet processing has already stopped.\n"
743 + "in - stop inbound processing.\n"
744 + "out - stop outbound processing.\n"
745 + "all - stop in and outbound processing.\n",
746 HandleStopCommand);
747
748 MainConsole.Instance.Commands.AddCommand(
749 "Debug",
750 false,
751 "debug lludp pool",
752 "debug lludp pool <on|off>",
753 "Turn object pooling within the lludp component on or off.",
754 HandlePoolCommand);
755
756 MainConsole.Instance.Commands.AddCommand(
757 "Debug",
758 false,
759 "debug lludp status",
760 "debug lludp status",
761 "Return status of LLUDP packet processing.",
762 HandleStatusCommand);
763
764 MainConsole.Instance.Commands.AddCommand(
765 "Debug",
766 false,
767 "debug lludp throttle log",
768 "debug lludp throttle log <level> <avatar-first-name> <avatar-last-name>",
769 "Change debug logging level for throttles.",
770 "If level >= 0 then throttle debug logging is performed.\n"
771 + "If level <= 0 then no throttle debug logging is performed.",
772 HandleThrottleCommand);
773
774 MainConsole.Instance.Commands.AddCommand(
775 "Debug",
776 false,
777 "debug lludp throttle get",
778 "debug lludp throttle get <avatar-first-name> <avatar-last-name>",
779 "Return debug settings for throttles.",
780 HandleThrottleGetCommand);
781
782 MainConsole.Instance.Commands.AddCommand(
783 "Debug",
784 false,
785 "debug lludp throttle set",
786 "debug lludp throttle set <param> <value> <avatar-first-name> <avatar-last-name>",
787 "Set a throttle parameter for the given client.",
788 "Only current setting is 'adaptive' which must be 'true' or 'false'",
789 HandleThrottleSetCommand);
790
791 MainConsole.Instance.Commands.AddCommand(
792 "Debug",
793 false,
794 "debug lludp toggle agentupdate",
795 "debug lludp toggle agentupdate",
796 "Toggle whether agentupdate packets are processed or simply discarded.",
797 HandleAgentUpdateCommand);
798 }
799
800 private void HandleDataCommand(string module, string[] args)
801 {
802 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
803 return;
804
805 if (args.Length != 7)
806 {
807 MainConsole.Instance.OutputFormat("Usage: debug lludp data out <true|false> <avatar-first-name> <avatar-last-name>");
808 return;
809 }
810
811 int level;
812 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
813 return;
814
815 string firstName = args[5];
816 string lastName = args[6];
817
818 Scene.ForEachScenePresence(sp =>
819 {
820 if (sp.Firstname == firstName && sp.Lastname == lastName)
821 {
822 MainConsole.Instance.OutputFormat(
823 "Data debug for {0} ({1}) set to {2} in {3}",
824 sp.Name, sp.IsChildAgent ? "child" : "root", level, Scene.Name);
825
826 ((LLClientView)sp.ControllingClient).UDPClient.DebugDataOutLevel = level;
827 }
828 });
829 }
830
831 private void HandleThrottleCommand(string module, string[] args)
832 {
833 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
834 return;
835
836 if (args.Length != 7)
837 {
838 MainConsole.Instance.OutputFormat("Usage: debug lludp throttle log <level> <avatar-first-name> <avatar-last-name>");
839 return;
840 }
841
842 int level;
843 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
844 return;
845
846 string firstName = args[5];
847 string lastName = args[6];
848
849 Scene.ForEachScenePresence(sp =>
850 {
851 if (sp.Firstname == firstName && sp.Lastname == lastName)
852 {
853 MainConsole.Instance.OutputFormat(
854 "Throttle log level for {0} ({1}) set to {2} in {3}",
855 sp.Name, sp.IsChildAgent ? "child" : "root", level, Scene.Name);
856
857 ((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level;
858 }
859 });
860 }
861
862 private void HandleThrottleSetCommand(string module, string[] args)
863 {
864 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
865 return;
866
867 if (args.Length != 8)
868 {
869 MainConsole.Instance.OutputFormat(
870 "Usage: debug lludp throttle set <param> <value> <avatar-first-name> <avatar-last-name>");
871 return;
872 }
873
874 string param = args[4];
875 string rawValue = args[5];
876 string firstName = args[6];
877 string lastName = args[7];
878
879 if (param == "adaptive")
880 {
881 bool newValue;
882 if (!ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, rawValue, out newValue))
883 return;
884
885 Scene.ForEachScenePresence(sp =>
886 {
887 if (sp.Firstname == firstName && sp.Lastname == lastName)
888 {
889 MainConsole.Instance.OutputFormat(
890 "Setting param {0} to {1} for {2} ({3}) in {4}",
891 param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", Scene.Name);
892
893 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
894 udpClient.FlowThrottle.Enabled = newValue;
895// udpClient.FlowThrottle.MaxDripRate = 0;
896// udpClient.FlowThrottle.AdjustedDripRate = 0;
897 }
898 });
899 }
900 }
901
902 private void HandleThrottleGetCommand(string module, string[] args)
903 {
904 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
905 return;
906
907 if (args.Length != 6)
908 {
909 MainConsole.Instance.OutputFormat("Usage: debug lludp throttle get <avatar-first-name> <avatar-last-name>");
910 return;
911 }
912
913 string firstName = args[4];
914 string lastName = args[5];
915
916 Scene.ForEachScenePresence(sp =>
917 {
918 if (sp.Firstname == firstName && sp.Lastname == lastName)
919 {
920 MainConsole.Instance.OutputFormat(
921 "Status for {0} ({1}) in {2}",
922 sp.Name, sp.IsChildAgent ? "child" : "root", Scene.Name);
923
924 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
925 MainConsole.Instance.OutputFormat("Adaptive throttle: {0}", udpClient.FlowThrottle.Enabled);
926 }
927 });
928 }
929
930 private void HandlePacketCommand(string module, string[] args)
931 {
932 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
933 return;
934
935 bool setAsDefaultLevel = false;
936 bool setAll = false;
937 OptionSet optionSet = new OptionSet()
938 .Add("default", o => setAsDefaultLevel = (o != null))
939 .Add("all", o => setAll = (o != null));
940 List<string> filteredArgs = optionSet.Parse(args);
941
942 string name = null;
943
944 if (filteredArgs.Count == 6)
945 {
946 if (!(setAsDefaultLevel || setAll))
947 {
948 name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
949 }
950 else
951 {
952 MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default/all logging level");
953 return;
954 }
955 }
956
957 if (filteredArgs.Count > 3)
958 {
959 int newDebug;
960 if (int.TryParse(filteredArgs[3], out newDebug))
961 {
962 if (setAsDefaultLevel || setAll)
963 {
964 DefaultClientPacketDebugLevel = newDebug;
965
966 MainConsole.Instance.OutputFormat(
967 "Packet debug for {0} clients set to {1} in {2}",
968 (setAll ? "all" : "future"), DefaultClientPacketDebugLevel, Scene.Name);
969
970 if (setAll)
971 {
972 Scene.ForEachScenePresence(sp =>
973 {
974 MainConsole.Instance.OutputFormat(
975 "Packet debug for {0} ({1}) set to {2} in {3}",
976 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name);
977
978 sp.ControllingClient.DebugPacketLevel = newDebug;
979 });
980 }
981 }
982 else
983 {
984 Scene.ForEachScenePresence(sp =>
985 {
986 if (name == null || sp.Name == name)
987 {
988 MainConsole.Instance.OutputFormat(
989 "Packet debug for {0} ({1}) set to {2} in {3}",
990 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name);
991
992 sp.ControllingClient.DebugPacketLevel = newDebug;
993 }
994 });
995 }
996 }
997 else
998 {
999 MainConsole.Instance.Output("Usage: debug lludp packet [--default | --all] 0..255 [<first-name> <last-name>]");
1000 }
1001 }
1002 }
1003
1004 private void HandleDropCommand(string module, string[] args)
1005 {
1006 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
1007 return;
1008
1009 if (args.Length != 6)
1010 {
1011 MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>");
1012 return;
1013 }
1014
1015 string direction = args[3];
1016 string subCommand = args[4];
1017 string packetName = args[5];
1018
1019 if (subCommand == "add")
1020 {
1021 MainConsole.Instance.OutputFormat(
1022 "Adding packet {0} to {1} drop list for all connections in {2}", direction, packetName, Scene.Name);
1023
1024 Scene.ForEachScenePresence(
1025 sp =>
1026 {
1027 LLClientView llcv = (LLClientView)sp.ControllingClient;
1028
1029 if (direction == "in")
1030 llcv.AddInPacketToDropSet(packetName);
1031 else if (direction == "out")
1032 llcv.AddOutPacketToDropSet(packetName);
1033 }
1034 );
1035 }
1036 else if (subCommand == "remove")
1037 {
1038 MainConsole.Instance.OutputFormat(
1039 "Removing packet {0} from {1} drop list for all connections in {2}", direction, packetName, Scene.Name);
1040
1041 Scene.ForEachScenePresence(
1042 sp =>
1043 {
1044 LLClientView llcv = (LLClientView)sp.ControllingClient;
1045
1046 if (direction == "in")
1047 llcv.RemoveInPacketFromDropSet(packetName);
1048 else if (direction == "out")
1049 llcv.RemoveOutPacketFromDropSet(packetName);
1050 }
1051 );
1052 }
1053 }
1054
1055 private void HandleStartCommand(string module, string[] args)
1056 {
1057 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
1058 return;
1059
1060 if (args.Length != 4)
1061 {
1062 MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
1063 return;
1064 }
1065
1066 string subCommand = args[3];
1067
1068 if (subCommand == "in" || subCommand == "all")
1069 StartInbound();
1070
1071 if (subCommand == "out" || subCommand == "all")
1072 StartOutbound();
1073 }
1074
1075 private void HandleStopCommand(string module, string[] args)
1076 {
1077 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
1078 return;
1079
1080 if (args.Length != 4)
1081 {
1082 MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
1083 return;
1084 }
1085
1086 string subCommand = args[3];
1087
1088 if (subCommand == "in" || subCommand == "all")
1089 StopInbound();
1090
1091 if (subCommand == "out" || subCommand == "all")
1092 StopOutbound();
1093 }
1094
1095 private void HandlePoolCommand(string module, string[] args)
1096 {
1097 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
1098 return;
1099
1100 if (args.Length != 4)
1101 {
1102 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
1103 return;
1104 }
1105
1106 string enabled = args[3];
1107
1108 if (enabled == "on")
1109 {
1110 if (EnablePools())
1111 {
1112 EnablePoolStats();
1113 MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", Scene.Name);
1114 }
1115 }
1116 else if (enabled == "off")
1117 {
1118 if (DisablePools())
1119 {
1120 DisablePoolStats();
1121 MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", Scene.Name);
1122 }
1123 }
1124 else
1125 {
1126 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
1127 }
1128 }
1129
1130 bool m_discardAgentUpdates;
1131
1132 private void HandleAgentUpdateCommand(string module, string[] args)
1133 {
1134 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
1135 return;
1136
1137 m_discardAgentUpdates = !m_discardAgentUpdates;
1138
1139 MainConsole.Instance.OutputFormat(
1140 "Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, Scene.Name);
1141 }
1142
1143 private void HandleStatusCommand(string module, string[] args)
1144 {
1145 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
1146 return;
1147
1148 MainConsole.Instance.OutputFormat(
1149 "IN LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningInbound ? "enabled" : "disabled");
1150
1151 MainConsole.Instance.OutputFormat(
1152 "OUT LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningOutbound ? "enabled" : "disabled");
1153
1154 MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", Scene.Name, UsePools ? "on" : "off");
1155
1156 MainConsole.Instance.OutputFormat(
1157 "Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel);
1158 } 699 }
1159 700
1160 public bool HandlesRegion(Location x) 701 public bool HandlesRegion(Location x)
@@ -1781,7 +1322,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1781 1322
1782 if (packet.Type == PacketType.AgentUpdate) 1323 if (packet.Type == PacketType.AgentUpdate)
1783 { 1324 {
1784 if (m_discardAgentUpdates) 1325 if (DiscardInboundAgentUpdates)
1785 return; 1326 return;
1786 1327
1787 ((LLClientView)client).TotalAgentUpdates++; 1328 ((LLClientView)client).TotalAgentUpdates++;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
new file mode 100644
index 0000000..5b23080
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
@@ -0,0 +1,518 @@
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.Collections.Generic;
30using NDesk.Options;
31using OpenSim.Framework;
32using OpenSim.Framework.Console;
33using OpenSim.Region.Framework.Scenes;
34
35namespace OpenSim.Region.ClientStack.LindenUDP
36{
37 public class LLUDPServerCommands
38 {
39 private ICommandConsole m_console;
40 private LLUDPServer m_udpServer;
41
42 public LLUDPServerCommands(ICommandConsole console, LLUDPServer udpServer)
43 {
44 m_console = console;
45 m_udpServer = udpServer;
46 }
47
48 public void Register()
49 {
50 m_console.Commands.AddCommand(
51 "Debug", false, "debug lludp packet",
52 "debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]",
53 "Turn on packet debugging. This logs information when the client stack hands a processed packet off to downstream code or when upstream code first requests that a certain packet be sent.",
54 "If level > 255 then all incoming and outgoing packets are logged.\n"
55 + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
56 + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
57 + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
58 + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
59 + "If level <= 0 then no packets are logged.\n"
60 + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
61 + "If --all is specified then the level becomes the default logging level for all current and subsequent agents.\n"
62 + "In these cases, you cannot also specify an avatar name.\n"
63 + "If an avatar name is given then only packets from that avatar are logged.",
64 HandlePacketCommand);
65
66 m_console.Commands.AddCommand(
67 "Debug", false, "debug lludp data out",
68 "debug lludp data out <level> <avatar-first-name> <avatar-last-name>\"",
69 "Turn on debugging for final outgoing data to the given user's client.",
70 "This operates at a much lower level than the packet command and prints out available details when the data is actually sent.\n"
71 + "If level > 0 then information about all outgoing UDP data for this avatar is logged.\n"
72 + "If level <= 0 then no information about outgoing UDP data for this avatar is logged.",
73 HandleDataCommand);
74
75 m_console.Commands.AddCommand(
76 "Debug", false, "debug lludp drop",
77 "debug lludp drop <in|out> <add|remove> <packet-name>",
78 "Drop all in or outbound packets that match the given name",
79 "For test purposes.",
80 HandleDropCommand);
81
82 m_console.Commands.AddCommand(
83 "Debug",
84 false,
85 "debug lludp start",
86 "debug lludp start <in|out|all>",
87 "Control LLUDP packet processing.",
88 "No effect if packet processing has already started.\n"
89 + "in - start inbound processing.\n"
90 + "out - start outbound processing.\n"
91 + "all - start in and outbound processing.\n",
92 HandleStartCommand);
93
94 m_console.Commands.AddCommand(
95 "Debug",
96 false,
97 "debug lludp stop",
98 "debug lludp stop <in|out|all>",
99 "Stop LLUDP packet processing.",
100 "No effect if packet processing has already stopped.\n"
101 + "in - stop inbound processing.\n"
102 + "out - stop outbound processing.\n"
103 + "all - stop in and outbound processing.\n",
104 HandleStopCommand);
105
106 m_console.Commands.AddCommand(
107 "Debug",
108 false,
109 "debug lludp pool",
110 "debug lludp pool <on|off>",
111 "Turn object pooling within the lludp component on or off.",
112 HandlePoolCommand);
113
114 m_console.Commands.AddCommand(
115 "Debug",
116 false,
117 "debug lludp status",
118 "debug lludp status",
119 "Return status of LLUDP packet processing.",
120 HandleStatusCommand);
121
122 m_console.Commands.AddCommand(
123 "Debug",
124 false,
125 "debug lludp throttle log",
126 "debug lludp throttle log <level> <avatar-first-name> <avatar-last-name>",
127 "Change debug logging level for throttles.",
128 "If level >= 0 then throttle debug logging is performed.\n"
129 + "If level <= 0 then no throttle debug logging is performed.",
130 HandleThrottleCommand);
131
132 m_console.Commands.AddCommand(
133 "Debug",
134 false,
135 "debug lludp throttle get",
136 "debug lludp throttle get <avatar-first-name> <avatar-last-name>",
137 "Return debug settings for throttles.",
138 HandleThrottleGetCommand);
139
140 m_console.Commands.AddCommand(
141 "Debug",
142 false,
143 "debug lludp throttle set",
144 "debug lludp throttle set <param> <value> <avatar-first-name> <avatar-last-name>",
145 "Set a throttle parameter for the given client.",
146 "Only current setting is 'adaptive' which must be 'true' or 'false'",
147 HandleThrottleSetCommand);
148
149 m_console.Commands.AddCommand(
150 "Debug",
151 false,
152 "debug lludp toggle agentupdate",
153 "debug lludp toggle agentupdate",
154 "Toggle whether agentupdate packets are processed or simply discarded.",
155 HandleAgentUpdateCommand);
156 }
157
158 private void HandleDataCommand(string module, string[] args)
159 {
160 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
161 return;
162
163 if (args.Length != 7)
164 {
165 MainConsole.Instance.OutputFormat("Usage: debug lludp data out <true|false> <avatar-first-name> <avatar-last-name>");
166 return;
167 }
168
169 int level;
170 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
171 return;
172
173 string firstName = args[5];
174 string lastName = args[6];
175
176 m_udpServer.Scene.ForEachScenePresence(sp =>
177 {
178 if (sp.Firstname == firstName && sp.Lastname == lastName)
179 {
180 MainConsole.Instance.OutputFormat(
181 "Data debug for {0} ({1}) set to {2} in {3}",
182 sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
183
184 ((LLClientView)sp.ControllingClient).UDPClient.DebugDataOutLevel = level;
185 }
186 });
187 }
188
189 private void HandleThrottleCommand(string module, string[] args)
190 {
191 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
192 return;
193
194 if (args.Length != 7)
195 {
196 MainConsole.Instance.OutputFormat("Usage: debug lludp throttle log <level> <avatar-first-name> <avatar-last-name>");
197 return;
198 }
199
200 int level;
201 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
202 return;
203
204 string firstName = args[5];
205 string lastName = args[6];
206
207 m_udpServer.Scene.ForEachScenePresence(sp =>
208 {
209 if (sp.Firstname == firstName && sp.Lastname == lastName)
210 {
211 MainConsole.Instance.OutputFormat(
212 "Throttle log level for {0} ({1}) set to {2} in {3}",
213 sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
214
215 ((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level;
216 }
217 });
218 }
219
220 private void HandleThrottleSetCommand(string module, string[] args)
221 {
222 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
223 return;
224
225 if (args.Length != 8)
226 {
227 MainConsole.Instance.OutputFormat(
228 "Usage: debug lludp throttle set <param> <value> <avatar-first-name> <avatar-last-name>");
229 return;
230 }
231
232 string param = args[4];
233 string rawValue = args[5];
234 string firstName = args[6];
235 string lastName = args[7];
236
237 if (param == "adaptive")
238 {
239 bool newValue;
240 if (!ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, rawValue, out newValue))
241 return;
242
243 m_udpServer.Scene.ForEachScenePresence(sp =>
244 {
245 if (sp.Firstname == firstName && sp.Lastname == lastName)
246 {
247 MainConsole.Instance.OutputFormat(
248 "Setting param {0} to {1} for {2} ({3}) in {4}",
249 param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
250
251 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
252 udpClient.FlowThrottle.Enabled = newValue;
253 // udpClient.FlowThrottle.MaxDripRate = 0;
254 // udpClient.FlowThrottle.AdjustedDripRate = 0;
255 }
256 });
257 }
258 }
259
260 private void HandleThrottleGetCommand(string module, string[] args)
261 {
262 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
263 return;
264
265 if (args.Length != 6)
266 {
267 MainConsole.Instance.OutputFormat("Usage: debug lludp throttle get <avatar-first-name> <avatar-last-name>");
268 return;
269 }
270
271 string firstName = args[4];
272 string lastName = args[5];
273
274 m_udpServer.Scene.ForEachScenePresence(sp =>
275 {
276 if (sp.Firstname == firstName && sp.Lastname == lastName)
277 {
278 MainConsole.Instance.OutputFormat(
279 "Status for {0} ({1}) in {2}",
280 sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
281
282 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
283 MainConsole.Instance.OutputFormat("Adaptive throttle: {0}", udpClient.FlowThrottle.Enabled);
284 }
285 });
286 }
287
288 private void HandlePacketCommand(string module, string[] args)
289 {
290 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
291 return;
292
293 bool setAsDefaultLevel = false;
294 bool setAll = false;
295 OptionSet optionSet = new OptionSet()
296 .Add("default", o => setAsDefaultLevel = (o != null))
297 .Add("all", o => setAll = (o != null));
298 List<string> filteredArgs = optionSet.Parse(args);
299
300 string name = null;
301
302 if (filteredArgs.Count == 6)
303 {
304 if (!(setAsDefaultLevel || setAll))
305 {
306 name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
307 }
308 else
309 {
310 MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default/all logging level");
311 return;
312 }
313 }
314
315 if (filteredArgs.Count > 3)
316 {
317 int newDebug;
318 if (int.TryParse(filteredArgs[3], out newDebug))
319 {
320 if (setAsDefaultLevel || setAll)
321 {
322 m_udpServer.DefaultClientPacketDebugLevel = newDebug;
323
324 MainConsole.Instance.OutputFormat(
325 "Packet debug for {0} clients set to {1} in {2}",
326 (setAll ? "all" : "future"), m_udpServer.DefaultClientPacketDebugLevel, m_udpServer.Scene.Name);
327
328 if (setAll)
329 {
330 m_udpServer.Scene.ForEachScenePresence(sp =>
331 {
332 MainConsole.Instance.OutputFormat(
333 "Packet debug for {0} ({1}) set to {2} in {3}",
334 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
335
336 sp.ControllingClient.DebugPacketLevel = newDebug;
337 });
338 }
339 }
340 else
341 {
342 m_udpServer.Scene.ForEachScenePresence(sp =>
343 {
344 if (name == null || sp.Name == name)
345 {
346 MainConsole.Instance.OutputFormat(
347 "Packet debug for {0} ({1}) set to {2} in {3}",
348 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
349
350 sp.ControllingClient.DebugPacketLevel = newDebug;
351 }
352 });
353 }
354 }
355 else
356 {
357 MainConsole.Instance.Output("Usage: debug lludp packet [--default | --all] 0..255 [<first-name> <last-name>]");
358 }
359 }
360 }
361
362 private void HandleDropCommand(string module, string[] args)
363 {
364 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
365 return;
366
367 if (args.Length != 6)
368 {
369 MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>");
370 return;
371 }
372
373 string direction = args[3];
374 string subCommand = args[4];
375 string packetName = args[5];
376
377 if (subCommand == "add")
378 {
379 MainConsole.Instance.OutputFormat(
380 "Adding packet {0} to {1} drop list for all connections in {2}",
381 direction, packetName, m_udpServer.Scene.Name);
382
383 m_udpServer.Scene.ForEachScenePresence(
384 sp =>
385 {
386 LLClientView llcv = (LLClientView)sp.ControllingClient;
387
388 if (direction == "in")
389 llcv.AddInPacketToDropSet(packetName);
390 else if (direction == "out")
391 llcv.AddOutPacketToDropSet(packetName);
392 }
393 );
394 }
395 else if (subCommand == "remove")
396 {
397 MainConsole.Instance.OutputFormat(
398 "Removing packet {0} from {1} drop list for all connections in {2}",
399 direction, packetName, m_udpServer.Scene.Name);
400
401 m_udpServer.Scene.ForEachScenePresence(
402 sp =>
403 {
404 LLClientView llcv = (LLClientView)sp.ControllingClient;
405
406 if (direction == "in")
407 llcv.RemoveInPacketFromDropSet(packetName);
408 else if (direction == "out")
409 llcv.RemoveOutPacketFromDropSet(packetName);
410 }
411 );
412 }
413 }
414
415 private void HandleStartCommand(string module, string[] args)
416 {
417 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
418 return;
419
420 if (args.Length != 4)
421 {
422 MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
423 return;
424 }
425
426 string subCommand = args[3];
427
428 if (subCommand == "in" || subCommand == "all")
429 m_udpServer.StartInbound();
430
431 if (subCommand == "out" || subCommand == "all")
432 m_udpServer.StartOutbound();
433 }
434
435 private void HandleStopCommand(string module, string[] args)
436 {
437 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
438 return;
439
440 if (args.Length != 4)
441 {
442 MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
443 return;
444 }
445
446 string subCommand = args[3];
447
448 if (subCommand == "in" || subCommand == "all")
449 m_udpServer.StopInbound();
450
451 if (subCommand == "out" || subCommand == "all")
452 m_udpServer.StopOutbound();
453 }
454
455 private void HandlePoolCommand(string module, string[] args)
456 {
457 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
458 return;
459
460 if (args.Length != 4)
461 {
462 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
463 return;
464 }
465
466 string enabled = args[3];
467
468 if (enabled == "on")
469 {
470 if (m_udpServer.EnablePools())
471 {
472 m_udpServer.EnablePoolStats();
473 MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name);
474 }
475 }
476 else if (enabled == "off")
477 {
478 if (m_udpServer.DisablePools())
479 {
480 m_udpServer.DisablePoolStats();
481 MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name);
482 }
483 }
484 else
485 {
486 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
487 }
488 }
489
490 private void HandleAgentUpdateCommand(string module, string[] args)
491 {
492 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
493 return;
494
495 m_udpServer.DiscardInboundAgentUpdates = !m_udpServer.DiscardInboundAgentUpdates;
496
497 MainConsole.Instance.OutputFormat(
498 "Discard AgentUpdates now {0} for {1}", m_udpServer.DiscardInboundAgentUpdates, m_udpServer.Scene.Name);
499 }
500
501 private void HandleStatusCommand(string module, string[] args)
502 {
503 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
504 return;
505
506 MainConsole.Instance.OutputFormat(
507 "IN LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningInbound ? "enabled" : "disabled");
508
509 MainConsole.Instance.OutputFormat(
510 "OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled");
511
512 MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off");
513
514 MainConsole.Instance.OutputFormat(
515 "Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel);
516 }
517 }
518} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 88494be..5323d5a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -135,7 +135,7 @@ namespace OpenMetaverse
135 /// manner (not throwing an exception when the remote side resets the 135 /// manner (not throwing an exception when the remote side resets the
136 /// connection). This call is ignored on Mono where the flag is not 136 /// connection). This call is ignored on Mono where the flag is not
137 /// necessary</remarks> 137 /// necessary</remarks>
138 public void StartInbound(int recvBufferSize, bool asyncPacketHandling) 138 public virtual void StartInbound(int recvBufferSize, bool asyncPacketHandling)
139 { 139 {
140 m_asyncPacketHandling = asyncPacketHandling; 140 m_asyncPacketHandling = asyncPacketHandling;
141 141
@@ -185,14 +185,14 @@ namespace OpenMetaverse
185 /// <summary> 185 /// <summary>
186 /// Start outbound UDP packet handling. 186 /// Start outbound UDP packet handling.
187 /// </summary> 187 /// </summary>
188 public void StartOutbound() 188 public virtual void StartOutbound()
189 { 189 {
190 m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop"); 190 m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop");
191 191
192 IsRunningOutbound = true; 192 IsRunningOutbound = true;
193 } 193 }
194 194
195 public void StopInbound() 195 public virtual void StopInbound()
196 { 196 {
197 if (IsRunningInbound) 197 if (IsRunningInbound)
198 { 198 {
@@ -203,14 +203,14 @@ namespace OpenMetaverse
203 } 203 }
204 } 204 }
205 205
206 public void StopOutbound() 206 public virtual void StopOutbound()
207 { 207 {
208 m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop"); 208 m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop");
209 209
210 IsRunningOutbound = false; 210 IsRunningOutbound = false;
211 } 211 }
212 212
213 protected virtual bool EnablePools() 213 public virtual bool EnablePools()
214 { 214 {
215 if (!UsePools) 215 if (!UsePools)
216 { 216 {
@@ -224,7 +224,7 @@ namespace OpenMetaverse
224 return false; 224 return false;
225 } 225 }
226 226
227 protected virtual bool DisablePools() 227 public virtual bool DisablePools()
228 { 228 {
229 if (UsePools) 229 if (UsePools)
230 { 230 {