private static IEnumerable <OutgoingPacket> BuildSplitList(byte[] rawData, PacketType packetType) { int pos = 0; bool first = true; bool last; const int maxContent = MaxPacketSize - HeaderSize; do { int blockSize = Math.Min(maxContent, rawData.Length - pos); if (blockSize <= 0) { break; } var tmpBuffer = new byte[blockSize]; Array.Copy(rawData, pos, tmpBuffer, 0, blockSize); var packet = new OutgoingPacket(tmpBuffer, packetType); last = pos + blockSize == rawData.Length; if (first ^ last) { packet.FragmentedFlag = true; } if (first) { first = false; } yield return(packet); pos += blockSize; } while (!last); }
private void AddOutgoingPacket(OutgoingPacket packet, PacketFlags flags = PacketFlags.None) { lock (sendLoopLock) { var ids = GetPacketCounter(packet.PacketType); if (ts3Crypt.CryptoInitComplete) { IncPacketCounter(packet.PacketType); } packet.PacketId = ids.Id; packet.GenerationId = ids.Generation; packet.ClientId = ClientId; packet.PacketFlags |= flags; switch (packet.PacketType) { case PacketType.Voice: case PacketType.VoiceWhisper: packet.PacketFlags |= PacketFlags.Unencrypted; NetUtil.H2N(packet.PacketId, packet.Data, 0); break; case PacketType.Command: case PacketType.CommandLow: packet.PacketFlags |= PacketFlags.Newprotocol; packetAckManager.Add(packet.PacketId, packet); break; case PacketType.Ping: lastSentPingId = packet.PacketId; packet.PacketFlags |= PacketFlags.Unencrypted; break; case PacketType.Pong: packet.PacketFlags |= PacketFlags.Unencrypted; break; case PacketType.Ack: case PacketType.AckLow: break; // Nothing to do case PacketType.Init1: packet.PacketFlags |= PacketFlags.Unencrypted; packetAckManager.Add(packet.PacketId, packet); break; default: throw Util.UnhandledDefault(packet.PacketType); } ColorDbg.WritePkgOut(packet); ts3Crypt.Encrypt(packet); packet.FirstSendTime = Util.Now; SendRaw(packet); } }
private void AddOutgoingPacket(OutgoingPacket packet, PacketFlags flags = PacketFlags.None) { lock (sendLoopLock) { if (packet.PacketType == PacketType.Init1) { packet.PacketFlags |= flags | PacketFlags.Unencrypted; packet.PacketId = 101; packet.ClientId = 0; } else { if (packet.PacketType == PacketType.Ping || packet.PacketType == PacketType.Pong || packet.PacketType == PacketType.Voice || packet.PacketType == PacketType.VoiceWhisper) { packet.PacketFlags |= flags | PacketFlags.Unencrypted; } else if (packet.PacketType == PacketType.Ack) { packet.PacketFlags |= flags; } else { packet.PacketFlags |= flags | PacketFlags.Newprotocol; } var ids = GetPacketCounter(packet.PacketType); packet.PacketId = ids.Item1; packet.GenerationId = ids.Item2; if (packet.PacketType == PacketType.Voice || packet.PacketType == PacketType.VoiceWhisper) { NetUtil.H2N(packet.PacketId, packet.Data, 0); } if (ts3Crypt.CryptoInitComplete) { IncPacketCounter(packet.PacketType); } packet.ClientId = ClientId; } ts3Crypt.Encrypt(packet); if (packet.PacketType == PacketType.Command || packet.PacketType == PacketType.CommandLow || packet.PacketType == PacketType.Init1) { packetAckManager.Add(packet.PacketId, packet); } else if (packet.PacketType == PacketType.Ping) { packetPingManager.Add(packet.PacketId, packet); } SendRaw(packet); } }
private void AddOutgoingPacket(OutgoingPacket packet, PacketFlags flags = PacketFlags.None) { lock (sendLoopLock) { if (packet.PacketType == PacketType.Init1) { packet.PacketFlags |= flags | PacketFlags.Unencrypted; packet.PacketId = 101; packet.ClientId = 0; } else { if (packet.PacketType == PacketType.Ping || packet.PacketType == PacketType.Pong || packet.PacketType == PacketType.Voice || packet.PacketType == PacketType.VoiceWhisper) { packet.PacketFlags |= flags | PacketFlags.Unencrypted; } else if (packet.PacketType == PacketType.Ack) { packet.PacketFlags |= flags; } else { packet.PacketFlags |= flags | PacketFlags.Newprotocol; } packet.PacketId = GetPacketCounter(packet.PacketType); if (packet.PacketType == PacketType.Voice || packet.PacketType == PacketType.VoiceWhisper) { NetUtil.H2N(packet.PacketId, packet.Data, 0); } if (ts3Crypt.CryptoInitComplete) { IncPacketCounter(packet.PacketType); } packet.ClientId = ClientId; } ts3Crypt.Encrypt(packet); if (packet.PacketType == PacketType.Command || packet.PacketType == PacketType.CommandLow || packet.PacketType == PacketType.Init1) { packetAckManager.Add(packet.PacketId, packet); } else if (packet.PacketType == PacketType.Ping) { try { packetPingManager.Add(packet.PacketId, packet); } catch { Console.WriteLine("Error with ping packet"); } } SendRaw(packet); } }
public void LogOutPacket(OutgoingPacket packet) { var kind = TypeToKind(packet.PacketType); outPackets[(int)kind]++; outBytes[(int)kind] += packet.Raw.Length; lock (queueLock) { DropOver(outBytesTime, TimeMinute); outBytesTime.Enqueue(new PacketData(packet.Raw.Length, Util.Now, kind)); } }
private void FakeEncrypt(OutgoingPacket packet, byte[] mac) { packet.BuildHeader(); packet.Raw = new byte[packet.Data.Length + MacLen + OutHeaderLen]; // Copy the Mac from [Mac...] to [Mac..., Header..., Data...] Array.Copy(mac, 0, packet.Raw, 0, MacLen); // Copy the Header from packet.Header to [Mac..., Header..., Data...] Array.Copy(packet.Header, 0, packet.Raw, MacLen, OutHeaderLen); // Copy the Data from packet.Data to [Mac..., Header..., Data...] Array.Copy(packet.Data, 0, packet.Raw, MacLen + OutHeaderLen, packet.Data.Length); // Raw is now [Mac..., Header..., Data...] }
internal void Encrypt(OutgoingPacket packet) { if (packet.PacketType == PacketType.Init1) { FakeEncrypt(packet, TS3InitMac); return; } if (packet.UnencryptedFlag) { FakeEncrypt(packet, fakeSignature); return; } var keyNonce = GetKeyNonce(false, packet.PacketId, packet.GenerationId, packet.PacketType); packet.BuildHeader(); ICipherParameters ivAndKey = new AeadParameters(new KeyParameter(keyNonce.Item1), 8 * MacLen, keyNonce.Item2, packet.Header); byte[] result; int len; lock (eaxCipher) { eaxCipher.Init(true, ivAndKey); result = new byte[eaxCipher.GetOutputSize(packet.Size)]; try { len = eaxCipher.ProcessBytes(packet.Data, 0, packet.Size, result, 0); len += eaxCipher.DoFinal(result, len); } catch (Exception ex) { throw new Ts3Exception("Internal encryption error.", ex); } } // result consists of [Data..., Mac...] // to build the final TS3/libtomcrypt we need to copy it into another order // len is Data.Length + Mac.Length packet.Raw = new byte[OutHeaderLen + len]; // Copy the Mac from [Data..., Mac...] to [Mac..., Header..., Data...] Array.Copy(result, len - MacLen, packet.Raw, 0, MacLen); // Copy the Header from packet.Header to [Mac..., Header..., Data...] Array.Copy(packet.Header, 0, packet.Raw, MacLen, OutHeaderLen); // Copy the Data from [Data..., Mac...] to [Mac..., Header..., Data...] Array.Copy(result, 0, packet.Raw, MacLen + OutHeaderLen, len - MacLen); // Raw is now [Mac..., Header..., Data...] }
private void SendRaw(OutgoingPacket packet) { packet.LastSendTime = Util.Now; NetworkStats.LogOutPacket(packet); udpClient.Send(packet.Raw, packet.Raw.Length); }