diff options
author | lbsa71 | 2008-08-09 05:26:33 +0000 |
---|---|---|
committer | lbsa71 | 2008-08-09 05:26:33 +0000 |
commit | 6849f4566047cf358ffb42f9efcb90658f2be42d (patch) | |
tree | 3b3346d8efa4936db4f81479f62b8dda627a49c8 | |
parent | Mantis#1521. Thank you kindly, HomerHorwitz for a patch that: (diff) | |
download | opensim-SC_OLD-6849f4566047cf358ffb42f9efcb90658f2be42d.zip opensim-SC_OLD-6849f4566047cf358ffb42f9efcb90658f2be42d.tar.gz opensim-SC_OLD-6849f4566047cf358ffb42f9efcb90658f2be42d.tar.bz2 opensim-SC_OLD-6849f4566047cf358ffb42f9efcb90658f2be42d.tar.xz |
* Shielded against various forms of Malformed data crashes - if there is an error in packet creation, we just log and ignore it
* If there's a Socket.AlreadyInProgress, just silently ignore this one
* Tried to refactor the Reset and BeginRecieve logic into something a little more readable, little less duplicated
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 184 |
1 files changed, 65 insertions, 119 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index b08b59d..6e9bca3 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -153,9 +153,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
153 | 153 | ||
154 | int numBytes = 1; | 154 | int numBytes = 1; |
155 | 155 | ||
156 | bool ok = false; | ||
157 | |||
156 | try | 158 | try |
157 | { | 159 | { |
158 | numBytes = m_socket.EndReceiveFrom(result, ref epSender); | 160 | numBytes = m_socket.EndReceiveFrom(result, ref epSender); |
161 | ok = true; | ||
159 | } | 162 | } |
160 | catch (SocketException e) | 163 | catch (SocketException e) |
161 | { | 164 | { |
@@ -165,149 +168,52 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
165 | switch (e.SocketErrorCode) | 168 | switch (e.SocketErrorCode) |
166 | { | 169 | { |
167 | case SocketError.AlreadyInProgress: | 170 | case SocketError.AlreadyInProgress: |
171 | return; | ||
172 | |||
168 | case SocketError.NetworkReset: | 173 | case SocketError.NetworkReset: |
169 | case SocketError.ConnectionReset: | 174 | case SocketError.ConnectionReset: |
170 | try | ||
171 | { | ||
172 | CloseEndPoint(epSender); | ||
173 | } | ||
174 | catch (Exception a) | ||
175 | { | ||
176 | m_log.Info("[UDPSERVER]: " + a.ToString()); | ||
177 | } | ||
178 | try | ||
179 | { | ||
180 | m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, | ||
181 | ReceivedData, null); | ||
182 | |||
183 | // Ter: For some stupid reason ConnectionReset basically kills our async event structure.. | ||
184 | // so therefore.. we've got to tell the server to BeginReceiveFrom again. | ||
185 | // This will happen over and over until we've gone through all packets | ||
186 | // sent to and from this particular user. | ||
187 | // Stupid I know.. | ||
188 | // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method. | ||
189 | } | ||
190 | catch (SocketException) | ||
191 | { | ||
192 | } | ||
193 | break; | 175 | break; |
176 | |||
194 | default: | 177 | default: |
195 | try | 178 | throw; |
196 | { | ||
197 | CloseEndPoint(epSender); | ||
198 | } | ||
199 | catch (Exception) | ||
200 | { | ||
201 | //m_log.Info("[UDPSERVER]" + a.ToString()); | ||
202 | } | ||
203 | try | ||
204 | { | ||
205 | m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, | ||
206 | ReceivedData, null); | ||
207 | |||
208 | // Ter: For some stupid reason ConnectionReset basically kills our async event structure.. | ||
209 | // so therefore.. we've got to tell the server to BeginReceiveFrom again. | ||
210 | // This will happen over and over until we've gone through all packets | ||
211 | // sent to and from this particular user. | ||
212 | // Stupid I know.. | ||
213 | // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method. | ||
214 | } | ||
215 | catch (SocketException e2) | ||
216 | { | ||
217 | m_log.Error("[UDPSERVER]: " + e2.ToString()); | ||
218 | } | ||
219 | |||
220 | // Here's some reference code! :D | ||
221 | // Shutdown and restart the UDP listener! hehe | ||
222 | // Shiny | ||
223 | |||
224 | //Server.Shutdown(SocketShutdown.Both); | ||
225 | //CloseEndPoint(epSender); | ||
226 | //ServerListener(); | ||
227 | break; | ||
228 | } | 179 | } |
229 | |||
230 | //return; | ||
231 | } | 180 | } |
232 | catch (ObjectDisposedException e) | 181 | catch (ObjectDisposedException e) |
233 | { | 182 | { |
234 | m_log.Debug("[UDPSERVER]: " + e.ToString()); | 183 | m_log.DebugFormat("ObjectDisposedException: Object {0} disposed.", e.ObjectName); |
235 | try | 184 | // Uhh, what object, and why? this needs better handling. |
236 | { | ||
237 | m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, | ||
238 | ReceivedData, null); | ||
239 | |||
240 | // Ter: For some stupid reason ConnectionReset basically kills our async event structure.. | ||
241 | // so therefore.. we've got to tell the server to BeginReceiveFrom again. | ||
242 | // This will happen over and over until we've gone through all packets | ||
243 | // sent to and from this particular user. | ||
244 | // Stupid I know.. | ||
245 | // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method. | ||
246 | } | ||
247 | |||
248 | catch (SocketException e2) | ||
249 | { | ||
250 | m_log.Error("[UDPSERVER]: " + e2.ToString()); | ||
251 | } | ||
252 | catch (ObjectDisposedException) | ||
253 | { | ||
254 | } | ||
255 | //return; | ||
256 | } | 185 | } |
257 | 186 | ||
258 | //System.Console.WriteLine("UDPServer : recieved message from {0}", epSender.ToString()); | 187 | if (ok) |
259 | epProxy = epSender; | ||
260 | if (proxyPortOffset != 0) | ||
261 | { | 188 | { |
262 | epSender = ProxyCodec.DecodeProxyMessage(RecvBuffer, ref numBytes); | 189 | epProxy = epSender; |
263 | } | 190 | if (proxyPortOffset != 0) |
264 | 191 | { | |
265 | int packetEnd = numBytes - 1; | 192 | epSender = ProxyCodec.DecodeProxyMessage(RecvBuffer, ref numBytes); |
193 | } | ||
266 | 194 | ||
267 | try | 195 | int packetEnd = numBytes - 1; |
268 | { | ||
269 | packet = PacketPool.Instance.GetPacket(RecvBuffer, ref packetEnd, ZeroBuffer); | ||
270 | } | ||
271 | catch (Exception e) | ||
272 | { | ||
273 | m_log.Debug("[UDPSERVER]: " + e.ToString()); | ||
274 | } | ||
275 | 196 | ||
276 | try | ||
277 | { | ||
278 | m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); | ||
279 | } | ||
280 | catch (SocketException) | ||
281 | { | ||
282 | try | 197 | try |
283 | { | 198 | { |
284 | CloseEndPoint(epSender); | 199 | packet = PacketPool.Instance.GetPacket(RecvBuffer, ref packetEnd, ZeroBuffer); |
285 | } | 200 | } |
286 | catch (Exception a) | 201 | catch (MalformedDataException e) |
287 | { | 202 | { |
288 | m_log.Info("[UDPSERVER]: " + a.ToString()); | 203 | m_log.DebugFormat("Dropped Malformed Packet due to MalformedDataException: {0}", e.StackTrace); |
289 | } | 204 | } |
290 | try | 205 | catch (IndexOutOfRangeException e) |
291 | { | 206 | { |
292 | m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, | 207 | m_log.DebugFormat("Dropped Malformed Packet due to IndexOutOfRangeException: {0}", e.StackTrace); |
293 | ReceivedData, null); | ||
294 | |||
295 | // Ter: For some stupid reason ConnectionReset basically kills our async event structure.. | ||
296 | // so therefore.. we've got to tell the server to BeginReceiveFrom again. | ||
297 | // This will happen over and over until we've gone through all packets | ||
298 | // sent to and from this particular user. | ||
299 | // Stupid I know.. | ||
300 | // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method. | ||
301 | } | 208 | } |
302 | catch (SocketException e5) | 209 | catch (Exception e) |
303 | { | 210 | { |
304 | m_log.Error("[UDPSERVER]: " + e5.ToString()); | 211 | m_log.Debug("[UDPSERVER]: " + e.ToString()); |
305 | } | 212 | } |
306 | } | 213 | } |
307 | catch (ObjectDisposedException) | ||
308 | { | ||
309 | } | ||
310 | 214 | ||
215 | BeginReceive(); | ||
216 | |||
311 | if (packet != null) | 217 | if (packet != null) |
312 | { | 218 | { |
313 | try | 219 | try |
@@ -360,7 +266,47 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
360 | } | 266 | } |
361 | } | 267 | } |
362 | } | 268 | } |
269 | } | ||
270 | |||
271 | private void BeginReceive() | ||
272 | { | ||
273 | try | ||
274 | { | ||
275 | m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); | ||
276 | } | ||
277 | catch (SocketException) | ||
278 | { | ||
279 | ResetEndPoint(); | ||
280 | } | ||
281 | } | ||
282 | |||
283 | private void ResetEndPoint() | ||
284 | { | ||
285 | try | ||
286 | { | ||
287 | CloseEndPoint(epSender); | ||
288 | } | ||
289 | catch (Exception a) | ||
290 | { | ||
291 | m_log.Info("[UDPSERVER]: " + a.ToString()); | ||
292 | } | ||
363 | 293 | ||
294 | try | ||
295 | { | ||
296 | m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, | ||
297 | ReceivedData, null); | ||
298 | |||
299 | // Ter: For some stupid reason ConnectionReset basically kills our async event structure.. | ||
300 | // so therefore.. we've got to tell the server to BeginReceiveFrom again. | ||
301 | // This will happen over and over until we've gone through all packets | ||
302 | // sent to and from this particular user. | ||
303 | // Stupid I know.. | ||
304 | // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method. | ||
305 | } | ||
306 | catch (SocketException e) | ||
307 | { | ||
308 | m_log.DebugFormat("[UDPSERVER]: Exception {0} : {1}", e.Message, e.StackTrace ); | ||
309 | } | ||
364 | } | 310 | } |
365 | 311 | ||
366 | private void CloseEndPoint(EndPoint sender) | 312 | private void CloseEndPoint(EndPoint sender) |