aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/UDPServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/UDPServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/UDPServer.cs488
1 files changed, 0 insertions, 488 deletions
diff --git a/OpenSim/Region/ClientStack/UDPServer.cs b/OpenSim/Region/ClientStack/UDPServer.cs
deleted file mode 100644
index 7c4c03c..0000000
--- a/OpenSim/Region/ClientStack/UDPServer.cs
+++ /dev/null
@@ -1,488 +0,0 @@
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 OpenSim 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 System.Net;
31using System.Net.Sockets;
32using System.Reflection;
33using libsecondlife.Packets;
34using log4net;
35using OpenSim.Framework;
36using OpenSim.Framework.Communications.Cache;
37
38namespace OpenSim.Region.ClientStack
39{
40 public class UDPServer : ClientStackNetworkHandler
41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
45 public Dictionary<uint, EndPoint> clientCircuits_reverse = new Dictionary<uint, EndPoint>();
46 protected Dictionary<uint, EndPoint> proxyCircuits = new Dictionary<uint, EndPoint>();
47 public Socket Server;
48 protected IPEndPoint ServerIncoming;
49 protected byte[] RecvBuffer = new byte[4096];
50 protected byte[] ZeroBuffer = new byte[8192];
51 protected IPEndPoint ipeSender;
52 protected EndPoint epSender;
53 protected EndPoint epProxy;
54 protected int proxyPortOffset;
55 protected AsyncCallback ReceivedData;
56 protected PacketServer m_packetServer;
57 protected ulong m_regionHandle;
58
59 protected uint listenPort;
60 protected bool Allow_Alternate_Port;
61 protected IPAddress listenIP = IPAddress.Parse("0.0.0.0");
62 protected IScene m_localScene;
63 protected AssetCache m_assetCache;
64 protected AgentCircuitManager m_authenticateSessionsClass;
65
66 public PacketServer PacketServer
67 {
68 get { return m_packetServer; }
69 set { m_packetServer = value; }
70 }
71
72 public IScene LocalScene
73 {
74 set
75 {
76 m_localScene = value;
77 m_packetServer.LocalScene = m_localScene;
78 m_regionHandle = m_localScene.RegionInfo.RegionHandle;
79 }
80 }
81
82 public ulong RegionHandle
83 {
84 get { return m_regionHandle; }
85 }
86
87 public UDPServer()
88 {
89 }
90
91 public UDPServer(IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, AssetCache assetCache, AgentCircuitManager authenticateClass)
92 {
93 this.proxyPortOffset = proxyPortOffset;
94 listenPort = (uint) (port + proxyPortOffset);
95 listenIP = _listenIP;
96 Allow_Alternate_Port = allow_alternate_port;
97 m_assetCache = assetCache;
98 m_authenticateSessionsClass = authenticateClass;
99 CreatePacketServer();
100
101 // Return new port
102 // This because in Grid mode it is not really important what port the region listens to as long as it is correctly registered.
103 // So the option allow_alternate_ports="true" was added to default.xml
104 port = (uint)(listenPort - proxyPortOffset);
105 }
106
107 protected virtual void CreatePacketServer()
108 {
109 PacketServer packetServer = new PacketServer(this);
110 }
111
112 protected virtual void OnReceivedData(IAsyncResult result)
113 {
114 ipeSender = new IPEndPoint(listenIP, 0);
115 epSender = (EndPoint) ipeSender;
116 Packet packet = null;
117
118 int numBytes = 1;
119
120 try
121 {
122 numBytes = Server.EndReceiveFrom(result, ref epSender);
123 }
124 catch (SocketException e)
125 {
126 // TODO : Actually only handle those states that we have control over, re-throw everything else,
127 // TODO: implement cases as we encounter them.
128 //m_log.Error("[UDPSERVER]: Connection Error! - " + e.ToString());
129 switch (e.SocketErrorCode)
130 {
131 case SocketError.AlreadyInProgress:
132 case SocketError.NetworkReset:
133 case SocketError.ConnectionReset:
134 try
135 {
136 CloseEndPoint(epSender);
137 }
138 catch (Exception a)
139 {
140 m_log.Info("[UDPSERVER]: " + a.ToString());
141 }
142 try
143 {
144 Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender,
145 ReceivedData, null);
146
147 // Ter: For some stupid reason ConnectionReset basically kills our async event structure..
148 // so therefore.. we've got to tell the server to BeginReceiveFrom again.
149 // This will happen over and over until we've gone through all packets
150 // sent to and from this particular user.
151 // Stupid I know..
152 // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method.
153 }
154 catch (SocketException)
155 {
156 }
157 break;
158 default:
159 try
160 {
161 CloseEndPoint(epSender);
162 }
163 catch (Exception)
164 {
165 //m_log.Info("[UDPSERVER]" + a.ToString());
166 }
167 try
168 {
169 Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender,
170 ReceivedData, null);
171
172 // Ter: For some stupid reason ConnectionReset basically kills our async event structure..
173 // so therefore.. we've got to tell the server to BeginReceiveFrom again.
174 // This will happen over and over until we've gone through all packets
175 // sent to and from this particular user.
176 // Stupid I know..
177 // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method.
178 }
179 catch (SocketException e2)
180 {
181 m_log.Error("[UDPSERVER]: " + e2.ToString());
182 }
183
184 // Here's some reference code! :D
185 // Shutdown and restart the UDP listener! hehe
186 // Shiny
187
188 //Server.Shutdown(SocketShutdown.Both);
189 //CloseEndPoint(epSender);
190 //ServerListener();
191 break;
192 }
193
194 //return;
195 }
196 catch (ObjectDisposedException e)
197 {
198 m_log.Debug("[UDPSERVER]: " + e.ToString());
199 try
200 {
201 Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender,
202 ReceivedData, null);
203
204 // Ter: For some stupid reason ConnectionReset basically kills our async event structure..
205 // so therefore.. we've got to tell the server to BeginReceiveFrom again.
206 // This will happen over and over until we've gone through all packets
207 // sent to and from this particular user.
208 // Stupid I know..
209 // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method.
210 }
211
212 catch (SocketException e2)
213 {
214 m_log.Error("[UDPSERVER]: " + e2.ToString());
215 }
216 catch (ObjectDisposedException)
217 {
218 }
219 //return;
220 }
221
222 //System.Console.WriteLine("UDPServer : recieved message from {0}", epSender.ToString());
223 epProxy = epSender;
224 if (proxyPortOffset != 0)
225 {
226 epSender = PacketPool.DecodeProxyMessage(RecvBuffer, ref numBytes);
227 }
228
229 int packetEnd = numBytes - 1;
230
231 try
232 {
233 packet = PacketPool.Instance.GetPacket(RecvBuffer, ref packetEnd, ZeroBuffer);
234 }
235 catch (Exception e)
236 {
237 m_log.Debug("[UDPSERVER]: " + e.ToString());
238 }
239
240 try
241 {
242 Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
243 }
244 catch (SocketException)
245 {
246 try
247 {
248 CloseEndPoint(epSender);
249 }
250 catch (Exception a)
251 {
252 m_log.Info("[UDPSERVER]: " + a.ToString());
253 }
254 try
255 {
256 Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender,
257 ReceivedData, null);
258
259 // Ter: For some stupid reason ConnectionReset basically kills our async event structure..
260 // so therefore.. we've got to tell the server to BeginReceiveFrom again.
261 // This will happen over and over until we've gone through all packets
262 // sent to and from this particular user.
263 // Stupid I know..
264 // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method.
265 }
266 catch (SocketException e5)
267 {
268 m_log.Error("[UDPSERVER]: " + e5.ToString());
269 }
270 }
271 catch (ObjectDisposedException)
272 {
273 }
274
275 if (packet != null)
276 {
277 try
278 {
279 // do we already have a circuit for this endpoint
280 uint circuit;
281
282 bool ret = false;
283 lock (clientCircuits)
284 {
285 ret = clientCircuits.TryGetValue(epSender, out circuit);
286 }
287 if (ret)
288 {
289 //if so then send packet to the packetserver
290 //m_log.Warn("[UDPSERVER]: ALREADY HAVE Circuit!");
291 m_packetServer.InPacket(circuit, packet);
292 }
293 else if (packet.Type == PacketType.UseCircuitCode)
294 {
295 // new client
296 m_log.Debug("[UDPSERVER]: Adding New Client");
297 AddNewClient(packet);
298
299 UseCircuitCodePacket p = (UseCircuitCodePacket)packet;
300
301 // Ack the first UseCircuitCode packet
302 PacketAckPacket ack_it = (PacketAckPacket)PacketPool.Instance.GetPacket(PacketType.PacketAck);
303 // TODO: don't create new blocks if recycling an old packet
304 ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
305 ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
306 ack_it.Packets[0].ID = packet.Header.Sequence;
307 ack_it.Header.Reliable = false;
308 SendPacketTo(ack_it.ToBytes(),ack_it.ToBytes().Length,SocketFlags.None,p.CircuitCode.Code);
309 }
310 else
311 {
312 // invalid client
313 //CFK: This message seems to have served its usefullness as of 12-15 so I am commenting it out for now
314 //m_log.Warn("[UDPSERVER]: Got a packet from an invalid client - " + packet.ToString());
315 }
316 }
317 catch (Exception)
318 {
319 m_log.Error("[UDPSERVER]: Exception in processing packet.");
320 m_log.Debug("[UDPSERVER]: Adding New Client");
321 try
322 {
323 AddNewClient(packet);
324 }
325 catch (Exception e3)
326 {
327 m_log.Error("[UDPSERVER]: Adding New Client threw exception " + e3.ToString());
328 Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender,
329 ReceivedData, null);
330 }
331 }
332 }
333
334 }
335
336 private void CloseEndPoint(EndPoint sender)
337 {
338 uint circuit;
339 lock (clientCircuits)
340 {
341 if (clientCircuits.TryGetValue(sender, out circuit))
342 {
343 m_packetServer.CloseCircuit(circuit);
344 }
345 }
346 }
347
348 protected virtual void AddNewClient(Packet packet)
349 {
350 //Slave regions don't accept new clients
351 if(m_localScene.Region_Status != RegionStatus.SlaveScene)
352 {
353 UseCircuitCodePacket useCircuit = (UseCircuitCodePacket) packet;
354 lock (clientCircuits)
355 {
356 if (!clientCircuits.ContainsKey(epSender))
357 clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);
358 else
359 m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
360 }
361 lock (clientCircuits_reverse)
362 {
363 if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code))
364 clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, epSender);
365 else
366 m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
367 }
368
369 lock (proxyCircuits)
370 {
371 if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
372 proxyCircuits.Add(useCircuit.CircuitCode.Code, epProxy);
373 else
374 m_log.Error("[UDPSERVER]: proxyCircuits already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
375 }
376
377 PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_authenticateSessionsClass, epProxy);
378 }
379 PacketPool.Instance.ReturnPacket(packet);
380 }
381
382 public void ServerListener()
383 {
384 uint newPort = listenPort;
385 m_log.Info("[SERVER]: Opening UDP socket on " + listenIP.ToString() + " " + newPort + ".");
386
387 ServerIncoming = new IPEndPoint(listenIP, (int)newPort);
388 Server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
389 Server.Bind(ServerIncoming);
390 listenPort = newPort;
391
392 m_log.Info("[SERVER]: UDP socket bound, getting ready to listen");
393
394 ipeSender = new IPEndPoint(listenIP, 0);
395 epSender = (EndPoint)ipeSender;
396 ReceivedData = new AsyncCallback(OnReceivedData);
397 Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
398
399 m_log.Info("[SERVER]: Listening on port " + newPort);
400 }
401
402 public virtual void RegisterPacketServer(PacketServer server)
403 {
404 m_packetServer = server;
405 }
406
407 public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
408 //EndPoint packetSender)
409 {
410 // find the endpoint for this circuit
411 EndPoint sendto = null;
412 lock (clientCircuits_reverse)
413 {
414 if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto))
415 {
416 //we found the endpoint so send the packet to it
417 if (proxyPortOffset != 0)
418 {
419 //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo proxy " + proxyCircuits[circuitcode].ToString() + ": client " + sendto.ToString());
420 PacketPool.EncodeProxyMessage(buffer, ref size, sendto);
421 Server.SendTo(buffer, size, flags, proxyCircuits[circuitcode]);
422 }
423 else
424 {
425 //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo : client " + sendto.ToString());
426 Server.SendTo(buffer, size, flags, sendto);
427 }
428 }
429 }
430 }
431
432 public virtual void RemoveClientCircuit(uint circuitcode)
433 {
434 EndPoint sendto = null;
435 lock (clientCircuits_reverse)
436 {
437 if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto))
438 {
439 clientCircuits.Remove(sendto);
440
441 clientCircuits_reverse.Remove(circuitcode);
442 proxyCircuits.Remove(circuitcode);
443 }
444 }
445 }
446
447 public void RestoreClient(AgentCircuitData circuit, EndPoint userEP, EndPoint proxyEP)
448 {
449 //MainLog.Instance.Verbose("UDPSERVER", "RestoreClient");
450
451 UseCircuitCodePacket useCircuit = new UseCircuitCodePacket();
452 useCircuit.CircuitCode.Code = circuit.circuitcode;
453 useCircuit.CircuitCode.ID = circuit.AgentID;
454 useCircuit.CircuitCode.SessionID = circuit.SessionID;
455
456 lock (clientCircuits)
457 {
458 if (!clientCircuits.ContainsKey(userEP))
459 clientCircuits.Add(userEP, useCircuit.CircuitCode.Code);
460 else
461 m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
462 }
463 lock (clientCircuits_reverse)
464 {
465 if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code))
466 clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, userEP);
467 else
468 m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
469 }
470
471 lock (proxyCircuits)
472 {
473 if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
474 {
475 proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
476 }
477 else
478 {
479 // re-set proxy endpoint
480 proxyCircuits.Remove(useCircuit.CircuitCode.Code);
481 proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
482 }
483 }
484
485 PacketServer.AddNewClient(userEP, useCircuit, m_assetCache, m_authenticateSessionsClass, proxyEP);
486 }
487 }
488}