package org.kne.cloud.network.tun; import java.io.IOException; import java.lang.foreign.MemorySegment; import java.net.SocketException; import java.nio.ByteBuffer; import org.kne.cloud.network.tun.WintunDriver.Packet; import org.kne.cloud.network.tun.WintunDriver.SendPacket; import org.kne.cloud.network.tun.WintunDriver.WintunSessionHandle; public class WindowsTUNChannel implements TUNChannel { private WintunSessionHandle session; private MemorySegment waitevent; protected WindowsTUNChannel(WintunSessionHandle session) { this.session=session; this.waitevent =WintunDriver.getReadWaitEvent(session); } @Override public int write(ByteBuffer src) throws IOException { if(session==null) { throw new SocketException("TUN session closed!"); } int rem=src.remaining(); SendPacket sendPacket = WintunDriver.allocateSendPacket(session, rem); if (sendPacket != null) { sendPacket.data().asByteBuffer().put(src); sendPacket.send(); } return rem; } @Override public int read(ByteBuffer dst) throws IOException { while (true) { if(session==null) { throw new SocketException("TUN session closed!"); } WindowsWaitHandle.waitForSingleObject(waitevent, 10); Packet packet = WintunDriver.receivePacket(session); if (packet != null) { ByteBuffer bytebuf=packet.data().asByteBuffer(); int rem=Math.min(bytebuf.remaining(),dst.remaining()); dst.put(bytebuf); packet.release(); return rem; } } } @Override public boolean isOpen() { return session!=null; } @Override public void close() throws IOException { WintunSessionHandle wsh=session; session=null; WintunDriver.endSession(wsh); } }