使用Java开发代理

IPv6Only

package com.github.monkeywie.proxyee;

import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class IPv6OnlyProxy {
    private static final int PROXY_PORT = 9999;
    private static final ExecutorService threadPool = Executors.newCachedThreadPool();

    public static void main(String[] args) {
        // 强制JVM使用IPv6
        System.setProperty("java.net.preferIPv6Addresses", "true");
        System.setProperty("java.net.preferIPv4Stack", "false");

        try {
            // 创建IPv6服务器套接字
            ServerSocket serverSocket = new ServerSocket();
            serverSocket.bind(new InetSocketAddress("::", PROXY_PORT));
            System.out.println("IPv6 Only Proxy Server running on port " + PROXY_PORT);

            while (true) {
                Socket clientSocket = serverSocket.accept();
                threadPool.submit(() -> handleClient(clientSocket));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void handleClient(Socket clientSocket) {
        try {
            // 读取客户端请求
            BufferedReader clientReader = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));

            // 解析请求行
            String requestLine = clientReader.readLine();
            if (requestLine == null) return;

            String[] parts = requestLine.split(" ");
            if (parts.length < 2) return;

            String method = parts[0];
            String urlStr = parts[1];

            // 解析目标主机和端口
            URL url;
            try {
                url = new URL(urlStr);
            } catch (MalformedURLException e) {
                // 处理CONNECT方法(HTTPS)
                if (method.equalsIgnoreCase("CONNECT")) {
                    String[] hostPort = urlStr.split(":");
                    String host = hostPort[0];
                    int port = hostPort.length > 1 ? Integer.parseInt(hostPort[1]) : 443;
                    handleHttpsConnect(clientSocket, host, port);
                    return;
                }
                throw e;
            }

            String host = url.getHost();
            int port = url.getPort() != -1 ? url.getPort() : url.getDefaultPort();

            // 只允许IPv6连接
            InetAddress[] addresses = Inet6Address.getAllByName(host);
            if (addresses.length == 0) {
                sendErrorResponse(clientSocket, "No IPv6 address available for " + host);
                return;
            }
            InetAddress ipv6Only=null;
            for(int i=0;i<addresses.length;i++){
                InetAddress ia=addresses[i];
                if(ia instanceof  Inet6Address){
                    ipv6Only=ia;
                }
                System.out.println("host:"+host+ " addr:"+new String(ia.getAddress()));
            }
            if(ipv6Only==null){
                return;
            }

            // 连接到目标服务器(IPv6)
            try (Socket serverSocket = new Socket()) {
                //serverSocket.connect(new InetSocketAddress(addresses[0], port), 5000);
                serverSocket.connect(new InetSocketAddress(ipv6Only, port), 5000);

                // 转发请求
                if (method.equalsIgnoreCase("CONNECT")) {
                    // HTTPS连接已在上方处理
                    return;
                }

                // HTTP请求
                OutputStream serverOut = serverSocket.getOutputStream();
                PrintWriter serverWriter = new PrintWriter(serverOut, true);

                // 发送请求行
                serverWriter.println(requestLine);

                // 转发头部
                String line;
                while (!(line = clientReader.readLine()).isEmpty()) {
                    serverWriter.println(line);
                }
                serverWriter.println();

                // 转发响应
                InputStream serverIn = serverSocket.getInputStream();
                OutputStream clientOut = clientSocket.getOutputStream();

                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = serverIn.read(buffer)) != -1) {
                    clientOut.write(buffer, 0, bytesRead);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void handleHttpsConnect(Socket clientSocket, String host, int port) {
        try {
            // 解析IPv6地址
            InetAddress[] addresses = Inet6Address.getAllByName(host);
            if (addresses.length == 0) {
                sendErrorResponse(clientSocket, "No IPv6 address available for " + host);
                return;
            }
            InetAddress ipv6Only=null;
            for(int i=0;i<addresses.length;i++){
                InetAddress ia=addresses[i];
                if(ia instanceof  Inet6Address){
                    ipv6Only=ia;
                }
                System.out.println("host:"+host+ " addr:"+new String(ia.getAddress()));
            }
            if(ipv6Only==null){
                return;
            }

            // 连接到目标服务器
            try (Socket serverSocket = new Socket()) {
                //serverSocket.connect(new InetSocketAddress(addresses[0], port), 5000);
                serverSocket.connect(new InetSocketAddress(ipv6Only, port), 5000);

                // 发送200 Connection Established响应
                PrintWriter clientWriter = new PrintWriter(clientSocket.getOutputStream(), true);
                clientWriter.println("HTTP/1.1 200 Connection Established");
                clientWriter.println("Proxy-agent: IPv6-Only-Proxy/1.0");
                clientWriter.println();
                clientWriter.flush();

                // 双向转发数据
                forwardData(clientSocket, serverSocket);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void forwardData(Socket source, Socket destination) {
        threadPool.submit(() -> {
            try {
                InputStream in = source.getInputStream();
                OutputStream out = destination.getOutputStream();
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
            } catch (IOException e) {
                // 连接关闭
            }
        });

        try {
            InputStream in = destination.getInputStream();
            OutputStream out = source.getOutputStream();
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            // 连接关闭
        }
    }

    private static void sendErrorResponse(Socket clientSocket, String message) {
        try {
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
            out.println("HTTP/1.1 502 Bad Gateway");
            out.println("Content-Type: text/plain");
            out.println();
            out.println("502 Bad Gateway: " + message);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

文/程忠 浏览次数:0次   2025-04-17 16:11:53

相关阅读


评论:
点击刷新

↓ 广告开始-头部带绿为生活 ↓
↑ 广告结束-尾部支持多点击 ↑