예제 #1
0
        private void ParseData(SocketObject asyncState, byte[] byteData, int nReceived)
        {
            if ((byteData == null) || (byteData[9] != 6))
            {
                return;
            }
            var startIndex = (byte) ((byteData[0] & 15) * 4);
            var lengthCheck = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(byteData, 2));
            if ((nReceived < lengthCheck) || (startIndex > lengthCheck))
            {
                return;
            }
            var IP = new IPHeader(byteData, nReceived);
            var TCP = new TCPHeader(byteData, nReceived);
            var serverConnection = new ServerConnection
            {
                SourceAddress = (uint) BitConverter.ToInt32(byteData, 12),
                DestinationAddress = (uint) BitConverter.ToInt32(byteData, 16),
                SourcePort = (ushort) BitConverter.ToInt16(byteData, startIndex),
                DestinationPort = (ushort) BitConverter.ToInt16(byteData, startIndex + 2),
                TimeStamp = DateTime.Now
                /*
                    // these don't return the right ports for some reason
                    DestinationAddress = BitConverter.ToUInt32(IP.DestinationAddress.GetAddressBytes(), 0),
                    DestinationPort = Convert.ToUInt16(TCP.DestinationPort),
                    SourcePort = Convert.ToUInt16(TCP.SourcePort),
                    SourceAddress = BitConverter.ToUInt32(IP.SourceAddress.GetAddressBytes(), 0),
                    TimeStamp = DateTime.Now
                 */
            };
            lock (Lock)
            {
                var found = Enumerable.Contains(ServerConnections, serverConnection);
                if (!found)
                {
                    if (Enumerable.Contains(DroppedConnections, serverConnection))
                    {
                        return;
                    }
                    UpdateConnectionList();
                    if (!Enumerable.Contains(ServerConnections, serverConnection))
                    {
                        DroppedConnections.Add(serverConnection);
                        return;
                    }
                }
            }
            if ((startIndex + 12) > nReceived)
            {
                return;
            }
            var nextTCPSequence = (uint) IPAddress.NetworkToHostOrder(BitConverter.ToInt32(byteData, startIndex + 4));
            var cut = (byte) (((byteData[startIndex + 12] & 240) >> 4) * 4);
            var length = (nReceived - startIndex) - cut;
            if ((length < 0) || (length > 0x10000))
            {
                return;
            }

            if (lengthCheck == startIndex + cut)
            {
                return;
            }

            lock (asyncState.SocketLock)
            {
                var connection = asyncState.Connections.FirstOrDefault(x => x.Equals(serverConnection));
                if (connection == null)
                {
                    connection = new NetworkConnection
                    {
                        SourceAddress = serverConnection.SourceAddress,
                        SourcePort = serverConnection.SourcePort,
                        DestinationAddress = serverConnection.DestinationAddress,
                        DestinationPort = serverConnection.DestinationPort
                    };
                    asyncState.Connections.Add(connection);
                }
                if (length == 0)
                {
                    return;
                }
                var destinationBuffer = new byte[length];
                Array.Copy(byteData, startIndex + cut, destinationBuffer, 0, length);
                if (connection.StalePackets.ContainsKey(nextTCPSequence))
                {
                    connection.StalePackets.Remove(nextTCPSequence);
                }
                var packet = new NetworkPacket
                {
                    TCPSequence = nextTCPSequence,
                    Buffer = destinationBuffer,
                    Push = (byteData[startIndex + 13] & 8) != 0
                };
                connection.StalePackets.Add(nextTCPSequence, packet);


                if (!connection.NextTCPSequence.HasValue)
                {
                    connection.NextTCPSequence = nextTCPSequence;
                }
                if (connection.StalePackets.Count == 1)
                {
                    connection.LastGoodNetworkPacketTime = DateTime.Now;
                }

                if (!connection.StalePackets.Any(x => (x.Key <= connection.NextTCPSequence.Value)))
                {
                    if (DateTime.Now.Subtract(connection.LastGoodNetworkPacketTime)
                                .TotalSeconds <= 10.0)
                    {
                        return;
                    }
                    connection.NextTCPSequence = connection.StalePackets.Min(x => x.Key);
                }
                while (connection.StalePackets.Any(x => x.Key <= connection.NextTCPSequence.Value))
                {
                    NetworkPacket stalePacket;
                    uint sequenceLength = 0;
                    if (connection.StalePackets.ContainsKey(connection.NextTCPSequence.Value))
                    {
                        stalePacket = connection.StalePackets[connection.NextTCPSequence.Value];
                    }
                    else
                    {
                        stalePacket = (connection.StalePackets.Where(x => x.Key <= connection.NextTCPSequence.Value)
                                                 .OrderBy(x => x.Key)).FirstOrDefault()
                                                                      .Value;
                        sequenceLength = connection.NextTCPSequence.Value - stalePacket.TCPSequence;
                    }
                    connection.StalePackets.Remove(stalePacket.TCPSequence);
                    if (connection.NetworkBufferPosition == 0)
                    {
                        connection.LastNetworkBufferUpdate = DateTime.Now;
                    }
                    if (sequenceLength >= stalePacket.Buffer.Length)
                    {
                        continue;
                    }
                    connection.NextTCPSequence = stalePacket.TCPSequence + ((uint) stalePacket.Buffer.Length);
                    Array.Copy(stalePacket.Buffer, sequenceLength, connection.NetworkBuffer, connection.NetworkBufferPosition, stalePacket.Buffer.Length - sequenceLength);
                    connection.NetworkBufferPosition += stalePacket.Buffer.Length - ((int) sequenceLength);
                    if (stalePacket.Push)
                    {
                        ProcessNetworkBuffer(connection);
                    }
                }
            }
        }
