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