Java Damn Simple HTTP Proxy

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class HttpProxy {

  private static byte[] CONNECTION_ESTABLISHED =
      "HTTP/1.0 200 Connection established\r\nProxy-Agent: HTTP Proxy/1.0\r\n\r\n".getBytes();

  public static void main(String[] args) throws IOException {
    ExecutorService threadPool = Executors.newCachedThreadPool();
    ServerSocket serverSocket = new ServerSocket(8080);
    while (true) {
      threadPool.submit(new UpstramHandler(serverSocket.accept()));
    }
  }

  static class UpstramHandler implements Runnable {

    private final Socket socket;
    private final ExecutorService executorService;

    UpstramHandler(Socket socket) {
      this.socket = socket;
      this.executorService = Executors.newSingleThreadExecutor();
    }

    @Override
    public void run() {
      byte[] buffer = new byte[2048];
      while (true) {
        try {
          Socket remoteSocket = null;
          int recv = 1;
          while (recv > 0) {
            recv = socket.getInputStream().read(buffer);
            if (recv > 0) {
              if (recv > 8) {
                String s = new String(buffer, 0, 8);
                if (s.contains("CONNECT")) {
                  int endlIndx = 0;
                  for (int i = 8; i < recv - 1; i++) {
                    if (buffer[i] == '\r' && buffer[i + 1] == '\n') {
                      endlIndx = i + 1;
                      break;
                    }
                  }
                  if (endlIndx > 8) {
                    String request = new String(buffer, 0, endlIndx + 1);
                    int connectIndex = request.indexOf("CONNECT");
                    int startIndex = request.indexOf(" ", connectIndex) + 1;
                    int endIndex = request.indexOf(" ", startIndex);
                    String[] hostnameAndPort;
                    if (endIndex < startIndex) {
                      hostnameAndPort = request.substring(startIndex).split(":");
                    } else {
                      hostnameAndPort = request.substring(startIndex, endIndex).split(":");
                    }
                    String hostname = hostnameAndPort[0];
                    int port = Integer.parseInt(hostnameAndPort[1]);
                    remoteSocket = new Socket(hostname, port);
                    socket.getOutputStream().write(CONNECTION_ESTABLISHED);
                    socket.getOutputStream().flush();
                    executorService.submit(new DownstreamHandler(socket, remoteSocket));
                    continue;
                  }
                }
              }
              if (remoteSocket != null) {
                remoteSocket.getOutputStream().write(buffer, 0, recv);
                remoteSocket.getOutputStream().flush();
              }
            }
          }
        } catch (IOException e) {
          System.err.println(e);
        }
      }
    }
  }

  static class DownstreamHandler implements Runnable {

    private final Socket socket;
    private final Socket remoteSocket;

    DownstreamHandler(Socket socket, Socket remoteSocket) {
      this.socket = socket;
      this.remoteSocket = remoteSocket;
    }

    @Override
    public void run() {
      byte[] buffer = new byte[2048];
      int recv = 1;
      while (recv > 0) {
        try {
          recv = remoteSocket.getInputStream().read(buffer);
          if (recv > 0 && remoteSocket != null) {
            socket.getOutputStream().write(buffer, 0, recv);
            socket.getOutputStream().flush();
          }
        } catch (IOException e) {
          System.err.println(e);
        }
      }
    }
  }
}

Build JDK from source on Ubuntu 20.04

cd /home/iconplus/Download

wget -c https://releases.llvm.org/9.0.0/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz

tar -xvf clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz

./configure --with-num-cores=4 --with-memory-size=4096 --with-toolchain-type=clang --with-toolchain-path=/home/iconplus/Downloads/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-18.04/bin --with-libclang=/home/iconplus/Downloads/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-18.04

make images

Mikrotik Simple Routing

Mikrotik

  • Show IP

/ip dhcp-client print

  • Get IP from dhcp

/ip dhcp-client add interface=ether1 disable=no

  • Add bridge interface

/interface bridge add name=bridge1

/interface bridge port

add bridge=bridge1 interface=ether2

add bridge=bridge1 interface=ether3

  • Assign ip to bridge interface

/ip address add interface=bridge1 address=192.168.100.1/24

/ip route add gateway=bridge1

/ip dns set servers=8.8.8.8

/ip dns set allow-remote-request=yes

  • Configure firewall

/ip firewall nat add chain=srcnat out-interface=ether1 action=masquerade

/ip firewall nat print

  • Setup DHCP Server

/ip dhcp-server setup

Select interface to run DHCP server on 
dhcp server interface: bridge1
Select network for DHCP addresses 
dhcp address space: 192.168.100.0/24
Select gateway for given network 
gateway for dhcp network: 192.168.100.1
Select pool of ip addresses given out by DHCP server 
addresses to give out: 192.168.100.2-192.168.100.254
Select DNS servers 
dns servers: 8.8.8.8
Select lease time 
lease time: 10m 

/ip dhcp-server enable

/ip dhcp-server print

Ubuntu Client 20.04

  • Using DHCP client

dhclient eth0

  • Static IP

ip 192.168.100.2/24 192.168.100.1