package org.rx.socks.proxy;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.rx.common.Logger; import java.util.function.BiConsumer; import static org.rx.common.Contract.require; public class DirectClientHandler extends SimpleChannelInboundHandler<byte[]> {
private BiConsumer<ChannelHandlerContext, byte[]> onReceive;
private ChannelHandlerContext ctx; public Channel getChannel() {
require(ctx);
return ctx.channel();
} public DirectClientHandler(BiConsumer<ChannelHandlerContext, byte[]> onReceive) {
require(onReceive); this.onReceive = onReceive;
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
this.ctx = ctx;
Logger.info("DirectClientHandler %s connect %s", ctx.channel().localAddress(), ctx.channel().remoteAddress());
} @Override
protected void channelRead0(ChannelHandlerContext ctx, byte[] bytes) {
onReceive.accept(ctx, bytes);
Logger.info("DirectClientHandler %s recv %s bytes from %s", ctx.channel().remoteAddress(), bytes.length,
ctx.channel().localAddress());
} public ChannelFuture send(byte[] bytes) {
try {
return ctx.channel().writeAndFlush(bytes);
} finally {
Logger.info("DirectClientHandler %s send %s bytes to %s", ctx.channel().localAddress(), bytes.length,
ctx.channel().remoteAddress());
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
Logger.error(cause, "DirectClientHandler");
ctx.close();
}
}
package org.rx.socks.proxy;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.rx.common.Logger; import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer; import static org.rx.common.Contract.require; public class DirectServerHandler extends SimpleChannelInboundHandler<byte[]> {
private static class ClientState {
private ProxyClient directClient;
// private int length;
// private MemoryStream stream; public ProxyClient getDirectClient() {
return directClient;
} public ClientState(boolean enableSsl, SocketAddress directAddress,
BiConsumer<ChannelHandlerContext, byte[]> onReceive) {
require(directAddress, onReceive); directClient = new ProxyClient();
directClient.setEnableSsl(enableSsl);
directClient.connect((InetSocketAddress) directAddress, onReceive);
// stream = new MemoryStream(32, true);
} // private int readRemoteAddress(byte[] bytes) {
// int offset = 0;
// if (length == -1) {
// stream.setLength(length = Bytes.toInt(bytes, 0));
// stream.setPosition(0);
// offset = Integer.BYTES;
// }
// int count = length - stream.getPosition();
// stream.write(bytes, offset, Math.min(count, bytes.length));
// if (stream.getPosition() < length) {
// return -1;
// }
//
// directAddress = Sockets.parseAddress(Bytes.toString(stream.getBuffer(), 0, length));
// length = -1;
// return bytes.length - count;
// }
} private final Map<ChannelHandlerContext, ClientState> clients;
private boolean enableSsl;
private SocketAddress directAddress; public DirectServerHandler(boolean enableSsl, SocketAddress directAddress) {
require(directAddress); clients = new ConcurrentHashMap<>();
this.enableSsl = enableSsl;
this.directAddress = directAddress;
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
clients.put(ctx, new ClientState(enableSsl, directAddress, (directChannel, bytes) -> {
ctx.writeAndFlush(bytes);
Logger.info("DirectServerHandler %s recv %s bytes from %s", ctx.channel().remoteAddress(), bytes.length,
directAddress);
}));
Logger.info("DirectServerHandler %s connect %s", ctx.channel().remoteAddress(), directAddress);
} @Override
protected void channelRead0(ChannelHandlerContext ctx, byte[] bytes) {
ClientState state = clients.get(ctx);
require(state); ProxyClient directClient = state.getDirectClient();
directClient.send(bytes);
Logger.info("DirectServerHandler %s send %s bytes to %s",
directClient.getHandler().getChannel().remoteAddress(), bytes.length, ctx.channel().remoteAddress());
} @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
clients.remove(ctx);
Logger.info("DirectServerHandler %s disconnect %s", ctx.channel().remoteAddress(), directAddress);
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
Logger.error(cause, "DirectServerHandler");
ctx.close();
}
}
package org.rx.socks.proxy;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.compression.ZlibWrapper;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import lombok.SneakyThrows;
import org.rx.common.App;
import org.rx.common.Disposable; import java.net.InetSocketAddress;
import java.util.function.BiConsumer; import static org.rx.common.Contract.require;
import static org.rx.socks.proxy.ProxyServer.Compression_Key; public class ProxyClient extends Disposable {
private EventLoopGroup group;
private boolean enableSsl;
private DirectClientHandler handler; public boolean isEnableSsl() {
return enableSsl;
} public void setEnableSsl(boolean enableSsl) {
this.enableSsl = enableSsl;
} public boolean isEnableCompression() {
return App.convert(App.readSetting(Compression_Key), boolean.class);
} public DirectClientHandler getHandler() {
checkNotClosed();
return handler;
} @Override
protected void freeObjects() {
if (group != null) {
group.shutdownGracefully();
}
} public void connect(InetSocketAddress remoteAddress) {
connect(remoteAddress, null);
} @SneakyThrows
public void connect(InetSocketAddress remoteAddress, BiConsumer<ChannelHandlerContext, byte[]> onReceive) {
checkNotClosed();
require(group == null);
require(remoteAddress); // Configure SSL.
SslContext sslCtx = null;
if (enableSsl) {
sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} Bootstrap b = new Bootstrap();
SslContext ssl = sslCtx;
b.group(group = new NioEventLoopGroup()).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
if (ssl != null) {
pipeline.addLast(
ssl.newHandler(ch.alloc(), remoteAddress.getHostName(), remoteAddress.getPort()));
}
if (isEnableCompression()) {
pipeline.addLast(ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
pipeline.addLast(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
} pipeline.addLast(new ByteArrayDecoder());
pipeline.addLast(new ByteArrayEncoder()); pipeline.addLast(new DirectClientHandler(onReceive));
}
});
ChannelFuture f = b.connect(remoteAddress).sync();
handler = (DirectClientHandler) f.channel().pipeline().last();
} public ChannelFuture send(byte[] bytes) {
checkNotClosed();
require(group != null);
require(bytes); return getHandler().send(bytes);
}
}
package org.rx.socks.proxy;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.compression.ZlibWrapper;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import lombok.SneakyThrows;
import org.rx.common.App;
import org.rx.common.Disposable;
import org.rx.socks.Sockets; import java.net.InetSocketAddress;
import java.net.SocketAddress; import static org.rx.common.Contract.require; public final class ProxyServer extends Disposable {
public static final String Compression_Key = "app.netProxy.compression";
public static final String ListenBlock_Key = "app.netProxy.listenBlock";
private EventLoopGroup group;
private boolean enableSsl; public boolean isEnableSsl() {
return enableSsl;
} public void setEnableSsl(boolean enableSsl) {
this.enableSsl = enableSsl;
} public boolean isEnableCompression() {
return App.convert(App.readSetting(Compression_Key), boolean.class);
} public boolean isListening() {
return group != null;
} private boolean isListenBlock() {
return App.convert(App.readSetting(ListenBlock_Key), boolean.class);
} @Override
protected void freeObjects() {
if (group != null) {
group.shutdownGracefully();
}
} public void start(int localPort, SocketAddress directAddress) {
start(new InetSocketAddress(Sockets.AnyAddress, localPort), directAddress);
} @SneakyThrows
public void start(SocketAddress localAddress, SocketAddress directAddress) {
checkNotClosed();
require(group == null);
require(localAddress); // Configure SSL.
SslContext sslCtx = null;
if (enableSsl) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
} ServerBootstrap b = new ServerBootstrap();
SslContext ssl = sslCtx;
b.group(group = new NioEventLoopGroup()).channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
if (ssl != null) {
pipeline.addLast(ssl.newHandler(ch.alloc()));
}
if (isEnableCompression()) {
// Enable stream compression (you can remove these two if unnecessary)
pipeline.addLast(ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
pipeline.addLast(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
} // Add the number codec first,
pipeline.addLast(new ByteArrayDecoder());
pipeline.addLast(new ByteArrayEncoder()); // and then business logic.
// Please note we create a handler for every new channel because it has stateful properties.
pipeline.addLast(new DirectServerHandler(enableSsl, directAddress));
}
});
ChannelFuture f = b.bind(localAddress).sync();
if (isListenBlock()) {
f.channel().closeFuture().sync();
}
} public void closeClients() {
checkNotClosed();
if (group == null) {
return;
} group.shutdownGracefully();
group = null;
}
}

