ReassemblingHandshakeMessage extends GenericHandshakeMessage { public void add(FragmentedHandshakeMessage message) { if (type != message.getMessageType()) { throw new IllegalArgumentException( "Fragment message type " + message.getMessageType() + " differs from " + type + "!"); } else if (getMessageSeq() != message.getMessageSeq()) { throw new IllegalArgumentException("Fragment message sequence number " + message.getMessageSeq() + " differs from " + getMessageSeq() + "!"); } else if (getMessageLength() != message.getMessageLength()) { throw new IllegalArgumentException("Fragment message length " + message.getMessageLength() + " differs from " + getMessageLength() + "!"); } else if (!getPeer().equals(message.getPeer())) { throw new IllegalArgumentException( "Fragment message peer " + message.getPeer() + " differs from " + getPeer() + "!"); } if (isComplete()) { return; } FragmentRange newRange = new FragmentRange(message.getFragmentOffset(), message.getFragmentLength()); if (getMessageLength() < newRange.end) { throw new IllegalArgumentException( "Fragment message " + newRange.end + " bytes exceeds message " + getMessageLength() + " bytes!"); } int end = 0; int position = 0; for (; position < fragments.size(); ++position) { FragmentRange currentRange = fragments.get(position); if (newRange.offset < currentRange.offset) { if (currentRange.offset < newRange.end && newRange.end <= currentRange.end) { newRange.reduceEnd(currentRange.offset); } break; } else if (newRange.end <= currentRange.end) { return; } else if (newRange.offset == currentRange.offset) { ++position; break; } end = currentRange.end; } int skip = newRange.skipToOffset(end); if (newRange.length == 0) { return; } add(position, skip, newRange, message); FragmentRange currentRange = fragments.get(0); for (position = 1; position < fragments.size(); ++position) { FragmentRange nextRange = fragments.get(position); if (nextRange.offset <= currentRange.end) { currentRange.amendEnd(nextRange.end); fragments.remove(position); --position; } else { currentRange = nextRange; } } } ReassemblingHandshakeMessage(FragmentedHandshakeMessage message); boolean isComplete(); void add(FragmentedHandshakeMessage message); @Override HandshakeType getMessageType(); @Override int getMessageLength(); @Override String toString(); @Override byte[] fragmentToByteArray();  }
@Test(expected = IllegalArgumentException.class) public void testFragmentExceedMessageSize() { FragmentedHandshakeMessage first = fragments.get(0); ReassemblingHandshakeMessage message = new ReassemblingHandshakeMessage(first); FragmentedHandshakeMessage msg = new FragmentedHandshakeMessage(HandshakeType.CERTIFICATE, MESSAGE_SIZE, MESSAGE_SEQN + 1, first.getFragmentLength(), payload, peerAddress); message.add(msg); }