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); } } } }
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); } } } }