diff --git a/.classpath b/.classpath index 7155ec1..71c7d80 100644 --- a/.classpath +++ b/.classpath @@ -1,8 +1,7 @@ - - + @@ -12,5 +11,15 @@ + + + + + + + + + + diff --git a/JavaTUN.dll b/JavaTUN.dll new file mode 100644 index 0000000..352922f Binary files /dev/null and b/JavaTUN.dll differ diff --git a/KLALB协议规范V3.0.docx b/KLALB协议规范V3.0.docx new file mode 100644 index 0000000..0d41d4f Binary files /dev/null and b/KLALB协议规范V3.0.docx differ diff --git a/klalbconfig-old.json b/klalbconfig-old.json new file mode 100644 index 0000000..99629f9 --- /dev/null +++ b/klalbconfig-old.json @@ -0,0 +1,79 @@ +[ + {"Type":"KLALBController" , + "TCPListen" : "0.0.0.0:4565", + "UDPListen" : "{UDP}0.0.0.0:4572", + "VirtualSocketName" : "KLALB_Stream", + "LineTable":["43.248.189.107:65529", +"cn-bj-bgp-3.openfrp.top:65529", +"180.76.147.250:65529", +"cn-ah-dx-1.natfrp.cloud:65529", +"cn-nn-dx-1.natfrp.cloud:65529", +"cn-wh-dx-1.natfrp.cloud:65529", +"cn-zz-bgp-10.natfrp.cloud:23330", +"cn-zz-bgp-7.natfrp.cloud:33336", +"43.143.109.64:49965", +"frp.104300.xyz:49965", +"us.afrps.cn:49966", +"hk.afrps.cn:49966", +"la.afrps.cn:49966", +"frp.freefrp.net:49965", +"frp1.freefrp.net:49965", +"frp2.freefrp.net:49965", +"frp4.freefrp.net:49965", +"cn-he-plc-2.openfrp.top:4572", +"{UDP}cn-he-plc-2.openfrp.top:4572", +"frp-mom.top:22226", +"frp-man.top:36555", +"us-sjc-bgp-2.openfrp.top:36555", +"us-sjc-bgp-1.openfrp.top:36555", +"[240e:340:d856:b700:6d02:6a6a:f9fc:865b]:4572"] + }, + {"Type":"SocketBridge" , + "Listen" : "0.0.0.0:4572", +"Bridge":{ + "KLALB" : "SocketBridge", + "RDP":"SocketBridge", + "HTTP":"SocketBridge", + "HTTPS":"SocketBridge", + "DEFAULT":"MinecraftSocketBridge23332" + } , + "Connect" : { + "KLALB" : "127.0.0.1:4565", + "RDP":"127.0.0.1:3389", + "HTTP":"127.0.0.1:5212", + "HTTPS":"192.168.1.235:443", + "DEFAULT":"127.0.0.1:36555" + } + }, + {"Type":"SocketBridge" , + "Listen" : "{KLALB_Stream}[::0]:23332", +"Bridge":"MinecraftSocketBridge23332", + "Connect" : "127.0.0.1:36555" + }, + { "Type":"SocketBridge" , + "Listen" : "{KLALB_Stream}[::0]:23333", +"Bridge":"SocketBridge", + "Connect" : "127.0.0.1:5212" + }, + + + + + + {"Type":"SocketBridge" , + "Listen" : "0.0.0.0:25561", +"Bridge":{ + "KLALB" : "SocketBridge", + "DEFAULT":"MinecraftSocketBridge23330" + } , + "Connect" : { + "KLALB" : "127.0.0.1:4565", + "DEFAULT":"127.0.0.1:25562" + } + }, + {"Type":"SocketBridge" , + "Listen" : "{KLALB_Stream}[::0]:23330", +"Bridge":"MinecraftSocketBridge23330", + "Connect" : "127.0.0.1:25562" + } +] \ No newline at end of file diff --git a/klalbconfig.json b/klalbconfig.json index 99629f9..bb1b8a5 100644 --- a/klalbconfig.json +++ b/klalbconfig.json @@ -1,32 +1,9 @@ [ - {"Type":"KLALBController" , + {"Type":"KLALBController" ,"VirtualAddress":"2486:1:34de:4abd:98c1:abd1:fc7a:401", "TCPListen" : "0.0.0.0:4565", "UDPListen" : "{UDP}0.0.0.0:4572", "VirtualSocketName" : "KLALB_Stream", - "LineTable":["43.248.189.107:65529", -"cn-bj-bgp-3.openfrp.top:65529", -"180.76.147.250:65529", -"cn-ah-dx-1.natfrp.cloud:65529", -"cn-nn-dx-1.natfrp.cloud:65529", -"cn-wh-dx-1.natfrp.cloud:65529", -"cn-zz-bgp-10.natfrp.cloud:23330", -"cn-zz-bgp-7.natfrp.cloud:33336", -"43.143.109.64:49965", -"frp.104300.xyz:49965", -"us.afrps.cn:49966", -"hk.afrps.cn:49966", -"la.afrps.cn:49966", -"frp.freefrp.net:49965", -"frp1.freefrp.net:49965", -"frp2.freefrp.net:49965", -"frp4.freefrp.net:49965", -"cn-he-plc-2.openfrp.top:4572", -"{UDP}cn-he-plc-2.openfrp.top:4572", -"frp-mom.top:22226", -"frp-man.top:36555", -"us-sjc-bgp-2.openfrp.top:36555", -"us-sjc-bgp-1.openfrp.top:36555", -"[240e:340:d856:b700:6d02:6a6a:f9fc:865b]:4572"] + "LineTable":["cn-he-plc-2.ofalias.com:4572"] }, {"Type":"SocketBridge" , "Listen" : "0.0.0.0:4572", diff --git a/lib/JavaTUN.jar b/lib/JavaTUN.jar new file mode 100644 index 0000000..e0dc66e Binary files /dev/null and b/lib/JavaTUN.jar differ diff --git a/lib/pcap4j-core-1.8.2.jar b/lib/pcap4j-core-1.8.2.jar new file mode 100644 index 0000000..9663471 Binary files /dev/null and b/lib/pcap4j-core-1.8.2.jar differ diff --git a/lib/pcap4j-distribution-1.8.2-src.zip b/lib/pcap4j-distribution-1.8.2-src.zip new file mode 100644 index 0000000..4002cc7 Binary files /dev/null and b/lib/pcap4j-distribution-1.8.2-src.zip differ diff --git a/lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar b/lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar new file mode 100644 index 0000000..7f13634 Binary files /dev/null and b/lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar differ diff --git a/lib/pcap4j-packetfactory-static-1.8.2.jar b/lib/pcap4j-packetfactory-static-1.8.2.jar new file mode 100644 index 0000000..e5cf3ab Binary files /dev/null and b/lib/pcap4j-packetfactory-static-1.8.2.jar differ diff --git a/lib/pcap4j-packettest-1.8.2-tests.jar b/lib/pcap4j-packettest-1.8.2-tests.jar new file mode 100644 index 0000000..ea12ea3 Binary files /dev/null and b/lib/pcap4j-packettest-1.8.2-tests.jar differ diff --git a/lib/pcap4j-sample-1.8.2.jar b/lib/pcap4j-sample-1.8.2.jar new file mode 100644 index 0000000..efc5b8a Binary files /dev/null and b/lib/pcap4j-sample-1.8.2.jar differ diff --git a/lib/slf4j-api-2.0.9-javadoc.jar b/lib/slf4j-api-2.0.9-javadoc.jar new file mode 100644 index 0000000..17f14f3 Binary files /dev/null and b/lib/slf4j-api-2.0.9-javadoc.jar differ diff --git a/lib/slf4j-api-2.0.9-sources.jar b/lib/slf4j-api-2.0.9-sources.jar new file mode 100644 index 0000000..9a2a2dc Binary files /dev/null and b/lib/slf4j-api-2.0.9-sources.jar differ diff --git a/lib/slf4j-api-2.0.9-tests.jar b/lib/slf4j-api-2.0.9-tests.jar new file mode 100644 index 0000000..2452fa4 Binary files /dev/null and b/lib/slf4j-api-2.0.9-tests.jar differ diff --git a/lib/slf4j-api-2.0.9.jar b/lib/slf4j-api-2.0.9.jar new file mode 100644 index 0000000..3796afe Binary files /dev/null and b/lib/slf4j-api-2.0.9.jar differ diff --git a/src/assets/KNEL.png b/src/assets/KLALB.png similarity index 100% rename from src/assets/KNEL.png rename to src/assets/KLALB.png diff --git a/src/org/kne/cloud/clock/AdjustedNanoClock.java b/src/org/kne/cloud/clock/AdjustedNanoClock.java index ff38f9a..4a2fa50 100644 --- a/src/org/kne/cloud/clock/AdjustedNanoClock.java +++ b/src/org/kne/cloud/clock/AdjustedNanoClock.java @@ -55,7 +55,7 @@ private ReentrantLock lock=new ReentrantLock(); //System.out.println(delta+" "+currentTime+" "+taccurace); }else { accuracy=(accuracy*9999+taccurace)/10000; - } + } } public void calibrate2(long delta,long taccurace) { if(accuracy==Long.MAX_VALUE||taccurace<= accuracy) { @@ -71,4 +71,5 @@ private ReentrantLock lock=new ReentrantLock(); accuracy=(accuracy*9999+taccurace)/10000; } } + } diff --git a/src/org/kne/cloud/network/StreamChannelBridge.java b/src/org/kne/cloud/network/ChannelBridge.java similarity index 88% rename from src/org/kne/cloud/network/StreamChannelBridge.java rename to src/org/kne/cloud/network/ChannelBridge.java index 05f27f3..77734a6 100644 --- a/src/org/kne/cloud/network/StreamChannelBridge.java +++ b/src/org/kne/cloud/network/ChannelBridge.java @@ -9,12 +9,12 @@ import java.util.UUID; import org.kne.io.Task; -public class StreamChannelBridge extends Task{ +public class ChannelBridge extends Task{ protected ReadableByteChannel in; protected WritableByteChannel out; protected int blocksize=65535; protected long delay=0; - public StreamChannelBridge(ReadableByteChannel in, WritableByteChannel out) { + public ChannelBridge(ReadableByteChannel in, WritableByteChannel out) { super(); Objects.requireNonNull(in); Objects.requireNonNull(out); diff --git a/src/org/kne/cloud/network/DefaultMinecraftSocketBridgeFactory.java b/src/org/kne/cloud/network/DefaultMinecraftSocketBridgeFactory.java index 0d5fdc3..e8781d4 100644 --- a/src/org/kne/cloud/network/DefaultMinecraftSocketBridgeFactory.java +++ b/src/org/kne/cloud/network/DefaultMinecraftSocketBridgeFactory.java @@ -25,14 +25,14 @@ public class DefaultMinecraftSocketBridgeFactory extends SocketBridgeFactory { @Override public SocketBridge createBridge(Socket a, Socket b) throws IOException { - if(a instanceof KLALBVirtualSocket) { + /*if(a instanceof KLALBVirtualSocket) { KLALBVirtualSocket klv=(KLALBVirtualSocket) a; klv.setCompress(1); } if(b instanceof KLALBVirtualSocket) { KLALBVirtualSocket klv=(KLALBVirtualSocket) b; klv.setCompress(1); - } + }*/ MinecraftSocketBridge msb=new MinecraftSocketBridge(a, b); msb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return vaddr;},()->{return vport;})); return msb; diff --git a/src/org/kne/cloud/network/IPMulticastDiscovery.java b/src/org/kne/cloud/network/IPMulticastDiscovery.java new file mode 100644 index 0000000..5f4a807 --- /dev/null +++ b/src/org/kne/cloud/network/IPMulticastDiscovery.java @@ -0,0 +1,172 @@ +package org.kne.cloud.network; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.MulticastSocket; +import java.net.NetworkInterface; +import java.net.NoRouteToHostException; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +public class IPMulticastDiscovery extends Thread implements Closeable, AutoCloseable { + private MulticastSocket soc; + private NetworkInterface ninterface; + private volatile boolean closed = false; + private InetSocketAddress group; + private InetSocketAddress bind; + private int type; + private List msas; + + private volatile Consumer con; + + public NetworkInterface getNinterface() { + return ninterface; + } + + public InetSocketAddress getGroup() { + return group; + } + + public InetSocketAddress getBind() { + return bind; + } + + public Consumer getCon() { + return con; + } + + public void setCon(Consumer con) { + this.con = con; + } + + public IPMulticastDiscovery(InetSocketAddress bind, InetSocketAddress group, NetworkInterface ninterface, + List msas) throws IOException { + soc = new MulticastSocket(bind); + soc.joinGroup(group, ninterface); + this.bind = bind; + this.group = group; + this.ninterface = ninterface; + this.msas = msas; + } + + @Override + public void run() { + Thread.currentThread().setName("线路发现线程"); + + ThreadTool.makeVDaemonThreadIfSupport("线路通知线程", () -> { + try { + while (!closed) { + HashSet s = new HashSet(); + for (Iterator iterator = msas.iterator(); iterator.hasNext();) { + MultipurposeSocketAddress multipurposeSocketAddress = (MultipurposeSocketAddress) iterator + .next(); + + MultipurposeSocketAddress mpsa = new MultipurposeSocketAddress( + multipurposeSocketAddress.getType(), "::0", multipurposeSocketAddress.getPort()); + try { + if (s.add(mpsa)) { + boolean bf = true; + Enumeration ei = ninterface.getInetAddresses(); + while (ei.hasMoreElements()) { + InetAddress inetAddress = (InetAddress) ei.nextElement(); + if (inetAddress.equals(multipurposeSocketAddress.getInetAddress())) { + bf = false; + break; + } + } + if (bf) { + continue; + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dops = new DataOutputStream(baos); + dops.writeInt(multipurposeSocketAddress.getPort()); + dops.writeUTF(multipurposeSocketAddress.getType()); + dops.close(); + byte[] b = baos.toByteArray(); + DatagramPacket dp = new DatagramPacket(b, b.length, group); + soc.send(dp); + } + } catch (NoRouteToHostException|UnknownHostException e) { + } + + } + + Thread.sleep(10000L); + } + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } finally { + try { + close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + }).start(); + + try { + loop:while (!closed) { + byte[] b = new byte[65535]; + DatagramPacket dp = new DatagramPacket(b, b.length); + soc.receive(dp); + ByteArrayInputStream bis = new ByteArrayInputStream(b, 0, dp.getLength()); + DataInputStream dis = new DataInputStream(bis); + int port = dis.readInt(); + String type = dis.readUTF(); + dis.close(); + MultipurposeSocketAddress mpsa = new MultipurposeSocketAddress(type, dp.getAddress().getHostAddress(), + port); + //System.out.println(mpsa); + Enumeration ei = ninterface.getInetAddresses(); + while (ei.hasMoreElements()) { + InetAddress inetAddress = (InetAddress) ei.nextElement(); + if (inetAddress.equals(mpsa.getInetAddress())) { + continue loop; + } + } + + if (con != null) { + con.accept(mpsa); + } + + } + } catch (IOException e) { + System.out.println(bind + " " + group + " " + ninterface); + e.printStackTrace(); + } finally { + try { + close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @Override + public void close() throws IOException { + soc.close(); + closed = true; + } + + public boolean isClosed() { + return closed; + } + +} diff --git a/src/org/kne/cloud/network/MultipurposeSocketAddress.java b/src/org/kne/cloud/network/MultipurposeSocketAddress.java index f5018a5..1b039fd 100644 --- a/src/org/kne/cloud/network/MultipurposeSocketAddress.java +++ b/src/org/kne/cloud/network/MultipurposeSocketAddress.java @@ -68,7 +68,9 @@ public class MultipurposeSocketAddress implements Serializable{ tps=tps.substring(0, v); } port=Integer.parseInt(tps); - + if(port<0) { + throw new IllegalArgumentException("port < 0"); + } } @Override public int hashCode() { diff --git a/src/org/kne/cloud/network/NetworkPacket.java b/src/org/kne/cloud/network/NetworkPacket.java new file mode 100644 index 0000000..00f55d4 --- /dev/null +++ b/src/org/kne/cloud/network/NetworkPacket.java @@ -0,0 +1,140 @@ +package org.kne.cloud.network; + +import java.io.IOException; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.kne.cloud.network.klalb.ByteArrayPool; +import org.kne.cloud.network.klalb.ByteBufferPool; +import org.kne.cloud.network.klalb.KLALBPacket; +import org.kne.debug.TimeDebugger; + +public abstract class NetworkPacket implements Comparable{ + private static final boolean debugPassport=false; + + + + public static final ByteArrayPool dataarraypool_65535=new ByteArrayPool(10000, 65535); + + public static final ByteBufferPool databufferpool_65535=new ByteBufferPool(10000, 65535,false); + + public static final ByteBufferPool databufferpool_2048=new ByteBufferPool(10000, 2048,false); + + public static final ByteBufferPool databufferpool_40=new ByteBufferPool(10000, 40,false); + + + + private TimeDebugger passport; + { + if(debugPassport) { + passport=new TimeDebugger(); + passport.putTime(getClass().getSimpleName()+ "_create"); + } + } + + public void putTimePassport(String label) { + if(passport!=null) { + passport.putTime(label); + } + } + + public void printPassport() { + if(passport!=null) { + passport.printWithTimeFilter(100000000L); + } + + } + + private volatile boolean disposeAfterSend=false; + + public boolean isDisposeAfterSend() { + return disposeAfterSend; + } + public void setDisposeAfterSend(boolean disposeAfterSend) { + this.disposeAfterSend = disposeAfterSend; + } + private volatile boolean disposed=false; + private Lock disposeLock=new ReentrantLock(); + public boolean isDisposed() { + return disposed; + } + public Lock getDisposeLock() { + return disposeLock; + } + public abstract long getLength(); + public void dispose() { + /*disposeLock.lock(); + try {*/ + disposed=true; + /*}finally { + disposeLock.unlock(); + }*/ + } + + public void lockAll() { + disposeLock.lock(); + } + + public boolean isSomeDisposed() { + return disposed; + } + + public void unlockAll() { + disposeLock.unlock(); + } + + + public long getPriority() { + return priority; + } + public void setPriority(long priority) { + this.priority = priority; + } + public long getSendseq() { + return sendseq; + } + + private long priority; + private long sendseq; + private static final AtomicLong seqgen=new AtomicLong(); + + @Override + public int compareTo(NetworkPacket o) { + if(priority>o.priority) { + return 1; + }else if(priorityo.sendseq) { + return 1; + }else if(sendseq"+dport; + } + public PortPair(int sport, int dport) { + super(); + this.sport = sport; + this.dport = dport; + } + public int getSport() { + return sport; + } + public int getDport() { + return dport; + } + @Override + public int hashCode() { + return Objects.hash(dport, sport); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PortPair other = (PortPair) obj; + return dport == other.dport && sport == other.sport; + } + + +} diff --git a/src/org/kne/cloud/network/SocketBridge.java b/src/org/kne/cloud/network/SocketBridge.java index 52d8ee9..cfd49e4 100644 --- a/src/org/kne/cloud/network/SocketBridge.java +++ b/src/org/kne/cloud/network/SocketBridge.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.*; +import org.kne.cloud.network.klalb.CannotAssociateException; import org.kne.cloud.network.klalb.KLALBVirtualSocket; import org.kne.io.Task; public class SocketBridge extends Task{ @@ -31,9 +32,24 @@ public class SocketBridge extends Task{ protected void runTask() { try { if(a instanceof KLALBVirtualSocket) { + try { ((KLALBVirtualSocket) a).associateSocket(b); + }catch(CannotAssociateException e) { + bridgeAB.runAtNewThread("SocketBridge A->B thread"); + bridgeBA.runAtNewThread("SocketBridge B->A thread"); + bridgeAB.waitfortask(); + bridgeBA.waitfortask(); + } }else if(b instanceof KLALBVirtualSocket){ + try { ((KLALBVirtualSocket) b).associateSocket(a); + }catch(CannotAssociateException e) { + bridgeAB.runAtNewThread("SocketBridge A->B thread"); + bridgeBA.runAtNewThread("SocketBridge B->A thread"); + bridgeAB.waitfortask(); + bridgeBA.waitfortask(); + + } }else { bridgeAB.runAtNewThread("SocketBridge A->B thread"); bridgeBA.runAtNewThread("SocketBridge B->A thread"); diff --git a/src/org/kne/cloud/network/SocketChannelBridge.java b/src/org/kne/cloud/network/SocketChannelBridge.java index 5a35223..6bdcf85 100644 --- a/src/org/kne/cloud/network/SocketChannelBridge.java +++ b/src/org/kne/cloud/network/SocketChannelBridge.java @@ -5,18 +5,19 @@ import java.io.OutputStream; import java.net.*; import java.nio.channels.SocketChannel; +import org.kne.cloud.network.klalb.CannotAssociateException; import org.kne.cloud.network.klalb.KLALBVirtualSocket; import org.kne.cloud.network.klalb.KLALBVirtualSocketChannel; import org.kne.io.Task; public class SocketChannelBridge extends Task{ protected SocketChannel a; protected SocketChannel b; - protected StreamChannelBridge bridgeAB; - protected StreamChannelBridge bridgeBA; - public StreamChannelBridge getBridgeAB() { + protected ChannelBridge bridgeAB; + protected ChannelBridge bridgeBA; + public ChannelBridge getBridgeAB() { return bridgeAB; } - public StreamChannelBridge getBridgeBA() { + public ChannelBridge getBridgeBA() { return bridgeBA; } public SocketChannelBridge(SocketChannel a, SocketChannel b) throws IOException { @@ -26,16 +27,32 @@ public class SocketChannelBridge extends Task{ createStreamChannelBridge(); } protected void createStreamChannelBridge() throws IOException { - bridgeAB = new StreamChannelBridge(a, b); - bridgeBA = new StreamChannelBridge(b, a); + bridgeAB = new ChannelBridge(a, b); + bridgeBA = new ChannelBridge(b, a); } @Override protected void runTask() { try { if(a instanceof KLALBVirtualSocketChannel) { + try { ((KLALBVirtualSocketChannel) a).associateSocketChannel(b); + }catch(CannotAssociateException e) { + bridgeAB.runAtNewThread("SocketBridge A->B thread"); + bridgeBA.runAtNewThread("SocketBridge B->A thread"); + bridgeAB.waitfortask(); + bridgeBA.waitfortask(); + + } }else if(b instanceof KLALBVirtualSocketChannel){ + try { ((KLALBVirtualSocketChannel) b).associateSocketChannel(a); +}catch(CannotAssociateException e) { + bridgeAB.runAtNewThread("SocketBridge A->B thread"); + bridgeBA.runAtNewThread("SocketBridge B->A thread"); + bridgeAB.waitfortask(); + bridgeBA.waitfortask(); + + } }else { bridgeAB.runAtNewThread("SocketBridge A->B thread"); bridgeBA.runAtNewThread("SocketBridge B->A thread"); @@ -49,12 +66,14 @@ public class SocketChannelBridge extends Task{ //new Exception().printStackTrace(); try { a.close(); + //System.out.println("closeA"); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } try { b.close(); + //System.out.println("closeB"); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); diff --git a/src/org/kne/cloud/network/SocketToSocketProxy.java b/src/org/kne/cloud/network/SocketToSocketProxy.java index 1aac538..53c8367 100644 --- a/src/org/kne/cloud/network/SocketToSocketProxy.java +++ b/src/org/kne/cloud/network/SocketToSocketProxy.java @@ -4,6 +4,9 @@ import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketOption; +import java.net.SocketOptions; +import java.net.StandardSocketOptions; import java.net.UnknownHostException; import java.nio.channels.SocketChannel; import java.util.Map; @@ -148,11 +151,16 @@ public class SocketToSocketProxy extends Proxy { } protected void runBridge(SocketBridgeFactory sbf,Socket sk, Socket sox) throws IOException { + + sk.setTcpNoDelay(true); + sox.setTcpNoDelay(true); SocketBridge sb = sbf.createBridge(sk, sox); sb.run(); } protected void runChannelBridge(SocketChannelBridgeFactory sbf,SocketChannel sk, SocketChannel sox) throws IOException { + sk.setOption(StandardSocketOptions.TCP_NODELAY, true); + sox.setOption(StandardSocketOptions.TCP_NODELAY, true); SocketChannelBridge sb = sbf.createBridge(sk, sox); sb.run(); } diff --git a/src/org/kne/cloud/network/SpeedLimiter.java b/src/org/kne/cloud/network/SpeedLimiter.java index 01b2dc2..3e7b4de 100644 --- a/src/org/kne/cloud/network/SpeedLimiter.java +++ b/src/org/kne/cloud/network/SpeedLimiter.java @@ -1,21 +1,17 @@ package org.kne.cloud.network; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.LockSupport; +import java.util.function.LongUnaryOperator; +import java.util.function.UnaryOperator; public class SpeedLimiter { + public boolean isHitlimit() { return hitlimit; } - public SpeedLimiter(long limitspeed, long timedeltans) { - super(); - this.limitspeed = limitspeed; - this.timedeltans = timedeltans; - } - public SpeedLimiter() { - super(); - } private volatile long limitspeed=1024*1024; - private volatile long timedeltans=5000000; + private long brustTime=1000000L; private volatile boolean hitlimit=false; public long getLimitspeed() { return limitspeed; @@ -25,56 +21,76 @@ public class SpeedLimiter { super(); this.limitspeed = limitspeed; } + public SpeedLimiter(long limitspeed, long brustTime) { + super(); + this.limitspeed = limitspeed; + this.brustTime = brustTime; + } + public void setLimitspeed(long limitspeed) { this.limitspeed = limitspeed; //System.out.println("更新限速:"+limitspeed); } - public long getTimedeltans() { - return timedeltans; + public long getBrustTime() { + return brustTime; } - public void setTimedeltans(long timedeltans) { - this.timedeltans = timedeltans; + public void setBrustTime(long brustTime) { + this.brustTime = brustTime; } - private long ltime=System.nanoTime(); - private long counter=0; + private AtomicLong ltime=new AtomicLong( System.nanoTime()); + private AtomicLong waitingtime=new AtomicLong(); @Override public String toString() { return "SpeedLimiter [limitspeed=" + limitspeed + "]"; } + public void forceTransmit(long datasize) { + long limitspeedx=limitspeed; + if(limitspeedx>0) { + long curtime=System.nanoTime(); + long pasttime=ltime.getAndSet(curtime); + long nv=waitingtime.updateAndGet(new LongUnaryOperator() { + @Override + public long applyAsLong(long t) { + t-=curtime-pasttime; + if(t<0L) + t=0L; + return t; + } + + }); + waitingtime.addAndGet(datasize*1000000000L/limitspeedx); + } +} public boolean checkTransmit(long datasize) { - long curtime=System.nanoTime(); - if(curtime-ltime>timedeltans) { - ltime=curtime; - if((counter*1000000000)/timedeltans<=limitspeed) { - hitlimit=false; - } - counter=0; - } - if((counter*1000000000)/timedeltans<=limitspeed) { - counter+=datasize; - return true; - } - hitlimit=true; + long limitspeedx=limitspeed; + if(limitspeedx<=0) { return false; + } + + long curtime=System.nanoTime(); + long pasttime=ltime.getAndSet(curtime); + long nv=waitingtime.updateAndGet(new LongUnaryOperator() { + @Override + public long applyAsLong(long t) { + t-=curtime-pasttime; + if(t<0L) + t=0L; + return t; + } + + }); + if(nv<=brustTime) { + waitingtime.addAndGet(datasize*1000000000L/limitspeedx); + //System.out.println(limitspeed); + return true; + }else { + return false; + } } public void transmit(long datasize) { - while(true) { - long curtime=System.nanoTime(); - if(curtime-ltime>timedeltans) { - ltime=curtime; - if((counter*1000000000)/timedeltans<=limitspeed) { - hitlimit=false; - } - counter=0; - } - if((counter*1000000000)/timedeltans<=limitspeed) { - counter+=datasize; - return; - } - hitlimit=true; - //System.out.println("hit limit"); + while(!checkTransmit(datasize)) { LockSupport.parkNanos(100000); } } diff --git a/src/org/kne/cloud/network/StreamBridge.java b/src/org/kne/cloud/network/StreamBridge.java index a2da102..298227c 100644 --- a/src/org/kne/cloud/network/StreamBridge.java +++ b/src/org/kne/cloud/network/StreamBridge.java @@ -7,6 +7,8 @@ import java.util.UUID; import org.kne.io.Task; public class StreamBridge extends Task{ + private static final boolean debug =false; + protected InputStream in; protected OutputStream out; protected int blocksize=65535; @@ -41,6 +43,7 @@ public class StreamBridge extends Task{ } } } catch (IOException e) { + if(debug) e.printStackTrace(); }finally { /*if(fos!=null) diff --git a/src/org/kne/cloud/network/ThreadTool.java b/src/org/kne/cloud/network/ThreadTool.java index 62238e1..f32949e 100644 --- a/src/org/kne/cloud/network/ThreadTool.java +++ b/src/org/kne/cloud/network/ThreadTool.java @@ -4,7 +4,7 @@ import java.lang.reflect.Method; public class ThreadTool { public static boolean first=true; - public static boolean forceD=false; + public static boolean forceD=true; public static Thread makeVThreadIfSupport(String name,Runnable r) { if(forceD) return new Thread(r, name); diff --git a/src/org/kne/cloud/network/TimeoutTimer.java b/src/org/kne/cloud/network/TimeoutTimer.java index cd10c83..ddcd65a 100644 --- a/src/org/kne/cloud/network/TimeoutTimer.java +++ b/src/org/kne/cloud/network/TimeoutTimer.java @@ -19,6 +19,7 @@ public class TimeoutTimer extends Timer { public void run() { try { res.close(); + System.out.println("timeout"); } catch (IOException e) { } } @@ -26,6 +27,7 @@ public class TimeoutTimer extends Timer { }else { tt=null; } + if(tt!=null) schedule(tt, timeout); return tt; } diff --git a/src/org/kne/cloud/network/frpc/FrpcProcess.java b/src/org/kne/cloud/network/frpc/FrpcProcess.java index 2f9afac..e3677ed 100644 --- a/src/org/kne/cloud/network/frpc/FrpcProcess.java +++ b/src/org/kne/cloud/network/frpc/FrpcProcess.java @@ -54,7 +54,8 @@ public class FrpcProcess extends Process{ } AtomicReferencearex=new AtomicReference(); synchronized (getClass()) { - config_file = new File(base,"frpc_conf_"+UUID.randomUUID()+".ini"); + UUID uid=UUID.randomUUID(); + config_file = new File(base,"frpc_conf_"+uid+".ini"); config_file.createNewFile(); config_file.deleteOnExit(); PrintWriter ps=null; @@ -95,12 +96,15 @@ public class FrpcProcess extends Process{ break; } cdl.countDown(); - System.out.println (s); + System.out.println ("{"+uid+"}"+s); if(s.contains("start proxy success")) { t.interrupt(); }else if(s.contains("port already used")){ arex.set(new BindException("port on server already used")); t.interrupt(); + }else if(s.contains("远程端口已经在使用了")) { + arex.set(new BindException("port on server already used")); + t.interrupt(); }else if(s.contains("no such host")) { arex.set(new UnknownHostException("no such host")); t.interrupt(); diff --git a/src/org/kne/cloud/network/ipv6/FlowSession.java b/src/org/kne/cloud/network/ipv6/FlowSession.java new file mode 100644 index 0000000..9c11765 --- /dev/null +++ b/src/org/kne/cloud/network/ipv6/FlowSession.java @@ -0,0 +1,49 @@ +package org.kne.cloud.network.ipv6; + +import java.io.Serializable; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.util.Objects; + +public class FlowSession implements Serializable{ + private Inet6Address srcAddr; + private Inet6Address dstAddr; + private int flowLabel; + public FlowSession(Inet6Address srcAddr, Inet6Address dstAddr, int flowLabel) { + super(); + this.srcAddr = srcAddr; + this.dstAddr = dstAddr; + this.flowLabel = flowLabel; + } + public Inet6Address getSrcAddr() { + return srcAddr; + } + public Inet6Address getDstAddr() { + return dstAddr; + } + public int getFlowLabel() { + return flowLabel; + } + @Override + public String toString() { + return "FlowSession [srcAddr=" + srcAddr + ", dstAddr=" + dstAddr + ", flowLabel=" + flowLabel + "]"; + } + @Override + public int hashCode() { + return Objects.hash(dstAddr, flowLabel, srcAddr); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + FlowSession other = (FlowSession) obj; + return Objects.equals(dstAddr, other.dstAddr) && flowLabel == other.flowLabel + && Objects.equals(srcAddr, other.srcAddr); + } + +} + diff --git a/src/org/kne/cloud/network/ipv6/IPv6NetworkLink.java b/src/org/kne/cloud/network/ipv6/IPv6NetworkLink.java new file mode 100644 index 0000000..b26423c --- /dev/null +++ b/src/org/kne/cloud/network/ipv6/IPv6NetworkLink.java @@ -0,0 +1,23 @@ +package org.kne.cloud.network.ipv6; + +import java.io.IOException; +import java.net.Inet6Address; +import java.util.*; +import java.util.function.Consumer; + +import org.kne.cloud.network.ipv6.IPv6Packet; +import org.kne.cloud.network.klalb.KLALBPacket; +import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; + +public interface IPv6NetworkLink { + public boolean isLoopBack(); + public Inet6AddressGroup getAddressGroup(); + public List getNeighborsInfo(); + public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException; + public boolean isCongress(IPv6Packet iPv6Packet); + public String getName(); + public boolean isUp(); + public boolean canSend(IPv6Packet iPv6Packet); + public void setReceiveConsumer(Consumercon); +} diff --git a/src/org/kne/cloud/network/ipv6/IPv6Packet.java b/src/org/kne/cloud/network/ipv6/IPv6Packet.java new file mode 100644 index 0000000..65ef23f --- /dev/null +++ b/src/org/kne/cloud/network/ipv6/IPv6Packet.java @@ -0,0 +1,840 @@ +package org.kne.cloud.network.ipv6; + +import java.io.EOFException; +import java.io.IOException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.kne.cloud.network.NetworkPacket; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader; +import org.kne.cloud.network.klalb.KLALBPacket; +import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV; +import org.kne.cloud.network.srv6.IpV6RoutingSRHData; +import org.kne.cloud.network.srv6.SRv6Pad1TLV; +import org.kne.cloud.network.srv6.SRv6PadNTLV; +import org.kne.cloud.network.srv6.SRv6StreamSequenceTLV; +import org.kne.cloud.network.srv6.SRv6TLV; +import org.pcap4j.packet.namednumber.IpNumber; + +public class IPv6Packet extends NetworkPacket { + private volatile ByteBuffer IPv6header ; + + private volatile List headers = new ArrayList<>(); + + private IPv6Payload payload; + + public static final int IPv6_HEADER_LENGTH = 40; + + public IPv6Payload getPayload() { + return payload; + } + + public void setPayload(IPv6Payload payload) { + this.payload = payload; + } + + public IPv6Packet() { + IPv6header = NetworkPacket.databufferpool_40.borrow(); + IPv6header.limit(IPv6_HEADER_LENGTH); + } + + public static int getIPVersion(byte b) { + return b>>>4; + } + + public int getVersion() { + return IPv6header.get(0) >>> 4; + } + + public void setVersion(int version) { + IPv6header.put(0, (byte) (IPv6header.get(0) & 0b00001111 | version << 4)); + } + + public int getTrafficClass() { + return (IPv6header.get(0) << 4) & (IPv6header.get(1) >>> 4) & 0xff; + } + + public void setTrafficClass(int trafficClass) { + IPv6header.put(0, (byte) (IPv6header.get(0) & 0b11110000 | (trafficClass >>> 4))); + IPv6header.put(1, (byte) (IPv6header.get(1) & 0b00001111 | ((trafficClass & 0b00001111) << 4))); + } + + public boolean isEnableECN() { + return (IPv6header.get(1)&0b00110000)!=0; + } + + public void enableECN() { + IPv6header.put(1, (byte) ((IPv6header.get(1)&0b11101111)|0b00100000)); + } + + public void markCE() { + IPv6header.put(1,(byte) (IPv6header.get(1)|0b00110000)); + } + + public boolean isCE() { + return ((IPv6header.get(1)>>>4)&0b11)==0b11; + } + + public int getFlowLabel() { + return ((IPv6header.get(1) & 0b00001111) << 16) | (IPv6header.getShort(2) & 0xffff); + } + + public void setFlowLabel(int flowLabel) { + IPv6header.put(1, (byte) (IPv6header.get(1) & 0b11110000 | (flowLabel >>> 16))); + IPv6header.putShort(2, (short) flowLabel); + } + + public int getPayloadLength() { + return IPv6header.getShort(4) & 0xffff; + } + + public void setPayloadLength(int payloadLength) { + IPv6header.putShort(4, (short) payloadLength); + } + + public int getNextHeader() { + return IPv6header.get(6) & 0xff; + } + + public void setNextHeader(int nextHeader) { + IPv6header.put(6, (byte) nextHeader); + } + + public int getHopLimit() { + return IPv6header.get(7) & 0xff; + } + + public void setHopLimit(int hopLimit) { + IPv6header.put(7, (byte) hopLimit); + } + + public Inet6Address getSourceAddress() { + byte[] b = new byte[16]; + IPv6header.get(8, b, 0, b.length); + try { + return (Inet6Address) Inet6Address.getByAddress(b); + } catch (UnknownHostException e) { + return null; + } + } + + public void setSourceAddress(Inet6Address sourceAddress) { + byte[] b = sourceAddress.getAddress(); + IPv6header.put(8, b, 0, b.length); + } + + public Inet6Address getDestinationAddress() { + byte[] b = new byte[16]; + IPv6header.get(24, b, 0, b.length); + try { + return (Inet6Address) Inet6Address.getByAddress(b); + } catch (UnknownHostException e) { + return null; + } + } + + public void setDestinationAddress(Inet6Address destinationAddress) { + byte[] b = destinationAddress.getAddress(); + IPv6header.put(24, b, 0, b.length); + } + + public FlowSession getFlowSession() { + return new FlowSession(getSourceAddress(), getDestinationAddress(), getFlowLabel()); + } + + private int calcPayloadLength() { + int lth=0; + for (int i = 0; i < headers.size(); i++) { + lth+= headers.get(i).getLength(); + } + lth+=payload.getLength(); + return lth; + } + + @Override + public long getLength() { + return calcPayloadLength()+IPv6_HEADER_LENGTH; + } + + @Override + public void doDisposeAfterSend() { + super.doDisposeAfterSend(); + payload.doDisposeAfterSend(); + } + + @Override + public void dispose() { + super.dispose(); + /*ByteBuffer headerx = IPv6header; + IPv6header = null; + if(headerx!=null) + NetworkPacket.databufferpool_40.back(headerx);*/ + } + + @Override + public void disposeAll() { + super.disposeAll(); + for (int i = 0; i < headers.size(); i++) { + headers.get(i).disposeAll(); + } + payload.disposeAll(); + } + + + @Override + public void writeToChannel(WritableByteChannel dto) throws IOException { + if(headers.isEmpty()) { + setNextHeader(payload.getProtocolNumber()); + }else { + setNextHeader(headers.get(0).getProtocolNumber()); + } + setPayloadLength(calcPayloadLength()); + dto.write(IPv6header.slice(0, IPv6header.limit())); + for (int i = 0; i < headers.size(); i++) { + IPv6ExtHeader exth=headers.get(i); + if(i+1 iterator = headers.iterator(); iterator.hasNext();) { + IPv6ExtHeader iPv6ExtHeader = (IPv6ExtHeader) iterator.next(); + if(iPv6ExtHeader.isSomeDisposed()) + return true; + } + return false; + } + + @Override + public void unlockAll() { + payload.unlockAll(); + for (int i = 0; i < headers.size(); i++) { + headers.get(i).unlockAll(); + } + super.unlockAll(); + } + + @Override + public String toString() { + return "IPv6Packet [getVersion()=" + getVersion() + ", getTrafficClass()=" + getTrafficClass() + + ", getFlowLabel()=" + getFlowLabel() + ", getPayloadLength()=" + getPayloadLength() + + ", getNextHeader()=" + getNextHeader() + ", getHopLimit()=" + getHopLimit() + ", getSourceAddress()=" + + getSourceAddress() + ", getDestinationAddress()=" + getDestinationAddress() + ", getLength()=" + + getLength() + ", headers=" + headers + ", payload=" + payload + "]"; + } + + public static class IPv6Payload extends NetworkPacket{ + private ByteBuffer data ; + + private boolean onDefault=true; + + public ByteBuffer getData() { + return data; + } + + private int protocolNumber; + + public IPv6Payload(int protocolNumber) { + this(protocolNumber,true); + } + + protected IPv6Payload(int protocolNumber,boolean isonDefault) { + this.protocolNumber = protocolNumber; + this.onDefault=isonDefault; + if(onDefault) + this.data=NetworkPacket.databufferpool_65535.borrow(); + } + + public int getProtocolNumber() { + return protocolNumber; + } + + public long getLength() { + return data.limit(); + } + + @Override + protected void writeToChannel(WritableByteChannel dto) throws IOException { + if(onDefault) + dto.write(data.slice(0,data.limit())); + } + + @Override + protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { + if(onDefault) { + data.limit((int) length); + while (data.hasRemaining()) { + if (din.read(data) == -1) { + throw new EOFException(); + } + } + } + } + + @Override + public void dispose() { + super.dispose(); + /*if(onDefault) { + ByteBuffer datax = data; + data = null; + NetworkPacket.databufferpool_65535.back(datax); + }*/ + } + + @Override + protected boolean needEndPosition() { + return true; + } + + } + + public static class IPv6ExtHeader extends NetworkPacket{ + private ByteBuffer data ; + + private int protocolNumber; + + private boolean onDefault=true; + + @Override + public String toString() { + return "IPv6ExtHeader [protocolNumber=" + protocolNumber + ", getNextHeader()=" + getNextHeader() + + ", getExtLength()=" + getExtLength() + "]"; + } + + public ByteBuffer getData() { + return data; + } + + public IPv6ExtHeader(int type) { + this(type,true); + } + + protected IPv6ExtHeader(int protocolNumber,boolean isonDefault) { + this.protocolNumber = protocolNumber; + this.onDefault=isonDefault; + if(onDefault) { + this.data=NetworkPacket.databufferpool_2048.borrow(); + }else { + this.data=NetworkPacket.databufferpool_40.borrow(); + } + } + + protected IPv6ExtHeader(int protocolNumber,boolean isonDefault,ByteBuffer data) { + this.protocolNumber = protocolNumber; + this.onDefault=isonDefault; + this.data=data; + } + + public int getProtocolNumber() { + return protocolNumber; + } + + public int getNextHeader() { + return data.get(0) & 0xff; + } + + public void setNextHeader(int nextHeader) { + data.put(0, (byte) nextHeader); + } + + public int getExtLength() { + return data.get(1) & 0xff; + } + + protected void setExtLength(int extLength) { + data.put(1, (byte) extLength); + } + + public long getLength() { + return data.limit(); + } + + @Override + protected void writeToChannel(WritableByteChannel dto) throws IOException { + if(onDefault) { + int ext=(data.limit()-8)/8; + setExtLength(ext); + dto.write(data.slice(0,data.limit())); + }else { + dto.write(data.slice(0,8)); + } + } + + @Override + protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { + data.limit(8); + while (data.hasRemaining()) { + if (din.read(data) == -1) { + throw new EOFException(); + } + } + if(onDefault) { + int newLimit=getExtLength()*8+data.limit(); + data.limit(newLimit); + while (data.hasRemaining()) { + if (din.read(data) == -1) { + throw new EOFException(); + } + } + } + } + + @Override + protected boolean needEndPosition() { + return false; + } + + @Override + public void dispose() { + super.dispose(); + /*ByteBuffer bbft=data; + data=null; + if(bbft!=null) { + if(bbft.capacity()==40) { + NetworkPacket.databufferpool_40.back(bbft); + }else { + NetworkPacket.databufferpool_2048.back(bbft); + } + }*/ + } + + + + } + public static class IPv6RoutingHeader extends IPv6ExtHeader{ + @Override + public String toString() { + return "IPv6RoutingHeader [protocolNumber=" + getProtocolNumber() + ", getNextHeader()=" + getNextHeader() + + ", getExtLength()=" + getExtLength()+ ", getRoutingType()="+getRoutingType() + "]"; + } + public IPv6RoutingHeader() { + super(43); + } + public IPv6RoutingHeader(boolean onDefault) { + super(43,onDefault); + } + + public IPv6RoutingHeader( boolean isonDefault, ByteBuffer data) { + super(43, isonDefault, data); + } + public int getRoutingType() { + return getData().get(2)&0xff; + } + public void setRoutingType(int routingTypr) { + getData().put(2, (byte) routingTypr); + } + public int getSegmentsLeft() { + return getData().get(3); + } + public void setSegmentsLeft(int segmentsLeft) { + getData().put(3,(byte) segmentsLeft); + } + } + + public static class IPv6SegmentRoutingHeader extends IPv6RoutingHeader{ + + private final List addresses=new ArrayList(); + private final List tlvs=new ArrayList(); + + + @Override + public String toString() { + return "IPv6SegmentRoutingHeader [addresses=" + addresses + ", tlvs=" + tlvs + ", getLastEntry()=" + + getLastEntry() + ", getFlags()=" + getFlags() + ", getTag()=" + getTag() + ", getAddresses()=" + + getAddresses() + ", getRoutingType()=" + getRoutingType() + ", getSegmentsLeft()=" + + getSegmentsLeft() + ", getProtocolNumber()=" + getProtocolNumber() + ", getNextHeader()=" + + getNextHeader() + ", getExtLength()=" + getExtLength() + "]"; + } + public IPv6SegmentRoutingHeader() { + super(false); + setRoutingType(4); + } + + public IPv6SegmentRoutingHeader(ByteBuffer bbf) { + super(false,bbf); + } + public IPv6SegmentRoutingHeader(List segs) { + this(); + this.addresses.addAll( segs); + int ln=addresses.size()-1; + setLastEntry(ln); + setSegmentsLeft(ln); + } + public int getLastEntry() { + return getData().get(4)&0xff; + } + + public void setLastEntry(int lastEntry) { + getData().put(4, (byte) lastEntry); + } + + public int getFlags() { + return getData().get(5)&0xff; + } + + public void setFlags(int flags) { + getData().put(5,(byte) flags); + } + + public int getTag() { + return getData().getShort(6)&0xffff; + } + + public void setTag(int tag) { + getData().putShort(6,(short) tag); + } + public List getAddresses() { + return addresses; + } + @Override + protected void writeToChannel(WritableByteChannel dto) throws IOException { + setExtLength(calcExtLength()/8); + setLastEntry(addresses.size()-1); + super.writeToChannel(dto); + for (Iterator iterator = addresses.iterator(); iterator.hasNext();) { + Inet6Address inet6Address = (Inet6Address) iterator.next(); + dto.write(ByteBuffer.wrap(inet6Address.getAddress())); + } + + } + private int calcExtLength() { + int tlvsl=0; + for (Iterator iterator = tlvs.iterator(); iterator.hasNext();) { + IPv6SegmentRoutingTLV tlve = (IPv6SegmentRoutingTLV) iterator.next(); + tlvsl+=tlve.getLength(); + } + return addresses.size()*16+tlvsl; + } + @Override + protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { + super.readFromChannel(din, length); + int extl=getExtLength(); + int laste=getLastEntry(); + + int rl=extl*8; + int usdl=0; + + //System.out.println("SR length:"+(laste+1)); + addresses.clear(); + ByteBuffer bfr=ByteBuffer.allocate(16); + for (int i = 0; i < (laste+1); i++) { + bfr.clear(); + while (bfr.hasRemaining()) { + if (din.read(bfr) == -1) { + throw new EOFException(); + } + } + bfr.flip(); + usdl+=bfr.limit(); + Inet6Address addr=(Inet6Address) Inet6Address.getByAddress(bfr.array()); + //System.out.println("SR:"+addr); + addresses.add(addr); + } + return; + } + @Override + public long getLength() { + return calcExtLength()+8; + } + + + + } + + public static class IPv6DestinationHeader extends IPv6ExtHeader{ + @Override + public String toString() { + return "IPv6DestinationHeader [protocolNumber=" + getProtocolNumber() + ", getNextHeader()=" + getNextHeader() + + ", getExtLength()=" + getExtLength()+ ", getRoutingType()="+getRoutingType() + "]"; + } + public IPv6DestinationHeader() { + super( 60); + } + public int getRoutingType() { + return getData().get(2)&0xff; + } + public void setRoutingType(int routingTypr) { + getData().put(2, (byte) routingTypr); + } + public int getSegmentsLeft() { + return getData().get(3); + } + public void setSegmentsLeft(int segmentsLeft) { + getData().put(3,(byte) segmentsLeft); + } + } + + + + public List getHeaders() { + return headers; + } + + /*public IPv6DestinationHeader insertDestinationHeader(int index,int extLength) { + long ptr; + long lth=extLength*8+8; + if(index==headers.size()) { + ptr=payload.getPointer(); + }else if(index=headers.size()) { + irh.setNextHeader(payload.getType()); + }else { + irh.setNextHeader(headers.get(index).getType()); + } + if(index-1<0) { + setNextHeader(irh.getType()); + }else { + headers.get(index-1).setNextHeader(irh.getType()); + } + headers.add(index, irh); + analyse(); + return irh; + } + public IPv6RoutingHeader insertSRHRoutingHeader(int index,IpV6RoutingSRHData srh) { + long ptr; + long lth=srh.length()+4; + if(index==headers.size()) { + ptr=payload.getPointer(); + }else if(index=headers.size()) { + irh.setNextHeader(payload.getType()); + }else { + irh.setNextHeader(headers.get(index).getType()); + } + if(index-1<0) { + setNextHeader(irh.getType()); + }else { + headers.get(index-1).setNextHeader(irh.getType()); + } + headers.add(index, irh); + irh.setRoutingType(4); + irh.setSegmentsLeft(srh.getLastEntry()); + irh.getData().put(4, srh.getRawData()); + analyse(); + return irh; + }*/ + @Override + protected boolean needEndPosition() { + return false; + } + + + + + + +} diff --git a/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java b/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java new file mode 100644 index 0000000..2c7cb49 --- /dev/null +++ b/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java @@ -0,0 +1,248 @@ +package org.kne.cloud.network.ipv6; + +import java.io.Closeable; +import java.io.IOException; +import java.net.Inet6Address; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.LockSupport; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Consumer; + +import org.kne.cloud.network.NetworkPacket; +import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl; +import org.kne.cloud.network.srv6.IpV6RoutingSRHData; +import org.kne.cloud.network.srv6.PacketConsumer; +import org.kne.cloud.network.srv6.PacketReorder; +import org.kne.cloud.network.srv6.SRv6StreamSequenceTLV; +import org.kne.cloud.network.srv6.SRv6TLV; +import org.kne.cloud.network.tun.TUNNetworkDevice; +import org.kne.concurrent.SpinLock; +import org.kne.io.KNEChannels; + +public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, AutoCloseable { + + public static final String KLALB_DECENTRALIZED_S_RV6_NETWORK = "KLALB Decentralized SRv6 Network"; + + public static final String KLALB_S_RV6 = "KLALB SRv6"; + + private TUNNetworkDevice tun; + + private Inet6AddressGroup hostAddress; + + private Thread tr; + + private ThreadPoolExecutor exc = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + private Lock slok=new SpinLock(); + + public IPv6TUNLoopbackNetworkLink(Inet6AddressGroup hostAddress, int mtu) throws IOException { + if (tun != null) + throw new IllegalStateException("already open!"); + try { + tun = TUNNetworkDevice.createDevice(KLALB_S_RV6, KLALB_DECENTRALIZED_S_RV6_NETWORK); + tun.open(); + tun.setStatus(true); + this.hostAddress = hostAddress; + if (hostAddress != null) + tun.setIPAddress(hostAddress.getAddress(), hostAddress.getPrefixLength()); + tun.setMTU(mtu); + Thread tb = new Thread(() -> { + while (true) { + ByteBuffer tmp = NetworkPacket.databufferpool_65535.borrow(); + try { + tun.read(tmp); + tmp.flip(); + if (IPv6Packet.getIPVersion(tmp.get(0)) == 6) { + while(exc.getQueue().size()>10) { + LockSupport.parkNanos(1000000); + } + exc.execute(() -> { + try { + IPv6Packet ipp = new IPv6Packet(); + ipp.readFromChannel(KNEChannels.newReadableChannel(tmp), mtu); + NetworkPacket.databufferpool_65535.back(tmp); + if (con != null) { + + monitor.getOutPacketCounterAL().incrementAndGet(); + monitor.getOutTrafficAL().addAndGet(ipp.getLength()); + ipp.setDisposeAfterSend(true); + ipp.getPayload().setDisposeAfterSend(true); + con.accept(ipp); + } else { + ipp.dispose(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + }); + }else { + NetworkPacket.databufferpool_65535.back(tmp); + } + } catch (Exception e) { + NetworkPacket.databufferpool_65535.back(tmp); + e.printStackTrace(); + } + } + }); + tb.setPriority(Thread.MAX_PRIORITY-1); + tb.start(); + tr = new Thread(() -> { + while (true) { + ByteBuffer tmp = sendQueue.poll(); + if (tmp != null) { + + slok.lock(); + try { + tun.write(tmp); + } catch (IOException e) { + e.printStackTrace(); + }finally { + slok.unlock(); + NetworkPacket.databufferpool_65535.back(tmp); + } + } else { + LockSupport.parkNanos(1000000L); + } + + } + }); + tr.setPriority(Thread.MAX_PRIORITY-1); + tr.start(); + + }catch(UnsatisfiedLinkError e) { + throw new IOException(e); + } + } + + private LinkedBlockingQueue sendQueue = new LinkedBlockingQueue(); + + private volatile Consumer con; + + private SpeedAndTrafficMonitorDataImpl monitor; + + @Override + public void sendPacket(IPv6Packet pack, Inet6Address next) throws IOException { + if (tun != null) {/* + * AtomicLong seqs=null; try { IPv6RoutingHeader + * srhh=getRoutingHeaderFromPacket(pack); if(srhh!=null) { byte[]srd=new + * byte[(int) (srhh.getLength()-4)]; srhh.getData().get(4, srd); + * IpV6RoutingSRHData srh=IpV6RoutingSRHData.newInstance( srd,0,srd.length); + * SRv6StreamSequenceTLV ssqv= getStreamSequenceTLV(srh); if(ssqv!=null) + * seqs=new AtomicLong( ssqv.getSequence()); } }catch(IllegalRawDataException + * re) { + * + * } + */ + + // System.out.println("add"); + while(exc.getQueue().size()>10) { + LockSupport.parkNanos(1000000); + } + exc.execute(()->{ + ByteBuffer tmp = NetworkPacket.databufferpool_65535.borrow(); + + try { + // System.out.println("rev"); + pack.writeToChannel(KNEChannels.newWritableChannel(tmp)); + monitor.getInPacketCounterAL().incrementAndGet(); + monitor.getInTrafficAL().addAndGet(pack.getLength()); + tmp.flip(); + sendQueue.add(tmp); + LockSupport.unpark(tr); + + } catch (IOException e) { + NetworkPacket.databufferpool_65535.back(tmp); + e.printStackTrace(); + } + + pack.disposeAll(); + }); + } else { + pack.disposeAll(); + } + } + + private SRv6StreamSequenceTLV getStreamSequenceTLV(IpV6RoutingSRHData srh) { + List stv = srh.getTlvs(); + for (Iterator iterator = stv.iterator(); iterator.hasNext();) { + SRv6TLV sRv6TLV = (SRv6TLV) iterator.next(); + if (sRv6TLV.getType() == SRv6TLV.SEQS) { + return (SRv6StreamSequenceTLV) sRv6TLV; + } + } + return null; + } + + @Override + public boolean isLoopBack() { + return true; + } + + @Override + public List getNeighborsInfo() { + List hs = new ArrayList<>(); + //if (hostAddress != null) + //hs.put(hostAddress, null); + return hs; + } + + @Override + public boolean isCongress(IPv6Packet iPv6Packet) { + return sendQueue.size() > 1000; + } + + @Override + public String getName() { + return "tunLoopBack"; + } + + @Override + public boolean isUp() { + return tun.isOpen(); + } + + public void close() throws IOException { + if (tun != null) { + tun.close(); + tun = null; + } + } + + @Override + public boolean canSend(IPv6Packet iPv6Packet) { + return true; + } + + @Override + public void setReceiveConsumer(Consumer con) { + this.con = con; + } + + public void setMonitor(SpeedAndTrafficMonitorDataImpl monitor) { + this.monitor = monitor; + } + + public SpeedAndTrafficMonitorDataImpl getMonitor() { + return monitor; + } + + @Override + public Inet6AddressGroup getAddressGroup() { + return hostAddress; + } + + + +} diff --git a/src/org/kne/cloud/network/ipv6/Inet6AddressGroup.java b/src/org/kne/cloud/network/ipv6/Inet6AddressGroup.java new file mode 100644 index 0000000..030c13e --- /dev/null +++ b/src/org/kne/cloud/network/ipv6/Inet6AddressGroup.java @@ -0,0 +1,93 @@ +package org.kne.cloud.network.ipv6; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Objects; + +public class Inet6AddressGroup implements Comparable{ + private static final byte[][] maskTransf=new byte[129][16]; + static { + for (int i = 0; i < 129; i++) { + for(int j=0;j>>j%8)|maskTransf[i][j/8]); + } + } + /* for (int i = 0; i < maskTransf.length; i++) { + try { + System.out.println(InetAddress.getByAddress(maskTransf[i])); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + }*/ + } + public Inet6AddressGroup(Inet6Address address) { + this(address, 128); + } + @Override + public String toString() { + return address.getHostAddress()+"/"+prefixLength; + } + @Override + public int hashCode() { + return Objects.hash(address, prefixLength); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Inet6AddressGroup other = (Inet6AddressGroup) obj; + return Objects.equals(address, other.address) && prefixLength == other.prefixLength; + } + public Inet6AddressGroup(Inet6Address address, int prefixLength) { + super(); + this.address = address; + this.prefixLength = prefixLength; + } + public Inet6AddressGroup(DataInputStream in) throws IOException { + readFromStream(in); + } + private Inet6Address address; + private int prefixLength=128; + public Inet6Address getAddress() { + return address; + } + public int getPrefixLength() { + return prefixLength; + } + public boolean checkMatch(Inet6Address ia) { + byte[]mask=maskTransf[prefixLength]; + byte[]andj=and0(mask,ia.getAddress()); + byte[]andm=and0(mask ,address.getAddress()); + return Arrays.equals(andj,andm); + } + private byte[] and0(byte[] bs, byte[] address2) { + byte[]rez=new byte[bs.length]; + for (int i = 0; i < rez.length; i++) { + rez[i]=(byte) (bs[i]&address2[i]); + } + return rez; + } + @Override + public int compareTo(Inet6AddressGroup o) { + return -Integer.compare(prefixLength, o.prefixLength); + } + public void writeToStream(DataOutputStream out) throws IOException { + out.write(address.getAddress()); + out.write(prefixLength); + } + public void readFromStream(DataInputStream in) throws IOException { + byte[]b=new byte[16]; + in.readFully(b); + address=(Inet6Address) Inet6Address.getByAddress(b); + prefixLength=in.read(); + } +} diff --git a/src/org/kne/cloud/network/ipv6/Neighbor.java b/src/org/kne/cloud/network/ipv6/Neighbor.java new file mode 100644 index 0000000..e379e29 --- /dev/null +++ b/src/org/kne/cloud/network/ipv6/Neighbor.java @@ -0,0 +1,48 @@ +package org.kne.cloud.network.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.util.Objects; + +import org.kne.cloud.network.monitor.MonitorData; + +public class Neighbor { + private Inet6AddressGroup address; + private Inet6AddressGroup locator; + private MonitorData monitor; + public MonitorData getMonitor() { + return monitor; + } + public Inet6AddressGroup getAddress() { + return address; + } + public Inet6AddressGroup getLocator() { + return locator; + } + public Neighbor(Inet6AddressGroup address, Inet6AddressGroup locator, MonitorData monitor) { + super(); + this.address = address; + this.locator = locator; + this.monitor = monitor; + } + @Override + public String toString() { + return "Neighbor [address=" + address + ", locator=" + locator + ", monitor=" + monitor + "]"; + } + @Override + public int hashCode() { + return Objects.hash(address, locator); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Neighbor other = (Neighbor) obj; + return Objects.equals(address, other.address) && Objects.equals(locator, other.locator); + } + +} diff --git a/src/org/kne/cloud/network/ipv6/RouteItem.java b/src/org/kne/cloud/network/ipv6/RouteItem.java new file mode 100644 index 0000000..56ad9b4 --- /dev/null +++ b/src/org/kne/cloud/network/ipv6/RouteItem.java @@ -0,0 +1,111 @@ +package org.kne.cloud.network.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.util.Objects; + + +import org.kne.cloud.network.ipv6.IPv6NetworkLink; +import org.kne.cloud.network.ipv6.Inet6AddressGroup; +import org.kne.cloud.network.monitor.DelayMonitorData; +import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.QueueingMonitorDataImpl; + +public class RouteItem implements Comparable{ + private Inet6AddressGroup destination; + private Inet6Address nexthop; + private IPv6NetworkLink destlink; + private String proto; + private int pre; + private long cost; + private String flag; + private MonitorData monitor; + public String getFlag() { + return flag; + } + public MonitorData getMonitor() { + return monitor; + } + @Override + public int hashCode() { + return Objects.hash(cost, destination, destlink, flag, nexthop, pre, proto); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RouteItem other = (RouteItem) obj; + return cost == other.cost && Objects.equals(destination, other.destination) + && Objects.equals(flag, other.flag) + && pre == other.pre && Objects.equals(proto, other.proto); + } + public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre, + long cost,String flag) { + super(); + this.destination = destination; + this.nexthop = nexthop; + this.destlink = destlink; + this.proto = proto; + this.pre = pre; + this.cost = cost; + this.flag=flag; + } + public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre, + long cost,MonitorData monitor,String flag) { + super(); + this.destination = destination; + this.nexthop = nexthop; + this.destlink = destlink; + this.proto = proto; + this.pre = pre; + this.cost = cost; + this.monitor=monitor; + this.flag=flag; + } + public Inet6AddressGroup getDestination() { + return destination; + } + public Inet6Address getNexthop() { + return nexthop; + } + public IPv6NetworkLink getDestlink() { + return destlink; + } + public String getProto() { + return proto; + } + public int getPre() { + return pre; + } + @Override + public String toString() { + return getDestination()+"\t"+getProto()+"\t"+getPre()+"\t"+getCost()+"\t"+getFlag()+"\t"+getNexthop().getHostAddress()+"\t"+getDestlink().getName(); + } + public long getCost() { + return cost; + } + public boolean checkMatch(Inet6Address ia) { + return destination.checkMatch(ia); + } + @Override + public int compareTo(RouteItem o) { + int v1=destination.compareTo(o.destination); + if(v1!=0) + return v1; + int v2=Integer.compare(pre, o.pre); + if(v2!=0) + return v2; + int v3=Long.compare(cost, o.cost); + if(v3!=0) + return v3; + if(monitor==null||o.monitor==null||(!(monitor instanceof DelayMonitorData))||(!(o.monitor instanceof DelayMonitorData))) + return v3; + if(!(monitor instanceof QueueingMonitorDataImpl)||!(o.monitor instanceof QueueingMonitorDataImpl)) + return Long.compare(((DelayMonitorData)monitor).getOutDelay(), ((DelayMonitorData)o.monitor).getOutDelay()); + return Long.compare(((DelayMonitorData)monitor).getOutDelay()+((QueueingMonitorDataImpl)monitor).getQueueingDelay(), ((DelayMonitorData)o.monitor).getOutDelay()+((QueueingMonitorDataImpl)o.monitor).getQueueingDelay()); + } +} diff --git a/src/org/kne/cloud/network/klalb/ACKTPacket.java b/src/org/kne/cloud/network/klalb/ACKTPacket.java index 50e2a18..5095863 100644 --- a/src/org/kne/cloud/network/klalb/ACKTPacket.java +++ b/src/org/kne/cloud/network/klalb/ACKTPacket.java @@ -14,18 +14,21 @@ import java.util.concurrent.atomic.AtomicInteger; public class ACKTPacket extends KLALBPacket implements PortPacket { + private static final int HEADER_LENGTH=28; - public ACKTPacket(int sport,int dport,long number,boolean avaliable,int sendcount) { - super(ACKT); - header.putInt(sport); - header.putInt(dport); - header.putLong(number); - header.put((byte) sendcount); - header.put((byte) (avaliable?1:0)); + public ACKTPacket(int sport,int dport,long number,boolean avaliable,boolean congress,long rcvSpeed,int sendcount) { + super(ACKT,HEADER_LENGTH); + klalbHeader.putInt(sport); + klalbHeader.putInt(dport); + klalbHeader.putLong(number); + klalbHeader.put((byte) sendcount); + klalbHeader.put((byte) (avaliable?1:0)); + klalbHeader.put((byte) (congress?1:0)); + klalbHeader.putLong(rcvSpeed); } public ACKTPacket(ByteBuffer bb) { - super(bb); + super(bb,HEADER_LENGTH); } @Override @@ -34,28 +37,30 @@ public class ACKTPacket extends KLALBPacket implements PortPacket { } public int getSport() { - return header.getInt(1); + return klalbHeader.getInt(1); } - @Override - public int getHeaderSize() { - return super.getHeaderSize()+18; + public boolean isCongress() { + return klalbHeader.get(19)!=0; } - + public int getDport() { - return header.getInt(5); + return klalbHeader.getInt(5); } public long getNumber() { - return header.getLong(9); + return klalbHeader.getLong(9); } public boolean isAvaliable() { - return header.get(18)!=0; + return klalbHeader.get(18)!=0; } public int getSendcount() { - return header.getInt(17); + return klalbHeader.getInt(17); + } + public long getRcvSpeed() { + return klalbHeader.getLong(20); } } \ No newline at end of file diff --git a/src/org/kne/cloud/network/klalb/ADDLINESPacket.java b/src/org/kne/cloud/network/klalb/ADDLINESPacket.java index 226e272..465a302 100644 --- a/src/org/kne/cloud/network/klalb/ADDLINESPacket.java +++ b/src/org/kne/cloud/network/klalb/ADDLINESPacket.java @@ -16,19 +16,20 @@ import java.nio.charset.Charset; public class ADDLINESPacket extends KLALBPacket { private String lines; + private static final int HEADER_LENGTH=3; public String getLines() { return lines; } public ADDLINESPacket(String lines) { - super(ADDLINES); + super(ADDLINES,HEADER_LENGTH); this.lines=lines; } public ADDLINESPacket(ByteBuffer bb) { - super(bb); + super(bb,HEADER_LENGTH); } @@ -42,7 +43,7 @@ public class ADDLINESPacket extends KLALBPacket { @Override protected void writeToChannel(WritableByteChannel dto) throws IOException { byte[]bta=lines.getBytes(Charset.forName("UTF-8")); - header.putChar(1,(char) bta.length); + klalbHeader.putChar(1,(char) bta.length); super.writeToChannel(dto); dto.write(ByteBuffer.wrap(bta)); } @@ -50,7 +51,7 @@ public class ADDLINESPacket extends KLALBPacket { @Override protected void readFromChannel(ReadableByteChannel din) throws IOException { super.readFromChannel(din); - int lth=header.getChar(1); + int lth=klalbHeader.getChar(1); byte[]b=new byte[lth]; ByteBuffer wp= ByteBuffer.wrap(b); while(wp.hasRemaining()){ @@ -61,14 +62,9 @@ public class ADDLINESPacket extends KLALBPacket { lines=new String(b, Charset.forName("UTF-8")); } - @Override - protected int getHeaderSize() { - return super.getHeaderSize()+2; - } - @Override public long getLength() { - return super.getLength()+2+lines.getBytes(Charset.forName("UTF-8")).length; + return HEADER_LENGTH+lines.getBytes(Charset.forName("UTF-8")).length; } } diff --git a/src/org/kne/cloud/network/klalb/ADDRPacket.java b/src/org/kne/cloud/network/klalb/ADDRPacket.java new file mode 100644 index 0000000..381c56c --- /dev/null +++ b/src/org/kne/cloud/network/klalb/ADDRPacket.java @@ -0,0 +1,42 @@ +package org.kne.cloud.network.klalb; + +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.Inet6Address; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; + +import org.kne.cloud.network.ipv6.Inet6AddressGroup; + +public class ADDRPacket extends KLALBPacket { + private static final int HEADER_LENGTH=18; + public Inet6AddressGroup getAddr() { + byte[]b=new byte[16]; + klalbHeader.get(1, b); + try { + return new Inet6AddressGroup( (Inet6Address) Inet6Address.getByAddress(b),klalbHeader.get(17)&0xff); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + return null; + } + + public ADDRPacket(Inet6AddressGroup addr) { + super(ADDR,HEADER_LENGTH); + klalbHeader.put(1, addr.getAddress().getAddress()); + klalbHeader.put(17,(byte) addr.getPrefixLength()); + } + + public ADDRPacket(ByteBuffer bb) { + super(bb,HEADER_LENGTH); + } + + @Override + public String toString() { + return "ADDR "+getAddr(); + } + +} diff --git a/src/org/kne/cloud/network/klalb/ADDRREQPacket.java b/src/org/kne/cloud/network/klalb/ADDRREQPacket.java new file mode 100644 index 0000000..7398019 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/ADDRREQPacket.java @@ -0,0 +1,22 @@ +package org.kne.cloud.network.klalb; + +import java.nio.ByteBuffer; + +public class ADDRREQPacket extends KLALBPacket { + + private static final int HEADER_LENGTH=1; + + public ADDRREQPacket() { + super(ADDRREQ,HEADER_LENGTH); + } + + public ADDRREQPacket(ByteBuffer bb) { + super(bb,HEADER_LENGTH); + } + + @Override + public String toString() { + return "ADDRREQ"; + } + +} diff --git a/src/org/kne/cloud/network/klalb/BWINFPacket.java b/src/org/kne/cloud/network/klalb/BWINFPacket.java index 9124c27..6bc02b8 100644 --- a/src/org/kne/cloud/network/klalb/BWINFPacket.java +++ b/src/org/kne/cloud/network/klalb/BWINFPacket.java @@ -9,14 +9,14 @@ import java.nio.ByteBuffer; public class BWINFPacket extends KLALBPacket { - + private static final int HEADER_LENGTH=17; public long getUpSpeed() { - return header.getLong(1); + return klalbHeader.getLong(1); } public long getDownSpeed() { - return header.getLong(9); + return klalbHeader.getLong(9); } @Override @@ -24,18 +24,13 @@ public class BWINFPacket extends KLALBPacket { return super.getLength()+16; } - @Override - protected int getHeaderSize() { - return super.getHeaderSize()+16; - } - public BWINFPacket(long upSpeed,long downSpeed) { - super( BWINF,-1); - header.putLong(upSpeed); - header.putLong(downSpeed); + super( BWINF,HEADER_LENGTH,-1); + klalbHeader.putLong(upSpeed); + klalbHeader.putLong(downSpeed); } public BWINFPacket(ByteBuffer bb) { - super(bb); + super(bb,HEADER_LENGTH); } @Override diff --git a/src/org/kne/cloud/network/klalb/ByteArrayPool.java b/src/org/kne/cloud/network/klalb/ByteArrayPool.java index d507d55..3923460 100644 --- a/src/org/kne/cloud/network/klalb/ByteArrayPool.java +++ b/src/org/kne/cloud/network/klalb/ByteArrayPool.java @@ -1,17 +1,18 @@ package org.kne.cloud.network.klalb; +import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentLinkedQueue; public class ByteArrayPool { - private ArrayBlockingQueuerec; + private Queue rec; private int maxcount; private int length; public ByteArrayPool(int maxcount, int length) { super(); this.maxcount = maxcount; this.length = length; - rec=new ArrayBlockingQueue(length); + rec=new ConcurrentLinkedQueue(); } public void back(byte[]b) { if(b.length!=length) diff --git a/src/org/kne/cloud/network/klalb/ByteBufferPool.java b/src/org/kne/cloud/network/klalb/ByteBufferPool.java index 104a021..71dbeee 100644 --- a/src/org/kne/cloud/network/klalb/ByteBufferPool.java +++ b/src/org/kne/cloud/network/klalb/ByteBufferPool.java @@ -1,11 +1,19 @@ package org.kne.cloud.network.klalb; import java.nio.ByteBuffer; +import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import org.kne.concurrent.SpinLock; +import org.kne.debug.TimeDebugger; +/* public class ByteBufferPool { - private ArrayBlockingQueuerec; + private Queue rec; private int maxcount; private int length; private boolean direct; @@ -14,7 +22,7 @@ public class ByteBufferPool { this.maxcount = maxcount; this.length = length; this.direct=direct; - rec=new ArrayBlockingQueue(length); + rec=new ConcurrentLinkedQueue(); } public ByteBufferPool(int maxcount, int length) { this(maxcount, length, true); @@ -42,4 +50,64 @@ public class ByteBufferPool { return length; } +}*/ + +public class ByteBufferPool { + private ByteBuffer[]rec; + private volatile int pos=0; + private Lock lock=new SpinLock(); + + private int maxcount; + private int length; + private int mcj; + private boolean direct; + public ByteBufferPool(int maxcount, int length,boolean direct) { + super(); + this.maxcount = maxcount; + this.length = length; + this.direct=direct; + rec=new ByteBuffer[maxcount]; + mcj=rec.length-1; + } + public ByteBufferPool(int maxcount, int length) { + this(maxcount, length, true); + } + public void back(ByteBuffer b) { + if(b.capacity()!=length) + throw new IllegalArgumentException("wrong length"); + b.clear(); + lock.lock(); + try { + if(pos0) { + b=rec[pos--]; + //rec[pos--]=null; + } + }finally{ + lock.unlock(); + } + if(b==null) { + if(direct) + b=ByteBuffer.allocateDirect(length); + else + b=ByteBuffer.allocate(length); + } + return b; + } + public int getMaxCount() { + return maxcount; + } + public int getLength() { + return length; + } + } diff --git a/src/org/kne/cloud/network/klalb/CONST.java b/src/org/kne/cloud/network/klalb/CONST.java index af90078..e0c8fea 100644 --- a/src/org/kne/cloud/network/klalb/CONST.java +++ b/src/org/kne/cloud/network/klalb/CONST.java @@ -1,6 +1,8 @@ package org.kne.cloud.network.klalb; public class CONST { - public static String klalb="KLALB"; - public static String klalbver="2.3"; + public static final String klalb="KLALB"; + public static final String klalbver="3.0"; + public static final int bversion=3; + public static final int sversion=0; } diff --git a/src/org/kne/cloud/network/klalb/CannotAssociateException.java b/src/org/kne/cloud/network/klalb/CannotAssociateException.java new file mode 100644 index 0000000..e95457e --- /dev/null +++ b/src/org/kne/cloud/network/klalb/CannotAssociateException.java @@ -0,0 +1,27 @@ +package org.kne.cloud.network.klalb; + +import java.io.IOException; + +public class CannotAssociateException extends IOException { + + public CannotAssociateException() { + super(); + // TODO 自动生成的构造函数存根 + } + + public CannotAssociateException(String message, Throwable cause) { + super(message, cause); + // TODO 自动生成的构造函数存根 + } + + public CannotAssociateException(String message) { + super(message); + // TODO 自动生成的构造函数存根 + } + + public CannotAssociateException(Throwable cause) { + super(cause); + // TODO 自动生成的构造函数存根 + } + +} diff --git a/src/org/kne/cloud/network/klalb/DATATPacket.java b/src/org/kne/cloud/network/klalb/DATATPacket.java index 9a28874..5d3f6ea 100644 --- a/src/org/kne/cloud/network/klalb/DATATPacket.java +++ b/src/org/kne/cloud/network/klalb/DATATPacket.java @@ -1,84 +1,76 @@ package org.kne.cloud.network.klalb; -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.DataOutput; -import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; -import java.io.StreamCorruptedException; import java.nio.ByteBuffer; -import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; -import java.util.Objects; -import java.util.zip.CRC32; -import javax.sound.sampled.Port; +import org.kne.cloud.network.NetworkPacket; public class DATATPacket extends KLALBPacket implements PortPacket{ /*private int sport,dport; private long number; - private int size; + private int size; private byte[]data; private int sendcount;*/ - - @Override - protected int getHeaderSize() { - return super.getHeaderSize()+19; - } + private static final int HEADER_LENGTH=20; @Override public long getLength() { - return super.getLength()+19+data.limit(); + return HEADER_LENGTH+dataBuffer.limit(); } - volatile long resendtimer=System.nanoTime(); - private ByteBuffer data=KLALBPacket.databufferpool.borrow(); + private ByteBuffer dataBuffer;//=NetworkPacket.databufferpool_65535.borrow(); public DATATPacket(int sport,int dport,long number,int mtulimit) { - super(DATAT); + super(DATAT,HEADER_LENGTH); /*this.sport=sport; this.dport=dport; this.number=number; this.data=data; this.size=size;*/ - header.putInt(sport); - header.putInt(dport); - header.putLong(number); - header.put((byte) 0); - header.putChar((char) 0); + klalbHeader.putInt(sport); + klalbHeader.putInt(dport); + klalbHeader.putLong(number); + numberc=number; + klalbHeader.put((byte) 0); + klalbHeader.putChar((char) 0); - data.limit(mtulimit); + //dataBuffer.limit(mtulimit); + dataBuffer=ByteBuffer.allocate(mtulimit); } public int getSendcount() { - return header.get(17); + return klalbHeader.get(17); } public DATATPacket() { - super(DATAT); + super(DATAT,HEADER_LENGTH); } public DATATPacket(ByteBuffer bb) { - super(bb); + super(bb,HEADER_LENGTH); } public int getSport() { - return header.getInt(1); + return klalbHeader.getInt(1); } public int getDport() { - return header.getInt(5); + return klalbHeader.getInt(5); } + private long numberc=Long.MIN_VALUE; public long getNumber() { - return header.getLong(9); + if(numberc!=Long.MIN_VALUE) { + return numberc; + } + return (numberc= klalbHeader.getLong(9)); } - public ByteBuffer getDataBuffer() { - return data; + return dataBuffer; } @Override @@ -104,37 +96,40 @@ public class DATATPacket extends KLALBPacket implements PortPacket{ } public int getSize() { - return data.limit(); + return dataBuffer.limit(); } @Override protected void writeToChannel(WritableByteChannel dto) throws IOException { - header.put(17, (byte) getSendRecord().size()); - header.putChar(18, (char) data.limit()); + klalbHeader.put(17, (byte) getSendCounter()); + klalbHeader.putChar(18, (char) dataBuffer.limit()); super.writeToChannel(dto); - dto.write(data.slice(0, data.limit())); + //System.out.println(dataBuffer); + dto.write(dataBuffer.slice(0, dataBuffer.limit())); } @Override protected void readFromChannel(ReadableByteChannel din) throws IOException { super.readFromChannel(din); - data.clear(); - data.limit(header.getChar(18)); - while(data.hasRemaining()){ - if(din.read(data)==-1) { + numberc=Long.MIN_VALUE; + int limit=klalbHeader.getChar(18); + //dataBuffer.clear(); + //dataBuffer.limit(); + dataBuffer=ByteBuffer.allocate(limit); + while(dataBuffer.hasRemaining()){ + if(din.read(dataBuffer)==-1) { throw new EOFException(); } } - data.flip(); + dataBuffer.flip(); } @Override public void dispose() { super.dispose(); - ByteBuffer datan=data; - data=null; - KLALBPacket.databufferpool.back(datan); + /*ByteBuffer datan=dataBuffer; + dataBuffer=null; + NetworkPacket.databufferpool_65535.back(datan);*/ } - } diff --git a/src/org/kne/cloud/network/klalb/IPv6OverKLALBPacket.java b/src/org/kne/cloud/network/klalb/IPv6OverKLALBPacket.java new file mode 100644 index 0000000..0b40c87 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/IPv6OverKLALBPacket.java @@ -0,0 +1,101 @@ +package org.kne.cloud.network.klalb; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; + +import org.kne.cloud.network.ipv6.IPv6Packet; + +public class IPv6OverKLALBPacket extends KLALBPacket { + private static final int HEADER_LENGTH=9; + @Override + public boolean isSomeDisposed() { + return super.isDisposed()||ipv6Packet.isSomeDisposed(); + } + + + + @Override + public void lockAll() { + super.lockAll(); + ipv6Packet.lockAll(); + } + + + + @Override + public void unlockAll() { + ipv6Packet.unlockAll(); + super.unlockAll(); + } + + + @Override + public long getLength() { + return HEADER_LENGTH+ipv6Packet.getLength(); + } + + private IPv6Packet ipv6Packet; + + public IPv6OverKLALBPacket(IPv6Packet ipv6Packet) { + super(IPV6OVERKLALB,HEADER_LENGTH); + klalbHeader.putLong((int) ipv6Packet.getLength()); + this.ipv6Packet=ipv6Packet; + } + + + + public IPv6OverKLALBPacket() { + super(IPV6OVERKLALB,HEADER_LENGTH); + this.ipv6Packet=new IPv6Packet(); + } + + public IPv6OverKLALBPacket(ByteBuffer bb) { + super(bb,HEADER_LENGTH); + this.ipv6Packet=new IPv6Packet(); + } + + @Override + public void disposeAll() { + super.disposeAll(); + ipv6Packet.disposeAll(); + } + + public IPv6Packet getIPv6Packet() { + return ipv6Packet; + } + + @Override + public String toString() { + return "IPv6 "+ipv6Packet.getSourceAddress().getHostAddress()+"->"+ipv6Packet.getDestinationAddress().getHostAddress()+" type:"+ipv6Packet.getPayload().getProtocolNumber()+"["+getSize()+"]"; + } + + + public long getSize() { + return ipv6Packet.getLength(); + } + + @Override + protected void writeToChannel(WritableByteChannel dto) throws IOException { + klalbHeader.putLong(1, ipv6Packet.getLength()); + super.writeToChannel(dto); + ipv6Packet.writeToChannel(dto); + } + + @Override + protected void readFromChannel(ReadableByteChannel din,long length) throws IOException { + super.readFromChannel(din,length); + ipv6Packet.readFromChannel(din, klalbHeader.getLong(1)); + } + + + + @Override + public void doDisposeAfterSend() { + super.doDisposeAfterSend(); + ipv6Packet.doDisposeAfterSend(); + } + +} diff --git a/src/org/kne/cloud/network/klalb/KLALBController.java b/src/org/kne/cloud/network/klalb/KLALBController.java index dd9226a..6c9cad2 100644 --- a/src/org/kne/cloud/network/klalb/KLALBController.java +++ b/src/org/kne/cloud/network/klalb/KLALBController.java @@ -2,23 +2,22 @@ package org.kne.cloud.network.klalb; import java.io.IOException; 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.NetworkInterface; import java.net.NoRouteToHostException; -import java.net.Socket; -import java.net.SocketAddress; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; -import java.time.Clock; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -29,46 +28,58 @@ import java.util.Set; import java.util.Timer; import java.util.TimerTask; import java.util.UUID; -import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.function.Supplier; - -import javax.management.openmbean.ArrayType; -import javax.net.ServerSocketFactory; -import javax.net.SocketFactory; import org.kne.cloud.clock.AdjustedNanoClock; +import org.kne.cloud.network.IPMulticastDiscovery; import org.kne.cloud.network.MultipurposeSocketAddress; -import org.kne.cloud.network.NetworkService; -import org.kne.cloud.network.Proxy; +import org.kne.cloud.network.PortPair; import org.kne.cloud.network.SocketType; import org.kne.cloud.network.ThreadTool; +import org.kne.cloud.network.ipv6.IPv6NetworkLink; +import org.kne.cloud.network.ipv6.IPv6Packet; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload; +import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink; +import org.kne.cloud.network.ipv6.Inet6AddressGroup; import org.kne.cloud.network.monitor.MonitorData; import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl; -import org.kne.debug.TimeDebugger; - -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtMethod; -import javassist.bytecode.Bytecode; -import javassist.bytecode.CodeAttribute; -import javassist.bytecode.CodeIterator; +import org.kne.cloud.network.srv6.PacketConsumer; +import org.kne.cloud.network.srv6.SRv6Router; +import org.kne.cloud.network.te.BandwidthDistributer; +import org.kne.cloud.network.te.DWRRLoadingBalanceAlgorithm; +import org.kne.concurrent.HighPerformanceExecutor; +import org.kne.io.KNEChannels; +import org.pcap4j.packet.IpV6Packet.IpV6Header; public class KLALBController { + private SpeedAndTrafficMonitorDataImpl linkMonitor=new SpeedAndTrafficMonitorDataImpl(); private SpeedAndTrafficMonitorDataImpl datatMonitor=new SpeedAndTrafficMonitorDataImpl(); private ListselflineTable=new ArrayList<>(); + + private static final boolean showpacket = false; + + private static final int PREFIX = 112; + private static final int DISCOVERY_PORT=4569; + + private static List ipmd=new ArrayList<>(); + private Timer twk=new Timer("网卡检测扫描计时器", true); { @@ -76,16 +87,23 @@ public class KLALBController { @Override public void run() { + try { + + + Enumerationeu= NetworkInterface.getNetworkInterfaces(); while (eu.hasMoreElements()) { NetworkInterface networkInterface = (NetworkInterface) eu.nextElement(); + if(networkInterface.getDisplayName().startsWith(IPv6TUNLoopbackNetworkLink.KLALB_DECENTRALIZED_S_RV6_NETWORK)) { + continue; + } if(networkInterface.isUp()) { //System.out.println(networkInterface+" "+networkInterface.isUp()); Enumerationei= networkInterface.getInetAddresses(); while (ei.hasMoreElements()) { InetAddress inetAddress = (InetAddress) ei.nextElement(); - + if(!inetAddress.isLoopbackAddress()) for (Iterator iterator = listens.iterator(); iterator.hasNext();) { MultipurposeSocketAddress tcpl = (MultipurposeSocketAddress) iterator.next(); @@ -107,11 +125,15 @@ public class KLALBController { } } + + } } } catch (SocketException e) { } + lineslock.writeLock().lock(); try { + Listlocaladdress=new ArrayList<>(); Enumerationeu= NetworkInterface.getNetworkInterfaces(); while (eu.hasMoreElements()) { @@ -169,7 +191,82 @@ public class KLALBController { } } + for (Iterator iterator = ipmd.iterator(); iterator.hasNext();) { + IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next(); + if(ipMulticastDiscovery.isClosed()||(!ipMulticastDiscovery.getNinterface().isUp())) { + iterator.remove(); + try { + ipMulticastDiscovery.close(); + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("移除网卡:"+ipMulticastDiscovery.getNinterface()); + } + } + Enumerationeu2= NetworkInterface.getNetworkInterfaces(); + while (eu2.hasMoreElements()) { + NetworkInterface networkInterface = (NetworkInterface) eu2.nextElement(); + if(networkInterface.getDisplayName().startsWith(IPv6TUNLoopbackNetworkLink.KLALB_DECENTRALIZED_S_RV6_NETWORK)) { + continue; + } + if(networkInterface.isUp()) { + boolean b=true; + for (Iterator iterator = ipmd.iterator(); iterator.hasNext();) { + IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next(); + if(networkInterface.equals(ipMulticastDiscovery.getNinterface())) { + b=false; + break; + } + } + if(b) { + /*InetAddress bidr=null; + Enumerationei= networkInterface.getInetAddresses(); + while (ei.hasMoreElements()) { + InetAddress inetAddress = (InetAddress) ei.nextElement(); + if(inetAddress instanceof Inet6Address) { + Inet6Address i6=(Inet6Address) inetAddress; + if(i6.getHostAddress().startsWith("fe80")) { + bidr=i6; + break; + } + } + + } + if(bidr!=null)*/ + try { + InetAddress bidr=InetAddress.getByName("::0"); + IPMulticastDiscovery ipd=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("ff02::2486"),DISCOVERY_PORT), networkInterface,selflineTable); + ipd.setCon((mpa)->{ + //System.out.println("添加本地IPv6链路:"+mpa); + addRemoteLines(mpa); + }); + ipd.start(); + ipmd.add(ipd); + + bidr=InetAddress.getByName("0.0.0.0"); + IPMulticastDiscovery ipd2=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("224.0.0.86"),DISCOVERY_PORT), networkInterface,selflineTable); + ipd2.setCon((mpa)->{ + //System.out.println("添加本地IPv4链路:"+mpa); + addRemoteLines(mpa); + }); + ipd2.start(); + ipmd.add(ipd2); + + System.out.println("添加网卡:"+networkInterface); + }catch(BindException e) { + //e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + } catch (SocketException e) { + }finally { + lineslock.writeLock().unlock(); } } @@ -229,13 +326,13 @@ public class KLALBController { } - private Inet6Address self; + private Inet6AddressGroup self; public Inet6Address getSelf() { - return self; + return self.getAddress(); } private List lines=new CopyOnWriteArrayList<>(); - //private ReadWriteLock lineslock=new ReentrantReadWriteLock(); + private ReadWriteLock lineslock=new ReentrantReadWriteLock(); public List getLines() { return lines; @@ -256,50 +353,35 @@ public class KLALBController { } private PacketReceiver prc=new PacketReceiver(); - private class PacketReceiver implements KLALBPacketConsumer{ + private class PacketReceiver implements Consumer{ @Override - public void accept(KLALBRemoteLine krs, KLALBPacket rec) { - try { - if(rec instanceof PortPacket&&krs.getRemoteVaddr()!=null) { - PortPacket pt=(PortPacket) rec; - if(!streamPortBinder.distributePacketToConsumer(krs, pt)) { - if(!(pt instanceof RSTPacket)) - sendPacketToAddress(krs.getRemoteVaddr(), new RSTPacket(pt.getDport(), pt.getSport()),2); - } - }else { - switch (rec.getType()) { - case KLALBPacket.ADDLINES: - ADDLINESPacket lpt=(ADDLINESPacket) rec; - String s=lpt.getLines(); - ThreadTool.makeVDaemonThreadIfSupport("线路添加任务", ()->{ - Scanner scn=new Scanner(s); - while(scn.hasNext()) { - String sn=scn.nextLine(); - MultipurposeSocketAddress msa= new MultipurposeSocketAddress(sn); - try { - addRemoteLines(msa); - } catch (SocketTimeoutException e) { - } catch (SocketException e) { - } - - } - }).start(); - break; - default: - break; + public void accept( KLALBPacket rec) { + switch (rec.getType()) { + case KLALBPacket.ADDLINES: + ADDLINESPacket lpt=(ADDLINESPacket) rec; + String s=lpt.getLines(); + ThreadTool.makeVDaemonThreadIfSupport("线路添加任务", ()->{ + Scanner scn=new Scanner(s); + while(scn.hasNext()) { + String sn=scn.nextLine(); + MultipurposeSocketAddress msa= new MultipurposeSocketAddress(sn); + addRemoteLines(msa); + } - } - } catch (IOException e) { - // TODO 自动生成的 catch 块 - e.printStackTrace(); + }).start(); + break; + default: + break; + } } } - public void addRemoteLines(MultipurposeSocketAddress target) throws SocketTimeoutException, SocketException { - + + public List addRemoteLines(MultipurposeSocketAddress target) { + Listadded=new ArrayList<>(); try { Enumerationeu= NetworkInterface.getNetworkInterfaces(); while (eu.hasMoreElements()) { @@ -320,19 +402,35 @@ public class KLALBController { } catch (UnknownHostException e) { } if(!checkContainsTargetAndBind(target,bind)) { - //System.out.println(target+" "+bind); - addRemoteLine( new KLALBRemoteLine(target,bind)); + KLALBRemoteLine line=new KLALBRemoteLine(target,bind); + addRemoteLine(line ); + added.add(line); } } } } } catch (SocketException e) { - if(!checkContainsTarget(target)) - addRemoteLine( new KLALBRemoteLine(target)); + if(!checkContainsTarget(target)) { + KLALBRemoteLine line= new KLALBRemoteLine(target); + addRemoteLine(line); + added.add(line); + } //throw e; } - + return added; + } + public List removeRemoteLines(MultipurposeSocketAddress mpsa) { + + Listrmved=new ArrayList<>(); + for (Iterator iterator = lines.iterator(); iterator.hasNext();) { + KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next(); + if(mpsa.equals( klalbRemoteLine.getSocketAddress())){ + klalbRemoteLine.close(); + rmved.add(klalbRemoteLine); + } + } + return rmved; } public Inet6Address getRemoteVaddrBySocketAddress(MultipurposeSocketAddress target) throws SocketTimeoutException { KLALBRemoteLine kr=null; @@ -352,7 +450,7 @@ public class KLALBController { kr.reconnectImmediately(); kr.waitForRemoteVaddrAvaliable(20000); } - return kr.getRemoteVaddr(); + return kr.getRemoteVaddr().getAddress(); } private boolean checkContainsTargetAndBind(MultipurposeSocketAddress target,MultipurposeSocketAddress bind) { boolean b=false; @@ -386,7 +484,12 @@ public class KLALBController { String selflineTable=generateSelfLineTable(); if(selflineTable!=null&&!selflineTable.equals("")) krs.sendPacket(new ADDLINESPacket(selflineTable)); + lineslock.writeLock().lock(); + try { lines.add(krs); + }finally { + lineslock.writeLock().unlock(); + } } @@ -401,11 +504,77 @@ public class KLALBController { } public KLALBController(Inet6Address self) { - this.self = self; + this.self =new Inet6AddressGroup(self, PREFIX); + loadSRv6ProtocolStack(); + } + private class KLALBProtocolPacketConsumer implements PacketConsumer{ + + @Override + public void accept(IPv6Packet packx) throws IOException { + HighPerformanceExecutor.defaultExecutor.execute(()->{ + + /*System.out.println("RCV:"+packx.getPayload().getData()); + byte[]b=new byte[packx.getPayload().getData().limit()]; + packx.getPayload().getData().get(0, b); + System.out.println(Arrays.toString(b));*/ + IPv6Payload pl=packx.getPayload(); + packx.putTimePassport("unpacked"); + packx.printPassport(); + if(pl instanceof KLALBPacket) { + KLALBPacket rec=(KLALBPacket) pl; + //KLALBPacket rec=KLALBPacket.createByBuffer(packx.getPayload().getData()); + if(showpacket) + System.out.println("KLALB_RX:"+rec); + if(rec instanceof PortPacket) { + rec.setCE(packx.isCE()); + Inet6Address srcA=packx.getSourceAddress(); + PortPacket pt=(PortPacket) rec; + if(!streamPortBinder.distributePacketToConsumer( srcA,pt)) { + if(!(pt instanceof RSTPacket)) + try { + sendPacketToAddress(srcA,0, new RSTPacket(pt.getDport(), pt.getSport()),2); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + packx.dispose(); + }); + } + + } + private void loadSRv6ProtocolStack() { + srv6Router=new SRv6Router(self); + try { + IPv6TUNLoopbackNetworkLink tunlink=new IPv6TUNLoopbackNetworkLink(new Inet6AddressGroup( srv6Router.getLocator().getAddress(),32),SRv6Router.MTU); + tunlink.setMonitor(datatMonitor); + srv6Router.getLinkTabel().add(tunlink); + Thread.sleep(100); + } catch (Exception e) { + e.printStackTrace(); + } + srv6Router.runKLALBRouteProtocol(); + srv6Router.getProtocolNumberRegister().put(KLALBPacket.KLALB_PROTOCOL_NUMBER,new KLALBProtocolPacketConsumer()); + System.out.println("SRv6协议栈已加载"); } public KLALBController() { - this.self=KLALBUtils.uuidToIP(UUID.randomUUID()); + SecureRandom sc=new SecureRandom(); + byte[]v=new byte[16]; + sc.nextBytes(v); + v[0]=(byte)0x24; + v[1]=(byte) 0x86; + v[2]=0; + v[3]=1; + v[14]=0; + v[15]=1; + try { + this.self=new Inet6AddressGroup( (Inet6Address) InetAddress.getByAddress(v),PREFIX); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + loadSRv6ProtocolStack(); } protected KLALBVirtualSocketImpl createVirtualImpl() { @@ -416,9 +585,16 @@ public class KLALBController { - protected void sendPacketToAddress(Inet6Address addr, KLALBPacket packet) + protected void sendPacketToLinkAddress(Inet6Address addr, KLALBPacket packet) throws IOException { - sendPacketToAddress(addr, packet, 1); + sendPacketToLinkAddress(addr, packet, 1); + } + + private SRv6Router srv6Router; + + + public SRv6Router getIpv6Router() { + return srv6Router; } private Timer trtr=new Timer("路由表刷新计时器", true); @@ -427,35 +603,55 @@ private Timer trtr=new Timer("路由表刷新计时器", true); @Override public void run() { - Map> lines2 =new ConcurrentHashMap<>(); + Map> lines2 =new ConcurrentHashMap<>(); for (Iterator iterator = lines.iterator(); iterator.hasNext();) { KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next(); if(klalbRemoteLine.isClosed()) { + lineslock.writeLock().lock(); + try { lines.remove(klalbRemoteLine); + }finally{ + lineslock.writeLock().unlock(); + } }else { if(klalbRemoteLine.getRemoteVaddr()!=null&&klalbRemoteLine.getMonitor().getState()==MonitorData.ONLINE) { if(lines2.containsKey(klalbRemoteLine.getRemoteVaddr())) { - lines2.get(klalbRemoteLine.getRemoteVaddr()).add(klalbRemoteLine); + lines2.get(klalbRemoteLine.getRemoteVaddr()).getEntries().add(klalbRemoteLine); }else { ArrayListal1=new ArrayList<>(); al1.add(klalbRemoteLine); - lines2.put(klalbRemoteLine.getRemoteVaddr(), al1); + lines2.put(klalbRemoteLine.getRemoteVaddr().getAddress(), new DWRRLoadingBalanceAlgorithm<>(al1)); } + if(!srv6Router.getLinkTabel().contains(klalbRemoteLine)) { + srv6Router.getLinkTabel().add(klalbRemoteLine); + } } } } - for (Iterator>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) { - Entry> klalbRemoteLine = (Entry>) iterator.next(); - klalbRemoteLine.getValue().forEach((r)->{ + for (Iterator>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) { + Entry> klalbRemoteLine = (Entry>) iterator.next(); + List lineList=klalbRemoteLine.getValue().getEntries(); + lineList.forEach((r)->{ r.runPredict(); }); - Collections.sort(klalbRemoteLine.getValue()); + Collections.sort(lineList); + for (int i = 0; i < lineList.size(); i++) { + KLALBRemoteLine krl=lineList.get(i); + krl.noticeRank(i); + } + } KLALBController.this.lines2=lines2; + if(srv6Router!=null) { + srv6Router.getLinkTabel().removeIf((v)->{ + return (v instanceof KLALBRemoteLine)&&(!v.isUp()); + }); + srv6Router.updateRouteTabel(); + } } - }, 5, 5); + }, 1, 1); } - private void updateLines2(Inet6Address addr) throws SocketTimeoutException { + /*private void updateLines2(Inet6Address addr) throws SocketTimeoutException { List l=new ArrayList(); for (int i = 0; i < lines.size(); i++) { KLALBRemoteLine klalbRemoteLine = lines.get(i); @@ -478,11 +674,11 @@ private Timer trtr=new Timer("路由表刷新计时器", true); Collections.sort(l); lines2.put(addr, l); } - } - private Map> lines2 = new ConcurrentHashMap<>(); + }*/ + private Map> lines2 = new ConcurrentHashMap<>(); - protected void sendPacketToAddress(Inet6Address addr, KLALBPacket packet, int count) + protected void sendPacketToLinkAddress(Inet6Address addr, KLALBPacket packet, int count) throws IOException { if(packet==null) throw new NullPointerException("packet is null!"); @@ -491,7 +687,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true); //tdb.putTime("start"); packet.genseq(); - loop:while(true) { + /*loop:while(true) { if(packet.isDisposed()) return; List lines2x; @@ -508,8 +704,9 @@ private Timer trtr=new Timer("路由表刷新计时器", true); KLALBRemoteLine krst =lines2x.get(i); if(krst.getMonitor().getState()==MonitorData.ONLINE) if(!packet.getSendRecord().contains(krst)) { - if(krst.getQueue().size()<3) { + if(krst.getQueue().size()<10) { packet.getSendRecord().add(krst); + //System.out.println(krst); krst.sendPacket(packet); count0--; if (count0 <= 0) @@ -521,8 +718,9 @@ private Timer trtr=new Timer("路由表刷新计时器", true); KLALBRemoteLine krst =lines2x.get(i); if(krst.getMonitor().getState()==MonitorData.ONLINE) if(packet.getSendRecord().contains(krst)) { - if(krst.getQueue().size()<3) { + if(krst.getQueue().size()<10) { packet.getSendRecord().add(krst); + //System.out.println(krst); krst.sendPacket(packet); count0--; if (count0 <= 0) @@ -532,7 +730,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true); } LockSupport.parkNanos(50000); //tdb.putTime("sendfailed"); - } + }*/ //tdb.putTime("sendsuccess"); //tdb.print(); @@ -545,17 +743,160 @@ private Timer trtr=new Timer("路由表刷新计时器", true); KLALBRemoteLine kr= lines2x.get(0); kr.sendPacket(packet); packet.getSendRecord().add(kr);*/ + + /*loop:while(true) { + if(packet.isDisposed()) + return; + DWRRLoadingBalanceAlgorithm dwrlines2x; + + dwrlines2x=lines2.get(addr); + + if (dwrlines2x == null || dwrlines2x.getEntries().isEmpty()) { + throw new NoRouteToHostException("address unreachable: " + addr); + } + + Listlines2x=dwrlines2x.roundEntriesList(); + + int count0 = Math.min(count, lines2x.size()); + + for (int i = 0; i < lines2x.size(); i++) { + KLALBRemoteLine krst =lines2x.get(i); + if(krst.getMonitor().getState()==MonitorData.ONLINE) + if(!packet.getSendRecord().contains(krst)) { + if(krst.getQueue().size()<5) { + packet.getSendRecord().add(krst); + //System.out.println(krst); + krst.sendPacket(packet); + count0--; + if (count0 <= 0) + break loop; + } + } + } + for (int i = 0; i < lines2x.size(); i++) { + KLALBRemoteLine krst =lines2x.get(i); + if(krst.getMonitor().getState()==MonitorData.ONLINE) + if(packet.getSendRecord().contains(krst)) { + if(krst.getQueue().size()<5) { + packet.getSendRecord().add(krst); + //System.out.println(krst); + krst.sendPacket(packet); + count0--; + if (count0 <= 0) + break loop; + } + } + } + LockSupport.parkNanos(50000); + //tdb.putTime("sendfailed"); + }*/ } - /*protected void removeFromSend(Inet6Address addr,KLALBPacket klalbPacket) { - for (Iterator iterator = lines.iterator(); iterator.hasNext();) { - KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next(); - klalbRemoteLine.remoeFromSendQueue(klalbPacket); - + + + + protected void sendPacketToAddress(Inet6Address addr,int flowlabel, KLALBPacket packet) + throws IOException { + sendPacketToAddress(addr,flowlabel, packet, 1); + } + + protected void sendPacketToAddress(Inet6Address addr, int flowlabel,KLALBPacket packet, int count) + throws IOException { + HighPerformanceExecutor.defaultExecutor.execute(()->{ + + IPv6Packet ipv=new IPv6Packet(); + packet.getDisposeLock().lock(); + try { + if(packet.isDisposed()) { + return; } + if(showpacket) + System.out.println("KLALB_TX:"+packet); + + ipv.setVersion(6); + ipv.setTrafficClass(0); + ipv.setFlowLabel(flowlabel); + ipv.setHopLimit(255); + ipv.setSourceAddress(self.getAddress()); + ipv.setDestinationAddress(addr); + ipv.setPriority(packet.getPriority()); + ipv.enableECN(); + ipv.setPayload(packet); + //System.out.println(ipv.getPayload().getProtocolNumber()); + /*System.out.println("SND:"+ipv.getPayload().getData()); + byte[]b=new byte[ipv.getPayload().getData().limit()]; + ipv.getPayload().getData().get(0, b); + System.out.println(Arrays.toString(b));*/ + //packet.getSendRecord().add(null); + packet.incSendCounter(); + }finally { + packet.getDisposeLock().unlock(); + } + packet.putTimePassport("packedInIPv6"); + packet.printPassport(); + ipv.putTimePassport("packed"); + srv6Router.putProtocolNumberPacketAndInsertSRH(ipv); + }); + } + + + private Map> bandwidthDistrmap=new ConcurrentHashMap<>(); + + private Lock bdmLock=new ReentrantLock(); + + protected Map> getBandwidthDistrmap() { + return bandwidthDistrmap; + } + + protected void registerDistUpdateConsumer(Inet6Address targetaAddress,PortPair portp, Consumer updateConsumer) { + if(updateConsumer==null) { + System.out.println("连接"+targetaAddress.getHostAddress()+" "+portp+" 释放带宽!"); + bdmLock.lock(); + try { + BandwidthDistributer bdr= bandwidthDistrmap.get(targetaAddress); + if(bdr!=null) { + bdr.setDistrUpdateConsumer(portp, updateConsumer); + bdr.setBandwidthRequest(portp, 0L); + if(bdr.getDistrUpdateConsumerMap().isEmpty()) { + bandwidthDistrmap.remove(targetaAddress); + } + } + }finally { + bdmLock.unlock(); + } + }else { + System.out.println("连接"+targetaAddress.getHostAddress()+" "+portp+" 申请带宽!"); + bdmLock.lock(); + try { + BandwidthDistributer bdr= bandwidthDistrmap.get(targetaAddress); + if(bdr==null) { + bandwidthDistrmap.put(targetaAddress, bdr=new BandwidthDistributer<>(1024*20000L*1024)); + } - }*/ + bdr.setDistrUpdateConsumer(portp, updateConsumer); + }finally { + bdmLock.unlock(); + } + } + } + + protected void updateBandwidthRequest(Inet6Address targetaAddress,PortPair portp,long bandwidth) { + if(bandwidth<0) { + throw new IllegalArgumentException(bandwidth+"<0"); + } + //System.out.println("连接"+targetaAddress.getHostAddress()+" "+portp+" 调整带宽到"+bandwidth/1024 +"KB/s!"); + BandwidthDistributer bdr= bandwidthDistrmap.get(targetaAddress); + + if(bdr!=null) { + bdr.setBandwidthRequest(portp, bandwidth); + }else { + throw new NullPointerException("连接"+targetaAddress.getHostAddress()+" "+portp+" 未申请带宽!"); + } + + } + + private Timer t=new Timer("数据包重传计时器", true); - public Timer getResendTimer() { + protected Timer getResendTimer() { return t; } private Timer t2=new Timer("数据包粘包计时器", true); diff --git a/src/org/kne/cloud/network/klalb/KLALBInputStream.java b/src/org/kne/cloud/network/klalb/KLALBInputStream.java index f22fd71..9a3f0d4 100644 --- a/src/org/kne/cloud/network/klalb/KLALBInputStream.java +++ b/src/org/kne/cloud/network/klalb/KLALBInputStream.java @@ -20,8 +20,8 @@ public class KLALBInputStream extends DataInputStream { } int bv=readInt(); int sv=readInt(); - if(bv!=2) - throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V2.0"); + if(bv!=CONST.bversion) + throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V"+CONST.klalbver); } public KLALBPacket readPacket() throws IOException { return KLALBPacket.readKLALBPacketFromStream(this); diff --git a/src/org/kne/cloud/network/klalb/KLALBMain.java b/src/org/kne/cloud/network/klalb/KLALBMain.java index 5c3d43e..8c43720 100644 --- a/src/org/kne/cloud/network/klalb/KLALBMain.java +++ b/src/org/kne/cloud/network/klalb/KLALBMain.java @@ -2,13 +2,34 @@ package org.kne.cloud.network.klalb; import java.io.File; import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.Scanner; + +import javax.swing.JFrame; + import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.SocketChannelListener; +import org.kne.cloud.network.SocketListener; +import org.kne.cloud.network.ipv6.RouteItem; +import org.kne.cloud.network.klalb.ui.KLALBStateGUI2; +import org.kne.cloud.network.klalb.ui.UIEnv; +import org.kne.cloud.network.perf.Kperf; +import org.kne.debug.Debuger; public class KLALBMain { public static KLALBStateGUI2 ksg; public static void main(String[] args) throws IOException { + try { + UIEnv.inituie(); + }catch(Exception e) { + + } System.out.println(CONST.klalb+" V"+CONST.klalbver); Scanner scn=new Scanner(System.in); @@ -16,31 +37,51 @@ public class KLALBMain { KLALBProxySystem kpcje=new KLALBProxySystem(); kpcje.loadConfigJson(configJson); - MultipurposeSocketAddress mpa=new MultipurposeSocketAddress("127.9.9.9", 49573); + System.out.println("SRv6地址:"+kpcje.getKlalbController().getSelf().getHostAddress()); + try { + openGUI(kpcje); + }catch(RuntimeException e) { + e.printStackTrace(); + } + /*MultipurposeSocketAddress mpa=new MultipurposeSocketAddress("127.9.9.9", 49573); kpcje.enableRemoteManagement(mpa); - System.out.println("远程管理端口已在"+mpa+"端口上开启"); + System.out.println("远程管理端口已在"+mpa+"端口上开启");*/ + /*if(true) + return;*/ + ServerSocketChannel kpsvr=KLALBVirtualServerSocketChannel.open(kpcje.getKlalbController()); + kpsvr.bind(new InetSocketAddress("::0", 4564)); + SocketChannelListener stlr=new SocketChannelListener(kpsvr); + stlr.setCon((scl)->{ + try { + new Kperf(new StreamChannelKLALBPacketLink(scl)).startPerfing(); + } catch (IOException e) { + e.printStackTrace(); + } + }); while(true) { - String s=scn.next(); - String[]sc=s.split(" "); + try { + String s=scn.nextLine(); + String[]sc=s.trim().split(" "); switch(sc[0]) { case "?": case "help": System.out.println("help:查看命令使用说明"); - System.out.println("state:查看线路状态"); - //System.out.println("reload:重新加载线路配置文件"); - System.out.println("reconnect:所有离线线路跳过重连等待时间立即尝试重连"); System.out.println("monitor:显示监视器图形界面"); + System.out.println("lines-state:查看线路状态"); + System.out.println("lines-add <地址:端口>:添加线路"); + System.out.println("lines-remove <地址:端口>:删除线路"); + System.out.println("lines-reconnect:所有离线线路立即尝试重连"); + System.out.println("route:显示路由表"); + System.out.println("kperf <地址:端口>:网络性能测试"); System.out.println("stop:退出程序"); - break; case "monitor": - if(ksg==null) - ksg=kpcje.getKLALBGUI(); - ksg.setVisible(true); + openGUI(kpcje); break; - case "state": - System.out.println("状态\t可靠性\t上传流量\t下载流量\t上传速度\t下载速度\t上传延迟\t下载延迟\t上传抖动\t下载抖动"); + case "lines-state": + System.out.println("线路状态:"); + System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t上传延迟\t下载延迟\t上传抖动\t下载抖动"); synchronized (kpcje.getKlalbController().getLines()) { for (Iterator iterator = kpcje.getKlalbController().getLines().iterator(); iterator.hasNext();) { KLALBRemoteLine hostPort = iterator.next(); @@ -49,17 +90,90 @@ public class KLALBMain { } } break; + case "lines-add": + if(sc.length>=2) { + MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(sc[1]); + Listaddl=kpcje.getKlalbController().addRemoteLines(mpsa); + if(addl.isEmpty()) { + System.out.println("添加失败,线路已存在!"); + }else { + for (Iterator iterator = addl.iterator(); iterator.hasNext();) { + KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next(); + + System.out.println("添加成功:"+klalbRemoteLine.getMonitor().getName()); + } + } + }else { + System.out.println("请输入要添加地址:端口!"); + } + break; + case "lines-remove": + if(sc.length>=2) { + MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(sc[1]); + Listrmvl=kpcje.getKlalbController().removeRemoteLines(mpsa); + if(rmvl.isEmpty()) { + System.out.println("未找到匹配移除项"); + }else { + for (Iterator iterator = rmvl.iterator(); iterator.hasNext();) { + KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next(); + + System.out.println("移除成功:"+klalbRemoteLine.getMonitor().getName()); + } + } + }else { + System.out.println("请输入要添加地址:端口!"); + } + break; case "stop": + System.out.println("已退出程序"); System.exit(0); break; - case "reconnect": + case "lines-reconnect": + System.out.println("尝试重连断开的线路"); kpcje.getKlalbController().reconnectImmediately(); break; + case "route": + List lri=new ArrayList<>( kpcje.getKlalbController().getIpv6Router().getCurrentRouteTabel()); + Collections.sort(lri); + System.out.println("路由表:"); + System.out.println("前缀\t协议\t优先级\t开销\t标志\t下一跳\t接口"); + for (Iterator iterator = lri.iterator(); iterator.hasNext();) { + RouteItem routeItem = (RouteItem) iterator.next(); + System.out.println(routeItem.getDestination()+"\t"+routeItem.getProto()+"\t"+routeItem.getPre()+"\t"+routeItem.getCost()+"\t"+routeItem.getFlag()+"\t"+routeItem.getNexthop().getHostAddress()+"\t"+routeItem.getDestlink().getName()); + } + + break; + case "kperf": + if(sc.length>=2) { + MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(sc[1]); + Kperf kp=new Kperf(mpsa); + kp.startPerfing(); + }else { + System.out.println("请输入测速服务端地址:端口!"); + } + + break; + //case "$$SYSTEM:": + //System.out.println(); + //break; default: System.out.println("未知命令,请输入help以查询命令说明"); } + }catch(RuntimeException e) { + System.out.println("错误!"); + e.printStackTrace(); + } } } + private static void openGUI(KLALBProxySystem kpcje) throws RuntimeException{ + /*JFrame jf=new JFrame(); + jf.setSize(200, 200); + jf.setVisible(true);*/ + if(ksg==null) + ksg=kpcje.getKLALBGUI(); + ksg.setVisible(true); + //System.out.println("UI loaded"); + } } diff --git a/src/org/kne/cloud/network/klalb/KLALBOutputStream.java b/src/org/kne/cloud/network/klalb/KLALBOutputStream.java index 3fcb13b..3dbf0f4 100644 --- a/src/org/kne/cloud/network/klalb/KLALBOutputStream.java +++ b/src/org/kne/cloud/network/klalb/KLALBOutputStream.java @@ -11,8 +11,8 @@ public class KLALBOutputStream extends DataOutputStream { super(out); byte[]b=new byte[] {'K','L','A','L','B'}; write(b); - writeInt(2); - writeInt(1); + writeInt(CONST.bversion); + writeInt(CONST.sversion); flush(); } public void writePacket(KLALBPacket klb) throws IOException { diff --git a/src/org/kne/cloud/network/klalb/KLALBPacket.java b/src/org/kne/cloud/network/klalb/KLALBPacket.java index 13b2715..d5c7302 100644 --- a/src/org/kne/cloud/network/klalb/KLALBPacket.java +++ b/src/org/kne/cloud/network/klalb/KLALBPacket.java @@ -1,26 +1,25 @@ package org.kne.cloud.network.klalb; -import java.io.DataInput; import java.io.DataInputStream; -import java.io.DataOutput; import java.io.DataOutputStream; import java.io.EOFException; -import java.io.Externalizable; import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; -import java.io.StreamCorruptedException; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.util.ArrayList; import java.util.List; -import java.util.Vector; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; -public abstract class KLALBPacket implements Comparable{ +import org.kne.cloud.network.NetworkPacket; +import org.kne.cloud.network.ipv6.IPv6Packet; + +public abstract class KLALBPacket extends IPv6Packet.IPv6Payload { + public static final int KLALB_PROTOCOL_NUMBER=254; + + public static final int PING=0; public static final int PONG=1; public static final int BWINF=2; @@ -36,139 +35,112 @@ public abstract class KLALBPacket implements Comparable{ public static final int TEST=11; public static final int VADDRACK=12; public static final int VADDRREQ=13; - + public static final int IPV6OVERKLALB=14; + public static final int ADDR=15; + public static final int ADDRREQ=16; - private static final int HEADER_CAPACITY = 32; - public static final ByteBufferPool headerbufferpool=new ByteBufferPool(1000, HEADER_CAPACITY); - public static final ByteBufferPool databufferpool=new ByteBufferPool(1000, 65535); + //private static final int HEADER_CAPACITY = 32; + + private int headerLength=1; //public static final ByteArrayPool dataarraypool=new ByteArrayPool(5000, 8192); - protected volatile ByteBuffer header; + protected volatile ByteBuffer klalbHeader; - - - protected KLALBPacket(ByteBuffer header) { - super(); - this.header = header; + protected KLALBPacket(ByteBuffer klalbHeader,int headerLength) { + super(KLALB_PROTOCOL_NUMBER,false); + this.klalbHeader = klalbHeader; + this.headerLength=headerLength; } - public KLALBPacket(int type) { - super(); - header=headerbufferpool.borrow(); - header.put((byte) type); + public KLALBPacket(int type,int headerLength) { + super(KLALB_PROTOCOL_NUMBER,false); + klalbHeader=ByteBuffer.allocate(headerLength); + klalbHeader.put((byte) type); + this.headerLength=headerLength; } - public KLALBPacket(int type, long priority) { - this(type); - this.priority=priority; + public KLALBPacket(int type,int headerLength, long priority) { + this(type,headerLength); + setPriority(priority); } @Override public String toString() { return "KLALBPacket [type=" + getType() + "]"; } public int getType() { - return header.get(0)&0xff; + return klalbHeader.get(0)&0xff; } private long sndtime,rcvtime; + private long joinqueuetime; - - protected void writeToChannel(WritableByteChannel dto) throws IOException { - sndtime=System.nanoTime(); - dto.write(header.slice(0, getHeaderSize())); + public void markJoinqueuetime() { + joinqueuetime=System.nanoTime(); } - protected void readFromChannel(ReadableByteChannel din) throws IOException { - rcvtime=System.nanoTime(); - header.limit(getHeaderSize()); - while(header.hasRemaining()){ - if(din.read(header)==-1) { + public long getJoinqueuetime() { + return joinqueuetime; + } + + protected void writeToChannel(WritableByteChannel dto) throws IOException { + sndtime=System.nanoTime(); + dto.write(klalbHeader.slice(0, headerLength)); + } + + @Override + protected boolean needEndPosition() { + return false; + } + + protected void readFromChannel(ReadableByteChannel din,long length) throws IOException { + klalbHeader.limit(headerLength); + while(klalbHeader.hasRemaining()){ + if(din.read(klalbHeader)==-1) { throw new EOFException(); } } + rcvtime=System.nanoTime(); } - protected int getHeaderSize() { - return 1; - } public long getSndtime() { return sndtime; } public long getRcvtime() { return rcvtime; } - public long getLength() { - return getHeaderSize(); + public long getLength() {//缓冲区limit,实际长度 + return headerLength; } - public long getPriority() { - return priority; - } - public void setPriority(long priority) { - this.priority = priority; - } - public long getSendseq() { - return sendseq; - } + + + //private List sendRecord=new ArrayList<>(2); + + private AtomicInteger sendCounter=new AtomicInteger(0); - private long priority; - private long sendseq; - private static final AtomicLong seqgen=new AtomicLong(); - - @Override - public int compareTo(KLALBPacket o) { - if(priority>o.priority) { - return 1; - }else if(priorityo.sendseq) { - return 1; - }else if(sendseq sendRecord=new ArrayList<>(2); - private volatile boolean disposed; - private volatile ReentrantLock disposeLock=new ReentrantLock(); - public boolean isDisposed() { - return disposed; - } - - public List getSendRecord() { + /*public List getSendRecord() { return sendRecord; - } + }*/ - - - public ReentrantLock getDisposeLock() { - return disposeLock; - } - protected ByteBuffer getHeader() { - return header; + protected ByteBuffer getKLALBHeader() { + return klalbHeader; } public void dispose() { - disposeLock.lock(); - try { - disposed=true; - }finally { - disposeLock.unlock(); - } - ByteBuffer headerx=header; - header=null; - KLALBPacket.headerbufferpool.back(headerx); + super.dispose(); + /* ByteBuffer datax=klalbHeader; + klalbHeader=null; + if(datax!=null) + KLALBPacket.databufferpool_40.back(datax);*/ } public static KLALBPacket readKLALBPacketFromStream(DataInputStream in) throws IOException { @@ -176,7 +148,8 @@ public abstract class KLALBPacket implements Comparable{ } public static KLALBPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException { - ByteBuffer bb=headerbufferpool.borrow(); + while(true) { + ByteBuffer bb=databufferpool_40.borrow(); bb.limit(1); while(bb.hasRemaining()){ if(in.read(bb)==-1) { @@ -235,8 +208,22 @@ public abstract class KLALBPacket implements Comparable{ klp=new VADDRREQPacket(bb); klp.readFromChannel(in); return klp; + case IPV6OVERKLALB: + klp=new IPv6OverKLALBPacket(bb); + klp.readFromChannel(in); + return klp; + case ADDR: + klp=new ADDRPacket(bb); + klp.readFromChannel(in); + return klp; + case ADDRREQ: + klp=new ADDRREQPacket(bb); + klp.readFromChannel(in); + return klp; } - throw new StreamCorruptedException("unknown package type:"+type); + //throw new StreamCorruptedException("unknown package type:"+type); + System.err.println("ignore unknown KLALBPacket type:"+type); + } } public static void writeKLALBPacketToStream(DataOutputStream out,KLALBPacket klb) throws IOException { @@ -245,4 +232,20 @@ public abstract class KLALBPacket implements Comparable{ public static void writeKLALBPacketToChannel(WritableByteChannel writableByteChannel,KLALBPacket klb) throws IOException { klb.writeToChannel(writableByteChannel); } + + public static KLALBPacket createByBuffer(ByteBuffer data) { + return null; + } + + public void doDisposeAfterSend() { + if(isDisposeAfterSend()) + dispose(); + } + private boolean ce=false; + public void setCE(boolean ce) { + this.ce=ce; + } + public boolean isCE() { + return ce; + } } diff --git a/src/org/kne/cloud/network/klalb/KLALBPacketConsumer.java b/src/org/kne/cloud/network/klalb/KLALBPacketConsumer.java index 4021a84..592890c 100644 --- a/src/org/kne/cloud/network/klalb/KLALBPacketConsumer.java +++ b/src/org/kne/cloud/network/klalb/KLALBPacketConsumer.java @@ -1,7 +1,9 @@ package org.kne.cloud.network.klalb; +import java.net.Inet6Address; import java.util.function.BiConsumer; +import java.util.function.Consumer; -public interface KLALBPacketConsumer extends BiConsumer { +public interface KLALBPacketConsumer extends BiConsumer { } diff --git a/src/org/kne/cloud/network/klalb/KLALBPacketLink.java b/src/org/kne/cloud/network/klalb/KLALBPacketLink.java index 03ae356..4c64269 100644 --- a/src/org/kne/cloud/network/klalb/KLALBPacketLink.java +++ b/src/org/kne/cloud/network/klalb/KLALBPacketLink.java @@ -3,6 +3,8 @@ package org.kne.cloud.network.klalb; import java.io.IOException; import java.net.SocketException; +import org.kne.cloud.network.MultipurposeSocketAddress; + public interface KLALBPacketLink { public void writePacket(KLALBPacket kp) throws IOException; public void flush() throws IOException; diff --git a/src/org/kne/cloud/network/klalb/KLALBProxySystem.java b/src/org/kne/cloud/network/klalb/KLALBProxySystem.java index 63ffb87..cdeda37 100644 --- a/src/org/kne/cloud/network/klalb/KLALBProxySystem.java +++ b/src/org/kne/cloud/network/klalb/KLALBProxySystem.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.Reader; import java.net.Inet6Address; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; @@ -19,6 +20,7 @@ import java.util.Map; import java.util.Map.Entry; import org.kne.cloud.network.*; +import org.kne.cloud.network.klalb.ui.KLALBStateGUI2; import org.kne.cloud.network.minecraft.MinecraftSocketBridge; import java.util.Set; @@ -109,6 +111,7 @@ public class KLALBProxySystem { switch (entry.get("Type").getAsString()) { case "KLALBController": JsonElement vase= entry.get("VirtualAddress"); + //System.out.println(vase); if(vase!=null) { try { klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString())); @@ -141,7 +144,8 @@ public class KLALBProxySystem { } }); - klalbController.getListenSocketAddress().add(mpsa); + MultipurposeSocketAddress mpsa2=new MultipurposeSocketAddress(mpsa.getType(), mpsa.getHost(),((InetSocketAddress)tcpl.getServerSocketChannel().getLocalAddress()).getPort()); + klalbController.getListenSocketAddress().add(mpsa2); } catch (IOException e1) { e1.printStackTrace(); } @@ -164,7 +168,8 @@ public class KLALBProxySystem { } }); - //klalbController.getListenSocketAddress().add(mpsa); + MultipurposeSocketAddress mpsau2=new MultipurposeSocketAddress(mpsa.getType(), mpsa.getHost(),((InetSocketAddress)(udpl.getDatagramServerSocket().getLocalSocketAddress())).getPort()); + //klalbController.getListenSocketAddress().add(mpsau2); } catch (IOException e1) { e1.printStackTrace(); } @@ -181,13 +186,7 @@ public class KLALBProxySystem { if(linetoc!=null) { JsonArray jary=(JsonArray)linetoc; jary.forEach((aline)->{ - try { - klalbController.addRemoteLines(new MultipurposeSocketAddress(aline.getAsString())); - } catch (SocketTimeoutException e) { - e.printStackTrace(); - } catch (SocketException e) { - e.printStackTrace(); - } + klalbController.addRemoteLines(new MultipurposeSocketAddress(aline.getAsString())); }); } break; diff --git a/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java b/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java index c379d9f..8561b68 100644 --- a/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java +++ b/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java @@ -5,55 +5,50 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; -import java.io.PrintWriter; -import java.net.BindException; import java.net.Inet6Address; import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; import java.net.SocketTimeoutException; import java.nio.channels.UnresolvedAddressException; -import java.time.Clock; +import java.security.SecureRandom; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.PriorityQueue; -import java.util.UUID; -import java.util.Vector; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; -import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; -import javax.management.monitor.Monitor; - import org.kne.cloud.clock.AdjustedNanoClock; -import org.kne.cloud.clock.ExponentialBackoffTimeClock; import org.kne.cloud.clock.ReliabilityBackoffTimeClock; import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.SpeedLimiter; import org.kne.cloud.network.ThreadTool; +import org.kne.cloud.network.ipv6.IPv6NetworkLink; +import org.kne.cloud.network.ipv6.IPv6Packet; +import org.kne.cloud.network.ipv6.Inet6AddressGroup; +import org.kne.cloud.network.ipv6.Neighbor; import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.QueueingMonitorDataImpl; import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; -import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl; -import org.kne.debug.TimeDebugger; +import org.kne.cloud.network.te.LoadingBalanceEntry; -public class KLALBRemoteLine implements Comparable { +public class KLALBRemoteLine implements IPv6NetworkLink,Comparable ,LoadingBalanceEntry{ - private static final boolean debug = true; + private static final boolean debug = false; private static final boolean showpacket = false; private ReliabilityBackoffTimeClock coll = new ReliabilityBackoffTimeClock(); private volatile boolean closed = false; - private volatile Supplier localVaddrSupplier; + private volatile Supplier localVaddrSupplier; private volatile KLALBController klalbController; @@ -64,21 +59,21 @@ public class KLALBRemoteLine implements Comparable { public void setKlalbController(KLALBController klalbController) { this.klalbController = klalbController; if (klalbController != null && remoteVaddr != null) { - adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr); + adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress()); } } - public Supplier getLocalVaddrSupplier() { + public Supplier getLocalVaddrSupplier() { return localVaddrSupplier; } - public void setLocalVaddrSupplier(Supplier localVaddrSupplier) { + public void setLocalVaddrSupplier(Supplier localVaddrSupplier) { this.localVaddrSupplier = localVaddrSupplier; } - private volatile Inet6Address remoteVaddr; + private volatile Inet6AddressGroup remoteVaddr; - public Inet6Address getRemoteVaddr() { + public Inet6AddressGroup getRemoteVaddr() { return remoteVaddr; } @@ -98,7 +93,7 @@ public class KLALBRemoteLine implements Comparable { } } - public SpeedAndTrafficAndDelayMonitorDataImpl getMonitor() { + public QueueingMonitorDataImpl getMonitor() { return monitor; } @@ -106,7 +101,7 @@ public class KLALBRemoteLine implements Comparable { return remoteVaddr + "\t" + monitor.toString(); } - private SpeedAndTrafficAndDelayMonitorDataImpl monitor; + private QueueingMonitorDataImpl monitor; private volatile KLALBPacketLink kplink; private MultipurposeSocketAddress bindAddress; private MultipurposeSocketAddress socketAddress; @@ -129,56 +124,43 @@ public class KLALBRemoteLine implements Comparable { return bindAddress; } - protected static KLALBPacketLink createLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress mpa) - throws IOException { - if (mpa.isStream()) { - if (mpa.supportNIO()) { - if (bindAddress != null) { - return new StreamChannelKLALBPacketLink(mpa - .connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort())); - } else { - return new StreamChannelKLALBPacketLink(mpa.connectSocketChannel()); - } - } else { - if (bindAddress != null) { - return new StreamKLALBPacketLink( - mpa.connectSocket(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort())); - } else { - return new StreamKLALBPacketLink(mpa.connectSocket()); - } - } - } else { - if (bindAddress != null) { - return new SplitedDatagramKLALBPacketLink( - mpa.connectDatagramSocket(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort())); - } else { - return new SplitedDatagramKLALBPacketLink(mpa.connectDatagramSocket()); - } - } + private Inet6AddressGroup addressGroup; + private Inet6AddressGroup peerAddress; + @Override + public Inet6AddressGroup getAddressGroup() { + return addressGroup; + } + + public Inet6AddressGroup getPeerAddress() { + return peerAddress; } - public KLALBRemoteLine(MultipurposeSocketAddress mpa) { - this(mpa, new SpeedAndTrafficAndDelayMonitorDataImpl()); + + + public KLALBRemoteLine(MultipurposeSocketAddress mpa, Inet6AddressGroup address) { + this(mpa,address, new QueueingMonitorDataImpl()); } - public KLALBRemoteLine(MultipurposeSocketAddress mpa, SpeedAndTrafficAndDelayMonitorDataImpl monitor) { - this(mpa, null, monitor); + public KLALBRemoteLine(MultipurposeSocketAddress mpa, Inet6AddressGroup address, QueueingMonitorDataImpl monitor) { + this(mpa, null,address, monitor); } - public KLALBRemoteLine(KLALBPacketLink kpl) { - this(kpl, new SpeedAndTrafficAndDelayMonitorDataImpl()); + public KLALBRemoteLine(KLALBPacketLink kpl, Inet6AddressGroup address) { + this(kpl,address, new QueueingMonitorDataImpl()); } - public KLALBRemoteLine(KLALBPacketLink kpl, SpeedAndTrafficAndDelayMonitorDataImpl monitor) { + public KLALBRemoteLine(KLALBPacketLink kpl, Inet6AddressGroup address,QueueingMonitorDataImpl monitor) { this.kplink = kpl; + this.addressGroup=address; this.monitor = monitor; monitor.setName(kpl.toString()); } - public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr, - SpeedAndTrafficAndDelayMonitorDataImpl monitor) { + public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr,Inet6AddressGroup address, + QueueingMonitorDataImpl monitor) { this.socketAddress = mpa; this.bindAddress = bindaddr; + this.addressGroup=address; this.monitor = monitor; if (bindaddr == null) { monitor.setName("→" + mpa.toString()); @@ -187,8 +169,20 @@ public class KLALBRemoteLine implements Comparable { } } - public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr) { - this(mpa, bindaddr, new SpeedAndTrafficAndDelayMonitorDataImpl()); + public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr, Inet6AddressGroup address) { + this(mpa, bindaddr,address, new QueueingMonitorDataImpl()); + } + + public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bind) { + this(mpa, bind, null); + } + + public KLALBRemoteLine(MultipurposeSocketAddress mpa) { + this(mpa,(Inet6AddressGroup)null); + } + + public KLALBRemoteLine(KLALBPacketLink link) { + this(link, (Inet6AddressGroup)null); } PrintStream pw; @@ -225,13 +219,15 @@ public class KLALBRemoteLine implements Comparable { e.printStackTrace(); } } - - private SpeedLimiter congress = new SpeedLimiter(); + + private static long MIN_SPEED=256*1024L; + private SpeedLimiter congress = new SpeedLimiter(MIN_SPEED,10000000L); private long congressSpeed = 0; - private double increaceFactor = 1.2; + private double loadPercent = 1.01; protected void startIO() { ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> { + //Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1); while (true) { try { @@ -241,13 +237,34 @@ public class KLALBRemoteLine implements Comparable { close(); break; } + if(addressGroup==null) { + byte[]addr=new byte[16]; + SecureRandom scr=new SecureRandom(); + scr.nextBytes(addr); + addr[0]=(byte)0x24; + addr[1]=(byte) 0x86; + addr[2]=0; + addr[3]=2; + addr[14]=0; + addr[15]=1; + Inet6Address i6a=(Inet6Address) Inet6Address.getByAddress(addr); + addressGroup=new Inet6AddressGroup(i6a, 112); + } } else { - kplink = createLink(bindAddress, socketAddress); + kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress); } - startRecord(); - kplink.setSoTimeout(10000); + //startRecord(); + kplink.setSoTimeout(20000); Thread t = ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> { + tlock = Thread.currentThread(); + //tlock.setPriority(Thread.NORM_PRIORITY+1); try { + writePacketToKPL(new ADDRREQPacket()); + writePacketToKPL(new ADDRREQPacket()); + if(addressGroup!=null) { + writePacketToKPL(new ADDRPacket(addressGroup)); + writePacketToKPL(new ADDRPacket(addressGroup)); + } writePacketToKPL(new VADDRREQPacket()); writePacketToKPL(new VADDRREQPacket()); writePacketToKPL(new VADDRPacket(localVaddrSupplier.get())); @@ -257,20 +274,22 @@ public class KLALBRemoteLine implements Comparable { while ((!kplink.isClosed()) && (!closed)) { // TimeDebugger tdb=new TimeDebugger(); // tdb.putTime("start"); - - boolean flsh = false; - if (checkPingTime()) { + if(checkBandwidthReportTime()) { + sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg2(), monitor.getInSpeedAvg2())); + } + if (checkPingTimeSleep()) { writePacketToKPL(new PINGPacket(System.nanoTime())); if (remoteVaddr == null) writePacketToKPL(new VADDRREQPacket()); - monitor.updateSpeedSync(); - flsh = true; - } + if(peerAddress==null) + writePacketToKPL(new ADDRREQPacket()); + + }else { KLALBPacket kpip = IsendDequeList.poll(); if (kpip != null) { writePacketToKPL(kpip); - flsh = true; - } + + }else { // tdb.putTime("Isend"); @@ -278,32 +297,45 @@ public class KLALBRemoteLine implements Comparable { do { kpp = sendDequeList.poll(); } while (kpp != null && kpp.isDisposed()); + if(kpp==null) { + monitor.setQueueingDelay(0); + } } // System.out.println(sendDequeList.size()); if (kpp != null) { - kpp.getDisposeLock().lock(); + // TimeDebugger tdb=new TimeDebugger(); + //tdb.putTime("start"); + KLALBPacket kppt=kpp; + kppt.lockAll(); try { - if (kpp.isDisposed()) { - kpp.getDisposeLock().unlock(); + if (kpp.isSomeDisposed()) { kpp = null; } else { - if (congress.checkTransmit(kpp.getLength())) { - + // if (congress.checkTransmit(length)) { + writePacketToKPL(kpp); - if (kpp instanceof DATATPacket) { - resetSleepTimer(); + if (checkPingTime()) { + writePacketToKPL(new PINGPacket(System.nanoTime())); } - flsh = true; - kpp.getDisposeLock().unlock(); + monitor.setQueueingDelay( System.nanoTime()- kpp.getJoinqueuetime()); + /*if (kpp instanceof DATATPacket||kpp instanceof IPv6OverKLALBPacket) { + resetSleepTimer(); + }*/ + kpp.doDisposeAfterSend(); kpp = null; } - } + //} } finally { - if(kpp!=null) - kpp.getDisposeLock().unlock(); + kppt.unlockAll(); } + //tdb.putTime("sendToLink"); + //tdb.print(); + }else { + LockSupport.parkNanos(1000000); } - if (flsh) { + } + } + /*if (flsh) { flushKPL(); } else { @@ -320,7 +352,7 @@ public class KLALBRemoteLine implements Comparable { } // tdb.putTime("park"); - } + }*/ // tdb.print(); // System.out.println(sendDequeList.isEmpty()); @@ -343,26 +375,26 @@ public class KLALBRemoteLine implements Comparable { while ((!kplink.isClosed()) && (!closed)) { long readStart = System.nanoTime(); KLALBPacket kpp = readPacketFromKPL(); - long readTime = System.nanoTime() - readStart; + /*long readTime = System.nanoTime() - readStart; readTime *= 10; if (readTime > stime) { stime = readTime; } else { - stime = (stime * 99 + readTime) / 100; + stime = (stime * 999 + readTime) / 1000; } if (stime < 2000000000L) { stime = 2000000000L; - } + }*/ // System.out.println(readTime); - // kplink.setSoTimeout(5000); + kplink.setSoTimeout(3000); kplink.setSoTimeout((int) (stime / 1000000)); - if (kpp == null) + if (kpp == null) { break; + } switch (kpp.getType()) { case KLALBPacket.PING: sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime())); - sendIPacket(new BWINFPacket(monitor.getOutSpeed(), monitor.getInSpeed())); break; case KLALBPacket.PONG: PONGPacket png = (PONGPacket) kpp; @@ -401,10 +433,10 @@ public class KLALBRemoteLine implements Comparable { monitor.setOutDelay(DsndDelayFactor); monitor.setInDelay(DrcvDelayFactor); monitor.setRecentPingNanoTime(png.getTimepingsnd()); - pingInterval = monitor.getOutDelayMin(); + //pingInterval = monitor.getLatencyAvg()+2000000L; - double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay(); - increaceFactor =Math.max( 2.0 - load*2,1.0); + //double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay(); + loadPercent =Math.max( 1.2,0.4); } LockSupport.unpark(tlock); @@ -416,19 +448,32 @@ public class KLALBRemoteLine implements Comparable { } else { congressSpeed = (congressSpeed * 999 + bwi.getDownSpeed()) / 1000; } - congress.setLimitspeed((long) (congressSpeed * increaceFactor) + 32768); + congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) ); // System.out.println(congressSpeed); break; + case KLALBPacket.ADDRREQ: + if(addressGroup!=null) + sendIPacket(new ADDRPacket(addressGroup)); + break; + case KLALBPacket.ADDR: + peerAddress = ((ADDRPacket) kpp).getAddr(); + if(addressGroup==null) { + byte[]ab=peerAddress.getAddress().getAddress(); + ab[15]=2; + Inet6AddressGroup ardg2=new Inet6AddressGroup((Inet6Address) InetAddress.getByAddress(ab),peerAddress.getPrefixLength()); + addressGroup=ardg2; + } + break; case KLALBPacket.VADDRREQ: sendIPacket(new VADDRPacket(localVaddrSupplier.get())); break; case KLALBPacket.VADDR: - Inet6Address vdr = ((VADDRPacket) kpp).getVaddr(); + Inet6AddressGroup vdr = ((VADDRPacket) kpp).getVaddr(); remoteVaddr = vdr; sendIPacket(new VADDRACKPacket()); if (klalbController != null) { - adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr); + adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress()); } if (fst) { // coll.resetCoolingTime(); @@ -440,11 +485,21 @@ public class KLALBRemoteLine implements Comparable { break; case KLALBPacket.TEST: break; + case KLALBPacket.IPV6OVERKLALB: + if(ipv6con!=null) { + IPv6OverKLALBPacket ivk=(IPv6OverKLALBPacket) kpp; + IPv6Packet iv6= ivk.getIPv6Packet(); + ivk.putTimePassport("unpacked"); + ivk.printPassport(); + iv6.putTimePassport("unpackFromLink"); + ipv6con.accept(iv6); + } + break; default: while (rec == null) { Thread.sleep(1); } - rec.accept(KLALBRemoteLine.this, kpp); + rec.accept( kpp); break; } Thread.yield(); @@ -463,17 +518,17 @@ public class KLALBRemoteLine implements Comparable { } catch (IOException e) { e.printStackTrace(); } - KLALBPacket pack; + /*KLALBPacket pack; while((pack=sendDequeList.poll())!=null) { try { if(remoteVaddr!=null) { - klalbController.sendPacketToAddress(remoteVaddr, pack); + klalbController.sendPacketToLinkAddress(remoteVaddr, pack); if(debug) System.out.println("RETRY:"+pack); } } catch (IOException e) { } - } + }*/ } if (closed) { @@ -499,29 +554,56 @@ public class KLALBRemoteLine implements Comparable { if (showpacket) { if (!(packet instanceof PINGPacket)) if (!(packet instanceof PONGPacket)) + if (!(packet instanceof BWINFPacket)) System.out.println("RX:" + packet); } if (packet != null) { - monitor.getInTrafficAL().addAndGet(packet.getLength()); + packet.putTimePassport("received"); + long length=packet.getLength(); + monitor.getInTrafficAL().addAndGet(length); + monitor.getInPacketCounterAL().incrementAndGet(); if (klalbController != null) - klalbController.getLinkMonitor().getInTrafficAL().addAndGet(packet.getLength()); + klalbController.getLinkMonitor().getInTrafficAL().addAndGet(length); + klalbController.getLinkMonitor().getInPacketCounterAL().incrementAndGet(); } return packet; } private void writePacketToKPL(KLALBPacket packet) throws IOException { - monitor.getOutTrafficAL().addAndGet(packet.getLength()); + long length=packet.getLength(); + monitor.getOutTrafficAL().addAndGet(length); + monitor.getOutPacketCounterAL().incrementAndGet(); if (klalbController != null) - klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(packet.getLength()); + klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length); + klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet(); + kplink.writePacket(packet); + packet.putTimePassport("sended"); + packet.printPassport(); + + if (showpacket) { + if (!(packet instanceof PINGPacket)) + if (!(packet instanceof PONGPacket)) + if (!(packet instanceof BWINFPacket)) + System.err.println("TX:" + packet); + } + } + + private void writePacketToKPL(KLALBPacket packet,long length) throws IOException { + monitor.getOutTrafficAL().addAndGet(length); + monitor.getOutPacketCounterAL().incrementAndGet(); + if (klalbController != null) + klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length); + klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet(); kplink.writePacket(packet); if (showpacket) { if (!(packet instanceof PINGPacket)) if (!(packet instanceof PONGPacket)) + if (!(packet instanceof BWINFPacket)) System.err.println("TX:" + packet); } } - + public void close() { closed = true; monitor.setState(MonitorData.OFFLINE); @@ -538,28 +620,48 @@ public class KLALBRemoteLine implements Comparable { return closed; } - private volatile long timeTurnSleep = System.nanoTime(); - private volatile long time = System.nanoTime(); - private volatile long pingInterval = 50000000L; + private volatile long pingInterval = 10000000L; private volatile long pingIntervalSleep = 200000000L; - private void resetSleepTimer() { - timeTurnSleep = System.nanoTime(); - } - private boolean checkPingTime() { long cu = System.nanoTime(); - if (cu - time > ((System.nanoTime() - timeTurnSleep > 500000000) ? pingIntervalSleep - : Math.min(pingIntervalSleep, pingInterval))) { - time = cu; - return true; - } else { - return false; - } + if (cu - time > pingInterval) { + time = cu; + return true; + } else { + return false; + } + } - private volatile BiConsumer rec; + private boolean checkPingTimeSleep() { + long cu = System.nanoTime(); + if (cu - time > pingIntervalSleep) { + time = cu; + return true; + } else { + return false; + } + + } + + + private volatile long bwtime = System.nanoTime(); + private volatile long bwpingInterval = 10000000L; + private volatile long bwpingIntervalSleep = 100000000L; + private boolean checkBandwidthReportTime(){ + long cu = System.nanoTime(); + if (cu - bwtime > bwpingIntervalSleep) { + bwtime = cu; + return true; + } else { + return false; + } + + } + + private volatile Consumer rec; private volatile Thread tlock; @@ -572,6 +674,7 @@ public class KLALBRemoteLine implements Comparable { } protected void sendPacket(KLALBPacket blk) { + blk.markJoinqueuetime(); sendDequeList.add(blk); LockSupport.unpark(tlock); } @@ -581,7 +684,7 @@ public class KLALBRemoteLine implements Comparable { LockSupport.unpark(tlock); } - public void setPacketReceiver(BiConsumer rec) { + public void setPacketReceiver(Consumer< KLALBPacket> rec) { this.rec = rec; } @@ -641,7 +744,7 @@ public class KLALBRemoteLine implements Comparable { } } - private static final TESTPacket testPacket = new TESTPacket(); + private static final TESTPacket testPacket = new TESTPacket(60000); private volatile boolean pressure = false; private SpeedLimiter pressureSpeed = new SpeedLimiter(32768); @@ -671,4 +774,111 @@ public class KLALBRemoteLine implements Comparable { return predictTime; } + private Listranks=new ArrayList(); + + private Consumer ipv6con; + @Override + public void noticeRank(int rank) { + while(rank>=ranks.size()) { + ranks.add(0.5); + } + for (int i = 0; i < ranks.size(); i++) { + if(i==rank) { + ranks.set(i, (ranks.get(i)*99.0+1.0D)/100.0); + }else { + ranks.set(i, ranks.get(i)*99.0/100.0); + } + } + } + + @Override + public double getWeightAtRank(int rank) { + while(rank>=ranks.size()) { + ranks.add(0.5); + } + return ranks.get(rank); + } + + public List getRanks() { + + return ranks; + } + + @Override + public boolean isLoopBack() { + return false; + } + + @Override + public List getNeighborsInfo() { + Lisths=new ArrayList<>(); + if(peerAddress!=null) { + hs.add(new Neighbor(peerAddress, remoteVaddr, monitor)); + //System.out.println(peerAddress+" "+addressGroup); + } + return hs; + } + + + + + + @Override + public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException { + pack.lockAll(); + try { + if(pack.isSomeDisposed()) { + return; + } + if(inet6Address.equals(remoteVaddr.getAddress())||inet6Address.equals(peerAddress.getAddress())) { + IPv6OverKLALBPacket kipv6=new IPv6OverKLALBPacket(pack); + kipv6.setPriority(pack.getPriority()); + kipv6.setDisposeAfterSend(true); + pack.putTimePassport("packdInLink"); + pack.printPassport(); + sendPacketToLink(kipv6); + } + }finally { + pack.unlockAll(); + } + } + + private void sendPacketToLink(KLALBPacket packet) { + packet.genseq(); + //packet.getSendRecord().add(this); + sendPacket(packet); + } + + @Override + public boolean isCongress(IPv6Packet iPv6Packet) { + int size=getQueue().size(); + if(size>30) { + return true; + }else { + return !congress.checkTransmit(iPv6Packet.getLength()); + } + } + + @Override + public String getName() { + return monitor.getName(); + } + + @Override + public boolean isUp() { + return (!isClosed())&&getMonitor().getState()==MonitorData.ONLINE; + } + + @Override + public boolean canSend(IPv6Packet iPv6Packet) { + return true; + } + + @Override + public void setReceiveConsumer(Consumer ipv6con) { + this.ipv6con=ipv6con; + } + + + } diff --git a/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java b/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java index a9d6e56..483dc0a 100644 --- a/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java +++ b/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java @@ -74,7 +74,7 @@ public class KLALBRemoteManagement { jklbrl.addProperty("ipport", klalbRemoteLine.getSocketAddress().toString()); jklbrl.addProperty("state",MonitorData.parseStateToString( klalbRemoteLine.getMonitor().getState())); - jklbrl.addProperty("Vaddr", klalbRemoteLine.getRemoteVaddr().getHostAddress()); + jklbrl.addProperty("Vaddr", klalbRemoteLine.getRemoteVaddr().getAddress().getHostAddress()); jklbrl.addProperty("uploadspeed", klalbRemoteLine.getMonitor().getOutSpeed()); jklbrl.addProperty("downloadspeed", klalbRemoteLine.getMonitor().getInSpeed()); diff --git a/src/org/kne/cloud/network/klalb/KLALBUtils.java b/src/org/kne/cloud/network/klalb/KLALBUtils.java index e231ba9..1ff7c8d 100644 --- a/src/org/kne/cloud/network/klalb/KLALBUtils.java +++ b/src/org/kne/cloud/network/klalb/KLALBUtils.java @@ -1,12 +1,17 @@ package org.kne.cloud.network.klalb; +import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Inet6Address; +import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; import java.util.UUID; +import java.util.concurrent.LinkedBlockingQueue; + +import org.kne.cloud.network.MultipurposeSocketAddress; public class KLALBUtils { public static Inet6Address uuidToIP(UUID uuid) { @@ -34,15 +39,15 @@ public class KLALBUtils { } public static 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"; + return String.format("%.2f", 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"; + return String.format("%.2f", 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"; + return String.format("%.2f", v / (1024.0 * 1024.0 * 1024.0)) + "GB"; } else if (v >= 1024L * 1024) { - return String.format("%.1f", v / (1024.0 * 1024.0)) + "MB"; + return String.format("%.2f", v / (1024.0 * 1024.0)) + "MB"; } else if (v >= 1024L) { - return String.format("%.1f", v / (1024.0)) + "KB"; + return String.format("%.2f", v / (1024.0)) + "KB"; } else { return v + "B"; } @@ -62,6 +67,24 @@ public class KLALBUtils { return v+"B"; } } + + + public static String defaultUnit(long v) { + if(v>=1024L*1024*1024*1024*1024) { + return format( v/(1024.0*1024.0*1024.0*1024.0*1024.0))+"P"; + }else if(v>=1024L*1024*1024*1024) { + return format (v/(1024.0*1024.0*1024.0*1024.0))+"T"; + }else if(v>=1024L*1024*1024) { + return format( v/(1024.0*1024.0*1024.0))+"G"; + }else if(v>=1024L*1024) { + return format( v/(1024.0*1024.0))+"M"; + }else if(v>=1024L) { + return format( v/(1024.0))+"K"; + }else { + return Long.toString(v) ; + } + } + private static String format( double d) { String fmt=String.format( "%.2f",d); if(fmt.length()>4) { @@ -92,4 +115,82 @@ public class KLALBUtils { } return -1; } + public static Color getColorByLoadPercentage(float f) { + int r=0; + int g=255; + if(f<50f) { + r+=f/50f*255f; + }else { + r=255; + g-=(f-50f)/50f*255f; + } + if(r>255) + r=255; + if(r<0) + r=0; + if(g>255) + g=255; + if(g<0) + g=0; + Color col=new Color( r,g,0); + return col; + } + + public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress targetAddress) + throws IOException { + if (targetAddress.isStream()) { + if (targetAddress.supportNIO()) { + if (bindAddress != null) { + return new StreamChannelKLALBPacketLink(targetAddress + .connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort())); + } else { + return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel()); + } + } else { + if (bindAddress != null) { + return new StreamKLALBPacketLink( + targetAddress.connectSocket(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort())); + } else { + return new StreamKLALBPacketLink(targetAddress.connectSocket()); + } + } + } else { + if (bindAddress != null) { + return new SplitedDatagramKLALBPacketLink( + targetAddress.connectDatagramSocket(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort())); + } else { + return new SplitedDatagramKLALBPacketLink(targetAddress.connectDatagramSocket()); + } + } + } + public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress, + MultipurposeSocketAddress targetAddress, int timeout) throws UnknownHostException, IOException { + if (targetAddress.isStream()) { + if (targetAddress.supportNIO()) { + if (bindAddress != null) { + return new StreamChannelKLALBPacketLink(targetAddress + .connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout)); + } else { + return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout)); + } + } else { + if (bindAddress != null) { + return new StreamKLALBPacketLink( + targetAddress.connectSocket(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout)); + } else { + return new StreamKLALBPacketLink(targetAddress.connectSocket(timeout)); + } + } + } else { + if (bindAddress != null) { + return new SplitedDatagramKLALBPacketLink( + targetAddress.connectDatagramSocket(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort())); + } else { + return new SplitedDatagramKLALBPacketLink(targetAddress.connectDatagramSocket()); + } + } + } + + + } diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java index 29717aa..9a87a07 100644 --- a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java +++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java @@ -34,10 +34,12 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.locks.Lock; @@ -54,10 +56,12 @@ import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import org.kne.acclerate.FastLib; +import org.kne.cloud.network.PortPair; import org.kne.cloud.network.SpeedLimiter; import org.kne.cloud.network.ThreadTool; import org.kne.cloud.network.VirtualSocketImpl; import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; +import org.kne.concurrent.SpinLock; import org.kne.debug.TimeDebugger; import org.kne.io.Data; @@ -82,6 +86,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl private SpeedAndTrafficAndDelayMonitorDataImpl socketMonitor=new SpeedAndTrafficAndDelayMonitorDataImpl(); + private SpeedAndTrafficAndDelayMonitorDataImpl socketRawMonitor=new SpeedAndTrafficAndDelayMonitorDataImpl(); + private KLALBController controller; protected int getInputchachesize() { @@ -100,16 +106,29 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl this.outputchachesize = outputchachesize; } - //private Speed + //60000 30 30 + private static final int MTU=8192; - private volatile int inputchachesize = MTU * 2000; - private volatile int outputchachesize = MTU * 50; - private volatile int reallimit = MTU * 40; - //private SpeedLimiter spdlmt=new SpeedLimiter(1024*1024); + //4000 100 100 + //10000 500 500 + private volatile int inputchachesize = MTU * 4000; + private volatile int outputchachesize = MTU * 240;//500 + private volatile int reallimit = MTU * 240; + + private final long MIN_RTTVAR=50000000L; + private final long MIN_LIMIT_SPEED=64*1024L; + private volatile long rcvSpeed=MIN_LIMIT_SPEED; + private volatile long requestSpeed=MIN_LIMIT_SPEED; + private SpeedLimiter spdlmt=new SpeedLimiter(MIN_LIMIT_SPEED,1000000L); + private volatile long congressSpeed=0; + private volatile double congressFactor=2; + + //private double[] congressFactors=new double[] {0.95,0.95,0.95,1.2,0.8}; + //private int congressFactorsState=0; //private volatile double maxutilization=0.8; - private volatile boolean nodelay=false; - private volatile long delaytime=1; + private volatile boolean nodelay=true; + private volatile long delaytime=2; public long getDelaytime() { return delaytime; @@ -131,9 +150,13 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl private ReentrantLock backlogQueuelock=new ReentrantLock(); private volatile Thread sendDequeLock; - private Queue sendDeque = new ArrayBlockingQueue(20000); + private Queue recvQueue = new ConcurrentLinkedQueue(); + private AtomicInteger recvQueueUsed=new AtomicInteger(0); + //private AtomicInteger recvCounter=new AtomicInteger(0); + private Map sendmap=new ConcurrentHashMap(); + private AtomicInteger sendmapWindowUsed=new AtomicInteger(0); //private ReentrantReadWriteLock sendmaplock=new ReentrantReadWriteLock(); private volatile Thread sendthread; @@ -142,27 +165,29 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl private class SendCheckTask extends TimerTask{ public void run() { - /*sendmaplock.writeLock().lock(); - try {*/ + + + + try { Collection cdp=sendmap.values(); for (Iterator iterator = cdp.iterator(); iterator.hasNext();) { DATATPacket dtp = (DATATPacket) iterator.next(); try { long x=System.nanoTime(); long dt=x-dtp.resendtimer; - long limit= (long) (Math.pow(2, dtp.getSendRecord().size()-1)*(RTTMin*20+100000L)); + long limit= (long) (Math.pow(2, dtp.getSendCounter()-1)*(RTO)); if(dt>limit) { - if(dtp.getSendRecord().size()>=10) { + if(dtp.getSendCounter()>=10) { throw new IOException("send error!"); } - /*if(reallimit>LIMIT*2) { - reallimit=reallimit-4096; - System.out.println(reallimit+" -4096"); - }*/ - /*if(spdlmt.getLimitspeed()>LIMIT*2) - spdlmt.setLimitspeed(spdlmt.getLimitspeed()-4096);*/ + + if(dtp.isDisposed()) + continue; dtp.setPriority(4); - controller.sendPacketToAddress((Inet6Address) remoteaddr,dtp,1); + long length= dtp.getLength(); + socketRawMonitor.getOutTrafficAL().addAndGet(length); + spdlmt.forceTransmit(length); + controller.sendPacketToAddress((Inet6Address) remoteaddr,0,dtp,1); //System.out.println("第"+(dtp.getSendRecord().size()-1)+"次重传:"+dtp+" "+dt+">"+limit); dtp.resendtimer=x; @@ -178,10 +203,11 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl } } - /*}finally { - sendmaplock.writeLock().unlock(); - }*/ - + }catch(Exception e) { + e.printStackTrace(); + } + if(portp!=null) + updateBandwidthReq(requestSpeed); } } @@ -191,11 +217,12 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl @Override public void run() { - if(sendDeque.isEmpty()) { - try {if(getLocalPort()!=0&&getPort()!=0) + if(recvQueue.isEmpty()) { + try { + if(getLocalPort()!=0&&getPort()!=0) if(remoteaddr instanceof Inet6Address&&(!remoteaddr.isAnyLocalAddress())) - controller.sendPacketToAddress((Inet6Address) remoteaddr, new ACKTPacket(getLocalPort(),getPort(), -1, - true,0)); + controller.sendPacketToAddress((Inet6Address) remoteaddr,0, new ACKTPacket(getLocalPort(),getPort(), -1, + true,false,socketMonitor.getInSpeedMax(),0)); } catch (IOException e) { try { close0(true); @@ -215,15 +242,23 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl return backlogQueue != null; } - //private int inputcross = 0; - private List inputchache = new ArrayList<>(); - private ReentrantLock inputchachelock=new ReentrantLock(); + //private List inputchache = new RangeArrayList<>(); + private Map inputchache=new ConcurrentHashMap(); + private Lock inputchachelock=new SpinLock(); private long inputcount = 0; private volatile boolean avaliable = true; + private AtomicBoolean firstUpdate=new AtomicBoolean(true); + private volatile long RTTMin=1000000000L; + private volatile long RTTVar=1000000000L; + private volatile long RTTAvg=1000000000L; + private volatile long RTO=1000000000L; + + private volatile long QueueingAvg=1000000000L; + + private volatile long RunningSpeed=spdlmt.getLimitspeed(); - private long RTTMin=1000000000L; private volatile boolean ignoreBindCheck; private boolean connected; @@ -307,7 +342,9 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl protected void connect(InetAddress address, int port) throws IOException { connect(new InetSocketAddress(address, port), 10000); } - + + private PortPair portp; + @Override protected void connect(SocketAddress address, int timeout) throws IOException { if(!ignoreBindCheck) @@ -317,13 +354,14 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl port = ((InetSocketAddress) address).getPort(); this.address=this.remoteaddr = (Inet6Address) ((InetSocketAddress) address).getAddress(); + if(connected) throw new SocketException("already connected"); controller.getStreamPortBinder().connect(this); connectionPending=true; - controller.getResendTimer().schedule(sendCheckTask, 50, 50); + controller.getResendTimer().schedule(sendCheckTask, 10, 10); //controller.sendPacketToAddress((Inet6Address) this.remoteaddr, new SYNTPacket(localport, port), 0,1); try { getKVSIOutputStream().write(compress); @@ -345,6 +383,16 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl } connected=true; + + PortPair portpx=new PortPair(localport, port); + controller.registerDistUpdateConsumer(remoteaddr, portpx, (c)->{ + //System.out.println(c); + spdlmt.setLimitspeed(Math.max(MIN_LIMIT_SPEED,c)); + }); + updateBandwidthReq(requestSpeed); + + this.portp=portpx; + }catch(SocketTimeoutException e) { throw new SocketTimeoutException("connect time out"); }catch(NoRouteToHostException e) { @@ -357,6 +405,11 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl controller.getResendTimer().schedule(flowControlTask, 5000, 5000); } + private void updateBandwidthReq(long requestSpeed) { + if(remoteaddr!=null&&portp!=null) + controller.updateBandwidthRequest(remoteaddr, portp,requestSpeed ); + } + public boolean isConnectionPending() { return connectionPending; } @@ -424,7 +477,7 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl kvsi.remoteaddr=(Inet6Address) isa.getAddress(); kvsi.bind(localaddr, localport,true); - kvsi.accept((KLALBRemoteLine)p[1],(KLALBPacket) p[2]); + kvsi.accept((Inet6Address)p[1],(KLALBPacket) p[2]); kvsi.connect(isa, 5000); /*kvsi.port = isa.getPort(); kvsi.localport = localport; @@ -463,26 +516,30 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl while (true) { if (isClosed()) throw new SocketException("Socket is closed"); - DATATPacket dtp2 = sendDeque.poll(); + DATATPacket dtp2 = recvQueue.poll(); if (dtp2 != null) { + recvQueueUsed.addAndGet(-dtp2.getSize()); //System.out.println("PULL:"+dtp2); dataPack = dtp2; socketMonitor.getInTrafficAL().addAndGet(dtp2.getSize()); + socketMonitor.getInPacketCounterAL().incrementAndGet(); controller.getDatatMonitor().getInTrafficAL().addAndGet(dtp2.getSize()); - checkFlowControl(dtp2); + controller.getDatatMonitor().getInPacketCounterAL().incrementAndGet(); + //checkFlowControl(dtp2); break; } sendDequeLock=Thread.currentThread(); LockSupport.parkNanos(1000000); } + //System.out.println("sorted:"+dataPack); return dataPack; } - private void checkFlowControl(DATATPacket dtp2) throws IOException { - if(sendDeque.size() >= inputchachesize/MTU-4) { - controller.sendPacketToAddress(remoteaddr, new ACKTPacket(dtp2.getDport(), dtp2.getSport(), dtp2.getNumber(), + /*private void checkFlowControl(DATATPacket dtp2) throws IOException { + if(recvQueue.size() >= inputchachesize/MTU-4) { + controller.sendPacketToAddress(remoteaddr,0,KLALB_PROTOCOL_NUMBER, new ACKTPacket(dtp2.getDport(), dtp2.getSport(), dtp2.getNumber(), true,dtp2.getSendcount())); } - } + }*/ @Override @@ -501,6 +558,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl dst.limit(dst.position()+len); dst.put( dataPack.getDataBuffer().get()) ; if(!dataPack.getDataBuffer().hasRemaining()) { + dataPack.putTimePassport("unpacked"); + dataPack.printPassport(); dataPack.dispose(); dataPack=null; } @@ -523,6 +582,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl i+=min; //b[off + i]= dtp.getData()[count++] ; if(!dataPack.getDataBuffer().hasRemaining()) { + dataPack.putTimePassport("unpacked"); + dataPack.printPassport(); dataPack.dispose(); dataPack=null; } @@ -558,6 +619,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl len = Math.min(len, available()); b[off]= dataPack.getDataBuffer().get() ; if(!dataPack.getDataBuffer().hasRemaining()) { + dataPack.putTimePassport("unpacked"); + dataPack.printPassport(); dataPack.dispose(); dataPack=null; } @@ -578,6 +641,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl i+=min; //b[off + i]= dtp.getData()[count++] ; if(!dataPack.getDataBuffer().hasRemaining()) { + dataPack.putTimePassport("unpacked"); + dataPack.printPassport(); dataPack.dispose(); dataPack=null; } @@ -601,13 +666,13 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl } @Override public int available() throws IOException { - AtomicInteger i = new AtomicInteger(0); - sendDeque.forEach((V) -> { - i.addAndGet(V.getSize()); - }); + int i = recvQueueUsed.get(); + /*for(DATATPacket V:recvQueue) { + i+=(V.getSize()); + }*/ if (dataPack != null) - i.addAndGet(dataPack.getDataBuffer().remaining()); - return i.get(); + i+=dataPack.getDataBuffer().remaining(); + return i; } @Override @@ -629,7 +694,6 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl this.compress = compress; } - private static final int MTU=60000; protected class KVSIOutputStream extends OutputStream implements WritableByteChannel{ DATATPacket dataPack=new DATATPacket(localport, port, outputcount++,MTU); @@ -730,7 +794,7 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl throw new SocketException("Socket is closed"); if(sendmap.isEmpty()) break; - if(timeout!=0&&(System.nanoTime()-start>timeout*1000000)) + if(timeout!=0&&(System.nanoTime()-start>timeout*1000000L)) throw new SocketTimeoutException("wait for acknowledged timout"); sendthread=Thread.currentThread(); LockSupport.parkNanos(1000000L); @@ -794,6 +858,7 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl } //TimeDebugger td=new TimeDebugger(); //td.putTime("start"); + dataPack.putTimePassport("packed"); while (!avaliable) { try { Thread.sleep(1); @@ -801,35 +866,46 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl e.printStackTrace(); } } + dataPack.putTimePassport("waitForAvaliable"); //td.putTime("waitForAvaliable"); while(true){ if (isClosed()) throw new SocketException("Socket is closed"); //System.out.println(sendmap.size()); - boolean b=sendmap.size()<=reallimit/MTU; + boolean b=sendmapWindowUsed.get()<=reallimit; + //boolean b=sendmap.size()<=reallimit/MTU; if(b) break; sendthread=Thread.currentThread(); LockSupport.parkNanos(1000000L); } + dataPack.putTimePassport("waitForWindow"); //td.putTime("waitForCache"); DATATPacket pack=dataPack; dataPack=new DATATPacket(localport, port, outputcount++,MTU); + dataPack.putTimePassport("buildHeader"); pack.getDataBuffer().flip(); + //System.out.println(pack.getDataBuffer()); //cacheCreateTime=System.nanoTime(); //td.putTime("flushBuffer"); - //spdlmt.transmit(count); + spdlmt.transmit(pack.getDataBuffer().limit()); socketMonitor.getOutTrafficAL().addAndGet(pack.getDataBuffer().limit()); + socketMonitor.getOutPacketCounterAL().incrementAndGet(); controller.getDatatMonitor().getOutTrafficAL().addAndGet(pack.getDataBuffer().limit()); + controller.getDatatMonitor().getOutPacketCounterAL().incrementAndGet(); //td.putTime("doStatistic"); pack.setPriority(5); pack.resendtimer=System.nanoTime(); - controller.sendPacketToAddress(remoteaddr,pack); + socketRawMonitor.getOutTrafficAL().addAndGet(pack.getLength()); + controller.sendPacketToAddress(remoteaddr,0,pack); //td.putTime("doSend"); /* sendmaplock.readLock().lock(); try{*/ pack.resendtimer=System.nanoTime(); - sendmap.put(pack.getNumber(),pack); + DATATPacket prv= sendmap.put(pack.getNumber(),pack); + sendmapWindowUsed.addAndGet(pack.getSize()); + if(prv!=null) + sendmapWindowUsed.addAndGet(-prv.getSize()); //System.out.println("PUSH:"+pack); /*}finally { sendmaplock.readLock().unlock(); @@ -849,20 +925,24 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl } private void close0() throws IOException { //outputclosed=true; + if(isClosed()) + return; olock.lock(); try { flush0(); }finally { olock.unlock(); } + DATATPacket pack=new DATATPacket(localport, port, outputcount++,MTU); pack.setPriority(5); pack.getDataBuffer(). flip(); - controller.sendPacketToAddress(remoteaddr,pack); + controller.sendPacketToAddress(remoteaddr,0,pack); /*sendmaplock.readLock().lock(); try{*/ pack.resendtimer=System.nanoTime(); sendmap.put(pack.getNumber(),pack); + sendmapWindowUsed.addAndGet(pack.getSize()); /*}finally { sendmaplock.readLock().unlock(); }*/ @@ -958,6 +1038,7 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl private void close0(boolean b) throws IOException { if ( !isClosed()) { closed = true; + if(!isListening() ) { sendCheckTask.cancel(); flowControlTask.cancel(); @@ -965,11 +1046,17 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl if(remoteaddr!=null) try { - controller.sendPacketToAddress(remoteaddr, new RSTPacket(super.localport, super.port), + controller.sendPacketToAddress(remoteaddr,0, new RSTPacket(super.localport, super.port), 2); } catch (NoRouteToHostException e) { } controller.getStreamPortBinder().disconnect(this); + if(portp!=null) { + PortPair portpx=portp; + portp=null; + controller.updateBandwidthRequest(remoteaddr, portpx, 0L); + controller.registerDistUpdateConsumer(remoteaddr, portpx, null); + } }else { //System.out.println("unlisten"+getLocalPort()); controller.getStreamPortBinder().unlisten(this); @@ -1001,18 +1088,22 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ InputStream is=getInputStream(); OutputStream os=getOutputStream(); if((!(is instanceof KVSIInputStream))||(!(os instanceof KVSIOutputStream))) { - throw new SocketException("cant use association because compress is enabled"); + throw new CannotAssociateException("cant use association because compress is enabled"); } KVSIInputStream kis=(KVSIInputStream) is; KVSIOutputStream kos=(KVSIOutputStream) os; Thread t1=ThreadTool.makeVThreadIfSupport("本地发送线程", ()->{ + boolean onError=false; try { DATATPacket dp; while((dp=kis.nextPacket()).getSize()!=0) { b.write(dp.getDataBuffer()); + dp.putTimePassport("unpacked"); + dp.printPassport(); dp.dispose(); } }catch(IOException e) { + onError=true; e.printStackTrace(); }finally { try { @@ -1025,23 +1116,68 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ } catch (IOException e) { e.printStackTrace(); } + if(true) { + try { + b.close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + try { + close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + } } }); Thread t2=ThreadTool.makeVThreadIfSupport("本地接收线程", ()->{ + boolean onError=false; try { + ByteBuffer tst=ByteBuffer.allocateDirect(MTU); while(true) { - if(b.read(kos.dataPack.getDataBuffer())==-1) { + if(nodelay) { + if(b.read(kos.dataPack.getDataBuffer())==-1) { + break; + } + kos.flush0(); + }else { + if(b.read(tst)==-1) { break; } + tst.flip(); + kos.olock.lock(); try { - kos.flush0(); + kos.dataPack.getDataBuffer().put(tst); + /*if(b.read(kos.dataPack.getDataBuffer())==-1) { + break; + }*/ }finally { kos.olock.unlock(); + } + if(kos.dataPack.getDataBuffer().hasRemaining()) { + kos.olock.lock(); + try { + kos.flush(); + }finally { + kos.olock.unlock(); + } + }else { + kos.olock.lock(); + try { + kos.flush0(); + }finally { + kos.olock.unlock(); + } + } + tst.clear(); } } }catch(IOException e) { + onError=true; e.printStackTrace(); }finally { try { @@ -1054,6 +1190,20 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ } catch (IOException e) { e.printStackTrace(); } + if(true) { + try { + b.close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + try { + close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + } } }); t1.start(); @@ -1064,6 +1214,7 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ } catch (InterruptedException e) { e.printStackTrace(); } + b.close(); close(); } @@ -1077,18 +1228,22 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ InputStream is=getInputStream(); OutputStream os=getOutputStream(); if((!(is instanceof KVSIInputStream))||(!(os instanceof KVSIOutputStream))) { - throw new SocketException("cant use association because compress is enabled"); + throw new CannotAssociateException("cant use association because compress is enabled"); } KVSIInputStream kis=(KVSIInputStream) is; KVSIOutputStream kos=(KVSIOutputStream) os; Thread t1=ThreadTool.makeVThreadIfSupport("本地发送线程", ()->{ + boolean onError=false; try { DATATPacket dp; while((dp=kis.nextPacket()).getSize()!=0) { orc.write(dp.getDataBuffer()); + dp.putTimePassport("unpacked"); + dp.printPassport(); dp.dispose(); } }catch(IOException e) { + onError=true; e.printStackTrace(); }finally { try { @@ -1101,23 +1256,68 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ } catch (IOException e) { e.printStackTrace(); } + if(true) { + try { + associateSocket.close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + try { + close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + } } }); Thread t2=ThreadTool.makeVThreadIfSupport("本地接收线程", ()->{ + boolean onError=false; try { + ByteBuffer tst=ByteBuffer.allocateDirect(MTU); while(true) { - if(irc.read(kos.dataPack.getDataBuffer())==-1) { - break; - } + if(nodelay) { + if(irc.read(kos.dataPack.getDataBuffer())==-1) { + break; + } + kos.flush0(); + }else { + if(irc.read(tst)==-1) { + break; + } + tst.flip(); + + kos.olock.lock(); + try { + kos.dataPack.getDataBuffer().put(tst); + /*if(irc.read(kos.dataPack.getDataBuffer())==-1) { + break; + }*/ + }finally { + kos.olock.unlock(); + + } + if(kos.dataPack.getDataBuffer().hasRemaining()) { + kos.olock.lock(); + try { + kos.flush(); + }finally { + kos.olock.unlock(); + } + }else { kos.olock.lock(); try { kos.flush0(); }finally { kos.olock.unlock(); - } + } + tst.clear(); + } } }catch(IOException e) { + onError=true; e.printStackTrace(); }finally { try { @@ -1130,6 +1330,20 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ } catch (IOException e) { e.printStackTrace(); } + if(true) { + try { + associateSocket.close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + try { + close(); + } catch (IOException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + } } }); t1.start(); @@ -1140,11 +1354,12 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ } catch (InterruptedException e) { e.printStackTrace(); } + associateSocket.close(); close(); } @Override - public void accept(KLALBRemoteLine from, KLALBPacket u) { + public void accept(Inet6Address from, KLALBPacket u) { try { //System.out.println(this+" "+u); switch (u.getType()) { @@ -1155,13 +1370,15 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ break; case KLALBPacket.DATAT: DATATPacket dtp = (DATATPacket) u; + + socketRawMonitor.getInTrafficAL().addAndGet(dtp.getLength()); if(isListening()) { if(dtp.getNumber()==0) { backlogQueuelock.lock(); try{ //controller.getStreamPortBinder().checkIsConnected(new Pair); - InetSocketAddress is=new InetSocketAddress(from.getRemoteVaddr(), dtp.getSport()); + InetSocketAddress is=new InetSocketAddress(from, dtp.getSport()); AtomicBoolean ab=new AtomicBoolean(true); for (Iterator iterator = backlogQueue.iterator(); iterator.hasNext();) { Object[] objects = (Object[]) iterator.next(); @@ -1171,7 +1388,7 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ } } if(ab.get()) { - if(controller.getStreamPortBinder().checkIsConnect(this,new InetSocketAddress(from.getRemoteVaddr(), dtp.getSport()))) { + if(controller.getStreamPortBinder().checkIsConnect(this,new InetSocketAddress(from, dtp.getSport()))) { ab.set(false); } } @@ -1182,7 +1399,7 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ /* controller.sendPacketToAddress(from.getRemoteVaddr(), new ACKTPacket(dtp.getDport(), dtp.getSport(),dtp.getNumber(),true,0), 0,2);*/ }else { - controller.sendPacketToAddress(from.getRemoteVaddr(), new RSTPacket(dtp.getDport(), dtp.getSport()), + controller.sendPacketToAddress(from,0, new RSTPacket(dtp.getDport(), dtp.getSport()), 2); } @@ -1191,96 +1408,185 @@ public void associateSocketChannel(SocketChannel b) throws IOException{ backlogQueuelock.unlock(); } }else { - controller.sendPacketToAddress(from.getRemoteVaddr(), new RSTPacket(dtp.getDport(), dtp.getSport()), + controller.sendPacketToAddress(from,0, new RSTPacket(dtp.getDport(), dtp.getSport()), 2); } }else { - controller.sendPacketToAddress(from.getRemoteVaddr(), new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp.getNumber(), - sendDeque.size() < inputchachesize/MTU,dtp.getSendcount()), 1); - inputchachelock.lock(); - try{ - if (dtp.getNumber() >= inputcount) { - int currindex=(int) (dtp.getNumber()-inputcount); + //System.out.println(dtp.isCE()); + controller.sendPacketToAddress(from,0, new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp.getNumber(), + recvQueueUsed.get() < inputchachesize,dtp.isCE(),socketMonitor.getInSpeedMax(),dtp.getSendcount()), 1); + + boolean added=false; + + long number=dtp.getNumber(); + if (number >= inputcount) { + + inputchache.putIfAbsent(number, dtp); + + /*inputchachelock.lock(); + try{ + int currindex=(int) (number-inputcount); int reqsize=1+currindex; + while(reqsize>inputchache.size()) { - inputchache.add(new AtomicInteger()); - } - for (int i = 0; i < currindex; i++) { - Object o=inputchache.get(i); - if(o instanceof AtomicInteger) { - ((AtomicInteger) o).incrementAndGet(); - /*if(((AtomicInteger) o).get()==30) { - controller.sendPacketToAddress(from.getRemoteVaddr(), new NACKTPacket(dtp.getDport(), dtp.getSport(), inputcount+i),1); - //System.out.println("请求快速重传:"+(inputcount+i)); - }*/ - } - } - inputchache.set(currindex, dtp); - - Iteratoritr=inputchache.iterator(); - while (itr.hasNext()) { - Object datatPacket = itr.next(); - if(datatPacket instanceof DATATPacket) { - itr.remove(); - sendDeque.add((DATATPacket) datatPacket); - LockSupport.unpark(sendDequeLock); - inputcount++; - }else { - break; - } - + inputchache.add(null); } + + + if(currindex>=0) { + DATATPacket old=(DATATPacket) inputchache.get(currindex); + if(old==null) { + inputchache.set(currindex, dtp); + }else { + dtp.dispose(); + } + } + + + int spos=inputchache.size(); + for (int i = 0; i < inputchache.size(); i++) { + DATATPacket datatPacket=(DATATPacket) inputchache.get(i); + if(datatPacket==null) { + spos=i; + break; + } + } + for (int i = 0; i < spos; i++) { + DATATPacket datatPacket = (DATATPacket)inputchache.get(i); + recvQueueUsed.addAndGet(datatPacket.getSize()); + recvQueue.add(datatPacket); + added=true; + inputcount++; + } + ((RangeArrayList)inputchache).removeRange(0,spos); + + }finally{ + inputchachelock.unlock(); + }*/ + + + + + + }else { + dtp.dispose(); } - }finally{ + + inputchachelock.lock(); + try { + DATATPacket datatPacket = inputchache.remove(inputcount); + if(datatPacket!=null) { + inputcount++; + recvQueueUsed.addAndGet(datatPacket.getSize()); + recvQueue.add(datatPacket); + added=true; + } + }finally { inputchachelock.unlock(); } + if(added) { + LockSupport.unpark(sendDequeLock); + } + //dbg.println(from.getMonitor()+","+dtp.getNumber()); } break; case KLALBPacket.ACKT: ACKTPacket ackt = (ACKTPacket) u; if(isListening()) { - controller.sendPacketToAddress(from.getRemoteVaddr(), new RSTPacket(ackt.getDport(), ackt.getSport()), + controller.sendPacketToAddress(from,0, new RSTPacket(ackt.getDport(), ackt.getSport()), 2); }else { avaliable = ackt.isAvaliable(); + + + rcvSpeed=ackt.getRcvSpeed(); + + /*if(rcvSpeed>=congressSpeed) { + congressSpeed=rcvSpeed; + }else { + congressSpeed=(congressSpeed*99+rcvSpeed)/100; + }*/ + + + if(ackt.isCongress()) { + congressFactor=1.2; + if(reallimit>MTU*2) { + reallimit-=8192; + //System.out.println(reallimit+" -2048"); + } + }else { + if(sendmapWindowUsed.get()*2L>=reallimit) { + reallimit+=1024; + //System.out.println(reallimit+" +1024"); + } + } + requestSpeed=(long) (Math.max(MIN_LIMIT_SPEED, rcvSpeed)*congressFactor); + + //System.out.println(spdlmt.getLimitspeed()/1024+"K "+ackt.getRcvSpeed()/1024+"K"); DATATPacket kl=null; - /*sendmaplock.readLock().lock(); - try{*/ + kl=sendmap.remove(ackt.getNumber()); - - /* }finally { - sendmaplock.readLock().unlock(); - }*/ + if(kl!=null) { + sendmapWindowUsed.addAndGet(-kl.getSize()); + } if(kl!=null) { if(sendthread!=null) LockSupport.unpark(sendthread); //controller.removeFromSend(from.getRemoteVaddr(),kl); - if(kl.getSendRecord().size()==1) { + if(kl.getSendCounter()==1) { long RTTC=ackt.getRcvtime()- kl.getSndtime(); if(RTTC<=RTTMin) { RTTMin=RTTC; }else { - RTTMin= (RTTMin*9999+RTTC)/10000; + RTTMin= (RTTMin*99999+RTTC)/100000; } - - /*if(RTTC>RTTMin*2) { - if(reallimit>MTU*3) { - reallimit=reallimit-512; - } + + long queueing=RTTC-RTTMin; + QueueingAvg=(QueueingAvg*99999+queueing)/100000; + if(firstUpdate.compareAndSet(true, false)) { + RTTAvg=RTTC; + RTTVar=RTTC/2; + + }else { + RTTVar=(RTTVar*3+Math.abs(RTTAvg-RTTC))/4; + RTTAvg= (RTTAvg*7+RTTC)/8; + } + RTO=RTTAvg+Math.max(MIN_RTTVAR, RTTVar*4);//RTTVar*4 + + + + /*if(RTTC>RTO) { + congressFactor=Math.min( 0.9,congressFactor); }else { - if(reallimit(local, remote)); if(bkc!=null) { - bkc.accept(krl, (KLALBPacket) packet); + bkc.accept(srcAddr, (KLALBPacket) packet); return true; } InetSocketAddress localany=new InetSocketAddress(ANYLA, packet.getDport()); bkc=connectMap.get(new Pair(localany, remote)); if(bkc!=null) { - bkc.accept(krl, (KLALBPacket) packet); + bkc.accept(srcAddr, (KLALBPacket) packet); return true; } bkc=listenMap.get(local); if(bkc!=null) { - bkc.accept(krl, (KLALBPacket) packet); + bkc.accept(srcAddr, (KLALBPacket) packet); return true; } bkc=listenMap.get(localany); if(bkc!=null) { - bkc.accept(krl, (KLALBPacket) packet); + bkc.accept(srcAddr, (KLALBPacket) packet); return true; } diff --git a/src/org/kne/cloud/network/klalb/RSTPacket.java b/src/org/kne/cloud/network/klalb/RSTPacket.java index 11cf6a9..318b0c6 100644 --- a/src/org/kne/cloud/network/klalb/RSTPacket.java +++ b/src/org/kne/cloud/network/klalb/RSTPacket.java @@ -8,33 +8,24 @@ import java.io.IOException; import java.nio.ByteBuffer; public class RSTPacket extends KLALBPacket implements PortPacket{ + private static final int HEADER_LENGTH=9; public RSTPacket(int sport,int dport) { - super(RST); - header.putInt(sport); - header.putInt(dport); + super(RST,HEADER_LENGTH); + klalbHeader.putInt(sport); + klalbHeader.putInt(dport); } public RSTPacket(ByteBuffer bb) { - super(bb); - } - - @Override - public long getLength() { - return super.getLength()+8; - } - - @Override - protected int getHeaderSize() { - return super.getHeaderSize()+8; + super(bb,HEADER_LENGTH); } public int getSport() { - return header.getInt(1); + return klalbHeader.getInt(1); } public int getDport() { - return header.getInt(5); + return klalbHeader.getInt(5); } @Override diff --git a/src/org/kne/cloud/network/klalb/RangeArrayList.java b/src/org/kne/cloud/network/klalb/RangeArrayList.java new file mode 100644 index 0000000..cf992b3 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/RangeArrayList.java @@ -0,0 +1,13 @@ +package org.kne.cloud.network.klalb; + +import java.util.ArrayList; + +public class RangeArrayList extends ArrayList{ + + @Override + protected void removeRange(int fromIndex, int toIndex) { + // TODO 自动生成的方法存根 + super.removeRange(fromIndex, toIndex); + } + +} diff --git a/src/org/kne/cloud/network/klalb/SimpleKLALBClient.java b/src/org/kne/cloud/network/klalb/SimpleKLALBClient.java index b18558e..a008113 100644 --- a/src/org/kne/cloud/network/klalb/SimpleKLALBClient.java +++ b/src/org/kne/cloud/network/klalb/SimpleKLALBClient.java @@ -15,6 +15,7 @@ import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.SocketBridge; import org.kne.cloud.network.SocketListener; import org.kne.cloud.network.SocketToSocketProxy; +import org.kne.cloud.network.klalb.ui.KLALBStateGUI2; import org.kne.util.AutoProperties; public class SimpleKLALBClient { diff --git a/src/org/kne/cloud/network/klalb/SimpleKLALBServer.java b/src/org/kne/cloud/network/klalb/SimpleKLALBServer.java index f8a265f..cbe142f 100644 --- a/src/org/kne/cloud/network/klalb/SimpleKLALBServer.java +++ b/src/org/kne/cloud/network/klalb/SimpleKLALBServer.java @@ -17,6 +17,7 @@ import org.kne.cloud.network.SocketBridge; import org.kne.cloud.network.SocketListener; import org.kne.cloud.network.SocketToSocketProxy; import org.kne.cloud.network.SocketType; +import org.kne.cloud.network.klalb.ui.KLALBStateGUI2; public class SimpleKLALBServer { public static KLALBStateGUI2 ksg; diff --git a/src/org/kne/cloud/network/klalb/StreamChannelKLALBPacketLink.java b/src/org/kne/cloud/network/klalb/StreamChannelKLALBPacketLink.java index 9ee4eb1..330ae45 100644 --- a/src/org/kne/cloud/network/klalb/StreamChannelKLALBPacketLink.java +++ b/src/org/kne/cloud/network/klalb/StreamChannelKLALBPacketLink.java @@ -24,7 +24,27 @@ import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.TimeoutTimer; public class StreamChannelKLALBPacketLink implements KLALBPacketLink { - private static TimeoutTimer tmoTimer=new TimeoutTimer(); + private volatile long timeoutTimer; + private volatile boolean timerenabled=false; + private Thread timeouter=new Thread() { + public void run() { + timeoutTimer=System.nanoTime(); + while(connectSocket.isOpen()) { + if(timerenabled&&(System.nanoTime()-timeoutTimer>sotimeout*1000000L)) { + if(connectSocket!=null) + try { + connectSocket.close(); + } catch (IOException e) { + } + } + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }; @Override public String toString() { try { @@ -38,9 +58,10 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink { private int sotimeout; public StreamChannelKLALBPacketLink(SocketChannel connectSocket) throws IOException { this.connectSocket=connectSocket; + connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true); + timeouter.start(); new KLALBOutputStream(Channels.newOutputStream(connectSocket)); new KLALBInputStream(Channels.newInputStream(connectSocket)); - connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true); } @@ -51,19 +72,21 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink { @Override public KLALBPacket readPacket() throws IOException { - TimerTask tsk= tmoTimer.createTimeOutTask(connectSocket, sotimeout); + timeoutTimer=System.nanoTime(); + timerenabled=true; KLALBPacket res; try { res=KLALBPacket.readKLALBPacketFromChannel(connectSocket); }finally { - if(tsk!=null) - tsk.cancel(); + timerenabled=false; } return res; } @Override public void close() throws IOException { + //System.out.println("连接被关闭"); + //new Exception().printStackTrace(); connectSocket.close(); } diff --git a/src/org/kne/cloud/network/klalb/TESTPacket.java b/src/org/kne/cloud/network/klalb/TESTPacket.java index 2055971..15fee88 100644 --- a/src/org/kne/cloud/network/klalb/TESTPacket.java +++ b/src/org/kne/cloud/network/klalb/TESTPacket.java @@ -4,53 +4,69 @@ import java.io.DataInput; import java.io.DataInputStream; import java.io.DataOutput; import java.io.DataOutputStream; +import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; +import org.kne.cloud.network.NetworkPacket; + public class TESTPacket extends KLALBPacket { - private static ByteBuffer K=ByteBuffer.allocateDirect(1024); + + private static final int HEADER_LENGTH=3; + + private ByteBuffer dataBuffer;//=NetworkPacket.databufferpool_65535.borrow(); @Override public long getLength() { - return super.getLength()+K.limit(); + return HEADER_LENGTH+dataBuffer.limit(); } - @Override - protected int getHeaderSize() { - return super.getHeaderSize(); + public TESTPacket(int limit) { + super(TEST,HEADER_LENGTH); + //dataBuffer.limit(limit); + dataBuffer=ByteBuffer.allocate(limit); } + - public TESTPacket() { - super(TEST); + public ByteBuffer getDataBuffer() { + return dataBuffer; } - @Override protected void writeToChannel(WritableByteChannel dto) throws IOException { + klalbHeader.putChar(1, (char) dataBuffer.limit()); super.writeToChannel(dto); - dto.write(K.slice()); + //System.out.println(dataBuffer); + dto.write(dataBuffer.slice(0, dataBuffer.limit())); } - @Override protected void readFromChannel(ReadableByteChannel din) throws IOException { super.readFromChannel(din); - din.read(K.slice()); + int limit=klalbHeader.getChar(1); + //dataBuffer.clear(); + //dataBuffer.limit(limit); + dataBuffer=ByteBuffer.allocate(limit); + while(dataBuffer.hasRemaining()){ + if(din.read(dataBuffer)==-1) { + throw new EOFException(); + } + } + dataBuffer.flip(); } - public TESTPacket(ByteBuffer bb) { - super(bb); + super(bb,HEADER_LENGTH); } @Override public String toString() { - return "TEST"; + return "TEST["+dataBuffer.limit()+"]"; } diff --git a/src/org/kne/cloud/network/klalb/VADDRACKPacket.java b/src/org/kne/cloud/network/klalb/VADDRACKPacket.java index cd57a70..9bdf783 100644 --- a/src/org/kne/cloud/network/klalb/VADDRACKPacket.java +++ b/src/org/kne/cloud/network/klalb/VADDRACKPacket.java @@ -4,12 +4,13 @@ import java.nio.ByteBuffer; public class VADDRACKPacket extends KLALBPacket { + private static final int HEADER_LENGTH=1; public VADDRACKPacket() { - super(VADDRACK); + super(VADDRACK,HEADER_LENGTH); } public VADDRACKPacket(ByteBuffer bb) { - super(bb); + super(bb,HEADER_LENGTH); } @Override diff --git a/src/org/kne/cloud/network/klalb/VADDRPacket.java b/src/org/kne/cloud/network/klalb/VADDRPacket.java index abcef6d..d31279f 100644 --- a/src/org/kne/cloud/network/klalb/VADDRPacket.java +++ b/src/org/kne/cloud/network/klalb/VADDRPacket.java @@ -9,40 +9,34 @@ import java.net.Inet6Address; import java.net.UnknownHostException; import java.nio.ByteBuffer; +import org.kne.cloud.network.ipv6.Inet6AddressGroup; + public class VADDRPacket extends KLALBPacket { - public Inet6Address getVaddr() { + private static final int HEADER_LENGTH=18; + public Inet6AddressGroup getVaddr() { byte[]b=new byte[16]; - header.get(1, b); + klalbHeader.get(1, b); try { - return (Inet6Address) Inet6Address.getByAddress(b); + return new Inet6AddressGroup( (Inet6Address) Inet6Address.getByAddress(b),klalbHeader.get(17)&0xff); } catch (UnknownHostException e) { e.printStackTrace(); } return null; } - public VADDRPacket(Inet6Address vaddr) { - super(VADDR); - header.put(1, vaddr.getAddress()); + public VADDRPacket(Inet6AddressGroup vaddr) { + super(VADDR,HEADER_LENGTH); + klalbHeader.put(1, vaddr.getAddress().getAddress()); + klalbHeader.put(17,(byte) vaddr.getPrefixLength()); } public VADDRPacket(ByteBuffer bb) { - super(bb); + super(bb,HEADER_LENGTH); } @Override public String toString() { - return "VADDR "+getVaddr().getHostAddress(); - } - - @Override - protected int getHeaderSize() { - return super.getHeaderSize()+16; - } - - @Override - public long getLength() { - return super.getLength()+16; + return "VADDR "+getVaddr(); } } diff --git a/src/org/kne/cloud/network/klalb/VADDRREQPacket.java b/src/org/kne/cloud/network/klalb/VADDRREQPacket.java index d1da239..8638b6a 100644 --- a/src/org/kne/cloud/network/klalb/VADDRREQPacket.java +++ b/src/org/kne/cloud/network/klalb/VADDRREQPacket.java @@ -4,12 +4,14 @@ import java.nio.ByteBuffer; public class VADDRREQPacket extends KLALBPacket { + private static final int HEADER_LENGTH=1; + public VADDRREQPacket() { - super(VADDRREQ); + super(VADDRREQ,HEADER_LENGTH); } public VADDRREQPacket(ByteBuffer bb) { - super(bb); + super(bb,HEADER_LENGTH); } @Override diff --git a/src/org/kne/cloud/network/klalb/KLALBStateGUI.java b/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI.java similarity index 92% rename from src/org/kne/cloud/network/klalb/KLALBStateGUI.java rename to src/org/kne/cloud/network/klalb/ui/KLALBStateGUI.java index d26871a..295fe77 100644 --- a/src/org/kne/cloud/network/klalb/KLALBStateGUI.java +++ b/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI.java @@ -1,4 +1,4 @@ -package org.kne.cloud.network.klalb; +package org.kne.cloud.network.klalb.ui; import java.awt.AWTException; import java.awt.Color; @@ -21,6 +21,9 @@ import javax.imageio.ImageIO; import javax.swing.JPanel; import javax.swing.border.LineBorder; +import org.kne.cloud.network.klalb.CONST; +import org.kne.cloud.network.klalb.KLALBController; +import org.kne.cloud.network.klalb.KLALBRemoteLine; import org.kne.ui.XFrame; import org.kne.ui.YScrollPane; diff --git a/src/org/kne/cloud/network/klalb/KLALBStateGUI2.java b/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI2.java similarity index 50% rename from src/org/kne/cloud/network/klalb/KLALBStateGUI2.java rename to src/org/kne/cloud/network/klalb/ui/KLALBStateGUI2.java index f6a4275..fa282a6 100644 --- a/src/org/kne/cloud/network/klalb/KLALBStateGUI2.java +++ b/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI2.java @@ -1,45 +1,42 @@ -package org.kne.cloud.network.klalb; +package org.kne.cloud.network.klalb.ui; import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; +import java.awt.GridLayout; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.SystemTray; +import java.awt.Toolkit; import java.awt.TrayIcon; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; 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.image.BufferedImage; -import java.io.File; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; import java.io.IOException; -import java.net.ConnectException; -import java.net.UnknownHostException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Iterator; -import java.util.List; -import java.util.Map.Entry; import java.util.Timer; import java.util.TimerTask; -import javax.imageio.ImageIO; -import javax.management.monitor.Monitor; -import javax.swing.ButtonGroup; import javax.swing.JButton; -import javax.swing.JComboBox; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.JTextField; +import javax.swing.SwingConstants; +import javax.swing.border.LineBorder; -import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; -import org.jfree.chart.plot.dial.DialLayer; import org.jfree.chart.plot.dial.DialPlot; import org.jfree.chart.plot.dial.DialPointer; import org.jfree.chart.plot.dial.DialTextAnnotation; @@ -47,35 +44,20 @@ import org.jfree.chart.plot.dial.StandardDialFrame; import org.jfree.chart.plot.dial.StandardDialRange; import org.jfree.chart.plot.dial.StandardDialScale; import org.jfree.chart.ui.RectangleEdge; -import org.jfree.chart.ui.RectangleInsets; -import org.jfree.data.general.Dataset; import org.jfree.data.general.DefaultValueDataset; -import org.jfree.data.general.ValueDataset; import org.kne.cloud.network.MultipurposeSocketAddress; -import org.kne.cloud.network.SocketBridge; -import org.kne.cloud.network.SocketListener; -import org.kne.cloud.network.ThreadTool; +import org.kne.cloud.network.klalb.CONST; import org.kne.cloud.network.klalb.KLALBController; +import org.kne.cloud.network.klalb.KLALBRemoteLine; +import org.kne.cloud.network.klalb.KLALBUtils; import org.kne.cloud.network.monitor.MonitorData; import org.kne.ui.XFrame; import org.kne.ui.YScrollPane; -import javax.swing.JProgressBar; -import javax.swing.border.LineBorder; -import javax.swing.JTabbedPane; -import javax.swing.JMenuBar; -import javax.swing.JMenu; -import javax.swing.JRadioButtonMenuItem; -import javax.swing.JCheckBoxMenuItem; -import java.awt.GridLayout; -import java.awt.Image; -import java.awt.FlowLayout; -import javax.swing.JLabel; -import javax.swing.SwingConstants; -import java.awt.Font; +import javax.swing.JScrollPane; public class KLALBStateGUI2 extends XFrame { - private TimerTask tsk,tsk2,tsk3; + private TimerTask tsk,tsk2,tsk3,tsk4,tsk5; private SystemTray st; @@ -83,7 +65,7 @@ public class KLALBStateGUI2 extends XFrame { private long rate=200; - private Timer t,t2; + private Timer t,t2,t3; private JCheckBoxMenuItem showoffline; @@ -96,42 +78,57 @@ public class KLALBStateGUI2 extends XFrame { private DefaultValueDataset downSpeed; - private DefaultValueDataset upEfficiency; + + private DefaultValueDataset upPPS; + + private DialTextAnnotation upPPSText; + + private DialTextAnnotation downPPSText; + + private DefaultValueDataset downPPS; + + private DefaultValueDataset upDataSpeed; + + private DefaultValueDataset downDataSpeed; + + private DefaultValueDataset upDataPPS; + + private DefaultValueDataset downDataPPS; + + /*private DefaultValueDataset upEfficiency; private DialTextAnnotation upEfficiencyText; private DialTextAnnotation downEfficiencyText; - private DefaultValueDataset downEfficiency; + private DefaultValueDataset downEfficiency;*/ private YScrollPane ysp; - private static BufferedImage bi; - - public static Image getKLALBIcon() { - if(bi==null) - try { - bi = ImageIO.read(KLALBStateGUI2.class.getResourceAsStream("/assets/KNEL.png")); - } catch (IOException e) { - e.printStackTrace(); - } - return bi; - } + private JTextField devicesOnline; + private JTextField textField; + private JTextField addressField; + + private NetworkGraphPanel graph; + - public KLALBStateGUI2(KLALBController kpcje) { - this(kpcje ,CONST.klalb+" network accelerator V"+CONST.klalbver); - } /** * @wbp.parser.constructor */ + public KLALBStateGUI2(KLALBController kpcje) { + this(kpcje ,CONST.klalb+" SRv6 network accelerator V"+CONST.klalbver); + } + + public KLALBStateGUI2(KLALBController kc,String title) { //setResizable(false); - Image bix=getKLALBIcon(); - if(bix!=null) - setIconImage(bix); - setTitleColor(new Color(255, 255, 255, 250)); - //getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f)); + setIconImage(UIEnv.getIcon()); + //setTitleColor(new Color(255, 255, 255, 250)); + setTitleColor(UIEnv.getDefaultTitleColor()); + getContentPane().setBackground(UIEnv.getDefaultBackgroundColor()); + getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f)); getTitlepanel().setBorder(new LineBorder(Color.LIGHT_GRAY)); + getTitlelabel().setForeground(Color.WHITE); //getContentPane().setBackground(new Color(0,0,0,0)); /*setTitleColor(new Color(0,0,0,80)); getContentPane().setBackground(new Color(0,0,0,80)); @@ -145,13 +142,21 @@ public class KLALBStateGUI2 extends XFrame { overview.setOpaque(false); tabbedPane.addTab("Overview", null, overview, null); overview.setLayout(new BorderLayout(0, 0)); + JPanel dashboard = new JPanel(); dashboard.setOpaque(false); - overview.add(dashboard, BorderLayout.CENTER); + dashboard.setBorder(new LineBorder(new Color(0, 0, 0))); + JPanel dashs = new JPanel(); + dashs.setOpaque(false); + overview.add(dashboard,BorderLayout.CENTER); + dashboard.setLayout(new BorderLayout(0, 0)); + dashboard.add(dashs); { upSpeed = new DefaultValueDataset(0); + upDataSpeed=new DefaultValueDataset(0); DialPlot dpup=new DialPlot(); - dpup.setDataset(upSpeed); + dpup.setDataset(1,upSpeed); + dpup.setDataset(0, upDataSpeed); StandardDialFrame sdfs=new StandardDialFrame(); sdfs.setVisible(false); dpup.setDialFrame(sdfs); @@ -175,19 +180,29 @@ public class KLALBStateGUI2 extends XFrame { sdrr3.setOuterRadius(0.83); dpup.addLayer(sdrr3); + DialPointer.Pointer dpd=new DialPointer.Pointer(); + dpd.setRadius(0.7); + dpd.setFillPaint(new Color(127, 0, 0,0)); + dpd.setOutlinePaint(new Color(127, 0, 0)); + dpd.setDatasetIndex(0); + dpup.addLayer(dpd); + DialPointer.Pointer dp=new DialPointer.Pointer(); dp.setRadius(0.7); dp.setFillPaint(Color.RED); dp.setOutlinePaint(Color.RED); + dp.setDatasetIndex(1); dpup.addLayer(dp); + upSpeedText = new DialTextAnnotation("0%"); - upSpeedText.setFont(upSpeedText.getFont().deriveFont(12)); + upSpeedText.setFont(UIEnv.getFont().deriveFont(16.0f)); dpup.addLayer(upSpeedText); JFreeChart jfup= new JFreeChart(dpup); jfup.setBorderPaint(Color.WHITE); jfup.setTitle("Upload speed"); + jfup.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f)); jfup.getTitle().setPosition(RectangleEdge.BOTTOM); dpup.setView(0, 0, 1, 1); ChartPanel cpup=new ChartPanel(jfup); @@ -195,7 +210,7 @@ public class KLALBStateGUI2 extends XFrame { cpup.setSize(cpup.getPreferredSize()); cpup.setBackground(Color.WHITE); cpup.setBorder(new LineBorder(Color.LIGHT_GRAY)); - dashboard.add(cpup); + dashs.add(cpup); @@ -203,8 +218,10 @@ public class KLALBStateGUI2 extends XFrame { downSpeed = new DefaultValueDataset(0); + downDataSpeed=new DefaultValueDataset(0); DialPlot dpup1=new DialPlot(); - dpup1.setDataset(downSpeed); + dpup1.setDataset(1,downSpeed); + dpup1.setDataset(0,downDataSpeed); StandardDialFrame sdfs1=new StandardDialFrame(); sdfs1.setVisible(false); dpup1.setDialFrame(sdfs1); @@ -228,19 +245,29 @@ public class KLALBStateGUI2 extends XFrame { sdrr31.setOuterRadius(0.83); dpup1.addLayer(sdrr31); + + DialPointer.Pointer dp11=new DialPointer.Pointer(); + dp11.setRadius(0.7); + dp11.setFillPaint(new Color(0,127,0,0)); + dp11.setOutlinePaint(new Color(0,127,0)); + dp11.setDatasetIndex(0); + dpup1.addLayer(dp11); + DialPointer.Pointer dp1=new DialPointer.Pointer(); dp1.setRadius(0.7); dp1.setFillPaint(Color.GREEN); dp1.setOutlinePaint(Color.GREEN); + dp1.setDatasetIndex(1); dpup1.addLayer(dp1); downSpeedText = new DialTextAnnotation("0%"); - downSpeedText.setFont(downSpeedText.getFont().deriveFont(12)); + downSpeedText.setFont(UIEnv.getFont().deriveFont(16.0f)); dpup1.addLayer(downSpeedText); JFreeChart jfup1= new JFreeChart(dpup1); jfup1.setBorderPaint(Color.WHITE); jfup1.setTitle("Download speed"); + jfup1.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f)); jfup1.getTitle().setPosition(RectangleEdge.BOTTOM); dpup1.setView(0, 0, 1, 1); ChartPanel cpup1=new ChartPanel(jfup1); @@ -248,15 +275,140 @@ public class KLALBStateGUI2 extends XFrame { cpup1.setSize(cpup1.getPreferredSize()); cpup1.setBackground(Color.WHITE); cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY)); - dashboard.add(cpup1); + dashs.add(cpup1); } - - - { + upPPS = new DefaultValueDataset(0); + upDataPPS=new DefaultValueDataset(0); + DialPlot dpup=new DialPlot(); + dpup.setDataset(1,upPPS); + dpup.setDataset(0,upDataPPS); + StandardDialFrame sdfs=new StandardDialFrame(); + sdfs.setVisible(false); + dpup.setDialFrame(sdfs); + StandardDialScale sds=new StandardDialScale(0, 100, -120, -300, 10, 5); + sds.setTickRadius(0.8); + sds.setTickLabelsVisible(false); + dpup.addScale(0, sds); + + StandardDialRange sdrr=new StandardDialRange(0, 70,Color.GREEN); + sdrr.setInnerRadius(0.82); + sdrr.setOuterRadius(0.83); + dpup.addLayer(sdrr); + + StandardDialRange sdrr2=new StandardDialRange(70, 90,Color.YELLOW); + sdrr2.setInnerRadius(0.82); + sdrr2.setOuterRadius(0.83); + dpup.addLayer(sdrr2); + + StandardDialRange sdrr3=new StandardDialRange(90, 100,Color.RED); + sdrr3.setInnerRadius(0.82); + sdrr3.setOuterRadius(0.83); + dpup.addLayer(sdrr3); + + DialPointer.Pointer dp1=new DialPointer.Pointer(); + dp1.setRadius(0.7); + dp1.setFillPaint(new Color(127,0,0,0)); + dp1.setOutlinePaint(new Color(127,0,0)); + dp1.setDatasetIndex(0); + dpup.addLayer(dp1); + + DialPointer.Pointer dp=new DialPointer.Pointer(); + dp.setRadius(0.7); + dp.setFillPaint(Color.RED); + dp.setOutlinePaint(Color.RED); + dp.setDatasetIndex(1); + dpup.addLayer(dp); + + + upPPSText = new DialTextAnnotation("0PPS"); + upPPSText.setFont(UIEnv.getFont().deriveFont(16.0f)); + dpup.addLayer(upPPSText); + + JFreeChart jfup= new JFreeChart(dpup); + jfup.setBorderPaint(Color.WHITE); + jfup.setTitle("Upload PPS"); + jfup.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f)); + jfup.getTitle().setPosition(RectangleEdge.BOTTOM); + dpup.setView(0, 0, 1, 1); + ChartPanel cpup=new ChartPanel(jfup); + cpup.setPreferredSize(new Dimension(150, 165)); + cpup.setSize(cpup.getPreferredSize()); + cpup.setBackground(Color.WHITE); + cpup.setBorder(new LineBorder(Color.LIGHT_GRAY)); + dashs.add(cpup); + + + + + + + downPPS = new DefaultValueDataset(0); + downDataPPS=new DefaultValueDataset(0); + DialPlot dpup1=new DialPlot(); + dpup1.setDataset(1,downPPS); + dpup1.setDataset(0,downDataPPS); + StandardDialFrame sdfs1=new StandardDialFrame(); + sdfs1.setVisible(false); + dpup1.setDialFrame(sdfs1); + StandardDialScale sds1=new StandardDialScale(0, 100, -120, -300, 10, 5); + sds1.setTickRadius(0.8); + sds1.setTickLabelsVisible(false); + dpup1.addScale(0, sds1); + + StandardDialRange sdrr1=new StandardDialRange(0, 70,Color.GREEN); + sdrr1.setInnerRadius(0.82); + sdrr1.setOuterRadius(0.83); + dpup1.addLayer(sdrr1); + + StandardDialRange sdrr21=new StandardDialRange(70, 90,Color.YELLOW); + sdrr21.setInnerRadius(0.82); + sdrr21.setOuterRadius(0.83); + dpup1.addLayer(sdrr21); + + StandardDialRange sdrr31=new StandardDialRange(90, 100,Color.RED); + sdrr31.setInnerRadius(0.82); + sdrr31.setOuterRadius(0.83); + dpup1.addLayer(sdrr31); + + DialPointer.Pointer dp111=new DialPointer.Pointer(); + dp111.setRadius(0.7); + dp111.setFillPaint(new Color(0,127,0,0)); + dp111.setOutlinePaint(new Color(0,127,0)); + dp111.setDatasetIndex(0); + dpup1.addLayer(dp111); + DialPointer.Pointer dp11=new DialPointer.Pointer(); + dp11.setRadius(0.7); + dp11.setFillPaint(Color.GREEN); + dp11.setOutlinePaint(Color.GREEN); + dp11.setDatasetIndex(1); + dpup1.addLayer(dp11); + + + + downPPSText = new DialTextAnnotation("0PPS"); + downPPSText.setFont(UIEnv.getFont().deriveFont(16.0f)); + dpup1.addLayer(downPPSText); + + JFreeChart jfup1= new JFreeChart(dpup1); + jfup1.setBorderPaint(Color.WHITE); + jfup1.setTitle("Download PPS"); + jfup1.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f)); + jfup1.getTitle().setPosition(RectangleEdge.BOTTOM); + dpup1.setView(0, 0, 1, 1); + ChartPanel cpup1=new ChartPanel(jfup1); + cpup1.setPreferredSize(new Dimension(150, 165)); + cpup1.setSize(cpup1.getPreferredSize()); + cpup1.setBackground(Color.WHITE); + cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY)); + dashs.add(cpup1); + } + + + /*{ upEfficiency = new DefaultValueDataset(0); DialPlot dpup=new DialPlot(); dpup.setDataset(upEfficiency); @@ -290,12 +442,13 @@ public class KLALBStateGUI2 extends XFrame { dpup.addLayer(dp); upEfficiencyText = new DialTextAnnotation("0%"); - upEfficiencyText.setFont(upEfficiencyText.getFont().deriveFont(12)); + upEfficiencyText.setFont(UIEnv.getFont().deriveFont(16.0f)); dpup.addLayer(upEfficiencyText); JFreeChart jfup= new JFreeChart(dpup); jfup.setBorderPaint(Color.WHITE); jfup.setTitle("Upload bandwidth efficiency"); + jfup.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f)); jfup.getTitle().setPosition(RectangleEdge.BOTTOM); dpup.setView(0, 0, 1, 1); ChartPanel cpup=new ChartPanel(jfup); @@ -303,7 +456,7 @@ public class KLALBStateGUI2 extends XFrame { cpup.setSize(cpup.getPreferredSize()); cpup.setBackground(Color.WHITE); cpup.setBorder(new LineBorder(Color.LIGHT_GRAY)); - dashboard.add(cpup); + dashs.add(cpup); @@ -343,12 +496,13 @@ public class KLALBStateGUI2 extends XFrame { dpup1.addLayer(dp1); downEfficiencyText = new DialTextAnnotation("0%"); - downEfficiencyText.setFont(downEfficiencyText.getFont().deriveFont(12)); + downEfficiencyText.setFont(UIEnv.getFont().deriveFont(16.0f)); dpup1.addLayer(downEfficiencyText); JFreeChart jfup1= new JFreeChart(dpup1); jfup1.setBorderPaint(Color.WHITE); jfup1.setTitle("Download bandwidth efficiency"); + jfup1.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f)); jfup1.getTitle().setPosition(RectangleEdge.BOTTOM); dpup1.setView(0, 0, 1, 1); ChartPanel cpup1=new ChartPanel(jfup1); @@ -356,13 +510,68 @@ public class KLALBStateGUI2 extends XFrame { cpup1.setSize(cpup1.getPreferredSize()); cpup1.setBackground(Color.WHITE); cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY)); - dashboard.add(cpup1); - } + dashs.add(cpup1); + }*/ JLabel ashboard = new JLabel("Dashboard"); - ashboard.setFont(new Font("宋体", Font.PLAIN, 18)); + ashboard.setFont(UIEnv.getFont().deriveFont(20.0f)); ashboard.setHorizontalAlignment(SwingConstants.CENTER); - overview.add(ashboard, BorderLayout.NORTH); + dashboard.add(ashboard, BorderLayout.NORTH); + JPanel panelp = new JPanel(); + panelp.setOpaque(false); + JPanel panel = new JPanel(); + panel.setOpaque(false); + panel.setBorder(new LineBorder(Color.GRAY)); + overview.add(panelp, BorderLayout.SOUTH); + panelp.setLayout(new GridLayout(0, 1, 0, 0)); + + JPanel panel_2x = new JPanel(); + panel_2x.setOpaque(false); + + + + JPanel panel_2 = new JPanel(); + panel_2.setOpaque(false); + panelp.add(panel_2x); + panel_2x.setLayout(new GridLayout(2, 1, 0, 0)); + JLabel lblNewLabel = new JLabel("IPv6 addresss"); + lblNewLabel.setFont(UIEnv.getFont().deriveFont(20.0f)); + lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER); + panel_2x.add(lblNewLabel); + panel_2x.add(panel_2); + panel_2.setLayout(new BorderLayout(0, 0)); + + addressField = new JTextField(); + addressField.setHorizontalAlignment(SwingConstants.CENTER); + addressField.setOpaque(false); + panel_2.add(addressField); + addressField.setColumns(10); + addressField.setFont(UIEnv.getFont().deriveFont(20.0f)); + + JButton btnNewButton_1 = new JButton("Copy"); + btnNewButton_1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(addressField.getText()), null); + } + }); + panel_2.add(btnNewButton_1, BorderLayout.EAST); + + + panelp.add(panel); + panel.setLayout(new GridLayout(2, 2, 0, 0)); + + JLabel jlb = new JLabel("Devices Online"); + jlb.setHorizontalAlignment(SwingConstants.CENTER); + jlb.setFont(UIEnv.getFont().deriveFont(20.0f)); + panel.add(jlb); + + devicesOnline = new JTextField(); + devicesOnline.setOpaque(false); + devicesOnline.setHorizontalAlignment(SwingConstants.CENTER); + devicesOnline.setFont(UIEnv.getFont().deriveFont(20.0f)); + devicesOnline.setEditable(false); + panel.add(devicesOnline); + devicesOnline.setColumns(10); @@ -370,14 +579,16 @@ public class KLALBStateGUI2 extends XFrame { - + JPanel linesPanel=new JPanel(); + linesPanel.setOpaque(false); + tabbedPane.add(linesPanel); + tabbedPane.setTitleAt(1, "Remote lines"); + linesPanel.setLayout(new BorderLayout()); ysp = new YScrollPane(730); ysp.setOpaque(false); - tabbedPane.add(ysp); - tabbedPane.setTitleAt(1, "Remote lines"); JPanel wv = ysp.getView(); - + linesPanel.add(ysp,BorderLayout.CENTER); JMenuBar menuBar = new JMenuBar(); getContentPane().add(menuBar, BorderLayout.NORTH); @@ -481,10 +692,9 @@ public class KLALBStateGUI2 extends XFrame { setLocationRelativeTo(null); //setVisible(true); - if (SystemTray.isSupported()) { st = SystemTray.getSystemTray(); - ti = new TrayIcon(bi); + ti = new TrayIcon(UIEnv.getIcon()); ti.setImageAutoSize(true); PopupMenu jpm = new PopupMenu(); MenuItem mix = new MenuItem("open"); @@ -518,9 +728,73 @@ public class KLALBStateGUI2 extends XFrame { //repaint(); + t3 = new Timer("监视器刷新线程",true); t2 = new Timer("仪表盘刷新线程",true); t = new Timer("状态刷新线程",true); createRefreshTask(kc, ysp); + + JPanel panel_1 = new JPanel(); + panel_1.setOpaque(false); + linesPanel.add(panel_1, BorderLayout.NORTH); + panel_1.setLayout(new BorderLayout(0, 0)); + + textField = new JTextField(); + panel_1.add(textField); + textField.setColumns(10); + textField.setToolTipText("Line address:port"); + + JButton btnNewButton = new JButton("Add line"); + btnNewButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + kc.addRemoteLines(new MultipurposeSocketAddress(textField.getText())); + }catch(RuntimeException ex) { + JOptionPane.showMessageDialog(KLALBStateGUI2.this, "Input format error", "Error", JOptionPane.ERROR_MESSAGE); + ex.printStackTrace(); + } + } + }); + panel_1.add(btnNewButton, BorderLayout.EAST); + + JButton btnReconnect = new JButton("ReconnectAll"); + btnReconnect.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + kc.reconnectImmediately(); + } + }); + panel_1.add(btnReconnect, BorderLayout.WEST); + + JPanel panel_3 = new JPanel(); + panel_3.setBackground(new Color(255, 255, 255)); + tabbedPane.addTab("Network graph", null, panel_3, null); + panel_3.setLayout(new BorderLayout(0, 0)); + + JPanel panel_4 = new JPanel(); + panel_3.add(panel_4, BorderLayout.NORTH); + + graph = new NetworkGraphPanel(kc.getIpv6Router().getKlalbRouteProtol()); + graph.setOpaque(false); + JScrollPane jsp=new JScrollPane(graph); + panel_3.add(jsp, BorderLayout.CENTER); + textField.addKeyListener(new KeyListener() { + + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + // TODO 自动生成的方法存根 + + if(e.getKeyCode()==KeyEvent.VK_ENTER) { + btnNewButton.doClick(); + } + } + }); } private void createRefreshTask(KLALBController kc, YScrollPane ysp) { if(tsk!=null) { @@ -548,7 +822,7 @@ public class KLALBStateGUI2 extends XFrame { } } } - TPanel2 tp=new TPanel2(ent); + TPanel2 tp=new TPanel2(ent,kc); tp.setVisible(showoffline.isSelected()||ent.getMonitor().getState()==MonitorData.ONLINE); ysp.getView().add(tp); } @@ -563,6 +837,7 @@ public class KLALBStateGUI2 extends XFrame { }*/ if(kc.getLines().contains(((TPanel2) tp).getTunnel())) { try { + if(tp.isVisible()) ((TPanel2) tp).updateTraffic(); }catch(RuntimeException e) { e.printStackTrace(); @@ -576,7 +851,7 @@ public class KLALBStateGUI2 extends XFrame { //repaint(); } }; - t.scheduleAtFixedRate(tsk, 200, 100); + t.scheduleAtFixedRate(tsk, 200, 500); if(tsk2!=null) { tsk2.cancel(); } @@ -584,13 +859,53 @@ public class KLALBStateGUI2 extends XFrame { @Override public void run() { + double outload=kc.getLinkMonitor().getOutSpeed()*100.0/kc.getLinkMonitor().getOutSpeedMax2(); + if(Double.isFinite(outload)) { upSpeedText.setLabel(KLALBUtils.bytesUnit(kc.getLinkMonitor().getOutSpeedAvg())+"/s"); - upSpeed.setValue(upSpeed.getValue().doubleValue()*0.95+kc.getLinkMonitor().getOutSpeed()*100.0/(50*1024*1024)*0.05); - - downSpeedText.setLabel(KLALBUtils.bytesUnit(kc.getLinkMonitor().getInSpeedAvg())+"/s"); - downSpeed.setValue(downSpeed.getValue().doubleValue()*0.95+kc.getLinkMonitor().getInSpeed()*100.0/(50*1024*1024)*0.05); + upSpeed.setValue(Math.min(upSpeed.getValue().doubleValue()*0.98+outload*0.02,101.0)); + } - double outefi=kc.getDatatMonitor().getOutSpeedAvg2()*100.0D/kc.getLinkMonitor().getOutSpeedAvg2(); + double inload=kc.getLinkMonitor().getInSpeed()*100.0/kc.getLinkMonitor().getInSpeedMax2(); + if(Double.isFinite(inload)) { + downSpeedText.setLabel(KLALBUtils.bytesUnit(kc.getLinkMonitor().getInSpeedAvg())+"/s"); + downSpeed.setValue(Math.min(downSpeed.getValue().doubleValue()*0.98+inload*0.02,101.0)); + } + + double outPPSload=kc.getLinkMonitor().getOutPPS()*100.0/kc.getLinkMonitor().getOutPPSMax2(); + if(Double.isFinite(outPPSload)) { + upPPSText.setLabel(KLALBUtils.defaultUnit(kc.getLinkMonitor().getOutPPSAvg())+"PPS"); + upPPS.setValue(Math.min(upPPS.getValue().doubleValue()*0.98+outPPSload*0.02,101.0)); + } + + double inPPSload=kc.getLinkMonitor().getInPPS()*100.0/kc.getLinkMonitor().getInPPSMax2(); + if(Double.isFinite(inPPSload)) { + downPPSText.setLabel(KLALBUtils.defaultUnit(kc.getLinkMonitor().getInPPSAvg())+"PPS"); + downPPS.setValue(Math.min(downPPS.getValue().doubleValue()*0.98+inPPSload*0.02,101.0)); + } + + + + double outload1=kc.getDatatMonitor().getOutSpeed()*100.0/kc.getLinkMonitor().getOutSpeedMax2(); + if(Double.isFinite(outload1)) { + upDataSpeed.setValue(Math.min(upDataSpeed.getValue().doubleValue()*0.98+outload1*0.02,101.0)); + } + + double inload1=kc.getDatatMonitor().getInSpeed()*100.0/kc.getLinkMonitor().getInSpeedMax2(); + if(Double.isFinite(inload1)) { + downDataSpeed.setValue(Math.min(downDataSpeed.getValue().doubleValue()*0.98+inload1*0.02,101.0)); + } + + double outPPSload1=kc.getDatatMonitor().getOutPPS()*100.0/kc.getLinkMonitor().getOutPPSMax2(); + if(Double.isFinite(outPPSload1)) { + upDataPPS.setValue(Math.min(upDataPPS.getValue().doubleValue()*0.98+outPPSload1*0.02,101.0)); + } + + double inPPSload1=kc.getDatatMonitor().getInPPS()*100.0/kc.getLinkMonitor().getInPPSMax2(); + if(Double.isFinite(inPPSload1)) { + downDataPPS.setValue(Math.min(downDataPPS.getValue().doubleValue()*0.98+inPPSload1*0.02,101.0)); + } + + /*double outefi=kc.getDatatMonitor().getOutSpeedAvg2()*100.0D/kc.getLinkMonitor().getOutSpeedAvg2(); if(Double.isFinite(outefi)) { upEfficiency.setValue(upEfficiency.getValue().doubleValue()*0.95+ outefi*0.05); upEfficiencyText.setLabel(String.format("%.1f", upEfficiency.getValue().doubleValue())+"%"); @@ -600,6 +915,14 @@ public class KLALBStateGUI2 extends XFrame { if(Double.isFinite(inefi)) { downEfficiency.setValue(downEfficiency.getValue().doubleValue()*0.95+ inefi*0.05); downEfficiencyText.setLabel(String.format("%.1f", downEfficiency.getValue().doubleValue())+"%"); + }*/ + String contt=Long.toString( kc.getIpv6Router().getKlalbRouteProtol().getDevicesFound()); + if(!contt.equals(devicesOnline.getText())) { + devicesOnline.setText(contt); + } + String address=kc.getSelf().getHostAddress(); + if(!address.equals(addressField.getText())) { + addressField.setText(address); } } }; @@ -625,7 +948,42 @@ public class KLALBStateGUI2 extends XFrame { } } }; - t.scheduleAtFixedRate(tsk3, 200, 20); + t3.scheduleAtFixedRate(tsk3, 200, 200); + + if(tsk4!=null) { + tsk4.cancel(); + } + tsk4=new TimerTask() { + + @Override + public void run() { + Component[] count=ysp.getView().getComponents(); + for (int i = 0; i < count.length; i++) { + Component tp=count[i]; + if(tp instanceof TPanel2) { + try { + ((TPanel2) tp).getMdg().recordData(); + }catch(RuntimeException e) { + e.printStackTrace(); + } + } + } + } + }; + t3.scheduleAtFixedRate(tsk4, 200, 10); + if(tsk5!=null) { + tsk5.cancel(); + } + tsk5=new TimerTask() { + + @Override + public void run() { + if(graph.isVisible()) + graph.repaint(); + } + }; + t.scheduleAtFixedRate(tsk5, 200, 2000); + //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void close() { diff --git a/src/org/kne/cloud/network/klalb/LineMonitorGUI.java b/src/org/kne/cloud/network/klalb/ui/LineMonitorGUI.java similarity index 69% rename from src/org/kne/cloud/network/klalb/LineMonitorGUI.java rename to src/org/kne/cloud/network/klalb/ui/LineMonitorGUI.java index 6e7d37b..0daeaaa 100644 --- a/src/org/kne/cloud/network/klalb/LineMonitorGUI.java +++ b/src/org/kne/cloud/network/klalb/ui/LineMonitorGUI.java @@ -1,4 +1,4 @@ -package org.kne.cloud.network.klalb; +package org.kne.cloud.network.klalb.ui; import java.awt.Color; import java.awt.Dimension; @@ -16,12 +16,15 @@ import javax.swing.border.LineBorder; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; +import org.jfree.chart.ChartRenderingInfo; import org.jfree.chart.JFreeChart; import org.jfree.data.time.Millisecond; import org.jfree.data.time.RegularTimePeriod; import org.jfree.data.time.TimePeriod; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; +import org.kne.cloud.network.ipv6.Inet6AddressGroup; +import org.kne.cloud.network.klalb.KLALBRemoteLine; import org.kne.cloud.network.monitor.MonitorData; import org.kne.ui.XFrame; @@ -44,8 +47,8 @@ public class LineMonitorGUI extends XFrame{ private TimeSeries delayup=new TimeSeries("Upload delay"); private TimeSeries delaydown=new TimeSeries("Download delay"); - private TimeSeries delayupmin=new TimeSeries("Upload delay minimum"); - private TimeSeries delaydownmin=new TimeSeries("Download delay minimum"); + //private TimeSeries delayupmin=new TimeSeries("Upload delay minimum"); + //private TimeSeries delaydownmin=new TimeSeries("Download delay minimum"); private KLALBRemoteLine tr; private JTextField vaddrs; @@ -60,12 +63,11 @@ public class LineMonitorGUI extends XFrame{ setSize(700, 700); setLocationRelativeTo(null); - Image bi=KLALBStateGUI2.getKLALBIcon(); - if(bi!=null) - setIconImage(bi); + setIconImage(UIEnv.getIcon()); setTitle("Line Monitor:"+t.getMonitor().getName()); - setTitleColor(new Color(255, 255, 255, 250)); - //getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f)); + setTitleColor(UIEnv.getDefaultTitleColor()); + getContentPane().setBackground(UIEnv.getDefaultBackgroundColor()); + getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f)); getTitlepanel().setBorder(new LineBorder(Color.LIGHT_GRAY)); JPanel jp=new JPanel(); @@ -80,6 +82,7 @@ public class LineMonitorGUI extends XFrame{ jfc.getXYPlot().setBackgroundPaint(Color.BLACK); jfc.getXYPlot().getRenderer().setSeriesPaint(0,Color.RED); jfc.getXYPlot().getRenderer().setSeriesPaint(1,Color.GREEN); + changeFont(jfc); spdp = new JLabel(); spdp.setBorder(new LineBorder(Color.DARK_GRAY)); jp.add(spdp); @@ -88,8 +91,8 @@ public class LineMonitorGUI extends XFrame{ tsce.addSeries(delayup); tsce.addSeries(delaydown); - tsce.addSeries(delayupmin); - tsce.addSeries(delaydownmin); + //tsce.addSeries(delayupmin); + //tsce.addSeries(delaydownmin); jfce = ChartFactory.createTimeSeriesChart("Delay monitor", "Time(s)", "Delay(ms)", tsce); jfce.getXYPlot().getDomainAxis().setFixedAutoRange(5000); jfce.getXYPlot().setBackgroundPaint(Color.BLACK); @@ -97,10 +100,11 @@ public class LineMonitorGUI extends XFrame{ jfce.getXYPlot().getRenderer().setSeriesPaint(1,Color.GREEN); BasicStroke dotted = new BasicStroke(2, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 0, new float[]{0,6,0,6}, 0); - jfce.getXYPlot().getRenderer().setSeriesPaint(2,Color.RED); + /*jfce.getXYPlot().getRenderer().setSeriesPaint(2,Color.RED); jfce.getXYPlot().getRenderer().setSeriesStroke(2, dotted); jfce.getXYPlot().getRenderer().setSeriesPaint(3,Color.GREEN); - jfce.getXYPlot().getRenderer().setSeriesStroke(3, dotted); + jfce.getXYPlot().getRenderer().setSeriesStroke(3, dotted);*/ + changeFont(jfce); delp = new JLabel(); delp.setBorder(new LineBorder(Color.DARK_GRAY)); jp.add(delp); @@ -118,6 +122,7 @@ public class LineMonitorGUI extends XFrame{ vaddrs.setColumns(10); JPanel panel_1 = new JPanel(); + panel_1.setOpaque(false); panel.add(panel_1); Dimension dms=new Dimension(140, 20); JButton btnNewButton = new JButton("Force disconnect"); @@ -140,7 +145,7 @@ public class LineMonitorGUI extends XFrame{ btnNewButton_1.setForeground(Color.GREEN); panel_1.add(btnNewButton_1); - JButton btnNewButton_2 = new JButton("Pressure test"); + /*JButton btnNewButton_2 = new JButton("Pressure test"); btnNewButton_2.setPreferredSize(dms); btnNewButton_2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -148,7 +153,15 @@ public class LineMonitorGUI extends XFrame{ } }); panel_1.add(btnNewButton_2); - btnNewButton_2.setForeground(Color.BLUE); + btnNewButton_2.setForeground(Color.BLUE);*/ + } + private void changeFont(JFreeChart jfc2) { + jfc2.getTitle().setFont(UIEnv.getFont().deriveFont(16.0f)); + jfc2.getLegend().setItemFont(UIEnv.getFont()); + jfc2.getXYPlot().getRangeAxis().setLabelFont(UIEnv.getFont()); + jfc2.getXYPlot().getRangeAxis().setTickLabelFont(UIEnv.getFont()); + jfc2.getXYPlot().getDomainAxis().setLabelFont(UIEnv.getFont()); + jfc2.getXYPlot().getDomainAxis().setTickLabelFont(UIEnv.getFont()); } public void recordData() { if(isVisible()) { @@ -157,13 +170,13 @@ public class LineMonitorGUI extends XFrame{ spddown.addOrUpdate(ms, tr.getMonitor().getInSpeed()/1024.0); - Millisecond msu= new Millisecond(new Date(System.currentTimeMillis()-(System.nanoTime()- tr.getMonitor().getRecentPingNanoTime())/1000000L)); - delayup.addOrUpdate(msu, tr.getMonitor().getOutDelay()/1000000.0); - delaydown.addOrUpdate(msu, tr.getMonitor().getInDelay()/1000000.0); + //Millisecond msu= new Millisecond(new Date(System.currentTimeMillis()-(System.nanoTime()- tr.getMonitor().getRecentPingNanoTime())/1000000L)); + delayup.addOrUpdate(ms, (tr.getMonitor().getOutDelay()+tr.getMonitor().getQueueingDelay())/1000000.0); + delaydown.addOrUpdate(ms, tr.getMonitor().getInDelay()/1000000.0); //Millisecond msup= new Millisecond(new Date( tr.getMonitor().getUpdateDelayTime()+tr.getMonitor().getOutDelay()/1000000L)); - delayupmin.addOrUpdate(ms, tr.getMonitor().getOutDelayPredicted()/1000000.0); - delaydownmin.addOrUpdate(ms, tr.getMonitor().getInDelayPredicted()/1000000.0); + //delayupmin.addOrUpdate(ms, tr.getMonitor().getQueueingDelay()/1000000.0); + //delaydownmin.addOrUpdate(ms, tr.getMonitor().getInDelayPredicted()/1000000.0); } } @@ -178,26 +191,33 @@ public class LineMonitorGUI extends XFrame{ case MonitorData.ONLINE: getTitlelabel().setForeground(Color.GREEN); - recordData(); - break; default: break; } if(isVisible()) { + //long ax=System.nanoTime(); ImageIcon i1=new ImageIcon(jfc.createBufferedImage(spdp.getWidth(), spdp.getHeight())); ImageIcon i2=new ImageIcon(jfce.createBufferedImage(delp.getWidth(), delp.getHeight())); + //System.out.println(System.nanoTime()-ax); spdp.setIcon(i1); delp.setIcon(i2); //spddown.fireSeriesChanged(); //delaydown.fireSeriesChanged(); - - Inet6Address i6a= tr.getRemoteVaddr(); - if(i6a==null) { - vaddrs.setText("unknown"); + Inet6AddressGroup irg=tr.getRemoteVaddr(); + String text; + if(irg==null) { + + text="unknown"; }else { - vaddrs.setText(i6a.getHostAddress()); + Inet6Address i6a= irg.getAddress(); + + text=i6a.getHostAddress(); + + } + if(!vaddrs.getText().equals(text)) { + vaddrs.setText(text); } } diff --git a/src/org/kne/cloud/network/klalb/ui/NetworkGraphPanel.java b/src/org/kne/cloud/network/klalb/ui/NetworkGraphPanel.java new file mode 100644 index 0000000..2dbc0ff --- /dev/null +++ b/src/org/kne/cloud/network/klalb/ui/NetworkGraphPanel.java @@ -0,0 +1,298 @@ +package org.kne.cloud.network.klalb.ui; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.Dimension2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; +import java.awt.image.ImageObserver; +import java.net.Inet6Address; +import java.text.AttributedCharacterIterator; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; +import java.util.Set; + +import javax.swing.JButton; +import javax.swing.JPanel; + +import org.kne.cloud.network.klalb.KLALBUtils; +import org.kne.cloud.network.srv6.KLALBRoutingProtocol; +import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection; + +public class NetworkGraphPanel extends JPanel { + private KLALBRoutingProtocol routingProtocol; + private Map nodes=new HashMap(); + private List edgeGroups=new ArrayList(); + private static final int nodesize=80; + private class GraphNode{ + private String text; + private Color color; + private int x; + private int y; + + public GraphNode(String text, Color color, int x, int y) { + super(); + this.text = text; + this.color = color; + this.x = x; + this.y = y; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public GraphNode() { + super(); + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + + public void paint(Graphics2D g) { + g.setColor(Color.BLACK); + g.setStroke(new BasicStroke(2.0f)); + g.drawOval(x-nodesize/2, y-nodesize/2, nodesize, nodesize); + g.setFont(UIEnv.getFont().deriveFont(10.0f)); + g.drawString(text, x+nodesize/2, y-nodesize/3); + } + } + private class GraphEdge{ + private GraphNode from; + private GraphNode to; + private LinkDirection linkPath; + + public GraphEdge(GraphNode nfrom, GraphNode nto,LinkDirection lp) { + this.from=nfrom; + this.to=nto; + this.linkPath=lp; + } + + } + private class GraphEdgeGroup{ + private static final double gap=3; + private GraphNode nodeA,nodeB; + private List edges=new ArrayList<>(); + + private boolean match(GraphNode a,GraphNode b) { + if(a.equals( nodeA)&&b.equals( nodeB)) + return true; + if(b.equals( nodeA)&&a.equals( nodeB)) + return true; + return false; + } + + public GraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) { + super(); + this.nodeA = nodeA; + this.nodeB = nodeB; + } + public List getPaths() { + return edges; + } + public void paint(Graphics2D g) { + g.setStroke(new BasicStroke(1.0f)); + + Vector2 nodeAv=new Vector2(nodeA.getX(), nodeA.getY()); + Vector2 nodeBv=new Vector2(nodeB.getX(), nodeB.getY()); + Vector2 vecDir=nodeBv.subtract(nodeAv); + Vector2 vecDirnor=vecDir.normalize(); + Vector2 vecR=vecDirnor.multi(nodesize/2); + + Vector2 vec90nor=new Vector2( -vecDir.y, vecDir.x).normalize(); + + double width=gap*(edges.size()-1); + + Vector2 startPoint=nodeAv.add(vecR).add(vec90nor.multi(width/2)); + Vector2 endPoint=nodeBv.subtract(vecR).add(vec90nor.multi(width/2)); + //System.out.println(width); + for (Iterator iterator = edges.iterator(); iterator.hasNext();) { + GraphEdge graphEdge = (GraphEdge) iterator.next(); + + //System.out.println(vec90nor); + + g.setColor(KLALBUtils.getColorByLoadPercentage(graphEdge.linkPath.getSpeed()*100f/graphEdge.linkPath.getBandwidth())); + + if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) ) + drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g); + + + if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) ) + drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g); + + startPoint=startPoint.subtract(vec90nor.multi(gap)); + endPoint=endPoint.subtract(vec90nor.multi(gap)); + } + + //g.drawLine(nodeA.getX(), nodeA.getY(), nodeB.getX(), nodeB.getY()); + + } + + public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2) + { + + double H = 5; // 箭头高度 + double L = 2; // 底边的一半 + int x3 = 0; + int y3 = 0; + int x4 = 0; + int y4 = 0; + double awrad = Math.atan(L / H); // 箭头角度 + double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度 + double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len); + double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len); + double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点 + double y_3 = ey - arrXY_1[1]; + double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点 + double y_4 = ey - arrXY_2[1]; + + Double X3 = new Double(x_3); + x3 = X3.intValue(); + Double Y3 = new Double(y_3); + y3 = Y3.intValue(); + Double X4 = new Double(x_4); + x4 = X4.intValue(); + Double Y4 = new Double(y_4); + y4 = Y4.intValue(); + // 画线 + g2.drawLine(sx, sy, ex, ey); + // + GeneralPath triangle = new GeneralPath(); + triangle.moveTo(ex, ey); + triangle.lineTo(x3, y3); + triangle.lineTo(x4, y4); + triangle.closePath(); + //实心箭头 + g2.fill(triangle); + //非实心箭头 + //g2.draw(triangle); + + } + + // 计算 + public static double[] rotateVec(int px, int py, double ang, + boolean isChLen, double newLen) { + + double mathstr[] = new double[2]; + // 矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度 + double vx = px * Math.cos(ang) - py * Math.sin(ang); + double vy = px * Math.sin(ang) + py * Math.cos(ang); + if (isChLen) { + double d = Math.sqrt(vx * vx + vy * vy); + vx = vx / d * newLen; + vy = vy / d * newLen; + mathstr[0] = vx; + mathstr[1] = vy; + } + return mathstr; + } + + } + public NetworkGraphPanel(KLALBRoutingProtocol routingProtocol) { + super(); + this.routingProtocol = routingProtocol; + //setSize(10000, 10000); + //setPreferredSize(getSize()); + } + @Override + public void paint(Graphics g) { + super.paint(g); + loadNodes(); + + Graphics2D g2d=(Graphics2D)g; + + for (Iterator iterator = edgeGroups.iterator(); iterator.hasNext();) { + GraphEdgeGroup graphNode = (GraphEdgeGroup) iterator.next(); + graphNode.paint(g2d); + } + + for (Iterator iterator = nodes.values().iterator(); iterator.hasNext();) { + GraphNode graphNode = (GraphNode) iterator.next(); + graphNode.paint(g2d); + } + + + } + Random r=new Random(); + private void loadNodes() { + Map addr= routingProtocol.getAddresses(); + Set ks=addr.keySet(); + for (Iterator iterator = ks.iterator(); iterator.hasNext();) { + Inet6Address inet6Address = (Inet6Address) iterator.next(); + if(!nodes.containsKey(inet6Address)) + nodes.put(inet6Address,new GraphNode(inet6Address.getHostAddress(),Color.BLACK,r.nextInt(50,getWidth()-100),r.nextInt(50,getHeight()-50))); + } + Set kns=nodes.keySet(); + for (Iterator iterator = kns.iterator(); iterator.hasNext();) { + Inet6Address inet6Address = (Inet6Address) iterator.next(); + if(!addr.containsKey(inet6Address)) { + iterator.remove(); + } + } + //System.out.println("------------------------------------"); + edgeGroups.clear(); + Map> addr1= routingProtocol.getPaths(); + Set>> salink=addr1.entrySet(); + for (Iterator>> iterator = salink.iterator(); iterator.hasNext();) { + Entry> entry = (Entry>) iterator.next(); + Setlps=entry.getValue(); + for (Iterator iterator2 = lps.iterator(); iterator2.hasNext();) { + LinkDirection linkPath = (LinkDirection) iterator2.next(); + //System.out.println(linkPath); + GraphNode nfrom=nodes.get(linkPath.getFromLocator()); + GraphNode nto=nodes.get(linkPath.getToLocator()); + GraphEdgeGroup group=getGroup(nfrom, nto); + group.getPaths().add(new GraphEdge(nfrom,nto,linkPath)); + } + } + } + + private GraphEdgeGroup getGroup(GraphNode a,GraphNode b) { + for (Iterator iterator = edgeGroups.iterator(); iterator.hasNext();) { + GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next(); + if(graphEdgeGroup.match(a,b)) { + return graphEdgeGroup; + } + } + GraphEdgeGroup ng=new GraphEdgeGroup(a, b); + edgeGroups.add(ng); + return ng; + } +} diff --git a/src/org/kne/cloud/network/klalb/TPanel.java b/src/org/kne/cloud/network/klalb/ui/TPanel.java similarity index 93% rename from src/org/kne/cloud/network/klalb/TPanel.java rename to src/org/kne/cloud/network/klalb/ui/TPanel.java index edff62b..121db5d 100644 --- a/src/org/kne/cloud/network/klalb/TPanel.java +++ b/src/org/kne/cloud/network/klalb/ui/TPanel.java @@ -1,4 +1,4 @@ -package org.kne.cloud.network.klalb; +package org.kne.cloud.network.klalb.ui; import javax.swing.JPanel; import javax.swing.JLabel; @@ -8,6 +8,7 @@ import java.awt.Color; import javax.swing.SwingConstants; import javax.swing.border.LineBorder; +import org.kne.cloud.network.klalb.KLALBRemoteLine; import org.kne.cloud.network.monitor.MonitorData; import java.awt.Font; diff --git a/src/org/kne/cloud/network/klalb/TPanel2.java b/src/org/kne/cloud/network/klalb/ui/TPanel2.java similarity index 85% rename from src/org/kne/cloud/network/klalb/TPanel2.java rename to src/org/kne/cloud/network/klalb/ui/TPanel2.java index 05c5981..8df7561 100644 --- a/src/org/kne/cloud/network/klalb/TPanel2.java +++ b/src/org/kne/cloud/network/klalb/ui/TPanel2.java @@ -1,4 +1,4 @@ -package org.kne.cloud.network.klalb; +package org.kne.cloud.network.klalb.ui; import javax.swing.JPanel; import javax.swing.JLabel; @@ -9,10 +9,15 @@ import java.awt.Dimension; import javax.swing.SwingConstants; import javax.swing.border.LineBorder; +import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.klalb.KLALBController; +import org.kne.cloud.network.klalb.KLALBRemoteLine; +import org.kne.cloud.network.klalb.KLALBUtils; import org.kne.cloud.network.monitor.MonitorData; import java.awt.Font; import java.awt.Image; +import java.awt.MenuItem; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; @@ -66,7 +71,7 @@ public class TPanel2 extends JPanel { /** * @wbp.parser.constructor */ - public TPanel2(KLALBRemoteLine t) { + public TPanel2(KLALBRemoteLine t,KLALBController kc) { this.tunnel = t; //setOpaque(false); setBackground(Color.WHITE); @@ -183,6 +188,19 @@ public class TPanel2 extends JPanel { } }); + + + mntmNewMenuItem3 = new JMenuItem("Try reconnect"); + popupMenu.add(mntmNewMenuItem3); + mntmNewMenuItem3.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + tunnel.reconnectImmediately(); + + } + }); + mntmNewMenuItem3.setForeground(Color.GREEN); mntmNewMenuItem2 = new JMenuItem("Force disconnect"); popupMenu.add(mntmNewMenuItem2); mntmNewMenuItem2.addActionListener(new ActionListener() { @@ -194,17 +212,21 @@ public class TPanel2 extends JPanel { }); mntmNewMenuItem2.setForeground(Color.RED); - mntmNewMenuItem3 = new JMenuItem("Force reconnect"); - popupMenu.add(mntmNewMenuItem3); - mntmNewMenuItem3.addActionListener(new ActionListener() { + JMenuItem mi=new JMenuItem("Remove line"); + popupMenu.add(mi); + mi.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - tunnel.reconnectImmediately(); - + MultipurposeSocketAddress mtar=tunnel.getSocketAddress(); + if(mtar!=null) { + kc.removeRemoteLines(mtar); + }else { + tunnel.close(); + } } - }); - mntmNewMenuItem3.setForeground(Color.GREEN); + }); + mi.setForeground(Color.RED); mdg=new LineMonitorGUI(t); addMouseListener(new MouseListener() { @@ -282,10 +304,10 @@ public class TPanel2 extends JPanel { private void updateText() { - targup.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getOutTraffic()) + "\u2191 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getOutSpeed()) + "/s\u2191 "+ String.format("%.1f", tunnel.getMonitor().getOutDelay()/1000000.0) + "ms"); - targdown.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getInTraffic()) + "\u2193 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getInSpeed()) + "/s\u2193 " + String.format("%.1f", tunnel.getMonitor().getInDelay()/1000000.0) + "ms"); + targup.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getOutTraffic()) + "\u2191 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getOutSpeedAvg()) + "/s\u2191 "+ String.format("%.1f", tunnel.getMonitor().getOutDelay()/1000000.0) + "ms"); + targdown.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getInTraffic()) + "\u2193 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getInSpeedAvg()) + "/s\u2193 " + String.format("%.1f", tunnel.getMonitor().getInDelay()/1000000.0) + "ms"); - if(tunnel.getMonitor().getOutSpeed()>2048||tunnel.getMonitor().getInSpeed()>2048) { + if(tunnel.getMonitor().getOutSpeed()>4096||tunnel.getMonitor().getInSpeed()>4096) { lblNewLabel_2.setBackground(Color.ORANGE); }else { lblNewLabel_2.setBackground(Color.LIGHT_GRAY); @@ -327,7 +349,7 @@ public class TPanel2 extends JPanel { lblNewLabel_1.setBackground(Color.GREEN); - Inet6Address unvar=tunnel.getRemoteVaddr(); + Inet6Address unvar=tunnel.getRemoteVaddr().getAddress(); if(unvar==null) { this.vaddr.setText("unknown"); }else { diff --git a/src/org/kne/cloud/network/klalb/ui/UIEnv.java b/src/org/kne/cloud/network/klalb/ui/UIEnv.java new file mode 100644 index 0000000..59830ab --- /dev/null +++ b/src/org/kne/cloud/network/klalb/ui/UIEnv.java @@ -0,0 +1,144 @@ +package org.kne.cloud.network.klalb.ui; + +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Font; +import java.awt.FontFormatException; +import java.awt.Image; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.geom.AffineTransform; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; + +import javax.swing.JButton; +import javax.swing.JColorChooser; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.plaf.ColorChooserUI; +public class UIEnv { + private static Font font; + private static Image icon ; + private static Color defaultcolor=new Color(207,218,223);//new Color(207,218,223) + private static Color selectedcolor=new Color(207/2,218/2,223/2); + + private static ResourceBundle rsb; + public static void setRsb(String xrsb) throws IOException { + rsb=new PropertyResourceBundle(UIEnv.class.getResourceAsStream("/knemcl_"+xrsb+".properties")); + } + + public static void setRsb(ResourceBundle xrsb) { + rsb=xrsb; + } + public static ResourceBundle getRsb() { + if(rsb==null) { + try { + rsb=new PropertyResourceBundle(UIEnv.class.getResourceAsStream("/knemcl_en_US.properties")); + } catch (IOException e) { + e.printStackTrace(); + } + } + return rsb; + } + //private static Color tpccolor=new Color(250,250,250,190); + public static Color getDefaultcolor() { + return defaultcolor; + } + public static void setDefaultColor(Color defaultcolor) { + UIEnv.defaultcolor = defaultcolor; + } + + public static Color titlecolor=new Color(0,0,100,200); + + public static Color backgroundcolor=new Color(0,0,100,255); + public static Color getDefaultTitleColor() { + return titlecolor; + } + + public static Color getDefaultBackgroundColor() { + return backgroundcolor; + } + + public static Color getHalfTransparentDefaultColor() { + return new Color(defaultcolor.getRed(), defaultcolor.getGreen(), defaultcolor.getBlue(), 210); + } + public static void inituie(){ + /*try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } catch (ClassNotFoundException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } catch (InstantiationException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } catch (UnsupportedLookAndFeelException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + }*/ + font=new Font("微软雅黑",Font.PLAIN , 12); + /*try { + font = Font.createFont(Font.PLAIN, UIEnv.class.getResourceAsStream("/assets/SourceHanSansCN-Light.otf")).deriveFont(13f); + } catch (FontFormatException e1) { + e1.printStackTrace(); + } catch (IOException e1) { + // TODO 自动生成的 catch 块 + e1.printStackTrace(); + }*/ + + java.util.Enumeration keys = UIManager.getDefaults().keys(); + while (keys.hasMoreElements()) { + Object key = keys.nextElement(); + Object value = UIManager.get(key); + if (value instanceof javax.swing.plaf.FontUIResource) { + UIManager.put(key, font); + } + } + icon=Toolkit.getDefaultToolkit().getImage( + UIEnv.class.getResource("/assets/KLALB.png")); + } + public static void defbut(JButton start) { + if(font==null) + inituie(); + start.setBorderPainted(false); + start.setForeground(Color.WHITE); + start.setFont(font.deriveFont(Font.BOLD, 18)); + start.setBackground(defaultcolor); + } + public static void defbut(JButton start,int fontsize) { + if(font==null) + inituie(); + start.setBorderPainted(false); + start.setForeground(Color.WHITE); + start.setFont(font.deriveFont(Font.BOLD, fontsize)); + start.setBackground(defaultcolor); + } + public static Font getFont(){ + if(icon==null) + inituie(); + return font; + } + public static Image getIcon(){ + if(icon==null) + inituie(); + return icon; + } + + public static Color getSelectedcolor() { + return selectedcolor; + } + public static void setSelectedcolor(Color selectedcolor) { + UIEnv.selectedcolor = selectedcolor; + } + /*public static Color getHalfTransparentColor() { + return tpccolor; + }*/ + +} diff --git a/src/org/kne/cloud/network/klalb/ui/Vector2.java b/src/org/kne/cloud/network/klalb/ui/Vector2.java new file mode 100644 index 0000000..df993d8 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/ui/Vector2.java @@ -0,0 +1,99 @@ +package org.kne.cloud.network.klalb.ui; + + +public class Vector2 { + public double x,y; + + public Vector2(double x, double y) { + super(); + this.x = x; + this.y = y; + } + + + + public Vector2 Set(double x, double y) { + this.x = x; + this.y = y; + return this; + } + + public Vector2 normalize()//ʹ����Ϊ1����Ϊ��λ���� + { + double l=Math.sqrt(x*x+y*y); + return l==0?new Vector2(0,0): new Vector2(x / l, y / l); + } + public Vector2 normalizeold()//ʹ����Ϊ1����Ϊ��λ���� + { + double l=Math.sqrt(x*x+y*y); + if(l==0){ + x=y=0; + }else{ + this.x = x / l; + this.y = y / l; + } + return this; + } + public Vector2 add(Vector2 vec)//�� + { + + return new Vector2(this.x + vec.x,this.y + vec.y); + } + public Vector2 subtract(Vector2 vec)//�� + { + return new Vector2(this.x - vec.x,this.y - vec.y); + } + public Vector2 multi(double m)//�������� + { + return new Vector2(this.x*m, this.y*m); + } + public double dot(Vector2 vec)//������� + { + return vec.x*x + vec.y*y ; + } + public Vector2 opposite(){//�෴ + return new Vector2(-x, -y); + } + public Vector2 signs() {//�������� + return new Vector2(signs(x),signs(y)); + } + + public static int signs(double z2) { + return z2>0?1:(z2<0?-1:0); + } + + + + public Vector2 rotate(Vector2 degree){ + + double sita=sita()+degree.sita(); + double l=Length(); + return new Vector2(l*Math.cos(sita), l*Math.sin(sita)); + } + public Vector2 rotate(float degree){ + + double sita=sita()+degree; + double l=Length(); + return new Vector2(l*Math.cos(sita), l*Math.sin(sita)); + } + public float sita() { + double sita; + if(x<0){ + sita=Math.atan(y/x)-180; + }else if(x>0){ + sita=Math.atan(y/x); + }else{ + sita=y>=0?90:90-180; + } + return (float) sita; + } + public double Length() { + + return Math.sqrt(x*x+y*y); + } + @Override + public String toString() { + return "Vector2 [x="+x+", y="+y+"]"; + } + +} diff --git a/src/org/kne/cloud/network/minecraft/MinecraftScanner.java b/src/org/kne/cloud/network/minecraft/MinecraftScanner.java index 6926fc7..c654940 100644 --- a/src/org/kne/cloud/network/minecraft/MinecraftScanner.java +++ b/src/org/kne/cloud/network/minecraft/MinecraftScanner.java @@ -7,6 +7,7 @@ import java.util.function.BiConsumer; import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.scanner.InetAddressRange; import org.kne.cloud.network.scanner.PortRange; +import org.kne.cloud.network.scanner.ScanRange; import org.kne.cloud.network.scanner.TCPNetworkScanner; public class MinecraftScanner extends TCPNetworkScanner{ @@ -19,7 +20,7 @@ public class MinecraftScanner extends TCPNetworkScanner{ public void setMinecraftConsumer(BiConsumer minecraftConsumer) { this.minecraftConsumer = minecraftConsumer; } - public MinecraftScanner() { + { super.setConsumer((mpsa,s)->{ if(s!=null) { try { @@ -28,9 +29,13 @@ public class MinecraftScanner extends TCPNetworkScanner{ minecraftConsumer.accept(mpsa, msp); } } catch (UnknownHostException e) { - e.printStackTrace(); + if(minecraftConsumer!=null) { + minecraftConsumer.accept(mpsa, null); + } } catch (Exception e) { - e.printStackTrace(); + if(minecraftConsumer!=null) { + minecraftConsumer.accept(mpsa, null); + } } }else { if(minecraftConsumer!=null) { @@ -39,35 +44,20 @@ public class MinecraftScanner extends TCPNetworkScanner{ } }); } + public MinecraftScanner() { + + } public MinecraftScanner(int connectTimeout, int soTimeout) { super(connectTimeout, soTimeout); - super.setConsumer((mpsa,s)->{ - if(s!=null) { - try { - MinecraftServerPinger msp=new MinecraftServerPinger(mpsa,s); - if(minecraftConsumer!=null) { - minecraftConsumer.accept(mpsa, msp); - } - } catch (UnknownHostException e) { - e.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } - }else { - if(minecraftConsumer!=null) { - minecraftConsumer.accept(mpsa, null); - } - } - }); + } public static void main(String[] args) throws UnknownHostException { MinecraftScanner tcn = new MinecraftScanner(); - tcn.getPortRanges().add(new PortRange(25565)); - tcn.getPortRanges().add(new PortRange(34000, 37000)); - tcn.getAddressRanges().add(new InetAddressRange("192.168.0.1","192.168.0.255")); + tcn.getRanges().add(new ScanRange(new InetAddressRange("127.0.0.1","127.0.0.2"),new PortRange(25565,37000))); tcn.setMinecraftConsumer((mpsa,mc)->{ + if(mc!=null) System.out.println(mc); }); tcn.setProcessConsumer((f)->{//System.out.println(f); diff --git a/src/org/kne/cloud/network/minecraft/MinecraftServerPinger.java b/src/org/kne/cloud/network/minecraft/MinecraftServerPinger.java index f8d8c06..fe18e31 100644 --- a/src/org/kne/cloud/network/minecraft/MinecraftServerPinger.java +++ b/src/org/kne/cloud/network/minecraft/MinecraftServerPinger.java @@ -3,8 +3,11 @@ package org.kne.cloud.network.minecraft; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.EOFException; +import java.io.Externalizable; import java.io.IOException; import java.io.InputStream; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.io.OutputStream; import java.io.Serializable; import java.io.StringReader; @@ -37,7 +40,7 @@ public class MinecraftServerPinger implements Serializable{ private long latency=-1; private String json; - private BufferedImage icon; + //private BufferedImage icon; private int max; private int online; private String description; @@ -47,6 +50,8 @@ public class MinecraftServerPinger implements Serializable{ private String klalbversion; private Inet6Address klalbvaddr; private int klalbvport; + private String icon; + private transient BufferedImage image; public MinecraftServerPinger(MultipurposeSocketAddress target) throws UnknownHostException, IOException { this(target,target.connectSocket()); @@ -146,12 +151,8 @@ public class MinecraftServerPinger implements Serializable{ if(favicon!=null) { String s=favicon.getAsString(); if(s.startsWith("data:image/png;base64,")){ - s=s.replace("\n", ""); - try { - icon=ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(s.substring("data:image/png;base64,".length())))); - } catch (IOException e) { - e.printStackTrace(); - } + icon=s.replace("\n", ""); + } } /*try { @@ -261,7 +262,15 @@ public class MinecraftServerPinger implements Serializable{ } public BufferedImage getIcon() { - return icon; + if(icon==null) + return null; + if(image==null) + try { + image= ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(icon.substring("data:image/png;base64,".length())))); + } catch (IOException e) { + e.printStackTrace(); + } + return image; } public int getMax() { @@ -305,4 +314,6 @@ public class MinecraftServerPinger implements Serializable{ MinecraftServerPinger sp=new MinecraftServerPinger(MinecraftServerAddress.findAddress("mc.hypixel.cn")); System.out.println(sp); } + + } diff --git a/src/org/kne/cloud/network/minecraft/MinecraftServerScanRange.java b/src/org/kne/cloud/network/minecraft/MinecraftServerScanRange.java new file mode 100644 index 0000000..4880e47 --- /dev/null +++ b/src/org/kne/cloud/network/minecraft/MinecraftServerScanRange.java @@ -0,0 +1,38 @@ +package org.kne.cloud.network.minecraft; + +import java.net.UnknownHostException; + +import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.scanner.InetAddressRange; +import org.kne.cloud.network.scanner.PortRange; +import org.kne.cloud.network.scanner.ScanRange; + +public class MinecraftServerScanRange extends ScanRange { + + public MinecraftServerScanRange(InetAddressRange addressRange, PortRange portRange) { + super(addressRange, portRange); + } + + public MinecraftServerScanRange(MultipurposeSocketAddress begin, MultipurposeSocketAddress end) + throws UnknownHostException { + super(begin, end); + } + + public MinecraftServerScanRange(String range) throws UnknownHostException { + super(range); + } + + @Override + protected void setMsaString(String range) throws UnknownHostException { + String[]sp=range.split("~"); + MultipurposeSocketAddress begin=MinecraftServerAddress.findAddress (sp[0]); + MultipurposeSocketAddress end; + if(sp.length>1) { + end=MinecraftServerAddress.findAddress (sp[1]); + }else { + end=MinecraftServerAddress.findAddress (sp[0]); + } + setMsa(begin, end); + } + +} diff --git a/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftClient.java b/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftClient.java index d621aec..f2a0fb5 100644 --- a/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftClient.java +++ b/src/org/kne/cloud/network/minecraft/SimpleKLALBMinecraftClient.java @@ -18,7 +18,7 @@ import org.kne.cloud.network.SocketToSocketProxy; import org.kne.cloud.network.klalb.CONST; import org.kne.cloud.network.klalb.KLALBController; import org.kne.cloud.network.klalb.KLALBRemoteLine; -import org.kne.cloud.network.klalb.KLALBStateGUI2; +import org.kne.cloud.network.klalb.ui.KLALBStateGUI2; import org.kne.util.AutoProperties; public class SimpleKLALBMinecraftClient { diff --git a/src/org/kne/cloud/network/monitor/MonitorDataImpl.java b/src/org/kne/cloud/network/monitor/MonitorDataImpl.java index 3f48abf..e74ab72 100644 --- a/src/org/kne/cloud/network/monitor/MonitorDataImpl.java +++ b/src/org/kne/cloud/network/monitor/MonitorDataImpl.java @@ -77,9 +77,9 @@ private TimerTask ptt=new TimerTask() { sb.append(name); sb.append('\n'); sb.append(getDsc()); - sb.append('\t'); + /*sb.append('\t'); sb.append((int)(reliability*100)); - sb.append('%'); + sb.append('%');*/ return sb.toString(); } @Override diff --git a/src/org/kne/cloud/network/monitor/QueueingMonitorDataImpl.java b/src/org/kne/cloud/network/monitor/QueueingMonitorDataImpl.java new file mode 100644 index 0000000..1494bba --- /dev/null +++ b/src/org/kne/cloud/network/monitor/QueueingMonitorDataImpl.java @@ -0,0 +1,13 @@ +package org.kne.cloud.network.monitor; + +public class QueueingMonitorDataImpl extends SpeedAndTrafficAndDelayMonitorDataImpl { + private long queueingDelay; + + public long getQueueingDelay() { + return queueingDelay; + } + + public void setQueueingDelay(long queueingDelay) { + this.queueingDelay = queueingDelay; + } +} diff --git a/src/org/kne/cloud/network/monitor/SpeedAndTrafficAndDelayMonitorDataImpl.java b/src/org/kne/cloud/network/monitor/SpeedAndTrafficAndDelayMonitorDataImpl.java index 616cd94..e8a3294 100644 --- a/src/org/kne/cloud/network/monitor/SpeedAndTrafficAndDelayMonitorDataImpl.java +++ b/src/org/kne/cloud/network/monitor/SpeedAndTrafficAndDelayMonitorDataImpl.java @@ -3,27 +3,24 @@ package org.kne.cloud.network.monitor; public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonitorDataImpl implements SpeedAndTrafficMonitorData,DelayMonitorData{ - @Override - protected void createTask() { - } - public void updateSpeedSync(){ - tmt.run(); - } private volatile long outDelay; private volatile long outDelayMin=Long.MAX_VALUE; + private volatile long outDelayAvg=Long.MAX_VALUE; private long outDelayOld; private volatile long outJitter; private volatile long inDelay; private volatile long inDelayMin=Long.MAX_VALUE; + private volatile long inDelayAvg=Long.MAX_VALUE; private long inDelayOld; private volatile long inJitter; private volatile long latency; private volatile long latencyMin=Long.MAX_VALUE; + private volatile long latencyAvg=Long.MAX_VALUE; private long latencyOld; private volatile long totalJitter; @@ -32,6 +29,19 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit private volatile long recentPingNanoTime; + + + public long getOutDelayAvg() { + return outDelayAvg; + } + public long getInDelayAvg() { + return inDelayAvg; + } + public long getLatencyAvg() { + return latencyAvg; + } + + public long getRecentPingNanoTime() { return recentPingNanoTime; } @@ -46,18 +56,29 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit @Override public void setOutDelay(long delay) { this.outDelay=delay; + if(outDelayAvg==Long.MAX_VALUE) { + outDelayAvg=delay; + }else { + outDelayAvg=(outDelayAvg*9999+delay)/10000; + } if(outDelayMin==Long.MAX_VALUE||delay<=outDelayMin) { outDelayMin=delay; }else{ outDelayMin=(outDelayMin*9999+delay)/10000; } this.latency=outDelay+inDelay; + + if(latencyAvg==Long.MAX_VALUE) { + latencyAvg=latency; + }else { + latencyAvg=(latencyAvg*9999+latency)/10000; + } if(latencyMin==Long.MAX_VALUE||latency<= latencyMin) { latencyMin=latency; }else { latencyMin=(latencyMin*9999+latency)/10000; } - outDelayPredicted=outDelay+(outDelay-outDelayOld); + outDelayPredicted=outDelay; updateOutJitter(); updateTotalJitter(); } @@ -70,18 +91,28 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit @Override public void setInDelay(long delay) { this.inDelay=delay; + if(inDelayAvg==Long.MAX_VALUE) { + inDelayAvg=latency; + }else { + inDelayAvg=(inDelayAvg*9999+delay)/10000; + } if(inDelayMin==Long.MAX_VALUE||delay<=inDelayMin) { inDelayMin=delay; }else{ inDelayMin=(inDelayMin*9999+delay)/10000; } this.latency=outDelay+inDelay; + if(latencyAvg==Long.MAX_VALUE) { + latencyAvg=latency; + }else { + latencyAvg=(latencyAvg*9999+latency)/10000; + } if(latencyMin==Long.MAX_VALUE||latency<= latencyMin) { latencyMin=latency; }else { latencyMin=(latencyMin*9999+latency)/10000; } - inDelayPredicted=inDelay+(inDelay-inDelayOld); + inDelayPredicted=inDelay; updateInJitter(); updateTotalJitter(); } @@ -95,6 +126,11 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit @Override public void setLatency(long latency) { this.latency=latency; + if(latencyAvg==Long.MAX_VALUE) { + latencyAvg=latency; + }else { + latencyAvg=(latencyAvg*9999+latency)/10000; + } if(latencyMin==Long.MAX_VALUE||latency<= latencyMin) { latencyMin=latency; }else { @@ -102,19 +138,30 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit } long tmp= latency>>1; this.inDelay=tmp; + if(inDelayAvg==Long.MAX_VALUE) { + inDelayAvg=latency; + }else { + inDelayAvg=(inDelayAvg*9999+tmp)/10000; + } if(inDelayMin==Long.MAX_VALUE||tmp<=inDelayMin) { inDelayMin=tmp; }else{ inDelayMin=(inDelayMin*9999+tmp)/10000; } + this.outDelay=tmp; + if(outDelayAvg==Long.MAX_VALUE) { + outDelayAvg=latency; + }else { + outDelayAvg=(outDelayAvg*9999+tmp)/10000; + } if(outDelayMin==Long.MAX_VALUE||tmp<=outDelayMin) { outDelayMin=tmp; }else{ outDelayMin=(outDelayMin*9999+tmp)/10000; } - outDelayPredicted=outDelay+(outDelay-outDelayOld); - inDelayPredicted=inDelay+(inDelay-inDelayOld); + outDelayPredicted=outDelay; + inDelayPredicted=inDelay; updateOutJitter(); updateInJitter(); updateTotalJitter(); diff --git a/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorData.java b/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorData.java index a583ca5..917c355 100644 --- a/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorData.java +++ b/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorData.java @@ -16,4 +16,19 @@ public long getInSpeed(); public long getOutSpeed(); + +public long getInPPS(); + +public long getOutPPS(); + +public AtomicLong getInPacketCounterAL(); + +public AtomicLong getOutPacketCounterAL(); + +public long getInPacketCounter(); + + +public long getOutPacketCounter(); + + } diff --git a/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorDataImpl.java b/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorDataImpl.java index fc498c4..11214df 100644 --- a/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorDataImpl.java +++ b/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorDataImpl.java @@ -32,6 +32,8 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S private volatile long inSpeedMax; private volatile long outSpeedMax; + private volatile long inSpeedMax2; + private volatile long outSpeedMax2; public SpeedAndTrafficMonitorDataImpl() { super(); @@ -101,12 +103,23 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S return outSpeedMax; } + + public long getInSpeedMax2() { + return inSpeedMax2; + } + + + public long getOutSpeedMax2() { + return outSpeedMax2; + } + + protected TimerTask tmt=new TimerTask() { @Override public void run() { long d=System.nanoTime()-updatetime; - + if(d!=0) { if(inTraffic!=null) { long i=inTraffic.get()-inTrafficOld; inTrafficOld =inTraffic.get(); @@ -119,16 +132,40 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S outSpeed= o*1000000000/d; } + if(inCounter!=null) { + long i=inCounter.get()-inCounterOld; + inCounterOld =inCounter.get(); + inPPS= i*1000000000/d; + } + if(outCounter!=null) { + long i=outCounter.get()-outCounterOld; + outCounterOld =outCounter.get(); + outPPS= i*1000000000/d; + } + } if(outSpeed>=outSpeedMax) { outSpeedMax=outSpeed; }else { - outSpeedMax=(outSpeedMax*999+outSpeed)/1000; + outSpeedMax=(outSpeedMax*99+outSpeed)/100; } if(inSpeed>=inSpeedMax) { inSpeedMax=inSpeed; }else { - inSpeedMax=(inSpeedMax*999+inSpeed)/1000; + inSpeedMax=(inSpeedMax*99+inSpeed)/100; + } + + + if(outPPS>=outPPSMax) { + outPPSMax=outPPS; + }else { + outPPSMax=(outPPSMax*99+outPPS)/100; + } + + if(inPPS>=inPPSMax) { + inPPSMax=inPPS; + }else { + inPPSMax=(inPPSMax*99+inPPS)/100; } updatetime=System.nanoTime(); @@ -141,7 +178,7 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S @Override public void run() { long d=System.nanoTime()-updatetime1; - + if(d!=0) { if(inTraffic!=null) { long i=inTraffic.get()-inTrafficOld1; inTrafficOld1 =inTraffic.get(); @@ -153,8 +190,19 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S outTrafficOld1 =outTraffic.get(); outSpeedAvg= o*1000000000/d; } + + if(inCounter!=null) { + long i=inCounter.get()-inCounterOld1; + inCounterOld1 =inCounter.get(); + inPPSAvg= i*1000000000/d; + } - + if(outCounter!=null) { + long o=outCounter.get()-outCounterOld1; + outCounterOld1 =outCounter.get(); + outPPSAvg= o*1000000000/d; + } + } updatetime1=System.nanoTime(); @@ -166,7 +214,7 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S @Override public void run() { long d=System.nanoTime()-updatetime2; - + if(d!=0) { if(inTraffic!=null) { long i=inTraffic.get()-inTrafficOld2; inTrafficOld2 =inTraffic.get(); @@ -180,6 +228,45 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S } + + if(inCounter!=null) { + long i=inCounter.get()-inCounterOld2; + inCounterOld2 =inCounter.get(); + inPPSAvg2= i*1000000000/d; + } + + if(outCounter!=null) { + long o=outCounter.get()-outCounterOld2; + outCounterOld2 =outCounter.get(); + outPPSAvg2= o*1000000000/d; + } + } + + if(outSpeedAvg2>=outSpeedMax2) { + outSpeedMax2=outSpeedAvg2; + }else { + outSpeedMax2=(outSpeedMax2*999+outSpeedAvg2)/1000; + } + + if(inSpeedAvg2>=inSpeedMax2) { + inSpeedMax2=inSpeedAvg2; + }else { + inSpeedMax2=(inSpeedMax2*999+inSpeedAvg2)/1000; + } + + + if(outPPSAvg2>=outPPSMax2) { + outPPSMax2=outPPSAvg2; + }else { + outPPSMax2=(outPPSMax2*999+outPPSAvg2)/1000; + } + + if(inPPSAvg2>=inPPSMax2) { + inPPSMax2=inPPSAvg2; + }else { + inPPSMax2=(inPPSMax2*999+inPPSAvg2)/1000; + } + updatetime2=System.nanoTime(); } @@ -208,5 +295,77 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S tmt1.cancel(); tmt2.cancel(); } + + + + private volatile AtomicLong inCounter=new AtomicLong(); + private volatile AtomicLong outCounter=new AtomicLong(); + + private long inCounterOld; + private long outCounterOld; + private long inCounterOld1; + private long outCounterOld1; + private long inCounterOld2; + private long outCounterOld2; + + private volatile long inPPS; + private volatile long outPPS; + + + private volatile long inPPSMax; + private volatile long outPPSMax; + private volatile long inPPSMax2; + private volatile long outPPSMax2; + + private volatile long inPPSAvg; + private volatile long outPPSAvg; + private volatile long inPPSAvg2; + private volatile long outPPSAvg2; + + @Override + public long getInPPS() { + return inPPS; + } + + @Override + public long getOutPPS() { + return outPPS; + } + + @Override + public AtomicLong getInPacketCounterAL() { + return inCounter; + } + + @Override + public AtomicLong getOutPacketCounterAL() { + return outCounter; + } + + @Override + public long getInPacketCounter() { + return inCounter.get(); + } + + @Override + public long getOutPacketCounter() { + return outCounter.get(); + } + + public double getOutPPSMax2() { + return outPPSMax2; + } + + public double getInPPSMax2() { + return inPPSMax2; + } + + public long getOutPPSAvg() { + return outPPSAvg; + } + + public long getInPPSAvg() { + return inPPSAvg; + } } diff --git a/src/org/kne/cloud/network/perf/Kperf.java b/src/org/kne/cloud/network/perf/Kperf.java new file mode 100644 index 0000000..bafaef6 --- /dev/null +++ b/src/org/kne/cloud/network/perf/Kperf.java @@ -0,0 +1,476 @@ +package org.kne.cloud.network.perf; + +import java.io.IOException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.nio.channels.UnresolvedAddressException; +import java.util.Objects; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.locks.LockSupport; + +import org.kne.cloud.clock.AdjustedNanoClock; +import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.SpeedLimiter; +import org.kne.cloud.network.ThreadTool; +import org.kne.cloud.network.ipv6.IPv6Packet; +import org.kne.cloud.network.ipv6.Inet6AddressGroup; +import org.kne.cloud.network.klalb.ADDRPacket; +import org.kne.cloud.network.klalb.ADDRREQPacket; +import org.kne.cloud.network.klalb.BWINFPacket; +import org.kne.cloud.network.klalb.IPv6OverKLALBPacket; +import org.kne.cloud.network.klalb.KLALBPacket; +import org.kne.cloud.network.klalb.KLALBPacketLink; +import org.kne.cloud.network.klalb.KLALBUtils; +import org.kne.cloud.network.klalb.PINGPacket; +import org.kne.cloud.network.klalb.PONGPacket; +import org.kne.cloud.network.klalb.TESTPacket; +import org.kne.cloud.network.klalb.VADDRACKPacket; +import org.kne.cloud.network.klalb.VADDRPacket; +import org.kne.cloud.network.klalb.VADDRREQPacket; +import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.QueueingMonitorDataImpl; + +public class Kperf implements Runnable{ + + + + private ConcurrentLinkedQueue IsendDequeList = new ConcurrentLinkedQueue(); + + //private PriorityBlockingQueue sendDequeList = new PriorityBlockingQueue(); + + + private static final boolean debug = true; + + private static final boolean showpacket = false; + private volatile AdjustedNanoClock adjnc = new AdjustedNanoClock(); + private MultipurposeSocketAddress targetAddress; + private MultipurposeSocketAddress bindAddress; + private volatile boolean connected=false; + private volatile KLALBPacketLink link; + private QueueingMonitorDataImpl monitor=new QueueingMonitorDataImpl(); + + private volatile boolean closed = false; + + private volatile Thread tlock; + public Kperf(MultipurposeSocketAddress targetAddress,MultipurposeSocketAddress bindAddress) { + Objects.requireNonNull(targetAddress); + this.targetAddress=targetAddress; + this.bindAddress=bindAddress; + } + public Kperf(MultipurposeSocketAddress targetAddress) { + this(targetAddress,new MultipurposeSocketAddress("[::0]:0")); + } + public Kperf(KLALBPacketLink link) { + Objects.requireNonNull(link); + this.link=link; + } + + + + + + + private SpeedLimiter test = new SpeedLimiter(MIN_SPEED,10000000L); + + private static long MIN_SPEED=64*1024L; + private SpeedLimiter congress = new SpeedLimiter(0,10000000L); + private long congressSpeed = 0; + private double loadPercent = 1.01; + + private volatile int testSize=0; + //kperf {KLALB_Stream}[2486:1:34de:4abd:98c1:abd1:fc7a:401]:4564 + @Override + public void run() { + Thread tc = ThreadTool.makeVDaemonThreadIfSupport("测速控制线程", () -> { + final int wtimes=5; + System.out.println("测速开始!"); + try { + long startTime; + + /*System.out.println("测试1/4:延迟测试"); + test.setLimitspeed(0); + startTime=System.nanoTime(); + for (int i = 0; i < 30; i++) { + System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); + System.out.printf("上传延迟:%.3fms 下载延迟:%.3fms\n", monitor.getOutDelay()/1000000.0,monitor.getInDelay()/1000000.0); + Thread.sleep(1000); + } + System.out.printf("上传延迟 最小:%.3fms 平均:%.3fms 抖动:%.3fms\n",monitor.getOutDelayMin()/1000000.0,monitor.getOutDelayAvg()/1000000.0,monitor.getOutJitter()/1000000.0); + System.out.printf("下载延迟 最小:%.3fms 平均:%.3fms 抖动:%.3fms\n",monitor.getInDelayMin()/1000000.0,monitor.getInDelayAvg()/1000000.0,monitor.getInJitter()/1000000.0); + + System.out.println("等待时间"+wtimes+"s"); + Thread.sleep(wtimes*1000);*/ + + + startTime=System.nanoTime(); + if(targetAddress!=null) { + System.out.println("测试2/4:下载带宽测试"); + test.setLimitspeed(0); + testSize=60000; + for (int i = 0; i < 30; i++) { + System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); + System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg())); + Thread.sleep(1000); + } + + System.out.printf("下载带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getInSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getInSpeedMax2())); + }else { + System.out.println("测试2/4:上传带宽测试"); + test.setLimitspeed(1000L*1024L*1024L*1024L); + testSize=60000; + for (int i = 0; i < 30; i++) { + System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); + System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg())); + Thread.sleep(1000); + } + System.out.printf("上传带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getOutSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getOutSpeedMax2())); + } + System.out.println("等待时间"+wtimes+"s"); + Thread.sleep(wtimes*1000); + + + + startTime=System.nanoTime(); + if(targetAddress!=null) { + System.out.println("测试3/4:上传带宽测试"); + test.setLimitspeed(1000L*1024L*1024L*1024L); + testSize=60000; + for (int i = 0; i < 30; i++) { + System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); + System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg())); + Thread.sleep(1000); + } + System.out.printf("上传带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getOutSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getOutSpeedMax2())); + + }else { + System.out.println("测试3/4:下载带宽测试"); + test.setLimitspeed(0); + testSize=60000; + for (int i = 0; i < 30; i++) { + System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); + System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg())); + Thread.sleep(1000); + } + System.out.printf("下载带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getInSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getInSpeedMax2())); + } + + System.out.println("等待时间"+wtimes+"s"); + Thread.sleep(wtimes*1000); + + startTime=System.nanoTime(); + if(targetAddress!=null) { + System.out.println("测试2/4:下载包转发率测试"); + test.setLimitspeed(0); + testSize=0; + for (int i = 0; i < 30; i++) { + System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); + System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS())); + Thread.sleep(1000); + } + }else { + System.out.println("测试2/4:上传包转发率测试"); + test.setLimitspeed(1000L*1024L*1024L*1024L); + testSize=0; + for (int i = 0; i < 30; i++) { + System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); + System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS())); + Thread.sleep(1000); + } + //System.out.printf("上传带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getOutSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getOutSpeedMax2())); + } + System.out.println("等待时间"+wtimes+"s"); + Thread.sleep(wtimes*1000); + + startTime=System.nanoTime(); + if(targetAddress!=null) { + System.out.println("测试3/4:上传包转发率测试"); + test.setLimitspeed(1000L*1024L*1024L*1024L); + testSize=0; + for (int i = 0; i < 30; i++) { + System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); + System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS())); + Thread.sleep(1000); + } + + }else { + System.out.println("测试3/4:下载包转发率测试"); + test.setLimitspeed(0); + testSize=0; + for (int i = 0; i < 30; i++) { + System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); + System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS())); + Thread.sleep(1000); + } + + } + System.out.println("等待时间"+wtimes+"s"); + Thread.sleep(wtimes*1000); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("测速结束!"); + close(); + }); + try { + monitor.setState(MonitorData.CONNECTING); + if(link==null) + link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,20000); + + + link.setSoTimeout(20000); + + + Thread t = ThreadTool.makeVDaemonThreadIfSupport("测速发送线程", () -> { + tlock = Thread.currentThread(); + try { + KLALBPacket kpp = null; + + while ((!link.isClosed()) && (!closed)) { + // TimeDebugger tdb=new TimeDebugger(); + // tdb.putTime("start"); + if(checkBandwidthReportTime()) { + writePacketToKPL(new BWINFPacket(monitor.getOutSpeedAvg2(), monitor.getInSpeedAvg2())); + } + if (checkPingTimeSleep()) { + writePacketToKPL(new PINGPacket(System.nanoTime())); + + }else { + KLALBPacket kpip = IsendDequeList.poll(); + if (kpip != null) { + writePacketToKPL(kpip); + + }else { + + + if (test.checkTransmit(testSize+3)) { + TESTPacket tp=new TESTPacket(testSize); + writePacketToKPL(tp); + + + + }else { + LockSupport.parkNanos(1000000); + } + } + } + + Thread.yield(); + } + } catch (IOException | UnresolvedAddressException e) { + if (debug) + e.printStackTrace(); + } finally { + try { + link.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + t.start(); + + boolean fst = true; + while ((!link.isClosed()) && (!closed)) { + KLALBPacket kpp = readPacketFromKPL(); + + if (kpp == null) { + break; + } + switch (kpp.getType()) { + case KLALBPacket.PING: + sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime())); + break; + case KLALBPacket.PONG: + if (fst) { + // coll.resetCoolingTime(); + + monitor.setState(MonitorData.ONLINE); + connected=true; + if(targetAddress!=null) { + System.out.println("连接地址"+targetAddress+"成功!"); + }else { + System.out.println("接受地址"+link.toString()+"连接成功!"); + } + tc.start(); + fst = false; + } + + PONGPacket png = (PONGPacket) kpp; + long ul = png.getRcvtime() - png.getTimepingsnd()-(png.getTimepongsnd()-png.getTimepingrcv()); + + long DsndDelayFactor0 = png.getTimepingrcv() - png.getTimepingsnd(); + long DrcvDelayFactor0 = png.getRcvtime() - png.getTimepongsnd(); + long DsndDelayFactor; + long DrcvDelayFactor; + + adjnc.getLock().lock(); + try { + adjnc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2); + DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta(); + DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta(); + if (DsndDelayFactor < 0) { + if (DrcvDelayFactor < 0) { + + } else { + adjnc.setDelta(adjnc.getDelta() + DsndDelayFactor); + DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta(); + DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta(); + } + } else { + if (DrcvDelayFactor < 0) { + adjnc.setDelta(adjnc.getDelta() - DrcvDelayFactor); + DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta(); + DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta(); + } + } + } finally { + adjnc.getLock().unlock(); + } + + if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) { + monitor.setOutDelay(DsndDelayFactor); + monitor.setInDelay(DrcvDelayFactor); + monitor.setRecentPingNanoTime(png.getTimepingsnd()); + //pingInterval = monitor.getLatencyAvg()+2000000L; + + //double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay(); + loadPercent =Math.max( 1.2,0.4); + } + + LockSupport.unpark(tlock); + break; + case KLALBPacket.BWINF: + BWINFPacket bwi = (BWINFPacket) kpp; + if (bwi.getDownSpeed() >= congressSpeed) { + congressSpeed = bwi.getDownSpeed(); + } else { + congressSpeed = (congressSpeed * 999 + bwi.getDownSpeed()) / 1000; + } + congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) ); + // System.out.println(congressSpeed); + break; + case KLALBPacket.TEST: + break; + } + Thread.yield(); + } + } catch (IOException e) { + if(monitor.getState()==MonitorData.CONNECTING) + System.out.println("连接目标地址失败!"); + if(debug) + e.printStackTrace(); + + }finally { + monitor.setState(MonitorData.OFFLINE); + if(link!=null) { + try { + link.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + private volatile long time = System.nanoTime(); + private volatile long pingInterval = 10000000L; + private volatile long pingIntervalSleep = 200000000L; + + private boolean checkPingTime() { + long cu = System.nanoTime(); + if (cu - time > pingInterval) { + time = cu; + return true; + } else { + return false; + } + + } + + private boolean checkPingTimeSleep() { + long cu = System.nanoTime(); + if (cu - time > pingIntervalSleep) { + time = cu; + return true; + } else { + return false; + } + + } + + + + private volatile long bwtime = System.nanoTime(); + private volatile long bwpingInterval = 10000000L; + private volatile long bwpingIntervalSleep = 100000000L; + private boolean checkBandwidthReportTime(){ + long cu = System.nanoTime(); + if (cu - bwtime > bwpingIntervalSleep) { + bwtime = cu; + return true; + } else { + return false; + } + + } + + + public void close() { + closed = true; + monitor.setState(MonitorData.OFFLINE); + try { + if (link != null) + link.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + /*protected void sendPacket(KLALBPacket blk) { + blk.markJoinqueuetime(); + sendDequeList.add(blk); + LockSupport.unpark(tlock); + }*/ + + private void sendIPacket(KLALBPacket blk) { + IsendDequeList.add(blk); + LockSupport.unpark(tlock); + } + + + private KLALBPacket readPacketFromKPL() throws IOException { + KLALBPacket packet = link.readPacket(); + if (showpacket) { + + System.out.println("RX:" + packet); + } + if (packet != null) { + packet.putTimePassport("received"); + long length=packet.getLength(); + monitor.getInTrafficAL().addAndGet(length); + monitor.getInPacketCounterAL().incrementAndGet(); + } + return packet; + } + + private void writePacketToKPL(KLALBPacket packet) throws IOException { + long length=packet.getLength(); + monitor.getOutTrafficAL().addAndGet(length); + monitor.getOutPacketCounterAL().incrementAndGet(); + link.writePacket(packet); + link.flush(); + packet.putTimePassport("sended"); + packet.printPassport(); + + if (showpacket) { + System.err.println("TX:" + packet); + } + } + + + public void startPerfing() { + ThreadTool.makeVThreadIfSupport("测速接收线程" ,this).start(); + } +} diff --git a/src/org/kne/cloud/network/scanner/InetAddressRange.java b/src/org/kne/cloud/network/scanner/InetAddressRange.java index f155d6f..c0a190c 100644 --- a/src/org/kne/cloud/network/scanner/InetAddressRange.java +++ b/src/org/kne/cloud/network/scanner/InetAddressRange.java @@ -25,10 +25,14 @@ public class InetAddressRange { this.end = end; } public String getBeginHost() { + if(beginHost!=null) return beginHost; + return begin.getHostAddress(); } public String getEndHost() { + if(endHost!=null) return endHost; + return end.getHostAddress(); } public InetAddressRange(InetAddress address) { this(address,address); diff --git a/src/org/kne/cloud/network/scanner/PortRange.java b/src/org/kne/cloud/network/scanner/PortRange.java index adbd392..990fe3a 100644 --- a/src/org/kne/cloud/network/scanner/PortRange.java +++ b/src/org/kne/cloud/network/scanner/PortRange.java @@ -28,7 +28,7 @@ public class PortRange { } @Override public String toString() { - return "PortRange [begin=" + begin + ", end=" + end + "]"; + return begin + "~" + end ; } @Override public int hashCode() { diff --git a/src/org/kne/cloud/network/scanner/ScanRange.java b/src/org/kne/cloud/network/scanner/ScanRange.java new file mode 100644 index 0000000..0709232 --- /dev/null +++ b/src/org/kne/cloud/network/scanner/ScanRange.java @@ -0,0 +1,67 @@ +package org.kne.cloud.network.scanner; + +import java.io.Serializable; +import java.net.UnknownHostException; +import java.util.Objects; + +import org.kne.cloud.network.MultipurposeSocketAddress; + +public class ScanRange implements Serializable { + public ScanRange(String range) throws UnknownHostException { + setMsaString(range); + } + protected void setMsaString(String range) throws UnknownHostException { + String[]sp=range.split("~"); + MultipurposeSocketAddress begin=new MultipurposeSocketAddress(sp[0]); + MultipurposeSocketAddress end; + if(sp.length>1) { + end=new MultipurposeSocketAddress(sp[1]); + }else { + end=new MultipurposeSocketAddress(sp[0]); + } + setMsa(begin, end); + } + public ScanRange(MultipurposeSocketAddress begin,MultipurposeSocketAddress end) throws UnknownHostException { + setMsa(begin,end); + + } + + protected void setMsa(MultipurposeSocketAddress begin, MultipurposeSocketAddress end) throws UnknownHostException { + this.addressRange=new InetAddressRange(begin.getHost(), end.getHost()); + this.portRange=new PortRange(begin.getPort(), end.getPort()); + } + public ScanRange(InetAddressRange addressRange, PortRange portRange) { + super(); + this.addressRange = addressRange; + this.portRange = portRange; + } + private static final long serialVersionUID = 1L; + + protected InetAddressRange addressRange; + protected PortRange portRange; + public InetAddressRange getAddressRange() { + return addressRange; + } + public PortRange getPortRange() { + return portRange; + } + + public String toString() { + return new MultipurposeSocketAddress(addressRange.getBeginHost(), portRange.getBegin())+"~"+new MultipurposeSocketAddress(addressRange.getEndHost(), portRange.getEnd()); + } + @Override + public int hashCode() { + return Objects.hash(addressRange, portRange); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ScanRange other = (ScanRange) obj; + return Objects.equals(addressRange, other.addressRange) && Objects.equals(portRange, other.portRange); + } +} diff --git a/src/org/kne/cloud/network/scanner/TCPNetworkScanner.java b/src/org/kne/cloud/network/scanner/TCPNetworkScanner.java index 3ca583b..be5e6bf 100644 --- a/src/org/kne/cloud/network/scanner/TCPNetworkScanner.java +++ b/src/org/kne/cloud/network/scanner/TCPNetworkScanner.java @@ -35,16 +35,13 @@ public class TCPNetworkScanner implements Runnable { this.processConsumer = processConsumer; } - private List addressRanges = new ArrayList<>(); - private List portRanges = new ArrayList<>(); + private List ranges = new ArrayList<>(); - public List getAddressRanges() { - return addressRanges; - } + - public List getPortRanges() { - return portRanges; + public List getRanges() { + return ranges; } public BiConsumer getConsumer() { @@ -62,24 +59,25 @@ public class TCPNetworkScanner implements Runnable { @Override public void run() { - ThreadPoolExecutor exc=(ThreadPoolExecutor) Executors.newFixedThreadPool(8192,new ThreadFactory() { + ThreadPoolExecutor exc=(ThreadPoolExecutor) Executors.newFixedThreadPool(512,new ThreadFactory() { @Override public Thread newThread(Runnable r) { - return ThreadTool.makeVThreadIfSupport("端口扫描线程", r); + Thread t=ThreadTool.makeVThreadIfSupport("端口扫描线程", r); + t.setPriority(Thread.MIN_PRIORITY); + return t; } }); + +ThreadPoolExecutor excd=(ThreadPoolExecutor) Executors.newFixedThreadPool(8); + BigInteger bip=new BigInteger("0"); - for (Iterator iterator = portRanges.iterator(); iterator.hasNext();) { - PortRange portRange = (PortRange) iterator.next(); - bip=bip.add(portRange.getElementCount()); + for (Iterator iterator = ranges.iterator(); iterator.hasNext();) { + ScanRange sRange = (ScanRange) iterator.next(); + bip=bip.add(sRange.getPortRange().getElementCount().multiply(sRange.getAddressRange().getElementCount())); } - BigInteger bia=new BigInteger("0"); - for (Iterator iterator = addressRanges.iterator(); iterator.hasNext();) { - InetAddressRange inetAddressRange = (InetAddressRange) iterator.next(); - bia=bia.add(inetAddressRange.getElementCount()); - } - tot=bip.multiply(bia); + + tot=bip; ReentrantLock counterlock=new ReentrantLock(); counter=new BigInteger("0"); @@ -90,7 +88,12 @@ public class TCPNetworkScanner implements Runnable { if(processConsumer!=null) { BigDecimal bdt=new BigDecimal(tot); BigDecimal bdc=new BigDecimal(counter); - float fp=bdc.divide(bdt, 8, BigDecimal.ROUND_HALF_UP).floatValue()*100; + float fp; + if(bdt.equals(BigDecimal.ZERO)) { + fp=100; + }else { + fp=bdc.divide(bdt, 8, BigDecimal.ROUND_HALF_UP).floatValue()*100; + } processConsumer.accept(fp); } }finally { @@ -98,14 +101,20 @@ public class TCPNetworkScanner implements Runnable { } try { - for (Iterator iterator = portRanges.iterator(); iterator.hasNext();) { - PortRange portRange = (PortRange) iterator.next(); + for (Iterator iterator = ranges.iterator(); iterator.hasNext();) { + ScanRange sRange = (ScanRange) iterator.next(); + PortRange portRange=sRange.getPortRange(); + InetAddressRange inetAddressRange=sRange.getAddressRange(); + + while( excd.getQueue().size()>500) { + LockSupport.parkNanos(1000000); + } + excd.execute(()->{ int curport = portRange.getBegin(); while (curport <= portRange.getEnd()) { - for (Iterator iterator2 = addressRanges.iterator(); iterator2.hasNext();) { - InetAddressRange inetAddressRange = (InetAddressRange) iterator2.next(); - + + byte[]endarr=inetAddressRange.getEnd().getAddress(); byte[] curr = inetAddressRange.getBegin().getAddress(); while (compareIPAddress(curr,endarr)) { @@ -113,16 +122,16 @@ public class TCPNetworkScanner implements Runnable { int curport0=curport; InetAddress currAddress=pga(curr); - while( exc.getQueue().size()>1000) { + while( exc.getQueue().size()>500) { LockSupport.parkNanos(1000000); } exc.execute(()->{ MultipurposeSocketAddress mpsa; - if (inetAddressRange.getBeginHost() != null&&currAddress.equals(inetAddressRange.getBegin())) { + if (currAddress.equals(inetAddressRange.getBegin())) { mpsa = new MultipurposeSocketAddress(inetAddressRange.getBeginHost(), curport0); - }else if (inetAddressRange.getEndHost() != null&&currAddress.equals(inetAddressRange.getEnd())) { + }else if (currAddress.equals(inetAddressRange.getEnd())) { mpsa = new MultipurposeSocketAddress(inetAddressRange.getEndHost(), curport0); } else { mpsa = new MultipurposeSocketAddress(currAddress.getHostAddress(), @@ -135,11 +144,17 @@ public class TCPNetworkScanner implements Runnable { //System.out.println(isa); s.connect(isa,connectTimeout); s.setSoTimeout(soTimeout); - + try { acceptMultipurposeSocketAddress(mpsa, s); + }catch(Exception e) { + e.printStackTrace(); + } } catch (Exception e) { - + try { acceptMultipurposeSocketAddress(mpsa, null); + }catch(Exception ed) { + ed.printStackTrace(); + } } finally { if (s != null) try { @@ -154,7 +169,11 @@ public class TCPNetworkScanner implements Runnable { BigDecimal bdt=new BigDecimal(tot); BigDecimal bdc=new BigDecimal(counter); float fp=bdc.divide(bdt, 8, BigDecimal.ROUND_HALF_UP).floatValue()*100; + try { processConsumer.accept(fp); + }catch(Exception e) { + e.printStackTrace(); + } } }finally { counterlock.unlock(); @@ -162,7 +181,7 @@ public class TCPNetworkScanner implements Runnable { }); increaceIPAddress(curr); } - } + try { Thread.sleep(10); @@ -172,10 +191,16 @@ public class TCPNetworkScanner implements Runnable { curport++; } - + }); } }finally { + excd.shutdown(); + try { + excd.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); + } catch (InterruptedException e) { + e.printStackTrace(); + } exc.shutdown(); try { exc.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); @@ -233,15 +258,14 @@ public class TCPNetworkScanner implements Runnable { } public TCPNetworkScanner() { - // TODO 自动生成的构造函数存根 } public static void main(String[] args) throws UnknownHostException { TCPNetworkScanner tcn = new TCPNetworkScanner(); - tcn.getPortRanges().add(new PortRange(25565)); - tcn.getPortRanges().add(new PortRange(34000, 38000)); - tcn.getAddressRanges().add(new InetAddressRange("192.168.0.1","192.168.1.255")); + //tcn.getRanges().add(new ScanRange(new InetAddressRange("127.0.0.1","127.0.0.2"),new PortRange(25565,37000))); + tcn.getRanges().add(new ScanRange("ip.8mi.work:50000~ip.8mi.work:60000")); tcn.setConsumer((scanned,s) -> { + if(s!=null) System.out.println(scanned); }); tcn.setProcessConsumer((f)->{System.out.println(f); diff --git a/src/org/kne/cloud/network/srv6/DijkstraAlgorithm.java b/src/org/kne/cloud/network/srv6/DijkstraAlgorithm.java new file mode 100644 index 0000000..b1990cc --- /dev/null +++ b/src/org/kne/cloud/network/srv6/DijkstraAlgorithm.java @@ -0,0 +1,8 @@ +package org.kne.cloud.network.srv6; + +public interface DijkstraAlgorithm extends Runnable{ + public void setGraph(long[][]pointers,long[][]heap,long startPoint) ; + public void run(); + public long[] getDirection(); + public long[] getShortest(); +} diff --git a/src/org/kne/cloud/network/srv6/DijstraAlgorithm.java b/src/org/kne/cloud/network/srv6/DijstraAlgorithm.java new file mode 100644 index 0000000..4da8400 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/DijstraAlgorithm.java @@ -0,0 +1,82 @@ +package org.kne.cloud.network.srv6; +public class DijstraAlgorithm { + //不能设置为Integer.MAX_VALUE,否则两个Integer.MAX_VALUE相加会溢出导致出现负权 + public static int M = 100000; + //定义七个顶点 + private static char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'}; + + public static void main(String[] args) { + + //初始化邻接矩阵 + int[][] matrix = new int[vertex.length][vertex.length]; + matrix[0] = new int[]{M, 5, 7, M, M, M, 2}; + matrix[1] = new int[]{5, M, M, 9, M, M, 3}; + matrix[2] = new int[]{7, M, M, M, 8, M, M}; + matrix[3] = new int[]{M, 9, M, M, M, 4, M}; + matrix[4] = new int[]{M, M, 8, M, M, 5, 4}; + matrix[5] = new int[]{M, M, M, 4, 5, M, 6}; + matrix[6] = new int[]{2, 3, M, M, 4, 6, M}; + + //调用dijstra算法计算最短路径 + dijstra(matrix, 0); + } + + /** + * @param matrix:邻接矩阵 + * @param source:起点 + */ + public static void dijstra(int[][] matrix, int source) { + //最短路径长度 + int[] shortest = new int[matrix.length]; + //判断该点的最短路径是否求出 + int[] visited = new int[matrix.length]; + //存储输出路径 + String[] path = new String[matrix.length]; + + //初始化输出路径 + for (int i = 0; i < matrix.length; i++) { + path[i] = vertex[source] + "->" + vertex[i]; + } + + //初始化起点,将起点放入S + shortest[source] = 0; + visited[source] = 1; + + for (int i = 1; i < matrix.length; i++) { //i从1开始,因为起点已经加入S了 + int min = M; + int index = -1; + + //找出某节点到起点路径最短 + for (int j = 0; j < matrix.length; j++) { + //已经求出最短路径的节点不需要再加入计算并判断加入节点后是否存在更短路径 + if (visited[j] == 0 && matrix[source][j] < min) { + min = matrix[source][j]; + index = j; + } + } + + //更新最短路径,标记起点到该节点的最短路径已经求出 + shortest[index] = min; + visited[index] = 1; + + //更新从index跳到其它节点的较短路径 + for (int m = 0; m < matrix.length; m++) { + if (visited[m] == 0 && matrix[source][index] + matrix[index][m] < matrix[source][m]) { + matrix[source][m] = matrix[source][index] + matrix[index][m]; + path[m] = path[index] + "->" + vertex[m]; + } + } + } + + //打印最短路径 + for (int i = 0; i < matrix.length; i++) { + if (i != source) { + if (shortest[i] == M) { + System.out.println(vertex[source] + "到" + vertex[i] + "不可达"); + } else { + System.out.println(vertex[source] + "到" + vertex[i] + "的最短路径为:" + path[i] + ",最短距离是:" + shortest[i]); + } + } + } + } +} \ No newline at end of file diff --git a/src/org/kne/cloud/network/srv6/IPv6SegmentRoutingTLV.java b/src/org/kne/cloud/network/srv6/IPv6SegmentRoutingTLV.java new file mode 100644 index 0000000..1c7264e --- /dev/null +++ b/src/org/kne/cloud/network/srv6/IPv6SegmentRoutingTLV.java @@ -0,0 +1,147 @@ +package org.kne.cloud.network.srv6; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; + +import org.kne.cloud.network.NetworkPacket; +import org.kne.cloud.network.klalb.KLALBPacket; + +public class IPv6SegmentRoutingTLV extends NetworkPacket { + public static final int PAD1=0; + public static final int PADN=4; + public static final int HMAC=5; + public static final int SEQS=7; + + private boolean isDefault; + + protected volatile ByteBuffer header; + + private ByteBuffer data; + + public IPv6SegmentRoutingTLV(ByteBuffer header ) { + this(header,true); + } + + public ByteBuffer getData() { + return data; + } + + public IPv6SegmentRoutingTLV(ByteBuffer header ,boolean isDefault ) { + super(); + this.header = header; + if(isDefault&&(getType()!=PAD1)) { + data=ByteBuffer.allocate(512); + } + } + public IPv6SegmentRoutingTLV(int type) { + this(type,true); + } + public IPv6SegmentRoutingTLV(int type,boolean isDefault) { + super(); + this.header=ByteBuffer.allocate(2); + header.put((byte) type); + if(isDefault&&(type!=PAD1)) { + data=ByteBuffer.allocate(512); + } + } + + @Override + public long getLength() { + if(getType()==PAD1) + return 1; + return header.limit()+(isDefault?data.limit():0); + } + + public static IPv6SegmentRoutingTLV readIPv6SegmentRoutingTLVFromChannel(ReadableByteChannel din) throws IOException { + ByteBuffer bbf= ByteBuffer.allocate(2); + bbf.limit(1); + while (bbf.hasRemaining()) { + if (din.read(bbf) == -1) { + return null; + } + } + int type=bbf.get(0)&0xff; + IPv6SegmentRoutingTLV rtlv; + switch(type) { + case PAD1: + rtlv=new PAD1SegmentRoutingTLV(bbf); + rtlv.readFromChannel(din); + return rtlv; + case PADN: + rtlv=new PADNSegmentRoutingTLV(bbf); + rtlv.readFromChannel(din); + return rtlv; + default: + rtlv=new IPv6SegmentRoutingTLV(bbf); + rtlv.readFromChannel(din); + return rtlv; + } + } + public static void writeIPv6SegmentRoutingTLVToChannel(WritableByteChannel dto,IPv6SegmentRoutingTLV tlv) throws IOException { + tlv.writeToChannel(dto); + } + @Override + protected void writeToChannel(WritableByteChannel dto) throws IOException { + if(isDefault&&(getType()!=PAD1)) { + setDataLength(data.limit()); + } + dto.write(header.slice(0,header.limit())); + if(isDefault&&(getType()!=PAD1)) { + dto.write(data.slice(0, data.limit())); + } + } + + @Override + protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { + header.limit(1); + while (header.hasRemaining()) { + if (din.read(header) == -1) { + throw new EOFException(); + } + } + int type=getType(); + if(type!=PAD1) { + header.limit(2); + while (header.hasRemaining()) { + if (din.read(header) == -1) { + throw new EOFException(); + } + } + } + header.flip(); + + if(isDefault&&(getType()!=PAD1)) { + data.clear(); + data.limit(getDataLength()); + while(data.hasRemaining()){ + if(din.read(data)==-1) { + throw new EOFException(); + } + } + data.flip(); + } + } + + @Override + protected boolean needEndPosition() { + return false; + } + + public int getType() { + return header.get(0)&0xff; + } + public void setType(int type) { + header.put(0,(byte) type); + } + + public int getDataLength() { + return header.get(1)&0xff; + } + + public void setDataLength(int dataLength) { + header.put(1,(byte) dataLength); + } +} diff --git a/src/org/kne/cloud/network/srv6/IpV6RoutingSRHData.java b/src/org/kne/cloud/network/srv6/IpV6RoutingSRHData.java new file mode 100644 index 0000000..d195459 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/IpV6RoutingSRHData.java @@ -0,0 +1,209 @@ +package org.kne.cloud.network.srv6; + +import static org.pcap4j.util.ByteArrays.*; + +import java.net.Inet6Address; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.pcap4j.packet.IllegalRawDataException; +import org.pcap4j.packet.IpV6ExtRoutingPacket.IpV6RoutingData; +import org.pcap4j.util.ByteArrays; + + +public final class IpV6RoutingSRHData implements IpV6RoutingData { + + /** */ + private static final long serialVersionUID = -7972526977248222954L; + + private final int lastEntry; + private final int flags; + private final int tag; + private final List addresses; + private final List tlvs; + + /** + * A static factory method. This method validates the arguments by {@link + * ByteArrays#validateBounds(byte[], int, int)}, which may throw exceptions undocumented here. + * + * @param rawData rawData + * @param offset offset + * @param length length + * @return a new IpV6RoutingSourceRouteData object. + * @throws IllegalRawDataException if parsing the raw data fails. + */ + public static IpV6RoutingSRHData newInstance(byte[] rawData, int offset, int length) + throws IllegalRawDataException { + return new IpV6RoutingSRHData(rawData, offset, length); + } + + private IpV6RoutingSRHData(byte[] rawData, int offset, int length) + throws IllegalRawDataException { + + this.lastEntry = rawData[ offset]&0xff; + this.flags=rawData[offset+1]&0xff; + this.tag=ByteArrays.getShort(rawData, offset+2); + this.addresses = new ArrayList(); + this.tlvs=new ArrayList<>(); + + int endv=INT_SIZE_IN_BYTES+(lastEntry+1)*INET6_ADDRESS_SIZE_IN_BYTES; + for (int i = INT_SIZE_IN_BYTES; i < endv; i += INET6_ADDRESS_SIZE_IN_BYTES) { + addresses.add(ByteArrays.getInet6Address(rawData, i + offset)); + } + for(int itlv=endv;itlv getTlvs() { + return tlvs; +} + +public int getLastEntry() { + return lastEntry; +} + +public int getFlags() { + return flags; +} + +public int getTag() { + return tag; +} + +public List getAddresses() { + return addresses; +} + +public IpV6RoutingSRHData(List addresses) { + this(0,0,addresses,new ArrayList<>()); +} +public IpV6RoutingSRHData(List addresses,Listtlvs) { + this(0,0,addresses,tlvs); +} +/** + * @param reserved reserved + * @param addresses addresses + */ + public IpV6RoutingSRHData(int flags,int tag, List addresses,Listtlvs) { + if (addresses == null) { + throw new NullPointerException("addresses must not be null"); + } + this.lastEntry = addresses.size()-1; + this.flags=flags; + this.tag=tag; + this.addresses = new ArrayList(addresses); + this.tlvs=tlvs; + } + + + +@Override + public int length() { + int tlvsize=0; + for (int i = 0; i < tlvs.size(); i++) { + tlvsize+=tlvs.get(i).getTotalLength(); + } + return INT_SIZE_IN_BYTES+addresses.size() * INET6_ADDRESS_SIZE_IN_BYTES + tlvsize; + } + + @Override + public byte[] getRawData() { + byte[] rawData = new byte[length()]; + rawData[0]=(byte) lastEntry; + rawData[1]=(byte) flags; + rawData[2]=(byte) (tag>>8); + rawData[3]=(byte) tag; + ; + int i = INT_SIZE_IN_BYTES; + for ( Iterator iter = addresses.iterator(); iter.hasNext(); i += INET6_ADDRESS_SIZE_IN_BYTES) { + System.arraycopy( + ByteArrays.toByteArray(iter.next()), 0, rawData, i, INET6_ADDRESS_SIZE_IN_BYTES); + } + for (int j = 0; j < tlvs.size(); j++) { + SRv6TLV srt=tlvs.get(j); + switch(srt.getType()) { + case SRv6TLV.PAD1: + rawData[i++]=(byte) srt.getType(); + break; + case SRv6TLV.PADN: + rawData[i++]=(byte) srt.getType(); + int plth=srt.getLength(); + rawData[i++]=(byte) plth; + i+=plth; + break; + default: + rawData[i++]=(byte) srt.getType(); + int dlth=srt.getLength(); + rawData[i++]=(byte) dlth; + System.arraycopy(srt.getValue(), 0, rawData, i, dlth); + i+=dlth; + break; + } + } + return rawData; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[lastentry: ").append(lastEntry).append("][flags: ").append(flags).append("][tag: ").append(tag).append("] [addresses:"); + for (Inet6Address addr : addresses) { + sb.append(" ").append(addr); + } + sb.append("]"); + return sb.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!this.getClass().isInstance(obj)) { + return false; + } + + IpV6RoutingSRHData other = (IpV6RoutingSRHData) obj; + return lastEntry == other.lastEntry&&flags==other.flags&&tag==other.tag && addresses.equals(other.addresses); + } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + lastEntry; + result = 31 * result + flags; + result = 31 * result + tag; + result = 31 * result + addresses.hashCode(); + return result; + } +} diff --git a/src/org/kne/cloud/network/srv6/KLALBRoutingProtocol.java b/src/org/kne/cloud/network/srv6/KLALBRoutingProtocol.java new file mode 100644 index 0000000..925a0b9 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/KLALBRoutingProtocol.java @@ -0,0 +1,575 @@ +package org.kne.cloud.network.srv6; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.BindException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.SocketException; +import java.nio.channels.Channels; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; + +import org.kne.cloud.network.ipv6.IPv6NetworkLink; +import org.kne.cloud.network.ipv6.Inet6AddressGroup; +import org.kne.cloud.network.ipv6.Neighbor; +import org.kne.cloud.network.monitor.DelayMonitorData; +import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; +import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorData; +import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl; +import org.kne.cloud.network.scanner.InetAddressRange; + +public class KLALBRoutingProtocol extends Thread{ + + private static final boolean debug = false; + + private Map netmap=new ConcurrentHashMap<>(); + + + private volatile Mapaddresses; + + private volatile Map> paths; + + public static final int DEFAULT_PORT=1001; + + public static final long HOTSOPT_TIMEOUT = 1000000000; + + public static final int HOTSOPT_REPORT_INTERVAL = 100000000; + private SRv6Router router; + public SRv6Router getRouter() { + return router; + } + public KLALBRoutingProtocol(SRv6Router router) { + this.router=router; + } + + private ReentrantLock sendlock=new ReentrantLock(); + + private long floodTimer=System.nanoTime(); + private long floodTimer2=System.nanoTime(); + @Override + public void run() { + Thread.currentThread().setName("KLALB路由协议接收线程"); + getSelfRouterInfo(); + DatagramSocket ds = null; + try{ + ds=new DatagramSocket(new InetSocketAddress(router.getLocator().getAddress(), DEFAULT_PORT) ); + DatagramSocket ds2=ds; + new Thread(()->{ + Thread.currentThread().setName("KLALB路由协议接收线程"); + + while(true) { + try { + /*Listlinks=router.getLinkTabel(); + Object[] nls=links.toArray(); + byte[]to=createLinkStatePacket(nls); + DatagramPacket dgp=new DatagramPacket(to,to.length); + + for(int i=0;ineis=nl.discoverNeighbors(); + for (Iterator iteratorx = neis.iterator(); iteratorx.hasNext();) { + Inet6Address addresses = (Inet6Address) iteratorx.next(); + dgp.setAddress(addresses); + dgp.setPort(DEFAULT_PORT); + ds2.send(dgp); + } + } + }*/ + RouterInfo slf= getSelfRouterInfo(); + RouterInfo oslf=netmap.put(slf.getLocator().getAddress(), slf); + noticeUpdate(); + if(oslf==null||(!slf.equals(oslf))) { + //System.out.println("change:"+oslf+"\n"+slf); + long cur=System.nanoTime(); + if(cur-floodTimer2>5000000000L) { + //System.out.println("update10"); + floodTimer2=cur; + floodPacket(ds2, null, new RouterInfoPacket(slf,true)); + } + }else { + long cur=System.nanoTime(); + if(cur-floodTimer>60000000000L) { + //System.out.println("update60"); + floodTimer=cur; + floodPacket(ds2, null, new RouterInfoPacket(slf,true)); + } + } + Set requestSet=new HashSet<>(); + for (Iterator> iterator = netmap.entrySet().iterator(); iterator.hasNext();) { + Entry type = (Entry) iterator.next(); + RouterInfo val=type.getValue(); + if(val.checkTimeOut()) { + iterator.remove(); + noticeUpdate(); + } + Set ads=val.getNeighborAddresses(); + for (Iterator iterator2 = ads.iterator(); iterator2.hasNext();) { + Inet6Address address=iterator2.next().getLocator().getAddress(); + //System.out.println(address); + if(!netmap.containsKey(address)) { + requestSet.add(address); + } + + } + + } + computeShortestPathIfUpdated(); + + for (Iterator iterator = requestSet.iterator(); iterator.hasNext();) { + Inet6Address inet6Address = (Inet6Address) iterator.next(); + byte[]to=new byte[] {0}; + DatagramPacket dgp=new DatagramPacket(to,to.length); + dgp.setAddress(inet6Address); + dgp.setPort(DEFAULT_PORT); + if(debug) + System.out.println("Request:"+inet6Address); + sendlock.lock(); + try { + ds2.send(dgp); + }catch(SocketException e) { + System.out.println("Send failed:"+dgp.getAddress()); + }finally { + sendlock.unlock(); + } + } + + + for (Iterator> iterator = hotspots.entrySet().iterator(); iterator.hasNext();) { + Entry type = (Entry) iterator.next(); + if(type.getValue().checkReportTime()) { + //System.out.println("hotspot address:"+type.getKey()); + writePacket(ds2, new RouterInfoPacket( netmap.get(router.getLocator().getAddress()),false), new InetSocketAddress(type.getKey(), DEFAULT_PORT)); + } + if(type.getValue().checkTimeOut()) { + iterator.remove(); + } + + } + + Thread.sleep(1); + + + } catch (InterruptedException e) { + e.printStackTrace(); + }catch (IOException e1) { + // TODO 自动生成的 catch 块 + e1.printStackTrace(); + } + } + }).start(); + while(true) { + + try { + byte[]ca=new byte[65535]; + DatagramPacket dgp=new DatagramPacket(ca, ca.length); + ds.receive(dgp); + //System.out.println(Arrays.toString( Arrays.copyOf( dgp.getData(),dgp.getLength()))); + ByteArrayInputStream bi=new ByteArrayInputStream(dgp.getData(),0,dgp.getLength()); + KLALBRoutingProtocolPacket kp=KLALBRoutingProtocolPacket.readKLALBPacketFromChannel(Channels.newChannel(bi)); + + //System.out.println(kp); + switch(kp.getType()) { + case KLALBRoutingProtocolPacket.RINFO_REQ: + RouterInfo rifr=netmap.get(router.getLocator().getAddress()); + if(rifr!=null) + writePacket(ds, new RouterInfoPacket( rifr,false), dgp.getSocketAddress()); + break; + case KLALBRoutingProtocolPacket.RINFO: + + RouterInfoPacket rifp=(RouterInfoPacket) kp; + RouterInfo rif=rifp.getRinfo(); + RouterInfo oldrif=netmap.get(rif.getLocator().getAddress()); + + if(debug) + System.out.println(rif); + if(oldrif==null||oldrif.getCreateTime()links=router.getLinkTabel(); + Object[] nls=links.toArray(); + for(int i=0;ineis=nl.getNeighborsInfo(); + for (Iterator iteratorx = neis.iterator(); iteratorx.hasNext();) { + Neighbor addresses = (Neighbor) iteratorx.next(); + InetSocketAddress isa=new InetSocketAddress(addresses.getLocator().getAddress(),DEFAULT_PORT); + if(!isa.equals(except)) { + writePacket(ds, rifp, isa); + } + } + } + } + } + + private void writePacket(DatagramSocket ds,KLALBRoutingProtocolPacket pkt,SocketAddress dest) throws IOException { + ByteArrayOutputStream bos=new ByteArrayOutputStream(65535); + KLALBRoutingProtocolPacket.writeKLALBPacketToChannel(Channels.newChannel(bos),pkt); + byte[]to=bos.toByteArray(); + DatagramPacket dgpx=new DatagramPacket(to,to.length); + dgpx.setSocketAddress(dest); + sendlock.lock(); + try { + ds.send(dgpx); + }catch(BindException e) { + e.printStackTrace(); + System.err.println("Cannot assign:"+dest); + }finally { + sendlock.unlock(); + } + } + + private DijkstraAlgorithm algorithm=new SingleDijkstraAlgorithm(); + + private ReentrantLock directionLock=new ReentrantLock(); + + private volatile NetmapDirections directions; + + private static class NetmapDirections{ + + public NetmapDirections(long[] direction, List rias, + Map direction_airs) { + super(); + this.direction = direction; + this.direction_rias = rias; + this.direction_airs = direction_airs; + } + + private long[] direction; + + private List direction_rias; + + private Map direction_airs; + + public long[] getDirection() { + return direction; + } + + public List getDirection_rias() { + return direction_rias; + } + + public Map getDirection_airs() { + return direction_airs; + } + + } + + + + private volatile boolean updated=false; + public void noticeUpdate() { + updated=true; + } + private void computeShortestPathIfUpdated() { + if(updated) { + computeShortestPath(); + updated=false; + } + } + + private void computeShortestPath() { + + directionLock.lock(); + try { + if(netmap.get(router.getLocator().getAddress())==null) { + return; + } + Set> s=netmap.entrySet(); + Mapairs=new HashMap<>(); + + Listrias=new ArrayList<>(); + + Map>paths=new HashMap<>(); + long number=0; + for (Iterator> iterator = s.iterator(); iterator.hasNext();) { + Entry entry = (Entry) iterator.next(); + if(!airs.containsKey(entry.getKey())) { + airs.put(entry.getKey(),number); + rias.add( entry.getKey()); + number++; + } + Set ni= entry.getValue().getNeighborAddresses(); + for (Iterator iterator2 = ni.iterator(); iterator2.hasNext();) { + NeighborInfo neighborInfo = (NeighborInfo) iterator2.next(); + Inet6Address ias2=neighborInfo.getLocator().getAddress(); + if(!airs.containsKey(ias2)) { + airs.put(ias2,number); + rias.add( ias2); + number++; + } + Setlp1=paths.get(entry.getKey()); + if(lp1==null) { + paths.put(entry.getKey(), lp1=new HashSet<>()); + } + lp1.add(new LinkDirection(neighborInfo.getLocal(),neighborInfo.getNeighbor(),entry.getKey(), ias2, neighborInfo.getUploadDelay(),neighborInfo.getUploadSpeed(),neighborInfo.getUploadSpeedMax())); + + Setlp2=paths.get(ias2); + if(lp2==null) { + paths.put(ias2, lp2=new HashSet<>()); + } + lp2.add( new LinkDirection(neighborInfo.getNeighbor(),neighborInfo.getLocal(),ias2,entry.getKey() , neighborInfo.getDownloadDelay(),neighborInfo.getDownloadSpeed(),neighborInfo.getDownloadSpeedMax())); + } + } + + long[][]pointers=new long[(int) airs.size()][2]; + long heappos=0; + long linknumber=0; + for (Iterator>> iterator = paths.entrySet().iterator(); iterator.hasNext();) { + Entry> entry = (Entry>) iterator.next(); + linknumber+=entry.getValue().size(); + } + long[][]heap=new long[(int) (linknumber)][2]; + for (long i = 0; i < number; i++) { + long heapindex=0; + pointers[(int) i][0]=heappos; + InetAddress ia=rias.get((int) i); + Setlks=paths.get(ia); + if(lks!=null) + for (Iterator iterator = lks.iterator(); iterator.hasNext();) { + LinkDirection linkPath=iterator.next(); + heap[(int)(heappos+ heapindex)][0]=airs.get(linkPath.getToLocator()); + heap[(int) (heappos+heapindex)][1]=linkPath.getWeight(); + heapindex++; + + } + + heappos+=heapindex; + pointers[(int) i][1]=heapindex; + } + + algorithm.setGraph(pointers,heap,airs.get(router.getLocator().getAddress())); + algorithm.run(); + directions=new NetmapDirections(algorithm.getDirection(), rias, airs); + addresses=airs; + this.paths=paths; + }finally { + directionLock.unlock(); + } + //System.out.println(Arrays.toString( algorithm.getDirection())); + } + public static class LinkDirection{ + private Inet6AddressGroup fromAddress; + private Inet6AddressGroup toAddress; + private Inet6Address fromLocator; + private Inet6Address toLocator; + private long delay; + private long speed; + public long getSpeed() { + return speed; + } + private long bandwidth; + private long usedBandwidth=0; + public Inet6AddressGroup getFromAddress() { + return fromAddress; + } + public Inet6AddressGroup getToAddress() { + return toAddress; + } + public long getDelay() { + return delay; + } + public long getBandwidth() { + return bandwidth; + } + public LinkDirection(Inet6AddressGroup fromAddress, Inet6AddressGroup toAddress, Inet6Address fromLocator, + Inet6Address toLocator,long delay,long speed, long bandwidth) { + super(); + this.fromAddress = fromAddress; + this.toAddress = toAddress; + this.fromLocator = fromLocator; + this.toLocator = toLocator; + this.delay = delay; + this.speed=speed; + this.bandwidth = bandwidth; + } + @Override + public String toString() { + return "LinkDirection [fromAddress=" + fromAddress + ", toAddress=" + toAddress + ", fromLocator=" + + fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", speed=" + speed + + ", bandwidth=" + bandwidth + ", usedBandwidth=" + usedBandwidth + "]"; + } + public Inet6Address getFromLocator() { + return fromLocator; + } + @Override + public int hashCode() { + return Objects.hash(fromAddress, toAddress); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LinkDirection other = (LinkDirection) obj; + return Objects.equals(fromAddress, other.fromAddress) && Objects.equals(toAddress, other.toAddress); + } + public Inet6Address getToLocator() { + return toLocator; + } + public long getWeight() { + return delay; + } + } + private RouterInfo getSelfRouterInfo() { + Listlinks=router.getLinkTabel(); + Object[] nls=links.toArray(); + RouterInfo ri=new RouterInfo(System.currentTimeMillis()); + ri.setLocator(router.getLocator()); + for(int i=0;ineis=nl.getNeighborsInfo(); + for (Iterator iteratorx = neis.iterator(); iteratorx.hasNext();) { + Neighbor addresses = (Neighbor) iteratorx.next(); + long updelay=10000000000L; + long downdelay=10000000000L; + long uploadspeed=1024L*1024; + long downloadspeed=1024L*1024; + long uploadspeedmax=1024L*1024; + long downloadspeedmax=1024L*1024; + MonitorData md=addresses.getMonitor(); + if(md!=null) { + if(md instanceof DelayMonitorData) { + updelay=((DelayMonitorData) md).getOutDelay(); + downdelay=((DelayMonitorData) md).getInDelay(); + } + if(md instanceof SpeedAndTrafficMonitorData) { + uploadspeed=((SpeedAndTrafficMonitorData) md).getOutSpeed(); + downloadspeed=((SpeedAndTrafficMonitorData) md).getInSpeed(); + if(md instanceof SpeedAndTrafficMonitorDataImpl) { + SpeedAndTrafficMonitorDataImpl smd=(SpeedAndTrafficMonitorDataImpl) md; + uploadspeedmax=smd.getOutSpeedMax2(); + downloadspeedmax=smd.getInSpeedMax2(); + } + } + } + ri.getNeighborAddresses().add(new NeighborInfo(nl.getAddressGroup(),addresses.getAddress(),addresses.getLocator(),updelay ,downdelay ,uploadspeed ,downloadspeed,uploadspeedmax ,downloadspeedmax)); + + } + } + } + //if(debug) + //System.out.println(ri); + return ri; + } + + public Map getAddresses() { + return addresses; + } + public Map> getPaths() { + return paths; + } + public List createSegmentList(Inet6Address dest) { + NetmapDirections directionsx=directions; + if(directionsx==null) { + return null; + } + Long dn=directionsx.getDirection_airs().get(dest); + if(dn==null) { + return null; + } + Listsegments=new ArrayList<>(); + while(true) { + long idx=directionsx.getDirection()[(int) dn.longValue()]; + if(idx==-1) { + return null; + } + if(idx==dn) { + return segments; + } + segments.add(directionsx.getDirection_rias().get(dn.intValue())); + dn=idx; + } + } + public long getDevicesFound() { + return netmap.size(); + } + + private static class HotspotAddressTimer{ + private long putTime=System.nanoTime(); + private long reportTime =System.nanoTime(); + public boolean checkTimeOut() { + return System.nanoTime()-putTime>HOTSOPT_TIMEOUT; + } + public boolean checkReportTime() { + long cu = System.nanoTime(); + if (cu - reportTime > HOTSOPT_REPORT_INTERVAL) { + reportTime = cu; + return true; + } else { + return false; + } + } + public void refreshTimeout() { + putTime=System.nanoTime(); + } + } + + private Map hotspots=new ConcurrentHashMap<>(); + public void putHotspotAddress(Inet6Address sourceAddress) { + HotspotAddressTimer hat=hotspots.get(sourceAddress); + if(hat==null) { + hotspots.put(sourceAddress, new HotspotAddressTimer()); + }else { + hat.refreshTimeout(); + } + } + +} diff --git a/src/org/kne/cloud/network/srv6/KLALBRoutingProtocolPacket.java b/src/org/kne/cloud/network/srv6/KLALBRoutingProtocolPacket.java new file mode 100644 index 0000000..505f4af --- /dev/null +++ b/src/org/kne/cloud/network/srv6/KLALBRoutingProtocolPacket.java @@ -0,0 +1,137 @@ +package org.kne.cloud.network.srv6; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; + +import org.kne.cloud.network.NetworkPacket; + +public abstract class KLALBRoutingProtocolPacket extends NetworkPacket { + public static final int RINFO_REQ=0; + public static final int RINFO=1; + + private static final int HEADER_CAPACITY = 32; + + + //public static final ByteArrayPool dataarraypool=new ByteArrayPool(5000, 8192); + + protected volatile ByteBuffer header; + + + + protected KLALBRoutingProtocolPacket(ByteBuffer header) { + super(); + this.header = header; + } + + public KLALBRoutingProtocolPacket(int type) { + super(); + header=NetworkPacket.databufferpool_40.borrow(); + header.put((byte) type); + } + @Override + public String toString() { + return "KLALBRoutingProtocolPacket [type=" + getType() + "]"; + } + public int getType() { + return header.get(0)&0xff; + } + + private long sndtime,rcvtime; + + + + protected void writeToChannel(WritableByteChannel dto) throws IOException { + sndtime=System.nanoTime(); + dto.write(header.slice(0, (int) getHeaderSize())); + } + + @Override + protected boolean needEndPosition() { + return false; + } + + protected void readFromChannel(ReadableByteChannel din,long length) throws IOException { + rcvtime=System.nanoTime(); + //System.out.println(this+" "+getHeaderSize()); + header.limit((int) getHeaderSize()); + while(header.hasRemaining()){ + if(din.read(header)==-1) { + throw new EOFException(); + } + } + } + + protected long getHeaderSize() { + return 1; + } + public long getSndtime() { + return sndtime; + } + public long getRcvtime() { + return rcvtime; + } + public long getLength() { + return getHeaderSize(); + } + + + + protected ByteBuffer getHeader() { + return header; + } + + public void dispose() { + super.dispose(); + /* ByteBuffer headerx=header; + header=null; + KLALBRoutingProtocolPacket.databufferpool_40.back(headerx);*/ + } + + public static KLALBRoutingProtocolPacket readKLALBPacketFromStream(DataInputStream in) throws IOException { + return readKLALBPacketFromChannel(Channels.newChannel(in)); + } + + public static KLALBRoutingProtocolPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException { + while(true) { + ByteBuffer bb=databufferpool_40.borrow(); + bb.limit(1); + while(bb.hasRemaining()){ + if(in.read(bb)==-1) { + return null; + } + } + int type=bb.get(0); + bb.limit(bb.capacity()); + + KLALBRoutingProtocolPacket klp; + switch(type) { + case RINFO_REQ: + klp=new RouterInfoRequestPacket(bb); + klp.readFromChannel(in); + return klp; + case RINFO: + klp=new RouterInfoPacket(bb); + klp.readFromChannel(in); + return klp; + } + //throw new StreamCorruptedException("unknown package type:"+type); + System.err.println("ignore unknown KLALBRoutingProtocolPacket type:"+type); + } + } + + public static void writeKLALBPacketToStream(DataOutputStream out,KLALBRoutingProtocolPacket klb) throws IOException { + writeKLALBPacketToChannel(Channels.newChannel(out),klb); + } + public static void writeKLALBPacketToChannel(WritableByteChannel writableByteChannel,KLALBRoutingProtocolPacket klb) throws IOException { + klb.writeToChannel(writableByteChannel); + } +} diff --git a/src/org/kne/cloud/network/srv6/NeighborInfo.java b/src/org/kne/cloud/network/srv6/NeighborInfo.java new file mode 100644 index 0000000..54a0563 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/NeighborInfo.java @@ -0,0 +1,142 @@ +package org.kne.cloud.network.srv6; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.Serializable; +import java.net.Inet6Address; +import java.util.Objects; + +import org.kne.cloud.network.ipv6.Inet6AddressGroup; + +public class NeighborInfo implements Serializable { + @Override + public String toString() { + return "NeighborInfo [local=" + local + ", neighbor=" + neighbor + ", locator=" + locator + ", uploadDelay=" + + uploadDelay + ", downloadDelay=" + downloadDelay + ", uploadSpeed=" + uploadSpeed + ", downloadSpeed=" + + downloadSpeed + ", uploadSpeedMax=" + uploadSpeedMax + ", downloadSpeedMax=" + downloadSpeedMax + "]"; + } + /** + * + */ + private static final long serialVersionUID = 1L; + private Inet6AddressGroup local; + private Inet6AddressGroup neighbor; + private Inet6AddressGroup locator; + public NeighborInfo(Inet6AddressGroup local,Inet6AddressGroup neighbor,Inet6AddressGroup locator, long uploadDelay, long downloadDelay, long uploadSpeed, long downloadSpeed, long uploadspeedmax, long downloadspeedmax) { + super(); + this.local=local; + this.neighbor = neighbor; + this.locator=locator; + this.uploadDelay = uploadDelay; + this.downloadDelay = downloadDelay; + this.uploadSpeed = uploadSpeed; + this.downloadSpeed = downloadSpeed; + this.uploadSpeedMax=uploadspeedmax; + this.downloadSpeedMax=downloadspeedmax; + } + public NeighborInfo() { + } + private long uploadDelay; + private long downloadDelay; + private long uploadSpeed; + private long downloadSpeed; + private long uploadSpeedMax; + private long downloadSpeedMax; + public Inet6AddressGroup getNeighbor() { + return neighbor; + } + public void setNeighbor(Inet6AddressGroup neighbor) { + this.neighbor = neighbor; + } + public long getUploadDelay() { + return uploadDelay; + } + public void setUploadDelay(long uploadDelay) { + this.uploadDelay = uploadDelay; + } + public long getDownloadDelay() { + return downloadDelay; + } + public void setDownloadDelay(long downloadDelay) { + this.downloadDelay = downloadDelay; + } + public long getUploadSpeed() { + return uploadSpeed; + } + public void setUploadSpeed(long uploadSpeed) { + this.uploadSpeed = uploadSpeed; + } + public long getDownloadSpeed() { + return downloadSpeed; + } + public long getUploadSpeedMax() { + return uploadSpeedMax; + } + public void setUploadSpeedMax(long uploadSpeedMax) { + this.uploadSpeedMax = uploadSpeedMax; + } + public long getDownloadSpeedMax() { + return downloadSpeedMax; + } + public void setDownloadSpeedMax(long downloadSpeedMax) { + this.downloadSpeedMax = downloadSpeedMax; + } + public void setDownloadSpeed(long downloadSpeed) { + this.downloadSpeed = downloadSpeed; + } + public Inet6AddressGroup getLocal() { + return local; + } + public void setLocal(Inet6AddressGroup local) { + this.local = local; + } + public Inet6AddressGroup getLocator() { + return locator; + } + public void setLocator(Inet6AddressGroup locator) { + this.locator = locator; + } + @Override + public int hashCode() { + return Objects.hash(local, locator, neighbor); + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NeighborInfo other = (NeighborInfo) obj; + return Objects.equals(local, other.local) && Objects.equals(locator, other.locator) + && Objects.equals(neighbor, other.neighbor); + } + public void writeToStream(DataOutputStream out) throws IOException { + local.writeToStream(out); + neighbor.writeToStream(out); + locator.writeToStream(out); + out.writeLong(uploadDelay); + out.writeLong(downloadDelay); + out.writeLong(uploadSpeed); + out.writeLong(downloadSpeed); + out.writeLong(uploadSpeedMax); + out.writeLong(downloadSpeedMax); + } + + public void readFromStream(DataInputStream in) throws IOException { + local=new Inet6AddressGroup(in); + neighbor=new Inet6AddressGroup( in); + locator=new Inet6AddressGroup(in); + uploadDelay=in.readLong(); + downloadDelay=in.readLong(); + uploadSpeed=in.readLong(); + downloadSpeed=in.readLong(); + uploadSpeedMax=in.readLong(); + downloadSpeedMax=in.readLong(); + } +} diff --git a/src/org/kne/cloud/network/srv6/PAD1SegmentRoutingTLV.java b/src/org/kne/cloud/network/srv6/PAD1SegmentRoutingTLV.java new file mode 100644 index 0000000..bd968cb --- /dev/null +++ b/src/org/kne/cloud/network/srv6/PAD1SegmentRoutingTLV.java @@ -0,0 +1,20 @@ +package org.kne.cloud.network.srv6; + +import java.nio.ByteBuffer; + +public class PAD1SegmentRoutingTLV extends IPv6SegmentRoutingTLV { + + public PAD1SegmentRoutingTLV(int type) { + super(type); + } + + public PAD1SegmentRoutingTLV(ByteBuffer klalbHeader) { + super(klalbHeader); + } + + @Override + public String toString() { + return "PAD1SegmentRoutingTLV []"; + } + +} diff --git a/src/org/kne/cloud/network/srv6/PADNSegmentRoutingTLV.java b/src/org/kne/cloud/network/srv6/PADNSegmentRoutingTLV.java new file mode 100644 index 0000000..792d51f --- /dev/null +++ b/src/org/kne/cloud/network/srv6/PADNSegmentRoutingTLV.java @@ -0,0 +1,31 @@ +package org.kne.cloud.network.srv6; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; + +public class PADNSegmentRoutingTLV extends IPv6SegmentRoutingTLV { + public PADNSegmentRoutingTLV(ByteBuffer klalbHeader) { + super(klalbHeader); + } + + public PADNSegmentRoutingTLV(int type) { + super(type); + } + + @Override + protected void writeToChannel(WritableByteChannel dto) throws IOException { + + super.writeToChannel(dto); + + } + + @Override + protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { + super.readFromChannel(din, length); + + } + +} diff --git a/src/org/kne/cloud/network/srv6/PacketConsumer.java b/src/org/kne/cloud/network/srv6/PacketConsumer.java new file mode 100644 index 0000000..a18ba96 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/PacketConsumer.java @@ -0,0 +1,10 @@ +package org.kne.cloud.network.srv6; + +import java.io.IOException; + +import org.kne.cloud.network.ipv6.IPv6Packet; +import org.pcap4j.packet.IpV6Packet; + +public interface PacketConsumer { + public void accept(IPv6Packet packx)throws IOException; +} diff --git a/src/org/kne/cloud/network/srv6/PacketReorder.java b/src/org/kne/cloud/network/srv6/PacketReorder.java new file mode 100644 index 0000000..153d68b --- /dev/null +++ b/src/org/kne/cloud/network/srv6/PacketReorder.java @@ -0,0 +1,91 @@ +package org.kne.cloud.network.srv6; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Consumer; + +import org.kne.cloud.network.ipv6.IPv6Packet; +import org.pcap4j.packet.IpV6Packet; +import org.pcap4j.packet.TcpPacket; + +public class PacketReorder { + public PacketReorder(long sequenceNumber) { + this.sequenceNumber =sequenceNumber; + } + private ReentrantLock rlock=new ReentrantLock(); + private List tcps=new ArrayList<>(); + private volatile long sequenceNumber; + public List getTcps() { + return tcps; + } + public long getSequenceNumber() { + return sequenceNumber; + } + public static class TcpPacketEntry{ + private IPv6Packet packet; + private long sequenceNumber; + private long addtime=System.nanoTime(); + + public TcpPacketEntry(IPv6Packet packet, long sequenceNumber) { + super(); + this.packet = packet; + this.sequenceNumber = sequenceNumber; + } + public IPv6Packet getPacket() { + return packet; + } + public long getAddtime() { + return addtime; + } + public boolean checkTimeOut() { + return System.nanoTime()-addtime>10000000L; + } + public long getSequenceNumber() { + return sequenceNumber; + } + + } + public void sortPackets(IPv6Packet pack,long seq, PacketConsumer packconsumer) throws IOException { + rlock.lock(); + try { + //System.out.println("包序号:"+seq); + //System.out.println("当前序号:"+sequenceNumber); + if(seq iterator = tcps.iterator(); iterator.hasNext();) { + TcpPacketEntry tcpPacketEntry = (TcpPacketEntry) iterator.next(); + if(tcpPacketEntry.getSequenceNumber()==sequenceNumber) { + //System.out.println(" 排序:"+tcpPacketEntry.getSequenceNumber()); + iterator.remove(); + sequenceNumber++; + packconsumer.accept(pack); + }else if(tcpPacketEntry.getSequenceNumber() neighborAddresses=new HashSet<>(); + private long createTime; + + + public long getCreateTime() { + return createTime; + } + private static final long INFO_UPDATETIME=10000000000L; + private static final long INFO_TIMEOUT=20000000000L; + private long putTime=System.nanoTime(); + public boolean checkUpdateTime() { + return System.nanoTime()-putTime>INFO_UPDATETIME; + } + + public boolean checkTimeOut() { + return System.nanoTime()-putTime>INFO_TIMEOUT; + } + + @Override + public String toString() { + return "RINFO [locator=" + locator + ", neighborAddresses=" + neighborAddresses + ", putTime=" + putTime + + "]"; + } + public Set getNeighborAddresses() { + return neighborAddresses; + } + + public RouterInfo( long createTime) { + this.createTime = createTime; + } + public RouterInfo() { + } + public void writeToStream(DataOutputStream out) throws IOException { + locator.writeToStream(out); + out.writeLong(createTime); + out.writeInt(neighborAddresses.size()); + for (Iterator iterator = neighborAddresses.iterator(); iterator.hasNext();) { + NeighborInfo neighborInfo = (NeighborInfo) iterator.next(); + neighborInfo.writeToStream(out); + } + } + + protected void writeToChannel(WritableByteChannel dto) throws IOException { + writeToStream(new DataOutputStream( Channels.newOutputStream(dto))); + } + protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { + readFromStream(new DataInputStream(Channels.newInputStream(din))); + } + public void readFromStream(DataInputStream in) throws IOException { + locator=new Inet6AddressGroup(in); + createTime=in.readLong(); + int size=in.readInt(); + neighborAddresses=new HashSet<>(size); + for (int i = 0; i < size; i++) { + NeighborInfo nif=new NeighborInfo(); + nif.readFromStream(in); + neighborAddresses.add(nif); + + } + } +} diff --git a/src/org/kne/cloud/network/srv6/RouterInfoPacket.java b/src/org/kne/cloud/network/srv6/RouterInfoPacket.java new file mode 100644 index 0000000..928e70c --- /dev/null +++ b/src/org/kne/cloud/network/srv6/RouterInfoPacket.java @@ -0,0 +1,74 @@ +package org.kne.cloud.network.srv6; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.Serializable; +import java.net.Inet6Address; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import org.kne.cloud.network.NetworkPacket; +import org.kne.cloud.network.ipv6.Inet6AddressGroup; + +public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Serializable{ + + public RouterInfoPacket(RouterInfo routerInfo, boolean flood) { + super(RINFO); + getHeader().put(1,(byte) (flood?1:0)); + this.rinfo=routerInfo; + } + protected RouterInfoPacket(ByteBuffer bb) { + super(bb); + } + + private RouterInfo rinfo; + + public boolean isFlood() { + return (getHeader().get(1)&1)==1; + } + + public RouterInfo getRinfo() { + return rinfo; + } + @Override + protected long getHeaderSize() { + return super.getHeaderSize()+1; + } + @Override + public long getLength() { + return super.getLength(); + } + public void setRinfo(RouterInfo rinfo) { + this.rinfo = rinfo; + } + @Override + public String toString() { + return rinfo.toString(); + } + + + @Override + protected void writeToChannel(WritableByteChannel dto) throws IOException { + super.writeToChannel(dto); + rinfo.writeToChannel(dto); + } + @Override + protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { + super.readFromChannel(din, length); + rinfo=new RouterInfo(); + rinfo.readFromChannel(din, length); + } + +} diff --git a/src/org/kne/cloud/network/srv6/RouterInfoRequestPacket.java b/src/org/kne/cloud/network/srv6/RouterInfoRequestPacket.java new file mode 100644 index 0000000..e343146 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/RouterInfoRequestPacket.java @@ -0,0 +1,20 @@ +package org.kne.cloud.network.srv6; + +import java.nio.ByteBuffer; + +public class RouterInfoRequestPacket extends KLALBRoutingProtocolPacket { + + protected RouterInfoRequestPacket(ByteBuffer header) { + super(header); + } + + public RouterInfoRequestPacket() { + super(RINFO_REQ); + } + + @Override + public String toString() { + return "RINFO_REQ"; + } + +} diff --git a/src/org/kne/cloud/network/srv6/SRv6Pad1TLV.java b/src/org/kne/cloud/network/srv6/SRv6Pad1TLV.java new file mode 100644 index 0000000..63aa942 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/SRv6Pad1TLV.java @@ -0,0 +1,12 @@ +package org.kne.cloud.network.srv6; + +public class SRv6Pad1TLV extends SRv6TLV { + + public SRv6Pad1TLV() { + super(SRv6TLV.PAD1, 0, null); + + } + public String toString() { + return "PAD1"; + } +} diff --git a/src/org/kne/cloud/network/srv6/SRv6PadNTLV.java b/src/org/kne/cloud/network/srv6/SRv6PadNTLV.java new file mode 100644 index 0000000..cd51161 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/SRv6PadNTLV.java @@ -0,0 +1,12 @@ +package org.kne.cloud.network.srv6; + +public class SRv6PadNTLV extends SRv6TLV { + + public SRv6PadNTLV(int length) { + super(SRv6TLV.PADN, length, null); + + } + public String toString() { + return "PADN:"+getLength(); + } +} diff --git a/src/org/kne/cloud/network/srv6/SRv6Router.java b/src/org/kne/cloud/network/srv6/SRv6Router.java new file mode 100644 index 0000000..514d45b --- /dev/null +++ b/src/org/kne/cloud/network/srv6/SRv6Router.java @@ -0,0 +1,569 @@ +package org.kne.cloud.network.srv6; + +import java.io.IOException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Consumer; + +import org.kne.acclerate.FastLib; +import org.kne.cloud.network.NetworkPacket; +import org.kne.cloud.network.ipv6.FlowSession; +import org.kne.cloud.network.ipv6.IPv6NetworkLink; +import org.kne.cloud.network.ipv6.IPv6Packet; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6DestinationHeader; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6RoutingHeader; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader; +import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink; +import org.kne.cloud.network.ipv6.Inet6AddressGroup; +import org.kne.cloud.network.ipv6.Neighbor; +import org.kne.cloud.network.ipv6.RouteItem; +import org.kne.cloud.network.klalb.BindableKLALBPacketConsumer; +import org.kne.cloud.network.klalb.KLALBController; +import org.kne.cloud.network.klalb.KLALBRemoteLine; +import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; +import org.kne.cloud.network.tun.TUNNetworkDevice; +import org.kne.concurrent.HighPerformanceExecutor; +import org.kne.io.KNEChannels; +import org.pcap4j.packet.IcmpV6CommonPacket; +import org.pcap4j.packet.IcmpV6TimeExceededPacket; +import org.pcap4j.packet.IllegalRawDataException; +import org.pcap4j.packet.IpV6ExtRoutingPacket; +import org.pcap4j.packet.IpV6ExtRoutingPacket.IpV6ExtRoutingHeader; +import org.pcap4j.packet.IpV6Packet; +import org.pcap4j.packet.IpV6Packet.Builder; +import org.pcap4j.packet.IpV6RoutingSourceRouteData; +import org.pcap4j.packet.IpV6SimpleFlowLabel; +import org.pcap4j.packet.IpV6SimpleTrafficClass; +import org.pcap4j.packet.Packet; +import org.pcap4j.packet.Packet.Header; +import org.pcap4j.packet.TcpPacket; +import org.pcap4j.packet.TcpPacket.TcpHeader; +import org.pcap4j.packet.UnknownPacket; +import org.pcap4j.packet.namednumber.IcmpV6Code; +import org.pcap4j.packet.namednumber.IcmpV6Type; +import org.pcap4j.packet.namednumber.IpNumber; +import org.pcap4j.packet.namednumber.IpV6RoutingType; +import org.pcap4j.packet.namednumber.IpVersion; + +import com.google.gson.internal.Pair; + +public class SRv6Router { + private static final boolean debug = false; + + public static final int MTU = 9000; + + public static final IpV6RoutingType SRH_HEADER = new IpV6RoutingType((byte) 4, "SRH Header"); + // private Listlinks=new ArrayList<>(); + + private List routeTabel = new ArrayList<>(); + + private List linkTabel = new CopyOnWriteArrayList<>(); + + public List getLinkTabel() { + return linkTabel; + } + + // private ConcurrentHashMapswis=new + // ConcurrentHashMap<>(); + + private final LoopbackIPv6NetworkLink inLoopBack = new LoopbackIPv6NetworkLink(); + //private final LoopbackIPv6NetworkLink inLoopBackSRv6; + private final LoopbackIPv6NetworkLink hostLoopBack ; + + private class LoopbackIPv6NetworkLink implements IPv6NetworkLink { + private Inet6AddressGroup loopbackAddress; + + public LoopbackIPv6NetworkLink() { + super(); + try { + this.loopbackAddress=new Inet6AddressGroup( (Inet6Address) Inet6Address.getByName("::1"),128); + } catch (UnknownHostException e) { + // TODO 自动生成的 catch 块 + e.printStackTrace(); + } + } + + public LoopbackIPv6NetworkLink(Inet6Address loopbackAddress) { + super(); + this.loopbackAddress = new Inet6AddressGroup(loopbackAddress,128); + } + + public Consumer getReceiveConsumer() { + return receiveConsumer; + } + + private Consumer receiveConsumer; + + @Override + public void sendPacket(IPv6Packet pack, Inet6Address next) throws IOException { + PacketConsumer pcm; + if ((pcm = protocolNumberRegister.get(pack.getPayload().getProtocolNumber())) != null) { + pcm.accept(pack); + + return; + } + } + + @Override + public boolean isLoopBack() { + return true; + } + + @Override + public List getNeighborsInfo() { + List hs = new ArrayList<>(); + return hs; + } + + @Override + public boolean isCongress(IPv6Packet iPv6Packet) { + return false; + } + + @Override + public String getName() { + return "inLoopBack"; + } + + @Override + public boolean isUp() { + return true; + } + + @Override + public boolean canSend(IPv6Packet iPv6Packet) { + //System.out.println(iPv6Packet.getPayload().getProtocolNumber()); + return protocolNumberRegister.containsKey(iPv6Packet.getPayload().getProtocolNumber()); + } + + @Override + public void setReceiveConsumer(Consumer con) { + this.receiveConsumer = con; + } + + @Override + public Inet6AddressGroup getAddressGroup() { + return loopbackAddress; + } + + }; + + public List getRouteTabel() { + return routeTabel; + } + + public List getCurrentRouteTabel() { + return routeTabel0; + } + + private Consumer defaultReceive = new Consumer() { + + @Override + public void accept(IPv6Packet t) { + HighPerformanceExecutor.defaultExecutor.execute(() -> { + routePacket(t); + t.putTimePassport("routed"); + }); + } + }; + private Consumer srhReceive = new Consumer() { + + @Override + public void accept(IPv6Packet t) { + HighPerformanceExecutor.defaultExecutor.execute(() -> { + insertSRHandRoutePacket(t); + }); + } + }; + + public void updateRouteTabel() { + List routeTabel0x = new ArrayList<>(); + + for (Iterator iterator = linkTabel.iterator(); iterator.hasNext();) { + IPv6NetworkLink nlink = (IPv6NetworkLink) iterator.next(); + if (nlink.isLoopBack()) { + if (nlink instanceof IPv6TUNLoopbackNetworkLink) { + routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128), + nlink.getAddressGroup().getAddress(), nlink, "Direct", 0, 1, null, "D")); + + } else { + routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128), + nlink.getAddressGroup().getAddress(), nlink, "Direct", 0, 0, null, "D")); + + } + }/*else { + routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128), + nlink.getAddressGroup().getAddress(), inLoopBack, "Direct", 0, 0, null, "D")); + }*/ + for (Iterator iteratorx = nlink.getNeighborsInfo() + .iterator(); iteratorx.hasNext();) { + Neighbor addresses = (Neighbor) iteratorx.next(); + RouteItem ri = new RouteItem(new Inet6AddressGroup(addresses.getAddress().getAddress(), 128), addresses.getAddress().getAddress(), + nlink, "Direct", 0, 128, addresses.getMonitor(), "D"); + routeTabel0x.add(ri); + + RouteItem ris = new RouteItem(addresses.getLocator(), (Inet6Address) addresses.getLocator().getAddress(), + nlink, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D"); + routeTabel0x.add(ris); + + } + + + + if (nlink instanceof IPv6TUNLoopbackNetworkLink) { + + nlink.setReceiveConsumer(srhReceive); + } else { + nlink.setReceiveConsumer(defaultReceive); + } + } + + routeTabel0x.addAll(routeTabel); + Collections.sort(routeTabel0x); + routeTabel0 = routeTabel0x; + } + + private Inet6AddressGroup locator; + /* + * public List getLinks() { return links; } + */ + + + + + public Inet6AddressGroup getLocator() { + return locator; + } + + public void setLocator(Inet6AddressGroup locator) { + this.locator = locator; + updateRouteTabel(); + } + + + private ConcurrentHashMap swist = new ConcurrentHashMap<>(); + + // private AtomicLong qsn=new AtomicLong(); + public void insertSRHandRoutePacket(IPv6Packet ipp) { + insertSRH(ipp); + ipp.putTimePassport("SRH inserted"); + routePacket(ipp); + ipp.putTimePassport("routed"); + } + + public void insertSRH(IPv6Packet ipp) { + if (klalbRouteProtol != null) { + List segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress()); + // System.out.println(segs); + if (segs != null && (!segs.isEmpty())) { + /* + * Listtlvs=new ArrayList<>(1); if(ipp.getPayload().getType()==6) { + * SRv6StreamSequenceTLV sers= new SRv6StreamSequenceTLV(); + * sers.setSequence(qsn.getAndIncrement()); tlvs.add(sers); } + */ + + //IpV6RoutingSRHData srh = new IpV6RoutingSRHData(segs); + + IPv6SegmentRoutingHeader irh = new IPv6SegmentRoutingHeader(segs); + ipp.getHeaders().add(irh); + + ipp.setDestinationAddress(segs.get(segs.size() - 1)); + /* + * if(ipp.getPayload().getType()==6) System.out.println(ipp); + */ + } + } + } + + + private volatile List routeTabel0 = new ArrayList<>(); + + // private ReentrantReadWriteLock routelock=new ReentrantReadWriteLock(); + public void routePacket(IPv6Packet iPv6Packet) { + // routelock.readLock().lock(); + // try { + // System.out.println("路由表:"+routeTabel0); + StringBuilder dbg=null; + if (debug) { + dbg=new StringBuilder(); + } + iPv6Packet.lockAll(); + try { + if(iPv6Packet.isSomeDisposed()) + return; + int hop = iPv6Packet.getHopLimit(); + if (hop > 0) { + // List mached=new ArrayList<>(); + // RouteItem pri=null; + + Inet6Address ia = iPv6Packet.getDestinationAddress(); + if (debug) { + dbg.append("----------------------------------------\n"); + dbg.append("packet:" + iPv6Packet.getSourceAddress().getHostAddress() + "->" + + iPv6Packet.getDestinationAddress().getHostAddress()+"\n"); + } + for (int i = 0; i < routeTabel0.size(); i++) { + RouteItem tri = routeTabel0.get(i); + if (!tri.checkMatch(ia)) { + if (debug) { + dbg.append(tri+"\n"); + dbg.append("unmatched.\n"); + } + continue; + } + if (!tri.getDestlink().isUp()) { + if (debug) { + dbg.append(tri+"\n"); + dbg.append("linkdown.\n"); + } + continue; + } + if (tri.getDestlink().isCongress(iPv6Packet)) { + if (debug) { + dbg.append(tri+"\n"); + dbg.append("congress.\n"); + } + continue; + } + if (!tri.getDestlink().canSend(iPv6Packet)) { + if (debug) { + dbg.append(tri+"\n"); + dbg.append("linkrefused.\n"); + } + continue; + } + if (debug) { + dbg.append(tri+"\n"); + dbg.append("matched.\n"); + } + processPacket(iPv6Packet, tri); + return; + /* + * if(pri==null||pri.equals(tri)) { mached.add(tri); pri=tri; }else { break; } + */ + } + if (debug) { + dbg.append("miss.\n"); + } + if (iPv6Packet.isEnableECN()) { + iPv6Packet.markCE(); + for (int i = 0; i < routeTabel0.size(); i++) { + RouteItem tri = routeTabel0.get(i); + if (tri.checkMatch(ia)) { + if (!tri.getDestlink().isUp()) { + continue; + } + processPacket(iPv6Packet, tri); + return; + /* + * if(pri==null||pri.equals(tri)) { mached.add(tri); pri=tri; }else { break; } + */ + } + } + } + if (debug) + dbg.append("congress\n"); + // System.out.println(ia.getAddress()+" match "+ri); + /* + * for (Iterator iterator = mached.iterator(); iterator.hasNext();) { RouteItem + * routeItem = (RouteItem) iterator.next(); + * if(routeItem.getDestlink().isCongress()) { + * + * }else { processPacket(iPv6Packet,pri); break; } } + */ + // else + // System.out.println("路由失败:"+iPv6Packet); + + } else { + IcmpV6TimeExceededPacket.Builder icmpte = new IcmpV6TimeExceededPacket.Builder(); + ByteBuffer IPv6data = NetworkPacket.databufferpool_65535.borrow(); + iPv6Packet.writeToChannel(KNEChannels.newWritableChannel(IPv6data)); + byte[] raw = new byte[IPv6data.remaining()]; + IPv6data.get(0, raw); + icmpte.payload(IpV6Packet.newPacket(raw, 0, raw.length)); + + IcmpV6CommonPacket.Builder icbd = new IcmpV6CommonPacket.Builder(); + icbd.type(IcmpV6Type.TIME_EXCEEDED); + icbd.code(IcmpV6Code.HOP_LIMIT_EXCEEDED); + icbd.srcAddr(locator.getAddress()); + icbd.dstAddr(iPv6Packet.getSourceAddress()); + icbd.correctChecksumAtBuild(true); + icbd.payloadBuilder(icmpte); + + IPv6Packet icmpv = new IPv6Packet(); + icmpv.setSourceAddress(locator.getAddress()); + icmpv.setDestinationAddress(iPv6Packet.getSourceAddress()); + icmpv.setTrafficClass(iPv6Packet.getTrafficClass()); + icmpv.setVersion(6); + icmpv.setFlowLabel(0); + icmpv.setHopLimit(255); + IPv6Payload ipl = new IPv6Payload(IpNumber.ICMPV6.value()); + ipl.getData().put(icbd.build().getRawData()); + ipl.getData().flip(); + icmpv.setPayload(ipl); + insertSRHandRoutePacket(icmpv); + } + } catch (Exception e) { + e.printStackTrace(); + }finally { + if(debug) { + System.out.println(dbg.toString()); + } + iPv6Packet.unlockAll(); + } + // }finally { + // routelock.readLock().unlock(); + // } + } + + private void processPacket(IPv6Packet iPv6Packet, RouteItem ri) throws IllegalRawDataException, IOException { + int hop = iPv6Packet.getHopLimit(); + + if (ri.getDestlink().isLoopBack()) { + IPv6SegmentRoutingHeader srhh = getSRHHeaderFromPacket(iPv6Packet); + if (srhh != null) { + processSRv6Packet(iPv6Packet, ri, srhh); + } else { + ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop()); + } + } else { + hop--; + // System.out.println(ipp.getHeader().getSrcAddr()+"->"+ipp.getHeader().getDstAddr()+" + // "+(hop+1)+"->"+hop); + if (hop > 0) { + + iPv6Packet.setHopLimit(hop); + ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop()); + } else { + IcmpV6TimeExceededPacket.Builder icmpte = new IcmpV6TimeExceededPacket.Builder(); + ByteBuffer IPv6data = NetworkPacket.databufferpool_65535.borrow(); + iPv6Packet.writeToChannel(KNEChannels.newWritableChannel(IPv6data)); + byte[] raw = new byte[IPv6data.remaining()]; + IPv6data.get(0, raw); + icmpte.payload(IpV6Packet.newPacket(raw, 0, raw.length)); + + IcmpV6CommonPacket.Builder icbd = new IcmpV6CommonPacket.Builder(); + icbd.type(IcmpV6Type.TIME_EXCEEDED); + icbd.code(IcmpV6Code.HOP_LIMIT_EXCEEDED); + icbd.srcAddr(locator.getAddress()); + icbd.dstAddr(iPv6Packet.getSourceAddress()); + icbd.correctChecksumAtBuild(true); + icbd.payloadBuilder(icmpte); + + IPv6Packet icmpv = new IPv6Packet(); + icmpv.setSourceAddress(locator.getAddress()); + icmpv.setDestinationAddress(iPv6Packet.getSourceAddress()); + icmpv.setTrafficClass(iPv6Packet.getTrafficClass()); + icmpv.setVersion(6); + icmpv.setFlowLabel(0); + icmpv.setHopLimit(255); + IPv6Payload ipl = new IPv6Payload(IpNumber.ICMPV6.value()); + ipl.getData().put(icbd.build().getRawData()); + ipl.getData().flip(); + icmpv.setPayload(ipl); + insertSRHandRoutePacket(icmpv); + } + } + + } + + private void processSRv6Packet(IPv6Packet iPv6Packet, RouteItem ri, IPv6SegmentRoutingHeader srhh) + throws IllegalRawDataException, IOException { + /*byte[] srd = new byte[(int) (srhh.getLength() - 4)]; + srhh.getData().get(4, srd); + IpV6RoutingSRHData srh = IpV6RoutingSRHData.newInstance(srd, 0, srd.length);*/ + if (srhh.getSegmentsLeft() <= 0) { + ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop()); + } else { + + int newSL = srhh.getSegmentsLeft() - 1; + srhh.setSegmentsLeft(newSL); + iPv6Packet.setDestinationAddress(srhh.getAddresses().get(newSL)); + klalbRouteProtol.putHotspotAddress(iPv6Packet.getSourceAddress()); + routePacket(iPv6Packet); + } + } + + private IPv6SegmentRoutingHeader getSRHHeaderFromPacket(IPv6Packet iPv6Packet) { + IPv6SegmentRoutingHeader srhh = null; + List exhs = iPv6Packet.getHeaders(); + for (int j = 0; j < exhs.size(); j++) { + IPv6ExtHeader exh = exhs.get(j); + if (exh instanceof IPv6SegmentRoutingHeader) { + if (((IPv6SegmentRoutingHeader) exh).getRoutingType() == 4) { + srhh = (IPv6SegmentRoutingHeader) exh; + break; + } + } + } + return srhh; + } + + public SRv6Router(Inet6AddressGroup hostAddress) { + super(); + this.locator = hostAddress; + //this.inLoopBackSRv6=new LoopbackIPv6NetworkLink(locator.getAddress()); + this.hostLoopBack= new LoopbackIPv6NetworkLink(hostAddress.getAddress()); + linkTabel.add(inLoopBack); + //linkTabel.add(inLoopBackSRv6); + linkTabel.add(hostLoopBack); + } + + /*public SRv6Router() { + super(); + linkTabel.add(inLoopBack); + }*/ + + private KLALBRoutingProtocol klalbRouteProtol = null; + + public void runKLALBRouteProtocol() { + if (klalbRouteProtol != null) + throw new IllegalStateException("KLALB routing protocol is already running!"); + klalbRouteProtol = new KLALBRoutingProtocol(this); + klalbRouteProtol.start(); + } + + public KLALBRoutingProtocol getKlalbRouteProtol() { + return klalbRouteProtol; + } + + private Map protocolNumberRegister = new ConcurrentHashMap<>(); + + public Map getProtocolNumberRegister() { + return protocolNumberRegister; + } + + public void putProtocolNumberPacketAndInsertSRH(IPv6Packet pkt) { + // inLoopBack.getReceiveConsumer().accept(pkt); + srhReceive.accept(pkt); + } + + public void putProtocolNumberPacket(IPv6Packet pkt) { + // inLoopBack.getReceiveConsumer().accept(pkt); + defaultReceive.accept(pkt); + } +} diff --git a/src/org/kne/cloud/network/srv6/SRv6StreamSequenceTLV.java b/src/org/kne/cloud/network/srv6/SRv6StreamSequenceTLV.java new file mode 100644 index 0000000..67c0a88 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/SRv6StreamSequenceTLV.java @@ -0,0 +1,42 @@ +package org.kne.cloud.network.srv6; + +import java.io.DataInputStream; +import java.io.DataOutputStream; + +public class SRv6StreamSequenceTLV extends SRv6TLV { + + public SRv6StreamSequenceTLV() { + super(SEQS, 22, new byte[22]); + } + public SRv6StreamSequenceTLV(int lengthQTLV, byte[] rawQTLV) { + super(SEQS, lengthQTLV, rawQTLV); + } + public int getReserved(){ + return getValue()[0]<<8|getValue()[1]; + } + public void setReserved(int reserved) { + getValue()[0]=(byte) (reserved>>>8); + getValue()[1]=(byte) reserved; + } + public long getSequence() { + return (((long)getValue()[6] << 56) + + ((long)(getValue()[7] & 255) << 48) + + ((long)(getValue()[8] & 255) << 40) + + ((long)(getValue()[9] & 255) << 32) + + ((long)(getValue()[10] & 255) << 24) + + ((getValue()[11] & 255) << 16) + + ((getValue()[12] & 255) << 8) + + ((getValue()[13] & 255) << 0)); + } + public void setSequence(long sequence) { + getValue()[6] = (byte)(sequence >>> 56); + getValue()[7] = (byte)(sequence >>> 48); + getValue()[8] = (byte)(sequence >>> 40); + getValue()[9] = (byte)(sequence >>> 32); + getValue()[10] = (byte)(sequence >>> 24); + getValue()[11] = (byte)(sequence >>> 16); + getValue()[12] = (byte)(sequence >>> 8); + getValue()[13] = (byte)(sequence >>> 0); + + } +} diff --git a/src/org/kne/cloud/network/srv6/SRv6TLV.java b/src/org/kne/cloud/network/srv6/SRv6TLV.java new file mode 100644 index 0000000..0e8bc97 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/SRv6TLV.java @@ -0,0 +1,41 @@ +package org.kne.cloud.network.srv6; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +public class SRv6TLV { + public static final int PAD1=0; + public static final int PADN=4; + public static final int HMAC=5; + public static final int SEQS=7; + + private int type; + private int length; + private byte[]value; + public SRv6TLV(int type, int length, byte[] value) { + super(); + this.type = type; + this.length = length; + this.value = value; + } + @Override + public String toString() { + return "SRv6TLV [type=" + type + ", length=" + length + ", value=" + Arrays.toString(value) + "]"; + } + public int getType() { + return type; + } + public int getLength() { + return length; + } + public byte[] getValue() { + return value; + } + + public int getTotalLength() { + if(type==PAD1) { + return 1; + } + return 2+length; + } +} diff --git a/src/org/kne/cloud/network/srv6/SingleDijkstraAlgorithm.java b/src/org/kne/cloud/network/srv6/SingleDijkstraAlgorithm.java new file mode 100644 index 0000000..f41fa58 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/SingleDijkstraAlgorithm.java @@ -0,0 +1,86 @@ +package org.kne.cloud.network.srv6; + +import java.util.Arrays; + +public class SingleDijkstraAlgorithm implements DijkstraAlgorithm { + + private long[][] heap; + private long[][]pointers; + + private long[] direction; + private long[] shortest; + private boolean[] flags; + private long startPoint; + + + private static final long MAX_WEIGHT=Long.MAX_VALUE/256L; + @Override + public void setGraph(long[][] pointers,long[][] heap,long startPoint) { + this.heap=heap; + this.pointers=pointers; + /*for (int i = 0; i < pointers.length; i++) { + for (int j = 0; j < pointers[i].length; j++) { + System.out.println("pointers["+i+"]["+j+"]="+pointers[i][j]); + } + } + for (int i = 0; i < heap.length; i++) { + for (int j = 0; j < heap[i].length; j++) { + System.out.println("heap["+i+"]["+j+"]="+heap[i][j]); + } + }*/ + + this.startPoint=startPoint; + } + + @Override + public void run() { + direction=new long[pointers.length]; + shortest=new long[pointers.length]; + flags=new boolean[pointers.length]; + Arrays.fill(shortest, MAX_WEIGHT); + Arrays.fill(direction, -1); + + + shortest[(int) startPoint]=0; + direction[(int) startPoint]=startPoint; + + for(long i=1;i tcps=new ArrayList<>(); + private volatile long sequenceNumber; + public List getTcps() { + return tcps; + } + public long getSequenceNumber() { + return sequenceNumber; + } + public static class TcpPacketEntry{ + private IPv6Packet packet; + private long sequenceNumber; + private int length; + private long addtime=System.nanoTime(); + + public TcpPacketEntry(IPv6Packet packet, long sequenceNumber, int length) { + super(); + this.packet = packet; + this.sequenceNumber = sequenceNumber; + this.length = length; + } + public IPv6Packet getPacket() { + return packet; + } + public long getAddtime() { + return addtime; + } + public boolean checkTimeOut() { + return System.nanoTime()-addtime>5000000000L; + } + public long getSequenceNumber() { + return sequenceNumber; + } + public int getLength() { + return length; + } + @Override + public String toString() { + return "TcpPacketEntry [sequenceNumber=" + sequenceNumber + ", length=" + length + + ", addtime=" + addtime + "]"; + } + } + public void sortPackets(IPv6Packet pack,long seq,int length, PacketConsumer packconsumer) throws IOException { + rlock.lock(); + try { + //System.out.println("包序号:"+seq+" 长度:"+length); + //System.out.println("当前序号:"+sequenceNumber); + if(seq iterator = tcps.iterator(); iterator.hasNext();) { + TcpPacketEntry tcpPacketEntry = (TcpPacketEntry) iterator.next(); + if(tcpPacketEntry.getSequenceNumber()==sequenceNumber) { + iterator.remove(); + sequenceNumber+=tcpPacketEntry.getLength(); + packconsumer.accept(pack); + }else if(tcpPacketEntry.getSequenceNumber() tcps=new ConcurrentHashMap(); + public Map getTcps() { + return tcps; + } + public static class TcpPacketEntry{ + private IPv6Packet packet; + private long sequenceNumber; + private int length; + private long addtime=System.nanoTime(); + + public TcpPacketEntry(IPv6Packet packet, long sequenceNumber, int length) { + super(); + this.packet = packet; + this.sequenceNumber = sequenceNumber; + this.length = length; + } + public IPv6Packet getPacket() { + return packet; + } + public long getAddtime() { + return addtime; + } + public boolean checkTimeOut() { + return System.nanoTime()-addtime>1000000000L; + } + public long getSequenceNumber() { + return sequenceNumber; + } + public int getLength() { + return length; + } + @Override + public String toString() { + return "TcpPacketEntry [sequenceNumber=" + sequenceNumber + ", length=" + length + + ", addtime=" + addtime + "]"; + } + } + public boolean sortPackets(IPv6Packet pack,long seq,int length, PacketConsumer packconsumer) throws IOException { + if(length<=0) { + packconsumer.accept(pack); + return true; + } + rlock.lock(); + try { + //System.out.println("包序号:"+seq+" 长度:"+length); + Set>et= tcps.entrySet(); + for (Iterator> iterator = et.iterator(); iterator.hasNext();) { + Entry entry = (Entry) iterator.next(); + if(entry.getValue().checkTimeOut()) { + iterator.remove(); + } + } + TcpPacketEntry tpe= tcps.get(seq); + if(tpe==null) { + tcps.put(seq, new TcpPacketEntry(pack, seq, length)); + packconsumer.accept(pack); + }else { + if(tpe.getLength()==length) { + return false; + }else { + tcps.put(seq, new TcpPacketEntry(pack, seq, length)); + packconsumer.accept(pack); + } + } + }finally { + rlock.unlock(); + } + return true; + } +} diff --git a/src/org/kne/cloud/network/srv6/UnheaderObjectInputStream.java b/src/org/kne/cloud/network/srv6/UnheaderObjectInputStream.java new file mode 100644 index 0000000..6bb57cc --- /dev/null +++ b/src/org/kne/cloud/network/srv6/UnheaderObjectInputStream.java @@ -0,0 +1,17 @@ +package org.kne.cloud.network.srv6; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; + +public class UnheaderObjectInputStream extends ObjectInputStream{ + + + public UnheaderObjectInputStream(InputStream in) throws IOException { + super(in); + } + @Override + protected void readStreamHeader() throws IOException { + + } + + } \ No newline at end of file diff --git a/src/org/kne/cloud/network/srv6/UnheaderObjectOutputStream.java b/src/org/kne/cloud/network/srv6/UnheaderObjectOutputStream.java new file mode 100644 index 0000000..2c6db79 --- /dev/null +++ b/src/org/kne/cloud/network/srv6/UnheaderObjectOutputStream.java @@ -0,0 +1,17 @@ +package org.kne.cloud.network.srv6; + +import java.io.*; + +public class UnheaderObjectOutputStream extends ObjectOutputStream{ + + + public UnheaderObjectOutputStream(OutputStream out) throws IOException { + super(out); + } + @Override + protected void writeStreamHeader() throws IOException { + + } + +} + diff --git a/src/org/kne/cloud/network/te/BandwidthDistributer.java b/src/org/kne/cloud/network/te/BandwidthDistributer.java new file mode 100644 index 0000000..7475a02 --- /dev/null +++ b/src/org/kne/cloud/network/te/BandwidthDistributer.java @@ -0,0 +1,254 @@ +package org.kne.cloud.network.te; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +public class BandwidthDistributer { + private long totalBandwidth; + private AtomicLong totalBandwidthRequest=new AtomicLong(); + private long totalBandwidthRequestOld; + private volatile Map distrmap=new ConcurrentHashMap(); + private Map reqmap=new ConcurrentHashMap(); + private Map> distrUpdateConsumerMap=new ConcurrentHashMap>(); + private BiConsumer distUpdateConsumer; + private Consumer totalRequestUpdateConsumer; + private Lock rlock=new ReentrantLock(); + + public void setDistrUpdateConsumer(T address,Consumercon) { + if(con==null) { + distrUpdateConsumerMap.remove(address); + }else { + distrUpdateConsumerMap.put(address, con); + } + } + + public Map> getDistrUpdateConsumerMap() { + return distrUpdateConsumerMap; + } + + + public Consumer getTotalRequestUpdateConsumer() { + return totalRequestUpdateConsumer; + } + + + public void setTotalRequestUpdateConsumer(Consumer totalRequestUpdateConsumer) { + this.totalRequestUpdateConsumer = totalRequestUpdateConsumer; + } + + + public BiConsumer getDistUpdateConsumer() { + return distUpdateConsumer; + } + + + public void setDistUpdateConsumer(BiConsumer distUpdateConsumer) { + this.distUpdateConsumer = distUpdateConsumer; + } + + + private class BandwidthDistributeInfo implements Comparable{ + private T address; + private long distBandwidth; + @Override + public int compareTo(BandwidthDistributeInfo o) { + if(distBandwidth>o.distBandwidth) { + return 1; + }else if(distBandwidthndistrlist=new ArrayList(reqmap.size()); + + for (Entry entry : reqmap.entrySet()) { + T key = entry.getKey(); + Long val = entry.getValue(); + ndistrlist.add(new BandwidthDistributeInfo(key, val)); + } + + Collections.sort(ndistrlist); + int sumb=0; + for (int i = 0; i < ndistrlist.size(); i++) { + int avgingCount=ndistrlist.size()-i; + long ibw=(totalBandwidth-sumb)/(long)avgingCount; + if(ibw<=ndistrlist.get(i).distBandwidth) { + for (int j = i; j < ndistrlist.size(); j++) { + ndistrlist.get(j).distBandwidth=ibw; + } + break; + } + sumb+=ndistrlist.get(i).distBandwidth; + } + //System.out.println(ndistrlist); + Map newdistrmap=new HashMap(); + for (int i = 0; i < ndistrlist.size(); i++) { + BandwidthDistributeInfo bwi=ndistrlist.get(i); + newdistrmap.put(bwi.address, bwi.distBandwidth); + } + applyNewDistribute(newdistrmap); + } + + + + private void applyNewDistribute(Map newdistrmap) { + for (Entry entry : newdistrmap.entrySet()) { + T key = entry.getKey(); + Long val = entry.getValue(); + Long oval=distrmap.get(key); + if(oval!=null) { + if(oval.longValue()!=val.longValue()) { + noticeDistributeUpdate(key, val); + + distrmap.put(key, val); + } + }else { + noticeDistributeUpdate(key, val); + + distrmap.put(key, val); + } + } + for (Iterator> iterator = distrmap.entrySet().iterator(); iterator.hasNext();) { + Entry entry = (Entry) iterator.next(); + if(!newdistrmap.containsKey(entry.getKey())) { + noticeDistributeUpdate(entry.getKey(), 0L); + + iterator.remove(); + } + } + } + + + private void noticeDistributeUpdate(T key, Long val) { + if(distUpdateConsumer!=null) { + distUpdateConsumer.accept(key, val); + } + Consumerconl= distrUpdateConsumerMap.get(key); + if(conl!=null) { + conl.accept(val); + } + } + + + public Map getDistrmap() { + return distrmap; + } + + + + + + public Map getReqmap() { + return reqmap; + } + + + @Override + public String toString() { + return "BandwidthDistributer [totalBandwidth=" + totalBandwidth + ", distrmap=" + distrmap + ", reqmap=" + + reqmap + "]"; + } + + + public static void main(String[] args) throws UnknownHostException { + BandwidthDistributer bwd=new BandwidthDistributer(100*1000000L); + bwd.setDistUpdateConsumer((k,v)->{System.out.println(((Inet6Address) k).getHostAddress()+" "+v);}); + bwd.setTotalRequestUpdateConsumer((l)->{System.out.println(l);}); + bwd.setBandwidthRequest((Inet6Address) InetAddress.getByName("::2"),1*1000000L ); + bwd.setBandwidthRequest((Inet6Address) InetAddress.getByName("::4"),10*1000000L ); + bwd.setBandwidthRequest((Inet6Address) InetAddress.getByName("::5"),100*1000000L ); + bwd.setTotalBandwidth(110*1000000L); + bwd.setBandwidthRequest((Inet6Address) InetAddress.getByName("::2"),0L ); + + } +} diff --git a/src/org/kne/cloud/network/te/DWRRLoadingBalanceAlgorithm.java b/src/org/kne/cloud/network/te/DWRRLoadingBalanceAlgorithm.java new file mode 100644 index 0000000..5efe748 --- /dev/null +++ b/src/org/kne/cloud/network/te/DWRRLoadingBalanceAlgorithm.java @@ -0,0 +1,65 @@ +package org.kne.cloud.network.te; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +import org.kne.cloud.network.klalb.KLALBRemoteLine; + +public class DWRRLoadingBalanceAlgorithm> { + private Listentries; + + public List getEntries() { + return entries; + } + + public DWRRLoadingBalanceAlgorithm(List entries) { + super(); + this.entries = entries; + } + + public List roundEntriesList() { + Listresult=new ArrayList<>(); + Listtmp=new ArrayList<>(entries.size()); + tmp .addAll(entries); + double[] ranges=new double[tmp.size()]; + int rankn=0; + while(!tmp.isEmpty()) { + double sum=0.0; + for (int i = 0; i < tmp.size(); i++) { + T val=tmp.get(i); + sum+=val.getWeightAtRank(rankn); + ranges[i]=sum; + } + double selected=generateSelectedNumber(sum); + for (int i = 0; i < ranges.length; i++) { + if(selected<=ranges[i]) { + result.add(tmp.remove(i)); + break; + } + } + + rankn++; + } + //System.out.println(result); + return result; + } + private int counter=0; + private double generateSelectedNumber(double bound) { + counter++; + if(counter>=256) { + counter=0; + } + int counter0=0; + for (int i = 0; i < 8; i++) { + counter0<<=1; + counter0|=(counter>>>i)&1; + } + return ((double)counter0)/256*bound; + } + /*private Random r=new Random(); + private double generateSelectedNumber(double bound) { + return r.nextDouble(bound); + }*/ +} diff --git a/src/org/kne/cloud/network/te/LoadingBalanceEntry.java b/src/org/kne/cloud/network/te/LoadingBalanceEntry.java new file mode 100644 index 0000000..8f3e1b9 --- /dev/null +++ b/src/org/kne/cloud/network/te/LoadingBalanceEntry.java @@ -0,0 +1,7 @@ +package org.kne.cloud.network.te; + +public interface LoadingBalanceEntry extends Comparable{ + public void runPredict(); +public void noticeRank(int rank); +public double getWeightAtRank(int rank); +} diff --git a/src/org/kne/debug/Debuger.java b/src/org/kne/debug/Debuger.java index 25e7668..be60d10 100644 --- a/src/org/kne/debug/Debuger.java +++ b/src/org/kne/debug/Debuger.java @@ -104,11 +104,11 @@ public class Debuger extends Thread { for(int d=0;d, Object[]>elements=tmp.get(d); - if(((Thread)(elements.getValue()[1])).getName().startsWith("SocketBridge A->B")){ + /*if(((Thread)(elements.getValue()[1])).getName().startsWith("SocketBridge A->B")){ }else{ continue; - } + }*/ List k=elements.getKey(); StringBuilder sb=new StringBuilder(); for(int d2=0;d2 l=new LinkedHashMap(); + private Map timeMap=new LinkedHashMap(); + private Lock timeLock=new ReentrantLock(); long tmp=-1; + public void putTime(String name){ - + timeLock.lock(); + try{ long v=System.nanoTime(); if(tmp==-1){ - l.put(name, 0l); + timeMap.put(name, 0l); }else{ - l.put(name, v-tmp); + timeMap.put(name, v-tmp); } tmp=v; + }finally { + timeLock.unlock(); + } } + + public Map getTimeMap() { + return timeMap; + } + public void print(){ exct.execute(()->{ - System.err.println(l+"(ns)"); + timeLock.lock(); + + try{ + StringBuilder sbdr=new StringBuilder(); + sbdr.append('{'); + for (Iterator> iterator = timeMap.entrySet().iterator(); iterator.hasNext();) { + Entry type = (Entry) iterator.next(); + sbdr.append(type.getKey()).append('=').append(type.getValue()); + if(iterator.hasNext()) { + sbdr.append(','); + } + } + sbdr.append("}(ns)"); + System.out.println(sbdr.toString()); + }finally { + timeLock.unlock(); + } + }); + } + + public void printWithTimeFilter(long nanos){ + exct.execute(()->{ + boolean b=false; + timeLock.lock(); + + try{ + StringBuilder sbdr=new StringBuilder(); + sbdr.append('{'); + for (Iterator> iterator = timeMap.entrySet().iterator(); iterator.hasNext();) { + Entry type = (Entry) iterator.next(); + if(type.getValue()>=nanos) { + b=true; + } + sbdr.append(type.getKey()).append('=').append(type.getValue()); + if(iterator.hasNext()) { + sbdr.append(','); + } + } + sbdr.append("}(ns)"); + if(b) + System.out.println(sbdr.toString()); + }finally { + timeLock.unlock(); + } }); } } diff --git a/src/org/kne/io/ByteBufferManagement.java b/src/org/kne/io/ByteBufferManagement.java new file mode 100644 index 0000000..15e3ae7 --- /dev/null +++ b/src/org/kne/io/ByteBufferManagement.java @@ -0,0 +1,5 @@ +package org.kne.io; + +public class ByteBufferManagement { + //private +} diff --git a/src/org/kne/io/KNEChannels.java b/src/org/kne/io/KNEChannels.java new file mode 100644 index 0000000..417ee9c --- /dev/null +++ b/src/org/kne/io/KNEChannels.java @@ -0,0 +1,73 @@ +package org.kne.io; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; + +public class KNEChannels { + private static class ByteBufferWritableByteChannel implements WritableByteChannel{ + private ByteBuffer bbf; + + public ByteBuffer getBbf() { + return bbf; + } + public ByteBufferWritableByteChannel(ByteBuffer bbf) { + this.bbf=bbf; + } + @Override + public boolean isOpen() { + return true; + } + + @Override + public void close() throws IOException { + + } + + @Override + public int write(ByteBuffer src) throws IOException { + int opos=src.position(); + //System.out.println(bbf+" "+src); + bbf.put(src); + return src.position()-opos; + } + } + public static WritableByteChannel newWritableChannel(ByteBuffer bbf) { + return new ByteBufferWritableByteChannel(bbf); + } + private static class ByteBufferReadableByteChannel implements ReadableByteChannel { + private ByteBuffer bbf; + + public ByteBuffer getBbf() { + return bbf; + } + public ByteBufferReadableByteChannel(ByteBuffer bbf) { + this.bbf=bbf; + } + @Override + public boolean isOpen() { + return true; + } + + @Override + public void close() throws IOException { + } + + @Override + public int read(ByteBuffer dst) throws IOException { + if(!bbf.hasRemaining()) { + return -1; + } + int lmtl=Math.min(bbf.remaining() ,dst.remaining()); + int olm=bbf.limit(); + bbf.limit(bbf.position()+lmtl); + dst.put(bbf); + bbf.limit(olm); + return lmtl; + } + } + public static ReadableByteChannel newReadableChannel(ByteBuffer bbf) { + return new ByteBufferReadableByteChannel(bbf); + } +} diff --git a/src/org/kne/io/Task.java b/src/org/kne/io/Task.java deleted file mode 100644 index 827debb..0000000 --- a/src/org/kne/io/Task.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.kne.io; - -public abstract class Task implements Runnable{ - private volatile boolean begin=false,end=false; - private volatile Object t=new Object(); - @Override - public void run() { - begin=true; - runTask(); - - end=true; - if(t!=null) { - synchronized(t) { - t.notifyAll(); - } - } - } - public void waitfortask() { - synchronized(t){ - - try { - while(!end) { - t.wait(1); - } - } catch (InterruptedException e) { - - e.printStackTrace(); - }} - } - protected abstract void runTask(); -} diff --git a/wintun.dll b/wintun.dll new file mode 100644 index 0000000..aee04e7 Binary files /dev/null and b/wintun.dll differ