Packet fragmentation had a bug

This commit is contained in:
Manevolent
2018-08-12 15:07:49 -04:00
parent 69024381de
commit 9d37b982d5
3 changed files with 77 additions and 3 deletions
@@ -3,7 +3,6 @@ package com.github.manevolent.ts3j.protocol.packet.fragment;
import com.github.manevolent.ts3j.protocol.Packet;
import com.github.manevolent.ts3j.protocol.header.HeaderFlag;
import com.github.manevolent.ts3j.util.QuickLZ;
import com.github.manevolent.ts3j.util.Ts3Debugging;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -19,6 +18,8 @@ public class PacketReassembly {
try {
// Pull out all other packets in the queue before this one which would also be fragmented
List<Integer> packetIds = new ArrayList<>();
for (int packetId = lastFragment.getHeader().getPacketId(); ; packetId--) {
if (packetId < 0) packetId = 65536 + packetId;
@@ -27,9 +28,14 @@ public class PacketReassembly {
if (olderPacket == null)
break; // Chain breaks here
else if (olderPacket.getHeader().getType() != lastFragment.getHeader().getType())
continue; // skip
continue; // skip???
else {
packetIds.add(packetId);
reassemblyList.add(olderPacket);
if (lastFragment.getHeader().getPacketId() != packetId &&
olderPacket.getHeader().getPacketFlag(HeaderFlag.FRAGMENTED))
break;
}
}
@@ -61,6 +67,9 @@ public class PacketReassembly {
reassembledPacket.readBody(reassemblyBuffer);
// Remove read packets
for (Integer packetId : packetIds) queue.remove(packetId);
return reassembledPacket;
} catch (Exception ex) {
throw new IOException("Problem reassembling " + reassemblyList.size() + " packet(s): [" +
@@ -9,7 +9,6 @@ import com.github.manevolent.ts3j.protocol.packet.fragment.Fragments;
import com.github.manevolent.ts3j.protocol.packet.fragment.PacketReassembly;
import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket;
import com.github.manevolent.ts3j.util.Pair;
import com.github.manevolent.ts3j.util.QuickLZ;
import com.github.manevolent.ts3j.util.Ts3Debugging;
import junit.framework.TestCase;
import org.bouncycastle.util.encoders.Base64;
@@ -0,0 +1,66 @@
package com.github.manevolent.ts3j;
import com.github.manevolent.ts3j.protocol.Packet;
import com.github.manevolent.ts3j.protocol.ProtocolRole;
import com.github.manevolent.ts3j.protocol.header.ClientPacketHeader;
import com.github.manevolent.ts3j.protocol.header.HeaderFlag;
import com.github.manevolent.ts3j.protocol.packet.PacketBody2Command;
import com.github.manevolent.ts3j.protocol.packet.PacketBodyType;
import com.github.manevolent.ts3j.protocol.packet.fragment.Fragments;
import com.github.manevolent.ts3j.protocol.packet.fragment.PacketBodyFragment;
import com.github.manevolent.ts3j.protocol.packet.fragment.PacketReassembly;
import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket;
import com.github.manevolent.ts3j.util.Pair;
import com.github.manevolent.ts3j.util.Ts3Debugging;
import junit.framework.TestCase;
import org.bouncycastle.util.encoders.Base64;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class FragmentTest2 extends TestCase {
public static void main(String[] args) throws Exception {
new FragmentTest2().testParser();
}
public void testParser() throws Exception {
Ts3Debugging.setEnabled(true);
String[] packets = new String[] {
// Put diagnostic here
};
List<Packet> pieces = new ArrayList<>();
for (int i = 0; i < packets.length; i ++) {
Packet packet = new Packet(ProtocolRole.SERVER);
ByteBuffer buffer = ByteBuffer.wrap(Base64.decode(packets[i]));
packet.readHeader(buffer);
packet.setBody(new PacketBodyFragment(packet.getHeader().getType(), ProtocolRole.SERVER));
packet.readBody(buffer);
pieces.add(packet);
Ts3Debugging.debug(
"Read type=" + packet.getHeader().getType()
+ " id=" + packet.getHeader().getPacketId()
+ " flags=" + packet.getHeader().getPacketFlags()
+ " fragment=" + packet.getHeader().getPacketFlag(HeaderFlag.FRAGMENTED)
);
}
Ts3Debugging.debug("Loaded " + pieces.size() + " pieces.");
PacketReassembly reassembly = new PacketReassembly();
for (Packet piece : pieces) {
Packet out = reassembly.put(piece);
if (out != null) {
Ts3Debugging.debug(((PacketBody2Command)out.getBody()).getText());
}
}
}
}