java proxy 转包的更多相关文章

  1. 深入理解Java Proxy

    深入理解Java Proxy: http://blog.csdn.net/rokii/article/details/4046098 整理之后的代码: package com.stono.reftes ...

  2. Java Proxy和CGLIB动态代理原理

    动态代理在Java中有着广泛的应用,比如Spring AOP,Hibernate数据查询.测试框架的后端mock.RPC,Java注解对象获取等.静态代理的代理关系在编译时就确定了,而动态代理的代理关 ...

  3. 动态代理:JDK原生动态代理(Java Proxy)和CGLIB动态代理原理+附静态态代理

    本文只是对原文的梳理总结,以及自行理解.自己总结的比较简单,而且不深入,不如直接看原文.不过自己梳理一遍更有助于理解. 详细可参考原文:http://www.cnblogs.com/Carpenter ...

  4. java Proxy InvocationHandler 动态代理实现详解

    spring 两大思想,其一是IOC,其二就是AOP..而AOP的原理就是java 的动态代理机制.这里主要记录java 动态代理的实现及相关类的说明. java  动态代理机制依赖于Invocati ...

  5. java Proxy(代理机制)

    我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习 ...

  6. Set Java Proxy for Http/Https

     Command Line JVM Settings The proxy settings are given to the JVM via command line arguments: java ...

  7. 深入理解Java Proxy机制(转)

    动态代理其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组 ...

  8. Java Proxy

    Client---->Interface A --        -- 代理类     Class AImpl 代理类是动态生成的,借助Proxy类和InvocationHandler接口进行实 ...

  9. 几个java proxy servlet 工具

    HTTP-Proxy-Servlet 这个工具使用比较简单,可以通过配置,或者代码的方式 https://github.com/mitre/HTTP-Proxy-Servlet servlet 配置方 ...

