All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.davfx.ninio.ssh.SshPacketOuputHandler Maven / Gradle / Ivy

package com.davfx.ninio.ssh;

import java.nio.ByteBuffer;
import java.security.SecureRandom;

import com.davfx.ninio.common.Address;
import com.davfx.ninio.common.CloseableByteBufferHandler;
import com.google.common.primitives.Ints;

final class SshPacketOuputHandler implements CloseableByteBufferHandler {
	static final int PLEASE_AVOID_COPY_OFFSET = Ints.BYTES + 1;
	
	private static final SecureRandom RANDOM = new SecureRandom();

	private static final int PADDING = 16;
	
	private final CloseableByteBufferHandler wrappee;
	
	public SshPacketOuputHandler(CloseableByteBufferHandler wrappee) {
		this.wrappee = wrappee;
	}
	
	@Override
	public void close() {
		wrappee.close();
	}
	
	@Override
	public void handle(Address address, ByteBuffer buffer) {
		int len = buffer.remaining();
		
		int pad = (-(len + Ints.BYTES + 1)) & (PADDING - 1);
		if (pad < PADDING) {
			pad += PADDING;
		}

		byte[] r = new byte[pad];
		RANDOM.nextBytes(r);

		if (buffer.position() < PLEASE_AVOID_COPY_OFFSET) {
			ByteBuffer b = ByteBuffer.allocate(Ints.BYTES + 1 + len + pad);
			b.putInt(len + pad + 1);
			b.put((byte) pad);
			b.put(buffer);
			b.put(r);
			b.flip();
			buffer = b;
		} else {
			// This optimisation is valid (no buffer copy) if ByteBuffer has space before the actual data
			buffer.position(buffer.position() - PLEASE_AVOID_COPY_OFFSET);
			buffer.putInt(len + pad + 1);
			buffer.put((byte) pad);
			buffer.position(buffer.position() + len);
			buffer.limit(buffer.position() + r.length);
			buffer.put(r);
			buffer.position(buffer.position() - r.length - len - PLEASE_AVOID_COPY_OFFSET);
		}
		
		wrappee.handle(address, buffer);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy