package org.artisanlogiciel.games.minetest.net; import org.artisanlogiciel.games.minetest.core.PacketException; import java.io.IOException; import java.net.*; /** * Man in the middle UDP * very simple for one client only */ public class MiM { DatagramSocket serverSocket; boolean running = false; InetSocketAddress serverAddress; // will be captured, incoming address & port SocketAddress fromClient = null; int localPort; PacketHandler handler = null; public MiM(int myPort, InetSocketAddress remoteAddress) { localPort = myPort; serverAddress = remoteAddress; } public void launch() { // ServerSocket socket = new ServerSocket() try { handler = new PacketHandler(); serverSocket = new DatagramSocket(localPort); DatagramSocket in = serverSocket; SocketAddress fromServer = serverAddress; Thread toServer = new Thread( () -> {runFromToServer(in,fromServer);}); running = true; toServer.start(); } catch(Exception e) { System.out.println("problem"); e.printStackTrace(System.err); running = false; } } public void stop() { running = false; } public void runFromToServer(DatagramSocket in, SocketAddress fromServer) { try { while (running) { // quick way, a new buffer at each reception // to handle split packets that are buffered byte[] buf = new byte[4096]; SocketAddress toRemote = null; DatagramPacket packet = new DatagramPacket(buf, buf.length); in.receive(packet); SocketAddress from = packet.getSocketAddress(); if ( from.equals(fromServer)) { // no client yet if ( fromClient == null ) { continue; } fromServer(buf,packet.getLength()); toRemote = fromClient; } else { // record client // later on to be smart : could try to record peer id ? // will add a constraint : only one auth at a time if ( fromClient == null ) { fromClient = from; } fromClient(buf,packet.getLength()); toRemote = fromServer; } packet = new DatagramPacket(buf, packet.getLength(), toRemote); in.send(packet); } } catch( IOException ioException) { // System.out.println("oops"); } // socket.close(); } void fromServer(byte[] buffer, int length) { try { // reply from server if (handler != null) { handler.fromServer(buffer, length); } } catch (PacketException packetException) { // } } void fromClient(byte[] buffer, int length) { try { // reply from client if (handler != null) { handler.fromClient(buffer, length); } } catch (PacketException packetException) { // } } }