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