aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs198
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs19
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs54
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs21
4 files changed, 115 insertions, 177 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index f6a7a0c..db0c3b8 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -37,6 +37,7 @@ using System.Xml;
37using log4net; 37using log4net;
38using OpenMetaverse; 38using OpenMetaverse;
39using OpenMetaverse.Packets; 39using OpenMetaverse.Packets;
40using OpenMetaverse.StructuredData;
40using OpenSim.Framework; 41using OpenSim.Framework;
41using OpenSim.Framework.Client; 42using OpenSim.Framework.Client;
42using OpenSim.Framework.Communications.Cache; 43using OpenSim.Framework.Communications.Cache;
@@ -314,14 +315,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
314 private readonly LLUDPClient m_udpClient; 315 private readonly LLUDPClient m_udpClient;
315 private readonly UUID m_sessionId; 316 private readonly UUID m_sessionId;
316 private readonly UUID m_secureSessionId; 317 private readonly UUID m_secureSessionId;
317 private readonly UUID m_agentId; 318 protected readonly UUID m_agentId;
318 private readonly uint m_circuitCode; 319 private readonly uint m_circuitCode;
319 private readonly byte[] m_channelVersion = Utils.EmptyBytes; 320 private readonly byte[] m_channelVersion = Utils.EmptyBytes;
320 private readonly Dictionary<string, UUID> m_defaultAnimations = new Dictionary<string, UUID>(); 321 private readonly Dictionary<string, UUID> m_defaultAnimations = new Dictionary<string, UUID>();
321 private readonly IGroupsModule m_GroupsModule; 322 private readonly IGroupsModule m_GroupsModule;
322 323
323 private int m_cachedTextureSerial; 324 private int m_cachedTextureSerial;
324 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates; 325 protected PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates;
325 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates; 326 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates;
326 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates; 327 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates;
327 private int m_moneyBalance; 328 private int m_moneyBalance;
@@ -1856,7 +1857,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1856 economyData.Info.TeleportMinPrice = TeleportMinPrice; 1857 economyData.Info.TeleportMinPrice = TeleportMinPrice;
1857 economyData.Info.TeleportPriceExponent = TeleportPriceExponent; 1858 economyData.Info.TeleportPriceExponent = TeleportPriceExponent;
1858 economyData.Header.Reliable = true; 1859 economyData.Header.Reliable = true;
1859 OutPacket(economyData, ThrottleOutPacketType.Unknown); 1860 OutPacket(economyData, ThrottleOutPacketType.Task);
1860 } 1861 }
1861 1862
1862 public void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data) 1863 public void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data)
@@ -2786,30 +2787,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2786 2787
2787 public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data) 2788 public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data)
2788 { 2789 {
2789 AvatarGroupsReplyPacket p = (AvatarGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarGroupsReply); 2790 OSDMap llsd = new OSDMap(3);
2790 2791 OSDArray AgentData = new OSDArray(1);
2791 p.AgentData = new AvatarGroupsReplyPacket.AgentDataBlock(); 2792 OSDMap AgentDataMap = new OSDMap(1);
2792 p.AgentData.AgentID = AgentId; 2793 AgentDataMap.Add("AgentID", OSD.FromUUID(this.AgentId));
2793 p.AgentData.AvatarID = avatarID; 2794 AgentDataMap.Add("AvatarID", OSD.FromUUID(avatarID));
2794 2795 AgentData.Add(AgentDataMap);
2795 p.GroupData = new AvatarGroupsReplyPacket.GroupDataBlock[data.Length]; 2796 llsd.Add("AgentData", AgentData);
2796 int i = 0; 2797 OSDArray GroupData = new OSDArray(data.Length);
2797 foreach (GroupMembershipData m in data) 2798 OSDArray NewGroupData = new OSDArray(data.Length);
2798 { 2799 foreach (GroupMembershipData m in data)
2799 p.GroupData[i] = new AvatarGroupsReplyPacket.GroupDataBlock(); 2800 {
2800 p.GroupData[i].GroupPowers = m.GroupPowers; 2801 OSDMap GroupDataMap = new OSDMap(6);
2801 p.GroupData[i].AcceptNotices = m.AcceptNotices; 2802 OSDMap NewGroupDataMap = new OSDMap(1);
2802 p.GroupData[i].GroupTitle = Utils.StringToBytes(m.GroupTitle); 2803 GroupDataMap.Add("GroupPowers", OSD.FromBinary(m.GroupPowers));
2803 p.GroupData[i].GroupID = m.GroupID; 2804 GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(m.AcceptNotices));
2804 p.GroupData[i].GroupName = Utils.StringToBytes(m.GroupName); 2805 GroupDataMap.Add("GroupTitle", OSD.FromString(m.GroupTitle));
2805 p.GroupData[i].GroupInsigniaID = m.GroupPicture; 2806 GroupDataMap.Add("GroupID", OSD.FromUUID(m.GroupID));
2806 i++; 2807 GroupDataMap.Add("GroupName", OSD.FromString(m.GroupName));
2807 } 2808 GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(m.GroupPicture));
2808 2809 NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(m.ListInProfile));
2809 p.NewGroupData = new AvatarGroupsReplyPacket.NewGroupDataBlock(); 2810 GroupData.Add(GroupDataMap);
2810 p.NewGroupData.ListInProfile = true; 2811 NewGroupData.Add(NewGroupDataMap);
2811 2812 }
2812 OutPacket(p, ThrottleOutPacketType.Task); 2813 llsd.Add("GroupData", GroupData);
2814 llsd.Add("NewGroupData", NewGroupData);
2815
2816 IEventQueue eq = this.Scene.RequestModuleInterface<IEventQueue>();
2817 if (eq != null)
2818 {
2819 eq.Enqueue(BuildEvent("AvatarGroupsReply", llsd), this.AgentId);
2820 }
2813 } 2821 }
2814 2822
2815 public void SendJoinGroupReply(UUID groupID, bool success) 2823 public void SendJoinGroupReply(UUID groupID, bool success)
@@ -3168,107 +3176,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3168 3176
3169 #endregion 3177 #endregion
3170 3178
3171 #region Prim/Avatar Updates
3172
3173 /*void SendObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3174 {
3175 bool canUseCompressed, canUseImproved;
3176 UpdateFlagsToPacketType(creatorFlags, updateFlags, out canUseCompressed, out canUseImproved);
3177
3178 if (!canUseImproved && !canUseCompressed)
3179 SendFullObjectUpdate(obj, creatorFlags, updateFlags);
3180 else if (!canUseImproved)
3181 SendObjectUpdateCompressed(obj, creatorFlags, updateFlags);
3182 else
3183 SendImprovedTerseObjectUpdate(obj, creatorFlags, updateFlags);
3184 }
3185
3186 void SendFullObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3187 {
3188 IClientAPI owner;
3189 if (m_scene.ClientManager.TryGetValue(obj.OwnerID, out owner) && owner is LLClientView)
3190 {
3191 LLClientView llOwner = (LLClientView)owner;
3192
3193 // Send an update out to the owner
3194 ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket();
3195 updateToOwner.RegionData.RegionHandle = obj.RegionHandle;
3196 //updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue);
3197 updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3198 updateToOwner.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags | creatorFlags | PrimFlags.ObjectYouOwner, 0);
3199
3200 m_udpServer.SendPacket(llOwner.UDPClient, updateToOwner, ThrottleOutPacketType.State, true);
3201 }
3202
3203 // Send an update out to everyone else
3204 ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket();
3205 updateToOthers.RegionData.RegionHandle = obj.RegionHandle;
3206 //updateToOthers.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue);
3207 updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3208 updateToOthers.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags, 0);
3209
3210 m_scene.ClientManager.ForEach(
3211 delegate(IClientAPI client)
3212 {
3213 if (client.AgentId != obj.OwnerID && client is LLClientView)
3214 {
3215 LLClientView llClient = (LLClientView)client;
3216 m_udpServer.SendPacket(llClient.UDPClient, updateToOthers, ThrottleOutPacketType.State, true);
3217 }
3218 }
3219 );
3220 }
3221
3222 void SendObjectUpdateCompressed(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3223 {
3224 }
3225
3226 void SendImprovedTerseObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3227 {
3228 }
3229
3230 void UpdateFlagsToPacketType(PrimFlags creatorFlags, PrimUpdateFlags updateFlags, out bool canUseCompressed, out bool canUseImproved)
3231 {
3232 canUseCompressed = true;
3233 canUseImproved = true;
3234
3235 if ((updateFlags & PrimUpdateFlags.FullUpdate) == PrimUpdateFlags.FullUpdate || creatorFlags != PrimFlags.None)
3236 {
3237 canUseCompressed = false;
3238 canUseImproved = false;
3239 }
3240 else
3241 {
3242 if ((updateFlags & PrimUpdateFlags.Velocity) != 0 ||
3243 (updateFlags & PrimUpdateFlags.Acceleration) != 0 ||
3244 (updateFlags & PrimUpdateFlags.CollisionPlane) != 0 ||
3245 (updateFlags & PrimUpdateFlags.Joint) != 0)
3246 {
3247 canUseCompressed = false;
3248 }
3249
3250 if ((updateFlags & PrimUpdateFlags.PrimFlags) != 0 ||
3251 (updateFlags & PrimUpdateFlags.ParentID) != 0 ||
3252 (updateFlags & PrimUpdateFlags.Scale) != 0 ||
3253 (updateFlags & PrimUpdateFlags.PrimData) != 0 ||
3254 (updateFlags & PrimUpdateFlags.Text) != 0 ||
3255 (updateFlags & PrimUpdateFlags.NameValue) != 0 ||
3256 (updateFlags & PrimUpdateFlags.ExtraData) != 0 ||
3257 (updateFlags & PrimUpdateFlags.TextureAnim) != 0 ||
3258 (updateFlags & PrimUpdateFlags.Sound) != 0 ||
3259 (updateFlags & PrimUpdateFlags.Particles) != 0 ||
3260 (updateFlags & PrimUpdateFlags.Material) != 0 ||
3261 (updateFlags & PrimUpdateFlags.ClickAction) != 0 ||
3262 (updateFlags & PrimUpdateFlags.MediaURL) != 0 ||
3263 (updateFlags & PrimUpdateFlags.Joint) != 0)
3264 {
3265 canUseImproved = false;
3266 }
3267 }
3268 }*/
3269
3270 #endregion Prim/Avatar Updates
3271
3272 #region Avatar Packet/Data Sending Methods 3179 #region Avatar Packet/Data Sending Methods
3273 3180
3274 /// <summary> 3181 /// <summary>
@@ -3314,7 +3221,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3314 ProcessAvatarTerseUpdates(); 3221 ProcessAvatarTerseUpdates();
3315 } 3222 }
3316 3223
3317 private void ProcessAvatarTerseUpdates() 3224 protected void ProcessAvatarTerseUpdates()
3318 { 3225 {
3319 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3226 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3320 terse.Header.Reliable = false; 3227 terse.Header.Reliable = false;
@@ -3335,6 +3242,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3335 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); 3242 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3336 } 3243 }
3337 3244
3245 // HACK: Using the task category until the tiered reprioritization code is in
3338 OutPacket(terse, ThrottleOutPacketType.Task); 3246 OutPacket(terse, ThrottleOutPacketType.Task);
3339 } 3247 }
3340 3248
@@ -4430,11 +4338,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4430 /// </summary> 4338 /// </summary>
4431 protected virtual void RegisterLocalPacketHandlers() 4339 protected virtual void RegisterLocalPacketHandlers()
4432 { 4340 {
4433 AddLocalPacketHandler(PacketType.LogoutRequest, Logout); 4341 AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout);
4434 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate); 4342 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate);
4435 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect); 4343 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect);
4436 AddLocalPacketHandler(PacketType.AgentCachedTexture, AgentTextureCached); 4344 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached);
4437 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, MultipleObjUpdate); 4345 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate);
4438 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest); 4346 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest);
4439 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest); 4347 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest);
4440 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); 4348 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
@@ -4703,7 +4611,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4703 /// <param name="client"></param> 4611 /// <param name="client"></param>
4704 /// <param name="packet"></param> 4612 /// <param name="packet"></param>
4705 /// <returns></returns> 4613 /// <returns></returns>
4706 protected virtual bool Logout(IClientAPI client, Packet packet) 4614 protected virtual bool HandleLogout(IClientAPI client, Packet packet)
4707 { 4615 {
4708 if (packet.Type == PacketType.LogoutRequest) 4616 if (packet.Type == PacketType.LogoutRequest)
4709 { 4617 {
@@ -4741,7 +4649,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4741 /// <param name="simclient"></param> 4649 /// <param name="simclient"></param>
4742 /// <param name="packet"></param> 4650 /// <param name="packet"></param>
4743 /// <returns></returns> 4651 /// <returns></returns>
4744 protected bool AgentTextureCached(IClientAPI simclient, Packet packet) 4652 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
4745 { 4653 {
4746 //m_log.Debug("texture cached: " + packet.ToString()); 4654 //m_log.Debug("texture cached: " + packet.ToString());
4747 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; 4655 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
@@ -4771,7 +4679,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4771 return true; 4679 return true;
4772 } 4680 }
4773 4681
4774 protected bool MultipleObjUpdate(IClientAPI simClient, Packet packet) 4682 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet)
4775 { 4683 {
4776 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; 4684 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
4777 if (multipleupdate.AgentData.SessionID != SessionId) return false; 4685 if (multipleupdate.AgentData.SessionID != SessionId) return false;
@@ -5050,7 +4958,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5050 /// </summary> 4958 /// </summary>
5051 /// <param name="packet">Packet to send</param> 4959 /// <param name="packet">Packet to send</param>
5052 /// <param name="throttlePacketType">Throttling category for the packet</param> 4960 /// <param name="throttlePacketType">Throttling category for the packet</param>
5053 private void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) 4961 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType)
5054 { 4962 {
5055 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); 4963 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true);
5056 } 4964 }
@@ -9944,7 +9852,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9944 commandMessagePacket.CommandBlock.Command = (uint)command; 9852 commandMessagePacket.CommandBlock.Command = (uint)command;
9945 commandMessagePacket.CommandBlock.Time = time; 9853 commandMessagePacket.CommandBlock.Time = time;
9946 9854
9947 OutPacket(commandMessagePacket, ThrottleOutPacketType.Unknown); 9855 OutPacket(commandMessagePacket, ThrottleOutPacketType.Task);
9948 } 9856 }
9949 9857
9950 public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID, 9858 public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID,
@@ -9962,7 +9870,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9962 updatePacket.DataBlockExtended.MediaHeight = mediaHeight; 9870 updatePacket.DataBlockExtended.MediaHeight = mediaHeight;
9963 updatePacket.DataBlockExtended.MediaLoop = mediaLoop; 9871 updatePacket.DataBlockExtended.MediaLoop = mediaLoop;
9964 9872
9965 OutPacket(updatePacket, ThrottleOutPacketType.Unknown); 9873 OutPacket(updatePacket, ThrottleOutPacketType.Task);
9966 } 9874 }
9967 9875
9968 #endregion 9876 #endregion
@@ -10236,7 +10144,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10236 } 10144 }
10237 10145
10238 #region PriorityQueue 10146 #region PriorityQueue
10239 private class PriorityQueue<TPriority, TValue> 10147 public class PriorityQueue<TPriority, TValue>
10240 { 10148 {
10241 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id); 10149 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id);
10242 10150
@@ -10264,7 +10172,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10264 this.m_comparison = comparison; 10172 this.m_comparison = comparison;
10265 } 10173 }
10266 10174
10267 internal object SyncRoot { get { return this.m_syncRoot; } } 10175 public object SyncRoot { get { return this.m_syncRoot; } }
10268 internal int Count 10176 internal int Count
10269 { 10177 {
10270 get 10178 get
@@ -10276,7 +10184,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10276 } 10184 }
10277 } 10185 }
10278 10186
10279 internal bool Enqueue(TPriority priority, TValue value, uint local_id) 10187 public bool Enqueue(TPriority priority, TValue value, uint local_id)
10280 { 10188 {
10281 LookupItem item; 10189 LookupItem item;
10282 10190
@@ -10396,5 +10304,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10396 } 10304 }
10397 #endregion 10305 #endregion
10398 10306
10307 public static OSD BuildEvent(string eventName, OSD eventBody)
10308 {
10309 OSDMap osdEvent = new OSDMap(2);
10310 osdEvent.Add("message", new OSDString(eventName));
10311 osdEvent.Add("body", eventBody);
10312
10313 return osdEvent;
10314 }
10399 } 10315 }
10400} 10316}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index 84a4959..9856a1c 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -135,8 +135,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
135 private readonly TokenBucket m_throttle; 135 private readonly TokenBucket m_throttle;
136 /// <summary>Throttle buckets for each packet category</summary> 136 /// <summary>Throttle buckets for each packet category</summary>
137 private readonly TokenBucket[] m_throttleCategories; 137 private readonly TokenBucket[] m_throttleCategories;
138 /// <summary>Throttle rate defaults and limits</summary>
139 private readonly ThrottleRates m_defaultThrottleRates;
140 /// <summary>Outgoing queues for throttled packets</summary> 138 /// <summary>Outgoing queues for throttled packets</summary>
141 private readonly OpenSim.Framework.LocklessQueue<OutgoingPacket>[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT]; 139 private readonly OpenSim.Framework.LocklessQueue<OutgoingPacket>[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT];
142 /// <summary>A container that can hold one packet for each outbox, used to store 140 /// <summary>A container that can hold one packet for each outbox, used to store
@@ -145,6 +143,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
145 /// <summary>A reference to the LLUDPServer that is managing this client</summary> 143 /// <summary>A reference to the LLUDPServer that is managing this client</summary>
146 private readonly LLUDPServer m_udpServer; 144 private readonly LLUDPServer m_udpServer;
147 145
146 private int m_defaultRTO = 3000;
147 private int m_maxRTO = 60000;
148
148 /// <summary> 149 /// <summary>
149 /// Default constructor 150 /// Default constructor
150 /// </summary> 151 /// </summary>
@@ -155,13 +156,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
155 /// <param name="circuitCode">Circuit code for this connection</param> 156 /// <param name="circuitCode">Circuit code for this connection</param>
156 /// <param name="agentID">AgentID for the connected agent</param> 157 /// <param name="agentID">AgentID for the connected agent</param>
157 /// <param name="remoteEndPoint">Remote endpoint for this connection</param> 158 /// <param name="remoteEndPoint">Remote endpoint for this connection</param>
158 public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint) 159 public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
159 { 160 {
160 AgentID = agentID; 161 AgentID = agentID;
161 RemoteEndPoint = remoteEndPoint; 162 RemoteEndPoint = remoteEndPoint;
162 CircuitCode = circuitCode; 163 CircuitCode = circuitCode;
163 m_udpServer = server; 164 m_udpServer = server;
164 m_defaultThrottleRates = rates; 165 if (defaultRTO != 0)
166 m_defaultRTO = defaultRTO;
167 if (maxRTO != 0)
168 m_maxRTO = maxRTO;
169
165 // Create a token bucket throttle for this client that has the scene token bucket as a parent 170 // Create a token bucket throttle for this client that has the scene token bucket as a parent
166 m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total); 171 m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total);
167 // Create an array of token buckets for this clients different throttle categories 172 // Create an array of token buckets for this clients different throttle categories
@@ -178,7 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
178 } 183 }
179 184
180 // Default the retransmission timeout to three seconds 185 // Default the retransmission timeout to three seconds
181 RTO = 3000; 186 RTO = m_defaultRTO;
182 187
183 // Initialize this to a sane value to prevent early disconnects 188 // Initialize this to a sane value to prevent early disconnects
184 TickLastPacketReceived = Environment.TickCount & Int32.MaxValue; 189 TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
@@ -500,7 +505,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
500 int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)); 505 int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR));
501 506
502 // Clamp the retransmission timeout to manageable values 507 // Clamp the retransmission timeout to manageable values
503 rto = Utils.Clamp(RTO, 3000, 60000); 508 rto = Utils.Clamp(RTO, m_defaultRTO, m_maxRTO);
504 509
505 RTO = rto; 510 RTO = rto;
506 511
@@ -520,7 +525,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
520 RTTVAR = 0.0f; 525 RTTVAR = 0.0f;
521 526
522 // Double the retransmission timeout 527 // Double the retransmission timeout
523 RTO = Math.Min(RTO * 2, 60000); 528 RTO = Math.Min(RTO * 2, m_maxRTO);
524 } 529 }
525 530
526 /// <summary> 531 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index e3233da..93946ae 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -118,13 +118,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
118 /// <summary></summary> 118 /// <summary></summary>
119 //private UDPClientCollection m_clients = new UDPClientCollection(); 119 //private UDPClientCollection m_clients = new UDPClientCollection();
120 /// <summary>Bandwidth throttle for this UDP server</summary> 120 /// <summary>Bandwidth throttle for this UDP server</summary>
121 private TokenBucket m_throttle; 121 protected TokenBucket m_throttle;
122 /// <summary>Bandwidth throttle rates for this UDP server</summary> 122 /// <summary>Bandwidth throttle rates for this UDP server</summary>
123 private ThrottleRates m_throttleRates; 123 protected ThrottleRates m_throttleRates;
124 /// <summary>Manages authentication for agent circuits</summary> 124 /// <summary>Manages authentication for agent circuits</summary>
125 private AgentCircuitManager m_circuitManager; 125 private AgentCircuitManager m_circuitManager;
126 /// <summary>Reference to the scene this UDP server is attached to</summary> 126 /// <summary>Reference to the scene this UDP server is attached to</summary>
127 private Scene m_scene; 127 protected Scene m_scene;
128 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> 128 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
129 private Location m_location; 129 private Location m_location;
130 /// <summary>The size of the receive buffer for the UDP socket. This value 130 /// <summary>The size of the receive buffer for the UDP socket. This value
@@ -153,6 +153,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
153 /// <summary>Flag to signal when clients should send pings</summary> 153 /// <summary>Flag to signal when clients should send pings</summary>
154 private bool m_sendPing; 154 private bool m_sendPing;
155 155
156 private int m_defaultRTO = 0;
157 private int m_maxRTO = 0;
158
156 public Socket Server { get { return null; } } 159 public Socket Server { get { return null; } }
157 160
158 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) 161 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
@@ -189,6 +192,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
189 AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10); 192 AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10);
190 PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100); 193 PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100);
191 TextureSendLimit = config.GetInt("TextureSendLimit", 20); 194 TextureSendLimit = config.GetInt("TextureSendLimit", 20);
195
196 m_defaultRTO = config.GetInt("DefaultRTO", 0);
197 m_maxRTO = config.GetInt("MaxRTO", 0);
192 } 198 }
193 else 199 else
194 { 200 {
@@ -247,8 +253,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
247 253
248 public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting) 254 public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting)
249 { 255 {
250 // CoarseLocationUpdate packets cannot be split in an automated way 256 // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way
251 if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting) 257 if ((packet.Type == PacketType.CoarseLocationUpdate || packet.Type == PacketType.AvatarGroupsReply) && allowSplitting)
252 allowSplitting = false; 258 allowSplitting = false;
253 259
254 if (allowSplitting && packet.HasVariableBlocks) 260 if (allowSplitting && packet.HasVariableBlocks)
@@ -256,8 +262,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 byte[][] datas = packet.ToBytesMultiple(); 262 byte[][] datas = packet.ToBytesMultiple();
257 int packetCount = datas.Length; 263 int packetCount = datas.Length;
258 264
259 //if (packetCount > 1) 265 if (packetCount < 1)
260 // m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); 266 m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length);
261 267
262 for (int i = 0; i < packetCount; i++) 268 for (int i = 0; i < packetCount; i++)
263 { 269 {
@@ -295,8 +301,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
295 byte[][] datas = packet.ToBytesMultiple(); 301 byte[][] datas = packet.ToBytesMultiple();
296 int packetCount = datas.Length; 302 int packetCount = datas.Length;
297 303
298 //if (packetCount > 1) 304 if (packetCount < 1)
299 // m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); 305 m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length);
300 306
301 for (int i = 0; i < packetCount; i++) 307 for (int i = 0; i < packetCount; i++)
302 { 308 {
@@ -409,6 +415,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
409 SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false); 415 SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false);
410 } 416 }
411 417
418 public void CompletePing(LLUDPClient udpClient, byte pingID)
419 {
420 CompletePingCheckPacket completePing = new CompletePingCheckPacket();
421 completePing.PingID.PingID = pingID;
422 SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false);
423 }
424
412 public void ResendUnacked(LLUDPClient udpClient) 425 public void ResendUnacked(LLUDPClient udpClient)
413 { 426 {
414 if (!udpClient.IsConnected) 427 if (!udpClient.IsConnected)
@@ -429,7 +442,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
429 442
430 if (expiredPackets != null) 443 if (expiredPackets != null)
431 { 444 {
432 m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO); 445 //m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO);
433 446
434 // Exponential backoff of the retransmission timeout 447 // Exponential backoff of the retransmission timeout
435 udpClient.BackoffRTO(); 448 udpClient.BackoffRTO();
@@ -585,7 +598,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
585 IClientAPI client; 598 IClientAPI client;
586 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView)) 599 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
587 { 600 {
588 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 601 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
589 return; 602 return;
590 } 603 }
591 604
@@ -669,10 +682,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
669 { 682 {
670 // We don't need to do anything else with ping checks 683 // We don't need to do anything else with ping checks
671 StartPingCheckPacket startPing = (StartPingCheckPacket)packet; 684 StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
672 685 CompletePing(udpClient, startPing.PingID.PingID);
673 CompletePingCheckPacket completePing = new CompletePingCheckPacket();
674 completePing.PingID.PingID = startPing.PingID.PingID;
675 SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false);
676 return; 686 return;
677 } 687 }
678 else if (packet.Type == PacketType.CompletePingCheck) 688 else if (packet.Type == PacketType.CompletePingCheck)
@@ -759,10 +769,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
759 } 769 }
760 } 770 }
761 771
762 private void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) 772 protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
763 { 773 {
764 // Create the LLUDPClient 774 // Create the LLUDPClient
765 LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint); 775 LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
766 IClientAPI existingClient; 776 IClientAPI existingClient;
767 777
768 if (!m_scene.TryGetClient(agentID, out existingClient)) 778 if (!m_scene.TryGetClient(agentID, out existingClient))
@@ -801,6 +811,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
801 { 811 {
802 IncomingPacket incomingPacket = null; 812 IncomingPacket incomingPacket = null;
803 813
814 // HACK: This is a test to try and rate limit packet handling on Mono.
815 // If it works, a more elegant solution can be devised
816 if (Util.FireAndForgetCount() < 2)
817 {
818 //m_log.Debug("[LLUDPSERVER]: Incoming packet handler is sleeping");
819 Thread.Sleep(30);
820 }
821
804 if (packetInbox.Dequeue(100, ref incomingPacket)) 822 if (packetInbox.Dequeue(100, ref incomingPacket))
805 Util.FireAndForget(ProcessInPacket, incomingPacket); 823 Util.FireAndForget(ProcessInPacket, incomingPacket);
806 } 824 }
@@ -968,7 +986,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
968 } 986 }
969 } 987 }
970 988
971 private void LogoutHandler(IClientAPI client) 989 protected void LogoutHandler(IClientAPI client)
972 { 990 {
973 client.SendLogoutPacket(); 991 client.SendLogoutPacket();
974 if (client.IsActive) 992 if (client.IsActive)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
index 008d827..aaf6e26 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
@@ -87,15 +87,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
87 IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; 87 IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"];
88 88
89 Resend = throttleConfig.GetInt("resend_default", 12500); 89 Resend = throttleConfig.GetInt("resend_default", 12500);
90 Land = throttleConfig.GetInt("land_default", 500); 90 Land = throttleConfig.GetInt("land_default", 1000);
91 Wind = throttleConfig.GetInt("wind_default", 500); 91 Wind = throttleConfig.GetInt("wind_default", 1000);
92 Cloud = throttleConfig.GetInt("cloud_default", 500); 92 Cloud = throttleConfig.GetInt("cloud_default", 1000);
93 Task = throttleConfig.GetInt("task_default", 500); 93 Task = throttleConfig.GetInt("task_default", 1000);
94 Texture = throttleConfig.GetInt("texture_default", 500); 94 Texture = throttleConfig.GetInt("texture_default", 1000);
95 Asset = throttleConfig.GetInt("asset_default", 500); 95 Asset = throttleConfig.GetInt("asset_default", 1000);
96 State = throttleConfig.GetInt("state_default", 500); 96 State = throttleConfig.GetInt("state_default", 1000);
97
98 Total = throttleConfig.GetInt("client_throttle_max_bps", 0);
99 97
100 ResendLimit = throttleConfig.GetInt("resend_limit", 18750); 98 ResendLimit = throttleConfig.GetInt("resend_limit", 18750);
101 LandLimit = throttleConfig.GetInt("land_limit", 29750); 99 LandLimit = throttleConfig.GetInt("land_limit", 29750);
@@ -104,9 +102,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
104 TaskLimit = throttleConfig.GetInt("task_limit", 18750); 102 TaskLimit = throttleConfig.GetInt("task_limit", 18750);
105 TextureLimit = throttleConfig.GetInt("texture_limit", 55750); 103 TextureLimit = throttleConfig.GetInt("texture_limit", 55750);
106 AssetLimit = throttleConfig.GetInt("asset_limit", 27500); 104 AssetLimit = throttleConfig.GetInt("asset_limit", 27500);
107 State = throttleConfig.GetInt("state_limit", 37000); 105 StateLimit = throttleConfig.GetInt("state_limit", 37000);
108 106
109 TotalLimit = throttleConfig.GetInt("client_throttle_max_bps", 0); 107 Total = throttleConfig.GetInt("client_throttle_max_bps", 0);
108 TotalLimit = Total;
110 } 109 }
111 catch (Exception) { } 110 catch (Exception) { }
112 } 111 }