随机推荐

  1. DataTable转实体类

    /// <summary> /// DataTable与实体类互相转换 /// </summary> /// <typeparam name="T"& ...

  2. 彻底搞懂Gradle、Gradle Wrapper与Android Plugin for Gradle的区别和联系

    首先用一段通俗易懂但是不是非常专业的话描述一下三者的概念.区别和联系. Gradle是个构建系统,能够简化你的编译.打包.测试过程.熟悉Java的同学,可以把Gradle类比成Maven. Gradl ...

  3. python转义符

  4. 在 Laravel 项目中使用 Elasticsearch 做引擎,scout 全文搜索(小白出品, 绝对白话)

    项目中需要搜索, 所以从零开始学习大家都在用的搜索神器 elasiticsearch. 刚开始 google 的时候, 搜到好多经验贴和视频(中文的, 英文的), 但是由于是第一次接触, 一点概念都没 ...

  5. 区块链 编译android geth 填坑记录 ubuntu

    下载geth 源码  直接 make android 下载android ndk sdk 配置环境变量cd 安装golang  设置环境变量 发现没有gomobile命令 按照wiki方法 执行安装g ...

  6. [Basics] 递归

    Recursion就是方法调用自己,递归其实和循环是非常像的,循环都可以改写成递归,递归未必能改写成循环,这是一个充分不必要的条件.

  7. cowboy源码分析(一)

    前段时间导读了ranch的源码,具体见ranch 源码分析(一), 现在整理了下ranch框架下经典应用cowboy. 源码地方:https://github.com/ninenines/cowboy ...

  8. 将一个JSON数组[{},{},{}]按一定规则合并到另一个JSON数组[{},{},{}]

    // 将一个JSON数组[{},{},{}]按一定规则合并到另一个JSON数组[{},{},{}] // Object.assign方法的第一个参数是目标对象,后面的参数都是源对象. var list ...

  9. git 拉取远程代码

    git 拉取远程代码 || 利用vscode编辑器自带了git,可在ctrl+~打开控制台拉取代码,非常好用哦~在实际项目开发过程中,往往是已经存在远程项目了,我们定义的需求是只需要简单的操作git, ...

  10. linux 7 关闭防火墙 开启sshd服务

    启动一个服务:systemctl start firewalld.service关闭一个服务:systemctl stop firewalld.service重启一个服务:systemctl rest ...