This commit is contained in:
chenhaodong
2023-07-05 11:06:03 +08:00
parent 8de47479c5
commit 7c55f8da61
234 changed files with 54941 additions and 18 deletions
@@ -0,0 +1,128 @@
package org.fengfei.lanproxy.client;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.fengfei.lanproxy.client.listener.ProxyChannelBorrowListener;
import org.fengfei.lanproxy.common.Config;
import org.fengfei.lanproxy.protocol.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.util.AttributeKey;
/**
* 代理客户端与后端真实服务器连接管理
*
* @author fengfei
*
*/
public class ClientChannelMannager {
private static Logger logger = LoggerFactory.getLogger(ClientChannelMannager.class);
private static final AttributeKey<Boolean> USER_CHANNEL_WRITEABLE = AttributeKey.newInstance("user_channel_writeable");
private static final AttributeKey<Boolean> CLIENT_CHANNEL_WRITEABLE = AttributeKey.newInstance("client_channel_writeable");
private static final int MAX_POOL_SIZE = 100;
private static Map<String, Channel> realServerChannels = new ConcurrentHashMap<String, Channel>();
private static ConcurrentLinkedQueue<Channel> proxyChannelPool = new ConcurrentLinkedQueue<Channel>();
private static volatile Channel cmdChannel;
private static Config config = Config.getInstance();
public static void borrowProxyChanel(Bootstrap bootstrap, final ProxyChannelBorrowListener borrowListener) {
Channel channel = proxyChannelPool.poll();
if (channel != null) {
borrowListener.success(channel);
return;
}
bootstrap.connect(config.getStringValue("server.host"), config.getIntValue("server.port")).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
borrowListener.success(future.channel());
} else {
logger.warn("connect proxy server failed", future.cause());
borrowListener.error(future.cause());
}
}
});
}
public static void returnProxyChanel(Channel proxyChanel) {
if (proxyChannelPool.size() > MAX_POOL_SIZE) {
proxyChanel.close();
} else {
proxyChanel.config().setOption(ChannelOption.AUTO_READ, true);
proxyChanel.attr(Constants.NEXT_CHANNEL).remove();
proxyChannelPool.offer(proxyChanel);
logger.debug("return ProxyChanel to the pool, channel is {}, pool size is {} ", proxyChanel, proxyChannelPool.size());
}
}
public static void removeProxyChanel(Channel proxyChanel) {
proxyChannelPool.remove(proxyChanel);
}
public static void setCmdChannel(Channel cmdChannel) {
ClientChannelMannager.cmdChannel = cmdChannel;
}
public static Channel getCmdChannel() {
return cmdChannel;
}
public static void setRealServerChannelUserId(Channel realServerChannel, String userId) {
realServerChannel.attr(Constants.USER_ID).set(userId);
}
public static String getRealServerChannelUserId(Channel realServerChannel) {
return realServerChannel.attr(Constants.USER_ID).get();
}
public static Channel getRealServerChannel(String userId) {
return realServerChannels.get(userId);
}
public static void addRealServerChannel(String userId, Channel realServerChannel) {
realServerChannels.put(userId, realServerChannel);
}
public static Channel removeRealServerChannel(String userId) {
return realServerChannels.remove(userId);
}
public static boolean isRealServerReadable(Channel realServerChannel) {
return realServerChannel.attr(CLIENT_CHANNEL_WRITEABLE).get() && realServerChannel.attr(USER_CHANNEL_WRITEABLE).get();
}
public static void clearRealServerChannels() {
logger.warn("channel closed, clear real server channels");
Iterator<Entry<String, Channel>> ite = realServerChannels.entrySet().iterator();
while (ite.hasNext()) {
Channel realServerChannel = ite.next().getValue();
if (realServerChannel.isActive()) {
realServerChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
}
realServerChannels.clear();
}
}
@@ -0,0 +1,161 @@
package org.fengfei.lanproxy.client;
import java.util.Arrays;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import org.fengfei.lanproxy.client.handlers.ClientChannelHandler;
import org.fengfei.lanproxy.client.handlers.RealServerChannelHandler;
import org.fengfei.lanproxy.client.listener.ChannelStatusListener;
import org.fengfei.lanproxy.common.Config;
import org.fengfei.lanproxy.common.container.Container;
import org.fengfei.lanproxy.common.container.ContainerHelper;
import org.fengfei.lanproxy.protocol.IdleCheckHandler;
import org.fengfei.lanproxy.protocol.ProxyMessage;
import org.fengfei.lanproxy.protocol.ProxyMessageDecoder;
import org.fengfei.lanproxy.protocol.ProxyMessageEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.ssl.SslHandler;
public class ProxyClientContainer implements Container, ChannelStatusListener {
private static Logger logger = LoggerFactory.getLogger(ProxyClientContainer.class);
private static final int MAX_FRAME_LENGTH = 1024 * 1024;
private static final int LENGTH_FIELD_OFFSET = 0;
private static final int LENGTH_FIELD_LENGTH = 4;
private static final int INITIAL_BYTES_TO_STRIP = 0;
private static final int LENGTH_ADJUSTMENT = 0;
private NioEventLoopGroup workerGroup;
private Bootstrap bootstrap;
private Bootstrap realServerBootstrap;
private Config config = Config.getInstance();
private SSLContext sslContext;
private long sleepTimeMill = 1000;
public ProxyClientContainer() {
workerGroup = new NioEventLoopGroup();
realServerBootstrap = new Bootstrap();
realServerBootstrap.group(workerGroup);
realServerBootstrap.channel(NioSocketChannel.class);
realServerBootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new RealServerChannelHandler());
}
});
bootstrap = new Bootstrap();
bootstrap.group(workerGroup);
bootstrap.channel(NioSocketChannel.class);
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
if (Config.getInstance().getBooleanValue("ssl.enable", false)) {
if (sslContext == null) {
sslContext = SslContextCreator.createSSLContext();
}
ch.pipeline().addLast(createSslHandler(sslContext));
}
ch.pipeline().addLast(new ProxyMessageDecoder(MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH, LENGTH_ADJUSTMENT, INITIAL_BYTES_TO_STRIP));
ch.pipeline().addLast(new ProxyMessageEncoder());
ch.pipeline().addLast(new IdleCheckHandler(IdleCheckHandler.READ_IDLE_TIME, IdleCheckHandler.WRITE_IDLE_TIME - 10, 0));
ch.pipeline().addLast(new ClientChannelHandler(realServerBootstrap, bootstrap, ProxyClientContainer.this));
}
});
}
@Override
public void start() {
connectProxyServer();
}
private ChannelHandler createSslHandler(SSLContext sslContext) {
SSLEngine sslEngine = sslContext.createSSLEngine();
sslEngine.setUseClientMode(true);
return new SslHandler(sslEngine);
}
private void connectProxyServer() {
bootstrap.connect(config.getStringValue("server.host"), config.getIntValue("server.port")).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
// 连接成功,向服务器发送客户端认证信息(clientKey)
ClientChannelMannager.setCmdChannel(future.channel());
ProxyMessage proxyMessage = new ProxyMessage();
proxyMessage.setType(ProxyMessage.C_TYPE_AUTH);
proxyMessage.setUri(config.getStringValue("client.key"));
future.channel().writeAndFlush(proxyMessage);
sleepTimeMill = 1000;
logger.info("connect proxy server success, {}", future.channel());
} else {
logger.warn("connect proxy server failed", future.cause());
// 连接失败,发起重连
reconnectWait();
connectProxyServer();
}
}
});
}
@Override
public void stop() {
workerGroup.shutdownGracefully();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
reconnectWait();
connectProxyServer();
}
private void reconnectWait() {
try {
if (sleepTimeMill > 60000) {
sleepTimeMill = 1000;
}
synchronized (this) {
sleepTimeMill = sleepTimeMill * 2;
wait(sleepTimeMill);
}
} catch (InterruptedException e) {
}
}
public static void main(String[] args) {
ContainerHelper.start(Arrays.asList(new Container[] { new ProxyClientContainer() }));
}
}
@@ -0,0 +1,90 @@
package org.fengfei.lanproxy.client;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.fengfei.lanproxy.common.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SslContextCreator {
private static Logger logger = LoggerFactory.getLogger(SslContextCreator.class);
public static SSLContext createSSLContext() {
return new SslContextCreator().initSSLContext();
}
public SSLContext initSSLContext() {
logger.info("Checking SSL configuration properties...");
final String jksPath = Config.getInstance().getStringValue("ssl.jksPath");
logger.info("Initializing SSL context. KeystorePath = {}.", jksPath);
if (jksPath == null || jksPath.isEmpty()) {
// key_store_password or key_manager_password are empty
logger.warn("The keystore path is null or empty. The SSL context won't be initialized.");
return null;
}
// if we have the port also the jks then keyStorePassword and
// keyManagerPassword
// has to be defined
final String keyStorePassword = Config.getInstance().getStringValue("ssl.keyStorePassword");
// if client authentification is enabled a trustmanager needs to be
// added to the ServerContext
try {
logger.info("Loading keystore. KeystorePath = {}.", jksPath);
InputStream jksInputStream = jksDatastore(jksPath);
SSLContext clientSSLContext = SSLContext.getInstance("TLS");
final KeyStore ks = KeyStore.getInstance("JKS");
ks.load(jksInputStream, keyStorePassword.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
TrustManager[] trustManagers = tmf.getTrustManagers();
// init sslContext
logger.info("Initializing SSL context...");
clientSSLContext.init(null, trustManagers, null);
logger.info("The SSL context has been initialized successfully.");
return clientSSLContext;
} catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | KeyManagementException
| IOException ex) {
logger.error("Unable to initialize SSL context. Cause = {}, errorMessage = {}.", ex.getCause(),
ex.getMessage());
return null;
}
}
private InputStream jksDatastore(String jksPath) throws FileNotFoundException {
URL jksUrl = getClass().getClassLoader().getResource(jksPath);
if (jksUrl != null) {
logger.info("Starting with jks at {}, jks normal {}", jksUrl.toExternalForm(), jksUrl);
return getClass().getClassLoader().getResourceAsStream(jksPath);
}
logger.warn("No keystore has been found in the bundled resources. Scanning filesystem...");
File jksFile = new File(jksPath);
if (jksFile.exists()) {
logger.info("Loading external keystore. Url = {}.", jksFile.getAbsolutePath());
return new FileInputStream(jksFile);
}
logger.warn("The keystore file does not exist. Url = {}.", jksFile.getAbsolutePath());
return null;
}
}
@@ -0,0 +1,174 @@
package org.fengfei.lanproxy.client.handlers;
import org.fengfei.lanproxy.client.ClientChannelMannager;
import org.fengfei.lanproxy.client.listener.ChannelStatusListener;
import org.fengfei.lanproxy.client.listener.ProxyChannelBorrowListener;
import org.fengfei.lanproxy.common.Config;
import org.fengfei.lanproxy.protocol.Constants;
import org.fengfei.lanproxy.protocol.ProxyMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
/**
*
* @author fengfei
*
*/
public class ClientChannelHandler extends SimpleChannelInboundHandler<ProxyMessage> {
private static Logger logger = LoggerFactory.getLogger(ClientChannelHandler.class);
private Bootstrap bootstrap;
private Bootstrap proxyBootstrap;
private ChannelStatusListener channelStatusListener;
public ClientChannelHandler(Bootstrap bootstrap, Bootstrap proxyBootstrap, ChannelStatusListener channelStatusListener) {
this.bootstrap = bootstrap;
this.proxyBootstrap = proxyBootstrap;
this.channelStatusListener = channelStatusListener;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ProxyMessage proxyMessage) throws Exception {
logger.debug("recieved proxy message, type is {}", proxyMessage.getType());
switch (proxyMessage.getType()) {
case ProxyMessage.TYPE_CONNECT:
handleConnectMessage(ctx, proxyMessage);
break;
case ProxyMessage.TYPE_DISCONNECT:
handleDisconnectMessage(ctx, proxyMessage);
break;
case ProxyMessage.P_TYPE_TRANSFER:
handleTransferMessage(ctx, proxyMessage);
break;
default:
break;
}
}
private void handleTransferMessage(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
Channel realServerChannel = ctx.channel().attr(Constants.NEXT_CHANNEL).get();
if (realServerChannel != null) {
ByteBuf buf = ctx.alloc().buffer(proxyMessage.getData().length);
buf.writeBytes(proxyMessage.getData());
logger.debug("write data to real server, {}", realServerChannel);
realServerChannel.writeAndFlush(buf);
}
}
private void handleDisconnectMessage(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
Channel realServerChannel = ctx.channel().attr(Constants.NEXT_CHANNEL).get();
logger.debug("handleDisconnectMessage, {}", realServerChannel);
if (realServerChannel != null) {
ctx.channel().attr(Constants.NEXT_CHANNEL).remove();
ClientChannelMannager.returnProxyChanel(ctx.channel());
realServerChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
}
private void handleConnectMessage(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
final Channel cmdChannel = ctx.channel();
final String userId = proxyMessage.getUri();
String[] serverInfo = new String(proxyMessage.getData()).split(":");
String ip = serverInfo[0];
int port = Integer.parseInt(serverInfo[1]);
bootstrap.connect(ip, port).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
// 连接后端服务器成功
if (future.isSuccess()) {
final Channel realServerChannel = future.channel();
logger.debug("connect realserver success, {}", realServerChannel);
realServerChannel.config().setOption(ChannelOption.AUTO_READ, false);
// 获取连接
ClientChannelMannager.borrowProxyChanel(proxyBootstrap, new ProxyChannelBorrowListener() {
@Override
public void success(Channel channel) {
// 连接绑定
channel.attr(Constants.NEXT_CHANNEL).set(realServerChannel);
realServerChannel.attr(Constants.NEXT_CHANNEL).set(channel);
// 远程绑定
ProxyMessage proxyMessage = new ProxyMessage();
proxyMessage.setType(ProxyMessage.TYPE_CONNECT);
proxyMessage.setUri(userId + "@" + Config.getInstance().getStringValue("client.key"));
channel.writeAndFlush(proxyMessage);
realServerChannel.config().setOption(ChannelOption.AUTO_READ, true);
ClientChannelMannager.addRealServerChannel(userId, realServerChannel);
ClientChannelMannager.setRealServerChannelUserId(realServerChannel, userId);
}
@Override
public void error(Throwable cause) {
ProxyMessage proxyMessage = new ProxyMessage();
proxyMessage.setType(ProxyMessage.TYPE_DISCONNECT);
proxyMessage.setUri(userId);
cmdChannel.writeAndFlush(proxyMessage);
}
});
} else {
ProxyMessage proxyMessage = new ProxyMessage();
proxyMessage.setType(ProxyMessage.TYPE_DISCONNECT);
proxyMessage.setUri(userId);
cmdChannel.writeAndFlush(proxyMessage);
}
}
});
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
Channel realServerChannel = ctx.channel().attr(Constants.NEXT_CHANNEL).get();
if (realServerChannel != null) {
realServerChannel.config().setOption(ChannelOption.AUTO_READ, ctx.channel().isWritable());
}
super.channelWritabilityChanged(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// 控制连接
if (ClientChannelMannager.getCmdChannel() == ctx.channel()) {
ClientChannelMannager.setCmdChannel(null);
ClientChannelMannager.clearRealServerChannels();
channelStatusListener.channelInactive(ctx);
} else {
// 数据传输连接
Channel realServerChannel = ctx.channel().attr(Constants.NEXT_CHANNEL).get();
if (realServerChannel != null && realServerChannel.isActive()) {
realServerChannel.close();
}
}
ClientChannelMannager.removeProxyChanel(ctx.channel());
super.channelInactive(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.error("exception caught", cause);
super.exceptionCaught(ctx, cause);
}
}
@@ -0,0 +1,80 @@
package org.fengfei.lanproxy.client.handlers;
import org.fengfei.lanproxy.client.ClientChannelMannager;
import org.fengfei.lanproxy.protocol.Constants;
import org.fengfei.lanproxy.protocol.ProxyMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
/**
* 处理服务端 channel.
*/
public class RealServerChannelHandler extends SimpleChannelInboundHandler<ByteBuf> {
private static Logger logger = LoggerFactory.getLogger(RealServerChannelHandler.class);
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) throws Exception {
Channel realServerChannel = ctx.channel();
Channel channel = realServerChannel.attr(Constants.NEXT_CHANNEL).get();
if (channel == null) {
// 代理客户端连接断开
ctx.channel().close();
} else {
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
String userId = ClientChannelMannager.getRealServerChannelUserId(realServerChannel);
ProxyMessage proxyMessage = new ProxyMessage();
proxyMessage.setType(ProxyMessage.P_TYPE_TRANSFER);
proxyMessage.setUri(userId);
proxyMessage.setData(bytes);
channel.writeAndFlush(proxyMessage);
logger.debug("write data to proxy server, {}, {}", realServerChannel, channel);
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Channel realServerChannel = ctx.channel();
String userId = ClientChannelMannager.getRealServerChannelUserId(realServerChannel);
ClientChannelMannager.removeRealServerChannel(userId);
Channel channel = realServerChannel.attr(Constants.NEXT_CHANNEL).get();
if (channel != null) {
logger.debug("channelInactive, {}", realServerChannel);
ProxyMessage proxyMessage = new ProxyMessage();
proxyMessage.setType(ProxyMessage.TYPE_DISCONNECT);
proxyMessage.setUri(userId);
channel.writeAndFlush(proxyMessage);
}
super.channelInactive(ctx);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
Channel realServerChannel = ctx.channel();
Channel proxyChannel = realServerChannel.attr(Constants.NEXT_CHANNEL).get();
if (proxyChannel != null) {
proxyChannel.config().setOption(ChannelOption.AUTO_READ, realServerChannel.isWritable());
}
super.channelWritabilityChanged(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.error("exception caught", cause);
super.exceptionCaught(ctx, cause);
}
}
@@ -0,0 +1,9 @@
package org.fengfei.lanproxy.client.listener;
import io.netty.channel.ChannelHandlerContext;
public interface ChannelStatusListener {
void channelInactive(ChannelHandlerContext ctx);
}
@@ -0,0 +1,11 @@
package org.fengfei.lanproxy.client.listener;
import io.netty.channel.Channel;
public interface ProxyChannelBorrowListener {
void success(Channel channel);
void error(Throwable cause);
}
@@ -0,0 +1,11 @@
#由服务端生成的key
client.key=client
#ssl是否开启,配置应与服务端一致
ssl.enable=false
ssl.jksPath=test.jks
ssl.keyStorePassword=123456
#服务端的ip
server.host=127.0.0.1
#服务端的端口
#default ssl port is 4993
server.port=4900
@@ -0,0 +1,13 @@
log4j.rootLogger=info,R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.R.File=${app.home}/logs/client.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.logger.io.netty=warn
@@ -0,0 +1,11 @@
@echo off & setlocal enabledelayedexpansion
title lanproxy-client
cd %~dp0
set LIB_JARS=""
cd ..\lib
for %%i in (*) do set LIB_JARS=!LIB_JARS!;..\lib\%%i
cd ..\bin
java -Dapp.home=../ -Xms64m -Xmx1024m -classpath ..\conf;%LIB_JARS% org.fengfei.lanproxy.client.ProxyClientContainer
goto end
@@ -0,0 +1,43 @@
#!/bin/bash
cd `dirname $0`
cd ..
DEPLOY_DIR=`pwd`
CONF_DIR=$DEPLOY_DIR/conf
LOGS_DIR=$DEPLOY_DIR/logs
APP_MAINCLASS=org.fengfei.lanproxy.client.ProxyClientContainer
PIDS=`ps -ef | grep -v grep | grep "$CONF_DIR" |awk '{print $2}'`
if [ -n "$PIDS" ]; then
echo "ERROR: already started!"
echo "PID: $PIDS"
exit 1
fi
if [ ! -d $LOGS_DIR ]; then
mkdir $LOGS_DIR
fi
STDOUT_FILE=$LOGS_DIR/stdout.log
CLOG_FILE=$LOGS_DIR/gc.log
LIB_DIR=$DEPLOY_DIR/lib
LIB_JARS=`ls $LIB_DIR|grep .jar|awk '{print "'$LIB_DIR'/"$0}'| xargs | sed "s/ /:/g"`
JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true "
JAVA_DEBUG_OPTS=""
if [ "$1" = "debug" ]; then
JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n "
fi
JAVA_JMX_OPTS=""
if [ "$1" = "jmx" ]; then
JAVA_JMX_OPTS=" -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false "
fi
JAVA_MEM_OPTS=""
#JAVA_MEM_OPTS="-server -Xms5120M -Xmx5120M -Xmn1024M -Xnoclassgc -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:$CLOG_FILE"
echo -e "Starting the proxy client ...\c"
nohup java -Dapp.home=$DEPLOY_DIR $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS -classpath $CONF_DIR:$LIB_JARS $APP_MAINCLASS >$STDOUT_FILE 2>&1 &
sleep 1
echo "started"
PIDS=`ps -ef | grep java | grep "$DEPLOY_DIR" | awk '{print $2}'`
echo "PID: $PIDS"
+35
View File
@@ -0,0 +1,35 @@
#!/bin/bash
cd `dirname $0`
BIN_DIR=`pwd`
cd ..
DEPLOY_DIR=`pwd`
LOGS_DIR=$DEPLOY_DIR/logs
if [ ! -d $LOGS_DIR ]; then
mkdir $LOGS_DIR
fi
STDOUT_FILE=$LOGS_DIR/stdout.log
PID=`ps -ef | grep -v grep | grep "$DEPLOY_DIR/conf" | awk '{print $2}'`
echo "PID: $PID"
if [ -z "$PID" ]; then
echo "ERROR: The proxy client does not started!"
exit 1
fi
echo -e "Stopping the proxy client...\c"
kill $PID > $STDOUT_FILE 2>&1
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
COUNT=1
PID_EXIST=`ps -f -p $PID | grep java`
if [ -n "$PID_EXIST" ]; then
COUNT=0
fi
done
echo "stopped"
echo "PID: $PID"
Binary file not shown.
@@ -0,0 +1,15 @@
package org.fengfei.lanparoxy.client.test;
import java.util.Arrays;
import org.fengfei.lanproxy.client.ProxyClientContainer;
import org.fengfei.lanproxy.common.container.Container;
import org.fengfei.lanproxy.common.container.ContainerHelper;
public class TestMain {
public static void main(String[] args) {
ContainerHelper.start(Arrays.asList(new Container[] { new ProxyClientContainer() }));
}
}
@@ -0,0 +1,9 @@
client.key=f49bfbca84e646a5ba4ce51ad9d8c14e
ssl.enable=false
ssl.jksPath=test.jks
ssl.keyStorePassword=123456
server.host=127.0.0.1
#default ssl port is 4993
server.port=4900
@@ -0,0 +1,9 @@
log4j.rootLogger=debug,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.logger.io.netty=warn
log4j.logger.org.fengfei.lanproxy.client.handlers.ClientChannelHandler=info
log4j.logger.org.fengfei.lanproxy.protocol.IdleCheckHandler=warn
Binary file not shown.