예제 #2
0
        private void ParseData(SocketObject asyncState, byte[] byteData, int nReceived)
        {
            if ((byteData == null) || (byteData[9] != 6))
            {
                return;
            }
            var startIndex  = (byte)((byteData[0] & 15) * 4);
            var lengthCheck = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(byteData, 2));

            if ((nReceived < lengthCheck) || (startIndex > lengthCheck))
            {
                return;
            }
            var IP  = new IPHeader(byteData, nReceived);
            var TCP = new TCPHeader(byteData, nReceived);
            var serverConnection = new ServerConnection
            {
                DestinationAddress = BitConverter.ToUInt32(IP.DestinationAddress.GetAddressBytes(), 0),
                DestinationPort    = Convert.ToUInt16(TCP.DestinationPort),
                SourcePort         = Convert.ToUInt16(TCP.SourcePort),
                SourceAddress      = BitConverter.ToUInt32(IP.SourceAddress.GetAddressBytes(), 0),
                TimeStamp          = DateTime.Now
            };

            lock (Lock)
            {
                var found = Enumerable.Contains(ServerConnections, serverConnection);
                if (!found)
                {
                    if (Enumerable.Contains(DroppedConnections, serverConnection))
                    {
                        found = true;
                    }
                    if (found)
                    {
                        return;
                    }
                    UpdateConnectionList();
                    if (Enumerable.Contains(ServerConnections, serverConnection))
                    {
                        found = true;
                    }
                    if (!found)
                    {
                        DroppedConnections.Add(serverConnection);
                        return;
                    }
                }
            }
            if ((startIndex + 12) > nReceived)
            {
                return;
            }
            var nextTCPSequence = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(byteData, startIndex + 4));
            var cut             = (byte)(((byteData[startIndex + 12] & 240) >> 4) * 4);
            var length          = (nReceived - startIndex) - cut;

            if ((length < 0) || (length > 0x10000))
            {
                return;
            }
            lock (asyncState.SocketLock)
            {
                Func <KeyValuePair <uint, NetworkPacket>, bool> func = null;
                Func <NetworkConnection, bool> predicate             = x => x.Equals(serverConnection);
                var connection = asyncState.Connections.FirstOrDefault(predicate);
                if (connection == null)
                {
                    connection = new NetworkConnection
                    {
                        SourceAddress      = serverConnection.SourceAddress,
                        SourcePort         = serverConnection.SourcePort,
                        DestinationAddress = serverConnection.DestinationAddress,
                        DestinationPort    = serverConnection.DestinationPort
                    };
                    asyncState.Connections.Add(connection);
                }
                if (length == 0)
                {
                    return;
                }
                var destinationBuffer = new byte[length];
                Array.Copy(byteData, startIndex + cut, destinationBuffer, 0, length);
                if (connection.StalePackets.ContainsKey(nextTCPSequence))
                {
                    connection.StalePackets.Remove(nextTCPSequence);
                }
                var packet = new NetworkPacket
                {
                    TCPSequence = nextTCPSequence,
                    Buffer      = destinationBuffer,
                    Push        = (byteData[startIndex + 13] & 8) != 0
                };
                connection.StalePackets.Add(nextTCPSequence, packet);
                if (!connection.NextTCPSequence.HasValue)
                {
                    connection.NextTCPSequence = nextTCPSequence;
                }
                if (connection.StalePackets.Count == 1)
                {
                    connection.LastGoodNetworkPacketTime = DateTime.Now;
                }
                if (!connection.StalePackets.Any(x => (x.Key <= connection.NextTCPSequence.Value)))
                {
                    if (DateTime.Now.Subtract(connection.LastGoodNetworkPacketTime)
                        .TotalSeconds <= 10.0)
                    {
                        return;
                    }
                    connection.NextTCPSequence = connection.StalePackets.Min(x => x.Key);
                }
                while (connection.StalePackets.Any(x => x.Key <= connection.NextTCPSequence.Value))
                {
                    NetworkPacket stalePacket;
                    uint          sequenceLength = 0;
                    if (connection.StalePackets.ContainsKey(connection.NextTCPSequence.Value))
                    {
                        stalePacket = connection.StalePackets[connection.NextTCPSequence.Value];
                    }
                    else
                    {
                        if (func == null)
                        {
                            func = x => x.Key <= connection.NextTCPSequence.Value;
                        }
                        stalePacket = (connection.StalePackets.Where(func)
                                       .OrderBy(x => x.Key)).FirstOrDefault()
                                      .Value;
                        sequenceLength = connection.NextTCPSequence.Value - stalePacket.TCPSequence;
                    }
                    connection.StalePackets.Remove(stalePacket.TCPSequence);
                    if (connection.NetworkBufferPosition == 0)
                    {
                        connection.LastNetworkBufferUpdate = DateTime.Now;
                    }
                    if (sequenceLength >= stalePacket.Buffer.Length)
                    {
                        continue;
                    }
                    connection.NextTCPSequence = stalePacket.TCPSequence + ((uint)stalePacket.Buffer.Length);
                    Array.Copy(stalePacket.Buffer, sequenceLength, connection.NetworkBuffer, connection.NetworkBufferPosition, stalePacket.Buffer.Length - sequenceLength);
                    connection.NetworkBufferPosition += stalePacket.Buffer.Length - ((int)sequenceLength);
                    if (stalePacket.Push)
                    {
                        ProcessNetworkBuffer(connection);
                    }
                }
            }
        }