private void Initialize(IPEndPoint address, bool connect) { lock (sendLoopLock) { ClientId = 0; closed = 0; smoothedRtt = MaxRetryInterval; smoothedRttVar = TimeSpan.Zero; currentRto = MaxRetryInterval; lastSentPingId = 0; lastReceivedPingId = 0; lastMessageTimer.Restart(); initPacketCheck = null; packetAckManager.Clear(); receiveQueueCommand.Clear(); receiveQueueCommandLow.Clear(); receiveWindowVoice.Reset(); receiveWindowVoiceWhisper.Reset(); Array.Clear(packetCounter, 0, packetCounter.Length); Array.Clear(generationCounter, 0, generationCounter.Length); NetworkStats.Reset(); socket?.Dispose(); try { if (connect) { remoteAddress = address; socket = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); socket.Bind(new IPEndPoint(address.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, 0)); var socketEventArgs = new SocketAsyncEventArgs(); socketEventArgs.SetBuffer(new byte[4096], 0, 4096); socketEventArgs.Completed += FetchPacketEvent; socketEventArgs.UserToken = this; socketEventArgs.RemoteEndPoint = remoteAddress; socket.ReceiveFromAsync(socketEventArgs); } else { remoteAddress = null; socket = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); socket.Bind(address); // TODO init socketevargs stuff } } catch (SocketException ex) { throw new Ts3Exception("Could not connect", ex); } pingCheckRunning = 0; pingCheck = Util.Now; if (resendTimer == null) { resendTimer = new Timer((_) => { using (MappedDiagnosticsContext.SetScoped("BotId", id)) ResendLoop(); }, null, ClockResolution, ClockResolution); } } }
private void Initialize(IPEndPoint address, bool connect) { var resendThread = new Thread(ResendLoop) { Name = "PacketHandler" }; resendThreadId = resendThread.ManagedThreadId; lock (sendLoopLock) { ClientId = 0; ExitReason = null; smoothedRtt = MaxRetryInterval; smoothedRttVar = TimeSpan.Zero; currentRto = MaxRetryInterval; lastSentPingId = 0; lastReceivedPingId = 0; lastMessageTimer.Restart(); initPacketCheck = null; packetAckManager.Clear(); receiveQueueCommand.Clear(); receiveQueueCommandLow.Clear(); receiveWindowVoice.Reset(); receiveWindowVoiceWhisper.Reset(); Array.Clear(packetCounter, 0, packetCounter.Length); Array.Clear(generationCounter, 0, generationCounter.Length); NetworkStats.Reset(); udpClient?.Dispose(); try { if (connect) { remoteAddress = address; udpClient = new UdpClient(address.AddressFamily); udpClient.Connect(address); } else { remoteAddress = null; udpClient = new UdpClient(address); } } catch (SocketException ex) { throw new Ts3Exception("Could not connect", ex); } } try { resendThread.Start(); } catch (SystemException ex) { throw new Ts3Exception("Error initializing internal stuctures", ex); } }
private void RegistResendPacket(CoopPacket packet, Func <Coop_Model_ACK, bool> onReceiveAck, Func <Coop_Model_Base, bool> onPreResend = null) { packet.model.r = true; ResendPacket resendPacket = new ResendPacket(); resendPacket.resendCount = 0; resendPacket.lastSendTime = Time.get_time(); resendPacket.onReceiveAck = onReceiveAck; resendPacket.onPreResend = onPreResend; resendPacket.packet = packet; resendPackets.Add((uint)packet.sequenceNo, resendPacket); }
public void Listen(IPEndPoint address) { lock (sendLoopLock) { Initialize(address, false).Unwrap(); // dummy initPacketCheck = new ResendPacket <TOut>(new Packet <TOut>(Array.Empty <byte>(), 0, 0, 0)) { FirstSendTime = DateTime.MaxValue, LastSendTime = DateTime.MaxValue }; } }
private void RemoveResendPacket(CoopPacket packet) { if (packet.packetType == PACKET_TYPE.ACK || packet.packetType == PACKET_TYPE.REGISTER_ACK || packet.packetType == PACKET_TYPE.PARTY_REGISTER_ACK || packet.packetType == PACKET_TYPE.LOUNGE_REGISTER_ACK) { Coop_Model_ACK coop_Model_ACK = packet.model as Coop_Model_ACK; if (coop_Model_ACK != null) { ResendPacket resendPacket = resendPackets.Get((uint)coop_Model_ACK.ack); if (resendPacket != null) { bool flag = coop_Model_ACK.positive; if (resendPacket.onReceiveAck != null) { flag = resendPacket.onReceiveAck(coop_Model_ACK); } if (flag) { LogDebug("Remove a packet from the resending queue: packet={0}, ack={1}", resendPacket.packet, coop_Model_ACK.ack); resendPackets.Remove((uint)coop_Model_ACK.ack); } } } } }
// is always locked on 'sendLoopLock' from a higher call private E <string> SendOutgoingData(ReadOnlySpan <byte> data, PacketType packetType, PacketFlags flags = PacketFlags.None) { var ids = GetPacketCounter(packetType); IncPacketCounter(packetType); var packet = new Packet <TOut>(data, packetType, ids.Id, ids.Generation) { PacketType = packetType }; if (typeof(TOut) == typeof(C2S)) // TODO: XXX { var meta = (C2S)(object)packet.HeaderExt !; meta.ClientId = ClientId.Value; packet.HeaderExt = (TOut)(object)meta; } packet.PacketFlags |= flags; switch (packet.PacketType) { case PacketType.Voice: case PacketType.VoiceWhisper: packet.PacketFlags |= PacketFlags.Unencrypted; BinaryPrimitives.WriteUInt16BigEndian(packet.Data, packet.PacketId); LogRawVoice.Trace("[O] {0}", packet); break; case PacketType.Command: case PacketType.CommandLow: packet.PacketFlags |= PacketFlags.Newprotocol; var resendPacket = new ResendPacket <TOut>(packet); packetAckManager.Add(packet.PacketId, resendPacket); LogRaw.Debug("[O] {0}", packet); break; case PacketType.Ping: lastSentPingId = packet.PacketId; packet.PacketFlags |= PacketFlags.Unencrypted; LogRaw.Trace("[O] Ping {0}", packet.PacketId); break; case PacketType.Pong: packet.PacketFlags |= PacketFlags.Unencrypted; LogRaw.Trace("[O] Pong {0}", BinaryPrimitives.ReadUInt16BigEndian(packet.Data)); break; case PacketType.Ack: LogRaw.Debug("[O] Acking Ack: {0}", BinaryPrimitives.ReadUInt16BigEndian(packet.Data)); break; case PacketType.AckLow: packet.PacketFlags |= PacketFlags.Unencrypted; LogRaw.Debug("[O] Acking AckLow: {0}", BinaryPrimitives.ReadUInt16BigEndian(packet.Data)); break; case PacketType.Init1: packet.PacketFlags |= PacketFlags.Unencrypted; initPacketCheck = new ResendPacket <TOut>(packet); LogRaw.Debug("[O] InitID: {0}", packet.Data[4]); LogRaw.Trace("[O] {0}", packet); break; default: throw Tools.UnhandledDefault(packet.PacketType); } tsCrypt.Encrypt(ref packet); return(SendRaw(ref packet)); }