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