KLALB完全大重写,代码规范了,可以当作网络库使用

This commit is contained in:
Administrator
2023-06-23 08:34:15 +08:00
parent 0499ecb34d
commit f743b23e53
154 changed files with 2985 additions and 15058 deletions
@@ -0,0 +1,66 @@
package org.kne.cloud.network.klalb;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class ACKTPacket extends KLALBPacket {
private int sport,dport;
private long number;
private boolean avaliable;
public ACKTPacket(int sport,int dport,long number,boolean avaliable) {
super(ACKT);
this.sport=sport;
this.dport=dport;
this.number=number;
this.avaliable=avaliable;
}
public ACKTPacket() {
super();
}
@Override
public String toString() {
return "ACKT "+sport+"->"+dport+" "+number+"[] "+avaliable;
}
public int getSport() {
return sport;
}
@Override
public long getLength() {
return super.getLength()+17;
}
public int getDport() {
return dport;
}
public long getNumber() {
return number;
}
public boolean isAvaliable() {
return avaliable;
}
@Override
protected void writeToStream(DataOutput dto) throws IOException {
super.writeToStream(dto);
dto.writeInt(sport);
dto.writeInt(dport);
dto.writeLong(number);
dto.writeBoolean(avaliable);
}
@Override
protected void readFromStream(DataInput din) throws IOException {
super.readFromStream(din);
sport=din.readInt();
dport=din.readInt();
number=din.readLong();
avaliable=din.readBoolean();
}
}
@@ -1,14 +0,0 @@
package org.kne.cloud.network.klalb;
public class Consts {
//public static final int BLOCKSIZE=8192;
public static final long PINGTIMENS=1000000000L;
public static final int SO_TIMEOUT = 2000;
public static final long SN_KEEP = 60000000000L;
public static final int MAX_RESEND = 20;
public static final long UACK_TIME = 2000000000L;
public static final int CONNECT_TIMEOUT=10000;
public static final double MAX_QUEUE_TIME=500;
public static final long KEEP_TIME = 60000000000L;
public static final int PRE_SO_TIMEOUT = 10000;
}
@@ -0,0 +1,68 @@
package org.kne.cloud.network.klalb;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class DATATPacket extends KLALBPacket {
@Override
public long getLength() {
return super.getLength()+18+data.length;
}
private int sport,dport;
private long number;
private byte[]data;
public DATATPacket(int sport,int dport,long number,byte[]data) {
super(DATAT);
this.sport=sport;
this.dport=dport;
this.number=number;
this.data=data;
}
public DATATPacket() {
super();
}
public int getSport() {
return sport;
}
public int getDport() {
return dport;
}
public long getNumber() {
return number;
}
public byte[] getData() {
return data;
}
@Override
public String toString() {
return "DATAT "+sport+"->"+dport+" "+number+"["+data.length+"]";
}
@Override
protected void writeToStream(DataOutput dto) throws IOException {
super.writeToStream(dto);
dto.writeInt(sport);
dto.writeInt(dport);
dto.writeLong(number);
dto.writeChar(data.length);
dto.write(data);
}
@Override
protected void readFromStream(DataInput din) throws IOException {
super.readFromStream(din);
sport=din.readInt();
dport=din.readInt();
number=din.readLong();
data=new byte[din.readChar()];
din.readFully(data);
}
}
@@ -1,84 +0,0 @@
package org.kne.cloud.network.klalb;
import java.util.Arrays;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.mport.IPPort;
public class KLALBBlock implements Comparable<KLALBBlock>{
//private static AtomicLong sng=new AtomicLong(1);
//public volatile long sn;//每个数据包的唯一编号
public volatile int cuid;//用于识别数据包的stream ID号
public volatile long number;//数据包的编号,用于排序
public volatile byte[]data;//数据内容
public volatile int command;//功能标记 0=PING 1=PONG 2=SYN 3=RST 4=KEEP 5=SYK
public volatile long pingtime;//PING计时器
public volatile boolean cacheused;
public volatile String lservice;
public volatile IPPort lipport;
public transient volatile long sendtime;
public transient volatile int resend;
//public volatile long sendtimeForRTT;
/*public KLALBBlock() {
sn=sng.getAndIncrement();
}*/
@Override
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append(cuid);
sb.append(' ');
if(number>0) {
if(data==null) {
sb.append("DATA").append(number).append(':').append("EOF");
}else {
sb.append("DATA").append(number).append(':').append(data.length);
}
}else if(number<0) {
sb.append("ACK").append(-number).append(':').append(cacheused);
}else {
switch(command) {
case 0:
sb.append("PING");
break;
case 1:
sb.append("PONG");
break;
case 2:
sb.append("SYN:").append(lservice).append(" ").append(lipport);
break;
case 3:
sb.append("RST");
break;
case 5:
sb.append("SYK");
break;
}
}
return sb.toString();
}
@Override
public int compareTo(KLALBBlock o) {
if(o.number>number) {
return -1;
}else if(o.number<number){
return 1;
}else {
return 0;
}
}
}
@@ -1,66 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.BindException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import org.kne.cloud.network.mport.ServiceElement;
public class KLALBCM {
public static void main(String[] args) throws IOException {
if(args.length==0){
System.out.println("命令行参数输入服务器任意一条线路的地址:端口可以下载服务器线路列表");
System.out.println("命令行参数输入服务器名称即可启动负载均衡");
}else if(args.length==1) {
if(args[0].equals("-gui")) {
KLALBClientGUI.main(args);
}else
if(args[0].contains(":")) {
KLALBIPList.createIPList(args[0]);
}else {
File pdis=KLALBIPList.getSLdir(args[0]);
File f=new File(pdis,"iplist.json");
if(f.exists()) {
System.out.println("加载线路列表:"+f);
try {
KLALBIPList.updateIPList(args[0]);
STJson stj=new STJson(new String(Files.readAllBytes(Paths.get(f.toURI()))));
KLALBClient kc= new KLALBClient();
kc.getTls().addAll(stj.getTunnels());
kc.connectTunnel();
ProxyJson pj=new ProxyJson(new File(pdis,"services.json"), stj);
kc.getPet().addAll(pj.getPls());
kc.listenProxy();
/* List<ServiceElement> lse=stj.getServices();
for (Iterator<ServiceElement> iterator = lse.iterator(); iterator.hasNext();) {
ServiceElement serviceElement = (ServiceElement) iterator.next();
ProxyIPPortProperties pippp=new ProxyIPPortProperties(pdis, serviceElement.name, "0.0.0.0", serviceElement.ipport.getPort());
try {
kc.open(pippp.getBindPort(),serviceElement, pippp.getBindIP());
}catch(BindException e) {
System.out.println("打开端口失败:"+pippp.getBindIP()+" "+pippp.getBindPort());
e.printStackTrace();
}
}*/
}catch (IOException e) {
e.printStackTrace();
}
}else {
System.out.println("线路列表不存在");
}
}
}else {
}
}
}
@@ -1,151 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.StringReader;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.text.html.HTMLDocument.HTMLReader.PreAction;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
import org.kne.cloud.network.mport.ThreadTool;
import com.google.gson.stream.JsonReader;
public class KLALBClient {
private UUID suid=UUID.randomUUID();
private KLALBController iom=new KLALBController();
private List<Tunnel> tls=new ArrayList<>();
private List<TCPListener> tcpl=new ArrayList<>();
private List<ProxyElement> pet=new ArrayList<>();
private void open(ProxyElement pe) throws IOException {
TCPListener tl=new TCPListener(pe.getIpport().getPort(),pe.getIpport().getIp());
tl.setCon((s)->{
LocalTCPConnection tcc = null;
try {
tcc = new LocalTCPConnection(s);
tcc.setServiceElement(pe.getSe());
//System.out.println("TCP"+tcc.getCuid()+"已连接");
iom.handleLocal(tcc,true);
//System.out.println("TCP"+tcc.getCuid()+"已关闭");
} catch (IOException e) {
e.printStackTrace();
}finally {
if(tcc!=null) {
tcc.close();
}
}
});
tl.open();
tcpl.add(tl);
System.out.println(pe.getSe().name+"映射已启动 端口:"+pe.getIpport().getPort()+" 绑定地址:"+pe.getIpport().getIp());
}
public void listenProxy() {
for (int i = 0; i < pet.size(); i++) {
ProxyElement pe=pet.get(i);
if(pe.getIpport().getPort()>0&&pe.getIpport().getPort()<65536)
try {
open(pe);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void connectTunnel() {
for (int i = 0; i < tls.size(); i++) {
Tunnel tll=tls.get(i);
ThreadTool.makeVThreadIfSupport("隧道监视线程", ()->{
int re=0;
RemoteTCPConnection tc=null;
while(iom.isOpen()) {
try {
re++;
tc=new RemoteTCPConnection(tll);
tc.getDout().write(1);
tc.getDout().writeUTF(tll.getName());
tc.getDout().writeUTF(tll.getIp());
tc.getDout().writeInt(tll.getPort());
tc.getDout().writeLong(suid.getMostSignificantBits());
tc.getDout().writeLong(suid.getLeastSignificantBits());
tc.getDout().flush();
tc.handshake(10);
re=0;
System.out.println(tll+":连接成功");
tll.setState(true);
iom.handleRemote(tc);
System.out.println(tll+":连接断开");
tll.setState(false);
} catch (UnknownHostException e) {
e.printStackTrace();
}catch(ConnectException|SocketTimeoutException e) {
}catch(EOFException e) {
} catch (IOException e) {
e.printStackTrace();
}finally {
if(tc!=null)
tc.close();
}
try {
//System.out.println(re);
Thread.sleep(5000*(1<<Math.min(re,3)));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
public List<Tunnel> getTls() {
return tls;
}
public List<ProxyElement> getPet() {
return pet;
}
public List<ServiceElement> services=new ArrayList<ServiceElement>();
public List<ServiceElement> getServices() {
return services;
}
public void close() {
iom.close();
for (Iterator<TCPListener> iterator = tcpl.iterator(); iterator.hasNext();) {
TCPListener tl = (TCPListener) iterator.next();
tl.close();
}
tls.forEach((v)->{
v.destroyFrpc();
});
}
}
@@ -1,294 +0,0 @@
package org.kne.cloud.network.klalb;
import java.awt.Color;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.BindException;
import java.net.ConnectException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.plaf.TabbedPaneUI;
import javax.swing.plaf.metal.MetalTabbedPaneUI;
import org.kne.cloud.network.mport.ServiceElement;
import org.kne.cloud.network.mport.ThreadTool;
import org.kne.ui.KTabUI;
import org.kne.ui.XFrame;
import org.kne.ui.YScrollPane;
import org.knemcl.ui.ProcessingFrame;
import org.knemcl.ui.UIEnv;
import java.awt.AWTException;
import java.awt.BorderLayout;
import javax.swing.JTabbedPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.ActionEvent;
public class KLALBClientGUI extends XFrame {
private JComboBox comboBox;
BufferedImage bi;
private Thread t;
public KLALBClientGUI() {
setResizable(false);
setTitleColor(UIEnv.getDefaultTitleColor());
try {
bi = ImageIO.read(KLALBClientGUI.class.getResourceAsStream("/assets/KNEL.png"));
} catch (IOException e) {
e.printStackTrace();
}
setIconImage(bi);
getTitlelabel().setForeground(Color.WHITE);
getContentPane().setBackground(UIEnv.getDefaultTitleColor());
comboBox = new JComboBox();
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
}
});
reloadCB();
YScrollPane ysp = new YScrollPane(580);
ysp.setOpaque(false);
getContentPane().add(ysp);
JPanel wv = ysp.getView();
wv.addComponentListener(new ComponentListener() {
@Override
public void componentShown(ComponentEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void componentResized(ComponentEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void componentMoved(ComponentEvent e) {
repaint();
}
@Override
public void componentHidden(ComponentEvent e) {
// TODO 自动生成的方法存根
}
});
JPanel panel_1 = new JPanel();
panel_1.setOpaque(false);
getContentPane().add(panel_1, BorderLayout.NORTH);
panel_1.setLayout(new BorderLayout(0, 0));
panel_1.add(comboBox, BorderLayout.CENTER);
JButton btnNewButton = new JButton("\u6DFB\u52A0");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s = JOptionPane.showInputDialog(KLALBClientGUI.this, "输入一条线路的地址");
if (s != null) {
if (s.equals("")) {
JOptionPane.showMessageDialog(KLALBClientGUI.this, "输入不能为空", "错误", JOptionPane.WARNING_MESSAGE);
} else {
ProcessingFrame psf = new ProcessingFrame("正在下载线路列表");
psf.setIconImage(bi);
psf.getProgressBar().setIndeterminate(true);
psf.setVisible(true);
ThreadTool.makeVThreadIfSupport("线路列表获取", () -> {
try {
KLALBIPList.createIPList(s);
reloadCB();
} catch (Exception e1) {
JOptionPane.showMessageDialog(KLALBClientGUI.this, e1.toString(), "错误",
JOptionPane.ERROR_MESSAGE);
e1.printStackTrace();
} finally {
psf.setVisible(false);
}
}).start();
}
}
}
});
panel_1.add(btnNewButton, BorderLayout.WEST);
JButton btnNewButton_1 = new JButton("\u542F\u52A8");
btnNewButton_1.setForeground(Color.GREEN);
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent edf) {
if(t!=null) {
t.interrupt();
t=null;
return;
}
t=ThreadTool.makeVThreadIfSupport("客户端主线程", () -> {
btnNewButton_1.setEnabled(false);
comboBox.setEnabled(false);
String s = (String) comboBox.getSelectedItem();
File pdis = KLALBIPList.getSLdir(s);
File f = new File(pdis, "iplist.json");
if (f.exists()) {
System.out.println("加载线路列表:" + f);;KLALBClient kc=null;
try {
KLALBIPList.updateIPList(s);
STJson stj=new STJson(new String(Files.readAllBytes(Paths.get(f.toURI()))));
kc = new KLALBClient();
kc.getTls().addAll(stj.getTunnels());
List<Tunnel>lt=kc.getTls();
for (Iterator<Tunnel> iterator = lt.iterator(); iterator.hasNext();) {
Tunnel tunnel = (Tunnel) iterator.next();
TPanel tp=new TPanel(tunnel);
tp.getTname().setForeground(Color.RED);
wv.add(tp);
tunnel.setTlr(new TListener() {
@Override
public void setState(boolean state) {
if(state) {
tp.getTname().setForeground(Color.GREEN);
}else {
tp.getTname().setForeground(Color.RED);
}
repaint();
}
@Override
public void setTraffic(long up, long down, long ups, long downs,long delay) {
tp.setTraffic(up,down,ups,downs,delay);
repaint();
}
});
}
ysp.updateUI();
ysp.repaint();
repaint();
kc.connectTunnel();
ProxyJson pj=new ProxyJson(new File(pdis,"services.json"), stj);
kc.getPet().addAll(pj.getPls());
kc.listenProxy();
btnNewButton_1.setForeground(Color.RED);
btnNewButton_1.setText("停止");
btnNewButton_1.setEnabled(true);
while(true) {
Thread.sleep(999);
List<Tunnel>ts=kc.getTls();
synchronized(ts) {
for(int i=0;i<ts.size();i++) {
Tunnel t=ts.get(i) ;
t.updateTraffics();
}
}
}
} catch (ConnectException e) {
JOptionPane.showMessageDialog(KLALBClientGUI.this, e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
}finally {
if(kc!=null) {
kc.close();
}
wv.removeAll();
}
} else {
System.out.println("线路列表不存在");
}
btnNewButton_1.setForeground(Color.GREEN);
btnNewButton_1.setText("启动");
btnNewButton_1.setEnabled(true);
comboBox.setEnabled(true);
});t.start();
}
});
panel_1.add(btnNewButton_1, BorderLayout.EAST);
setTitle("KNE云网络负载均衡客户端V1.0");
setSize(600, 370);
setLocationRelativeTo(null);
setVisible(true);
if (SystemTray.isSupported()) {
SystemTray st = SystemTray.getSystemTray();
TrayIcon ti = new TrayIcon(bi);
ti.setImageAutoSize(true);
PopupMenu jpm = new PopupMenu();
MenuItem mi = new MenuItem("退出");
mi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
jpm.add(mi);
ti.setPopupMenu(jpm);
try {
st.add(ti);
} catch (AWTException e1) {
e1.printStackTrace();
}
ti.addActionListener((x) -> {
setVisible(true);
});
}
repaint();
}
private void reloadCB() {
comboBox.removeAllItems();
File f = new File("KLALB");
f.mkdirs();
File[] fs = f.listFiles();
for (int i = 0; i < fs.length; i++) {
if (new File(fs[i], "iplist.json").exists()) {
comboBox.addItem(fs[i].getName());
}
}
}
public static void main(String[] args) {
new KLALBClientGUI();
}
}
@@ -1,242 +1,248 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.BindException;
import java.net.ConnectException;
import java.net.SocketException;
import java.util.Collection;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NoRouteToHostException;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Timer;
import java.util.UUID;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import org.kne.cloud.network.mport.ServiceElement;
import org.kne.cloud.network.mport.ThreadTool;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.bytecode.Bytecode;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.CodeIterator;
public class KLALBController {
private KLALBCore klc = new KLALBCore();
private volatile boolean isopen = true;
private Inet6Address self;
public Inet6Address getSelf() {
return self;
}
private Map<Inet6Address, List<KLALBRemoteSocket>> routes = new ConcurrentHashMap<>();
protected Map<Inet6Address, List<KLALBRemoteSocket>> getRoutes() {
return routes;
}
private void setLine(Inet6Address vaddr, KLALBRemoteSocket krs) {
synchronized (routes) {
List<KLALBRemoteSocket> al = routes.computeIfAbsent(vaddr, (vaddr2) -> {
return new ArrayList<KLALBRemoteSocket>();
});
al.add(krs);
}
}
private void removeLine(KLALBRemoteSocket krs) {
synchronized (routes) {
Iterator<Entry<Inet6Address, List<KLALBRemoteSocket>>> iter = routes.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<java.net.Inet6Address, java.util.List<org.kne.cloud.network.klalb.KLALBRemoteSocket>> entry = (Map.Entry<java.net.Inet6Address, java.util.List<org.kne.cloud.network.klalb.KLALBRemoteSocket>>) iter
.next();
entry.getValue().remove(krs);
if (entry.getValue().isEmpty()) {
iter.remove();
}
}
}
}
public void addRemoteSocket(KLALBRemoteSocket krs) {
CountDownLatch cdl = new CountDownLatch(1);
krs.setPacketReceiver((rec) -> {
try {
if (rec instanceof SYNTPacket) {
SYNTPacket synt = (SYNTPacket) rec;
KLALBVirtualSocketImpl kvi = bindmap.get(synt.getDport());
if (kvi != null) {
if (kvi.isListening()) {
kvi.getPackReceiver().accept(krs.getRemoteVaddr(), synt);
}
} else {
sendPacketToAddress(krs.getRemoteVaddr(), new RSTPacket(synt.getDport(), synt.getSport()),
65537);
}
} else if (rec instanceof SACKTPacket) {
SACKTPacket sackt = (SACKTPacket) rec;
KLALBVirtualSocketImpl kvi = bindmap.get(sackt.getDport());
if (kvi != null) {
if (!kvi.isListening()) {
kvi.getPackReceiver().accept(krs.getRemoteVaddr(), sackt);
}
}
} else if (rec instanceof RSTPacket) {
RSTPacket rst = (RSTPacket) rec;
KLALBVirtualSocketImpl kvi = bindmap.get(rst.getDport());
if (kvi != null) {
if (kvi.isListening()) {
KLALBVirtualSocketImpl kvi2 = kvi.getAccepts()
.get(new InetSocketAddress(krs.getRemoteVaddr(), rst.getSport()));
if (kvi2 != null) {
kvi2.getPackReceiver().accept(krs.getRemoteVaddr(), rst);
}
} else {
kvi.getPackReceiver().accept(krs.getRemoteVaddr(), rst);
}
}
} else if (rec instanceof DATATPacket) {
DATATPacket datat = (DATATPacket) rec;
KLALBVirtualSocketImpl kvi = bindmap.get(datat.getDport());
if (kvi != null) {
if (kvi.isListening()) {
KLALBVirtualSocketImpl kvi2 = kvi.getAccepts()
.get(new InetSocketAddress(krs.getRemoteVaddr(), datat.getSport()));
if (kvi2 != null) {
kvi2.getPackReceiver().accept(krs.getRemoteVaddr(), datat);
}
} else {
kvi.getPackReceiver().accept(krs.getRemoteVaddr(), datat);
}
}
} else if (rec instanceof ACKTPacket) {
ACKTPacket ackt = (ACKTPacket) rec;
KLALBVirtualSocketImpl kvi = bindmap.get(ackt.getDport());
if (kvi != null) {
if (kvi.isListening()) {
KLALBVirtualSocketImpl kvi2 = kvi.getAccepts()
.get(new InetSocketAddress(krs.getRemoteVaddr(), ackt.getSport()));
if (kvi2 != null) {
kvi2.getPackReceiver().accept(krs.getRemoteVaddr(), ackt);
}
} else {
kvi.getPackReceiver().accept(krs.getRemoteVaddr(), ackt);
}
}
} else if (rec instanceof VADDRPacket) {
VADDRPacket var = (VADDRPacket) rec;
setLine(var.getVaddr(), krs);
cdl.countDown();
}
} catch (NoRouteToHostException e) {
e.printStackTrace();
}
});
krs.setCloseListener((x) -> {
removeLine(krs);
});
krs.sendPacket(new VADDRPacket(self), 65537);
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public KLALBController() {
this.self = KLALBUtils.uuidToIP(UUID.randomUUID());
}
public void handleLocal(LocalTCPConnection tc, boolean syn) {
if(!isopen) {
return;
}
//klc.getLocaltcps().put(tc.getCuid(), tc);
klc.openLocal(tc);
// checkRemotes();
AtomicBoolean AB=new AtomicBoolean(true);
try {
//AtomicReference<Thread>tn=new AtomicReference<>();
//AtomicReference<Thread>ltn=new AtomicReference<>();
Thread lt = ThreadTool.makeVThreadIfSupport("数据包计时重发线程", () -> {
public KLALBController(Inet6Address self) {
this.self = self;
}
try {
while (AB.get()) {
klc.outputTimer(tc);
/*if(!checkRemotes()) {
AB.set(false);
}*/
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
AB.set(false);
/*tn.get().interrupt();
ltn.get().interrupt();
tc.getOutputcache().clear();*/
tc.close();
klc.closeLocal(tc);
}
});
//Thread.sleep(500);
Thread ls = ThreadTool.makeVThreadIfSupport("本地发送线程", () -> {
private Map<Integer, KLALBVirtualSocketImpl> bindmap = new ConcurrentHashMap<>();
try {
while (true) {
KLALBBlock rd=klc.getDataBlock(tc);
if(rd.data==null) {
break;
}
tc.unpackBlock(rd);
}
protected Map<Integer, KLALBVirtualSocketImpl> getBindmap() {
return bindmap;
}
} catch (IOException|InterruptedException e) {
e.printStackTrace();
AB.set(false);
/*lt.interrupt();
tc.getOutputcache().clear();*/
tc.close();
klc.closeLocal(tc);
}finally {
try {
tc.getDout().close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
// tn.set(ls);
Thread lr = ThreadTool.makeVThreadIfSupport("本地接收线程", () -> {
try {
while (true) {
KLALBBlock ks = tc.packBlock();
klc.putDataBlock(tc, ks);
if (ks.data == null) {
klc.waitOutput(tc);
break;
}
}
} catch (IOException|InterruptedException e) {
e.printStackTrace();
AB.set(false);
/*ls.interrupt();
lt.interrupt();
tc.getOutputcache().clear();*/
tc.close();
klc.closeLocal(tc);
} finally {
try {
tc.getDin().close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
//ltn.set(lr);
tc.setRSTHook((t)->{
//System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxx");
//System.exit(123);
AB.set(false);
/*ls.interrupt();
lt.interrupt();
tc.getOutputcache().clear();*/
tc.close();
klc.closeLocal(tc);
});
if (syn) {
klc.connectLocal(tc);
protected KLALBVirtualSocketImpl createVirtualImpl() {
return new KLALBVirtualSocketImpl(this);
}
protected int bind(KLALBVirtualSocketImpl klalbVirtualSocketImpl, int port) throws BindException {
synchronized (bindmap) {
if (port == 0) {
port = allocPort();
}
ls.start();
lr.start();
lt.start();
//System.out.println(klc.getLocaltcps());
lr.join();
ls.join();
ls.interrupt();
lt.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} finally {
klc.closeLocal(tc);
//klc.getLocaltcps().remove(tc.getCuid());
if (bindmap.putIfAbsent(port, klalbVirtualSocketImpl) != null) {
throw new BindException("port " + port + " is already bind!");
}
return port;
}
}
public void handleRemote(RemoteTCPConnection tc) {
if(!isopen) {
return;
}
klc.openRemote(tc);
try {
Thread rs = ThreadTool.makeVThreadIfSupport("远程发送线程", () -> {
try {
while (true) {
klc.remoteSend(tc);
}
} catch (InterruptedException e) {
} catch (IOException e) {
e.printStackTrace();
protected void unbind(KLALBVirtualSocketImpl klalbVirtualSocketImpl) {
synchronized (bindmap) {
Set<Entry<Integer, KLALBVirtualSocketImpl>> s = bindmap.entrySet();
Iterator<Entry<Integer, KLALBVirtualSocketImpl>> it = s.iterator();
while (it.hasNext()) {
Entry<Integer, KLALBVirtualSocketImpl> object = it.next();
if (klalbVirtualSocketImpl.equals(object.getValue())) {
it.remove();
return;
}
});
Thread rr = ThreadTool.makeVThreadIfSupport("远程接收线程", () -> {
try {
while (true) {
klc.remoteReceive(tc);
}
} catch (Exception e) {
e.printStackTrace();
rs.interrupt();
}
});
rs.start();
rr.start();
rr.join();
rs.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
klc.closeRemote(tc);
// checkRemotes();
}
}
/*private boolean checkRemotes() {
boolean b=true;
if(klc.getRemotetcps().isEmpty()) {
System.out.println("所有线路已断开");
b=false;
Collection<LocalTCPConnection> c=klc.getLocaltcps().values();
for (Iterator<LocalTCPConnection> iterator = c.iterator(); iterator.hasNext();) {
LocalTCPConnection object =iterator.next();
object.close();
}
}
return b;
}
*/
public void close() {
isopen = false;
Collection<LocalTCPConnection>ltcc= klc.getLocaltcps().values();
synchronized ( klc.getLocaltcps()) {
for (Iterator iterator = ltcc.iterator(); iterator.hasNext();) {
LocalTCPConnection localTCPConnection = (LocalTCPConnection) iterator.next();
localTCPConnection.close();
}
}
List<RemoteTCPConnection>rtcc= klc.getRemotetcps();
synchronized (rtcc) {
for (Iterator iterator = rtcc.iterator(); iterator.hasNext();) {
RemoteTCPConnection remoteTCPConnection = (RemoteTCPConnection) iterator.next();
remoteTCPConnection.close();
}
}
}
public boolean isOpen() {
return isopen;
protected int allocPort() throws BindException {
int i = 1;
while (bindmap.containsKey(i)) {
if (i == 65535) {
throw new BindException("can't alloc port");
}
i++;
}
return i;
}
public KLALBCore getCore() {
return klc;
protected void sendPacketToAddress(Inet6Address addr, KLALBPacket syntPacket, int priority)
throws NoRouteToHostException {
sendPacketToAddress(addr, syntPacket, priority, 1);
}
protected void sendPacketToAddress(Inet6Address addr, KLALBPacket packet, int priority, int count)
throws NoRouteToHostException {
synchronized (routes) {
List<KLALBRemoteSocket> l = routes.get(addr);
if (l == null || l.isEmpty()) {
throw new NoRouteToHostException("address unreachable: " + addr);
}
int count0 = Math.min(count, l.size());
List<KLALBRemoteSocket> l2 = (List<KLALBRemoteSocket>) ((ArrayList<KLALBRemoteSocket>) l).clone();
LineDecitionComparator ldc = new LineDecitionComparator(l2, priority);
l2.sort(ldc);
for (Iterator<KLALBRemoteSocket> iterator = l2.iterator(); iterator.hasNext();) {
KLALBRemoteSocket krst = (KLALBRemoteSocket) iterator.next();
krst.sendPacket(packet, priority);
count0--;
if (count0 <= 0)
break;
}
}
}
protected boolean checkIsBind(KLALBVirtualSocketImpl klalbVirtualSocketImpl) {
return bindmap.containsValue(klalbVirtualSocketImpl);
}
private Timer t=new Timer("数据包发送计时器", true);
public Timer getTimer() {
return t;
}
}
@@ -1,633 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StreamCorruptedException;
import java.lang.invoke.ConstantCallSite;
import java.net.ConnectException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.zip.DataFormatException;
import org.kne.cloud.network.mport.ThreadTool;
public class KLALBCore {
/*private volatile long RTT=1000000000;
private volatile long RTO=1000000000;
private volatile long DevRTT=0;
*/
//private volatile int cacheblocks;
private Map<Integer, LocalTCPConnection> localtcps = new ConcurrentHashMap<>();
private Set<Integer>localtcpsconnecting=Collections.synchronizedSet(new HashSet<>());
private List<RemoteTCPConnection> remotetcps = new Vector<>();
private BiConsumer<KLALBBlock,Consumer<Boolean>>acceptSYN;
/*private volatile long rsntime=System.nanoTime();
private Set<SN> rsns=Collections.synchronizedSet(new HashSet<SN>());
private static class SN{
volatile long sn;
volatile long time;
public SN(long sn) {
super();
this.sn = sn;
this.time=System.nanoTime();
}
public boolean isVaild() {
return System.nanoTime()-time<=Consts.SN_KEEP;
}
@Override
public int hashCode() {
return Objects.hash(sn);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SN other = (SN) obj;
return sn == other.sn;
}
}*/
public BiConsumer<KLALBBlock, Consumer<Boolean>> getAcceptSYN() {
return acceptSYN;
}
public void setAcceptSYN(BiConsumer<KLALBBlock, Consumer<Boolean>> acceptSYN) {
this.acceptSYN = acceptSYN;
}
public Map<Integer, LocalTCPConnection> getLocaltcps() {
return localtcps;
}
public List<RemoteTCPConnection> getRemotetcps() {
return remotetcps;
}
public void remoteSend(RemoteTCPConnection tc) throws InterruptedException, IOException {
for(;;) {
if(tc.checkPingTime()) {
KLALBBlock pdb=new KLALBBlock();
pdb.cuid=0;
pdb.number=0;
pdb.command=0;
pdb.pingtime=System.nanoTime();
tc.sendBlock(pdb);
tc.updateTraffics();
}
if(!tc.isEmpty())
break;
tc.lock(10);
}
KLALBBlock kbv=tc.getNextBlock();
/*KLALBBlock k0=tc.getNDSendDeque().poll();
if(k0!=null) {
if(k0.cuid==0&&k0.number==0&&k0.command==1) {
k0.pingtime+=System.nanoTime()- k0.sendtime;
}
tc.sendBlock(k0);
}else {
KLALBBlock k=tc.getSendDeque().poll();
if(k!=null) {
//if(localtcps.containsKey(k.cuid)||k.cuid.equals(ZERO_UUID))
tc.sendBlock(k);
}
}*/
if(kbv!=null) {
if(kbv.cuid==0&&kbv.number==0&&kbv.command==1) {
kbv.pingtime+=System.nanoTime()- kbv.sendtime;
}
tc.sendBlock(kbv);
}
}
public void remoteReceive(RemoteTCPConnection tc) throws IOException {
KLALBBlock brc=null;
/*for(;;) {
try {
brc=tc.receiveBlock();
} catch (DataFormatException e) {
throw new StreamCorruptedException("ZIP error");
}
brc.sendtime=System.nanoTime();
if(brc.number!=0||brc.sn==0) {
break;
}
SN s=new SN(brc.sn);
synchronized (rsns) {
if(!rsns.contains(s)) {
rsns.add(s);
break;
}
}
}
synchronized (rsns) {
long ctime=System.nanoTime();
if(ctime-rsntime>10000000000L) {
rsntime=ctime;
for (Iterator<SN> iterator = rsns.iterator(); iterator.hasNext();) {
SN sn = (SN) iterator.next();
if(!sn.isVaild()) {
iterator.remove();
}
}
}
} */
try {
brc=tc.receiveBlock();
} catch (DataFormatException e) {
throw new StreamCorruptedException("ZIP error");
}
brc.sendtime=System.nanoTime();
if(brc.cuid==0) {
if(brc.number==0) {
if(brc.command==0) {
KLALBBlock pdb=new KLALBBlock();
pdb.cuid=0;
pdb.number=0;
pdb.command=1;
pdb.pingtime=brc.pingtime;
pdb.sendtime=brc.sendtime;
tc.addBlock(pdb, 0);
//tc.getNDSendDeque().offer(pdb);
}else if(brc.command==1) {
long cur=System.nanoTime();
long delay=cur-brc.pingtime;
setDelayAvg(tc,delay);
tc.setSoTimeout(Consts.SO_TIMEOUT);
}
}
}else {
if(brc.number==0) {
if(brc.command==0) {
}else if(brc.command==1) {
}else if(brc.command==2) {
if(!localtcps.containsKey(brc.cuid)&&!localtcpsconnecting.contains(brc.cuid)) {
localtcpsconnecting.add(brc.cuid);
KLALBBlock brcx=brc;
ThreadTool.makeVThreadIfSupport("局域网连接监视线程", ()->{
try {
if(acceptSYN==null) {
KLALBBlock rst=new KLALBBlock();
rst.cuid=brcx.cuid;
rst.number=0;
rst.command=3;
submitDataBlockNoDelay(rst);
}else {acceptSYN.accept(brcx,(Consumer<Boolean>)(c)->{
if(c) {
KLALBBlock syk=new KLALBBlock();
syk.cuid=brcx.cuid;
syk.number=0;
syk.command=5;
submitDataBlockNoDelay(syk);
}else {
KLALBBlock rst=new KLALBBlock();
rst.cuid=brcx.cuid;
rst.number=0;
rst.command=3;
submitDataBlockNoDelay(rst);
}
});
}
}finally {
localtcpsconnecting.remove(brcx.cuid);
}
}).start();
}
}else if(brc.command==3) {
LocalTCPConnection ltc=localtcps.get(brc.cuid);
if(ltc!=null) {
//ltc.close();
ltc.setIsrst(true);
ltc.getRSTHook().accept(ltc);
}
}else if(brc.command==5) {
LocalTCPConnection ltc=localtcps.get(brc.cuid);
if(ltc!=null) {
ltc.setIssyk(true);
}
}
}else if(brc.number>0){
LocalTCPConnection ltcs=localtcps.get(brc.cuid);
if(ltcs!=null) {
KLALBBlock ack=new KLALBBlock();
ack.cuid=brc.cuid;
ack.number=-brc.number;
ack.cacheused=ltcs.getSendDeque().size()>ltcs.getInputcachesize()/ltcs.getBlocksize();
submitAckBlockNoDelay(ack,3);
List<KLALBBlock> ic=ltcs.getInputcache();
synchronized(ic) {
if(brc.number>=ltcs.getInputcount()) {
ic.add(brc);
while(true) {
KLALBBlock kkb=null;
for (int i = 0; i < ic.size(); i++) {
KLALBBlock klalbBlock = ic.get(i);
if(klalbBlock.number==ltcs.getInputcount()) {
ic.remove(i);
i--;
kkb=klalbBlock;
break;
}
}
if(kkb==null)
break;
ltcs.getSendDeque().add(kkb);
ltcs.incInputcount();
}
/*for (Iterator<KLALBBlock> iterator = ltcs.getInputcache().iterator(); iterator.hasNext();) {
KLALBBlock klalbBlock = (KLALBBlock) iterator.next();
if(klalbBlock.number==ltcs.getInputcount()) {
iterator.remove();
ltcs.getSendDeque().add(klalbBlock);
ltcs.incInputcount();
}else {
break;
}
}*/
}
}
}
}else {
long nx=-brc.number;
LocalTCPConnection ltc=localtcps.get(brc.cuid);
if(ltc!=null) {
/*List<KLALBBlock> l=ltc.getOutputcache();
synchronized (l) {
for (Iterator<KLALBBlock> iterator = l.iterator(); iterator.hasNext();) {
KLALBBlock klalbBlock = (KLALBBlock) iterator.next();
if(klalbBlock.number==nx) {
iterator.remove();
long SampleRTT=System.nanoTime()-klalbBlock.sendtimeForRTT;
RTT=(RTT*19+SampleRTT)/20;
DevRTT = (3*DevRTT + Math.abs( SampleRTT - RTT))/4;
RTO=RTT+DevRTT;
//System.out.println(RTO/1000000);
}
}
}*/
ltc.getOutputcache().removeIf((b) -> {
return b.number == nx;
});
ltc.setPeerFull(brc.cacheused);
}else {
KLALBBlock sbk = new KLALBBlock();
sbk.cuid = brc.cuid;
sbk.number = 0;
sbk.command = 3;
submitDataBlockNoDelay(sbk);
}
int cuid=brc.cuid;
synchronized (remotetcps) {
for (Iterator<RemoteTCPConnection> iterator = remotetcps.iterator(); iterator.hasNext();) {
RemoteTCPConnection remoteTCPConnection = (RemoteTCPConnection) iterator.next();
remoteTCPConnection.ackRemove(nx,cuid);
/*Queue<KLALBBlock>sq=remoteTCPConnection.getSendDeque();
*/
}
}
}
}
}
private void sortRemoteTCPByPrediction(int prio) {
remotetcps.forEach((x)->{
x.predictLatency(prio);
});
Collections.sort(remotetcps, new Comparator<RemoteTCPConnection>() {
@Override
public int compare(RemoteTCPConnection o1, RemoteTCPConnection o2) {
double o1x=o1.getPredictedLatency();
double o2x=o2.getPredictedLatency();
if(o1x>o2x) {
return 1;
}else if(o1x<o2x){
return -1;
}else {
return 0;
}
}
});
}
private void sortRemoteTCPByLatency() {
Collections.sort(remotetcps, new Comparator<RemoteTCPConnection>() {
@Override
public int compare(RemoteTCPConnection o1, RemoteTCPConnection o2) {
long o1x=o1.getDelay();
long o2x=o2.getDelay();
if(o1x>o2x) {
return 1;
}else if(o1x<o2x){
return -1;
}else {
return 0;
}
}
});
}
private void setDelayAvg(RemoteTCPConnection tc, long delay) {
/*if(tc.odelay==Long.MAX_VALUE) {
tc.odelay=delay;
tc.setDelay(tc.odelay);
}else {
if(delay<=tc.odelay) {
tc.odelay=delay;
}else {
tc.odelay=(delay+tc.odelay*100)/101;
}
tc.setDelay(tc.odelay);
}*/
tc.setDelay((tc.getDelay()*10+delay)/11);
}
public void submitDataBlock(KLALBBlock ks) throws InterruptedException, IOException {
submitDataBlock(ks,1);
}
public void submitDataBlock(KLALBBlock kb,int i) throws InterruptedException, IOException {
submitDataBlock(kb,1,5);
}
public void submitDataBlock(KLALBBlock kb,int i,int prio) throws InterruptedException, IOException {
int ni=Math.min(i, remotetcps.size());
while(true) {
if(remotetcps.isEmpty())
throw new IOException("发送错误");
synchronized (remotetcps) {
sortRemoteTCPByPrediction(5);
for (Iterator<RemoteTCPConnection> iterator = remotetcps.iterator(); iterator.hasNext();) {
RemoteTCPConnection rmt = (RemoteTCPConnection) iterator.next();
//if(remoteTCPConnection.getPredictedLatency()<Consts.MAX_QUEUE_TIME) {
rmt.addBlock(kb, prio);
ni--;
if(ni<=0)
return;
//}
}
}
Thread.sleep(1);
}
}
public void submitDataBlockNoDelay(KLALBBlock kb) {
synchronized (remotetcps) {
for (Iterator<RemoteTCPConnection> iterator = remotetcps.iterator(); iterator.hasNext();) {
RemoteTCPConnection rmt = (RemoteTCPConnection) iterator.next();
rmt.addBlock(kb, 0);
}
}
}
public void submitAckBlockNoDelay(KLALBBlock kb,int limit) {
synchronized (remotetcps) {
sortRemoteTCPByLatency();
int coun=0;
for (Iterator<RemoteTCPConnection> iterator = remotetcps.iterator(); iterator.hasNext();) {
if(coun>=limit) {
return;
}
RemoteTCPConnection rmt = (RemoteTCPConnection) iterator.next();
rmt.addBlock(kb, 0);
coun++;
}
}
}
public void putDataBlock(LocalTCPConnection tc, KLALBBlock ks) throws InterruptedException, IOException {
/*while (true) {
if(!localtcps.containsKey(tc.getCuid()))
throw new IOException("本地连接已关闭");
if(remotetcps.isEmpty())
throw new IOException("发送错误");
boolean b;
synchronized (tc.getOutputcache()) {
b=!tc.getOutputcache().isEmpty()&&(tc.getOutputcount()-tc.getOutputcache().get(0).number>tc.getOutputcachesize()/tc.getBlocksize());
}
if(!b) {
break;
}
Thread.sleep(1);
}*/
if(!localtcps.containsKey(tc.getCuid()))
throw new IOException("本地连接已关闭");
if(remotetcps.isEmpty())
throw new IOException("发送错误");
while(tc.getOutputcache().size()>tc.getOutputcachesize()/tc.getBlocksize()) {
if(!localtcps.containsKey(tc.getCuid()))
throw new IOException("本地连接已关闭");
if(remotetcps.isEmpty())
throw new IOException("发送错误");
Thread.sleep(1);
}
ks.sendtime=System.nanoTime();
// ks.sendtimeForRTT=ks.sendtime;
//System.out.println(tc.getOutputcache().size());
/*if(ks.data==null) {
submitDataBlock(ks);
}else {
if(ks.data.length<Consts.BLOCKSIZE/2) {
submitDataBlock(ks,2);
}else {
submitDataBlock(ks);
}
}*/
submitDataBlock(ks);
tc.getOutputcache().add(ks);
while( tc.isPeerFull()) {
if(!localtcps.containsKey(tc.getCuid()))
throw new IOException("本地连接已关闭");
if(remotetcps.isEmpty())
throw new IOException("发送错误");
Thread.sleep(1);
}
}
//private volatile long uackt=System.nanoTime();
public void outputTimer(LocalTCPConnection tc) throws InterruptedException, IOException {
List<KLALBBlock> l=tc.getOutputcache();
synchronized( l) {
for (int i = 0; i < l.size(); i++) {
KLALBBlock block=l.get(i);
long timex = (System.nanoTime() - block.sendtime)/1000000;
/*if(i<10) {
if(timex > Math.min(RTO,1000000000L )*(1<<Math.min(8,block.resend))+200*i) {
submitDataBlock(block);
block.sendtime = System.nanoTime();
System.out.println("超时重传:"+block+" 位置:"+i);
block.resend++;
if(block.resend>=Consts.MAX_RESEND) {
l.remove(i);
i--;
}
}
}*/
if (timex > (1<<Math.min(4,block.resend))*(i<remotetcps.size()?Consts.MAX_QUEUE_TIME:1000*i)) {
submitDataBlock(block,2,4);
block.sendtime = System.nanoTime();
System.out.println("超时重传:"+block+" 位置:"+i);
block.resend++;
if(block.resend>=Consts.MAX_RESEND) {
l.remove(i);
i--;
throw new IOException("重传失败:"+block);
}
}
}
}
long curr=System.nanoTime();
if(curr-tc.uackt>Consts.UACK_TIME) {
tc.uackt=curr;
KLALBBlock ack=new KLALBBlock();
ack.cuid=tc.getCuid();
ack.number=Long.MIN_VALUE;
ack.cacheused=tc.getSendDeque().size()>tc.getInputcachesize()/tc.getBlocksize();
submitAckBlockNoDelay(ack,3);
}
/*if(tc.getSendDeque().size()<cacheblocks&&curr-tc.ukeept>Consts.KEEP_TIME) {
tc.ukeept=curr;
KLALBBlock keep=new KLALBBlock();
keep.cuid=tc.getCuid();
keep.number=0;
keep.command=4;
submitDataBlockNoDelay(keep);
}*/
Thread.sleep(10);
}
public KLALBBlock getDataBlock(LocalTCPConnection tc) throws InterruptedException, IOException {
KLALBBlock recv=null;
while(true) {
if(!localtcps.containsKey(tc.getCuid()))
throw new IOException("本地连接已关闭");
if(remotetcps.isEmpty())
throw new IOException("接收错误");
recv=tc.getSendDeque().poll();
if(recv!=null)
break;
Thread.sleep(1);
}
return recv;
}
public void waitOutput(LocalTCPConnection tc) throws InterruptedException, IOException {
while(tc.getOutputcache().size()>0) {
if(!localtcps.containsKey(tc.getCuid()))
throw new IOException("本地连接已关闭");
if(remotetcps.isEmpty())
throw new IOException("发送错误");
Thread.sleep(10);
}
}
public void closeLocal(LocalTCPConnection tc) {
tc.getOutputcache().clear();
KLALBBlock sbk = new KLALBBlock();
sbk.cuid = tc.getCuid();
sbk.number = 0;
sbk.command = 3;
submitDataBlockNoDelay(sbk);
localtcps.remove(tc.getCuid());
}
public void openLocal(LocalTCPConnection tc) {
localtcps.put(tc.getCuid(), tc);
}
public void connectLocal(LocalTCPConnection tc) throws InterruptedException, IOException {
KLALBBlock sbk = new KLALBBlock();
sbk.cuid = tc.getCuid();
sbk.number = 0;
sbk.command = 2;
sbk.lservice = tc.getServiceElement().name;
sbk.lipport = tc.getServiceElement().ipport;
submitDataBlockNoDelay(sbk);
while(!tc.isIssyk()) {
if(!localtcps.containsKey(tc.getCuid()))
throw new IOException("本地连接已关闭");
if(tc.isIsrst()) {
throw new ConnectException("连接被拒绝");
}
if(remotetcps.isEmpty())
throw new IOException("接收错误");
Thread.sleep(2);
}
}
public void openRemote(RemoteTCPConnection tc) {
remotetcps.add(tc);
}
public void closeRemote(RemoteTCPConnection tc) {
remotetcps.remove(tc);
List<Queue<KLALBBlock>> l=tc.getSendDequeList();
synchronized (l) {
for (int i = 0; i < l.size(); i++) {
Queue<KLALBBlock> q=l.get(i);
int ix=i-1;
if(ix<0) {
ix=0;
}
int i2=ix;
q.forEach((kv)->{
try {
submitDataBlock(kv,1,i2);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
}
}
@@ -1,68 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import org.kne.cloud.network.mport.IPPort;
public class KLALBIPList {
public static String searchTunnels(String ipport) throws IOException {
IPPort u=new IPPort(ipport);
TCPConnection tcpc=null;
try {
Socket soc=new Socket();
soc.connect(new InetSocketAddress(u.getIp(),u.getPort()), Consts.CONNECT_TIMEOUT);
tcpc=new RemoteTCPConnection(null, soc);
tcpc.getDout().write(0);
tcpc.getDout().flush();
String json=tcpc.getDin().readUTF();
return json;
}finally {
if(tcpc!=null) {
tcpc.close();
}
}
}
public static File getSLdir(String name) {
File f=new File("./KLALB/"+name);
f.getParentFile().mkdirs();
return f;
}
public static void createIPList(String address) throws IOException {
String json=KLALBIPList.searchTunnels(address);
STJson stj=new STJson(json);
File f=new File(getSLdir(stj.getName()),"iplist.json");
System.out.println("线路列表已保存到:"+f);
f.getParentFile().mkdirs();
f.createNewFile();
PrintStream ps=new PrintStream(f);
ps.print(json);
ps.close();
}
public static void updateIPList(String name) throws IOException {
File f=getSLdir(name);
File j=new File(f, "iplist.json");
byte[]bytes = Files.readAllBytes(Paths.get(j.toURI()));
STJson stj = new STJson(new String(bytes));
List<Tunnel> l=stj.getTunnels();
for (Iterator iterator = l.iterator(); iterator.hasNext();) {
Tunnel tunnel = (Tunnel) iterator.next();
try{
createIPList(tunnel.getIpport().toString());
return;
}catch(IOException e) {
e.printStackTrace();
}
}
throw new ConnectException("搜索地址失败");
}
}
@@ -0,0 +1,66 @@
package org.kne.cloud.network.klalb;
import static org.kne.cloud.network.klalb.KLALBPacket.*;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StreamCorruptedException;
import java.net.Inet6Address;
public class KLALBInputStream extends DataInputStream {
public KLALBInputStream(InputStream in) throws IOException {
super(in);
byte[]b=new byte[5];
readFully(b);
String s=new String(b,"ascii");
if(!s.equals("KLALB")) {
throw new StreamCorruptedException("no KLALB format");
}
int bv=readInt();
int sv=readInt();
if(bv!=2)
throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V2.0");
}
public synchronized KLALBPacket readPacket() throws IOException {
int type=read();
if(type==-1) {
throw new EOFException();
}
KLALBPacket klp;
switch(type) {
case PING:klp=new PINGPacket();
klp.readFromStream(this);
return klp;
case PONG:
klp=new PONGPacket();
klp.readFromStream(this);
return klp;
case SYNT:
klp=new SYNTPacket();
klp.readFromStream(this);
return klp;
case SACKT:
klp=new SACKTPacket();
klp.readFromStream(this);
return klp;
case RST:
klp=new RSTPacket();
klp.readFromStream(this);
return klp;
case DATAT:
klp=new DATATPacket();
klp.readFromStream(this);
return klp;
case ACKT:
klp=new ACKTPacket();
klp.readFromStream(this);
return klp;
case VADDR:
klp=new VADDRPacket();
klp.readFromStream(this);
return klp;
}
throw new StreamCorruptedException("unknown package type:"+type);
}
}
@@ -0,0 +1,22 @@
package org.kne.cloud.network.klalb;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Inet6Address;
public class KLALBOutputStream extends DataOutputStream {
public KLALBOutputStream(OutputStream out) throws IOException {
super(out);
byte[]b=new byte[] {'K','L','A','L','B'};
write(b);
writeInt(2);
writeInt(0);
flush();
}
public synchronized void writePacket(KLALBPacket klb) throws IOException {
write(klb.getType());
klb.writeToStream(this);
}
}
@@ -0,0 +1,46 @@
package org.kne.cloud.network.klalb;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public abstract class KLALBPacket{
public static final int PING=0;
public static final int PONG=1;
public static final int SYNT=2;
public static final int SACKT=3;
public static final int RST=4;
public static final int DATAT=5;
public static final int ACKT=6;
public static final int DATAU=7;
public static final int VADDR=8;
private int type;
public KLALBPacket() {
super();
}
public KLALBPacket(int type) {
super();
this.type = type;
}
@Override
public String toString() {
return "KLALBPacket [type=" + type + "]";
}
public int getType() {
return type;
}
protected void writeToStream(DataOutput dto) throws IOException {
}
protected void readFromStream(DataInput din) throws IOException {
}
public long getLength() {
return 4;
}
}
@@ -0,0 +1,204 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.Socket;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import org.kne.cloud.network.mport.ThreadTool;
public class KLALBRemoteSocket extends MonitoredSocket {
private Inet6Address remoteVaddr;
public Inet6Address getRemoteVaddr() {
return remoteVaddr;
}
public KLALBRemoteSocket(Socket socket) {
super(socket);
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
try {
while (!isClosed()) {
KLALBPacket kpp = getInputStream().readPacket();
//System.out.println("RX:" + kpp);
if(kpp instanceof PINGPacket) {
sendPacket(new PONGPacket(), 65540);
}else if(kpp instanceof PONGPacket) {
latency.set(System.nanoTime()-pingstarttime);
pinging=false;
}else {
if(kpp instanceof VADDRPacket) {
remoteVaddr=((VADDRPacket) kpp).getVaddr();
}
while(rec==null) {
Thread.sleep(1);
}
rec.accept(kpp);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> {
try {
while (!isClosed()) {
if(System.nanoTime()-pingstarttime>100000000000L) {
pinging=false;
}
if(checkPingTime()&&!pinging) {
getOutputStream().writePacket(new PINGPacket());
pinging =true;
pingstarttime=System.nanoTime();
}else {
PQItem pqi=sendQueue.poll();
if(pqi!=null) {
KLALBPacket kpp=pqi.getPacket();
//System.out.println("TX:" + kpp);
getOutputStream().writePacket(kpp);
}else {
Thread.sleep(1);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
} finally {
try {
close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private volatile long pingstarttime=System.nanoTime();
private volatile boolean pinging=false;
private volatile long time = System.nanoTime();
private volatile long pingInterval=1000000000L;
public long getPingInterval() {
return pingInterval;
}
public void setPingInterval(long ns) {
this.pingInterval = ns;
}
private boolean checkPingTime() {
long cu = System.nanoTime();
if (cu - time > pingInterval) {
time = cu;
return true;
} else {
return false;
}
}
private volatile boolean waitingforPing = false;
public long getLatency() {
return latency.get();
}
private KLALBInputStream kis;
private KLALBOutputStream kos;
@Override
public KLALBInputStream getInputStream() throws IOException {
if (kis == null)
kis = new KLALBInputStream(super.getInputStream());
return kis;
}
@Override
public KLALBOutputStream getOutputStream() throws IOException {
if (kos == null)
kos = new KLALBOutputStream(super.getOutputStream());
return kos;
}
private AtomicLong latency = new AtomicLong();
private volatile Consumer<KLALBPacket> rec;
private Consumer<KLALBRemoteSocket> clo;
private PriorityBlockingQueue<PQItem> sendQueue=new PriorityBlockingQueue<PQItem>();
protected PriorityBlockingQueue<PQItem> getSendQueue() {
return sendQueue;
}
public void sendPacket(KLALBPacket kp) {
sendPacket(kp, 5);
}
public void sendPacket(KLALBPacket kp,int priority) {
sendQueue.add(new PQItem(kp, priority));
}
public void setPacketReceiver(Consumer<KLALBPacket> rec) {
this.rec = rec;
}
public void setCloseListener(Consumer<KLALBRemoteSocket> clo) {
this.clo = clo;
}
@Override
public synchronized void close() throws IOException {
super.close();
if(!isClosed()&&clo!=null)
clo.accept(this);
}
private AtomicLong al=new AtomicLong(0);
protected class PQItem implements Comparable<PQItem>{
private KLALBPacket packet;
private long index=al.getAndIncrement();
private int priority=5;
public PQItem(KLALBPacket value, int priority) {
super();
this.packet = value;
this.priority = priority;
}
public KLALBPacket getPacket() {
return packet;
}
public long getIndex() {
return index;
}
public int getPriority() {
return priority;
}
@Override
public int compareTo(PQItem o) {
if(priority<o.priority) {
return 1;
}else if(priority>o.priority) {
return -1;
}else {
if(index>o.index) {
return 1;
}else if(index<o.index){
return -1;
}else {
return 0;
}
}
}
}
}
@@ -1,53 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;
import java.util.function.Supplier;
import org.kne.cloud.network.mport.ServiceElement;
public class KLALBSM {
public static void main(String[] args) throws IOException {
System.out.println("KNE云负载均衡调度软件服务端V1.0");
ServerPropties sp=new ServerPropties();
int remp=sp.getPort();
System.out.println("开放端口:"+remp);
new KLALBServer(remp,new Supplier<String>() {
@Override
public String get() {
String sj="";
byte[] bytes;
try {
bytes = Files.readAllBytes(Paths.get("klalbs.json"));
sj = new String(bytes);
}catch (IOException e) {
e.printStackTrace();
}
return sj;
}
});
System.out.println("提示:运行时输入reload可以重新加载配置文件,已经建立的TCP连接不受影响(暂不支持修改开放端口)");
Scanner scn2=new Scanner(System.in);
while(true) {
String command=scn2.next();
switch(command) {
case "reload":
break;
}
}
}
}
@@ -1,145 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
import org.kne.cloud.network.mport.ThreadTool;
public class KLALBServer {
Map<UUID, KLALBController> whm=new ConcurrentHashMap<>();
//Map<UUID, IOThreadManager> whm=Collections.synchronizedMap( new WeakHashMap<UUID, IOThreadManager>());
public KLALBServer(int port,Supplier<String> gjso) throws IOException {
TCPListener tcpl=new TCPListener(port);
tcpl.setCon((s)->{
RemoteTCPConnection tcc=null;
KLALBController nx=null;
UUID uid=null;
try {
//s.setSoTimeout(10000);
tcc=new RemoteTCPConnection(null,s);
DataInputStream din=tcc.getDin();
int x=din.read();
if(x==0) {
String sj=gjso.get();
tcc.getDout().writeUTF(sj);
tcc.getDout().flush();
return;
}
String name = din.readUTF();
String ip = din.readUTF();
int portx=din.readInt();
Tunnel tll=new Tunnel(name,new IPPort( ip, portx));
tcc.setTunnel(tll);
uid=new UUID(din.readLong(),din.readLong());
tcc.handshake(10);
synchronized (whm) {
nx=whm.computeIfAbsent(uid, (kuid)->{
KLALBController iom=new KLALBController();
iom.getCore().setAcceptSYN((b,bol)->{
try {
STJson stj=new STJson(gjso.get());
if(!stj.checkSafety(b.lipport)) {
System.out.println("未授权的请求:"+b.lipport);
bol.accept(false);
return;
}
LocalTCPConnection ltc=null;
try {
Socket soc=new Socket(b.lipport.getIp(),b.lipport.getPort());
ltc=new LocalTCPConnection(soc, b.cuid);
bol.accept(true);
iom.handleLocal(ltc, false);
return;
} catch (IOException e) {
e.printStackTrace();
}finally {
if(ltc!=null)
ltc.close();
}
bol.accept(false);
return ;
} catch (IOException e) {
System.out.println("连接本地服务"+b.lipport+"失败,请检查你的本地服务");
e.printStackTrace();
}
bol.accept(false);
return;
});
return iom;
});
}
/*if(whm.containsKey(uid)) {
nx=whm.get(uid);
}else {
nx=new IOThreadManager();
IOThreadManager n1=nx;
nx.getCore().setAcceptSYN((b)->{
try {
STJson stj=new STJson(gjso.get());
if(!stj.checkSafety(b.lipport)) {
System.out.println("未授权的请求:"+b.lipport);
return false;
}
Socket soc=new Socket(b.lipport.getIp(),b.lipport.getPort());
LocalTCPConnection ltc=new LocalTCPConnection(soc, b.cuid);
ThreadTool.makeVThreadIfSupport("局域网连接监视线程", ()->{
try {
n1.handleLocal(ltc, false);
}finally {
ltc.close();
}
}).start();
return true;
} catch (IOException e) {
System.out.println("连接本地服务"+b.lipport+"失败,请检查你的本地服务");
e.printStackTrace();
}
return false;
});
whm.put(uid, nx);
}*/
nx.handleRemote(tcc);
}catch(IOException e) {
e.printStackTrace();
}finally {
if(tcc!=null)
tcc.close();
if(nx.getCore().getRemotetcps().isEmpty()) {
nx.close();
if(uid!=null)
whm.remove(uid);
}
}
});
tcpl.open();
}
/*public static void main(String[] args) throws IOException {
KLALBServer kc=new KLALBServer(4569);
}*/
}
@@ -0,0 +1,52 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import org.kne.cloud.network.mport.SocketBridge;
import org.kne.cloud.network.mport.TCPListener;
public class KLALBTest1 {
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
KLALBRemoteSocket s1=new KLALBRemoteSocket( new Socket("127.0.0.1", 8899));
KLALBRemoteSocket s2=new KLALBRemoteSocket(new Socket("127.0.0.1", 8899));
KLALBRemoteSocket s3=new KLALBRemoteSocket(new Socket("127.0.0.1", 8899));
KLALBController kc=new KLALBController((Inet6Address) Inet6Address.getByName("::2"));
kc.addRemoteSocket(s1);
kc.addRemoteSocket(s2);
kc.addRemoteSocket(s3);
TCPListener tl=new TCPListener(7463);
tl.open();
tl.setCon((x)->{
KLALBVirtualSocket kvs;
try {
kvs = new KLALBVirtualSocket(kc);
kvs.connect(new InetSocketAddress(InetAddress.getByName("::9"), 90));
new SocketBridge(kvs, x).run();
} catch (SocketException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
});
System.out.println("c");
Thread.sleep(20000);
s2.close();
while(true) {
Thread.sleep(1000);
}
}
}
@@ -0,0 +1,36 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.*;
import org.kne.cloud.network.mport.SocketBridge;
import org.kne.cloud.network.mport.TCPListener;
public class KLALBTest2 {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket ssk=new ServerSocket(8899);
KLALBRemoteSocket s1=new KLALBRemoteSocket(ssk.accept());
KLALBRemoteSocket s2=new KLALBRemoteSocket(ssk.accept());
KLALBRemoteSocket s3=new KLALBRemoteSocket(ssk.accept());
KLALBController cont=new KLALBController((Inet6Address) Inet6Address.getByName("::9"));
cont.addRemoteSocket(s1);
cont.addRemoteSocket(s2);
cont.addRemoteSocket(s3);
KLALBVirtualServerSocket ksr=new KLALBVirtualServerSocket(cont);
TCPListener tl=new TCPListener(90);
tl.setServerSocketFactory(new KLALBVirtualServerSocketFactory(cont));
tl.setCon((x)->{
try {
new SocketBridge(x, new Socket("127.0.0.1",5212)).run();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
});
tl.open();
Thread.sleep(20000);
s3.close();
}
}
@@ -0,0 +1,32 @@
package org.kne.cloud.network.klalb;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.util.UUID;
public class KLALBUtils {
public static Inet6Address uuidToIP(UUID uuid) {
ByteArrayOutputStream bos=new ByteArrayOutputStream(8);
DataOutputStream dos=new DataOutputStream(bos);
try {
dos.writeLong(uuid.getMostSignificantBits());
dos.writeLong(uuid.getLeastSignificantBits());
dos.close();} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
try {
return (Inet6Address) Inet6Address.getByAddress(bos.toByteArray());
} catch (UnknownHostException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
System.out.println(uuidToIP(new UUID(-1,-1)));
}
}
@@ -0,0 +1,55 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketImpl;
import org.kne.cloud.network.mport.VirtualServerSocket;
import org.kne.cloud.network.mport.VirtualSocket;
public class KLALBVirtualServerSocket extends VirtualServerSocket {
private KLALBController controler;
public KLALBVirtualServerSocket(KLALBController controler) throws IOException {
super(controler.createVirtualImpl());
this.controler=controler;
}
public KLALBVirtualServerSocket(KLALBController controler,int port) throws IOException {
this(controler,port, 50, null);
}
public KLALBVirtualServerSocket(KLALBController controler,int port, int backlog) throws IOException {
this(controler,port, backlog, null);
}
public KLALBVirtualServerSocket(KLALBController controler,int port, int backlog, InetAddress bindAddr) throws IOException {
this(controler);
if (backlog < 1)
backlog = 50;
try {
bind(new InetSocketAddress(bindAddr, port), backlog);
} catch(SecurityException e) {
close();
throw e;
} catch(IOException e) {
close();
throw e;
}
}
protected KLALBController getControler() {
return controler;
}
@Override
public KLALBVirtualSocket accept() throws IOException {
KLALBVirtualSocket s2=new KLALBVirtualSocket(controler);
implAccept(s2);
return s2;
}
}
@@ -0,0 +1,36 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import javax.net.ServerSocketFactory;
public class KLALBVirtualServerSocketFactory extends ServerSocketFactory {
private KLALBController controller;
public KLALBVirtualServerSocketFactory(KLALBController controller) {
super();
this.controller = controller;
}
public KLALBController getController() {
return controller;
}
@Override
public ServerSocket createServerSocket(int port) throws IOException {
return new KLALBVirtualServerSocket(controller,port);
}
@Override
public ServerSocket createServerSocket(int port, int backlog) throws IOException {
return new KLALBVirtualServerSocket(controller, port,backlog);
}
@Override
public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException {
return new KLALBVirtualServerSocket(controller, port, backlog, ifAddress);
}
}
@@ -0,0 +1,21 @@
package org.kne.cloud.network.klalb;
import java.net.SocketException;
import java.net.SocketImpl;
import org.kne.cloud.network.mport.VirtualSocket;
public class KLALBVirtualSocket extends VirtualSocket {
private KLALBController controler;
public KLALBVirtualSocket(KLALBController controler) throws SocketException {
super(controler.createVirtualImpl());
this.controler=controler;
}
protected KLALBController getControler() {
return controler;
}
}
@@ -0,0 +1,503 @@
package org.kne.cloud.network.klalb;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.BindException;
import java.net.ConnectException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NoRouteToHostException;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketImpl;
import java.net.SocketOptions;
import java.net.SocketTimeoutException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.kne.io.Data;
import java.util.*;
public class KLALBVirtualSocketImpl extends SocketImpl {
private KLALBController controller;
protected int getInputchachesize() {
return inputchachesize;
}
protected void setInputchachesize(int inputchachesize) {
this.inputchachesize = inputchachesize;
}
protected int getOutputchachesize() {
return outputchachesize;
}
protected void setOutputchachesize(int outputchachesize) {
this.outputchachesize = outputchachesize;
}
private int inputchachesize = 65535 * 50;
private int outputchachesize = 65535 * 50;
private Inet6Address bindaddr;
private BlockingQueue<InetSocketAddress> backlogQueue;
private BlockingDeque<DATATPacket> sendDeque = new LinkedBlockingDeque<>();
private List<SendTask> sendlist=new Vector<>();
private boolean succeed, refused;
protected boolean isListening() {
return backlogQueue != null;
}
private List<DATATPacket> inputchache = new ArrayList<>();
private long inputcount = 0;
private boolean avaliable = true;
private BiConsumer<Inet6Address, KLALBPacket> packReceiver = new BiConsumer<Inet6Address, KLALBPacket>() {
@Override
public void accept(Inet6Address from, KLALBPacket u) {
try {
if (u instanceof SYNTPacket) {
if (isListening()) {
if (backlogQueue.offer(new InetSocketAddress(from, ((SYNTPacket) u).getSport()))) {
controller.sendPacketToAddress(from,
new SACKTPacket(localport, ((SYNTPacket) u).getSport()), 65537);
} else {
controller.sendPacketToAddress(from, new RSTPacket(localport, ((SYNTPacket) u).getSport()),
65537);
}
} else {
controller.sendPacketToAddress(from, new RSTPacket(localport, ((SYNTPacket) u).getSport()),
65537);
}
} else if (u instanceof SACKTPacket) {
if (connecting) {
connecting = false;
succeed = true;
cdl.countDown();
}
} else if (u instanceof RSTPacket) {
if (connecting) {
connecting = false;
refused = true;
cdl.countDown();
close();
} else {
close();
}
} else if (u instanceof DATATPacket) {
DATATPacket dtp = (DATATPacket) u;
synchronized (inputchache) {
if (dtp.getNumber() >= inputcount) {
inputchache.add(dtp);
while (true) {
DATATPacket kkb = null;
for (int i = 0; i < inputchache.size(); i++) {
DATATPacket klalbBlock = inputchache.get(i);
if (klalbBlock.getNumber() == inputcount) {
inputchache.remove(i);
i--;
kkb = klalbBlock;
break;
}
}
if (kkb == null)
break;
sendDeque.add(kkb);
inputcount++;
}
}
}
controller.sendPacketToAddress(from, new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp.getNumber(),
countInputBytes() < inputchachesize), 32768);
} else if (u instanceof ACKTPacket) {
ACKTPacket ackt = (ACKTPacket) u;
avaliable = ackt.isAvaliable();
sendlist.removeIf((tsk)->{
boolean b=tsk.getKp().getNumber()==ackt.getNumber();
if(b)
tsk.cancel();
return b;
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
private int countInputBytes() {
AtomicInteger i = new AtomicInteger(0);
sendDeque.forEach((c) -> {
i.addAndGet(c.getData().length);
});
return i.get();
}
private int countOutputBytes() {
AtomicInteger i = new AtomicInteger(0);
sendlist.forEach((c) -> {
i.addAndGet(c.getKp().getData().length);
});
return i.get();
}
public KLALBController getController() {
return controller;
}
public BiConsumer<Inet6Address, KLALBPacket> getPackReceiver() {
return packReceiver;
}
public KLALBVirtualSocketImpl(KLALBController kc) {
super();
this.controller = kc;
}
@Override
public void setOption(int optID, Object value) throws SocketException {
// TODO 自动生成的方法存根
}
@Override
public Object getOption(int optID) throws SocketException {
// TODO 自动生成的方法存根
return null;
}
@Override
protected void create(boolean stream) throws IOException {
if (!stream) {
throw new RuntimeException("please use KLALBVirtualDatagramSocket to process udp packet");
}
}
@Override
protected void connect(String host, int port) throws IOException {
connect(InetAddress.getByName(host), port);
}
@Override
protected void connect(InetAddress address, int port) throws IOException {
connect(new InetSocketAddress(address, port), 10000);
}
private CountDownLatch cdl = new CountDownLatch(1);
@Override
protected void connect(SocketAddress address, int timeout) throws IOException {
if (!controller.checkIsBind(this)) {
bind(Inet6Address.getByName("::0"), 0);
}
connecting = true;
port = ((InetSocketAddress) address).getPort();
this.address = ((InetSocketAddress) address).getAddress();
controller.sendPacketToAddress((Inet6Address) this.address, new SYNTPacket(localport, port), 65537);
try {
if (timeout == 0) {
cdl.await();
} else {
cdl.await(timeout, TimeUnit.MILLISECONDS);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
connecting = false;
if (succeed) {
} else if (refused) {
throw new ConnectException("connect refused");
} else {
throw new SocketTimeoutException("connect time out");
}
}
private volatile boolean connecting = false;
public boolean isConnecting() {
return connecting;
}
@Override
protected void bind(InetAddress host, int port) throws IOException {
if (host.equals(Inet4Address.getByName("0.0.0.0"))) {
host = Inet6Address.getByName("::0");
}
if (!(host instanceof Inet6Address)) {
throw new IllegalArgumentException("invalid address type, KLALB socket can only use IPV6 virtualaddress");
}
if ((!host.isAnyLocalAddress()) && (!host.equals(controller.getSelf()))) {
throw new BindException("must bind to self");
}
bindaddr = (Inet6Address) host;
this.localport = controller.bind(this, port);
}
@Override
protected void listen(int backlog) throws IOException {
backlogQueue = new ArrayBlockingQueue<>(backlog);
}
private Map<InetSocketAddress, KLALBVirtualSocketImpl> accepts = new ConcurrentHashMap<>();
public Map<InetSocketAddress, KLALBVirtualSocketImpl> getAccepts() {
return accepts;
}
@Override
protected void accept(SocketImpl s) throws IOException {
try {
KLALBVirtualSocketImpl kvsi = (KLALBVirtualSocketImpl) s;
InetSocketAddress isa = backlogQueue.take();
kvsi.port = isa.getPort();
kvsi.address = isa.getAddress();
kvsi.localport = localport;
kvsi.bindaddr = bindaddr;
accepts.put(isa, kvsi);
kvsi.setCloseListener((x) -> {
accepts.remove(isa);
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private Consumer<KLALBVirtualSocketImpl> acceptedSocketCloseListener;
private void setCloseListener(Consumer<KLALBVirtualSocketImpl> lsr) {
this.acceptedSocketCloseListener = lsr;
}
private KVSIInputStream vin;
private KVSIOutputStream vout;
private class KVSIInputStream extends InputStream {
private DATATPacket dtp = null;
private int count = 0;
private boolean shutdown=false;
@Override
public int read() throws IOException {
if(shutdown)
return -1;
if (dtp == null || (count >= dtp.getData().length && dtp.getData().length != 0)) {
count = 0;
while (true) {
if (isClosed())
throw new SocketException("Socket is closed");
DATATPacket dtp2 = sendDeque.poll();
if (dtp2 != null) {
dtp = dtp2;
if(countInputBytes() < inputchachesize) {
controller.sendPacketToAddress((Inet6Address) address, new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp2.getNumber(),
true), 32768);
}
break;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (dtp.getData().length == 0) {
return -1;
} else
return dtp.getData()[count++] & 0xff;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
len = Math.min(len, available());
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte) c;
int i = 1;
try {
for (; i < len; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte) c;
}
} catch (IOException ee) {
}
return i;
}
@Override
public void close() throws IOException {
shutdown=true;
}
@Override
public int available() throws IOException {
AtomicInteger i = new AtomicInteger(0);
sendDeque.forEach((V) -> {
i.addAndGet(V.getData().length);
});
if (dtp != null)
i.addAndGet(dtp.getData().length - count);
return i.get();
}
}
private long outputcount = 0;
private class KVSIOutputStream extends OutputStream {
private ByteArrayOutputStream bos = new ByteArrayOutputStream(65535);
@Override
public void write(int b) throws IOException {
if (isClosed())
throw new SocketException("Socket is closed");
bos.write(b);
if (bos.size() >= 65535) {
flush();
}
}
@Override
public void flush() throws IOException {
if (bos.size() > 0) {
try {
while (!avaliable) {
Thread.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
while(countOutputBytes()>outputchachesize) {
Thread.sleep(1);
}
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, bos.toByteArray()), 5,5);
x.addToTimer(1000);
sendlist.add(x);
/*controller.sendPacketToAddress((Inet6Address) address,
new DATATPacket(localport, port, outputcount++, bos.toByteArray()), 5);*/
}
bos.reset();
}
@Override
public void close() throws IOException {
flush();
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, new byte[0]), 5,5);
x.addToTimer(1000);
sendlist.add(x);
/*controller.sendPacketToAddress((Inet6Address) address,
new DATATPacket(localport, port, outputcount++, new byte[0]), 5);*/
}
}
@Override
protected InputStream getInputStream() throws IOException {
if (vin == null) {
vin = new KVSIInputStream();
}
return vin;
}
@Override
protected OutputStream getOutputStream() throws IOException {
if (vout == null) {
vout = new KVSIOutputStream();
}
return vout;
}
@Override
protected int available() throws IOException {
return getInputStream().available();
}
@Override
protected void shutdownInput() throws IOException {
getInputStream().close();
}
@Override
protected void shutdownOutput() throws IOException {
getOutputStream().close();
}
@Override
protected void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
// TODO 自动生成的方法存根
super.setPerformancePreferences(connectionTime, latency, bandwidth);
}
@Override
protected void close() throws IOException {
if (!isListening() && !isClosed()) {
closed = true;
controller.sendPacketToAddress((Inet6Address) super.address, new RSTPacket(super.localport, super.port),
65537);
}
if (acceptedSocketCloseListener != null)
acceptedSocketCloseListener.accept(this);
else
controller.unbind(this);
}
private boolean closed;
private boolean isClosed() {
return closed;
}
@Override
protected void sendUrgentData(int data) throws IOException {
throw new UnsupportedOperationException("urgent data unspuuorted");
}
@Override
protected int getLocalPort() {
// TODO 自动生成的方法存根
return super.getLocalPort();
}
}
@@ -0,0 +1,50 @@
package org.kne.cloud.network.klalb;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
public class LineDecitionComparator implements Comparator<KLALBRemoteSocket> {
private Map<KLALBRemoteSocket,Long> predictedlatencys=new HashMap<>();
public LineDecitionComparator (List<KLALBRemoteSocket> krs,int priority) {
for (Iterator<KLALBRemoteSocket> iterator = krs.iterator(); iterator.hasNext();) {
KLALBRemoteSocket klalbRemoteSocket = (KLALBRemoteSocket) iterator.next();
long x=klalbRemoteSocket.getLatency()>>1;
AtomicLong al=new AtomicLong(0);
klalbRemoteSocket.getSendQueue().forEach((v)->{
if(v.getPriority()>=priority) {
al.addAndGet(v.getPacket().getLength());
}
});
long speed=klalbRemoteSocket.getOutSpeed();
if(speed==0) {
if(al.get()>0) {
x=Long.MAX_VALUE;
}
}else {
x+=al.get()*1000000000/speed;
}
predictedlatencys.put(klalbRemoteSocket, x);
}
}
public Map<KLALBRemoteSocket, Long> getPredictedlatencys() {
return predictedlatencys;
}
@Override
public int compare(KLALBRemoteSocket o1, KLALBRemoteSocket o2) {
long t1=predictedlatencys.get(o1);
long t2=predictedlatencys.get(o2);
if(t1>t2) {
return 1;
}else if(t1<t2){
return -1;
}else {
return 0;
}
}
}
@@ -1,174 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import org.kne.cloud.network.mport.ServiceElement;
public class LocalTCPConnection extends TCPConnection {
private static AtomicInteger sng=new AtomicInteger(1);
private int cuid;
private ServiceElement serviceElement;
//private Set<KLALBBlock> inputcache = Collections.synchronizedSet( new TreeSet<>());
private List<KLALBBlock>inputcache=new Vector<>();
private List<KLALBBlock> outputcache = new Vector<>();
private volatile int blocksize=8192;
private volatile int inputcachesize=100*blocksize;
private volatile int outputcachesize=100*blocksize;
private volatile long inputcount = 1;
private volatile long outputcount = 1;
public LocalTCPConnection(Socket s) throws IOException {
super(s);
s.setKeepAlive(true);
cuid=sng.getAndIncrement();
}
public LocalTCPConnection(Socket s,int uid) throws IOException {
super(s);
s.setKeepAlive(true);
cuid=uid;
}
public int getBlocksize() {
return blocksize;
}
public void setBlocksize(int blocksize) {
this.blocksize = blocksize;
}
public int getInputcachesize() {
return inputcachesize;
}
public void setInputcachesize(int inputcachesize) {
this.inputcachesize = inputcachesize;
}
public int getOutputcachesize() {
return outputcachesize;
}
public void setOutputcachesize(int outputcachesize) {
this.outputcachesize = outputcachesize;
}
public int getCuid() {
return cuid;
}
public void setCuid(int cuid) {
this.cuid = cuid;
}
public ServiceElement getServiceElement() {
return serviceElement;
}
public void setServiceElement(ServiceElement serviceElement) {
this.serviceElement = serviceElement;
}
public List<KLALBBlock> getInputcache() {
return inputcache;
}
public List<KLALBBlock> getOutputcache() {
return outputcache;
}
public long getInputcount() {
return inputcount;
}
public long getOutputcount() {
return outputcount;
}
public void unpackBlock(KLALBBlock data) throws IOException {
/*if(data.number<inputcount) {
return;
}
inputcache.add(data);
for (Iterator<KLALBBlock> iterator = inputcache.iterator(); iterator.hasNext();) {
KLALBBlock klalbBlock = (KLALBBlock) iterator.next();
if(klalbBlock.number==inputcount) {
iterator.remove();
getDout().write(klalbBlock.data);
getDout().flush();
inputcount++;
}else {
break;
}
}*/
getDout().write(data.data);
getDout().flush();
}
public KLALBBlock packBlock() throws IOException {
byte[]dat=new byte[blocksize];
int len=getDin().read(dat);
KLALBBlock pb=new KLALBBlock();
pb.cuid=cuid;
pb.number=outputcount++;
if(len==-1) {
pb.data=null;
}else if(len==dat.length){
pb.data=dat;
}else {
pb.data=Arrays.copyOf(dat, len);
}
return pb;
}
private BlockingDeque<KLALBBlock>sendDeque=new LinkedBlockingDeque<>();
public BlockingDeque<KLALBBlock> getSendDeque() {
return sendDeque;
}
//private volatile int pcu=0;
private volatile Consumer<LocalTCPConnection> hook;
public volatile long uackt=System.nanoTime();
public volatile long ukeept=System.nanoTime();
/*public void setPeerCacheUsed(int cacheused) {
pcu= cacheused;
}
public int getPeerCacheUsed() {
return pcu;
}*/
public Consumer<LocalTCPConnection> getRSTHook() {
return hook;
}
public void setRSTHook(Consumer<LocalTCPConnection> tc) {
this.hook=tc;
}
private volatile boolean pfl=false;
public void setPeerFull(boolean b) {
pfl=b;
}
public boolean isPeerFull() {
return pfl;
}
/*public int getSendDequeBytes() {
AtomicInteger a=new AtomicInteger(0);
getSendDeque().forEach((v)->{
if(v.data!=null)
a.addAndGet(v.data.length);
});
return a.get();
}*/
public void incInputcount() {
inputcount++;
}
private volatile boolean issyk=false;
public boolean isIssyk() {
return issyk;
}
public void setIssyk(boolean issyk) {
this.issyk = issyk;
}
private volatile boolean isrst=false;
public boolean isIsrst() {
return isrst;
}
public void setIsrst(boolean isrst) {
this.isrst = isrst;
}
}
@@ -4,11 +4,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicLong;
public class InputMetre extends InputStream {
public class MonitoredInputStream extends InputStream {
private InputStream in;
private AtomicLong[] total;
public InputMetre(InputStream inputStream,AtomicLong... v) {
public MonitoredInputStream(InputStream inputStream,AtomicLong... v) {
this.in=inputStream;
this.total=v;
}
@@ -4,11 +4,11 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicLong;
public class OutputMetre extends OutputStream {
public class MonitoredOutputStream extends OutputStream {
private OutputStream out;
private AtomicLong[] total;
public OutputMetre(OutputStream outputStream,AtomicLong ...v) {
public MonitoredOutputStream(OutputStream outputStream,AtomicLong ...v) {
this.out=outputStream;
this.total=v;
}
@@ -0,0 +1,80 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.mport.FilterSocket;
public class MonitoredSocket extends FilterSocket {
private static Timer t=new Timer("带宽测量线程",true);
private TimerTask ptt=new TimerTask() {
@Override
public void run() {
runMonitor();
}
};
public MonitoredSocket(Socket socket) {
super(socket);
t.scheduleAtFixedRate(ptt, 1000, 1000);
}
protected void runMonitor() {
inSpeed.set( inTraffic.get()-inTrafficOld.get());
outSpeed.set( outTraffic.get()-outTrafficOld.get());
inTrafficOld.set(inTraffic.get());
outTrafficOld.set(outTraffic.get());
}
public long getInTraffic() {
return inTraffic.get();
}
public long getOutTraffic() {
return outTraffic.get();
}
public long getInSpeed() {
return inSpeed.get();
}
public long getOutSpeed() {
return outSpeed.get();
}
private InputStream in;
private OutputStream out;
private AtomicLong inTraffic=new AtomicLong();
private AtomicLong outTraffic=new AtomicLong();
private AtomicLong inTrafficOld=new AtomicLong();
private AtomicLong outTrafficOld=new AtomicLong();
private AtomicLong inSpeed=new AtomicLong();
private AtomicLong outSpeed=new AtomicLong();
@Override
public InputStream getInputStream() throws IOException {
if(in==null)
in=new MonitoredInputStream(socket.getInputStream(), inTraffic);
return in;
}
@Override
public OutputStream getOutputStream() throws IOException {
if(out==null) {
out=new MonitoredOutputStream(socket.getOutputStream(), outTraffic);
}
return out;
}
}
@@ -0,0 +1,16 @@
package org.kne.cloud.network.klalb;
public class PINGPacket extends KLALBPacket {
public PINGPacket() {
super(PING);
}
@Override
public String toString() {
return "PING";
}
}
@@ -0,0 +1,12 @@
package org.kne.cloud.network.klalb;
public class PONGPacket extends KLALBPacket {
public PONGPacket() {
super(PONG);
}
@Override
public String toString() {
return "PONG";
}
}
@@ -1,46 +0,0 @@
package org.kne.cloud.network.klalb;
import java.util.Objects;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
public class ProxyElement {
private ServiceElement se;
private IPPort ipport;
public ServiceElement getSe() {
return se;
}
public IPPort getIpport() {
return ipport;
}
@Override
public int hashCode() {
return Objects.hash(ipport, se);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ProxyElement other = (ProxyElement) obj;
return Objects.equals(ipport, other.ipport) && Objects.equals(se, other.se);
}
public ProxyElement(ServiceElement se, IPPort ipport) {
super();
this.se = se;
this.ipport = ipport;
}
public ProxyElement() {
}
public void setSe(ServiceElement se) {
this.se = se;
}
public void setIpport(IPPort ipport) {
this.ipport = ipport;
}
}
@@ -1,42 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.util.Properties;
import org.kne.cloud.network.mport.ServiceElement;
public class ProxyIPPortProperties extends Properties{
public ProxyIPPortProperties(File location ,String name,String dip,int dport) throws FileNotFoundException, IOException {
File f=new File(location,name+".json");
if(!f.exists()||f.length()==0) {
f.createNewFile();
PrintStream ps=new PrintStream(f);
ps.println("bindport="+dport);
ps.println("bindip="+dip);
ps.close();
}
FileReader fr = null;
try {
fr=new FileReader(f);
load(fr);
}finally {
if(fr!=null)
fr.close();
}
}
public int getBindPort() {
return Integer.parseInt((String) get("bindport"));
}
public String getBindIP() {
return (String) get("bindip");
}
}
@@ -1,101 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.*;
import java.util.*;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
public class ProxyJson {
private File f;
private List<ProxyElement> pls=new ArrayList<>();
public List<ProxyElement> getPls() {
return pls;
}
public ProxyJson(File f,STJson def) throws IOException {
super();
this.f = f;
if(!f.exists()||f.length()==0l) {
f.createNewFile();
JsonWriter jw=null;
try {
jw=new JsonWriter(new FileWriter(f));
jw.setIndent(" ");
jw.beginObject();
jw.name("services");
jw.beginArray();
for (Iterator<ServiceElement> iterator = def.getServices().iterator(); iterator.hasNext();) {
ServiceElement proxye = (ServiceElement) iterator.next();
jw.beginObject();
jw.name("name");
jw.value(proxye.name);
jw.name("protocol");
jw.value(proxye.protocol);
jw.name("localaddress");
jw.value(proxye.ipport.toString());
jw.name("bindaddress");
jw.value("0.0.0.0:"+proxye.ipport.getPort());
jw.endObject();
}
jw.endArray();
jw.endObject();
}finally{
if(jw!=null)
jw.close();
}
}
JsonReader jr=null;
try {
jr=new JsonReader(new FileReader(f));
jr.beginObject();
while(jr.hasNext()) {
String name=jr.nextName();
switch(name) {
case "services":
jr.beginArray();
while(jr.hasNext()) {
jr.beginObject();
ProxyElement pe=new ProxyElement();
ServiceElement se=new ServiceElement();
pe.setSe(se);
while(jr.hasNext()) {
String n3=jr.nextName();
switch(n3) {
case "name":
se.name=jr.nextString();
break;
case "protocol":
se.protocol=jr.nextString();
break;
case "localaddress":
se.ipport=new IPPort (jr.nextString());
break;
case "bindaddress":
pe.setIpport(new IPPort (jr.nextString()));
break;
default:
jr.skipValue();
break;
}
}
pls.add(pe);
jr.endObject();
}
jr.endArray();
break;
default:
jr.skipValue();
break;
}
}
jr.endObject();
}finally {
if(jr!=null)
jr.close();
}
}
}
@@ -0,0 +1,51 @@
package org.kne.cloud.network.klalb;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class RSTPacket extends KLALBPacket {
private int sport,dport;
public RSTPacket(int sport,int dport) {
super(RST);
this.sport=sport;
this.dport=dport;
}
@Override
public long getLength() {
return super.getLength()+8;
}
public RSTPacket() {
super();
}
public int getSport() {
return sport;
}
public int getDport() {
return dport;
}
@Override
public String toString() {
return "RST "+sport+"->"+dport;
}
@Override
protected void writeToStream(DataOutput dto) throws IOException {
super.writeToStream(dto);
dto.writeInt(sport);
dto.writeInt(dport);
}
@Override
protected void readFromStream(DataInput din) throws IOException {
super.readFromStream(din);
sport=din.readInt();
dport=din.readInt();
}
}
@@ -1,404 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StreamCorruptedException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.UUID;
import java.util.Vector;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.Inflater;
import org.kne.cloud.network.mport.IPPort;
import org.kne.io.AddInputStream;
import org.kne.io.AddOutputStream;
public class RemoteTCPConnection extends TCPConnection {
public RemoteTCPConnection(Tunnel t) throws UnknownHostException, IOException {
this(t, t.connectClientSocket());
if (tunnel != null) {
t.getRtcs().add(this);
}
}
AtomicLong om=new AtomicLong(0);
AtomicLong im=new AtomicLong(0);
long om1=0;
long im1=0;
private volatile long ups,downs;
private volatile double upsm,downsm;
@Override
protected void initIO() throws IOException {
}
protected void initIOs() throws IOException {
connect.setTrafficClass(0x10);
connect.setTcpNoDelay(true);
OutputStream outm=null;
InputStream inm=null;
if(tunnel!=null) {
outm = new OutputMetre( connect.getOutputStream(),tunnel.getOM(),om);
inm = new InputMetre(connect.getInputStream(),tunnel.getIM(),im);
}else {
outm = new OutputMetre( connect.getOutputStream(),om);
inm = new InputMetre(connect.getInputStream(),im);
}
new DataOutputStream(outm).writeShort(59649);//59649
outm.flush();
int val=new DataInputStream(inm).readShort()&0xffff;
if(val!=59649) {
throw new StreamCorruptedException();
}
dout = new DataOutputStream(outm);
din = new DataInputStream(inm);
}
public long getUps() {
return ups;
}
public long getDowns() {
return downs;
}
public AtomicLong getOm() {
return om;
}
public AtomicLong getIm() {
return im;
}
private volatile long ptime=System.nanoTime();
public void updateTraffics() {
long ctime=System.nanoTime();
long det=ctime-ptime;
ptime=ctime;
ups= (om.get()-om1)*1000000000/det;
downs= (im.get()-im1)*1000000000/det;
/*
if(ndbg==null)
initcdbg();
ndbg.println((om.get()-om1)+ (im.get()-im1)+","+delay);
*/
om1=om.get();
im1=im.get();
if(ups>upsm) {
upsm=ups;
}else {
upsm=(upsm*1000+ups)/1001;
}
if(downs>downsm) {
downsm=downs;
}else {
downsm=(downsm*1000+downs)/1001;
}
//predictLatency();
//System.out.println(tunnel+"//// "+upsm+" "+downsm+" "+getPredictedLatency());
}
private double latency;
public double getPredictedLatency() {
return latency;
}
public void predictLatency(int prio) {
AtomicLong data=new AtomicLong(0);
for (int i = 0; i <=prio; i++) {
Queue<KLALBBlock> sendDequev=sendDequeList.get(i);
sendDequev.forEach((e)->{
data.addAndGet(12);
if(e.data!=null) {
data.addAndGet(e.data.length);
}
});
}
latency= delay/2000000.0+data.get()*1000.0/upsm;
}
@Override
public String toString() {
return "RemoteTCPConnection [tunnel=" + tunnel + "]";
}
public RemoteTCPConnection(Tunnel t, Socket s) throws UnknownHostException, IOException {
super(s);
tunnel=t;
initIOs();
s.setSoTimeout(Consts.PRE_SO_TIMEOUT);
}
private long delay = Long.MAX_VALUE;
private Tunnel tunnel;
public Tunnel getTunnel() {
return tunnel;
}
public void setTunnel(Tunnel tunnel) {
this.tunnel = tunnel;
}
public long getDelay() {
return delay;
}
public void setDelay(long delay) {
this.delay = delay;
if (tunnel != null) {
tunnel.setDelay(delay);
}
}
long odelay=Long.MAX_VALUE;
@Override
public void close() {
if (tunnel != null) {
tunnel.getRtcs().remove(this);
}
super.close();
}
@Override
protected void finalize() throws Throwable {
if (tunnel != null) {
tunnel.getRtcs().remove(this);
}
super.finalize();
}
public void sendBlock(KLALBBlock data) throws IOException {
sendBlock(data,true);
}
public void sendBlock(KLALBBlock data,boolean isflush) throws IOException {
dout.writeInt(data.cuid);
dout.writeLong(data.number);
if (data.number > 0) {
if (data.data == null) {
dout.writeShort(-1);
} else {
/*Deflater def = new Deflater(Deflater.BEST_COMPRESSION, true);
def.setInput(data.data);
def.finish();
byte[] b = new byte[(int)(data.data.length * 1.1D) + 64];
int nsize = def.deflate(b);
def.end();
this.dout.writeShort(nsize);
this.dout.write(b, 0, nsize);*/
dout.writeShort(data.data.length);
dout.write(data.data);
//System.out.println(Arrays.toString(data.data));
}
} else if (data.number == 0) {
dout.write(data.command);
/*if(data.command!=0&&data.command!=1) {
dout.writeLong(data.sn);
}else {
}*/
switch (data.command) {
case 0:
case 1:
dout.writeLong(data.pingtime);
break;
case 2:
dout.writeUTF(data.lservice);
dout.writeUTF(data.lipport.toString());
break;
default:
break;
}
} else {
dout.writeBoolean(data.cacheused);
}
if(isflush)
dout.flush();
System.out.println("SEND:" + data);
}
public KLALBBlock receiveBlock() throws IOException, DataFormatException {
KLALBBlock klb = new KLALBBlock();
klb.cuid = din.readInt();
klb.number = din.readLong();
if (klb.number > 0) {
int size = din.readShort();
if (size == -1) {
klb.data = null;
} else {
byte[] d = new byte[size];
din.readFully(d);
/*Inflater in = new Inflater(true);
in.setInput(d);
byte[] b = new byte[8192];
int nsize = in.inflate(b);
in.end();
if (nsize == b.length) {
klb.data = b;
} else {
klb.data = Arrays.copyOf(b, nsize);
} */
//System.out.println(Arrays.toString(d));
klb.data = d;
}
} else if (klb.number == 0) {
klb.command = din.read();
/*if(klb.command!=0&&klb.command!=1) {
klb.sn = din.readLong();
}else {
klb.sn=0;
}*/
switch (klb.command) {
case 0:
case 1:
klb.pingtime = din.readLong();
break;
case 2:
klb.lservice = din.readUTF();
klb.lipport = new IPPort(din.readUTF());
break;
default:
break;
}
} else {
klb.cacheused = din.readBoolean();
}
System.out.println("RECEIVE:" + klb);
return klb;
}
private volatile long time = System.nanoTime();
public boolean checkPingTime() {
long cu = System.nanoTime();
if (cu - time > Consts.PINGTIMENS) {
time = cu;
return true;
} else {
return false;
}
}
private List<Queue<KLALBBlock>> sendDequeList =new Vector<Queue<KLALBBlock>>();
{
for(int i=0;i<11;i++) {
sendDequeList.add(new ConcurrentLinkedQueue<KLALBBlock>());
}
}
public List<Queue<KLALBBlock>> getSendDequeList() {
return sendDequeList;
}
private Object lock=new Object();
public void addBlock(KLALBBlock blk,int prio) {
sendDequeList.get(prio).add(blk);
synchronized (lock) {
lock.notifyAll();
}
}
/* private Queue<KLALBBlock> NDsendDeque = new ConcurrentLinkedQueue<KLALBBlock>();
public Queue<KLALBBlock> getNDSendDeque() {
return NDsendDeque;
}
private Queue<KLALBBlock> sendDeque = new ConcurrentLinkedQueue<KLALBBlock>();
public Queue<KLALBBlock> getSendDeque() {
return sendDeque;
}*/
public void handshake(int x) throws IOException {
for(int i=0;i<x;i++) {
getDout().write(0);
getDout().flush();
int v=getDin().read();
if(v==-1) {
throw new EOFException();
}
if(v!=0) {
throw new StreamCorruptedException();
}
}
}
public void lock(long to) throws InterruptedException {
synchronized (lock) {
lock.wait(to);
}
}
public void ackRemove(long number, int cuid) {
for (Iterator<Queue<KLALBBlock>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
Queue<KLALBBlock> queue = iterator.next();
queue.removeIf((vb)->{
return vb.number==number&&vb.cuid==cuid;
});
}
}
public boolean isEmpty() {
synchronized (sendDequeList) {
for (Iterator<Queue<KLALBBlock>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
Queue<KLALBBlock> queue = (Queue<KLALBBlock>) iterator.next();
if(!queue.isEmpty()) {
return false;
}
}
}
return true;
}
public KLALBBlock getNextBlock() {
synchronized (sendDequeList) {
for (Iterator<Queue<KLALBBlock>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
Queue<KLALBBlock> queue = (Queue<KLALBBlock>) iterator.next();
KLALBBlock v=queue.poll();
if(v!=null)
return v;
}
}
return null;
}
public void setSoTimeout(int soTimeout) {
try {
connect.setSoTimeout(soTimeout);
} catch (SocketException e) {
//e.printStackTrace();
}
}
}
@@ -0,0 +1,52 @@
package org.kne.cloud.network.klalb;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class SACKTPacket extends KLALBPacket {
@Override
public long getLength() {
return super.getLength()+8;
}
public int getSport() {
return sport;
}
public int getDport() {
return dport;
}
private int sport,dport;
public SACKTPacket(int sport,int dport) {
super(SACKT);
this.sport=sport;
this.dport=dport;
}
public SACKTPacket() {
super();
}
@Override
public String toString() {
return "SACKT "+sport+"->"+dport;
}
@Override
protected void writeToStream(DataOutput dto) throws IOException {
super.writeToStream(dto);
dto.writeInt(sport);
dto.writeInt(dport);
}
@Override
protected void readFromStream(DataInput din) throws IOException {
super.readFromStream(din);
sport=din.readInt();
dport=din.readInt();
}
}
-104
View File
@@ -1,104 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.io.StringReader;
import java.util.*;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
import com.google.gson.stream.JsonReader;
public class STJson {
private String name;
private List<ServiceElement> services=new ArrayList<>();
private List<Tunnel> tunnels=new ArrayList<>();
public List<ServiceElement> getServices() {
return services;
}
public List<Tunnel> getTunnels() {
return tunnels;
}
public STJson(String json) throws IOException {
JsonReader sr = new JsonReader(new StringReader(json));
sr.beginObject();
while (sr.hasNext()) {
String n = sr.nextName();
if (n.equals("name")) {
name = sr.nextString();
} else if (n.equals("services")) {
sr.beginArray();
while (sr.hasNext()) {
sr.beginObject();
ServiceElement se=new ServiceElement();
while (sr.hasNext()) {
String n2 = sr.nextName();
if (n2.equals("name")) {
se.name=sr.nextString();
} else if (n2.equals("protocol")) {
se.protocol=sr.nextString();
} else if (n2.equals("localaddress")) {
se.ipport=new IPPort( sr.nextString());
} else{
sr.skipValue();
}
}
services .add(se);
sr.endObject();
}
sr.endArray();
} else if (n.equals("tunnels")) {
sr.beginArray();
while (sr.hasNext()) {
sr.beginObject();
Tunnel t=new Tunnel();
while (sr.hasNext()) {
String n2 = sr.nextName();
if (n2.equals("name")) {
t.setName(sr.nextString());
} else if (n2.equals("remoteaddress")) {
t.setIpport(new IPPort( sr.nextString()));
} else if (n2.equals("frpc")) {
StringBuilder sbd=new StringBuilder();
sr.beginArray();
while(sr.hasNext()) {
sbd.append(sr.nextString());
sbd.append('\r');
sbd.append('\n');
}
sr.endArray();
t.setFrpc(sbd.toString());
} else{
sr.skipValue();
}
}
tunnels.add(t);
sr.endObject();
}
sr.endArray();
} else {
sr.skipValue();
}
}
sr.endObject();
}
public String getName() {
return name;
}
public boolean checkSafety(IPPort lipport) {
for (Iterator iterator = services.iterator(); iterator.hasNext();) {
ServiceElement serviceElement = (ServiceElement) iterator.next();
if(lipport.equals(serviceElement.ipport)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,51 @@
package org.kne.cloud.network.klalb;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class SYNTPacket extends KLALBPacket {
private int sport,dport;
public SYNTPacket(int sport,int dport) {
super(SYNT);
this.sport=sport;
this.dport=dport;
}
public int getSport() {
return sport;
}
public int getDport() {
return dport;
}
public SYNTPacket() {
super();
}
@Override
public String toString() {
return "SYNT "+sport+"->"+dport;
}
@Override
protected void writeToStream(DataOutput dto) throws IOException {
super.writeToStream(dto);
dto.writeInt(sport);
dto.writeInt(dport);
}
@Override
public long getLength() {
return super.getLength()+8;
}
@Override
protected void readFromStream(DataInput din) throws IOException {
super.readFromStream(din);
sport=din.readInt();
dport=din.readInt();
}
}
@@ -0,0 +1,67 @@
package org.kne.cloud.network.klalb;
import java.net.Inet6Address;
import java.net.NoRouteToHostException;
import java.util.Timer;
import java.util.TimerTask;
public class SendTask extends TimerTask {
private int maxcount;
private int count;
private int priority;
private Inet6Address address;
public SendTask( KLALBController controllker,Inet6Address address,DATATPacket kp,int priority,int maxcount) {
super();
this.maxcount = maxcount;
this.controllker = controllker;
this.kp = kp;
this.address=address;
this.priority=priority;
}
public KLALBController getControllker() {
return controllker;
}
public DATATPacket getKp() {
return kp;
}
private KLALBController controllker;
private DATATPacket kp;
public int getMaxcount() {
return maxcount;
}
@Override
public void run() {
try {
controllker.sendPacketToAddress((Inet6Address) address,
kp, priority+count);
} catch (NoRouteToHostException e) {
e.printStackTrace();
}
count++;
if(count>1) {
System.out.println("重传:"+kp);
}
if(count>=maxcount) {
cancel();
}
}
public void addToTimer(int timeout) {
controllker.getTimer().scheduleAtFixedRate(this, 0, timeout);
}
}
@@ -1,36 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;
public class ServerPropties extends Properties {
public ServerPropties() throws IOException {
super();
load();
}
public void load() throws IOException {
File f=new File("kserver.ini");
if(!f.exists()||f.length()==0) {
f.createNewFile();
PrintStream ps=new PrintStream(f);
ps.println("port=4569");
ps.close();
}
FileReader fr = null;
try {
fr=new FileReader(f);
load(fr);
}finally {
if(fr!=null)
fr.close();
}
}
public int getPort() {
return Integer.parseInt( (String) get("port"));
}
}
@@ -1,77 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class TCPConnection {
protected volatile Socket connect;
protected DataInputStream din;
protected DataOutputStream dout;
public DataInputStream getDin() {
return din;
}
public DataOutputStream getDout() {
return dout;
}
public void close() {
try {
if (din != null)
din.close();
} catch (IOException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
try {
if (dout != null)
dout.close();
} catch (IOException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
try {
if (connect != null) {
connect.close();
}
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
//connect = null;
}
public TCPConnection( Socket soc) throws IOException {
connect = soc;
initIO();
}
protected void initIO() throws IOException {
dout = new DataOutputStream( connect.getOutputStream());
din = new DataInputStream( connect.getInputStream());
}
public boolean isOpen() {
if(connect==null) {
return false;
}
return !connect.isClosed();
}
}
@@ -1,78 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.function.Consumer;
import org.kne.cloud.network.mport.ThreadTool;
public class TCPListener {
private int port;
private ServerSocket servers;
private String bind;
private volatile boolean flag=false;
private Consumer<Socket>con;
private Runnable r=new Runnable() {
@Override
public void run() {
while(flag){
try {
Socket soce=servers.accept();
ThreadTool.makeVThreadIfSupport("端口监听线程",()->{
con.accept(soce);
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
public TCPListener(int port) throws IOException {
this.port=port;
}
public TCPListener(int port,String bind) throws IOException {
this.port=port;
this.bind=bind;
}
public void open() throws IOException {
flag=true;
if(bind==null) {
servers=new ServerSocket(port);
}else {
servers=new ServerSocket();
servers.bind(new InetSocketAddress(bind, port));
}
new Thread(r).start();
}
public void close() {
flag=false;
if(servers!=null) {
try {
servers.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public Consumer<Socket> getCon() {
return con;
}
public void setCon(Consumer<Socket> con) {
this.con = con;
}
}
@@ -1,7 +0,0 @@
package org.kne.cloud.network.klalb;
public interface TListener {
void setState(boolean state);
void setTraffic(long up,long down,long ups,long downs, long delay) ;
}
@@ -1,85 +0,0 @@
package org.kne.cloud.network.klalb;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import java.awt.Font;
public class TPanel extends JPanel{
private JLabel tname;
private JLabel targ;
private Tunnel tunnel;
public JLabel getTname() {
return tname;
}
public JLabel getTarg() {
return targ;
}
public TPanel (Tunnel t) {
this(t.getName());
this.tunnel=t;
}
/**
* @wbp.parser.constructor
*/
public TPanel(String name) {
setOpaque(false);
setLayout(new BorderLayout(0, 0));
tname = new JLabel(name);
tname.setFont(new Font("宋体", Font.BOLD, 20));
add(tname, BorderLayout.WEST);
targ = new JLabel();
targ.setFont(new Font("宋体", Font.PLAIN, 13));
targ.setHorizontalAlignment(SwingConstants.TRAILING);
targ.setForeground(Color.YELLOW);
add(targ, BorderLayout.CENTER);
setBorder(new LineBorder(Color.BLACK));
setSize(570, 30);
setPreferredSize(getSize());
}
private long up,down,ups,downs,delay;
public long getDelay() {
return delay;
}
private void updateText() {
String dl;
if(delay==Long.MAX_VALUE)
dl="??";
else
dl=Long.toString(delay/1000000);
targ.setText(bytesUnit(up)+"\u2191 "+bytesUnit(down)+"\u2193 "+bytesUnit(ups)+"/s\u2191 "+bytesUnit(downs)+"/s\u2193 "+dl+"ms");
}
private String bytesUnit(long v) {
if(v>=1024L*1024*1024*1024*1024) {
return String.format("%.1f", v/(1024.0*1024.0*1024.0*1024.0*1024.0))+"PB";
}else if(v>=1024L*1024*1024*1024) {
return String.format("%.1f", v/(1024.0*1024.0*1024.0*1024.0))+"TB";
}else if(v>=1024L*1024*1024) {
return String.format("%.1f", v/(1024.0*1024.0*1024.0))+"GB";
}else if(v>=1024L*1024) {
return String.format("%.1f", v/(1024.0*1024.0))+"MB";
}else if(v>=1024L) {
return String.format("%.1f", v/(1024.0))+"KB";
}else {
return v+"B";
}
}
public void setTraffic(long up2, long down2, long ups, long downs, long delay2) {
up=up2;
down=down2;
this.ups=ups;
this.downs=downs;
this.delay=delay2;
updateText();
}
}
-272
View File
@@ -1,272 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import javax.naming.spi.Resolver;
import javax.swing.JPanel;
import org.kne.cloud.network.mport.IPPort;
public class Tunnel{
private String name;
private IPPort ipport;
private String frpc;
public String getFrpc() {
return frpc;
}
private Thread hook;
public void setFrpc(String frpc) {
this.frpc = frpc;
if(frpc!=null&&hook==null) {
hook=new Thread(()->{
finalize();
});
Runtime.getRuntime().addShutdownHook(hook);
}
}
@Override
protected void finalize() {
if(hook!=null) {
try {
Runtime.getRuntime().removeShutdownHook(hook);
}catch(Exception e) {
}
if(p!=null) {
System.out.println("frpc已关闭");
p.destroy();
}
}
}
private volatile boolean state=false;
private TListener tlr;
public boolean isState() {
return state;
}
public void setState(boolean state) {
this.state = state;
if(tlr!=null) {
tlr.setState(state);
}
}
public IPPort getIpport() {
return ipport;
}
private long delay=Long.MAX_VALUE;
public TListener getTlr() {
return tlr;
}
public void setTlr(TListener tlr) {
this.tlr = tlr;
}
public long getDelay() {
return delay;
}
public void setDelay(long delay) {
this.delay = delay;
if(tlr!=null)
tlr.setTraffic(om.get(), im.get(), ups, downs,delay);
}
public Tunnel() {
}
public Tunnel(String name, IPPort ipport) {
super();
this.name = name;
this.ipport = ipport;
}
public String getName() {
return name;
}
public String getIp() {
return getIpport().getIp();
}
public int getPort() {
return getIpport().getPort();
}
@Override
public String toString() {
return getName()+"$"+getIpport()+" "+delay/1000000;
}
private volatile Process p=null;
public Socket connectClientSocket() throws UnknownHostException, IOException {
if(frpc!=null) {
File f=new File("frpc");
f.mkdirs();
File inif=new File(f,"frpc.ini");
inif.createNewFile();
PrintStream ps=new PrintStream(inif);
ps.print(frpc);
ps.close();
AtomicBoolean ab=new AtomicBoolean(false);
Object lock=new Object();
if(p==null)
new Thread(()->{
try {
p = Runtime.getRuntime().exec("./frpc/frpc_windows_amd64.exe",null,f);
BufferedReader brd=new BufferedReader(new InputStreamReader( p.getInputStream()));
while(true) {
String r=brd.readLine();
if(r==null)
break;
System.err.println(r);
if(r.contains("start visitor success")) {
synchronized (lock) {
lock.notifyAll();
}
return;
}
}
ab.set(true);
synchronized (lock) {
lock.notifyAll();
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(ab.get()) {
throw new IOException("frpc ERROR");
}
}
Socket socket=new Socket();
socket.connect(getIpport().getSocketAddress(), Consts.CONNECT_TIMEOUT);
return socket;
}
public long getUp() {
return om.get();
}
public long getDown() {
return im.get();
}
public long getUps() {
return ups;
}
public long getDowns() {
return downs;
}
@Override
public int hashCode() {
return Objects.hash(getIpport(), getName());
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Tunnel other = (Tunnel) obj;
return Objects.equals(getIpport(), other.getIpport()) && Objects.equals(getName(), other.getName());
}
private AtomicInteger ati=new AtomicInteger(0);
public AtomicInteger getCCount() {
return ati;
}
public void setName(String name) {
this.name = name;
}
public void setIpport(IPPort ipport) {
this.ipport = ipport;
}
private Vector<RemoteTCPConnection >rtcs=new Vector<>();
public Vector<RemoteTCPConnection> getRtcs() {
return rtcs;
}
AtomicLong om=new AtomicLong(0);
AtomicLong im=new AtomicLong(0);
long om1=0;
long im1=0;
private volatile long ups,downs;
public AtomicLong getOM() {
return om;
}
public AtomicLong getIM() {
return im;
}
/*PrintStream ndbg=null;
private void initcdbg() {
try {
ndbg=new PrintStream(name+".csv");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}*/
private volatile long ptime=System.nanoTime();
public void updateTraffics() {
long ctime=System.nanoTime();
long det=ctime-ptime;
ptime=ctime;
ups= (om.get()-om1)*1000000000/det;
downs= (im.get()-im1)*1000000000/det;
/*
if(ndbg==null)
initcdbg();
ndbg.println((om.get()-om1)+ (im.get()-im1)+","+delay);
*/
om1=om.get();
im1=im.get();
if(tlr!=null)
tlr.setTraffic(om.get(), im.get(), ups, downs,delay);
}
public void destroyFrpc() {
if(p!=null) {
p.destroy();
}
}
}
@@ -1,25 +0,0 @@
package org.kne.cloud.network.klalb;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Random;
public class UUID1 {
private static long get64LeastSignificantBitsForVersion1() {
Random random = new Random();
long random63BitLong = random.nextLong() & 0x3FFFFFFFFFFFFFFFL;
long variant3BitFlag = 0x8000000000000000L;
return random63BitLong + variant3BitFlag;
}
private static long get64MostSignificantBitsForVersion1() {
LocalDateTime start = LocalDateTime.of(1582, 10, 15, 0, 0, 0);
Duration duration = Duration.between(start, LocalDateTime.now());
long seconds = duration.getSeconds();
long nanos = duration.getNano();
long timeForUuidIn100Nanos = seconds * 10000000 + nanos * 100;
long least12SignificatBitOfTime = (timeForUuidIn100Nanos & 0x000000000000FFFFL) >> 4;
long version = 1 << 12;
return (timeForUuidIn100Nanos & 0xFFFFFFFFFFFF0000L) + version + least12SignificatBitOfTime;
}
}
@@ -0,0 +1,46 @@
package org.kne.cloud.network.klalb;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.net.Inet6Address;
public class VADDRPacket extends KLALBPacket {
private Inet6Address vaddr;
public Inet6Address getVaddr() {
return vaddr;
}
public VADDRPacket(Inet6Address vaddr) {
super(VADDR);
this.vaddr=vaddr;
}
public VADDRPacket() {
super();
}
@Override
public String toString() {
return "VADDR"+vaddr;
}
@Override
public long getLength() {
return super.getLength()+16;
}
@Override
protected void writeToStream(DataOutput dto) throws IOException {
super.writeToStream(dto);
dto.write(vaddr.getAddress());
}
@Override
protected void readFromStream(DataInput din) throws IOException {
super.readFromStream(din);
byte[]b=new byte[16];
din.readFully(b);
vaddr=(Inet6Address) Inet6Address.getByAddress(b);
}
}