private void ReceivePong(S2CPacket packet) { ushort answerId = BinaryPrimitives.ReadUInt16BigEndian(packet.Data); if (lastSentPingId == answerId) { var rtt = pingTimer.Elapsed; UpdateRto(rtt); NetworkStats.AddPing(rtt); } }
private void ReceivePong(S2CPacket packet) { ushort answerId = NetUtil.N2Hushort(packet.Data, 0); if (lastSentPingId == answerId) { var rtt = pingTimer.Elapsed; UpdateRto(rtt); NetworkStats.AddPing(rtt); } }
internal void LogInPacket(S2CPacket packet) { var kind = TypeToKind(packet.PacketType); inPackets[(int)kind]++; inBytes[(int)kind] += packet.Raw.Length; lock (queueLock) { DropOver(inBytesTime, TimeMinute); inBytesTime.Enqueue(new PacketData(packet.Raw.Length, Util.Now, kind)); } }
// These methods are for low level packet processing which the // rather high level TS3FullClient should not worry about. private void GenerateGenerationId(S2CPacket packet) { // TODO rework this for all packet types RingQueue <S2CPacket> packetQueue; switch (packet.PacketType) { case PacketType.Command: packetQueue = receiveQueue; break; case PacketType.CommandLow: packetQueue = receiveQueueLow; break; default: return; } packet.GenerationId = packetQueue.GetGeneration(packet.PacketId); }
private void ReceivePing(S2CPacket packet) { var idDiff = packet.PacketId - lastReceivedPingId; if (idDiff > 1 && idDiff < ReceivePacketWindowSize) { NetworkStats.LogLostPings(idDiff - 1); } if (idDiff > 0 || idDiff < -ReceivePacketWindowSize) { lastReceivedPingId = packet.PacketId; } byte[] pongData = new byte[2]; NetUtil.H2N(packet.PacketId, pongData, 0); AddOutgoingPacket(pongData, PacketType.Pong); }
private void ReceivePing(S2CPacket packet) { var idDiff = packet.PacketId - lastReceivedPingId; if (idDiff > 1 && idDiff < ReceivePacketWindowSize) { NetworkStats.LogLostPings(idDiff - 1); } if (idDiff > 0 || idDiff < -ReceivePacketWindowSize) { lastReceivedPingId = packet.PacketId; } byte[] pongData = new byte[2]; // stackalloc BinaryPrimitives.WriteUInt16BigEndian(pongData.AsSpan(), packet.PacketId); AddOutgoingPacket(pongData, PacketType.Pong); }
private S2CPacket ReceiveAck(S2CPacket packet) { if (packet.Data.Length < 2) { return(null); } ushort packetId = BinaryPrimitives.ReadUInt16BigEndian(packet.Data); lock (sendLoopLock) { if (packetAckManager.TryGetValue(packetId, out var ackPacket)) { UpdateRto(Util.Now - ackPacket.LastSendTime); packetAckManager.Remove(packetId); } } return(packet); }
private S2CPacket ReceiveAck(S2CPacket packet) { if (packet.Data.Length < 2) { return(null); } ushort packetId = NetUtil.N2Hushort(packet.Data, 0); lock (sendLoopLock) { if (packetAckManager.TryGetValue(packetId, out var ackPacket)) { UpdateRto(Util.Now - ackPacket.LastSendTime); packetAckManager.Remove(packetId); } } return(packet); }
private S2CPacket ReceiveCommand(S2CPacket packet, RingQueue <S2CPacket> packetQueue, PacketType ackType) { var setStatus = packetQueue.IsSet(packet.PacketId); // Check if we cannot accept this packet since it doesn't fit into the receive window if (setStatus == ItemSetStatus.OutOfWindowNotSet) { return(null); } packet.GenerationId = packetQueue.GetGeneration(packet.PacketId); SendAck(packet.PacketId, ackType); // Check if we already have this packet and only need to ack it. if (setStatus == ItemSetStatus.InWindowSet || setStatus == ItemSetStatus.OutOfWindowSet) { return(null); } packetQueue.Set(packet.PacketId, packet); return(TryFetchPacket(packetQueue, out var retPacket) ? retPacket : null); }
private void ReceiveInitAck(S2CPacket packet, bool done = false) { lock (sendLoopLock) { if (initPacketCheck == null || packet == null) { if (done) { initPacketCheck = null; } return; } // optional: add random number check from init data var forwardData = ts3Crypt.ProcessInit1(packet.Data); if (!forwardData.Ok) { LoggerRaw.Debug("Error init: {0}", forwardData.Error); return; } initPacketCheck = null; AddOutgoingPacket(forwardData.Value, PacketType.Init1); } }
private static bool TryFetchPacket(RingQueue <S2CPacket> packetQueue, out S2CPacket packet) { if (packetQueue.Count <= 0) { packet = null; return(false); } int take = 0; int takeLen = 0; bool hasStart = false; bool hasEnd = false; for (int i = 0; i < packetQueue.Count; i++) { if (packetQueue.TryPeekStart(i, out var peekPacket)) { take++; takeLen += peekPacket.Size; if (peekPacket.FragmentedFlag) { if (!hasStart) { hasStart = true; } else { hasEnd = true; break; } } else { if (!hasStart) { hasStart = true; hasEnd = true; break; } } } else { break; } } if (!hasStart || !hasEnd) { packet = null; return(false); } // GET if (!packetQueue.TryDequeue(out packet)) { throw new InvalidOperationException("Packet in queue got missing (?)"); } // MERGE if (take > 1) { var preFinalArray = new byte[takeLen]; // for loop at 0th element int curCopyPos = packet.Size; Array.Copy(packet.Data, 0, preFinalArray, 0, packet.Size); for (int i = 1; i < take; i++) { if (!packetQueue.TryDequeue(out S2CPacket nextPacket)) { throw new InvalidOperationException("Packet in queue got missing (?)"); } Array.Copy(nextPacket.Data, 0, preFinalArray, curCopyPos, nextPacket.Size); curCopyPos += nextPacket.Size; } packet.Data = preFinalArray; } // DECOMPRESS if (packet.CompressedFlag) { try { packet.Data = QuickerLz.Decompress(packet.Data, MaxDecompressedSize); } catch (Exception) { Debug.WriteLine("Got invalid compressed data."); return(false); } } return(true); }