diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 90 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 25 |
2 files changed, 78 insertions, 37 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 0431b53..ad3f715 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -108,6 +108,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
108 | 108 | ||
109 | StatsManager.RegisterStat( | 109 | StatsManager.RegisterStat( |
110 | new Stat( | 110 | new Stat( |
111 | "IncomingPacketsMalformedCount", | ||
112 | "Number of inbound UDP packets that could not be recognized as LL protocol packets.", | ||
113 | "", | ||
114 | "", | ||
115 | "clientstack", | ||
116 | scene.Name, | ||
117 | StatType.Pull, | ||
118 | MeasuresOfInterest.AverageChangeOverTime, | ||
119 | stat => stat.Value = m_udpServer.IncomingMalformedPacketCount, | ||
120 | StatVerbosity.Info)); | ||
121 | |||
122 | StatsManager.RegisterStat( | ||
123 | new Stat( | ||
124 | "IncomingPacketsOrphanedCount", | ||
125 | "Number of inbound packets that were not initial connections packets and could not be associated with a viewer.", | ||
126 | "", | ||
127 | "", | ||
128 | "clientstack", | ||
129 | scene.Name, | ||
130 | StatType.Pull, | ||
131 | MeasuresOfInterest.AverageChangeOverTime, | ||
132 | stat => stat.Value = m_udpServer.IncomingOrphanedPacketCount, | ||
133 | StatVerbosity.Info)); | ||
134 | |||
135 | StatsManager.RegisterStat( | ||
136 | new Stat( | ||
111 | "OutgoingUDPSendsCount", | 137 | "OutgoingUDPSendsCount", |
112 | "Number of UDP sends performed", | 138 | "Number of UDP sends performed", |
113 | "", | 139 | "", |
@@ -272,7 +298,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
272 | 298 | ||
273 | public Socket Server { get { return null; } } | 299 | public Socket Server { get { return null; } } |
274 | 300 | ||
275 | private int m_malformedCount = 0; // Guard against a spamming attack | 301 | /// <summary> |
302 | /// Record how many inbound packets could not be recognized as LLUDP packets. | ||
303 | /// </summary> | ||
304 | public int IncomingMalformedPacketCount { get; private set; } | ||
305 | |||
306 | /// <summary> | ||
307 | /// Record how many inbound packets could not be associated with a simulator circuit. | ||
308 | /// </summary> | ||
309 | public int IncomingOrphanedPacketCount { get; private set; } | ||
276 | 310 | ||
277 | /// <summary> | 311 | /// <summary> |
278 | /// Record current outgoing client for monitoring purposes. | 312 | /// Record current outgoing client for monitoring purposes. |
@@ -1193,6 +1227,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1193 | outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; | 1227 | outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; |
1194 | } | 1228 | } |
1195 | 1229 | ||
1230 | private void RecordMalformedInboundPacket(IPEndPoint endPoint) | ||
1231 | { | ||
1232 | // if (m_malformedCount < 100) | ||
1233 | // m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); | ||
1234 | |||
1235 | IncomingMalformedPacketCount++; | ||
1236 | |||
1237 | if ((IncomingMalformedPacketCount % 10000) == 0) | ||
1238 | m_log.WarnFormat( | ||
1239 | "[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack. Last was from {1}", | ||
1240 | IncomingMalformedPacketCount, endPoint); | ||
1241 | } | ||
1242 | |||
1196 | public override void PacketReceived(UDPPacketBuffer buffer) | 1243 | public override void PacketReceived(UDPPacketBuffer buffer) |
1197 | { | 1244 | { |
1198 | // Debugging/Profiling | 1245 | // Debugging/Profiling |
@@ -1214,6 +1261,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1214 | // "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", | 1261 | // "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", |
1215 | // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); | 1262 | // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); |
1216 | 1263 | ||
1264 | RecordMalformedInboundPacket(endPoint); | ||
1265 | |||
1217 | return; // Drop undersized packet | 1266 | return; // Drop undersized packet |
1218 | } | 1267 | } |
1219 | 1268 | ||
@@ -1232,6 +1281,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1232 | // "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}", | 1281 | // "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}", |
1233 | // buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); | 1282 | // buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); |
1234 | 1283 | ||
1284 | RecordMalformedInboundPacket(endPoint); | ||
1285 | |||
1235 | return; // Malformed header | 1286 | return; // Malformed header |
1236 | } | 1287 | } |
1237 | 1288 | ||
@@ -1247,34 +1298,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1247 | // Only allocate a buffer for zerodecoding if the packet is zerocoded | 1298 | // Only allocate a buffer for zerodecoding if the packet is zerocoded |
1248 | ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); | 1299 | ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); |
1249 | } | 1300 | } |
1250 | catch (MalformedDataException) | ||
1251 | { | ||
1252 | } | ||
1253 | catch (IndexOutOfRangeException) | ||
1254 | { | ||
1255 | // m_log.WarnFormat( | ||
1256 | // "[LLUDPSERVER]: Dropping short packet received from {0} in {1}", | ||
1257 | // buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); | ||
1258 | |||
1259 | return; // Drop short packet | ||
1260 | } | ||
1261 | catch (Exception e) | 1301 | catch (Exception e) |
1262 | { | 1302 | { |
1263 | if (m_malformedCount < 100) | 1303 | if (IncomingMalformedPacketCount < 100) |
1264 | m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); | 1304 | m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); |
1265 | |||
1266 | m_malformedCount++; | ||
1267 | |||
1268 | if ((m_malformedCount % 100000) == 0) | ||
1269 | m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount); | ||
1270 | } | 1305 | } |
1271 | 1306 | ||
1272 | // Fail-safe check | 1307 | // Fail-safe check |
1273 | if (packet == null) | 1308 | if (packet == null) |
1274 | { | 1309 | { |
1275 | m_log.ErrorFormat("[LLUDPSERVER]: Malformed data, cannot parse {0} byte packet from {1}:", | 1310 | if (IncomingMalformedPacketCount < 100) |
1276 | buffer.DataLength, buffer.RemoteEndPoint); | 1311 | { |
1277 | m_log.Error(Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)); | 1312 | m_log.WarnFormat("[LLUDPSERVER]: Malformed data, cannot parse {0} byte packet from {1}, data {2}:", |
1313 | buffer.DataLength, buffer.RemoteEndPoint, Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)); | ||
1314 | } | ||
1315 | |||
1316 | RecordMalformedInboundPacket(endPoint); | ||
1317 | |||
1278 | return; | 1318 | return; |
1279 | } | 1319 | } |
1280 | 1320 | ||
@@ -1337,6 +1377,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1337 | if (client == null || !(client is LLClientView)) | 1377 | if (client == null || !(client is LLClientView)) |
1338 | { | 1378 | { |
1339 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); | 1379 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); |
1380 | |||
1381 | IncomingOrphanedPacketCount++; | ||
1382 | |||
1383 | if ((IncomingOrphanedPacketCount % 10000) == 0) | ||
1384 | m_log.WarnFormat( | ||
1385 | "[LLUDPSERVER]: Received {0} orphaned packets so far. Last was from {1}", | ||
1386 | IncomingOrphanedPacketCount, endPoint); | ||
1387 | |||
1340 | return; | 1388 | return; |
1341 | } | 1389 | } |
1342 | 1390 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 1fdc410..5a2bcee 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | |||
@@ -145,39 +145,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
145 | return packet; | 145 | return packet; |
146 | } | 146 | } |
147 | 147 | ||
148 | // private byte[] decoded_header = new byte[10]; | ||
149 | private static PacketType GetType(byte[] bytes) | 148 | private static PacketType GetType(byte[] bytes) |
150 | { | 149 | { |
151 | byte[] decoded_header = new byte[10 + 8]; | ||
152 | ushort id; | 150 | ushort id; |
153 | PacketFrequency freq; | 151 | PacketFrequency freq; |
152 | bool isZeroCoded = (bytes[0] & Helpers.MSG_ZEROCODED) != 0; | ||
154 | 153 | ||
155 | if ((bytes[0] & Helpers.MSG_ZEROCODED) != 0) | 154 | if (bytes[6] == 0xFF) |
156 | { | 155 | { |
157 | Helpers.ZeroDecode(bytes, 16, decoded_header); | 156 | if (bytes[7] == 0xFF) |
158 | } | ||
159 | else | ||
160 | { | ||
161 | Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10); | ||
162 | } | ||
163 | |||
164 | if (decoded_header[6] == 0xFF) | ||
165 | { | ||
166 | if (decoded_header[7] == 0xFF) | ||
167 | { | 157 | { |
168 | id = (ushort) ((decoded_header[8] << 8) + decoded_header[9]); | ||
169 | freq = PacketFrequency.Low; | 158 | freq = PacketFrequency.Low; |
159 | if (isZeroCoded && bytes[8] == 0) | ||
160 | id = bytes[10]; | ||
161 | else | ||
162 | id = (ushort)((bytes[8] << 8) + bytes[9]); | ||
170 | } | 163 | } |
171 | else | 164 | else |
172 | { | 165 | { |
173 | id = decoded_header[7]; | ||
174 | freq = PacketFrequency.Medium; | 166 | freq = PacketFrequency.Medium; |
167 | id = bytes[7]; | ||
175 | } | 168 | } |
176 | } | 169 | } |
177 | else | 170 | else |
178 | { | 171 | { |
179 | id = decoded_header[6]; | ||
180 | freq = PacketFrequency.High; | 172 | freq = PacketFrequency.High; |
173 | id = bytes[6]; | ||
181 | } | 174 | } |
182 | 175 | ||
183 | return Packet.GetType(id, freq); | 176 | return Packet.GetType(id, freq); |