aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/FunSLUDP/LLUDPServer.cs
diff options
context:
space:
mode:
authorMike Mazur2008-08-08 05:57:14 +0000
committerMike Mazur2008-08-08 05:57:14 +0000
commit1040f3f454a6f469dcd74f19c45ea67d0584ade1 (patch)
tree36076b1a16ae66f3451666856e3f52f875e7d8a8 /OpenSim/Region/ClientStack/FunSLUDP/LLUDPServer.cs
parentCommitting first draft of the universal cache. This is by no means (diff)
downloadopensim-SC_OLD-1040f3f454a6f469dcd74f19c45ea67d0584ade1.zip
opensim-SC_OLD-1040f3f454a6f469dcd74f19c45ea67d0584ade1.tar.gz
opensim-SC_OLD-1040f3f454a6f469dcd74f19c45ea67d0584ade1.tar.bz2
opensim-SC_OLD-1040f3f454a6f469dcd74f19c45ea67d0584ade1.tar.xz
Remove FunSL client stack as it's under development and often won't compile.
This effectively undoes commits 5771 and 5769 as well as parts of the formatting cleanup commits 5774 and 5775.
Diffstat (limited to 'OpenSim/Region/ClientStack/FunSLUDP/LLUDPServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/FunSLUDP/LLUDPServer.cs545
1 files changed, 0 insertions, 545 deletions
diff --git a/OpenSim/Region/ClientStack/FunSLUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/FunSLUDP/LLUDPServer.cs
deleted file mode 100644
index 2b76c97..0000000
--- a/OpenSim/Region/ClientStack/FunSLUDP/LLUDPServer.cs
+++ /dev/null
@@ -1,545 +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;
30using System.Collections.Generic;
31using System.Net;
32using System.Net.Sockets;
33using System.Reflection;
34using libsecondlife.Packets;
35using log4net;
36using OpenSim.Framework;
37using OpenSim.Framework.Communications.Cache;
38using OpenSim.Region.ClientStack.FunSLUDP;
39using OpenSim.Region.Environment.Scenes;
40
41namespace OpenSim.Region.ClientStack.FunSLUDP
42{
43 public class LLUDPServer : LLClientStackNetworkHandler, IClientNetworkServer
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
48
49 //public Dictionary<uint, EndPoint> clientCircuits_reverse = new Dictionary<uint, EndPoint>();
50 public Hashtable clientCircuits_reverse = Hashtable.Synchronized(new Hashtable());
51
52 protected Dictionary<uint, EndPoint> proxyCircuits = new Dictionary<uint, EndPoint>();
53 private Socket m_socket;
54 protected IPEndPoint ServerIncoming;
55 protected byte[] RecvBuffer = new byte[4096];
56 protected byte[] ZeroBuffer = new byte[8192];
57 protected IPEndPoint ipeSender;
58 protected EndPoint epSender;
59 protected EndPoint epProxy;
60 protected int proxyPortOffset;
61 protected AsyncCallback ReceivedData;
62 protected LLPacketServer m_packetServer;
63 protected Location m_location;
64
65 protected uint listenPort;
66 protected bool Allow_Alternate_Port;
67 protected IPAddress listenIP = IPAddress.Parse("0.0.0.0");
68 protected IScene m_localScene;
69 protected AssetCache m_assetCache;
70 protected AgentCircuitManager m_authenticateSessionsClass;
71
72 public LLPacketServer PacketServer
73 {
74 get { return m_packetServer; }
75 set { m_packetServer = value; }
76 }
77
78 public IScene LocalScene
79 {
80 set
81 {
82 m_localScene = value;
83 m_packetServer.LocalScene = m_localScene;
84 m_location = new Location(m_localScene.RegionInfo.RegionHandle);
85 }
86 }
87
88 public ulong RegionHandle
89 {
90 get { return m_location.RegionHandle; }
91 }
92
93 Socket IClientNetworkServer.Server
94 {
95 get { return m_socket; }
96 }
97
98 public bool HandlesRegion(Location x)
99 {
100 return x == m_location;
101 }
102
103 public void AddScene(Scene x)
104 {
105 LocalScene = x;
106 }
107
108 public void Start()
109 {
110 ServerListener();
111 }
112
113 public void Stop()
114 {
115 m_socket.Close();
116 }
117
118 public LLUDPServer()
119 {
120 }
121
122 public LLUDPServer(IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, AssetCache assetCache, AgentCircuitManager authenticateClass)
123 {
124 Initialise(_listenIP, ref port, proxyPortOffset, allow_alternate_port, assetCache, authenticateClass);
125 }
126
127 public void Initialise(IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, AssetCache assetCache, AgentCircuitManager authenticateClass)
128 {
129 this.proxyPortOffset = proxyPortOffset;
130 listenPort = (uint) (port + proxyPortOffset);
131 listenIP = _listenIP;
132 Allow_Alternate_Port = allow_alternate_port;
133 m_assetCache = assetCache;
134 m_authenticateSessionsClass = authenticateClass;
135 CreatePacketServer();
136
137 // Return new port
138 // This because in Grid mode it is not really important what port the region listens to as long as it is correctly registered.
139 // So the option allow_alternate_ports="true" was added to default.xml
140 port = (uint)(listenPort - proxyPortOffset);
141 }
142
143 protected virtual void CreatePacketServer()
144 {
145 new LLPacketServer(this);
146 }
147
148 protected virtual void OnReceivedData(IAsyncResult result)
149 {
150 ipeSender = new IPEndPoint(listenIP, 0);
151 epSender = (EndPoint) ipeSender;
152 Packet packet = null;
153
154 int numBytes = 1;
155
156 try
157 {
158 numBytes = m_socket.EndReceiveFrom(result, ref epSender);
159 }
160 catch (SocketException e)
161 {
162 // TODO : Actually only handle those states that we have control over, re-throw everything else,
163 // TODO: implement cases as we encounter them.
164 //m_log.Error("[UDPSERVER]: Connection Error! - " + e.ToString());
165 switch (e.SocketErrorCode)
166 {
167 case SocketError.AlreadyInProgress:
168 case SocketError.NetworkReset:
169 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;
194 default:
195 try
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 }
229
230 //return;
231 }
232 catch (ObjectDisposedException e)
233 {
234 m_log.Debug("[UDPSERVER]: " + e.ToString());
235 try
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 }
257
258 //System.Console.WriteLine("UDPServer : recieved message from {0}", epSender.ToString());
259 epProxy = epSender;
260 if (proxyPortOffset != 0)
261 {
262 epSender = PacketPool.DecodeProxyMessage(RecvBuffer, ref numBytes);
263 }
264
265 int packetEnd = numBytes - 1;
266
267 try
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
276 try
277 {
278 m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
279 }
280 catch (SocketException)
281 {
282 try
283 {
284 CloseEndPoint(epSender);
285 }
286 catch (Exception a)
287 {
288 m_log.Info("[UDPSERVER]: " + a.ToString());
289 }
290 try
291 {
292 m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender,
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 }
302 catch (SocketException e5)
303 {
304 m_log.Error("[UDPSERVER]: " + e5.ToString());
305 }
306 }
307 catch (ObjectDisposedException)
308 {
309 }
310
311 if (packet != null)
312 {
313 try
314 {
315 // do we already have a circuit for this endpoint
316 uint circuit;
317
318 bool ret = false;
319 lock (clientCircuits)
320 {
321 ret = clientCircuits.TryGetValue(epSender, out circuit);
322 }
323 if (ret)
324 {
325 //if so then send packet to the packetserver
326 //m_log.Warn("[UDPSERVER]: ALREADY HAVE Circuit!");
327 m_packetServer.InPacket(circuit, packet);
328 }
329 else if (packet.Type == PacketType.UseCircuitCode)
330 {
331 // new client
332 m_log.Debug("[UDPSERVER]: Adding New Client");
333 AddNewClient(packet);
334
335 UseCircuitCodePacket p = (UseCircuitCodePacket)packet;
336
337 // Ack the first UseCircuitCode packet
338 PacketAckPacket ack_it = (PacketAckPacket)PacketPool.Instance.GetPacket(PacketType.PacketAck);
339 // TODO: don't create new blocks if recycling an old packet
340 ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
341 ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
342 ack_it.Packets[0].ID = packet.Header.Sequence;
343 ack_it.Header.Reliable = false;
344 SendPacketTo(ack_it.ToBytes(),ack_it.ToBytes().Length,SocketFlags.None,p.CircuitCode.Code);
345 }
346 }
347 catch (Exception)
348 {
349 m_log.Error("[UDPSERVER]: Exception in processing packet.");
350 m_log.Debug("[UDPSERVER]: Adding New Client");
351 try
352 {
353 AddNewClient(packet);
354 }
355 catch (Exception e3)
356 {
357 m_log.Error("[UDPSERVER]: Adding New Client threw exception " + e3.ToString());
358 m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender,
359 ReceivedData, null);
360 }
361 }
362 }
363
364 }
365
366 private void CloseEndPoint(EndPoint sender)
367 {
368 uint circuit;
369 lock (clientCircuits)
370 {
371 if (clientCircuits.TryGetValue(sender, out circuit))
372 {
373 m_packetServer.CloseCircuit(circuit);
374 }
375 }
376 }
377
378 protected virtual void AddNewClient(Packet packet)
379 {
380 //Slave regions don't accept new clients
381 if (m_localScene.Region_Status != RegionStatus.SlaveScene)
382 {
383 if (!(packet is UseCircuitCodePacket))
384 return;
385
386 UseCircuitCodePacket useCircuit = (UseCircuitCodePacket) packet;
387 lock (clientCircuits)
388 {
389 if (!clientCircuits.ContainsKey(epSender))
390 clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);
391 else
392 m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
393 }
394
395 // This doesn't need locking as it's synchronized data
396 if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code))
397 clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, epSender);
398 else
399 m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
400
401
402 lock (proxyCircuits)
403 {
404 if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
405 proxyCircuits.Add(useCircuit.CircuitCode.Code, epProxy);
406 else
407 m_log.Error("[UDPSERVER]: proxyCircuits already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
408 }
409
410 PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_authenticateSessionsClass, epProxy);
411 }
412 PacketPool.Instance.ReturnPacket(packet);
413 }
414
415 public void ServerListener()
416 {
417 uint newPort = listenPort;
418 m_log.Info("[SERVER]: Opening UDP socket on " + listenIP.ToString() + " " + newPort + ".");
419
420 ServerIncoming = new IPEndPoint(listenIP, (int)newPort);
421 m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
422 m_socket.Bind(ServerIncoming);
423 // Add flags to the UDP socket to prevent "Socket forcibly closed by host"
424 // uint IOC_IN = 0x80000000;
425 // uint IOC_VENDOR = 0x18000000;
426 // uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
427 // TODO: this apparently works in .NET but not in Mono, need to sort out the right flags here.
428 // m_socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
429
430 listenPort = newPort;
431
432 m_log.Info("[SERVER]: UDP socket bound, getting ready to listen");
433
434 ipeSender = new IPEndPoint(listenIP, 0);
435 epSender = (EndPoint)ipeSender;
436 ReceivedData = new AsyncCallback(OnReceivedData);
437 m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
438
439 m_log.Info("[SERVER]: Listening on port " + newPort);
440 }
441
442 public virtual void RegisterPacketServer(LLPacketServer server)
443 {
444 m_packetServer = server;
445 }
446
447 public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
448 //EndPoint packetSender)
449 {
450 // find the endpoint for this circuit
451 EndPoint sendto = null;
452 try {
453 sendto = (EndPoint)clientCircuits_reverse[circuitcode];
454 } catch {
455 // Exceptions here mean there is no circuit
456 m_log.Warn("Circuit not found, not sending packet");
457 return;
458 }
459
460 if (sendto != null)
461 {
462 //we found the endpoint so send the packet to it
463 if (proxyPortOffset != 0)
464 {
465 //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo proxy " + proxyCircuits[circuitcode].ToString() + ": client " + sendto.ToString());
466 PacketPool.EncodeProxyMessage(buffer, ref size, sendto);
467 m_socket.SendTo(buffer, size, flags, proxyCircuits[circuitcode]);
468 }
469 else
470 {
471 //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo : client " + sendto.ToString());
472 m_socket.SendTo(buffer, size, flags, sendto);
473 }
474 }
475 }
476
477 public virtual void RemoveClientCircuit(uint circuitcode)
478 {
479 EndPoint sendto = null;
480 if (clientCircuits_reverse.Contains(circuitcode))
481 {
482 sendto = (EndPoint)clientCircuits_reverse[circuitcode];
483
484 clientCircuits_reverse.Remove(circuitcode);
485
486 lock (clientCircuits)
487 {
488 if (sendto != null)
489 {
490 clientCircuits.Remove(sendto);
491 }
492 else
493 {
494 m_log.DebugFormat(
495 "[UDPSERVER]: endpoint for circuit code {0} in RemoveClientCircuit() was unexpectedly null!", circuitcode);
496 }
497 }
498 lock (proxyCircuits)
499 {
500 proxyCircuits.Remove(circuitcode);
501 }
502 }
503 }
504
505 public void RestoreClient(AgentCircuitData circuit, EndPoint userEP, EndPoint proxyEP)
506 {
507 //MainLog.Instance.Verbose("UDPSERVER", "RestoreClient");
508
509 UseCircuitCodePacket useCircuit = new UseCircuitCodePacket();
510 useCircuit.CircuitCode.Code = circuit.circuitcode;
511 useCircuit.CircuitCode.ID = circuit.AgentID;
512 useCircuit.CircuitCode.SessionID = circuit.SessionID;
513
514 lock (clientCircuits)
515 {
516 if (!clientCircuits.ContainsKey(userEP))
517 clientCircuits.Add(userEP, useCircuit.CircuitCode.Code);
518 else
519 m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
520 }
521
522 // This data structure is synchronized, so we don't need the lock
523 if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code))
524 clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, userEP);
525 else
526 m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
527
528 lock (proxyCircuits)
529 {
530 if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
531 {
532 proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
533 }
534 else
535 {
536 // re-set proxy endpoint
537 proxyCircuits.Remove(useCircuit.CircuitCode.Code);
538 proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
539 }
540 }
541
542 PacketServer.AddNewClient(userEP, useCircuit, m_assetCache, m_authenticateSessionsClass, proxyEP);
543 }
544 }
545}