diff options
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r-- | OpenSim/Region/ClientStack/ClientView.cs | 158 |
1 files changed, 85 insertions, 73 deletions
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 56ab5d6..230e8ef 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs | |||
@@ -2240,99 +2240,111 @@ namespace OpenSim.Region.ClientStack | |||
2240 | set { m_circuitCode = value; } | 2240 | set { m_circuitCode = value; } |
2241 | } | 2241 | } |
2242 | 2242 | ||
2243 | protected virtual void ProcessOutPacket(Packet Pack) | 2243 | // A thread safe sequence number allocator. |
2244 | protected uint NextSeqNum() | ||
2244 | { | 2245 | { |
2245 | // Keep track of when this packet was sent out | 2246 | // Set the sequence number |
2246 | Pack.TickCount = System.Environment.TickCount; | 2247 | uint seq = 1; |
2247 | 2248 | lock (SequenceLock) | |
2248 | if (!Pack.Header.Resent) | 2249 | { |
2250 | if (Sequence >= MAX_SEQUENCE) | ||
2251 | { | ||
2252 | Sequence = 1; | ||
2253 | } | ||
2254 | else | ||
2255 | { | ||
2256 | Sequence++; | ||
2257 | } | ||
2258 | seq = Sequence; | ||
2259 | } | ||
2260 | return seq; | ||
2261 | } | ||
2262 | |||
2263 | protected void AddAck(Packet Pack) | ||
2264 | { | ||
2265 | lock (NeedAck) | ||
2249 | { | 2266 | { |
2250 | // Set the sequence number | 2267 | if (!NeedAck.ContainsKey(Pack.Header.Sequence)) |
2251 | lock (SequenceLock) | ||
2252 | { | 2268 | { |
2253 | if (Sequence >= MAX_SEQUENCE) | 2269 | try |
2254 | { | 2270 | { |
2255 | Sequence = 1; | 2271 | NeedAck.Add(Pack.Header.Sequence, Pack); |
2256 | } | 2272 | } |
2257 | else | 2273 | catch (Exception e) // HACKY |
2258 | { | 2274 | { |
2259 | Sequence++; | 2275 | e.ToString(); |
2276 | // Ignore | ||
2277 | // Seems to throw a exception here occasionally | ||
2278 | // of 'duplicate key' despite being locked. | ||
2279 | // !?!?!? | ||
2260 | } | 2280 | } |
2261 | |||
2262 | Pack.Header.Sequence = Sequence; | ||
2263 | } | 2281 | } |
2282 | else | ||
2283 | { | ||
2284 | // Client.Log("Attempted to add a duplicate sequence number (" + | ||
2285 | // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + | ||
2286 | // packet.Type.ToString(), Helpers.LogLevel.Warning); | ||
2287 | } | ||
2288 | } | ||
2289 | } | ||
2264 | 2290 | ||
2265 | if (Pack.Header.Reliable) //DIRTY HACK | 2291 | protected virtual void SetPendingAcks(ref Packet Pack) |
2292 | { | ||
2293 | // Append any ACKs that need to be sent out to this packet | ||
2294 | lock (PendingAcks) | ||
2295 | { | ||
2296 | // TODO: If we are over MAX_APPENDED_ACKS we should drain off some of these | ||
2297 | if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS) | ||
2266 | { | 2298 | { |
2267 | lock (NeedAck) | 2299 | Pack.Header.AckList = new uint[PendingAcks.Count]; |
2300 | int i = 0; | ||
2301 | |||
2302 | foreach (uint ack in PendingAcks.Values) | ||
2268 | { | 2303 | { |
2269 | if (!NeedAck.ContainsKey(Pack.Header.Sequence)) | 2304 | Pack.Header.AckList[i] = ack; |
2270 | { | 2305 | i++; |
2271 | try | ||
2272 | { | ||
2273 | NeedAck.Add(Pack.Header.Sequence, Pack); | ||
2274 | } | ||
2275 | catch (Exception e) // HACKY | ||
2276 | { | ||
2277 | e.ToString(); | ||
2278 | // Ignore | ||
2279 | // Seems to throw a exception here occasionally | ||
2280 | // of 'duplicate key' despite being locked. | ||
2281 | // !?!?!? | ||
2282 | } | ||
2283 | } | ||
2284 | else | ||
2285 | { | ||
2286 | // Client.Log("Attempted to add a duplicate sequence number (" + | ||
2287 | // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + | ||
2288 | // packet.Type.ToString(), Helpers.LogLevel.Warning); | ||
2289 | } | ||
2290 | } | 2306 | } |
2307 | |||
2308 | PendingAcks.Clear(); | ||
2309 | Pack.Header.AppendedAcks = true; | ||
2310 | } | ||
2311 | } | ||
2312 | } | ||
2291 | 2313 | ||
2292 | // Don't append ACKs to resent packets, in case that's what was causing the | 2314 | protected virtual void ProcessOutPacket(Packet Pack) |
2293 | // delivery to fail | 2315 | { |
2294 | if (!Pack.Header.Resent) | 2316 | // Keep track of when this packet was sent out |
2295 | { | 2317 | Pack.TickCount = System.Environment.TickCount; |
2296 | // Append any ACKs that need to be sent out to this packet | ||
2297 | lock (PendingAcks) | ||
2298 | { | ||
2299 | if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && | ||
2300 | Pack.Type != PacketType.PacketAck && | ||
2301 | Pack.Type != PacketType.LogoutRequest) | ||
2302 | { | ||
2303 | Pack.Header.AckList = new uint[PendingAcks.Count]; | ||
2304 | int i = 0; | ||
2305 | 2318 | ||
2306 | foreach (uint ack in PendingAcks.Values) | 2319 | if (!Pack.Header.Resent) |
2307 | { | 2320 | { |
2308 | Pack.Header.AckList[i] = ack; | 2321 | Pack.Header.Sequence = NextSeqNum(); |
2309 | i++; | ||
2310 | } | ||
2311 | 2322 | ||
2312 | PendingAcks.Clear(); | 2323 | if (Pack.Header.Reliable) //DIRTY HACK |
2313 | Pack.Header.AppendedAcks = true; | 2324 | { |
2314 | } | 2325 | AddAck(Pack); // this adds the need to ack this packet later |
2315 | } | 2326 | |
2327 | if (Pack.Type != PacketType.PacketAck && Pack.Type != PacketType.LogoutRequest) | ||
2328 | { | ||
2329 | SetPendingAcks(ref Pack); | ||
2316 | } | 2330 | } |
2317 | } | 2331 | } |
2318 | } | 2332 | } |
2319 | 2333 | ||
2320 | byte[] ZeroOutBuffer = new byte[4096]; | 2334 | // Actually make the byte array and send it |
2321 | byte[] sendbuffer; | ||
2322 | sendbuffer = Pack.ToBytes(); | ||
2323 | |||
2324 | try | 2335 | try |
2325 | { | 2336 | { |
2326 | if (Pack.Header.Zerocoded) | 2337 | byte[] sendbuffer = Pack.ToBytes(); |
2327 | { | 2338 | if (Pack.Header.Zerocoded) |
2328 | int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); | 2339 | { |
2329 | m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode); //userEP); | 2340 | byte[] ZeroOutBuffer = new byte[4096]; |
2330 | } | 2341 | int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); |
2331 | else | 2342 | m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode); |
2332 | { | 2343 | } |
2333 | m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode); | 2344 | else |
2334 | //userEP); | 2345 | { |
2335 | } | 2346 | m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode); |
2347 | } | ||
2336 | } | 2348 | } |
2337 | catch (Exception e) | 2349 | catch (Exception e) |
2338 | { | 2350 | { |
@@ -2343,7 +2355,7 @@ namespace OpenSim.Region.ClientStack | |||
2343 | KillThread(); | 2355 | KillThread(); |
2344 | } | 2356 | } |
2345 | } | 2357 | } |
2346 | 2358 | ||
2347 | public virtual void InPacket(Packet NewPack) | 2359 | public virtual void InPacket(Packet NewPack) |
2348 | { | 2360 | { |
2349 | // Handle appended ACKs | 2361 | // Handle appended ACKs |