优化代码,性能暴涨

This commit is contained in:
Administrator
2025-01-29 14:01:11 +08:00
parent e243203535
commit 6de65562be
130 changed files with 9138 additions and 1020 deletions

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

@@ -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;
}
}
}
@@ -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);
@@ -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;
@@ -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<MultipurposeSocketAddress> msas;
private volatile Consumer<MultipurposeSocketAddress> con;
public NetworkInterface getNinterface() {
return ninterface;
}
public InetSocketAddress getGroup() {
return group;
}
public InetSocketAddress getBind() {
return bind;
}
public Consumer<MultipurposeSocketAddress> getCon() {
return con;
}
public void setCon(Consumer<MultipurposeSocketAddress> con) {
this.con = con;
}
public IPMulticastDiscovery(InetSocketAddress bind, InetSocketAddress group, NetworkInterface ninterface,
List<MultipurposeSocketAddress> 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<MultipurposeSocketAddress> s = new HashSet<MultipurposeSocketAddress>();
for (Iterator<MultipurposeSocketAddress> 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<InetAddress> 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<InetAddress> 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;
}
}
@@ -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() {
@@ -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<NetworkPacket>{
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(priority<o.priority){
return -1;
}else {
if(sendseq>o.sendseq) {
return 1;
}else if(sendseq<o.sendseq){
return -1;
}else {
return 0;
}
}
}
public void disposeAll() {
dispose();
}
public void doDisposeAfterSend() {
if(isDisposeAfterSend())
dispose();
}
public void genseq() {
this.sendseq=seqgen.getAndIncrement();
}
protected abstract void writeToChannel(WritableByteChannel dto) throws IOException ;
protected abstract void readFromChannel(ReadableByteChannel din,long length) throws IOException;
protected void readFromChannel(ReadableByteChannel din) throws IOException{
readFromChannel(din,-1);
}
protected abstract boolean needEndPosition();
}
+40
View File
@@ -0,0 +1,40 @@
package org.kne.cloud.network;
import java.util.Objects;
public class PortPair {
private int sport;
private int dport;
@Override
public String toString() {
return sport+"->"+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;
}
}
@@ -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");
@@ -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();
@@ -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();
}
+59 -43
View File
@@ -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);
}
}
@@ -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)
+1 -1
View File
@@ -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);
@@ -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;
}
@@ -54,7 +54,8 @@ public class FrpcProcess extends Process{
}
AtomicReference<IOException >arex=new AtomicReference<IOException >();
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();
@@ -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);
}
}
@@ -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<Neighbor> 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(Consumer<IPv6Packet>con);
}
@@ -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<IPv6ExtHeader> 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<headers.size()) {
exth.setNextHeader(headers.get(i+1).getProtocolNumber());
}else {
exth.setNextHeader(payload.getProtocolNumber());
}
exth.writeToChannel(dto);
}
payload.writeToChannel(dto);
}
@Override
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
IPv6header.limit(IPv6_HEADER_LENGTH);
IPv6header.position(0);
while (IPv6header.hasRemaining()) {
if (din.read(IPv6header) == -1) {
throw new EOFException();
}
}
int payloadlength=getPayloadLength();
int nextheader=getNextHeader();
loop:while(true) {
IPv6ExtHeader ext;
switch(nextheader) {
case 0:
ext=new IPv6ExtHeader(nextheader);
ext.readFromChannel(din, 0);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headers.add(ext);
break;
case 60:
ext=new IPv6DestinationHeader();
ext.readFromChannel(din, 0);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headers.add(ext);
break;
case 43:
ByteBuffer bbf=NetworkPacket.databufferpool_2048.borrow();
bbf.limit(4);
while (bbf.hasRemaining()) {
if (din.read(bbf) == -1) {
throw new EOFException();
}
}
int routingType= bbf.get(2)&0xff;
switch(routingType) {
case 4:
ext=new IPv6SegmentRoutingHeader(bbf);
break;
default:
ext=new IPv6RoutingHeader(true,bbf);
break;
}
ext.readFromChannel(din, 0);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headers.add(ext);
break;
case 44:
ext=new IPv6ExtHeader(nextheader);
ext.readFromChannel(din, 0);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headers.add(ext);
break;
case 50:
ext=new IPv6ExtHeader(nextheader);
ext.readFromChannel(din, 0);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headers.add(ext);
break;
case 51:
ext=new IPv6ExtHeader(nextheader);
ext.readFromChannel(din, 0);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headers.add(ext);
break;
case 59:
ext=new IPv6ExtHeader(nextheader);
ext.readFromChannel(din, 0);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headers.add(ext);
break;
case KLALBPacket.KLALB_PROTOCOL_NUMBER:
KLALBPacket kp=KLALBPacket.readKLALBPacketFromChannel(din);
this.payload=kp;
break loop;
default:
IPv6Payload pld=new IPv6Payload(nextheader);
pld.readFromChannel(din, payloadlength);
this.payload=pld;
break loop;
}
}
}
/*public void analyse() {
headers.clear();
int headerPos=IPv6_HEADER_LENGTH;
int nextheader=getNextHeader();
int payloadlength=getPayloadLength();
loop: while(true) {
IPv6ExtHeader ext;
switch(nextheader) {
case 0:
ext=new IPv6ExtHeader(headerPos,nextheader);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headerPos+=ext.getLength();
headers.add(ext);
break;
case 60:
ext=new IPv6DestinationHeader(headerPos);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headerPos+=ext.getLength();
headers.add(ext);
break;
case 43:
ext=new IPv6RoutingHeader(headerPos);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headerPos+=ext.getLength();
headers.add(ext);
break;
case 44:
ext=new IPv6ExtHeader(headerPos,nextheader);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headerPos+=ext.getLength();
headers.add(ext);
break;
case 50:
ext=new IPv6ExtHeader(headerPos,nextheader);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headerPos+=ext.getLength();
headers.add(ext);
break;
case 51:
ext=new IPv6ExtHeader(headerPos,nextheader);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headerPos+=ext.getLength();
headers.add(ext);
break;
case 59:
ext=new IPv6ExtHeader(headerPos,nextheader);
nextheader=ext.getNextHeader();
payloadlength-=ext.getLength();
headerPos+=ext.getLength();
headers.add(ext);
break;
default:
IPv6Payload pld=new IPv6Payload(headerPos,payloadlength,nextheader);
this.payload=pld;
break loop;
}
}
//System.out.println(headers);
//System.out.println(payload);
}*/
@Override
public void lockAll() {
super.lockAll();
for (int i = 0; i < headers.size(); i++) {
headers.get(i).lockAll();
}
payload.lockAll();
}
@Override
public boolean isSomeDisposed() {
if(super.isSomeDisposed()||payload.isSomeDisposed())
return true;
for (Iterator<IPv6ExtHeader> 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<Inet6Address> addresses=new ArrayList<Inet6Address>();
private final List<IPv6SegmentRoutingTLV> tlvs=new ArrayList<IPv6SegmentRoutingTLV>();
@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<Inet6Address> 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<Inet6Address> getAddresses() {
return addresses;
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
setExtLength(calcExtLength()/8);
setLastEntry(addresses.size()-1);
super.writeToChannel(dto);
for (Iterator<Inet6Address> iterator = addresses.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next();
dto.write(ByteBuffer.wrap(inet6Address.getAddress()));
}
}
private int calcExtLength() {
int tlvsl=0;
for (Iterator<IPv6SegmentRoutingTLV> 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<IPv6ExtHeader> 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()){
IPv6ExtHeader iext=headers.get(index);
ptr=iext.getPointer();
}else {
throw new IndexOutOfBoundsException(index);
}
byte[]temp=new byte[(int) (IPv6data.limit()-ptr)];
IPv6data.get((int) ptr, temp);
IPv6data.limit((int) (IPv6data.limit()+lth));
setPayloadLength((int) (getPayloadLength()+lth));
IPv6data.put((int) (ptr+lth), temp);
IPv6DestinationHeader irh=new IPv6DestinationHeader(ptr,extLength);
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()){
IPv6ExtHeader iext=headers.get(index);
ptr=iext.getPointer();
}else {
throw new IndexOutOfBoundsException(index);
}
byte[]temp=new byte[(int) (IPv6data.limit()-ptr)];
IPv6data.get((int) ptr, temp);
IPv6data.limit((int) (IPv6data.limit()+lth));
setPayloadLength((int) (getPayloadLength()+lth));
IPv6data.put((int) (ptr+lth), temp);
IPv6RoutingHeader irh=new IPv6RoutingHeader(ptr,(int) ((lth-8)/8));
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;
}
}
@@ -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<ByteBuffer> sendQueue = new LinkedBlockingQueue<ByteBuffer>();
private volatile Consumer<IPv6Packet> 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<SRv6TLV> 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<Neighbor> getNeighborsInfo() {
List<Neighbor> 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<IPv6Packet> con) {
this.con = con;
}
public void setMonitor(SpeedAndTrafficMonitorDataImpl monitor) {
this.monitor = monitor;
}
public SpeedAndTrafficMonitorDataImpl getMonitor() {
return monitor;
}
@Override
public Inet6AddressGroup getAddressGroup() {
return hostAddress;
}
}
@@ -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<Inet6AddressGroup>{
private static final byte[][] maskTransf=new byte[129][16];
static {
for (int i = 0; i < 129; i++) {
for(int j=0;j<i;j++) {
maskTransf[i][j/8]=(byte) (((0b10000000)>>>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();
}
}
@@ -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);
}
}
@@ -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<RouteItem>{
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());
}
}
+22 -17
View File
@@ -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);
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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";
}
}
@@ -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
@@ -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 ArrayBlockingQueue<byte[]>rec;
private Queue<byte[]> rec;
private int maxcount;
private int length;
public ByteArrayPool(int maxcount, int length) {
super();
this.maxcount = maxcount;
this.length = length;
rec=new ArrayBlockingQueue<byte[]>(length);
rec=new ConcurrentLinkedQueue<byte[]>();
}
public void back(byte[]b) {
if(b.length!=length)
@@ -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 ArrayBlockingQueue<ByteBuffer>rec;
private Queue<ByteBuffer> 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<ByteBuffer>(length);
rec=new ConcurrentLinkedQueue<ByteBuffer>();
}
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(pos<mcj)
rec[++pos]= b;
}finally{
lock.unlock();
}
}
public ByteBuffer borrow() {
ByteBuffer b=null;
lock.lock();
try {
if(pos>0) {
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;
}
}
+4 -2
View File
@@ -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;
}
@@ -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 自动生成的构造函数存根
}
}
@@ -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);*/
}
}
@@ -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();
}
}
@@ -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 List<MultipurposeSocketAddress>selflineTable=new ArrayList<>();
private static final boolean showpacket = false;
private static final int PREFIX = 112;
private static final int DISCOVERY_PORT=4569;
private static List<IPMulticastDiscovery> ipmd=new ArrayList<>();
private Timer twk=new Timer("网卡检测扫描计时器", true);
{
@@ -76,16 +87,23 @@ public class KLALBController {
@Override
public void run() {
try {
Enumeration<NetworkInterface>eu= 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());
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement();
if(!inetAddress.isLoopbackAddress())
for (Iterator<MultipurposeSocketAddress> iterator = listens.iterator(); iterator.hasNext();) {
MultipurposeSocketAddress tcpl = (MultipurposeSocketAddress) iterator.next();
@@ -107,11 +125,15 @@ public class KLALBController {
}
}
}
}
} catch (SocketException e) {
}
lineslock.writeLock().lock();
try {
List<MultipurposeSocketAddress>localaddress=new ArrayList<>();
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
while (eu.hasMoreElements()) {
@@ -169,7 +191,82 @@ public class KLALBController {
}
}
for (Iterator<IPMulticastDiscovery> 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());
}
}
Enumeration<NetworkInterface>eu2= 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<IPMulticastDiscovery> iterator = ipmd.iterator(); iterator.hasNext();) {
IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next();
if(networkInterface.equals(ipMulticastDiscovery.getNinterface())) {
b=false;
break;
}
}
if(b) {
/*InetAddress bidr=null;
Enumeration<InetAddress>ei= 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<KLALBRemoteLine> lines=new CopyOnWriteArrayList<>();
//private ReadWriteLock lineslock=new ReentrantReadWriteLock();
private ReadWriteLock lineslock=new ReentrantReadWriteLock();
public List<KLALBRemoteLine> 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<KLALBPacket>{
@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<KLALBRemoteLine> addRemoteLines(MultipurposeSocketAddress target) {
List<KLALBRemoteLine>added=new ArrayList<>();
try {
Enumeration<NetworkInterface>eu= 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<KLALBRemoteLine> removeRemoteLines(MultipurposeSocketAddress mpsa) {
List<KLALBRemoteLine>rmved=new ArrayList<>();
for (Iterator<KLALBRemoteLine> 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<Inet6Address,List<KLALBRemoteLine>> lines2 =new ConcurrentHashMap<>();
Map<Inet6Address,DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 =new ConcurrentHashMap<>();
for (Iterator<KLALBRemoteLine> 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 {
ArrayList<KLALBRemoteLine>al1=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<Entry<Inet6Address, List<KLALBRemoteLine>>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, List<KLALBRemoteLine>> klalbRemoteLine = (Entry<Inet6Address, List<KLALBRemoteLine>>) iterator.next();
klalbRemoteLine.getValue().forEach((r)->{
for (Iterator<Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> klalbRemoteLine = (Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>) iterator.next();
List<KLALBRemoteLine> 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<KLALBRemoteLine> 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<Inet6Address,List<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>();
}*/
private Map<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> 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<KLALBRemoteLine> 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<KLALBRemoteLine> dwrlines2x;
dwrlines2x=lines2.get(addr);
if (dwrlines2x == null || dwrlines2x.getEntries().isEmpty()) {
throw new NoRouteToHostException("address unreachable: " + addr);
}
List<KLALBRemoteLine>lines2x=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<Inet6Address,BandwidthDistributer<PortPair>> bandwidthDistrmap=new ConcurrentHashMap<>();
private Lock bdmLock=new ReentrantLock();
protected Map<Inet6Address, BandwidthDistributer<PortPair>> getBandwidthDistrmap() {
return bandwidthDistrmap;
}
protected void registerDistUpdateConsumer(Inet6Address targetaAddress,PortPair portp, Consumer<Long> updateConsumer) {
if(updateConsumer==null) {
System.out.println("连接"+targetaAddress.getHostAddress()+" "+portp+" 释放带宽!");
bdmLock.lock();
try {
BandwidthDistributer<PortPair> 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<PortPair> 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<PortPair> 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);
@@ -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);
+128 -14
View File
@@ -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<KLALBRemoteLine> 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]);
List<KLALBRemoteLine>addl=kpcje.getKlalbController().addRemoteLines(mpsa);
if(addl.isEmpty()) {
System.out.println("添加失败,线路已存在!");
}else {
for (Iterator<KLALBRemoteLine> 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]);
List<KLALBRemoteLine>rmvl=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<RouteItem> lri=new ArrayList<>( kpcje.getKlalbController().getIpv6Router().getCurrentRouteTabel());
Collections.sort(lri);
System.out.println("路由表:");
System.out.println("前缀\t协议\t优先级\t开销\t标志\t下一跳\t接口");
for (Iterator<RouteItem> 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");
}
}
@@ -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 {
+103 -100
View File
@@ -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<KLALBPacket>{
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<KLALBPacket>{
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<KLALBRemoteLine> 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(priority<o.priority){
return -1;
}else {
if(sendseq>o.sendseq) {
return 1;
}else if(sendseq<o.sendseq){
return -1;
}else {
return 0;
}
}
public int getSendCounter() {
return sendCounter.get();
}
protected void genseq() {
this.sendseq=seqgen.getAndIncrement();
public void incSendCounter() {
sendCounter.incrementAndGet();
}
private List<KLALBRemoteLine> sendRecord=new ArrayList<>(2);
private volatile boolean disposed;
private volatile ReentrantLock disposeLock=new ReentrantLock();
public boolean isDisposed() {
return disposed;
}
public List<KLALBRemoteLine> getSendRecord() {
/*public List<KLALBRemoteLine> 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<KLALBPacket>{
}
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<KLALBPacket>{
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<KLALBPacket>{
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;
}
}
@@ -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<KLALBRemoteLine, KLALBPacket> {
public interface KLALBPacketConsumer extends BiConsumer<Inet6Address, KLALBPacket> {
}
@@ -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;
@@ -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;
@@ -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<KLALBRemoteLine> {
public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteLine> ,LoadingBalanceEntry<KLALBRemoteLine>{
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<Inet6Address> localVaddrSupplier;
private volatile Supplier<Inet6AddressGroup> localVaddrSupplier;
private volatile KLALBController klalbController;
@@ -64,21 +59,21 @@ public class KLALBRemoteLine implements Comparable<KLALBRemoteLine> {
public void setKlalbController(KLALBController klalbController) {
this.klalbController = klalbController;
if (klalbController != null && remoteVaddr != null) {
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr);
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress());
}
}
public Supplier<Inet6Address> getLocalVaddrSupplier() {
public Supplier<Inet6AddressGroup> getLocalVaddrSupplier() {
return localVaddrSupplier;
}
public void setLocalVaddrSupplier(Supplier<Inet6Address> localVaddrSupplier) {
public void setLocalVaddrSupplier(Supplier<Inet6AddressGroup> 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<KLALBRemoteLine> {
}
}
public SpeedAndTrafficAndDelayMonitorDataImpl getMonitor() {
public QueueingMonitorDataImpl getMonitor() {
return monitor;
}
@@ -106,7 +101,7 @@ public class KLALBRemoteLine implements Comparable<KLALBRemoteLine> {
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<KLALBRemoteLine> {
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<KLALBRemoteLine> {
}
}
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<KLALBRemoteLine> {
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<KLALBRemoteLine> {
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<KLALBRemoteLine> {
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<KLALBRemoteLine> {
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<KLALBRemoteLine> {
}
// tdb.putTime("park");
}
}*/
// tdb.print();
// System.out.println(sendDequeList.isEmpty());
@@ -343,26 +375,26 @@ public class KLALBRemoteLine implements Comparable<KLALBRemoteLine> {
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<KLALBRemoteLine> {
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<KLALBRemoteLine> {
} 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<KLALBRemoteLine> {
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<KLALBRemoteLine> {
} 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<KLALBRemoteLine> {
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<KLALBRemoteLine> {
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<KLALBRemoteLine, KLALBPacket> 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<KLALBPacket> rec;
private volatile Thread tlock;
@@ -572,6 +674,7 @@ public class KLALBRemoteLine implements Comparable<KLALBRemoteLine> {
}
protected void sendPacket(KLALBPacket blk) {
blk.markJoinqueuetime();
sendDequeList.add(blk);
LockSupport.unpark(tlock);
}
@@ -581,7 +684,7 @@ public class KLALBRemoteLine implements Comparable<KLALBRemoteLine> {
LockSupport.unpark(tlock);
}
public void setPacketReceiver(BiConsumer<KLALBRemoteLine, KLALBPacket> rec) {
public void setPacketReceiver(Consumer< KLALBPacket> rec) {
this.rec = rec;
}
@@ -641,7 +744,7 @@ public class KLALBRemoteLine implements Comparable<KLALBRemoteLine> {
}
}
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<KLALBRemoteLine> {
return predictTime;
}
private List<Double>ranks=new ArrayList<Double>();
private Consumer<IPv6Packet> 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<Double> getRanks() {
return ranks;
}
@Override
public boolean isLoopBack() {
return false;
}
@Override
public List<Neighbor> getNeighborsInfo() {
List<Neighbor>hs=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<IPv6Packet> ipv6con) {
this.ipv6con=ipv6con;
}
}
@@ -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());
+106 -5
View File
@@ -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());
}
}
}
}
@@ -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<DATATPacket> sendDeque = new ArrayBlockingQueue<DATATPacket>(20000);
private Queue<DATATPacket> recvQueue = new ConcurrentLinkedQueue<DATATPacket>();
private AtomicInteger recvQueueUsed=new AtomicInteger(0);
//private AtomicInteger recvCounter=new AtomicInteger(0);
private Map<Long,DATATPacket> 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<DATATPacket> 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<Object> inputchache = new ArrayList<>();
private ReentrantLock inputchachelock=new ReentrantLock();
//private List<Object> inputchache = new RangeArrayList<>();
private Map<Long,DATATPacket> inputchache=new ConcurrentHashMap();
private Lock inputchachelock=new SpinLock();
private long inputcount = 0;
private volatile boolean avaliable = true;
private AtomicBoolean firstUpdate=new AtomicBoolean(true);
private volatile long RTTMin=1000000000L;
private volatile long RTTVar=1000000000L;
private volatile long RTTAvg=1000000000L;
private volatile long RTO=1000000000L;
private volatile long QueueingAvg=1000000000L;
private volatile long RunningSpeed=spdlmt.getLimitspeed();
private long RTTMin=1000000000L;
private volatile boolean ignoreBindCheck;
private boolean connected;
@@ -307,7 +342,9 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
protected void connect(InetAddress address, int port) throws IOException {
connect(new InetSocketAddress(address, port), 10000);
}
private PortPair portp;
@Override
protected void connect(SocketAddress address, int timeout) throws IOException {
if(!ignoreBindCheck)
@@ -317,13 +354,14 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
port = ((InetSocketAddress) address).getPort();
this.address=this.remoteaddr = (Inet6Address) ((InetSocketAddress) address).getAddress();
if(connected)
throw new SocketException("already connected");
controller.getStreamPortBinder().connect(this);
connectionPending=true;
controller.getResendTimer().schedule(sendCheckTask, 50, 50);
controller.getResendTimer().schedule(sendCheckTask, 10, 10);
//controller.sendPacketToAddress((Inet6Address) this.remoteaddr, new SYNTPacket(localport, port), 0,1);
try {
getKVSIOutputStream().write(compress);
@@ -345,6 +383,16 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
}
connected=true;
PortPair portpx=new PortPair(localport, port);
controller.registerDistUpdateConsumer(remoteaddr, portpx, (c)->{
//System.out.println(c);
spdlmt.setLimitspeed(Math.max(MIN_LIMIT_SPEED,c));
});
updateBandwidthReq(requestSpeed);
this.portp=portpx;
}catch(SocketTimeoutException e) {
throw new SocketTimeoutException("connect time out");
}catch(NoRouteToHostException e) {
@@ -357,6 +405,11 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
controller.getResendTimer().schedule(flowControlTask, 5000, 5000);
}
private void updateBandwidthReq(long requestSpeed) {
if(remoteaddr!=null&&portp!=null)
controller.updateBandwidthRequest(remoteaddr, portp,requestSpeed );
}
public boolean isConnectionPending() {
return connectionPending;
}
@@ -424,7 +477,7 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
kvsi.remoteaddr=(Inet6Address) isa.getAddress();
kvsi.bind(localaddr, localport,true);
kvsi.accept((KLALBRemoteLine)p[1],(KLALBPacket) p[2]);
kvsi.accept((Inet6Address)p[1],(KLALBPacket) p[2]);
kvsi.connect(isa, 5000);
/*kvsi.port = isa.getPort();
kvsi.localport = localport;
@@ -463,26 +516,30 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
while (true) {
if (isClosed())
throw new SocketException("Socket is closed");
DATATPacket dtp2 = sendDeque.poll();
DATATPacket dtp2 = recvQueue.poll();
if (dtp2 != null) {
recvQueueUsed.addAndGet(-dtp2.getSize());
//System.out.println("PULL:"+dtp2);
dataPack = dtp2;
socketMonitor.getInTrafficAL().addAndGet(dtp2.getSize());
socketMonitor.getInPacketCounterAL().incrementAndGet();
controller.getDatatMonitor().getInTrafficAL().addAndGet(dtp2.getSize());
checkFlowControl(dtp2);
controller.getDatatMonitor().getInPacketCounterAL().incrementAndGet();
//checkFlowControl(dtp2);
break;
}
sendDequeLock=Thread.currentThread();
LockSupport.parkNanos(1000000);
}
//System.out.println("sorted:"+dataPack);
return dataPack;
}
private void checkFlowControl(DATATPacket dtp2) throws IOException {
if(sendDeque.size() >= inputchachesize/MTU-4) {
controller.sendPacketToAddress(remoteaddr, new ACKTPacket(dtp2.getDport(), dtp2.getSport(), dtp2.getNumber(),
/*private void checkFlowControl(DATATPacket dtp2) throws IOException {
if(recvQueue.size() >= inputchachesize/MTU-4) {
controller.sendPacketToAddress(remoteaddr,0,KLALB_PROTOCOL_NUMBER, new ACKTPacket(dtp2.getDport(), dtp2.getSport(), dtp2.getNumber(),
true,dtp2.getSendcount()));
}
}
}*/
@Override
@@ -501,6 +558,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
dst.limit(dst.position()+len);
dst.put( dataPack.getDataBuffer().get()) ;
if(!dataPack.getDataBuffer().hasRemaining()) {
dataPack.putTimePassport("unpacked");
dataPack.printPassport();
dataPack.dispose();
dataPack=null;
}
@@ -523,6 +582,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
i+=min;
//b[off + i]= dtp.getData()[count++] ;
if(!dataPack.getDataBuffer().hasRemaining()) {
dataPack.putTimePassport("unpacked");
dataPack.printPassport();
dataPack.dispose();
dataPack=null;
}
@@ -558,6 +619,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
len = Math.min(len, available());
b[off]= dataPack.getDataBuffer().get() ;
if(!dataPack.getDataBuffer().hasRemaining()) {
dataPack.putTimePassport("unpacked");
dataPack.printPassport();
dataPack.dispose();
dataPack=null;
}
@@ -578,6 +641,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
i+=min;
//b[off + i]= dtp.getData()[count++] ;
if(!dataPack.getDataBuffer().hasRemaining()) {
dataPack.putTimePassport("unpacked");
dataPack.printPassport();
dataPack.dispose();
dataPack=null;
}
@@ -601,13 +666,13 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
}
@Override
public int available() throws IOException {
AtomicInteger i = new AtomicInteger(0);
sendDeque.forEach((V) -> {
i.addAndGet(V.getSize());
});
int i = recvQueueUsed.get();
/*for(DATATPacket V:recvQueue) {
i+=(V.getSize());
}*/
if (dataPack != null)
i.addAndGet(dataPack.getDataBuffer().remaining());
return i.get();
i+=dataPack.getDataBuffer().remaining();
return i;
}
@Override
@@ -629,7 +694,6 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
this.compress = compress;
}
private static final int MTU=60000;
protected class KVSIOutputStream extends OutputStream implements WritableByteChannel{
DATATPacket dataPack=new DATATPacket(localport, port, outputcount++,MTU);
@@ -730,7 +794,7 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
throw new SocketException("Socket is closed");
if(sendmap.isEmpty())
break;
if(timeout!=0&&(System.nanoTime()-start>timeout*1000000))
if(timeout!=0&&(System.nanoTime()-start>timeout*1000000L))
throw new SocketTimeoutException("wait for acknowledged timout");
sendthread=Thread.currentThread();
LockSupport.parkNanos(1000000L);
@@ -794,6 +858,7 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
}
//TimeDebugger td=new TimeDebugger();
//td.putTime("start");
dataPack.putTimePassport("packed");
while (!avaliable) {
try {
Thread.sleep(1);
@@ -801,35 +866,46 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
e.printStackTrace();
}
}
dataPack.putTimePassport("waitForAvaliable");
//td.putTime("waitForAvaliable");
while(true){
if (isClosed())
throw new SocketException("Socket is closed");
//System.out.println(sendmap.size());
boolean b=sendmap.size()<=reallimit/MTU;
boolean b=sendmapWindowUsed.get()<=reallimit;
//boolean b=sendmap.size()<=reallimit/MTU;
if(b)
break;
sendthread=Thread.currentThread();
LockSupport.parkNanos(1000000L);
}
dataPack.putTimePassport("waitForWindow");
//td.putTime("waitForCache");
DATATPacket pack=dataPack;
dataPack=new DATATPacket(localport, port, outputcount++,MTU);
dataPack.putTimePassport("buildHeader");
pack.getDataBuffer().flip();
//System.out.println(pack.getDataBuffer());
//cacheCreateTime=System.nanoTime();
//td.putTime("flushBuffer");
//spdlmt.transmit(count);
spdlmt.transmit(pack.getDataBuffer().limit());
socketMonitor.getOutTrafficAL().addAndGet(pack.getDataBuffer().limit());
socketMonitor.getOutPacketCounterAL().incrementAndGet();
controller.getDatatMonitor().getOutTrafficAL().addAndGet(pack.getDataBuffer().limit());
controller.getDatatMonitor().getOutPacketCounterAL().incrementAndGet();
//td.putTime("doStatistic");
pack.setPriority(5);
pack.resendtimer=System.nanoTime();
controller.sendPacketToAddress(remoteaddr,pack);
socketRawMonitor.getOutTrafficAL().addAndGet(pack.getLength());
controller.sendPacketToAddress(remoteaddr,0,pack);
//td.putTime("doSend");
/* sendmaplock.readLock().lock();
try{*/
pack.resendtimer=System.nanoTime();
sendmap.put(pack.getNumber(),pack);
DATATPacket prv= sendmap.put(pack.getNumber(),pack);
sendmapWindowUsed.addAndGet(pack.getSize());
if(prv!=null)
sendmapWindowUsed.addAndGet(-prv.getSize());
//System.out.println("PUSH:"+pack);
/*}finally {
sendmaplock.readLock().unlock();
@@ -849,20 +925,24 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
}
private void close0() throws IOException {
//outputclosed=true;
if(isClosed())
return;
olock.lock();
try {
flush0();
}finally {
olock.unlock();
}
DATATPacket pack=new DATATPacket(localport, port, outputcount++,MTU);
pack.setPriority(5);
pack.getDataBuffer(). flip();
controller.sendPacketToAddress(remoteaddr,pack);
controller.sendPacketToAddress(remoteaddr,0,pack);
/*sendmaplock.readLock().lock();
try{*/
pack.resendtimer=System.nanoTime();
sendmap.put(pack.getNumber(),pack);
sendmapWindowUsed.addAndGet(pack.getSize());
/*}finally {
sendmaplock.readLock().unlock();
}*/
@@ -958,6 +1038,7 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
private void close0(boolean b) throws IOException {
if ( !isClosed()) {
closed = true;
if(!isListening() ) {
sendCheckTask.cancel();
flowControlTask.cancel();
@@ -965,11 +1046,17 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
if(remoteaddr!=null)
try {
controller.sendPacketToAddress(remoteaddr, new RSTPacket(super.localport, super.port),
controller.sendPacketToAddress(remoteaddr,0, new RSTPacket(super.localport, super.port),
2);
} catch (NoRouteToHostException e) {
}
controller.getStreamPortBinder().disconnect(this);
if(portp!=null) {
PortPair portpx=portp;
portp=null;
controller.updateBandwidthRequest(remoteaddr, portpx, 0L);
controller.registerDistUpdateConsumer(remoteaddr, portpx, null);
}
}else {
//System.out.println("unlisten"+getLocalPort());
controller.getStreamPortBinder().unlisten(this);
@@ -1001,18 +1088,22 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
InputStream is=getInputStream();
OutputStream os=getOutputStream();
if((!(is instanceof KVSIInputStream))||(!(os instanceof KVSIOutputStream))) {
throw new SocketException("cant use association because compress is enabled");
throw new CannotAssociateException("cant use association because compress is enabled");
}
KVSIInputStream kis=(KVSIInputStream) is;
KVSIOutputStream kos=(KVSIOutputStream) os;
Thread t1=ThreadTool.makeVThreadIfSupport("本地发送线程", ()->{
boolean onError=false;
try {
DATATPacket dp;
while((dp=kis.nextPacket()).getSize()!=0) {
b.write(dp.getDataBuffer());
dp.putTimePassport("unpacked");
dp.printPassport();
dp.dispose();
}
}catch(IOException e) {
onError=true;
e.printStackTrace();
}finally {
try {
@@ -1025,23 +1116,68 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
} catch (IOException e) {
e.printStackTrace();
}
if(true) {
try {
b.close();
} catch (IOException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
try {
close();
} catch (IOException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
}
}
});
Thread t2=ThreadTool.makeVThreadIfSupport("本地接收线程", ()->{
boolean onError=false;
try {
ByteBuffer tst=ByteBuffer.allocateDirect(MTU);
while(true) {
if(b.read(kos.dataPack.getDataBuffer())==-1) {
if(nodelay) {
if(b.read(kos.dataPack.getDataBuffer())==-1) {
break;
}
kos.flush0();
}else {
if(b.read(tst)==-1) {
break;
}
tst.flip();
kos.olock.lock();
try {
kos.flush0();
kos.dataPack.getDataBuffer().put(tst);
/*if(b.read(kos.dataPack.getDataBuffer())==-1) {
break;
}*/
}finally {
kos.olock.unlock();
}
if(kos.dataPack.getDataBuffer().hasRemaining()) {
kos.olock.lock();
try {
kos.flush();
}finally {
kos.olock.unlock();
}
}else {
kos.olock.lock();
try {
kos.flush0();
}finally {
kos.olock.unlock();
}
}
tst.clear();
}
}
}catch(IOException e) {
onError=true;
e.printStackTrace();
}finally {
try {
@@ -1054,6 +1190,20 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
} catch (IOException e) {
e.printStackTrace();
}
if(true) {
try {
b.close();
} catch (IOException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
try {
close();
} catch (IOException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
}
}
});
t1.start();
@@ -1064,6 +1214,7 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
} catch (InterruptedException e) {
e.printStackTrace();
}
b.close();
close();
}
@@ -1077,18 +1228,22 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
InputStream is=getInputStream();
OutputStream os=getOutputStream();
if((!(is instanceof KVSIInputStream))||(!(os instanceof KVSIOutputStream))) {
throw new SocketException("cant use association because compress is enabled");
throw new CannotAssociateException("cant use association because compress is enabled");
}
KVSIInputStream kis=(KVSIInputStream) is;
KVSIOutputStream kos=(KVSIOutputStream) os;
Thread t1=ThreadTool.makeVThreadIfSupport("本地发送线程", ()->{
boolean onError=false;
try {
DATATPacket dp;
while((dp=kis.nextPacket()).getSize()!=0) {
orc.write(dp.getDataBuffer());
dp.putTimePassport("unpacked");
dp.printPassport();
dp.dispose();
}
}catch(IOException e) {
onError=true;
e.printStackTrace();
}finally {
try {
@@ -1101,23 +1256,68 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
} catch (IOException e) {
e.printStackTrace();
}
if(true) {
try {
associateSocket.close();
} catch (IOException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
try {
close();
} catch (IOException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
}
}
});
Thread t2=ThreadTool.makeVThreadIfSupport("本地接收线程", ()->{
boolean onError=false;
try {
ByteBuffer tst=ByteBuffer.allocateDirect(MTU);
while(true) {
if(irc.read(kos.dataPack.getDataBuffer())==-1) {
break;
}
if(nodelay) {
if(irc.read(kos.dataPack.getDataBuffer())==-1) {
break;
}
kos.flush0();
}else {
if(irc.read(tst)==-1) {
break;
}
tst.flip();
kos.olock.lock();
try {
kos.dataPack.getDataBuffer().put(tst);
/*if(irc.read(kos.dataPack.getDataBuffer())==-1) {
break;
}*/
}finally {
kos.olock.unlock();
}
if(kos.dataPack.getDataBuffer().hasRemaining()) {
kos.olock.lock();
try {
kos.flush();
}finally {
kos.olock.unlock();
}
}else {
kos.olock.lock();
try {
kos.flush0();
}finally {
kos.olock.unlock();
}
}
tst.clear();
}
}
}catch(IOException e) {
onError=true;
e.printStackTrace();
}finally {
try {
@@ -1130,6 +1330,20 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
} catch (IOException e) {
e.printStackTrace();
}
if(true) {
try {
associateSocket.close();
} catch (IOException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
try {
close();
} catch (IOException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
}
}
});
t1.start();
@@ -1140,11 +1354,12 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
} catch (InterruptedException e) {
e.printStackTrace();
}
associateSocket.close();
close();
}
@Override
public void accept(KLALBRemoteLine from, KLALBPacket u) {
public void accept(Inet6Address from, KLALBPacket u) {
try {
//System.out.println(this+" "+u);
switch (u.getType()) {
@@ -1155,13 +1370,15 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
break;
case KLALBPacket.DATAT:
DATATPacket dtp = (DATATPacket) u;
socketRawMonitor.getInTrafficAL().addAndGet(dtp.getLength());
if(isListening()) {
if(dtp.getNumber()==0) {
backlogQueuelock.lock();
try{
//controller.getStreamPortBinder().checkIsConnected(new Pair);
InetSocketAddress is=new InetSocketAddress(from.getRemoteVaddr(), dtp.getSport());
InetSocketAddress is=new InetSocketAddress(from, dtp.getSport());
AtomicBoolean ab=new AtomicBoolean(true);
for (Iterator iterator = backlogQueue.iterator(); iterator.hasNext();) {
Object[] objects = (Object[]) iterator.next();
@@ -1171,7 +1388,7 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
}
}
if(ab.get()) {
if(controller.getStreamPortBinder().checkIsConnect(this,new InetSocketAddress(from.getRemoteVaddr(), dtp.getSport()))) {
if(controller.getStreamPortBinder().checkIsConnect(this,new InetSocketAddress(from, dtp.getSport()))) {
ab.set(false);
}
}
@@ -1182,7 +1399,7 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
/* controller.sendPacketToAddress(from.getRemoteVaddr(), new ACKTPacket(dtp.getDport(), dtp.getSport(),dtp.getNumber(),true,0),
0,2);*/
}else {
controller.sendPacketToAddress(from.getRemoteVaddr(), new RSTPacket(dtp.getDport(), dtp.getSport()),
controller.sendPacketToAddress(from,0, new RSTPacket(dtp.getDport(), dtp.getSport()),
2);
}
@@ -1191,96 +1408,185 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
backlogQueuelock.unlock();
}
}else {
controller.sendPacketToAddress(from.getRemoteVaddr(), new RSTPacket(dtp.getDport(), dtp.getSport()),
controller.sendPacketToAddress(from,0, new RSTPacket(dtp.getDport(), dtp.getSport()),
2);
}
}else {
controller.sendPacketToAddress(from.getRemoteVaddr(), new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp.getNumber(),
sendDeque.size() < inputchachesize/MTU,dtp.getSendcount()), 1);
inputchachelock.lock();
try{
if (dtp.getNumber() >= inputcount) {
int currindex=(int) (dtp.getNumber()-inputcount);
//System.out.println(dtp.isCE());
controller.sendPacketToAddress(from,0, new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp.getNumber(),
recvQueueUsed.get() < inputchachesize,dtp.isCE(),socketMonitor.getInSpeedMax(),dtp.getSendcount()), 1);
boolean added=false;
long number=dtp.getNumber();
if (number >= inputcount) {
inputchache.putIfAbsent(number, dtp);
/*inputchachelock.lock();
try{
int currindex=(int) (number-inputcount);
int reqsize=1+currindex;
while(reqsize>inputchache.size()) {
inputchache.add(new AtomicInteger());
}
for (int i = 0; i < currindex; i++) {
Object o=inputchache.get(i);
if(o instanceof AtomicInteger) {
((AtomicInteger) o).incrementAndGet();
/*if(((AtomicInteger) o).get()==30) {
controller.sendPacketToAddress(from.getRemoteVaddr(), new NACKTPacket(dtp.getDport(), dtp.getSport(), inputcount+i),1);
//System.out.println("请求快速重传:"+(inputcount+i));
}*/
}
}
inputchache.set(currindex, dtp);
Iterator<Object>itr=inputchache.iterator();
while (itr.hasNext()) {
Object datatPacket = itr.next();
if(datatPacket instanceof DATATPacket) {
itr.remove();
sendDeque.add((DATATPacket) datatPacket);
LockSupport.unpark(sendDequeLock);
inputcount++;
}else {
break;
}
inputchache.add(null);
}
if(currindex>=0) {
DATATPacket old=(DATATPacket) inputchache.get(currindex);
if(old==null) {
inputchache.set(currindex, dtp);
}else {
dtp.dispose();
}
}
int spos=inputchache.size();
for (int i = 0; i < inputchache.size(); i++) {
DATATPacket datatPacket=(DATATPacket) inputchache.get(i);
if(datatPacket==null) {
spos=i;
break;
}
}
for (int i = 0; i < spos; i++) {
DATATPacket datatPacket = (DATATPacket)inputchache.get(i);
recvQueueUsed.addAndGet(datatPacket.getSize());
recvQueue.add(datatPacket);
added=true;
inputcount++;
}
((RangeArrayList)inputchache).removeRange(0,spos);
}finally{
inputchachelock.unlock();
}*/
}else {
dtp.dispose();
}
}finally{
inputchachelock.lock();
try {
DATATPacket datatPacket = inputchache.remove(inputcount);
if(datatPacket!=null) {
inputcount++;
recvQueueUsed.addAndGet(datatPacket.getSize());
recvQueue.add(datatPacket);
added=true;
}
}finally {
inputchachelock.unlock();
}
if(added) {
LockSupport.unpark(sendDequeLock);
}
//dbg.println(from.getMonitor()+","+dtp.getNumber());
}
break;
case KLALBPacket.ACKT:
ACKTPacket ackt = (ACKTPacket) u;
if(isListening()) {
controller.sendPacketToAddress(from.getRemoteVaddr(), new RSTPacket(ackt.getDport(), ackt.getSport()),
controller.sendPacketToAddress(from,0, new RSTPacket(ackt.getDport(), ackt.getSport()),
2);
}else {
avaliable = ackt.isAvaliable();
rcvSpeed=ackt.getRcvSpeed();
/*if(rcvSpeed>=congressSpeed) {
congressSpeed=rcvSpeed;
}else {
congressSpeed=(congressSpeed*99+rcvSpeed)/100;
}*/
if(ackt.isCongress()) {
congressFactor=1.2;
if(reallimit>MTU*2) {
reallimit-=8192;
//System.out.println(reallimit+" -2048");
}
}else {
if(sendmapWindowUsed.get()*2L>=reallimit) {
reallimit+=1024;
//System.out.println(reallimit+" +1024");
}
}
requestSpeed=(long) (Math.max(MIN_LIMIT_SPEED, rcvSpeed)*congressFactor);
//System.out.println(spdlmt.getLimitspeed()/1024+"K "+ackt.getRcvSpeed()/1024+"K");
DATATPacket kl=null;
/*sendmaplock.readLock().lock();
try{*/
kl=sendmap.remove(ackt.getNumber());
/* }finally {
sendmaplock.readLock().unlock();
}*/
if(kl!=null) {
sendmapWindowUsed.addAndGet(-kl.getSize());
}
if(kl!=null) {
if(sendthread!=null)
LockSupport.unpark(sendthread);
//controller.removeFromSend(from.getRemoteVaddr(),kl);
if(kl.getSendRecord().size()==1) {
if(kl.getSendCounter()==1) {
long RTTC=ackt.getRcvtime()- kl.getSndtime();
if(RTTC<=RTTMin) {
RTTMin=RTTC;
}else {
RTTMin= (RTTMin*9999+RTTC)/10000;
RTTMin= (RTTMin*99999+RTTC)/100000;
}
/*if(RTTC>RTTMin*2) {
if(reallimit>MTU*3) {
reallimit=reallimit-512;
}
long queueing=RTTC-RTTMin;
QueueingAvg=(QueueingAvg*99999+queueing)/100000;
if(firstUpdate.compareAndSet(true, false)) {
RTTAvg=RTTC;
RTTVar=RTTC/2;
}else {
RTTVar=(RTTVar*3+Math.abs(RTTAvg-RTTC))/4;
RTTAvg= (RTTAvg*7+RTTC)/8;
}
RTO=RTTAvg+Math.max(MIN_RTTVAR, RTTVar*4);//RTTVar*4
/*if(RTTC>RTO) {
congressFactor=Math.min( 0.9,congressFactor);
}else {
if(reallimit<outputchachesize)
reallimit+=512;
}*/
if(congressFactor<1.1)
congressFactor+=0.001;
} */
//System.out.println(congressFactor);
//spdlmt.setLimitspeed(1024*1024);
//reallimit=Math.max(MTU*2,(int) (congressSpeed*RTTMin*4/1000000000L));
//System.out.println(reallimit/MTU);
/*long nspd=(long) (congressSpeed*congressFactor);
spdlmt.setLimitspeed(Math.max(nspd,MIN_LIMIT_SPEED));*/
// System.out.println("RwqSpeed:"+(requestSpeed/1024)+"K MaxSpeed:"+(congressSpeed/1024)+"K LimitSpeed:"+(spdlmt.getLimitspeed()/1024)+"K");
//System.out.println("RTTMin:"+RTTMin/1000000L+"ms RTTAvg:"+RTTAvg/1000000L+"ms");
}
kl.dispose();
}
}
ackt.dispose();
break;
@@ -1302,7 +1608,7 @@ public void associateSocketChannel(SocketChannel b) throws IOException{
//System.out.println("快速重传:"+st);
st.setPriority(4);
controller.sendPacketToAddress(remoteaddr,st);
controller.sendPacketToAddress(remoteaddr,0,st);
}
break;
default:
@@ -10,16 +10,17 @@ import java.util.concurrent.atomic.AtomicInteger;
public class NACKTPacket extends KLALBPacket implements PortPacket{
private static final int HEADER_LENGTH=18;
public NACKTPacket(int sport,int dport,long number) {
super(NACKT);
header.putInt(sport);
header.putInt(dport);
header.putLong(number);
super(NACKT,HEADER_LENGTH);
klalbHeader.putInt(sport);
klalbHeader.putInt(dport);
klalbHeader.putLong(number);
}
public NACKTPacket(ByteBuffer bb) {
super(bb);
super(bb,HEADER_LENGTH);
}
@Override
@@ -28,25 +29,15 @@ public class NACKTPacket extends KLALBPacket implements PortPacket{
}
public int getSport() {
return header.getInt(1);
}
@Override
protected int getHeaderSize() {
return super.getHeaderSize()+17;
}
@Override
public long getLength() {
return super.getLength()+17;
return klalbHeader.getInt(1);
}
public int getDport() {
return header.getInt(5);
return klalbHeader.getInt(5);
}
public long getNumber() {
return header.getLong(9);
return klalbHeader.getLong(9);
}
@@ -9,30 +9,20 @@ import java.nio.ByteBuffer;
public class PINGPacket extends KLALBPacket {
private static final int HEADER_LENGTH=9;
public long getTime() {
return header.getLong(1);
return klalbHeader.getLong(1);
}
@Override
public long getLength() {
return super.getLength()+8;
}
@Override
protected int getHeaderSize() {
return super.getHeaderSize()+8;
}
public PINGPacket(long time) {
super(PING,-1);
header.putLong(time);
super(PING,HEADER_LENGTH,-1);
klalbHeader.putLong(time);
}
public PINGPacket(ByteBuffer bb) {
super(bb);
super(bb,HEADER_LENGTH);
}
@Override
+11 -14
View File
@@ -9,40 +9,37 @@ import java.nio.ByteBuffer;
public class PONGPacket extends KLALBPacket {
private static final int HEADER_LENGTH=25;
public long getTimepingsnd() {
return header.getLong(1);
return klalbHeader.getLong(1);
}
public long getTimepingrcv() {
return header.getLong(9);
return klalbHeader.getLong(9);
}
public long getTimepongsnd() {
return header.getLong(17);
return klalbHeader.getLong(17);
}
@Override
protected int getHeaderSize() {
return super.getHeaderSize()+24;
}
@Override
public long getLength() {
return super.getLength()+24;
return HEADER_LENGTH;
}
public PONGPacket( long timepingsnd,long timepingrcv, long timepongsnd) {
super(PONG,-1);
header.putLong(timepingsnd);
header.putLong(timepingrcv);
header.putLong(timepongsnd);
super(PONG,HEADER_LENGTH,-1);
klalbHeader.putLong(timepingsnd);
klalbHeader.putLong(timepingrcv);
klalbHeader.putLong(timepongsnd);
}
public PONGPacket(ByteBuffer bb) {
super(bb);
super(bb,HEADER_LENGTH);
}
@@ -204,29 +204,29 @@ public class PortBinder {
}
return b;
}*/
public boolean distributePacketToConsumer(KLALBRemoteLine krl,PortPacket packet) throws SocketTimeoutException {
public boolean distributePacketToConsumer(Inet6Address srcAddr,PortPacket packet) {
InetSocketAddress local=new InetSocketAddress(controller.getSelf(), packet.getDport());
InetSocketAddress remote=new InetSocketAddress(krl.getRemoteVaddr(), packet.getSport());
InetSocketAddress remote=new InetSocketAddress(srcAddr, packet.getSport());
BindableKLALBPacketConsumer bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(local, remote));
if(bkc!=null) {
bkc.accept(krl, (KLALBPacket) packet);
bkc.accept(srcAddr, (KLALBPacket) packet);
return true;
}
InetSocketAddress localany=new InetSocketAddress(ANYLA, packet.getDport());
bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(localany, remote));
if(bkc!=null) {
bkc.accept(krl, (KLALBPacket) packet);
bkc.accept(srcAddr, (KLALBPacket) packet);
return true;
}
bkc=listenMap.get(local);
if(bkc!=null) {
bkc.accept(krl, (KLALBPacket) packet);
bkc.accept(srcAddr, (KLALBPacket) packet);
return true;
}
bkc=listenMap.get(localany);
if(bkc!=null) {
bkc.accept(krl, (KLALBPacket) packet);
bkc.accept(srcAddr, (KLALBPacket) packet);
return true;
}
+7 -16
View File
@@ -8,33 +8,24 @@ import java.io.IOException;
import java.nio.ByteBuffer;
public class RSTPacket extends KLALBPacket implements PortPacket{
private static final int HEADER_LENGTH=9;
public RSTPacket(int sport,int dport) {
super(RST);
header.putInt(sport);
header.putInt(dport);
super(RST,HEADER_LENGTH);
klalbHeader.putInt(sport);
klalbHeader.putInt(dport);
}
public RSTPacket(ByteBuffer bb) {
super(bb);
}
@Override
public long getLength() {
return super.getLength()+8;
}
@Override
protected int getHeaderSize() {
return super.getHeaderSize()+8;
super(bb,HEADER_LENGTH);
}
public int getSport() {
return header.getInt(1);
return klalbHeader.getInt(1);
}
public int getDport() {
return header.getInt(5);
return klalbHeader.getInt(5);
}
@Override
@@ -0,0 +1,13 @@
package org.kne.cloud.network.klalb;
import java.util.ArrayList;
public class RangeArrayList<E> extends ArrayList<E>{
@Override
protected void removeRange(int fromIndex, int toIndex) {
// TODO 自动生成的方法存根
super.removeRange(fromIndex, toIndex);
}
}
@@ -15,6 +15,7 @@ import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.SocketBridge;
import org.kne.cloud.network.SocketListener;
import org.kne.cloud.network.SocketToSocketProxy;
import org.kne.cloud.network.klalb.ui.KLALBStateGUI2;
import org.kne.util.AutoProperties;
public class SimpleKLALBClient {
@@ -17,6 +17,7 @@ import org.kne.cloud.network.SocketBridge;
import org.kne.cloud.network.SocketListener;
import org.kne.cloud.network.SocketToSocketProxy;
import org.kne.cloud.network.SocketType;
import org.kne.cloud.network.klalb.ui.KLALBStateGUI2;
public class SimpleKLALBServer {
public static KLALBStateGUI2 ksg;
@@ -24,7 +24,27 @@ import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.TimeoutTimer;
public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
private static TimeoutTimer tmoTimer=new TimeoutTimer();
private volatile long timeoutTimer;
private volatile boolean timerenabled=false;
private Thread timeouter=new Thread() {
public void run() {
timeoutTimer=System.nanoTime();
while(connectSocket.isOpen()) {
if(timerenabled&&(System.nanoTime()-timeoutTimer>sotimeout*1000000L)) {
if(connectSocket!=null)
try {
connectSocket.close();
} catch (IOException e) {
}
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
@Override
public String toString() {
try {
@@ -38,9 +58,10 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
private int sotimeout;
public StreamChannelKLALBPacketLink(SocketChannel connectSocket) throws IOException {
this.connectSocket=connectSocket;
connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
timeouter.start();
new KLALBOutputStream(Channels.newOutputStream(connectSocket));
new KLALBInputStream(Channels.newInputStream(connectSocket));
connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
}
@@ -51,19 +72,21 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
@Override
public KLALBPacket readPacket() throws IOException {
TimerTask tsk= tmoTimer.createTimeOutTask(connectSocket, sotimeout);
timeoutTimer=System.nanoTime();
timerenabled=true;
KLALBPacket res;
try {
res=KLALBPacket.readKLALBPacketFromChannel(connectSocket);
}finally {
if(tsk!=null)
tsk.cancel();
timerenabled=false;
}
return res;
}
@Override
public void close() throws IOException {
//System.out.println("连接被关闭");
//new Exception().printStackTrace();
connectSocket.close();
}
+30 -14
View File
@@ -4,53 +4,69 @@ import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import org.kne.cloud.network.NetworkPacket;
public class TESTPacket extends KLALBPacket {
private static ByteBuffer K=ByteBuffer.allocateDirect(1024);
private static final int HEADER_LENGTH=3;
private ByteBuffer dataBuffer;//=NetworkPacket.databufferpool_65535.borrow();
@Override
public long getLength() {
return super.getLength()+K.limit();
return HEADER_LENGTH+dataBuffer.limit();
}
@Override
protected int getHeaderSize() {
return super.getHeaderSize();
public TESTPacket(int limit) {
super(TEST,HEADER_LENGTH);
//dataBuffer.limit(limit);
dataBuffer=ByteBuffer.allocate(limit);
}
public TESTPacket() {
super(TEST);
public ByteBuffer getDataBuffer() {
return dataBuffer;
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
klalbHeader.putChar(1, (char) dataBuffer.limit());
super.writeToChannel(dto);
dto.write(K.slice());
//System.out.println(dataBuffer);
dto.write(dataBuffer.slice(0, dataBuffer.limit()));
}
@Override
protected void readFromChannel(ReadableByteChannel din) throws IOException {
super.readFromChannel(din);
din.read(K.slice());
int limit=klalbHeader.getChar(1);
//dataBuffer.clear();
//dataBuffer.limit(limit);
dataBuffer=ByteBuffer.allocate(limit);
while(dataBuffer.hasRemaining()){
if(din.read(dataBuffer)==-1) {
throw new EOFException();
}
}
dataBuffer.flip();
}
public TESTPacket(ByteBuffer bb) {
super(bb);
super(bb,HEADER_LENGTH);
}
@Override
public String toString() {
return "TEST";
return "TEST["+dataBuffer.limit()+"]";
}
@@ -4,12 +4,13 @@ import java.nio.ByteBuffer;
public class VADDRACKPacket extends KLALBPacket {
private static final int HEADER_LENGTH=1;
public VADDRACKPacket() {
super(VADDRACK);
super(VADDRACK,HEADER_LENGTH);
}
public VADDRACKPacket(ByteBuffer bb) {
super(bb);
super(bb,HEADER_LENGTH);
}
@Override
@@ -9,40 +9,34 @@ import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
public class VADDRPacket extends KLALBPacket {
public Inet6Address getVaddr() {
private static final int HEADER_LENGTH=18;
public Inet6AddressGroup getVaddr() {
byte[]b=new byte[16];
header.get(1, b);
klalbHeader.get(1, b);
try {
return (Inet6Address) Inet6Address.getByAddress(b);
return new Inet6AddressGroup( (Inet6Address) Inet6Address.getByAddress(b),klalbHeader.get(17)&0xff);
} catch (UnknownHostException e) {
e.printStackTrace();
}
return null;
}
public VADDRPacket(Inet6Address vaddr) {
super(VADDR);
header.put(1, vaddr.getAddress());
public VADDRPacket(Inet6AddressGroup vaddr) {
super(VADDR,HEADER_LENGTH);
klalbHeader.put(1, vaddr.getAddress().getAddress());
klalbHeader.put(17,(byte) vaddr.getPrefixLength());
}
public VADDRPacket(ByteBuffer bb) {
super(bb);
super(bb,HEADER_LENGTH);
}
@Override
public String toString() {
return "VADDR "+getVaddr().getHostAddress();
}
@Override
protected int getHeaderSize() {
return super.getHeaderSize()+16;
}
@Override
public long getLength() {
return super.getLength()+16;
return "VADDR "+getVaddr();
}
}
@@ -4,12 +4,14 @@ import java.nio.ByteBuffer;
public class VADDRREQPacket extends KLALBPacket {
private static final int HEADER_LENGTH=1;
public VADDRREQPacket() {
super(VADDRREQ);
super(VADDRREQ,HEADER_LENGTH);
}
public VADDRREQPacket(ByteBuffer bb) {
super(bb);
super(bb,HEADER_LENGTH);
}
@Override
@@ -1,4 +1,4 @@
package org.kne.cloud.network.klalb;
package org.kne.cloud.network.klalb.ui;
import java.awt.AWTException;
import java.awt.Color;
@@ -21,6 +21,9 @@ import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import org.kne.cloud.network.klalb.CONST;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.ui.XFrame;
import org.kne.ui.YScrollPane;
@@ -1,45 +1,42 @@
package org.kne.cloud.network.klalb;
package org.kne.cloud.network.klalb.ui;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
import javax.management.monitor.Monitor;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.dial.DialLayer;
import org.jfree.chart.plot.dial.DialPlot;
import org.jfree.chart.plot.dial.DialPointer;
import org.jfree.chart.plot.dial.DialTextAnnotation;
@@ -47,35 +44,20 @@ import org.jfree.chart.plot.dial.StandardDialFrame;
import org.jfree.chart.plot.dial.StandardDialRange;
import org.jfree.chart.plot.dial.StandardDialScale;
import org.jfree.chart.ui.RectangleEdge;
import org.jfree.chart.ui.RectangleInsets;
import org.jfree.data.general.Dataset;
import org.jfree.data.general.DefaultValueDataset;
import org.jfree.data.general.ValueDataset;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.SocketBridge;
import org.kne.cloud.network.SocketListener;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.klalb.CONST;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.ui.XFrame;
import org.kne.ui.YScrollPane;
import javax.swing.JProgressBar;
import javax.swing.border.LineBorder;
import javax.swing.JTabbedPane;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JCheckBoxMenuItem;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.FlowLayout;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import java.awt.Font;
import javax.swing.JScrollPane;
public class KLALBStateGUI2 extends XFrame {
private TimerTask tsk,tsk2,tsk3;
private TimerTask tsk,tsk2,tsk3,tsk4,tsk5;
private SystemTray st;
@@ -83,7 +65,7 @@ public class KLALBStateGUI2 extends XFrame {
private long rate=200;
private Timer t,t2;
private Timer t,t2,t3;
private JCheckBoxMenuItem showoffline;
@@ -96,42 +78,57 @@ public class KLALBStateGUI2 extends XFrame {
private DefaultValueDataset downSpeed;
private DefaultValueDataset upEfficiency;
private DefaultValueDataset upPPS;
private DialTextAnnotation upPPSText;
private DialTextAnnotation downPPSText;
private DefaultValueDataset downPPS;
private DefaultValueDataset upDataSpeed;
private DefaultValueDataset downDataSpeed;
private DefaultValueDataset upDataPPS;
private DefaultValueDataset downDataPPS;
/*private DefaultValueDataset upEfficiency;
private DialTextAnnotation upEfficiencyText;
private DialTextAnnotation downEfficiencyText;
private DefaultValueDataset downEfficiency;
private DefaultValueDataset downEfficiency;*/
private YScrollPane ysp;
private static BufferedImage bi;
public static Image getKLALBIcon() {
if(bi==null)
try {
bi = ImageIO.read(KLALBStateGUI2.class.getResourceAsStream("/assets/KNEL.png"));
} catch (IOException e) {
e.printStackTrace();
}
return bi;
}
private JTextField devicesOnline;
private JTextField textField;
private JTextField addressField;
private NetworkGraphPanel graph;
public KLALBStateGUI2(KLALBController kpcje) {
this(kpcje ,CONST.klalb+" network accelerator V"+CONST.klalbver);
}
/**
* @wbp.parser.constructor
*/
public KLALBStateGUI2(KLALBController kpcje) {
this(kpcje ,CONST.klalb+" SRv6 network accelerator V"+CONST.klalbver);
}
public KLALBStateGUI2(KLALBController kc,String title) {
//setResizable(false);
Image bix=getKLALBIcon();
if(bix!=null)
setIconImage(bix);
setTitleColor(new Color(255, 255, 255, 250));
//getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f));
setIconImage(UIEnv.getIcon());
//setTitleColor(new Color(255, 255, 255, 250));
setTitleColor(UIEnv.getDefaultTitleColor());
getContentPane().setBackground(UIEnv.getDefaultBackgroundColor());
getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f));
getTitlepanel().setBorder(new LineBorder(Color.LIGHT_GRAY));
getTitlelabel().setForeground(Color.WHITE);
//getContentPane().setBackground(new Color(0,0,0,0));
/*setTitleColor(new Color(0,0,0,80));
getContentPane().setBackground(new Color(0,0,0,80));
@@ -145,13 +142,21 @@ public class KLALBStateGUI2 extends XFrame {
overview.setOpaque(false);
tabbedPane.addTab("Overview", null, overview, null);
overview.setLayout(new BorderLayout(0, 0));
JPanel dashboard = new JPanel();
dashboard.setOpaque(false);
overview.add(dashboard, BorderLayout.CENTER);
dashboard.setBorder(new LineBorder(new Color(0, 0, 0)));
JPanel dashs = new JPanel();
dashs.setOpaque(false);
overview.add(dashboard,BorderLayout.CENTER);
dashboard.setLayout(new BorderLayout(0, 0));
dashboard.add(dashs);
{
upSpeed = new DefaultValueDataset(0);
upDataSpeed=new DefaultValueDataset(0);
DialPlot dpup=new DialPlot();
dpup.setDataset(upSpeed);
dpup.setDataset(1,upSpeed);
dpup.setDataset(0, upDataSpeed);
StandardDialFrame sdfs=new StandardDialFrame();
sdfs.setVisible(false);
dpup.setDialFrame(sdfs);
@@ -175,19 +180,29 @@ public class KLALBStateGUI2 extends XFrame {
sdrr3.setOuterRadius(0.83);
dpup.addLayer(sdrr3);
DialPointer.Pointer dpd=new DialPointer.Pointer();
dpd.setRadius(0.7);
dpd.setFillPaint(new Color(127, 0, 0,0));
dpd.setOutlinePaint(new Color(127, 0, 0));
dpd.setDatasetIndex(0);
dpup.addLayer(dpd);
DialPointer.Pointer dp=new DialPointer.Pointer();
dp.setRadius(0.7);
dp.setFillPaint(Color.RED);
dp.setOutlinePaint(Color.RED);
dp.setDatasetIndex(1);
dpup.addLayer(dp);
upSpeedText = new DialTextAnnotation("0%");
upSpeedText.setFont(upSpeedText.getFont().deriveFont(12));
upSpeedText.setFont(UIEnv.getFont().deriveFont(16.0f));
dpup.addLayer(upSpeedText);
JFreeChart jfup= new JFreeChart(dpup);
jfup.setBorderPaint(Color.WHITE);
jfup.setTitle("Upload speed");
jfup.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f));
jfup.getTitle().setPosition(RectangleEdge.BOTTOM);
dpup.setView(0, 0, 1, 1);
ChartPanel cpup=new ChartPanel(jfup);
@@ -195,7 +210,7 @@ public class KLALBStateGUI2 extends XFrame {
cpup.setSize(cpup.getPreferredSize());
cpup.setBackground(Color.WHITE);
cpup.setBorder(new LineBorder(Color.LIGHT_GRAY));
dashboard.add(cpup);
dashs.add(cpup);
@@ -203,8 +218,10 @@ public class KLALBStateGUI2 extends XFrame {
downSpeed = new DefaultValueDataset(0);
downDataSpeed=new DefaultValueDataset(0);
DialPlot dpup1=new DialPlot();
dpup1.setDataset(downSpeed);
dpup1.setDataset(1,downSpeed);
dpup1.setDataset(0,downDataSpeed);
StandardDialFrame sdfs1=new StandardDialFrame();
sdfs1.setVisible(false);
dpup1.setDialFrame(sdfs1);
@@ -228,19 +245,29 @@ public class KLALBStateGUI2 extends XFrame {
sdrr31.setOuterRadius(0.83);
dpup1.addLayer(sdrr31);
DialPointer.Pointer dp11=new DialPointer.Pointer();
dp11.setRadius(0.7);
dp11.setFillPaint(new Color(0,127,0,0));
dp11.setOutlinePaint(new Color(0,127,0));
dp11.setDatasetIndex(0);
dpup1.addLayer(dp11);
DialPointer.Pointer dp1=new DialPointer.Pointer();
dp1.setRadius(0.7);
dp1.setFillPaint(Color.GREEN);
dp1.setOutlinePaint(Color.GREEN);
dp1.setDatasetIndex(1);
dpup1.addLayer(dp1);
downSpeedText = new DialTextAnnotation("0%");
downSpeedText.setFont(downSpeedText.getFont().deriveFont(12));
downSpeedText.setFont(UIEnv.getFont().deriveFont(16.0f));
dpup1.addLayer(downSpeedText);
JFreeChart jfup1= new JFreeChart(dpup1);
jfup1.setBorderPaint(Color.WHITE);
jfup1.setTitle("Download speed");
jfup1.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f));
jfup1.getTitle().setPosition(RectangleEdge.BOTTOM);
dpup1.setView(0, 0, 1, 1);
ChartPanel cpup1=new ChartPanel(jfup1);
@@ -248,15 +275,140 @@ public class KLALBStateGUI2 extends XFrame {
cpup1.setSize(cpup1.getPreferredSize());
cpup1.setBackground(Color.WHITE);
cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY));
dashboard.add(cpup1);
dashs.add(cpup1);
}
{
upPPS = new DefaultValueDataset(0);
upDataPPS=new DefaultValueDataset(0);
DialPlot dpup=new DialPlot();
dpup.setDataset(1,upPPS);
dpup.setDataset(0,upDataPPS);
StandardDialFrame sdfs=new StandardDialFrame();
sdfs.setVisible(false);
dpup.setDialFrame(sdfs);
StandardDialScale sds=new StandardDialScale(0, 100, -120, -300, 10, 5);
sds.setTickRadius(0.8);
sds.setTickLabelsVisible(false);
dpup.addScale(0, sds);
StandardDialRange sdrr=new StandardDialRange(0, 70,Color.GREEN);
sdrr.setInnerRadius(0.82);
sdrr.setOuterRadius(0.83);
dpup.addLayer(sdrr);
StandardDialRange sdrr2=new StandardDialRange(70, 90,Color.YELLOW);
sdrr2.setInnerRadius(0.82);
sdrr2.setOuterRadius(0.83);
dpup.addLayer(sdrr2);
StandardDialRange sdrr3=new StandardDialRange(90, 100,Color.RED);
sdrr3.setInnerRadius(0.82);
sdrr3.setOuterRadius(0.83);
dpup.addLayer(sdrr3);
DialPointer.Pointer dp1=new DialPointer.Pointer();
dp1.setRadius(0.7);
dp1.setFillPaint(new Color(127,0,0,0));
dp1.setOutlinePaint(new Color(127,0,0));
dp1.setDatasetIndex(0);
dpup.addLayer(dp1);
DialPointer.Pointer dp=new DialPointer.Pointer();
dp.setRadius(0.7);
dp.setFillPaint(Color.RED);
dp.setOutlinePaint(Color.RED);
dp.setDatasetIndex(1);
dpup.addLayer(dp);
upPPSText = new DialTextAnnotation("0PPS");
upPPSText.setFont(UIEnv.getFont().deriveFont(16.0f));
dpup.addLayer(upPPSText);
JFreeChart jfup= new JFreeChart(dpup);
jfup.setBorderPaint(Color.WHITE);
jfup.setTitle("Upload PPS");
jfup.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f));
jfup.getTitle().setPosition(RectangleEdge.BOTTOM);
dpup.setView(0, 0, 1, 1);
ChartPanel cpup=new ChartPanel(jfup);
cpup.setPreferredSize(new Dimension(150, 165));
cpup.setSize(cpup.getPreferredSize());
cpup.setBackground(Color.WHITE);
cpup.setBorder(new LineBorder(Color.LIGHT_GRAY));
dashs.add(cpup);
downPPS = new DefaultValueDataset(0);
downDataPPS=new DefaultValueDataset(0);
DialPlot dpup1=new DialPlot();
dpup1.setDataset(1,downPPS);
dpup1.setDataset(0,downDataPPS);
StandardDialFrame sdfs1=new StandardDialFrame();
sdfs1.setVisible(false);
dpup1.setDialFrame(sdfs1);
StandardDialScale sds1=new StandardDialScale(0, 100, -120, -300, 10, 5);
sds1.setTickRadius(0.8);
sds1.setTickLabelsVisible(false);
dpup1.addScale(0, sds1);
StandardDialRange sdrr1=new StandardDialRange(0, 70,Color.GREEN);
sdrr1.setInnerRadius(0.82);
sdrr1.setOuterRadius(0.83);
dpup1.addLayer(sdrr1);
StandardDialRange sdrr21=new StandardDialRange(70, 90,Color.YELLOW);
sdrr21.setInnerRadius(0.82);
sdrr21.setOuterRadius(0.83);
dpup1.addLayer(sdrr21);
StandardDialRange sdrr31=new StandardDialRange(90, 100,Color.RED);
sdrr31.setInnerRadius(0.82);
sdrr31.setOuterRadius(0.83);
dpup1.addLayer(sdrr31);
DialPointer.Pointer dp111=new DialPointer.Pointer();
dp111.setRadius(0.7);
dp111.setFillPaint(new Color(0,127,0,0));
dp111.setOutlinePaint(new Color(0,127,0));
dp111.setDatasetIndex(0);
dpup1.addLayer(dp111);
DialPointer.Pointer dp11=new DialPointer.Pointer();
dp11.setRadius(0.7);
dp11.setFillPaint(Color.GREEN);
dp11.setOutlinePaint(Color.GREEN);
dp11.setDatasetIndex(1);
dpup1.addLayer(dp11);
downPPSText = new DialTextAnnotation("0PPS");
downPPSText.setFont(UIEnv.getFont().deriveFont(16.0f));
dpup1.addLayer(downPPSText);
JFreeChart jfup1= new JFreeChart(dpup1);
jfup1.setBorderPaint(Color.WHITE);
jfup1.setTitle("Download PPS");
jfup1.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f));
jfup1.getTitle().setPosition(RectangleEdge.BOTTOM);
dpup1.setView(0, 0, 1, 1);
ChartPanel cpup1=new ChartPanel(jfup1);
cpup1.setPreferredSize(new Dimension(150, 165));
cpup1.setSize(cpup1.getPreferredSize());
cpup1.setBackground(Color.WHITE);
cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY));
dashs.add(cpup1);
}
/*{
upEfficiency = new DefaultValueDataset(0);
DialPlot dpup=new DialPlot();
dpup.setDataset(upEfficiency);
@@ -290,12 +442,13 @@ public class KLALBStateGUI2 extends XFrame {
dpup.addLayer(dp);
upEfficiencyText = new DialTextAnnotation("0%");
upEfficiencyText.setFont(upEfficiencyText.getFont().deriveFont(12));
upEfficiencyText.setFont(UIEnv.getFont().deriveFont(16.0f));
dpup.addLayer(upEfficiencyText);
JFreeChart jfup= new JFreeChart(dpup);
jfup.setBorderPaint(Color.WHITE);
jfup.setTitle("Upload bandwidth efficiency");
jfup.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f));
jfup.getTitle().setPosition(RectangleEdge.BOTTOM);
dpup.setView(0, 0, 1, 1);
ChartPanel cpup=new ChartPanel(jfup);
@@ -303,7 +456,7 @@ public class KLALBStateGUI2 extends XFrame {
cpup.setSize(cpup.getPreferredSize());
cpup.setBackground(Color.WHITE);
cpup.setBorder(new LineBorder(Color.LIGHT_GRAY));
dashboard.add(cpup);
dashs.add(cpup);
@@ -343,12 +496,13 @@ public class KLALBStateGUI2 extends XFrame {
dpup1.addLayer(dp1);
downEfficiencyText = new DialTextAnnotation("0%");
downEfficiencyText.setFont(downEfficiencyText.getFont().deriveFont(12));
downEfficiencyText.setFont(UIEnv.getFont().deriveFont(16.0f));
dpup1.addLayer(downEfficiencyText);
JFreeChart jfup1= new JFreeChart(dpup1);
jfup1.setBorderPaint(Color.WHITE);
jfup1.setTitle("Download bandwidth efficiency");
jfup1.getTitle().setFont(UIEnv.getFont().deriveFont(20.0f));
jfup1.getTitle().setPosition(RectangleEdge.BOTTOM);
dpup1.setView(0, 0, 1, 1);
ChartPanel cpup1=new ChartPanel(jfup1);
@@ -356,13 +510,68 @@ public class KLALBStateGUI2 extends XFrame {
cpup1.setSize(cpup1.getPreferredSize());
cpup1.setBackground(Color.WHITE);
cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY));
dashboard.add(cpup1);
}
dashs.add(cpup1);
}*/
JLabel ashboard = new JLabel("Dashboard");
ashboard.setFont(new Font("宋体", Font.PLAIN, 18));
ashboard.setFont(UIEnv.getFont().deriveFont(20.0f));
ashboard.setHorizontalAlignment(SwingConstants.CENTER);
overview.add(ashboard, BorderLayout.NORTH);
dashboard.add(ashboard, BorderLayout.NORTH);
JPanel panelp = new JPanel();
panelp.setOpaque(false);
JPanel panel = new JPanel();
panel.setOpaque(false);
panel.setBorder(new LineBorder(Color.GRAY));
overview.add(panelp, BorderLayout.SOUTH);
panelp.setLayout(new GridLayout(0, 1, 0, 0));
JPanel panel_2x = new JPanel();
panel_2x.setOpaque(false);
JPanel panel_2 = new JPanel();
panel_2.setOpaque(false);
panelp.add(panel_2x);
panel_2x.setLayout(new GridLayout(2, 1, 0, 0));
JLabel lblNewLabel = new JLabel("IPv6 addresss");
lblNewLabel.setFont(UIEnv.getFont().deriveFont(20.0f));
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel_2x.add(lblNewLabel);
panel_2x.add(panel_2);
panel_2.setLayout(new BorderLayout(0, 0));
addressField = new JTextField();
addressField.setHorizontalAlignment(SwingConstants.CENTER);
addressField.setOpaque(false);
panel_2.add(addressField);
addressField.setColumns(10);
addressField.setFont(UIEnv.getFont().deriveFont(20.0f));
JButton btnNewButton_1 = new JButton("Copy");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(addressField.getText()), null);
}
});
panel_2.add(btnNewButton_1, BorderLayout.EAST);
panelp.add(panel);
panel.setLayout(new GridLayout(2, 2, 0, 0));
JLabel jlb = new JLabel("Devices Online");
jlb.setHorizontalAlignment(SwingConstants.CENTER);
jlb.setFont(UIEnv.getFont().deriveFont(20.0f));
panel.add(jlb);
devicesOnline = new JTextField();
devicesOnline.setOpaque(false);
devicesOnline.setHorizontalAlignment(SwingConstants.CENTER);
devicesOnline.setFont(UIEnv.getFont().deriveFont(20.0f));
devicesOnline.setEditable(false);
panel.add(devicesOnline);
devicesOnline.setColumns(10);
@@ -370,14 +579,16 @@ public class KLALBStateGUI2 extends XFrame {
JPanel linesPanel=new JPanel();
linesPanel.setOpaque(false);
tabbedPane.add(linesPanel);
tabbedPane.setTitleAt(1, "Remote lines");
linesPanel.setLayout(new BorderLayout());
ysp = new YScrollPane(730);
ysp.setOpaque(false);
tabbedPane.add(ysp);
tabbedPane.setTitleAt(1, "Remote lines");
JPanel wv = ysp.getView();
linesPanel.add(ysp,BorderLayout.CENTER);
JMenuBar menuBar = new JMenuBar();
getContentPane().add(menuBar, BorderLayout.NORTH);
@@ -481,10 +692,9 @@ public class KLALBStateGUI2 extends XFrame {
setLocationRelativeTo(null);
//setVisible(true);
if (SystemTray.isSupported()) {
st = SystemTray.getSystemTray();
ti = new TrayIcon(bi);
ti = new TrayIcon(UIEnv.getIcon());
ti.setImageAutoSize(true);
PopupMenu jpm = new PopupMenu();
MenuItem mix = new MenuItem("open");
@@ -518,9 +728,73 @@ public class KLALBStateGUI2 extends XFrame {
//repaint();
t3 = new Timer("监视器刷新线程",true);
t2 = new Timer("仪表盘刷新线程",true);
t = new Timer("状态刷新线程",true);
createRefreshTask(kc, ysp);
JPanel panel_1 = new JPanel();
panel_1.setOpaque(false);
linesPanel.add(panel_1, BorderLayout.NORTH);
panel_1.setLayout(new BorderLayout(0, 0));
textField = new JTextField();
panel_1.add(textField);
textField.setColumns(10);
textField.setToolTipText("Line address:port");
JButton btnNewButton = new JButton("Add line");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
kc.addRemoteLines(new MultipurposeSocketAddress(textField.getText()));
}catch(RuntimeException ex) {
JOptionPane.showMessageDialog(KLALBStateGUI2.this, "Input format error", "Error", JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
});
panel_1.add(btnNewButton, BorderLayout.EAST);
JButton btnReconnect = new JButton("ReconnectAll");
btnReconnect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
kc.reconnectImmediately();
}
});
panel_1.add(btnReconnect, BorderLayout.WEST);
JPanel panel_3 = new JPanel();
panel_3.setBackground(new Color(255, 255, 255));
tabbedPane.addTab("Network graph", null, panel_3, null);
panel_3.setLayout(new BorderLayout(0, 0));
JPanel panel_4 = new JPanel();
panel_3.add(panel_4, BorderLayout.NORTH);
graph = new NetworkGraphPanel(kc.getIpv6Router().getKlalbRouteProtol());
graph.setOpaque(false);
JScrollPane jsp=new JScrollPane(graph);
panel_3.add(jsp, BorderLayout.CENTER);
textField.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
// TODO 自动生成的方法存根
if(e.getKeyCode()==KeyEvent.VK_ENTER) {
btnNewButton.doClick();
}
}
});
}
private void createRefreshTask(KLALBController kc, YScrollPane ysp) {
if(tsk!=null) {
@@ -548,7 +822,7 @@ public class KLALBStateGUI2 extends XFrame {
}
}
}
TPanel2 tp=new TPanel2(ent);
TPanel2 tp=new TPanel2(ent,kc);
tp.setVisible(showoffline.isSelected()||ent.getMonitor().getState()==MonitorData.ONLINE);
ysp.getView().add(tp);
}
@@ -563,6 +837,7 @@ public class KLALBStateGUI2 extends XFrame {
}*/
if(kc.getLines().contains(((TPanel2) tp).getTunnel())) {
try {
if(tp.isVisible())
((TPanel2) tp).updateTraffic();
}catch(RuntimeException e) {
e.printStackTrace();
@@ -576,7 +851,7 @@ public class KLALBStateGUI2 extends XFrame {
//repaint();
}
};
t.scheduleAtFixedRate(tsk, 200, 100);
t.scheduleAtFixedRate(tsk, 200, 500);
if(tsk2!=null) {
tsk2.cancel();
}
@@ -584,13 +859,53 @@ public class KLALBStateGUI2 extends XFrame {
@Override
public void run() {
double outload=kc.getLinkMonitor().getOutSpeed()*100.0/kc.getLinkMonitor().getOutSpeedMax2();
if(Double.isFinite(outload)) {
upSpeedText.setLabel(KLALBUtils.bytesUnit(kc.getLinkMonitor().getOutSpeedAvg())+"/s");
upSpeed.setValue(upSpeed.getValue().doubleValue()*0.95+kc.getLinkMonitor().getOutSpeed()*100.0/(50*1024*1024)*0.05);
downSpeedText.setLabel(KLALBUtils.bytesUnit(kc.getLinkMonitor().getInSpeedAvg())+"/s");
downSpeed.setValue(downSpeed.getValue().doubleValue()*0.95+kc.getLinkMonitor().getInSpeed()*100.0/(50*1024*1024)*0.05);
upSpeed.setValue(Math.min(upSpeed.getValue().doubleValue()*0.98+outload*0.02,101.0));
}
double outefi=kc.getDatatMonitor().getOutSpeedAvg2()*100.0D/kc.getLinkMonitor().getOutSpeedAvg2();
double inload=kc.getLinkMonitor().getInSpeed()*100.0/kc.getLinkMonitor().getInSpeedMax2();
if(Double.isFinite(inload)) {
downSpeedText.setLabel(KLALBUtils.bytesUnit(kc.getLinkMonitor().getInSpeedAvg())+"/s");
downSpeed.setValue(Math.min(downSpeed.getValue().doubleValue()*0.98+inload*0.02,101.0));
}
double outPPSload=kc.getLinkMonitor().getOutPPS()*100.0/kc.getLinkMonitor().getOutPPSMax2();
if(Double.isFinite(outPPSload)) {
upPPSText.setLabel(KLALBUtils.defaultUnit(kc.getLinkMonitor().getOutPPSAvg())+"PPS");
upPPS.setValue(Math.min(upPPS.getValue().doubleValue()*0.98+outPPSload*0.02,101.0));
}
double inPPSload=kc.getLinkMonitor().getInPPS()*100.0/kc.getLinkMonitor().getInPPSMax2();
if(Double.isFinite(inPPSload)) {
downPPSText.setLabel(KLALBUtils.defaultUnit(kc.getLinkMonitor().getInPPSAvg())+"PPS");
downPPS.setValue(Math.min(downPPS.getValue().doubleValue()*0.98+inPPSload*0.02,101.0));
}
double outload1=kc.getDatatMonitor().getOutSpeed()*100.0/kc.getLinkMonitor().getOutSpeedMax2();
if(Double.isFinite(outload1)) {
upDataSpeed.setValue(Math.min(upDataSpeed.getValue().doubleValue()*0.98+outload1*0.02,101.0));
}
double inload1=kc.getDatatMonitor().getInSpeed()*100.0/kc.getLinkMonitor().getInSpeedMax2();
if(Double.isFinite(inload1)) {
downDataSpeed.setValue(Math.min(downDataSpeed.getValue().doubleValue()*0.98+inload1*0.02,101.0));
}
double outPPSload1=kc.getDatatMonitor().getOutPPS()*100.0/kc.getLinkMonitor().getOutPPSMax2();
if(Double.isFinite(outPPSload1)) {
upDataPPS.setValue(Math.min(upDataPPS.getValue().doubleValue()*0.98+outPPSload1*0.02,101.0));
}
double inPPSload1=kc.getDatatMonitor().getInPPS()*100.0/kc.getLinkMonitor().getInPPSMax2();
if(Double.isFinite(inPPSload1)) {
downDataPPS.setValue(Math.min(downDataPPS.getValue().doubleValue()*0.98+inPPSload1*0.02,101.0));
}
/*double outefi=kc.getDatatMonitor().getOutSpeedAvg2()*100.0D/kc.getLinkMonitor().getOutSpeedAvg2();
if(Double.isFinite(outefi)) {
upEfficiency.setValue(upEfficiency.getValue().doubleValue()*0.95+ outefi*0.05);
upEfficiencyText.setLabel(String.format("%.1f", upEfficiency.getValue().doubleValue())+"%");
@@ -600,6 +915,14 @@ public class KLALBStateGUI2 extends XFrame {
if(Double.isFinite(inefi)) {
downEfficiency.setValue(downEfficiency.getValue().doubleValue()*0.95+ inefi*0.05);
downEfficiencyText.setLabel(String.format("%.1f", downEfficiency.getValue().doubleValue())+"%");
}*/
String contt=Long.toString( kc.getIpv6Router().getKlalbRouteProtol().getDevicesFound());
if(!contt.equals(devicesOnline.getText())) {
devicesOnline.setText(contt);
}
String address=kc.getSelf().getHostAddress();
if(!address.equals(addressField.getText())) {
addressField.setText(address);
}
}
};
@@ -625,7 +948,42 @@ public class KLALBStateGUI2 extends XFrame {
}
}
};
t.scheduleAtFixedRate(tsk3, 200, 20);
t3.scheduleAtFixedRate(tsk3, 200, 200);
if(tsk4!=null) {
tsk4.cancel();
}
tsk4=new TimerTask() {
@Override
public void run() {
Component[] count=ysp.getView().getComponents();
for (int i = 0; i < count.length; i++) {
Component tp=count[i];
if(tp instanceof TPanel2) {
try {
((TPanel2) tp).getMdg().recordData();
}catch(RuntimeException e) {
e.printStackTrace();
}
}
}
}
};
t3.scheduleAtFixedRate(tsk4, 200, 10);
if(tsk5!=null) {
tsk5.cancel();
}
tsk5=new TimerTask() {
@Override
public void run() {
if(graph.isVisible())
graph.repaint();
}
};
t.scheduleAtFixedRate(tsk5, 200, 2000);
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void close() {
@@ -1,4 +1,4 @@
package org.kne.cloud.network.klalb;
package org.kne.cloud.network.klalb.ui;
import java.awt.Color;
import java.awt.Dimension;
@@ -16,12 +16,15 @@ import javax.swing.border.LineBorder;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.TimePeriod;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.ui.XFrame;
@@ -44,8 +47,8 @@ public class LineMonitorGUI extends XFrame{
private TimeSeries delayup=new TimeSeries("Upload delay");
private TimeSeries delaydown=new TimeSeries("Download delay");
private TimeSeries delayupmin=new TimeSeries("Upload delay minimum");
private TimeSeries delaydownmin=new TimeSeries("Download delay minimum");
//private TimeSeries delayupmin=new TimeSeries("Upload delay minimum");
//private TimeSeries delaydownmin=new TimeSeries("Download delay minimum");
private KLALBRemoteLine tr;
private JTextField vaddrs;
@@ -60,12 +63,11 @@ public class LineMonitorGUI extends XFrame{
setSize(700, 700);
setLocationRelativeTo(null);
Image bi=KLALBStateGUI2.getKLALBIcon();
if(bi!=null)
setIconImage(bi);
setIconImage(UIEnv.getIcon());
setTitle("Line Monitor:"+t.getMonitor().getName());
setTitleColor(new Color(255, 255, 255, 250));
//getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f));
setTitleColor(UIEnv.getDefaultTitleColor());
getContentPane().setBackground(UIEnv.getDefaultBackgroundColor());
getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f));
getTitlepanel().setBorder(new LineBorder(Color.LIGHT_GRAY));
JPanel jp=new JPanel();
@@ -80,6 +82,7 @@ public class LineMonitorGUI extends XFrame{
jfc.getXYPlot().setBackgroundPaint(Color.BLACK);
jfc.getXYPlot().getRenderer().setSeriesPaint(0,Color.RED);
jfc.getXYPlot().getRenderer().setSeriesPaint(1,Color.GREEN);
changeFont(jfc);
spdp = new JLabel();
spdp.setBorder(new LineBorder(Color.DARK_GRAY));
jp.add(spdp);
@@ -88,8 +91,8 @@ public class LineMonitorGUI extends XFrame{
tsce.addSeries(delayup);
tsce.addSeries(delaydown);
tsce.addSeries(delayupmin);
tsce.addSeries(delaydownmin);
//tsce.addSeries(delayupmin);
//tsce.addSeries(delaydownmin);
jfce = ChartFactory.createTimeSeriesChart("Delay monitor", "Time(s)", "Delay(ms)", tsce);
jfce.getXYPlot().getDomainAxis().setFixedAutoRange(5000);
jfce.getXYPlot().setBackgroundPaint(Color.BLACK);
@@ -97,10 +100,11 @@ public class LineMonitorGUI extends XFrame{
jfce.getXYPlot().getRenderer().setSeriesPaint(1,Color.GREEN);
BasicStroke dotted = new BasicStroke(2, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 0, new float[]{0,6,0,6}, 0);
jfce.getXYPlot().getRenderer().setSeriesPaint(2,Color.RED);
/*jfce.getXYPlot().getRenderer().setSeriesPaint(2,Color.RED);
jfce.getXYPlot().getRenderer().setSeriesStroke(2, dotted);
jfce.getXYPlot().getRenderer().setSeriesPaint(3,Color.GREEN);
jfce.getXYPlot().getRenderer().setSeriesStroke(3, dotted);
jfce.getXYPlot().getRenderer().setSeriesStroke(3, dotted);*/
changeFont(jfce);
delp = new JLabel();
delp.setBorder(new LineBorder(Color.DARK_GRAY));
jp.add(delp);
@@ -118,6 +122,7 @@ public class LineMonitorGUI extends XFrame{
vaddrs.setColumns(10);
JPanel panel_1 = new JPanel();
panel_1.setOpaque(false);
panel.add(panel_1);
Dimension dms=new Dimension(140, 20);
JButton btnNewButton = new JButton("Force disconnect");
@@ -140,7 +145,7 @@ public class LineMonitorGUI extends XFrame{
btnNewButton_1.setForeground(Color.GREEN);
panel_1.add(btnNewButton_1);
JButton btnNewButton_2 = new JButton("Pressure test");
/*JButton btnNewButton_2 = new JButton("Pressure test");
btnNewButton_2.setPreferredSize(dms);
btnNewButton_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@@ -148,7 +153,15 @@ public class LineMonitorGUI extends XFrame{
}
});
panel_1.add(btnNewButton_2);
btnNewButton_2.setForeground(Color.BLUE);
btnNewButton_2.setForeground(Color.BLUE);*/
}
private void changeFont(JFreeChart jfc2) {
jfc2.getTitle().setFont(UIEnv.getFont().deriveFont(16.0f));
jfc2.getLegend().setItemFont(UIEnv.getFont());
jfc2.getXYPlot().getRangeAxis().setLabelFont(UIEnv.getFont());
jfc2.getXYPlot().getRangeAxis().setTickLabelFont(UIEnv.getFont());
jfc2.getXYPlot().getDomainAxis().setLabelFont(UIEnv.getFont());
jfc2.getXYPlot().getDomainAxis().setTickLabelFont(UIEnv.getFont());
}
public void recordData() {
if(isVisible()) {
@@ -157,13 +170,13 @@ public class LineMonitorGUI extends XFrame{
spddown.addOrUpdate(ms, tr.getMonitor().getInSpeed()/1024.0);
Millisecond msu= new Millisecond(new Date(System.currentTimeMillis()-(System.nanoTime()- tr.getMonitor().getRecentPingNanoTime())/1000000L));
delayup.addOrUpdate(msu, tr.getMonitor().getOutDelay()/1000000.0);
delaydown.addOrUpdate(msu, tr.getMonitor().getInDelay()/1000000.0);
//Millisecond msu= new Millisecond(new Date(System.currentTimeMillis()-(System.nanoTime()- tr.getMonitor().getRecentPingNanoTime())/1000000L));
delayup.addOrUpdate(ms, (tr.getMonitor().getOutDelay()+tr.getMonitor().getQueueingDelay())/1000000.0);
delaydown.addOrUpdate(ms, tr.getMonitor().getInDelay()/1000000.0);
//Millisecond msup= new Millisecond(new Date( tr.getMonitor().getUpdateDelayTime()+tr.getMonitor().getOutDelay()/1000000L));
delayupmin.addOrUpdate(ms, tr.getMonitor().getOutDelayPredicted()/1000000.0);
delaydownmin.addOrUpdate(ms, tr.getMonitor().getInDelayPredicted()/1000000.0);
//delayupmin.addOrUpdate(ms, tr.getMonitor().getQueueingDelay()/1000000.0);
//delaydownmin.addOrUpdate(ms, tr.getMonitor().getInDelayPredicted()/1000000.0);
}
}
@@ -178,26 +191,33 @@ public class LineMonitorGUI extends XFrame{
case MonitorData.ONLINE:
getTitlelabel().setForeground(Color.GREEN);
recordData();
break;
default:
break;
}
if(isVisible()) {
//long ax=System.nanoTime();
ImageIcon i1=new ImageIcon(jfc.createBufferedImage(spdp.getWidth(), spdp.getHeight()));
ImageIcon i2=new ImageIcon(jfce.createBufferedImage(delp.getWidth(), delp.getHeight()));
//System.out.println(System.nanoTime()-ax);
spdp.setIcon(i1);
delp.setIcon(i2);
//spddown.fireSeriesChanged();
//delaydown.fireSeriesChanged();
Inet6Address i6a= tr.getRemoteVaddr();
if(i6a==null) {
vaddrs.setText("unknown");
Inet6AddressGroup irg=tr.getRemoteVaddr();
String text;
if(irg==null) {
text="unknown";
}else {
vaddrs.setText(i6a.getHostAddress());
Inet6Address i6a= irg.getAddress();
text=i6a.getHostAddress();
}
if(!vaddrs.getText().equals(text)) {
vaddrs.setText(text);
}
}
@@ -0,0 +1,298 @@
package org.kne.cloud.network.klalb.ui;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Dimension2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.image.ImageObserver;
import java.net.Inet6Address;
import java.text.AttributedCharacterIterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JPanel;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection;
public class NetworkGraphPanel extends JPanel {
private KLALBRoutingProtocol routingProtocol;
private Map<Inet6Address,GraphNode> nodes=new HashMap<Inet6Address,GraphNode>();
private List<GraphEdgeGroup> edgeGroups=new ArrayList<GraphEdgeGroup>();
private static final int nodesize=80;
private class GraphNode{
private String text;
private Color color;
private int x;
private int y;
public GraphNode(String text, Color color, int x, int y) {
super();
this.text = text;
this.color = color;
this.x = x;
this.y = y;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public GraphNode() {
super();
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void paint(Graphics2D g) {
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(2.0f));
g.drawOval(x-nodesize/2, y-nodesize/2, nodesize, nodesize);
g.setFont(UIEnv.getFont().deriveFont(10.0f));
g.drawString(text, x+nodesize/2, y-nodesize/3);
}
}
private class GraphEdge{
private GraphNode from;
private GraphNode to;
private LinkDirection linkPath;
public GraphEdge(GraphNode nfrom, GraphNode nto,LinkDirection lp) {
this.from=nfrom;
this.to=nto;
this.linkPath=lp;
}
}
private class GraphEdgeGroup{
private static final double gap=3;
private GraphNode nodeA,nodeB;
private List<GraphEdge> edges=new ArrayList<>();
private boolean match(GraphNode a,GraphNode b) {
if(a.equals( nodeA)&&b.equals( nodeB))
return true;
if(b.equals( nodeA)&&a.equals( nodeB))
return true;
return false;
}
public GraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
super();
this.nodeA = nodeA;
this.nodeB = nodeB;
}
public List<GraphEdge> getPaths() {
return edges;
}
public void paint(Graphics2D g) {
g.setStroke(new BasicStroke(1.0f));
Vector2 nodeAv=new Vector2(nodeA.getX(), nodeA.getY());
Vector2 nodeBv=new Vector2(nodeB.getX(), nodeB.getY());
Vector2 vecDir=nodeBv.subtract(nodeAv);
Vector2 vecDirnor=vecDir.normalize();
Vector2 vecR=vecDirnor.multi(nodesize/2);
Vector2 vec90nor=new Vector2( -vecDir.y, vecDir.x).normalize();
double width=gap*(edges.size()-1);
Vector2 startPoint=nodeAv.add(vecR).add(vec90nor.multi(width/2));
Vector2 endPoint=nodeBv.subtract(vecR).add(vec90nor.multi(width/2));
//System.out.println(width);
for (Iterator<GraphEdge> iterator = edges.iterator(); iterator.hasNext();) {
GraphEdge graphEdge = (GraphEdge) iterator.next();
//System.out.println(vec90nor);
g.setColor(KLALBUtils.getColorByLoadPercentage(graphEdge.linkPath.getSpeed()*100f/graphEdge.linkPath.getBandwidth()));
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) )
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) )
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
startPoint=startPoint.subtract(vec90nor.multi(gap));
endPoint=endPoint.subtract(vec90nor.multi(gap));
}
//g.drawLine(nodeA.getX(), nodeA.getY(), nodeB.getX(), nodeB.getY());
}
public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2)
{
double H = 5; // 箭头高度
double L = 2; // 底边的一半
int x3 = 0;
int y3 = 0;
int x4 = 0;
int y4 = 0;
double awrad = Math.atan(L / H); // 箭头角度
double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
double y_3 = ey - arrXY_1[1];
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
double y_4 = ey - arrXY_2[1];
Double X3 = new Double(x_3);
x3 = X3.intValue();
Double Y3 = new Double(y_3);
y3 = Y3.intValue();
Double X4 = new Double(x_4);
x4 = X4.intValue();
Double Y4 = new Double(y_4);
y4 = Y4.intValue();
// 画线
g2.drawLine(sx, sy, ex, ey);
//
GeneralPath triangle = new GeneralPath();
triangle.moveTo(ex, ey);
triangle.lineTo(x3, y3);
triangle.lineTo(x4, y4);
triangle.closePath();
//实心箭头
g2.fill(triangle);
//非实心箭头
//g2.draw(triangle);
}
// 计算
public static double[] rotateVec(int px, int py, double ang,
boolean isChLen, double newLen) {
double mathstr[] = new double[2];
// 矢量旋转函数参数含义分别是x分量y分量旋转角是否改变长度新长度
double vx = px * Math.cos(ang) - py * Math.sin(ang);
double vy = px * Math.sin(ang) + py * Math.cos(ang);
if (isChLen) {
double d = Math.sqrt(vx * vx + vy * vy);
vx = vx / d * newLen;
vy = vy / d * newLen;
mathstr[0] = vx;
mathstr[1] = vy;
}
return mathstr;
}
}
public NetworkGraphPanel(KLALBRoutingProtocol routingProtocol) {
super();
this.routingProtocol = routingProtocol;
//setSize(10000, 10000);
//setPreferredSize(getSize());
}
@Override
public void paint(Graphics g) {
super.paint(g);
loadNodes();
Graphics2D g2d=(Graphics2D)g;
for (Iterator<GraphEdgeGroup> iterator = edgeGroups.iterator(); iterator.hasNext();) {
GraphEdgeGroup graphNode = (GraphEdgeGroup) iterator.next();
graphNode.paint(g2d);
}
for (Iterator<GraphNode> iterator = nodes.values().iterator(); iterator.hasNext();) {
GraphNode graphNode = (GraphNode) iterator.next();
graphNode.paint(g2d);
}
}
Random r=new Random();
private void loadNodes() {
Map<Inet6Address, Long> addr= routingProtocol.getAddresses();
Set<Inet6Address> ks=addr.keySet();
for (Iterator<Inet6Address> iterator = ks.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next();
if(!nodes.containsKey(inet6Address))
nodes.put(inet6Address,new GraphNode(inet6Address.getHostAddress(),Color.BLACK,r.nextInt(50,getWidth()-100),r.nextInt(50,getHeight()-50)));
}
Set<Inet6Address> kns=nodes.keySet();
for (Iterator<Inet6Address> iterator = kns.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next();
if(!addr.containsKey(inet6Address)) {
iterator.remove();
}
}
//System.out.println("------------------------------------");
edgeGroups.clear();
Map<Inet6Address, Set<LinkDirection>> addr1= routingProtocol.getPaths();
Set<Entry<Inet6Address, Set<LinkDirection>>> salink=addr1.entrySet();
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = salink.iterator(); iterator.hasNext();) {
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();
Set<LinkDirection>lps=entry.getValue();
for (Iterator<LinkDirection> iterator2 = lps.iterator(); iterator2.hasNext();) {
LinkDirection linkPath = (LinkDirection) iterator2.next();
//System.out.println(linkPath);
GraphNode nfrom=nodes.get(linkPath.getFromLocator());
GraphNode nto=nodes.get(linkPath.getToLocator());
GraphEdgeGroup group=getGroup(nfrom, nto);
group.getPaths().add(new GraphEdge(nfrom,nto,linkPath));
}
}
}
private GraphEdgeGroup getGroup(GraphNode a,GraphNode b) {
for (Iterator iterator = edgeGroups.iterator(); iterator.hasNext();) {
GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
if(graphEdgeGroup.match(a,b)) {
return graphEdgeGroup;
}
}
GraphEdgeGroup ng=new GraphEdgeGroup(a, b);
edgeGroups.add(ng);
return ng;
}
}
@@ -1,4 +1,4 @@
package org.kne.cloud.network.klalb;
package org.kne.cloud.network.klalb.ui;
import javax.swing.JPanel;
import javax.swing.JLabel;
@@ -8,6 +8,7 @@ import java.awt.Color;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.monitor.MonitorData;
import java.awt.Font;
@@ -1,4 +1,4 @@
package org.kne.cloud.network.klalb;
package org.kne.cloud.network.klalb.ui;
import javax.swing.JPanel;
import javax.swing.JLabel;
@@ -9,10 +9,15 @@ import java.awt.Dimension;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.monitor.MonitorData;
import java.awt.Font;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
@@ -66,7 +71,7 @@ public class TPanel2 extends JPanel {
/**
* @wbp.parser.constructor
*/
public TPanel2(KLALBRemoteLine t) {
public TPanel2(KLALBRemoteLine t,KLALBController kc) {
this.tunnel = t;
//setOpaque(false);
setBackground(Color.WHITE);
@@ -183,6 +188,19 @@ public class TPanel2 extends JPanel {
}
});
mntmNewMenuItem3 = new JMenuItem("Try reconnect");
popupMenu.add(mntmNewMenuItem3);
mntmNewMenuItem3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
tunnel.reconnectImmediately();
}
});
mntmNewMenuItem3.setForeground(Color.GREEN);
mntmNewMenuItem2 = new JMenuItem("Force disconnect");
popupMenu.add(mntmNewMenuItem2);
mntmNewMenuItem2.addActionListener(new ActionListener() {
@@ -194,17 +212,21 @@ public class TPanel2 extends JPanel {
});
mntmNewMenuItem2.setForeground(Color.RED);
mntmNewMenuItem3 = new JMenuItem("Force reconnect");
popupMenu.add(mntmNewMenuItem3);
mntmNewMenuItem3.addActionListener(new ActionListener() {
JMenuItem mi=new JMenuItem("Remove line");
popupMenu.add(mi);
mi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
tunnel.reconnectImmediately();
MultipurposeSocketAddress mtar=tunnel.getSocketAddress();
if(mtar!=null) {
kc.removeRemoteLines(mtar);
}else {
tunnel.close();
}
}
});
mntmNewMenuItem3.setForeground(Color.GREEN);
});
mi.setForeground(Color.RED);
mdg=new LineMonitorGUI(t);
addMouseListener(new MouseListener() {
@@ -282,10 +304,10 @@ public class TPanel2 extends JPanel {
private void updateText() {
targup.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getOutTraffic()) + "\u2191 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getOutSpeed()) + "/s\u2191 "+ String.format("%.1f", tunnel.getMonitor().getOutDelay()/1000000.0) + "ms");
targdown.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getInTraffic()) + "\u2193 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getInSpeed()) + "/s\u2193 " + String.format("%.1f", tunnel.getMonitor().getInDelay()/1000000.0) + "ms");
targup.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getOutTraffic()) + "\u2191 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getOutSpeedAvg()) + "/s\u2191 "+ String.format("%.1f", tunnel.getMonitor().getOutDelay()/1000000.0) + "ms");
targdown.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getInTraffic()) + "\u2193 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getInSpeedAvg()) + "/s\u2193 " + String.format("%.1f", tunnel.getMonitor().getInDelay()/1000000.0) + "ms");
if(tunnel.getMonitor().getOutSpeed()>2048||tunnel.getMonitor().getInSpeed()>2048) {
if(tunnel.getMonitor().getOutSpeed()>4096||tunnel.getMonitor().getInSpeed()>4096) {
lblNewLabel_2.setBackground(Color.ORANGE);
}else {
lblNewLabel_2.setBackground(Color.LIGHT_GRAY);
@@ -327,7 +349,7 @@ public class TPanel2 extends JPanel {
lblNewLabel_1.setBackground(Color.GREEN);
Inet6Address unvar=tunnel.getRemoteVaddr();
Inet6Address unvar=tunnel.getRemoteVaddr().getAddress();
if(unvar==null) {
this.vaddr.setText("unknown");
}else {
@@ -0,0 +1,144 @@
package org.kne.cloud.network.klalb.ui;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.ColorChooserUI;
public class UIEnv {
private static Font font;
private static Image icon ;
private static Color defaultcolor=new Color(207,218,223);//new Color(207,218,223)
private static Color selectedcolor=new Color(207/2,218/2,223/2);
private static ResourceBundle rsb;
public static void setRsb(String xrsb) throws IOException {
rsb=new PropertyResourceBundle(UIEnv.class.getResourceAsStream("/knemcl_"+xrsb+".properties"));
}
public static void setRsb(ResourceBundle xrsb) {
rsb=xrsb;
}
public static ResourceBundle getRsb() {
if(rsb==null) {
try {
rsb=new PropertyResourceBundle(UIEnv.class.getResourceAsStream("/knemcl_en_US.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
return rsb;
}
//private static Color tpccolor=new Color(250,250,250,190);
public static Color getDefaultcolor() {
return defaultcolor;
}
public static void setDefaultColor(Color defaultcolor) {
UIEnv.defaultcolor = defaultcolor;
}
public static Color titlecolor=new Color(0,0,100,200);
public static Color backgroundcolor=new Color(0,0,100,255);
public static Color getDefaultTitleColor() {
return titlecolor;
}
public static Color getDefaultBackgroundColor() {
return backgroundcolor;
}
public static Color getHalfTransparentDefaultColor() {
return new Color(defaultcolor.getRed(), defaultcolor.getGreen(), defaultcolor.getBlue(), 210);
}
public static void inituie(){
/*try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch
e.printStackTrace();
} catch (InstantiationException e) {
// TODO 自动生成的 catch
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO 自动生成的 catch
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}*/
font=new Font("微软雅黑",Font.PLAIN , 12);
/*try {
font = Font.createFont(Font.PLAIN, UIEnv.class.getResourceAsStream("/assets/SourceHanSansCN-Light.otf")).deriveFont(13f);
} catch (FontFormatException e1) {
e1.printStackTrace();
} catch (IOException e1) {
// TODO 自动生成的 catch
e1.printStackTrace();
}*/
java.util.Enumeration keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
Object value = UIManager.get(key);
if (value instanceof javax.swing.plaf.FontUIResource) {
UIManager.put(key, font);
}
}
icon=Toolkit.getDefaultToolkit().getImage(
UIEnv.class.getResource("/assets/KLALB.png"));
}
public static void defbut(JButton start) {
if(font==null)
inituie();
start.setBorderPainted(false);
start.setForeground(Color.WHITE);
start.setFont(font.deriveFont(Font.BOLD, 18));
start.setBackground(defaultcolor);
}
public static void defbut(JButton start,int fontsize) {
if(font==null)
inituie();
start.setBorderPainted(false);
start.setForeground(Color.WHITE);
start.setFont(font.deriveFont(Font.BOLD, fontsize));
start.setBackground(defaultcolor);
}
public static Font getFont(){
if(icon==null)
inituie();
return font;
}
public static Image getIcon(){
if(icon==null)
inituie();
return icon;
}
public static Color getSelectedcolor() {
return selectedcolor;
}
public static void setSelectedcolor(Color selectedcolor) {
UIEnv.selectedcolor = selectedcolor;
}
/*public static Color getHalfTransparentColor() {
return tpccolor;
}*/
}
@@ -0,0 +1,99 @@
package org.kne.cloud.network.klalb.ui;
public class Vector2 {
public double x,y;
public Vector2(double x, double y) {
super();
this.x = x;
this.y = y;
}
public Vector2 Set(double x, double y) {
this.x = x;
this.y = y;
return this;
}
public Vector2 normalize()//ʹΪ1Ϊλ
{
double l=Math.sqrt(x*x+y*y);
return l==0?new Vector2(0,0): new Vector2(x / l, y / l);
}
public Vector2 normalizeold()//ʹΪ1Ϊλ
{
double l=Math.sqrt(x*x+y*y);
if(l==0){
x=y=0;
}else{
this.x = x / l;
this.y = y / l;
}
return this;
}
public Vector2 add(Vector2 vec)//
{
return new Vector2(this.x + vec.x,this.y + vec.y);
}
public Vector2 subtract(Vector2 vec)//
{
return new Vector2(this.x - vec.x,this.y - vec.y);
}
public Vector2 multi(double m)//
{
return new Vector2(this.x*m, this.y*m);
}
public double dot(Vector2 vec)//
{
return vec.x*x + vec.y*y ;
}
public Vector2 opposite(){//
return new Vector2(-x, -y);
}
public Vector2 signs() {//
return new Vector2(signs(x),signs(y));
}
public static int signs(double z2) {
return z2>0?1:(z2<0?-1:0);
}
public Vector2 rotate(Vector2 degree){
double sita=sita()+degree.sita();
double l=Length();
return new Vector2(l*Math.cos(sita), l*Math.sin(sita));
}
public Vector2 rotate(float degree){
double sita=sita()+degree;
double l=Length();
return new Vector2(l*Math.cos(sita), l*Math.sin(sita));
}
public float sita() {
double sita;
if(x<0){
sita=Math.atan(y/x)-180;
}else if(x>0){
sita=Math.atan(y/x);
}else{
sita=y>=0?90:90-180;
}
return (float) sita;
}
public double Length() {
return Math.sqrt(x*x+y*y);
}
@Override
public String toString() {
return "Vector2 [x="+x+", y="+y+"]";
}
}
@@ -7,6 +7,7 @@ import java.util.function.BiConsumer;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.scanner.InetAddressRange;
import org.kne.cloud.network.scanner.PortRange;
import org.kne.cloud.network.scanner.ScanRange;
import org.kne.cloud.network.scanner.TCPNetworkScanner;
public class MinecraftScanner extends TCPNetworkScanner{
@@ -19,7 +20,7 @@ public class MinecraftScanner extends TCPNetworkScanner{
public void setMinecraftConsumer(BiConsumer<MultipurposeSocketAddress, MinecraftServerPinger> minecraftConsumer) {
this.minecraftConsumer = minecraftConsumer;
}
public MinecraftScanner() {
{
super.setConsumer((mpsa,s)->{
if(s!=null) {
try {
@@ -28,9 +29,13 @@ public class MinecraftScanner extends TCPNetworkScanner{
minecraftConsumer.accept(mpsa, msp);
}
} catch (UnknownHostException e) {
e.printStackTrace();
if(minecraftConsumer!=null) {
minecraftConsumer.accept(mpsa, null);
}
} catch (Exception e) {
e.printStackTrace();
if(minecraftConsumer!=null) {
minecraftConsumer.accept(mpsa, null);
}
}
}else {
if(minecraftConsumer!=null) {
@@ -39,35 +44,20 @@ public class MinecraftScanner extends TCPNetworkScanner{
}
});
}
public MinecraftScanner() {
}
public MinecraftScanner(int connectTimeout, int soTimeout) {
super(connectTimeout, soTimeout);
super.setConsumer((mpsa,s)->{
if(s!=null) {
try {
MinecraftServerPinger msp=new MinecraftServerPinger(mpsa,s);
if(minecraftConsumer!=null) {
minecraftConsumer.accept(mpsa, msp);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}else {
if(minecraftConsumer!=null) {
minecraftConsumer.accept(mpsa, null);
}
}
});
}
public static void main(String[] args) throws UnknownHostException {
MinecraftScanner tcn = new MinecraftScanner();
tcn.getPortRanges().add(new PortRange(25565));
tcn.getPortRanges().add(new PortRange(34000, 37000));
tcn.getAddressRanges().add(new InetAddressRange("192.168.0.1","192.168.0.255"));
tcn.getRanges().add(new ScanRange(new InetAddressRange("127.0.0.1","127.0.0.2"),new PortRange(25565,37000)));
tcn.setMinecraftConsumer((mpsa,mc)->{
if(mc!=null)
System.out.println(mc);
});
tcn.setProcessConsumer((f)->{//System.out.println(f);
@@ -3,8 +3,11 @@ package org.kne.cloud.network.minecraft;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.Externalizable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.StringReader;
@@ -37,7 +40,7 @@ public class MinecraftServerPinger implements Serializable{
private long latency=-1;
private String json;
private BufferedImage icon;
//private BufferedImage icon;
private int max;
private int online;
private String description;
@@ -47,6 +50,8 @@ public class MinecraftServerPinger implements Serializable{
private String klalbversion;
private Inet6Address klalbvaddr;
private int klalbvport;
private String icon;
private transient BufferedImage image;
public MinecraftServerPinger(MultipurposeSocketAddress target) throws UnknownHostException, IOException {
this(target,target.connectSocket());
@@ -146,12 +151,8 @@ public class MinecraftServerPinger implements Serializable{
if(favicon!=null) {
String s=favicon.getAsString();
if(s.startsWith("data:image/png;base64,")){
s=s.replace("\n", "");
try {
icon=ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(s.substring("data:image/png;base64,".length()))));
} catch (IOException e) {
e.printStackTrace();
}
icon=s.replace("\n", "");
}
}
/*try {
@@ -261,7 +262,15 @@ public class MinecraftServerPinger implements Serializable{
}
public BufferedImage getIcon() {
return icon;
if(icon==null)
return null;
if(image==null)
try {
image= ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(icon.substring("data:image/png;base64,".length()))));
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
public int getMax() {
@@ -305,4 +314,6 @@ public class MinecraftServerPinger implements Serializable{
MinecraftServerPinger sp=new MinecraftServerPinger(MinecraftServerAddress.findAddress("mc.hypixel.cn"));
System.out.println(sp);
}
}
@@ -0,0 +1,38 @@
package org.kne.cloud.network.minecraft;
import java.net.UnknownHostException;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.scanner.InetAddressRange;
import org.kne.cloud.network.scanner.PortRange;
import org.kne.cloud.network.scanner.ScanRange;
public class MinecraftServerScanRange extends ScanRange {
public MinecraftServerScanRange(InetAddressRange addressRange, PortRange portRange) {
super(addressRange, portRange);
}
public MinecraftServerScanRange(MultipurposeSocketAddress begin, MultipurposeSocketAddress end)
throws UnknownHostException {
super(begin, end);
}
public MinecraftServerScanRange(String range) throws UnknownHostException {
super(range);
}
@Override
protected void setMsaString(String range) throws UnknownHostException {
String[]sp=range.split("~");
MultipurposeSocketAddress begin=MinecraftServerAddress.findAddress (sp[0]);
MultipurposeSocketAddress end;
if(sp.length>1) {
end=MinecraftServerAddress.findAddress (sp[1]);
}else {
end=MinecraftServerAddress.findAddress (sp[0]);
}
setMsa(begin, end);
}
}
@@ -18,7 +18,7 @@ import org.kne.cloud.network.SocketToSocketProxy;
import org.kne.cloud.network.klalb.CONST;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.klalb.KLALBStateGUI2;
import org.kne.cloud.network.klalb.ui.KLALBStateGUI2;
import org.kne.util.AutoProperties;
public class SimpleKLALBMinecraftClient {
@@ -77,9 +77,9 @@ private TimerTask ptt=new TimerTask() {
sb.append(name);
sb.append('\n');
sb.append(getDsc());
sb.append('\t');
/*sb.append('\t');
sb.append((int)(reliability*100));
sb.append('%');
sb.append('%');*/
return sb.toString();
}
@Override
@@ -0,0 +1,13 @@
package org.kne.cloud.network.monitor;
public class QueueingMonitorDataImpl extends SpeedAndTrafficAndDelayMonitorDataImpl {
private long queueingDelay;
public long getQueueingDelay() {
return queueingDelay;
}
public void setQueueingDelay(long queueingDelay) {
this.queueingDelay = queueingDelay;
}
}
@@ -3,27 +3,24 @@ package org.kne.cloud.network.monitor;
public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonitorDataImpl implements SpeedAndTrafficMonitorData,DelayMonitorData{
@Override
protected void createTask() {
}
public void updateSpeedSync(){
tmt.run();
}
private volatile long outDelay;
private volatile long outDelayMin=Long.MAX_VALUE;
private volatile long outDelayAvg=Long.MAX_VALUE;
private long outDelayOld;
private volatile long outJitter;
private volatile long inDelay;
private volatile long inDelayMin=Long.MAX_VALUE;
private volatile long inDelayAvg=Long.MAX_VALUE;
private long inDelayOld;
private volatile long inJitter;
private volatile long latency;
private volatile long latencyMin=Long.MAX_VALUE;
private volatile long latencyAvg=Long.MAX_VALUE;
private long latencyOld;
private volatile long totalJitter;
@@ -32,6 +29,19 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit
private volatile long recentPingNanoTime;
public long getOutDelayAvg() {
return outDelayAvg;
}
public long getInDelayAvg() {
return inDelayAvg;
}
public long getLatencyAvg() {
return latencyAvg;
}
public long getRecentPingNanoTime() {
return recentPingNanoTime;
}
@@ -46,18 +56,29 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit
@Override
public void setOutDelay(long delay) {
this.outDelay=delay;
if(outDelayAvg==Long.MAX_VALUE) {
outDelayAvg=delay;
}else {
outDelayAvg=(outDelayAvg*9999+delay)/10000;
}
if(outDelayMin==Long.MAX_VALUE||delay<=outDelayMin) {
outDelayMin=delay;
}else{
outDelayMin=(outDelayMin*9999+delay)/10000;
}
this.latency=outDelay+inDelay;
if(latencyAvg==Long.MAX_VALUE) {
latencyAvg=latency;
}else {
latencyAvg=(latencyAvg*9999+latency)/10000;
}
if(latencyMin==Long.MAX_VALUE||latency<= latencyMin) {
latencyMin=latency;
}else {
latencyMin=(latencyMin*9999+latency)/10000;
}
outDelayPredicted=outDelay+(outDelay-outDelayOld);
outDelayPredicted=outDelay;
updateOutJitter();
updateTotalJitter();
}
@@ -70,18 +91,28 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit
@Override
public void setInDelay(long delay) {
this.inDelay=delay;
if(inDelayAvg==Long.MAX_VALUE) {
inDelayAvg=latency;
}else {
inDelayAvg=(inDelayAvg*9999+delay)/10000;
}
if(inDelayMin==Long.MAX_VALUE||delay<=inDelayMin) {
inDelayMin=delay;
}else{
inDelayMin=(inDelayMin*9999+delay)/10000;
}
this.latency=outDelay+inDelay;
if(latencyAvg==Long.MAX_VALUE) {
latencyAvg=latency;
}else {
latencyAvg=(latencyAvg*9999+latency)/10000;
}
if(latencyMin==Long.MAX_VALUE||latency<= latencyMin) {
latencyMin=latency;
}else {
latencyMin=(latencyMin*9999+latency)/10000;
}
inDelayPredicted=inDelay+(inDelay-inDelayOld);
inDelayPredicted=inDelay;
updateInJitter();
updateTotalJitter();
}
@@ -95,6 +126,11 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit
@Override
public void setLatency(long latency) {
this.latency=latency;
if(latencyAvg==Long.MAX_VALUE) {
latencyAvg=latency;
}else {
latencyAvg=(latencyAvg*9999+latency)/10000;
}
if(latencyMin==Long.MAX_VALUE||latency<= latencyMin) {
latencyMin=latency;
}else {
@@ -102,19 +138,30 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit
}
long tmp= latency>>1;
this.inDelay=tmp;
if(inDelayAvg==Long.MAX_VALUE) {
inDelayAvg=latency;
}else {
inDelayAvg=(inDelayAvg*9999+tmp)/10000;
}
if(inDelayMin==Long.MAX_VALUE||tmp<=inDelayMin) {
inDelayMin=tmp;
}else{
inDelayMin=(inDelayMin*9999+tmp)/10000;
}
this.outDelay=tmp;
if(outDelayAvg==Long.MAX_VALUE) {
outDelayAvg=latency;
}else {
outDelayAvg=(outDelayAvg*9999+tmp)/10000;
}
if(outDelayMin==Long.MAX_VALUE||tmp<=outDelayMin) {
outDelayMin=tmp;
}else{
outDelayMin=(outDelayMin*9999+tmp)/10000;
}
outDelayPredicted=outDelay+(outDelay-outDelayOld);
inDelayPredicted=inDelay+(inDelay-inDelayOld);
outDelayPredicted=outDelay;
inDelayPredicted=inDelay;
updateOutJitter();
updateInJitter();
updateTotalJitter();
@@ -16,4 +16,19 @@ public long getInSpeed();
public long getOutSpeed();
public long getInPPS();
public long getOutPPS();
public AtomicLong getInPacketCounterAL();
public AtomicLong getOutPacketCounterAL();
public long getInPacketCounter();
public long getOutPacketCounter();
}
@@ -32,6 +32,8 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
private volatile long inSpeedMax;
private volatile long outSpeedMax;
private volatile long inSpeedMax2;
private volatile long outSpeedMax2;
public SpeedAndTrafficMonitorDataImpl() {
super();
@@ -101,12 +103,23 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
return outSpeedMax;
}
public long getInSpeedMax2() {
return inSpeedMax2;
}
public long getOutSpeedMax2() {
return outSpeedMax2;
}
protected TimerTask tmt=new TimerTask() {
@Override
public void run() {
long d=System.nanoTime()-updatetime;
if(d!=0) {
if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld;
inTrafficOld =inTraffic.get();
@@ -119,16 +132,40 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
outSpeed= o*1000000000/d;
}
if(inCounter!=null) {
long i=inCounter.get()-inCounterOld;
inCounterOld =inCounter.get();
inPPS= i*1000000000/d;
}
if(outCounter!=null) {
long i=outCounter.get()-outCounterOld;
outCounterOld =outCounter.get();
outPPS= i*1000000000/d;
}
}
if(outSpeed>=outSpeedMax) {
outSpeedMax=outSpeed;
}else {
outSpeedMax=(outSpeedMax*999+outSpeed)/1000;
outSpeedMax=(outSpeedMax*99+outSpeed)/100;
}
if(inSpeed>=inSpeedMax) {
inSpeedMax=inSpeed;
}else {
inSpeedMax=(inSpeedMax*999+inSpeed)/1000;
inSpeedMax=(inSpeedMax*99+inSpeed)/100;
}
if(outPPS>=outPPSMax) {
outPPSMax=outPPS;
}else {
outPPSMax=(outPPSMax*99+outPPS)/100;
}
if(inPPS>=inPPSMax) {
inPPSMax=inPPS;
}else {
inPPSMax=(inPPSMax*99+inPPS)/100;
}
updatetime=System.nanoTime();
@@ -141,7 +178,7 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
@Override
public void run() {
long d=System.nanoTime()-updatetime1;
if(d!=0) {
if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld1;
inTrafficOld1 =inTraffic.get();
@@ -153,8 +190,19 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
outTrafficOld1 =outTraffic.get();
outSpeedAvg= o*1000000000/d;
}
if(inCounter!=null) {
long i=inCounter.get()-inCounterOld1;
inCounterOld1 =inCounter.get();
inPPSAvg= i*1000000000/d;
}
if(outCounter!=null) {
long o=outCounter.get()-outCounterOld1;
outCounterOld1 =outCounter.get();
outPPSAvg= o*1000000000/d;
}
}
updatetime1=System.nanoTime();
@@ -166,7 +214,7 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
@Override
public void run() {
long d=System.nanoTime()-updatetime2;
if(d!=0) {
if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld2;
inTrafficOld2 =inTraffic.get();
@@ -180,6 +228,45 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
}
if(inCounter!=null) {
long i=inCounter.get()-inCounterOld2;
inCounterOld2 =inCounter.get();
inPPSAvg2= i*1000000000/d;
}
if(outCounter!=null) {
long o=outCounter.get()-outCounterOld2;
outCounterOld2 =outCounter.get();
outPPSAvg2= o*1000000000/d;
}
}
if(outSpeedAvg2>=outSpeedMax2) {
outSpeedMax2=outSpeedAvg2;
}else {
outSpeedMax2=(outSpeedMax2*999+outSpeedAvg2)/1000;
}
if(inSpeedAvg2>=inSpeedMax2) {
inSpeedMax2=inSpeedAvg2;
}else {
inSpeedMax2=(inSpeedMax2*999+inSpeedAvg2)/1000;
}
if(outPPSAvg2>=outPPSMax2) {
outPPSMax2=outPPSAvg2;
}else {
outPPSMax2=(outPPSMax2*999+outPPSAvg2)/1000;
}
if(inPPSAvg2>=inPPSMax2) {
inPPSMax2=inPPSAvg2;
}else {
inPPSMax2=(inPPSMax2*999+inPPSAvg2)/1000;
}
updatetime2=System.nanoTime();
}
@@ -208,5 +295,77 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
tmt1.cancel();
tmt2.cancel();
}
private volatile AtomicLong inCounter=new AtomicLong();
private volatile AtomicLong outCounter=new AtomicLong();
private long inCounterOld;
private long outCounterOld;
private long inCounterOld1;
private long outCounterOld1;
private long inCounterOld2;
private long outCounterOld2;
private volatile long inPPS;
private volatile long outPPS;
private volatile long inPPSMax;
private volatile long outPPSMax;
private volatile long inPPSMax2;
private volatile long outPPSMax2;
private volatile long inPPSAvg;
private volatile long outPPSAvg;
private volatile long inPPSAvg2;
private volatile long outPPSAvg2;
@Override
public long getInPPS() {
return inPPS;
}
@Override
public long getOutPPS() {
return outPPS;
}
@Override
public AtomicLong getInPacketCounterAL() {
return inCounter;
}
@Override
public AtomicLong getOutPacketCounterAL() {
return outCounter;
}
@Override
public long getInPacketCounter() {
return inCounter.get();
}
@Override
public long getOutPacketCounter() {
return outCounter.get();
}
public double getOutPPSMax2() {
return outPPSMax2;
}
public double getInPPSMax2() {
return inPPSMax2;
}
public long getOutPPSAvg() {
return outPPSAvg;
}
public long getInPPSAvg() {
return inPPSAvg;
}
}
+476
View File
@@ -0,0 +1,476 @@
package org.kne.cloud.network.perf;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.nio.channels.UnresolvedAddressException;
import java.util.Objects;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.locks.LockSupport;
import org.kne.cloud.clock.AdjustedNanoClock;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.SpeedLimiter;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.klalb.ADDRPacket;
import org.kne.cloud.network.klalb.ADDRREQPacket;
import org.kne.cloud.network.klalb.BWINFPacket;
import org.kne.cloud.network.klalb.IPv6OverKLALBPacket;
import org.kne.cloud.network.klalb.KLALBPacket;
import org.kne.cloud.network.klalb.KLALBPacketLink;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.klalb.PINGPacket;
import org.kne.cloud.network.klalb.PONGPacket;
import org.kne.cloud.network.klalb.TESTPacket;
import org.kne.cloud.network.klalb.VADDRACKPacket;
import org.kne.cloud.network.klalb.VADDRPacket;
import org.kne.cloud.network.klalb.VADDRREQPacket;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
public class Kperf implements Runnable{
private ConcurrentLinkedQueue<KLALBPacket> IsendDequeList = new ConcurrentLinkedQueue<KLALBPacket>();
//private PriorityBlockingQueue<KLALBPacket> sendDequeList = new PriorityBlockingQueue<KLALBPacket>();
private static final boolean debug = true;
private static final boolean showpacket = false;
private volatile AdjustedNanoClock adjnc = new AdjustedNanoClock();
private MultipurposeSocketAddress targetAddress;
private MultipurposeSocketAddress bindAddress;
private volatile boolean connected=false;
private volatile KLALBPacketLink link;
private QueueingMonitorDataImpl monitor=new QueueingMonitorDataImpl();
private volatile boolean closed = false;
private volatile Thread tlock;
public Kperf(MultipurposeSocketAddress targetAddress,MultipurposeSocketAddress bindAddress) {
Objects.requireNonNull(targetAddress);
this.targetAddress=targetAddress;
this.bindAddress=bindAddress;
}
public Kperf(MultipurposeSocketAddress targetAddress) {
this(targetAddress,new MultipurposeSocketAddress("[::0]:0"));
}
public Kperf(KLALBPacketLink link) {
Objects.requireNonNull(link);
this.link=link;
}
private SpeedLimiter test = new SpeedLimiter(MIN_SPEED,10000000L);
private static long MIN_SPEED=64*1024L;
private SpeedLimiter congress = new SpeedLimiter(0,10000000L);
private long congressSpeed = 0;
private double loadPercent = 1.01;
private volatile int testSize=0;
//kperf {KLALB_Stream}[2486:1:34de:4abd:98c1:abd1:fc7a:401]:4564
@Override
public void run() {
Thread tc = ThreadTool.makeVDaemonThreadIfSupport("测速控制线程", () -> {
final int wtimes=5;
System.out.println("测速开始!");
try {
long startTime;
/*System.out.println("测试1/4:延迟测试");
test.setLimitspeed(0);
startTime=System.nanoTime();
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传延迟:%.3fms 下载延迟:%.3fms\n", monitor.getOutDelay()/1000000.0,monitor.getInDelay()/1000000.0);
Thread.sleep(1000);
}
System.out.printf("上传延迟 最小:%.3fms 平均:%.3fms 抖动:%.3fms\n",monitor.getOutDelayMin()/1000000.0,monitor.getOutDelayAvg()/1000000.0,monitor.getOutJitter()/1000000.0);
System.out.printf("下载延迟 最小:%.3fms 平均:%.3fms 抖动:%.3fms\n",monitor.getInDelayMin()/1000000.0,monitor.getInDelayAvg()/1000000.0,monitor.getInJitter()/1000000.0);
System.out.println("等待时间"+wtimes+"s");
Thread.sleep(wtimes*1000);*/
startTime=System.nanoTime();
if(targetAddress!=null) {
System.out.println("测试2/4:下载带宽测试");
test.setLimitspeed(0);
testSize=60000;
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
Thread.sleep(1000);
}
System.out.printf("下载带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getInSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getInSpeedMax2()));
}else {
System.out.println("测试2/4:上传带宽测试");
test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=60000;
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
Thread.sleep(1000);
}
System.out.printf("上传带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getOutSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getOutSpeedMax2()));
}
System.out.println("等待时间"+wtimes+"s");
Thread.sleep(wtimes*1000);
startTime=System.nanoTime();
if(targetAddress!=null) {
System.out.println("测试3/4:上传带宽测试");
test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=60000;
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
Thread.sleep(1000);
}
System.out.printf("上传带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getOutSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getOutSpeedMax2()));
}else {
System.out.println("测试3/4:下载带宽测试");
test.setLimitspeed(0);
testSize=60000;
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
Thread.sleep(1000);
}
System.out.printf("下载带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getInSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getInSpeedMax2()));
}
System.out.println("等待时间"+wtimes+"s");
Thread.sleep(wtimes*1000);
startTime=System.nanoTime();
if(targetAddress!=null) {
System.out.println("测试2/4:下载包转发率测试");
test.setLimitspeed(0);
testSize=0;
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
Thread.sleep(1000);
}
}else {
System.out.println("测试2/4:上传包转发率测试");
test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=0;
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
Thread.sleep(1000);
}
//System.out.printf("上传带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getOutSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getOutSpeedMax2()));
}
System.out.println("等待时间"+wtimes+"s");
Thread.sleep(wtimes*1000);
startTime=System.nanoTime();
if(targetAddress!=null) {
System.out.println("测试3/4:上传包转发率测试");
test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=0;
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
Thread.sleep(1000);
}
}else {
System.out.println("测试3/4:下载包转发率测试");
test.setLimitspeed(0);
testSize=0;
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
Thread.sleep(1000);
}
}
System.out.println("等待时间"+wtimes+"s");
Thread.sleep(wtimes*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("测速结束!");
close();
});
try {
monitor.setState(MonitorData.CONNECTING);
if(link==null)
link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,20000);
link.setSoTimeout(20000);
Thread t = ThreadTool.makeVDaemonThreadIfSupport("测速发送线程", () -> {
tlock = Thread.currentThread();
try {
KLALBPacket kpp = null;
while ((!link.isClosed()) && (!closed)) {
// TimeDebugger tdb=new TimeDebugger();
// tdb.putTime("start");
if(checkBandwidthReportTime()) {
writePacketToKPL(new BWINFPacket(monitor.getOutSpeedAvg2(), monitor.getInSpeedAvg2()));
}
if (checkPingTimeSleep()) {
writePacketToKPL(new PINGPacket(System.nanoTime()));
}else {
KLALBPacket kpip = IsendDequeList.poll();
if (kpip != null) {
writePacketToKPL(kpip);
}else {
if (test.checkTransmit(testSize+3)) {
TESTPacket tp=new TESTPacket(testSize);
writePacketToKPL(tp);
}else {
LockSupport.parkNanos(1000000);
}
}
}
Thread.yield();
}
} catch (IOException | UnresolvedAddressException e) {
if (debug)
e.printStackTrace();
} finally {
try {
link.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
boolean fst = true;
while ((!link.isClosed()) && (!closed)) {
KLALBPacket kpp = readPacketFromKPL();
if (kpp == null) {
break;
}
switch (kpp.getType()) {
case KLALBPacket.PING:
sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime()));
break;
case KLALBPacket.PONG:
if (fst) {
// coll.resetCoolingTime();
monitor.setState(MonitorData.ONLINE);
connected=true;
if(targetAddress!=null) {
System.out.println("连接地址"+targetAddress+"成功!");
}else {
System.out.println("接受地址"+link.toString()+"连接成功!");
}
tc.start();
fst = false;
}
PONGPacket png = (PONGPacket) kpp;
long ul = png.getRcvtime() - png.getTimepingsnd()-(png.getTimepongsnd()-png.getTimepingrcv());
long DsndDelayFactor0 = png.getTimepingrcv() - png.getTimepingsnd();
long DrcvDelayFactor0 = png.getRcvtime() - png.getTimepongsnd();
long DsndDelayFactor;
long DrcvDelayFactor;
adjnc.getLock().lock();
try {
adjnc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
if (DsndDelayFactor < 0) {
if (DrcvDelayFactor < 0) {
} else {
adjnc.setDelta(adjnc.getDelta() + DsndDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
}
} else {
if (DrcvDelayFactor < 0) {
adjnc.setDelta(adjnc.getDelta() - DrcvDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
}
}
} finally {
adjnc.getLock().unlock();
}
if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) {
monitor.setOutDelay(DsndDelayFactor);
monitor.setInDelay(DrcvDelayFactor);
monitor.setRecentPingNanoTime(png.getTimepingsnd());
//pingInterval = monitor.getLatencyAvg()+2000000L;
//double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay();
loadPercent =Math.max( 1.2,0.4);
}
LockSupport.unpark(tlock);
break;
case KLALBPacket.BWINF:
BWINFPacket bwi = (BWINFPacket) kpp;
if (bwi.getDownSpeed() >= congressSpeed) {
congressSpeed = bwi.getDownSpeed();
} else {
congressSpeed = (congressSpeed * 999 + bwi.getDownSpeed()) / 1000;
}
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) );
// System.out.println(congressSpeed);
break;
case KLALBPacket.TEST:
break;
}
Thread.yield();
}
} catch (IOException e) {
if(monitor.getState()==MonitorData.CONNECTING)
System.out.println("连接目标地址失败!");
if(debug)
e.printStackTrace();
}finally {
monitor.setState(MonitorData.OFFLINE);
if(link!=null) {
try {
link.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private volatile long time = System.nanoTime();
private volatile long pingInterval = 10000000L;
private volatile long pingIntervalSleep = 200000000L;
private boolean checkPingTime() {
long cu = System.nanoTime();
if (cu - time > pingInterval) {
time = cu;
return true;
} else {
return false;
}
}
private boolean checkPingTimeSleep() {
long cu = System.nanoTime();
if (cu - time > pingIntervalSleep) {
time = cu;
return true;
} else {
return false;
}
}
private volatile long bwtime = System.nanoTime();
private volatile long bwpingInterval = 10000000L;
private volatile long bwpingIntervalSleep = 100000000L;
private boolean checkBandwidthReportTime(){
long cu = System.nanoTime();
if (cu - bwtime > bwpingIntervalSleep) {
bwtime = cu;
return true;
} else {
return false;
}
}
public void close() {
closed = true;
monitor.setState(MonitorData.OFFLINE);
try {
if (link != null)
link.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*protected void sendPacket(KLALBPacket blk) {
blk.markJoinqueuetime();
sendDequeList.add(blk);
LockSupport.unpark(tlock);
}*/
private void sendIPacket(KLALBPacket blk) {
IsendDequeList.add(blk);
LockSupport.unpark(tlock);
}
private KLALBPacket readPacketFromKPL() throws IOException {
KLALBPacket packet = link.readPacket();
if (showpacket) {
System.out.println("RX:" + packet);
}
if (packet != null) {
packet.putTimePassport("received");
long length=packet.getLength();
monitor.getInTrafficAL().addAndGet(length);
monitor.getInPacketCounterAL().incrementAndGet();
}
return packet;
}
private void writePacketToKPL(KLALBPacket packet) throws IOException {
long length=packet.getLength();
monitor.getOutTrafficAL().addAndGet(length);
monitor.getOutPacketCounterAL().incrementAndGet();
link.writePacket(packet);
link.flush();
packet.putTimePassport("sended");
packet.printPassport();
if (showpacket) {
System.err.println("TX:" + packet);
}
}
public void startPerfing() {
ThreadTool.makeVThreadIfSupport("测速接收线程" ,this).start();
}
}
@@ -25,10 +25,14 @@ public class InetAddressRange {
this.end = end;
}
public String getBeginHost() {
if(beginHost!=null)
return beginHost;
return begin.getHostAddress();
}
public String getEndHost() {
if(endHost!=null)
return endHost;
return end.getHostAddress();
}
public InetAddressRange(InetAddress address) {
this(address,address);
@@ -28,7 +28,7 @@ public class PortRange {
}
@Override
public String toString() {
return "PortRange [begin=" + begin + ", end=" + end + "]";
return begin + "~" + end ;
}
@Override
public int hashCode() {
@@ -0,0 +1,67 @@
package org.kne.cloud.network.scanner;
import java.io.Serializable;
import java.net.UnknownHostException;
import java.util.Objects;
import org.kne.cloud.network.MultipurposeSocketAddress;
public class ScanRange implements Serializable {
public ScanRange(String range) throws UnknownHostException {
setMsaString(range);
}
protected void setMsaString(String range) throws UnknownHostException {
String[]sp=range.split("~");
MultipurposeSocketAddress begin=new MultipurposeSocketAddress(sp[0]);
MultipurposeSocketAddress end;
if(sp.length>1) {
end=new MultipurposeSocketAddress(sp[1]);
}else {
end=new MultipurposeSocketAddress(sp[0]);
}
setMsa(begin, end);
}
public ScanRange(MultipurposeSocketAddress begin,MultipurposeSocketAddress end) throws UnknownHostException {
setMsa(begin,end);
}
protected void setMsa(MultipurposeSocketAddress begin, MultipurposeSocketAddress end) throws UnknownHostException {
this.addressRange=new InetAddressRange(begin.getHost(), end.getHost());
this.portRange=new PortRange(begin.getPort(), end.getPort());
}
public ScanRange(InetAddressRange addressRange, PortRange portRange) {
super();
this.addressRange = addressRange;
this.portRange = portRange;
}
private static final long serialVersionUID = 1L;
protected InetAddressRange addressRange;
protected PortRange portRange;
public InetAddressRange getAddressRange() {
return addressRange;
}
public PortRange getPortRange() {
return portRange;
}
public String toString() {
return new MultipurposeSocketAddress(addressRange.getBeginHost(), portRange.getBegin())+"~"+new MultipurposeSocketAddress(addressRange.getEndHost(), portRange.getEnd());
}
@Override
public int hashCode() {
return Objects.hash(addressRange, portRange);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ScanRange other = (ScanRange) obj;
return Objects.equals(addressRange, other.addressRange) && Objects.equals(portRange, other.portRange);
}
}
@@ -35,16 +35,13 @@ public class TCPNetworkScanner implements Runnable {
this.processConsumer = processConsumer;
}
private List<InetAddressRange> addressRanges = new ArrayList<>();
private List<PortRange> portRanges = new ArrayList<>();
private List<ScanRange> ranges = new ArrayList<>();
public List<InetAddressRange> getAddressRanges() {
return addressRanges;
}
public List<PortRange> getPortRanges() {
return portRanges;
public List<ScanRange> getRanges() {
return ranges;
}
public BiConsumer<MultipurposeSocketAddress,Socket> getConsumer() {
@@ -62,24 +59,25 @@ public class TCPNetworkScanner implements Runnable {
@Override
public void run() {
ThreadPoolExecutor exc=(ThreadPoolExecutor) Executors.newFixedThreadPool(8192,new ThreadFactory() {
ThreadPoolExecutor exc=(ThreadPoolExecutor) Executors.newFixedThreadPool(512,new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return ThreadTool.makeVThreadIfSupport("端口扫描线程", r);
Thread t=ThreadTool.makeVThreadIfSupport("端口扫描线程", r);
t.setPriority(Thread.MIN_PRIORITY);
return t;
}
});
ThreadPoolExecutor excd=(ThreadPoolExecutor) Executors.newFixedThreadPool(8);
BigInteger bip=new BigInteger("0");
for (Iterator<PortRange> iterator = portRanges.iterator(); iterator.hasNext();) {
PortRange portRange = (PortRange) iterator.next();
bip=bip.add(portRange.getElementCount());
for (Iterator<ScanRange> iterator = ranges.iterator(); iterator.hasNext();) {
ScanRange sRange = (ScanRange) iterator.next();
bip=bip.add(sRange.getPortRange().getElementCount().multiply(sRange.getAddressRange().getElementCount()));
}
BigInteger bia=new BigInteger("0");
for (Iterator<InetAddressRange> iterator = addressRanges.iterator(); iterator.hasNext();) {
InetAddressRange inetAddressRange = (InetAddressRange) iterator.next();
bia=bia.add(inetAddressRange.getElementCount());
}
tot=bip.multiply(bia);
tot=bip;
ReentrantLock counterlock=new ReentrantLock();
counter=new BigInteger("0");
@@ -90,7 +88,12 @@ public class TCPNetworkScanner implements Runnable {
if(processConsumer!=null) {
BigDecimal bdt=new BigDecimal(tot);
BigDecimal bdc=new BigDecimal(counter);
float fp=bdc.divide(bdt, 8, BigDecimal.ROUND_HALF_UP).floatValue()*100;
float fp;
if(bdt.equals(BigDecimal.ZERO)) {
fp=100;
}else {
fp=bdc.divide(bdt, 8, BigDecimal.ROUND_HALF_UP).floatValue()*100;
}
processConsumer.accept(fp);
}
}finally {
@@ -98,14 +101,20 @@ public class TCPNetworkScanner implements Runnable {
}
try {
for (Iterator<PortRange> iterator = portRanges.iterator(); iterator.hasNext();) {
PortRange portRange = (PortRange) iterator.next();
for (Iterator<ScanRange> iterator = ranges.iterator(); iterator.hasNext();) {
ScanRange sRange = (ScanRange) iterator.next();
PortRange portRange=sRange.getPortRange();
InetAddressRange inetAddressRange=sRange.getAddressRange();
while( excd.getQueue().size()>500) {
LockSupport.parkNanos(1000000);
}
excd.execute(()->{
int curport = portRange.getBegin();
while (curport <= portRange.getEnd()) {
for (Iterator<InetAddressRange> iterator2 = addressRanges.iterator(); iterator2.hasNext();) {
InetAddressRange inetAddressRange = (InetAddressRange) iterator2.next();
byte[]endarr=inetAddressRange.getEnd().getAddress();
byte[] curr = inetAddressRange.getBegin().getAddress();
while (compareIPAddress(curr,endarr)) {
@@ -113,16 +122,16 @@ public class TCPNetworkScanner implements Runnable {
int curport0=curport;
InetAddress currAddress=pga(curr);
while( exc.getQueue().size()>1000) {
while( exc.getQueue().size()>500) {
LockSupport.parkNanos(1000000);
}
exc.execute(()->{
MultipurposeSocketAddress mpsa;
if (inetAddressRange.getBeginHost() != null&&currAddress.equals(inetAddressRange.getBegin())) {
if (currAddress.equals(inetAddressRange.getBegin())) {
mpsa = new MultipurposeSocketAddress(inetAddressRange.getBeginHost(), curport0);
}else if (inetAddressRange.getEndHost() != null&&currAddress.equals(inetAddressRange.getEnd())) {
}else if (currAddress.equals(inetAddressRange.getEnd())) {
mpsa = new MultipurposeSocketAddress(inetAddressRange.getEndHost(), curport0);
} else {
mpsa = new MultipurposeSocketAddress(currAddress.getHostAddress(),
@@ -135,11 +144,17 @@ public class TCPNetworkScanner implements Runnable {
//System.out.println(isa);
s.connect(isa,connectTimeout);
s.setSoTimeout(soTimeout);
try {
acceptMultipurposeSocketAddress(mpsa, s);
}catch(Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
try {
acceptMultipurposeSocketAddress(mpsa, null);
}catch(Exception ed) {
ed.printStackTrace();
}
} finally {
if (s != null)
try {
@@ -154,7 +169,11 @@ public class TCPNetworkScanner implements Runnable {
BigDecimal bdt=new BigDecimal(tot);
BigDecimal bdc=new BigDecimal(counter);
float fp=bdc.divide(bdt, 8, BigDecimal.ROUND_HALF_UP).floatValue()*100;
try {
processConsumer.accept(fp);
}catch(Exception e) {
e.printStackTrace();
}
}
}finally {
counterlock.unlock();
@@ -162,7 +181,7 @@ public class TCPNetworkScanner implements Runnable {
});
increaceIPAddress(curr);
}
}
try {
Thread.sleep(10);
@@ -172,10 +191,16 @@ public class TCPNetworkScanner implements Runnable {
curport++;
}
});
}
}finally {
excd.shutdown();
try {
excd.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
exc.shutdown();
try {
exc.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
@@ -233,15 +258,14 @@ public class TCPNetworkScanner implements Runnable {
}
public TCPNetworkScanner() {
// TODO 自动生成的构造函数存根
}
public static void main(String[] args) throws UnknownHostException {
TCPNetworkScanner tcn = new TCPNetworkScanner();
tcn.getPortRanges().add(new PortRange(25565));
tcn.getPortRanges().add(new PortRange(34000, 38000));
tcn.getAddressRanges().add(new InetAddressRange("192.168.0.1","192.168.1.255"));
//tcn.getRanges().add(new ScanRange(new InetAddressRange("127.0.0.1","127.0.0.2"),new PortRange(25565,37000)));
tcn.getRanges().add(new ScanRange("ip.8mi.work:50000~ip.8mi.work:60000"));
tcn.setConsumer((scanned,s) -> {
if(s!=null)
System.out.println(scanned);
});
tcn.setProcessConsumer((f)->{System.out.println(f);
@@ -0,0 +1,8 @@
package org.kne.cloud.network.srv6;
public interface DijkstraAlgorithm extends Runnable{
public void setGraph(long[][]pointers,long[][]heap,long startPoint) ;
public void run();
public long[] getDirection();
public long[] getShortest();
}
@@ -0,0 +1,82 @@
package org.kne.cloud.network.srv6;
public class DijstraAlgorithm {
//不能设置为Integer.MAX_VALUE否则两个Integer.MAX_VALUE相加会溢出导致出现负权
public static int M = 100000;
//定义七个顶点
private static char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
public static void main(String[] args) {
//初始化邻接矩阵
int[][] matrix = new int[vertex.length][vertex.length];
matrix[0] = new int[]{M, 5, 7, M, M, M, 2};
matrix[1] = new int[]{5, M, M, 9, M, M, 3};
matrix[2] = new int[]{7, M, M, M, 8, M, M};
matrix[3] = new int[]{M, 9, M, M, M, 4, M};
matrix[4] = new int[]{M, M, 8, M, M, 5, 4};
matrix[5] = new int[]{M, M, M, 4, 5, M, 6};
matrix[6] = new int[]{2, 3, M, M, 4, 6, M};
//调用dijstra算法计算最短路径
dijstra(matrix, 0);
}
/**
* @param matrix邻接矩阵
* @param source起点
*/
public static void dijstra(int[][] matrix, int source) {
//最短路径长度
int[] shortest = new int[matrix.length];
//判断该点的最短路径是否求出
int[] visited = new int[matrix.length];
//存储输出路径
String[] path = new String[matrix.length];
//初始化输出路径
for (int i = 0; i < matrix.length; i++) {
path[i] = vertex[source] + "->" + vertex[i];
}
//初始化起点将起点放入S
shortest[source] = 0;
visited[source] = 1;
for (int i = 1; i < matrix.length; i++) { //i从1开始因为起点已经加入S了
int min = M;
int index = -1;
//找出某节点到起点路径最短
for (int j = 0; j < matrix.length; j++) {
//已经求出最短路径的节点不需要再加入计算并判断加入节点后是否存在更短路径
if (visited[j] == 0 && matrix[source][j] < min) {
min = matrix[source][j];
index = j;
}
}
//更新最短路径标记起点到该节点的最短路径已经求出
shortest[index] = min;
visited[index] = 1;
//更新从index跳到其它节点的较短路径
for (int m = 0; m < matrix.length; m++) {
if (visited[m] == 0 && matrix[source][index] + matrix[index][m] < matrix[source][m]) {
matrix[source][m] = matrix[source][index] + matrix[index][m];
path[m] = path[index] + "->" + vertex[m];
}
}
}
//打印最短路径
for (int i = 0; i < matrix.length; i++) {
if (i != source) {
if (shortest[i] == M) {
System.out.println(vertex[source] + "" + vertex[i] + "不可达");
} else {
System.out.println(vertex[source] + "" + vertex[i] + "的最短路径为:" + path[i] + ",最短距离是:" + shortest[i]);
}
}
}
}
}
@@ -0,0 +1,147 @@
package org.kne.cloud.network.srv6;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.klalb.KLALBPacket;
public class IPv6SegmentRoutingTLV extends NetworkPacket {
public static final int PAD1=0;
public static final int PADN=4;
public static final int HMAC=5;
public static final int SEQS=7;
private boolean isDefault;
protected volatile ByteBuffer header;
private ByteBuffer data;
public IPv6SegmentRoutingTLV(ByteBuffer header ) {
this(header,true);
}
public ByteBuffer getData() {
return data;
}
public IPv6SegmentRoutingTLV(ByteBuffer header ,boolean isDefault ) {
super();
this.header = header;
if(isDefault&&(getType()!=PAD1)) {
data=ByteBuffer.allocate(512);
}
}
public IPv6SegmentRoutingTLV(int type) {
this(type,true);
}
public IPv6SegmentRoutingTLV(int type,boolean isDefault) {
super();
this.header=ByteBuffer.allocate(2);
header.put((byte) type);
if(isDefault&&(type!=PAD1)) {
data=ByteBuffer.allocate(512);
}
}
@Override
public long getLength() {
if(getType()==PAD1)
return 1;
return header.limit()+(isDefault?data.limit():0);
}
public static IPv6SegmentRoutingTLV readIPv6SegmentRoutingTLVFromChannel(ReadableByteChannel din) throws IOException {
ByteBuffer bbf= ByteBuffer.allocate(2);
bbf.limit(1);
while (bbf.hasRemaining()) {
if (din.read(bbf) == -1) {
return null;
}
}
int type=bbf.get(0)&0xff;
IPv6SegmentRoutingTLV rtlv;
switch(type) {
case PAD1:
rtlv=new PAD1SegmentRoutingTLV(bbf);
rtlv.readFromChannel(din);
return rtlv;
case PADN:
rtlv=new PADNSegmentRoutingTLV(bbf);
rtlv.readFromChannel(din);
return rtlv;
default:
rtlv=new IPv6SegmentRoutingTLV(bbf);
rtlv.readFromChannel(din);
return rtlv;
}
}
public static void writeIPv6SegmentRoutingTLVToChannel(WritableByteChannel dto,IPv6SegmentRoutingTLV tlv) throws IOException {
tlv.writeToChannel(dto);
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
if(isDefault&&(getType()!=PAD1)) {
setDataLength(data.limit());
}
dto.write(header.slice(0,header.limit()));
if(isDefault&&(getType()!=PAD1)) {
dto.write(data.slice(0, data.limit()));
}
}
@Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
header.limit(1);
while (header.hasRemaining()) {
if (din.read(header) == -1) {
throw new EOFException();
}
}
int type=getType();
if(type!=PAD1) {
header.limit(2);
while (header.hasRemaining()) {
if (din.read(header) == -1) {
throw new EOFException();
}
}
}
header.flip();
if(isDefault&&(getType()!=PAD1)) {
data.clear();
data.limit(getDataLength());
while(data.hasRemaining()){
if(din.read(data)==-1) {
throw new EOFException();
}
}
data.flip();
}
}
@Override
protected boolean needEndPosition() {
return false;
}
public int getType() {
return header.get(0)&0xff;
}
public void setType(int type) {
header.put(0,(byte) type);
}
public int getDataLength() {
return header.get(1)&0xff;
}
public void setDataLength(int dataLength) {
header.put(1,(byte) dataLength);
}
}
@@ -0,0 +1,209 @@
package org.kne.cloud.network.srv6;
import static org.pcap4j.util.ByteArrays.*;
import java.net.Inet6Address;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.pcap4j.packet.IllegalRawDataException;
import org.pcap4j.packet.IpV6ExtRoutingPacket.IpV6RoutingData;
import org.pcap4j.util.ByteArrays;
public final class IpV6RoutingSRHData implements IpV6RoutingData {
/** */
private static final long serialVersionUID = -7972526977248222954L;
private final int lastEntry;
private final int flags;
private final int tag;
private final List<Inet6Address> addresses;
private final List<SRv6TLV> tlvs;
/**
* A static factory method. This method validates the arguments by {@link
* ByteArrays#validateBounds(byte[], int, int)}, which may throw exceptions undocumented here.
*
* @param rawData rawData
* @param offset offset
* @param length length
* @return a new IpV6RoutingSourceRouteData object.
* @throws IllegalRawDataException if parsing the raw data fails.
*/
public static IpV6RoutingSRHData newInstance(byte[] rawData, int offset, int length)
throws IllegalRawDataException {
return new IpV6RoutingSRHData(rawData, offset, length);
}
private IpV6RoutingSRHData(byte[] rawData, int offset, int length)
throws IllegalRawDataException {
this.lastEntry = rawData[ offset]&0xff;
this.flags=rawData[offset+1]&0xff;
this.tag=ByteArrays.getShort(rawData, offset+2);
this.addresses = new ArrayList<Inet6Address>();
this.tlvs=new ArrayList<>();
int endv=INT_SIZE_IN_BYTES+(lastEntry+1)*INET6_ADDRESS_SIZE_IN_BYTES;
for (int i = INT_SIZE_IN_BYTES; i < endv; i += INET6_ADDRESS_SIZE_IN_BYTES) {
addresses.add(ByteArrays.getInet6Address(rawData, i + offset));
}
for(int itlv=endv;itlv<length;) {
int type=rawData[itlv+offset]&0xff;
switch(type) {
case SRv6TLV.PAD1:
itlv++;
tlvs.add(new SRv6Pad1TLV());
break;
case SRv6TLV.PADN:
itlv++;
int lengthPN=rawData[itlv+offset]&0xff;
tlvs.add(new SRv6PadNTLV(lengthPN));
itlv+=1+lengthPN;
break;
case SRv6TLV.SEQS:
itlv++;
int lengthQTLV=rawData[itlv+offset]&0xff;
byte[]rawQTLV=new byte[lengthQTLV];
System.arraycopy(rawData, itlv+offset+1, rawQTLV, 0, lengthQTLV);
tlvs.add(new SRv6StreamSequenceTLV( lengthQTLV, rawQTLV));
itlv+=1+lengthQTLV;
break;
default:
itlv++;
int lengthTLV=rawData[itlv+offset]&0xff;
byte[]rawTLV=new byte[lengthTLV];
System.arraycopy(rawData, itlv+offset+1, rawTLV, 0, lengthTLV);
tlvs.add(new SRv6TLV(type, lengthTLV, rawTLV));
itlv+=1+lengthTLV;
break;
}
}
}
public List<SRv6TLV> getTlvs() {
return tlvs;
}
public int getLastEntry() {
return lastEntry;
}
public int getFlags() {
return flags;
}
public int getTag() {
return tag;
}
public List<Inet6Address> getAddresses() {
return addresses;
}
public IpV6RoutingSRHData(List<Inet6Address> addresses) {
this(0,0,addresses,new ArrayList<>());
}
public IpV6RoutingSRHData(List<Inet6Address> addresses,List<SRv6TLV>tlvs) {
this(0,0,addresses,tlvs);
}
/**
* @param reserved reserved
* @param addresses addresses
*/
public IpV6RoutingSRHData(int flags,int tag, List<Inet6Address> addresses,List<SRv6TLV>tlvs) {
if (addresses == null) {
throw new NullPointerException("addresses must not be null");
}
this.lastEntry = addresses.size()-1;
this.flags=flags;
this.tag=tag;
this.addresses = new ArrayList<Inet6Address>(addresses);
this.tlvs=tlvs;
}
@Override
public int length() {
int tlvsize=0;
for (int i = 0; i < tlvs.size(); i++) {
tlvsize+=tlvs.get(i).getTotalLength();
}
return INT_SIZE_IN_BYTES+addresses.size() * INET6_ADDRESS_SIZE_IN_BYTES + tlvsize;
}
@Override
public byte[] getRawData() {
byte[] rawData = new byte[length()];
rawData[0]=(byte) lastEntry;
rawData[1]=(byte) flags;
rawData[2]=(byte) (tag>>8);
rawData[3]=(byte) tag;
;
int i = INT_SIZE_IN_BYTES;
for ( Iterator<Inet6Address> iter = addresses.iterator(); iter.hasNext(); i += INET6_ADDRESS_SIZE_IN_BYTES) {
System.arraycopy(
ByteArrays.toByteArray(iter.next()), 0, rawData, i, INET6_ADDRESS_SIZE_IN_BYTES);
}
for (int j = 0; j < tlvs.size(); j++) {
SRv6TLV srt=tlvs.get(j);
switch(srt.getType()) {
case SRv6TLV.PAD1:
rawData[i++]=(byte) srt.getType();
break;
case SRv6TLV.PADN:
rawData[i++]=(byte) srt.getType();
int plth=srt.getLength();
rawData[i++]=(byte) plth;
i+=plth;
break;
default:
rawData[i++]=(byte) srt.getType();
int dlth=srt.getLength();
rawData[i++]=(byte) dlth;
System.arraycopy(srt.getValue(), 0, rawData, i, dlth);
i+=dlth;
break;
}
}
return rawData;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[lastentry: ").append(lastEntry).append("][flags: ").append(flags).append("][tag: ").append(tag).append("] [addresses:");
for (Inet6Address addr : addresses) {
sb.append(" ").append(addr);
}
sb.append("]");
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!this.getClass().isInstance(obj)) {
return false;
}
IpV6RoutingSRHData other = (IpV6RoutingSRHData) obj;
return lastEntry == other.lastEntry&&flags==other.flags&&tag==other.tag && addresses.equals(other.addresses);
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + lastEntry;
result = 31 * result + flags;
result = 31 * result + tag;
result = 31 * result + addresses.hashCode();
return result;
}
}
@@ -0,0 +1,575 @@
package org.kne.cloud.network.srv6;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.BindException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.channels.Channels;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor;
import org.kne.cloud.network.monitor.DelayMonitorData;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
import org.kne.cloud.network.scanner.InetAddressRange;
public class KLALBRoutingProtocol extends Thread{
private static final boolean debug = false;
private Map<Inet6Address, RouterInfo> netmap=new ConcurrentHashMap<>();
private volatile Map<Inet6Address,Long>addresses;
private volatile Map<Inet6Address, Set<LinkDirection>> paths;
public static final int DEFAULT_PORT=1001;
public static final long HOTSOPT_TIMEOUT = 1000000000;
public static final int HOTSOPT_REPORT_INTERVAL = 100000000;
private SRv6Router router;
public SRv6Router getRouter() {
return router;
}
public KLALBRoutingProtocol(SRv6Router router) {
this.router=router;
}
private ReentrantLock sendlock=new ReentrantLock();
private long floodTimer=System.nanoTime();
private long floodTimer2=System.nanoTime();
@Override
public void run() {
Thread.currentThread().setName("KLALB路由协议接收线程");
getSelfRouterInfo();
DatagramSocket ds = null;
try{
ds=new DatagramSocket(new InetSocketAddress(router.getLocator().getAddress(), DEFAULT_PORT) );
DatagramSocket ds2=ds;
new Thread(()->{
Thread.currentThread().setName("KLALB路由协议接收线程");
while(true) {
try {
/*List<NetworkLink>links=router.getLinkTabel();
Object[] nls=links.toArray();
byte[]to=createLinkStatePacket(nls);
DatagramPacket dgp=new DatagramPacket(to,to.length);
for(int i=0;i<nls.length;i++) {
NetworkLink nl=(NetworkLink) nls[i];
if(!nl.isLoopBack()) {
Set<Inet6Address>neis=nl.discoverNeighbors();
for (Iterator<Inet6Address> iteratorx = neis.iterator(); iteratorx.hasNext();) {
Inet6Address addresses = (Inet6Address) iteratorx.next();
dgp.setAddress(addresses);
dgp.setPort(DEFAULT_PORT);
ds2.send(dgp);
}
}
}*/
RouterInfo slf= getSelfRouterInfo();
RouterInfo oslf=netmap.put(slf.getLocator().getAddress(), slf);
noticeUpdate();
if(oslf==null||(!slf.equals(oslf))) {
//System.out.println("change:"+oslf+"\n"+slf);
long cur=System.nanoTime();
if(cur-floodTimer2>5000000000L) {
//System.out.println("update10");
floodTimer2=cur;
floodPacket(ds2, null, new RouterInfoPacket(slf,true));
}
}else {
long cur=System.nanoTime();
if(cur-floodTimer>60000000000L) {
//System.out.println("update60");
floodTimer=cur;
floodPacket(ds2, null, new RouterInfoPacket(slf,true));
}
}
Set<Inet6Address> requestSet=new HashSet<>();
for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = netmap.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, RouterInfo> type = (Entry<Inet6Address, RouterInfo>) iterator.next();
RouterInfo val=type.getValue();
if(val.checkTimeOut()) {
iterator.remove();
noticeUpdate();
}
Set<NeighborInfo> ads=val.getNeighborAddresses();
for (Iterator<NeighborInfo> iterator2 = ads.iterator(); iterator2.hasNext();) {
Inet6Address address=iterator2.next().getLocator().getAddress();
//System.out.println(address);
if(!netmap.containsKey(address)) {
requestSet.add(address);
}
}
}
computeShortestPathIfUpdated();
for (Iterator<Inet6Address> iterator = requestSet.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next();
byte[]to=new byte[] {0};
DatagramPacket dgp=new DatagramPacket(to,to.length);
dgp.setAddress(inet6Address);
dgp.setPort(DEFAULT_PORT);
if(debug)
System.out.println("Request:"+inet6Address);
sendlock.lock();
try {
ds2.send(dgp);
}catch(SocketException e) {
System.out.println("Send failed:"+dgp.getAddress());
}finally {
sendlock.unlock();
}
}
for (Iterator<Entry<Inet6Address, HotspotAddressTimer>> iterator = hotspots.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, HotspotAddressTimer> type = (Entry<Inet6Address, HotspotAddressTimer>) iterator.next();
if(type.getValue().checkReportTime()) {
//System.out.println("hotspot address:"+type.getKey());
writePacket(ds2, new RouterInfoPacket( netmap.get(router.getLocator().getAddress()),false), new InetSocketAddress(type.getKey(), DEFAULT_PORT));
}
if(type.getValue().checkTimeOut()) {
iterator.remove();
}
}
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}catch (IOException e1) {
// TODO 自动生成的 catch
e1.printStackTrace();
}
}
}).start();
while(true) {
try {
byte[]ca=new byte[65535];
DatagramPacket dgp=new DatagramPacket(ca, ca.length);
ds.receive(dgp);
//System.out.println(Arrays.toString( Arrays.copyOf( dgp.getData(),dgp.getLength())));
ByteArrayInputStream bi=new ByteArrayInputStream(dgp.getData(),0,dgp.getLength());
KLALBRoutingProtocolPacket kp=KLALBRoutingProtocolPacket.readKLALBPacketFromChannel(Channels.newChannel(bi));
//System.out.println(kp);
switch(kp.getType()) {
case KLALBRoutingProtocolPacket.RINFO_REQ:
RouterInfo rifr=netmap.get(router.getLocator().getAddress());
if(rifr!=null)
writePacket(ds, new RouterInfoPacket( rifr,false), dgp.getSocketAddress());
break;
case KLALBRoutingProtocolPacket.RINFO:
RouterInfoPacket rifp=(RouterInfoPacket) kp;
RouterInfo rif=rifp.getRinfo();
RouterInfo oldrif=netmap.get(rif.getLocator().getAddress());
if(debug)
System.out.println(rif);
if(oldrif==null||oldrif.getCreateTime()<rif.getCreateTime()) {
if(debug)
System.out.println("update RouterInfo");
netmap.put(rif.getLocator().getAddress(), rif);
noticeUpdate();
if(rifp.isFlood()) {
floodPacket(ds, dgp.getSocketAddress(), rifp);
}
}else {
if(debug)
System.out.println("dispose RouterInfo");
}
computeShortestPathIfUpdated();
break;
default:
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (SocketException e2) {
e2.printStackTrace();
}finally {
if(ds!=null) {
ds.close();
}
}
}
private void floodPacket(DatagramSocket ds,SocketAddress except,KLALBRoutingProtocolPacket rifp) throws IOException {
List<IPv6NetworkLink>links=router.getLinkTabel();
Object[] nls=links.toArray();
for(int i=0;i<nls.length;i++) {
IPv6NetworkLink nl=(IPv6NetworkLink) nls[i];
if(!nl.isLoopBack()) {
List<Neighbor>neis=nl.getNeighborsInfo();
for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
InetSocketAddress isa=new InetSocketAddress(addresses.getLocator().getAddress(),DEFAULT_PORT);
if(!isa.equals(except)) {
writePacket(ds, rifp, isa);
}
}
}
}
}
private void writePacket(DatagramSocket ds,KLALBRoutingProtocolPacket pkt,SocketAddress dest) throws IOException {
ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
KLALBRoutingProtocolPacket.writeKLALBPacketToChannel(Channels.newChannel(bos),pkt);
byte[]to=bos.toByteArray();
DatagramPacket dgpx=new DatagramPacket(to,to.length);
dgpx.setSocketAddress(dest);
sendlock.lock();
try {
ds.send(dgpx);
}catch(BindException e) {
e.printStackTrace();
System.err.println("Cannot assign:"+dest);
}finally {
sendlock.unlock();
}
}
private DijkstraAlgorithm algorithm=new SingleDijkstraAlgorithm();
private ReentrantLock directionLock=new ReentrantLock();
private volatile NetmapDirections directions;
private static class NetmapDirections{
public NetmapDirections(long[] direction, List<Inet6Address> rias,
Map<Inet6Address, Long> direction_airs) {
super();
this.direction = direction;
this.direction_rias = rias;
this.direction_airs = direction_airs;
}
private long[] direction;
private List<Inet6Address> direction_rias;
private Map<Inet6Address, Long> direction_airs;
public long[] getDirection() {
return direction;
}
public List<Inet6Address> getDirection_rias() {
return direction_rias;
}
public Map<Inet6Address, Long> getDirection_airs() {
return direction_airs;
}
}
private volatile boolean updated=false;
public void noticeUpdate() {
updated=true;
}
private void computeShortestPathIfUpdated() {
if(updated) {
computeShortestPath();
updated=false;
}
}
private void computeShortestPath() {
directionLock.lock();
try {
if(netmap.get(router.getLocator().getAddress())==null) {
return;
}
Set<Entry<Inet6Address, RouterInfo>> s=netmap.entrySet();
Map<Inet6Address,Long>airs=new HashMap<>();
List<Inet6Address>rias=new ArrayList<>();
Map<Inet6Address,Set< LinkDirection>>paths=new HashMap<>();
long number=0;
for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = s.iterator(); iterator.hasNext();) {
Entry<Inet6Address, RouterInfo> entry = (Entry<Inet6Address, RouterInfo>) iterator.next();
if(!airs.containsKey(entry.getKey())) {
airs.put(entry.getKey(),number);
rias.add( entry.getKey());
number++;
}
Set<NeighborInfo> ni= entry.getValue().getNeighborAddresses();
for (Iterator<NeighborInfo> iterator2 = ni.iterator(); iterator2.hasNext();) {
NeighborInfo neighborInfo = (NeighborInfo) iterator2.next();
Inet6Address ias2=neighborInfo.getLocator().getAddress();
if(!airs.containsKey(ias2)) {
airs.put(ias2,number);
rias.add( ias2);
number++;
}
Set<LinkDirection>lp1=paths.get(entry.getKey());
if(lp1==null) {
paths.put(entry.getKey(), lp1=new HashSet<>());
}
lp1.add(new LinkDirection(neighborInfo.getLocal(),neighborInfo.getNeighbor(),entry.getKey(), ias2, neighborInfo.getUploadDelay(),neighborInfo.getUploadSpeed(),neighborInfo.getUploadSpeedMax()));
Set<LinkDirection>lp2=paths.get(ias2);
if(lp2==null) {
paths.put(ias2, lp2=new HashSet<>());
}
lp2.add( new LinkDirection(neighborInfo.getNeighbor(),neighborInfo.getLocal(),ias2,entry.getKey() , neighborInfo.getDownloadDelay(),neighborInfo.getDownloadSpeed(),neighborInfo.getDownloadSpeedMax()));
}
}
long[][]pointers=new long[(int) airs.size()][2];
long heappos=0;
long linknumber=0;
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = paths.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();
linknumber+=entry.getValue().size();
}
long[][]heap=new long[(int) (linknumber)][2];
for (long i = 0; i < number; i++) {
long heapindex=0;
pointers[(int) i][0]=heappos;
InetAddress ia=rias.get((int) i);
Set<LinkDirection>lks=paths.get(ia);
if(lks!=null)
for (Iterator<LinkDirection> iterator = lks.iterator(); iterator.hasNext();) {
LinkDirection linkPath=iterator.next();
heap[(int)(heappos+ heapindex)][0]=airs.get(linkPath.getToLocator());
heap[(int) (heappos+heapindex)][1]=linkPath.getWeight();
heapindex++;
}
heappos+=heapindex;
pointers[(int) i][1]=heapindex;
}
algorithm.setGraph(pointers,heap,airs.get(router.getLocator().getAddress()));
algorithm.run();
directions=new NetmapDirections(algorithm.getDirection(), rias, airs);
addresses=airs;
this.paths=paths;
}finally {
directionLock.unlock();
}
//System.out.println(Arrays.toString( algorithm.getDirection()));
}
public static class LinkDirection{
private Inet6AddressGroup fromAddress;
private Inet6AddressGroup toAddress;
private Inet6Address fromLocator;
private Inet6Address toLocator;
private long delay;
private long speed;
public long getSpeed() {
return speed;
}
private long bandwidth;
private long usedBandwidth=0;
public Inet6AddressGroup getFromAddress() {
return fromAddress;
}
public Inet6AddressGroup getToAddress() {
return toAddress;
}
public long getDelay() {
return delay;
}
public long getBandwidth() {
return bandwidth;
}
public LinkDirection(Inet6AddressGroup fromAddress, Inet6AddressGroup toAddress, Inet6Address fromLocator,
Inet6Address toLocator,long delay,long speed, long bandwidth) {
super();
this.fromAddress = fromAddress;
this.toAddress = toAddress;
this.fromLocator = fromLocator;
this.toLocator = toLocator;
this.delay = delay;
this.speed=speed;
this.bandwidth = bandwidth;
}
@Override
public String toString() {
return "LinkDirection [fromAddress=" + fromAddress + ", toAddress=" + toAddress + ", fromLocator="
+ fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", speed=" + speed
+ ", bandwidth=" + bandwidth + ", usedBandwidth=" + usedBandwidth + "]";
}
public Inet6Address getFromLocator() {
return fromLocator;
}
@Override
public int hashCode() {
return Objects.hash(fromAddress, toAddress);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LinkDirection other = (LinkDirection) obj;
return Objects.equals(fromAddress, other.fromAddress) && Objects.equals(toAddress, other.toAddress);
}
public Inet6Address getToLocator() {
return toLocator;
}
public long getWeight() {
return delay;
}
}
private RouterInfo getSelfRouterInfo() {
List<IPv6NetworkLink>links=router.getLinkTabel();
Object[] nls=links.toArray();
RouterInfo ri=new RouterInfo(System.currentTimeMillis());
ri.setLocator(router.getLocator());
for(int i=0;i<nls.length;i++) {
IPv6NetworkLink nl=(IPv6NetworkLink) nls[i];
if((!nl.isLoopBack())&&nl.isUp()) {
List<Neighbor>neis=nl.getNeighborsInfo();
for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
long updelay=10000000000L;
long downdelay=10000000000L;
long uploadspeed=1024L*1024;
long downloadspeed=1024L*1024;
long uploadspeedmax=1024L*1024;
long downloadspeedmax=1024L*1024;
MonitorData md=addresses.getMonitor();
if(md!=null) {
if(md instanceof DelayMonitorData) {
updelay=((DelayMonitorData) md).getOutDelay();
downdelay=((DelayMonitorData) md).getInDelay();
}
if(md instanceof SpeedAndTrafficMonitorData) {
uploadspeed=((SpeedAndTrafficMonitorData) md).getOutSpeed();
downloadspeed=((SpeedAndTrafficMonitorData) md).getInSpeed();
if(md instanceof SpeedAndTrafficMonitorDataImpl) {
SpeedAndTrafficMonitorDataImpl smd=(SpeedAndTrafficMonitorDataImpl) md;
uploadspeedmax=smd.getOutSpeedMax2();
downloadspeedmax=smd.getInSpeedMax2();
}
}
}
ri.getNeighborAddresses().add(new NeighborInfo(nl.getAddressGroup(),addresses.getAddress(),addresses.getLocator(),updelay ,downdelay ,uploadspeed ,downloadspeed,uploadspeedmax ,downloadspeedmax));
}
}
}
//if(debug)
//System.out.println(ri);
return ri;
}
public Map<Inet6Address, Long> getAddresses() {
return addresses;
}
public Map<Inet6Address, Set<LinkDirection>> getPaths() {
return paths;
}
public List<Inet6Address> createSegmentList(Inet6Address dest) {
NetmapDirections directionsx=directions;
if(directionsx==null) {
return null;
}
Long dn=directionsx.getDirection_airs().get(dest);
if(dn==null) {
return null;
}
List<Inet6Address>segments=new ArrayList<>();
while(true) {
long idx=directionsx.getDirection()[(int) dn.longValue()];
if(idx==-1) {
return null;
}
if(idx==dn) {
return segments;
}
segments.add(directionsx.getDirection_rias().get(dn.intValue()));
dn=idx;
}
}
public long getDevicesFound() {
return netmap.size();
}
private static class HotspotAddressTimer{
private long putTime=System.nanoTime();
private long reportTime =System.nanoTime();
public boolean checkTimeOut() {
return System.nanoTime()-putTime>HOTSOPT_TIMEOUT;
}
public boolean checkReportTime() {
long cu = System.nanoTime();
if (cu - reportTime > HOTSOPT_REPORT_INTERVAL) {
reportTime = cu;
return true;
} else {
return false;
}
}
public void refreshTimeout() {
putTime=System.nanoTime();
}
}
private Map<Inet6Address, HotspotAddressTimer> hotspots=new ConcurrentHashMap<>();
public void putHotspotAddress(Inet6Address sourceAddress) {
HotspotAddressTimer hat=hotspots.get(sourceAddress);
if(hat==null) {
hotspots.put(sourceAddress, new HotspotAddressTimer());
}else {
hat.refreshTimeout();
}
}
}
@@ -0,0 +1,137 @@
package org.kne.cloud.network.srv6;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.NetworkPacket;
public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
public static final int RINFO_REQ=0;
public static final int RINFO=1;
private static final int HEADER_CAPACITY = 32;
//public static final ByteArrayPool dataarraypool=new ByteArrayPool(5000, 8192);
protected volatile ByteBuffer header;
protected KLALBRoutingProtocolPacket(ByteBuffer header) {
super();
this.header = header;
}
public KLALBRoutingProtocolPacket(int type) {
super();
header=NetworkPacket.databufferpool_40.borrow();
header.put((byte) type);
}
@Override
public String toString() {
return "KLALBRoutingProtocolPacket [type=" + getType() + "]";
}
public int getType() {
return header.get(0)&0xff;
}
private long sndtime,rcvtime;
protected void writeToChannel(WritableByteChannel dto) throws IOException {
sndtime=System.nanoTime();
dto.write(header.slice(0, (int) getHeaderSize()));
}
@Override
protected boolean needEndPosition() {
return false;
}
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
rcvtime=System.nanoTime();
//System.out.println(this+" "+getHeaderSize());
header.limit((int) getHeaderSize());
while(header.hasRemaining()){
if(din.read(header)==-1) {
throw new EOFException();
}
}
}
protected long getHeaderSize() {
return 1;
}
public long getSndtime() {
return sndtime;
}
public long getRcvtime() {
return rcvtime;
}
public long getLength() {
return getHeaderSize();
}
protected ByteBuffer getHeader() {
return header;
}
public void dispose() {
super.dispose();
/* ByteBuffer headerx=header;
header=null;
KLALBRoutingProtocolPacket.databufferpool_40.back(headerx);*/
}
public static KLALBRoutingProtocolPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
return readKLALBPacketFromChannel(Channels.newChannel(in));
}
public static KLALBRoutingProtocolPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException {
while(true) {
ByteBuffer bb=databufferpool_40.borrow();
bb.limit(1);
while(bb.hasRemaining()){
if(in.read(bb)==-1) {
return null;
}
}
int type=bb.get(0);
bb.limit(bb.capacity());
KLALBRoutingProtocolPacket klp;
switch(type) {
case RINFO_REQ:
klp=new RouterInfoRequestPacket(bb);
klp.readFromChannel(in);
return klp;
case RINFO:
klp=new RouterInfoPacket(bb);
klp.readFromChannel(in);
return klp;
}
//throw new StreamCorruptedException("unknown package type:"+type);
System.err.println("ignore unknown KLALBRoutingProtocolPacket type:"+type);
}
}
public static void writeKLALBPacketToStream(DataOutputStream out,KLALBRoutingProtocolPacket klb) throws IOException {
writeKLALBPacketToChannel(Channels.newChannel(out),klb);
}
public static void writeKLALBPacketToChannel(WritableByteChannel writableByteChannel,KLALBRoutingProtocolPacket klb) throws IOException {
klb.writeToChannel(writableByteChannel);
}
}
@@ -0,0 +1,142 @@
package org.kne.cloud.network.srv6;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.net.Inet6Address;
import java.util.Objects;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
public class NeighborInfo implements Serializable {
@Override
public String toString() {
return "NeighborInfo [local=" + local + ", neighbor=" + neighbor + ", locator=" + locator + ", uploadDelay="
+ uploadDelay + ", downloadDelay=" + downloadDelay + ", uploadSpeed=" + uploadSpeed + ", downloadSpeed="
+ downloadSpeed + ", uploadSpeedMax=" + uploadSpeedMax + ", downloadSpeedMax=" + downloadSpeedMax + "]";
}
/**
*
*/
private static final long serialVersionUID = 1L;
private Inet6AddressGroup local;
private Inet6AddressGroup neighbor;
private Inet6AddressGroup locator;
public NeighborInfo(Inet6AddressGroup local,Inet6AddressGroup neighbor,Inet6AddressGroup locator, long uploadDelay, long downloadDelay, long uploadSpeed, long downloadSpeed, long uploadspeedmax, long downloadspeedmax) {
super();
this.local=local;
this.neighbor = neighbor;
this.locator=locator;
this.uploadDelay = uploadDelay;
this.downloadDelay = downloadDelay;
this.uploadSpeed = uploadSpeed;
this.downloadSpeed = downloadSpeed;
this.uploadSpeedMax=uploadspeedmax;
this.downloadSpeedMax=downloadspeedmax;
}
public NeighborInfo() {
}
private long uploadDelay;
private long downloadDelay;
private long uploadSpeed;
private long downloadSpeed;
private long uploadSpeedMax;
private long downloadSpeedMax;
public Inet6AddressGroup getNeighbor() {
return neighbor;
}
public void setNeighbor(Inet6AddressGroup neighbor) {
this.neighbor = neighbor;
}
public long getUploadDelay() {
return uploadDelay;
}
public void setUploadDelay(long uploadDelay) {
this.uploadDelay = uploadDelay;
}
public long getDownloadDelay() {
return downloadDelay;
}
public void setDownloadDelay(long downloadDelay) {
this.downloadDelay = downloadDelay;
}
public long getUploadSpeed() {
return uploadSpeed;
}
public void setUploadSpeed(long uploadSpeed) {
this.uploadSpeed = uploadSpeed;
}
public long getDownloadSpeed() {
return downloadSpeed;
}
public long getUploadSpeedMax() {
return uploadSpeedMax;
}
public void setUploadSpeedMax(long uploadSpeedMax) {
this.uploadSpeedMax = uploadSpeedMax;
}
public long getDownloadSpeedMax() {
return downloadSpeedMax;
}
public void setDownloadSpeedMax(long downloadSpeedMax) {
this.downloadSpeedMax = downloadSpeedMax;
}
public void setDownloadSpeed(long downloadSpeed) {
this.downloadSpeed = downloadSpeed;
}
public Inet6AddressGroup getLocal() {
return local;
}
public void setLocal(Inet6AddressGroup local) {
this.local = local;
}
public Inet6AddressGroup getLocator() {
return locator;
}
public void setLocator(Inet6AddressGroup locator) {
this.locator = locator;
}
@Override
public int hashCode() {
return Objects.hash(local, locator, neighbor);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NeighborInfo other = (NeighborInfo) obj;
return Objects.equals(local, other.local) && Objects.equals(locator, other.locator)
&& Objects.equals(neighbor, other.neighbor);
}
public void writeToStream(DataOutputStream out) throws IOException {
local.writeToStream(out);
neighbor.writeToStream(out);
locator.writeToStream(out);
out.writeLong(uploadDelay);
out.writeLong(downloadDelay);
out.writeLong(uploadSpeed);
out.writeLong(downloadSpeed);
out.writeLong(uploadSpeedMax);
out.writeLong(downloadSpeedMax);
}
public void readFromStream(DataInputStream in) throws IOException {
local=new Inet6AddressGroup(in);
neighbor=new Inet6AddressGroup( in);
locator=new Inet6AddressGroup(in);
uploadDelay=in.readLong();
downloadDelay=in.readLong();
uploadSpeed=in.readLong();
downloadSpeed=in.readLong();
uploadSpeedMax=in.readLong();
downloadSpeedMax=in.readLong();
}
}
@@ -0,0 +1,20 @@
package org.kne.cloud.network.srv6;
import java.nio.ByteBuffer;
public class PAD1SegmentRoutingTLV extends IPv6SegmentRoutingTLV {
public PAD1SegmentRoutingTLV(int type) {
super(type);
}
public PAD1SegmentRoutingTLV(ByteBuffer klalbHeader) {
super(klalbHeader);
}
@Override
public String toString() {
return "PAD1SegmentRoutingTLV []";
}
}
@@ -0,0 +1,31 @@
package org.kne.cloud.network.srv6;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
public class PADNSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
public PADNSegmentRoutingTLV(ByteBuffer klalbHeader) {
super(klalbHeader);
}
public PADNSegmentRoutingTLV(int type) {
super(type);
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
super.writeToChannel(dto);
}
@Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length);
}
}
@@ -0,0 +1,10 @@
package org.kne.cloud.network.srv6;
import java.io.IOException;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.pcap4j.packet.IpV6Packet;
public interface PacketConsumer {
public void accept(IPv6Packet packx)throws IOException;
}
@@ -0,0 +1,91 @@
package org.kne.cloud.network.srv6;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.pcap4j.packet.IpV6Packet;
import org.pcap4j.packet.TcpPacket;
public class PacketReorder {
public PacketReorder(long sequenceNumber) {
this.sequenceNumber =sequenceNumber;
}
private ReentrantLock rlock=new ReentrantLock();
private List<TcpPacketEntry> tcps=new ArrayList<>();
private volatile long sequenceNumber;
public List<TcpPacketEntry> getTcps() {
return tcps;
}
public long getSequenceNumber() {
return sequenceNumber;
}
public static class TcpPacketEntry{
private IPv6Packet packet;
private long sequenceNumber;
private long addtime=System.nanoTime();
public TcpPacketEntry(IPv6Packet packet, long sequenceNumber) {
super();
this.packet = packet;
this.sequenceNumber = sequenceNumber;
}
public IPv6Packet getPacket() {
return packet;
}
public long getAddtime() {
return addtime;
}
public boolean checkTimeOut() {
return System.nanoTime()-addtime>10000000L;
}
public long getSequenceNumber() {
return sequenceNumber;
}
}
public void sortPackets(IPv6Packet pack,long seq, PacketConsumer packconsumer) throws IOException {
rlock.lock();
try {
//System.out.println("包序号:"+seq);
//System.out.println("当前序号:"+sequenceNumber);
if(seq<sequenceNumber) {
packconsumer.accept(pack);
}else {
loop: do {
for(int i=0;i<tcps.size();i++) {
TcpPacketEntry tpe=tcps.get(i);
if(seq<tpe.getSequenceNumber()) {
tcps.add(i, new TcpPacketEntry(pack, seq));
break loop;
}
}
tcps.add(new TcpPacketEntry(pack, seq));
}while(false);
}
for (Iterator<TcpPacketEntry> iterator = tcps.iterator(); iterator.hasNext();) {
TcpPacketEntry tcpPacketEntry = (TcpPacketEntry) iterator.next();
if(tcpPacketEntry.getSequenceNumber()==sequenceNumber) {
//System.out.println(" 排序:"+tcpPacketEntry.getSequenceNumber());
iterator.remove();
sequenceNumber++;
packconsumer.accept(pack);
}else if(tcpPacketEntry.getSequenceNumber()<sequenceNumber) {
iterator.remove();
packconsumer.accept(pack);
}else if(tcpPacketEntry.checkTimeOut()){
//System.out.println(" 超时:"+tcpPacketEntry.getSequenceNumber());
iterator.remove();
sequenceNumber=tcpPacketEntry.getSequenceNumber()+1;
packconsumer.accept(pack);
}
}
}finally {
rlock.unlock();
}
}
}
@@ -0,0 +1,114 @@
package org.kne.cloud.network.srv6;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.net.Inet6Address;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
public class RouterInfo implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Inet6AddressGroup locator;
public Inet6AddressGroup getLocator() {
return locator;
}
public void setLocator(Inet6AddressGroup locator) {
this.locator = locator;
}
@Override
public int hashCode() {
return Objects.hash(locator, neighborAddresses);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RouterInfo other = (RouterInfo) obj;
return Objects.equals(locator, other.locator) && Objects.equals(neighborAddresses, other.neighborAddresses);
}
private Set<NeighborInfo> neighborAddresses=new HashSet<>();
private long createTime;
public long getCreateTime() {
return createTime;
}
private static final long INFO_UPDATETIME=10000000000L;
private static final long INFO_TIMEOUT=20000000000L;
private long putTime=System.nanoTime();
public boolean checkUpdateTime() {
return System.nanoTime()-putTime>INFO_UPDATETIME;
}
public boolean checkTimeOut() {
return System.nanoTime()-putTime>INFO_TIMEOUT;
}
@Override
public String toString() {
return "RINFO [locator=" + locator + ", neighborAddresses=" + neighborAddresses + ", putTime=" + putTime
+ "]";
}
public Set<NeighborInfo> getNeighborAddresses() {
return neighborAddresses;
}
public RouterInfo( long createTime) {
this.createTime = createTime;
}
public RouterInfo() {
}
public void writeToStream(DataOutputStream out) throws IOException {
locator.writeToStream(out);
out.writeLong(createTime);
out.writeInt(neighborAddresses.size());
for (Iterator iterator = neighborAddresses.iterator(); iterator.hasNext();) {
NeighborInfo neighborInfo = (NeighborInfo) iterator.next();
neighborInfo.writeToStream(out);
}
}
protected void writeToChannel(WritableByteChannel dto) throws IOException {
writeToStream(new DataOutputStream( Channels.newOutputStream(dto)));
}
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
readFromStream(new DataInputStream(Channels.newInputStream(din)));
}
public void readFromStream(DataInputStream in) throws IOException {
locator=new Inet6AddressGroup(in);
createTime=in.readLong();
int size=in.readInt();
neighborAddresses=new HashSet<>(size);
for (int i = 0; i < size; i++) {
NeighborInfo nif=new NeighborInfo();
nif.readFromStream(in);
neighborAddresses.add(nif);
}
}
}
@@ -0,0 +1,74 @@
package org.kne.cloud.network.srv6;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.net.Inet6Address;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Serializable{
public RouterInfoPacket(RouterInfo routerInfo, boolean flood) {
super(RINFO);
getHeader().put(1,(byte) (flood?1:0));
this.rinfo=routerInfo;
}
protected RouterInfoPacket(ByteBuffer bb) {
super(bb);
}
private RouterInfo rinfo;
public boolean isFlood() {
return (getHeader().get(1)&1)==1;
}
public RouterInfo getRinfo() {
return rinfo;
}
@Override
protected long getHeaderSize() {
return super.getHeaderSize()+1;
}
@Override
public long getLength() {
return super.getLength();
}
public void setRinfo(RouterInfo rinfo) {
this.rinfo = rinfo;
}
@Override
public String toString() {
return rinfo.toString();
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
super.writeToChannel(dto);
rinfo.writeToChannel(dto);
}
@Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length);
rinfo=new RouterInfo();
rinfo.readFromChannel(din, length);
}
}
@@ -0,0 +1,20 @@
package org.kne.cloud.network.srv6;
import java.nio.ByteBuffer;
public class RouterInfoRequestPacket extends KLALBRoutingProtocolPacket {
protected RouterInfoRequestPacket(ByteBuffer header) {
super(header);
}
public RouterInfoRequestPacket() {
super(RINFO_REQ);
}
@Override
public String toString() {
return "RINFO_REQ";
}
}
@@ -0,0 +1,12 @@
package org.kne.cloud.network.srv6;
public class SRv6Pad1TLV extends SRv6TLV {
public SRv6Pad1TLV() {
super(SRv6TLV.PAD1, 0, null);
}
public String toString() {
return "PAD1";
}
}
@@ -0,0 +1,12 @@
package org.kne.cloud.network.srv6;
public class SRv6PadNTLV extends SRv6TLV {
public SRv6PadNTLV(int length) {
super(SRv6TLV.PADN, length, null);
}
public String toString() {
return "PADN:"+getLength();
}
}
@@ -0,0 +1,569 @@
package org.kne.cloud.network.srv6;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import org.kne.acclerate.FastLib;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.ipv6.FlowSession;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6DestinationHeader;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6RoutingHeader;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor;
import org.kne.cloud.network.ipv6.RouteItem;
import org.kne.cloud.network.klalb.BindableKLALBPacketConsumer;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
import org.kne.cloud.network.tun.TUNNetworkDevice;
import org.kne.concurrent.HighPerformanceExecutor;
import org.kne.io.KNEChannels;
import org.pcap4j.packet.IcmpV6CommonPacket;
import org.pcap4j.packet.IcmpV6TimeExceededPacket;
import org.pcap4j.packet.IllegalRawDataException;
import org.pcap4j.packet.IpV6ExtRoutingPacket;
import org.pcap4j.packet.IpV6ExtRoutingPacket.IpV6ExtRoutingHeader;
import org.pcap4j.packet.IpV6Packet;
import org.pcap4j.packet.IpV6Packet.Builder;
import org.pcap4j.packet.IpV6RoutingSourceRouteData;
import org.pcap4j.packet.IpV6SimpleFlowLabel;
import org.pcap4j.packet.IpV6SimpleTrafficClass;
import org.pcap4j.packet.Packet;
import org.pcap4j.packet.Packet.Header;
import org.pcap4j.packet.TcpPacket;
import org.pcap4j.packet.TcpPacket.TcpHeader;
import org.pcap4j.packet.UnknownPacket;
import org.pcap4j.packet.namednumber.IcmpV6Code;
import org.pcap4j.packet.namednumber.IcmpV6Type;
import org.pcap4j.packet.namednumber.IpNumber;
import org.pcap4j.packet.namednumber.IpV6RoutingType;
import org.pcap4j.packet.namednumber.IpVersion;
import com.google.gson.internal.Pair;
public class SRv6Router {
private static final boolean debug = false;
public static final int MTU = 9000;
public static final IpV6RoutingType SRH_HEADER = new IpV6RoutingType((byte) 4, "SRH Header");
// private List<NetworkLink>links=new ArrayList<>();
private List<RouteItem> routeTabel = new ArrayList<>();
private List<IPv6NetworkLink> linkTabel = new CopyOnWriteArrayList<>();
public List<IPv6NetworkLink> getLinkTabel() {
return linkTabel;
}
// private ConcurrentHashMap<FlowSession,SlidingWindowInformation>swis=new
// ConcurrentHashMap<>();
private final LoopbackIPv6NetworkLink inLoopBack = new LoopbackIPv6NetworkLink();
//private final LoopbackIPv6NetworkLink inLoopBackSRv6;
private final LoopbackIPv6NetworkLink hostLoopBack ;
private class LoopbackIPv6NetworkLink implements IPv6NetworkLink {
private Inet6AddressGroup loopbackAddress;
public LoopbackIPv6NetworkLink() {
super();
try {
this.loopbackAddress=new Inet6AddressGroup( (Inet6Address) Inet6Address.getByName("::1"),128);
} catch (UnknownHostException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
}
public LoopbackIPv6NetworkLink(Inet6Address loopbackAddress) {
super();
this.loopbackAddress = new Inet6AddressGroup(loopbackAddress,128);
}
public Consumer<IPv6Packet> getReceiveConsumer() {
return receiveConsumer;
}
private Consumer<IPv6Packet> receiveConsumer;
@Override
public void sendPacket(IPv6Packet pack, Inet6Address next) throws IOException {
PacketConsumer pcm;
if ((pcm = protocolNumberRegister.get(pack.getPayload().getProtocolNumber())) != null) {
pcm.accept(pack);
return;
}
}
@Override
public boolean isLoopBack() {
return true;
}
@Override
public List<Neighbor> getNeighborsInfo() {
List<Neighbor> hs = new ArrayList<>();
return hs;
}
@Override
public boolean isCongress(IPv6Packet iPv6Packet) {
return false;
}
@Override
public String getName() {
return "inLoopBack";
}
@Override
public boolean isUp() {
return true;
}
@Override
public boolean canSend(IPv6Packet iPv6Packet) {
//System.out.println(iPv6Packet.getPayload().getProtocolNumber());
return protocolNumberRegister.containsKey(iPv6Packet.getPayload().getProtocolNumber());
}
@Override
public void setReceiveConsumer(Consumer<IPv6Packet> con) {
this.receiveConsumer = con;
}
@Override
public Inet6AddressGroup getAddressGroup() {
return loopbackAddress;
}
};
public List<RouteItem> getRouteTabel() {
return routeTabel;
}
public List<RouteItem> getCurrentRouteTabel() {
return routeTabel0;
}
private Consumer<IPv6Packet> defaultReceive = new Consumer<IPv6Packet>() {
@Override
public void accept(IPv6Packet t) {
HighPerformanceExecutor.defaultExecutor.execute(() -> {
routePacket(t);
t.putTimePassport("routed");
});
}
};
private Consumer<IPv6Packet> srhReceive = new Consumer<IPv6Packet>() {
@Override
public void accept(IPv6Packet t) {
HighPerformanceExecutor.defaultExecutor.execute(() -> {
insertSRHandRoutePacket(t);
});
}
};
public void updateRouteTabel() {
List<RouteItem> routeTabel0x = new ArrayList<>();
for (Iterator<IPv6NetworkLink> iterator = linkTabel.iterator(); iterator.hasNext();) {
IPv6NetworkLink nlink = (IPv6NetworkLink) iterator.next();
if (nlink.isLoopBack()) {
if (nlink instanceof IPv6TUNLoopbackNetworkLink) {
routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128),
nlink.getAddressGroup().getAddress(), nlink, "Direct", 0, 1, null, "D"));
} else {
routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128),
nlink.getAddressGroup().getAddress(), nlink, "Direct", 0, 0, null, "D"));
}
}/*else {
routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128),
nlink.getAddressGroup().getAddress(), inLoopBack, "Direct", 0, 0, null, "D"));
}*/
for (Iterator<Neighbor> iteratorx = nlink.getNeighborsInfo()
.iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
RouteItem ri = new RouteItem(new Inet6AddressGroup(addresses.getAddress().getAddress(), 128), addresses.getAddress().getAddress(),
nlink, "Direct", 0, 128, addresses.getMonitor(), "D");
routeTabel0x.add(ri);
RouteItem ris = new RouteItem(addresses.getLocator(), (Inet6Address) addresses.getLocator().getAddress(),
nlink, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D");
routeTabel0x.add(ris);
}
if (nlink instanceof IPv6TUNLoopbackNetworkLink) {
nlink.setReceiveConsumer(srhReceive);
} else {
nlink.setReceiveConsumer(defaultReceive);
}
}
routeTabel0x.addAll(routeTabel);
Collections.sort(routeTabel0x);
routeTabel0 = routeTabel0x;
}
private Inet6AddressGroup locator;
/*
* public List<NetworkLink> getLinks() { return links; }
*/
public Inet6AddressGroup getLocator() {
return locator;
}
public void setLocator(Inet6AddressGroup locator) {
this.locator = locator;
updateRouteTabel();
}
private ConcurrentHashMap<FlowSession, TCPTransimitAgent> swist = new ConcurrentHashMap<>();
// private AtomicLong qsn=new AtomicLong();
public void insertSRHandRoutePacket(IPv6Packet ipp) {
insertSRH(ipp);
ipp.putTimePassport("SRH inserted");
routePacket(ipp);
ipp.putTimePassport("routed");
}
public void insertSRH(IPv6Packet ipp) {
if (klalbRouteProtol != null) {
List<Inet6Address> segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress());
// System.out.println(segs);
if (segs != null && (!segs.isEmpty())) {
/*
* List<SRv6TLV>tlvs=new ArrayList<>(1); if(ipp.getPayload().getType()==6) {
* SRv6StreamSequenceTLV sers= new SRv6StreamSequenceTLV();
* sers.setSequence(qsn.getAndIncrement()); tlvs.add(sers); }
*/
//IpV6RoutingSRHData srh = new IpV6RoutingSRHData(segs);
IPv6SegmentRoutingHeader irh = new IPv6SegmentRoutingHeader(segs);
ipp.getHeaders().add(irh);
ipp.setDestinationAddress(segs.get(segs.size() - 1));
/*
* if(ipp.getPayload().getType()==6) System.out.println(ipp);
*/
}
}
}
private volatile List<RouteItem> routeTabel0 = new ArrayList<>();
// private ReentrantReadWriteLock routelock=new ReentrantReadWriteLock();
public void routePacket(IPv6Packet iPv6Packet) {
// routelock.readLock().lock();
// try {
// System.out.println("路由表:"+routeTabel0);
StringBuilder dbg=null;
if (debug) {
dbg=new StringBuilder();
}
iPv6Packet.lockAll();
try {
if(iPv6Packet.isSomeDisposed())
return;
int hop = iPv6Packet.getHopLimit();
if (hop > 0) {
// List<RouteItem> mached=new ArrayList<>();
// RouteItem pri=null;
Inet6Address ia = iPv6Packet.getDestinationAddress();
if (debug) {
dbg.append("----------------------------------------\n");
dbg.append("packet:" + iPv6Packet.getSourceAddress().getHostAddress() + "->"
+ iPv6Packet.getDestinationAddress().getHostAddress()+"\n");
}
for (int i = 0; i < routeTabel0.size(); i++) {
RouteItem tri = routeTabel0.get(i);
if (!tri.checkMatch(ia)) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("unmatched.\n");
}
continue;
}
if (!tri.getDestlink().isUp()) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("linkdown.\n");
}
continue;
}
if (tri.getDestlink().isCongress(iPv6Packet)) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("congress.\n");
}
continue;
}
if (!tri.getDestlink().canSend(iPv6Packet)) {
if (debug) {
dbg.append(tri+"\n");
dbg.append("linkrefused.\n");
}
continue;
}
if (debug) {
dbg.append(tri+"\n");
dbg.append("matched.\n");
}
processPacket(iPv6Packet, tri);
return;
/*
* if(pri==null||pri.equals(tri)) { mached.add(tri); pri=tri; }else { break; }
*/
}
if (debug) {
dbg.append("miss.\n");
}
if (iPv6Packet.isEnableECN()) {
iPv6Packet.markCE();
for (int i = 0; i < routeTabel0.size(); i++) {
RouteItem tri = routeTabel0.get(i);
if (tri.checkMatch(ia)) {
if (!tri.getDestlink().isUp()) {
continue;
}
processPacket(iPv6Packet, tri);
return;
/*
* if(pri==null||pri.equals(tri)) { mached.add(tri); pri=tri; }else { break; }
*/
}
}
}
if (debug)
dbg.append("congress\n");
// System.out.println(ia.getAddress()+" match "+ri);
/*
* for (Iterator iterator = mached.iterator(); iterator.hasNext();) { RouteItem
* routeItem = (RouteItem) iterator.next();
* if(routeItem.getDestlink().isCongress()) {
*
* }else { processPacket(iPv6Packet,pri); break; } }
*/
// else
// System.out.println("路由失败:"+iPv6Packet);
} else {
IcmpV6TimeExceededPacket.Builder icmpte = new IcmpV6TimeExceededPacket.Builder();
ByteBuffer IPv6data = NetworkPacket.databufferpool_65535.borrow();
iPv6Packet.writeToChannel(KNEChannels.newWritableChannel(IPv6data));
byte[] raw = new byte[IPv6data.remaining()];
IPv6data.get(0, raw);
icmpte.payload(IpV6Packet.newPacket(raw, 0, raw.length));
IcmpV6CommonPacket.Builder icbd = new IcmpV6CommonPacket.Builder();
icbd.type(IcmpV6Type.TIME_EXCEEDED);
icbd.code(IcmpV6Code.HOP_LIMIT_EXCEEDED);
icbd.srcAddr(locator.getAddress());
icbd.dstAddr(iPv6Packet.getSourceAddress());
icbd.correctChecksumAtBuild(true);
icbd.payloadBuilder(icmpte);
IPv6Packet icmpv = new IPv6Packet();
icmpv.setSourceAddress(locator.getAddress());
icmpv.setDestinationAddress(iPv6Packet.getSourceAddress());
icmpv.setTrafficClass(iPv6Packet.getTrafficClass());
icmpv.setVersion(6);
icmpv.setFlowLabel(0);
icmpv.setHopLimit(255);
IPv6Payload ipl = new IPv6Payload(IpNumber.ICMPV6.value());
ipl.getData().put(icbd.build().getRawData());
ipl.getData().flip();
icmpv.setPayload(ipl);
insertSRHandRoutePacket(icmpv);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(debug) {
System.out.println(dbg.toString());
}
iPv6Packet.unlockAll();
}
// }finally {
// routelock.readLock().unlock();
// }
}
private void processPacket(IPv6Packet iPv6Packet, RouteItem ri) throws IllegalRawDataException, IOException {
int hop = iPv6Packet.getHopLimit();
if (ri.getDestlink().isLoopBack()) {
IPv6SegmentRoutingHeader srhh = getSRHHeaderFromPacket(iPv6Packet);
if (srhh != null) {
processSRv6Packet(iPv6Packet, ri, srhh);
} else {
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
}
} else {
hop--;
// System.out.println(ipp.getHeader().getSrcAddr()+"->"+ipp.getHeader().getDstAddr()+"
// "+(hop+1)+"->"+hop);
if (hop > 0) {
iPv6Packet.setHopLimit(hop);
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
} else {
IcmpV6TimeExceededPacket.Builder icmpte = new IcmpV6TimeExceededPacket.Builder();
ByteBuffer IPv6data = NetworkPacket.databufferpool_65535.borrow();
iPv6Packet.writeToChannel(KNEChannels.newWritableChannel(IPv6data));
byte[] raw = new byte[IPv6data.remaining()];
IPv6data.get(0, raw);
icmpte.payload(IpV6Packet.newPacket(raw, 0, raw.length));
IcmpV6CommonPacket.Builder icbd = new IcmpV6CommonPacket.Builder();
icbd.type(IcmpV6Type.TIME_EXCEEDED);
icbd.code(IcmpV6Code.HOP_LIMIT_EXCEEDED);
icbd.srcAddr(locator.getAddress());
icbd.dstAddr(iPv6Packet.getSourceAddress());
icbd.correctChecksumAtBuild(true);
icbd.payloadBuilder(icmpte);
IPv6Packet icmpv = new IPv6Packet();
icmpv.setSourceAddress(locator.getAddress());
icmpv.setDestinationAddress(iPv6Packet.getSourceAddress());
icmpv.setTrafficClass(iPv6Packet.getTrafficClass());
icmpv.setVersion(6);
icmpv.setFlowLabel(0);
icmpv.setHopLimit(255);
IPv6Payload ipl = new IPv6Payload(IpNumber.ICMPV6.value());
ipl.getData().put(icbd.build().getRawData());
ipl.getData().flip();
icmpv.setPayload(ipl);
insertSRHandRoutePacket(icmpv);
}
}
}
private void processSRv6Packet(IPv6Packet iPv6Packet, RouteItem ri, IPv6SegmentRoutingHeader srhh)
throws IllegalRawDataException, IOException {
/*byte[] srd = new byte[(int) (srhh.getLength() - 4)];
srhh.getData().get(4, srd);
IpV6RoutingSRHData srh = IpV6RoutingSRHData.newInstance(srd, 0, srd.length);*/
if (srhh.getSegmentsLeft() <= 0) {
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
} else {
int newSL = srhh.getSegmentsLeft() - 1;
srhh.setSegmentsLeft(newSL);
iPv6Packet.setDestinationAddress(srhh.getAddresses().get(newSL));
klalbRouteProtol.putHotspotAddress(iPv6Packet.getSourceAddress());
routePacket(iPv6Packet);
}
}
private IPv6SegmentRoutingHeader getSRHHeaderFromPacket(IPv6Packet iPv6Packet) {
IPv6SegmentRoutingHeader srhh = null;
List<IPv6ExtHeader> exhs = iPv6Packet.getHeaders();
for (int j = 0; j < exhs.size(); j++) {
IPv6ExtHeader exh = exhs.get(j);
if (exh instanceof IPv6SegmentRoutingHeader) {
if (((IPv6SegmentRoutingHeader) exh).getRoutingType() == 4) {
srhh = (IPv6SegmentRoutingHeader) exh;
break;
}
}
}
return srhh;
}
public SRv6Router(Inet6AddressGroup hostAddress) {
super();
this.locator = hostAddress;
//this.inLoopBackSRv6=new LoopbackIPv6NetworkLink(locator.getAddress());
this.hostLoopBack= new LoopbackIPv6NetworkLink(hostAddress.getAddress());
linkTabel.add(inLoopBack);
//linkTabel.add(inLoopBackSRv6);
linkTabel.add(hostLoopBack);
}
/*public SRv6Router() {
super();
linkTabel.add(inLoopBack);
}*/
private KLALBRoutingProtocol klalbRouteProtol = null;
public void runKLALBRouteProtocol() {
if (klalbRouteProtol != null)
throw new IllegalStateException("KLALB routing protocol is already running!");
klalbRouteProtol = new KLALBRoutingProtocol(this);
klalbRouteProtol.start();
}
public KLALBRoutingProtocol getKlalbRouteProtol() {
return klalbRouteProtol;
}
private Map<Integer, PacketConsumer> protocolNumberRegister = new ConcurrentHashMap<>();
public Map<Integer, PacketConsumer> getProtocolNumberRegister() {
return protocolNumberRegister;
}
public void putProtocolNumberPacketAndInsertSRH(IPv6Packet pkt) {
// inLoopBack.getReceiveConsumer().accept(pkt);
srhReceive.accept(pkt);
}
public void putProtocolNumberPacket(IPv6Packet pkt) {
// inLoopBack.getReceiveConsumer().accept(pkt);
defaultReceive.accept(pkt);
}
}
@@ -0,0 +1,42 @@
package org.kne.cloud.network.srv6;
import java.io.DataInputStream;
import java.io.DataOutputStream;
public class SRv6StreamSequenceTLV extends SRv6TLV {
public SRv6StreamSequenceTLV() {
super(SEQS, 22, new byte[22]);
}
public SRv6StreamSequenceTLV(int lengthQTLV, byte[] rawQTLV) {
super(SEQS, lengthQTLV, rawQTLV);
}
public int getReserved(){
return getValue()[0]<<8|getValue()[1];
}
public void setReserved(int reserved) {
getValue()[0]=(byte) (reserved>>>8);
getValue()[1]=(byte) reserved;
}
public long getSequence() {
return (((long)getValue()[6] << 56) +
((long)(getValue()[7] & 255) << 48) +
((long)(getValue()[8] & 255) << 40) +
((long)(getValue()[9] & 255) << 32) +
((long)(getValue()[10] & 255) << 24) +
((getValue()[11] & 255) << 16) +
((getValue()[12] & 255) << 8) +
((getValue()[13] & 255) << 0));
}
public void setSequence(long sequence) {
getValue()[6] = (byte)(sequence >>> 56);
getValue()[7] = (byte)(sequence >>> 48);
getValue()[8] = (byte)(sequence >>> 40);
getValue()[9] = (byte)(sequence >>> 32);
getValue()[10] = (byte)(sequence >>> 24);
getValue()[11] = (byte)(sequence >>> 16);
getValue()[12] = (byte)(sequence >>> 8);
getValue()[13] = (byte)(sequence >>> 0);
}
}
@@ -0,0 +1,41 @@
package org.kne.cloud.network.srv6;
import java.nio.ByteBuffer;
import java.util.Arrays;
public class SRv6TLV {
public static final int PAD1=0;
public static final int PADN=4;
public static final int HMAC=5;
public static final int SEQS=7;
private int type;
private int length;
private byte[]value;
public SRv6TLV(int type, int length, byte[] value) {
super();
this.type = type;
this.length = length;
this.value = value;
}
@Override
public String toString() {
return "SRv6TLV [type=" + type + ", length=" + length + ", value=" + Arrays.toString(value) + "]";
}
public int getType() {
return type;
}
public int getLength() {
return length;
}
public byte[] getValue() {
return value;
}
public int getTotalLength() {
if(type==PAD1) {
return 1;
}
return 2+length;
}
}

Some files were not shown because too many files have changed in this diff Show More