diff --git a/.classpath b/.classpath index a73e078..60354f2 100644 --- a/.classpath +++ b/.classpath @@ -1,12 +1,6 @@ - - - - - - @@ -27,5 +21,13 @@ + + + + + + + + diff --git a/klalb-config.json b/klalb-config.json index 52f6b3e..ad0c519 100644 --- a/klalb-config.json +++ b/klalb-config.json @@ -1,7 +1,7 @@ [ { "language": "ZH_CN", - "nogui": true, + "nogui": false, "VirtualAddress": "2486:1:0:0:0:0:0:8888", "VirtualASN": 2142606939373348329, "DNS": [ @@ -37,13 +37,14 @@ "{UDP}ntp.ntsc.ac.cn:123", "{UDP}us.ntp.org.cn:123" ], - "denyLineTableQuery": false, - "denyLineTableBroadcast": false, + "denyLineTableQuery": true, + "denyLineTableBroadcast": true, "congestionAlgorithm": "BBR", - "delayUpperBound": 1.506, - "delayLowerBound": 1.25, + "burstLimit": 1.5, + "delayUpperBound": 1.3, + "delayLowerBound": 1.3, "nagleDelayTime": 1000000, - "linkNagleDelayTime": 1000000, + "linkNagleDelayTime": 0, "linkConnectionsCount": 1, "TUNName": "KLALB_SRv6", "NetworkInterfaceExcepts": [], diff --git a/lib/KNEOptimize.jar b/lib/KNEOptimize.jar index ca0b6ec..a31c251 100644 Binary files a/lib/KNEOptimize.jar and b/lib/KNEOptimize.jar differ diff --git a/lib/KNElib1.0.jar b/lib/KNElib1.0.jar index eb9fac1..2d38b26 100644 Binary files a/lib/KNElib1.0.jar and b/lib/KNElib1.0.jar differ diff --git a/src/klalb_en_US.properties b/src/klalb_en_US.properties index cb4314e..112f698 100644 --- a/src/klalb_en_US.properties +++ b/src/klalb_en_US.properties @@ -55,7 +55,7 @@ delay=Delay virtualnetsettings=Virtual network settings tunnelnetsettings=Tunnel network settings linksettings=Link settings -klalbperf=KLALB-perf Speedtest tool +klalbperf=KLALB-perf Speedtest speedtest=Network speed test starttest=Start test testreport=Test report @@ -91,5 +91,17 @@ tunname=Virtual network device name dashboard=Dashboard backplanedelay=Backplane delay backplanepps=Backplane PPS +backplaneecnrate=Backplane ECN rate +backplanelossrate=Backplane Loss rate uisettings=UI settings -nogui=No GUI mode \ No newline at end of file +nogui=No GUI mode +bufferusagemonitor=Buffer usage monitor +buffer=Buffer +usedbuffer=Used buffer +maxbuffer=Max buffer +queueused=Used queue +downloadbasedelay=Download Base +uploadbasedelay=Upload Base +burstlimit=Burst limit +performancesettings=Performance settings +performancestrategy=Performance strategy \ No newline at end of file diff --git a/src/klalb_zh_CN.properties b/src/klalb_zh_CN.properties index 7e6e745..2df6772 100644 --- a/src/klalb_zh_CN.properties +++ b/src/klalb_zh_CN.properties @@ -55,7 +55,7 @@ delay=延迟 virtualnetsettings=虚拟网络设置 tunnelnetsettings=隧道网络设置 linksettings=链路设置 -klalbperf=KLALB-perf测速工具 +klalbperf=KLALB-perf网速测试 speedtest=网速测试 starttest=开始测试 testreport=测速报告 @@ -91,5 +91,17 @@ tunname=虚拟网卡名称 dashboard=仪表盘 backplanedelay=背板处理延迟 backplanepps=背板包转发率 +backplaneecnrate=背板ECN率 +backplanelossrate=背板丢包率 uisettings=UI设置 -nogui=无GUI模式 \ No newline at end of file +nogui=无GUI模式 +bufferusagemonitor=缓冲区监视器 +buffer=缓冲区 +usedbuffer=已用缓冲区 +maxbuffer=最大缓冲区 +queueused=已用队列 +downloadbasedelay=下载延迟基线 +uploadbasedelay=上传延迟基线 +burstlimit=突发限制 +performancesettings=性能设置 +performancestrategy=性能策略 \ No newline at end of file diff --git a/src/org/kne/cloud/network/BufferedChannel.java b/src/org/kne/cloud/network/BufferedChannel.java index b9440fd..71d9c5f 100644 --- a/src/org/kne/cloud/network/BufferedChannel.java +++ b/src/org/kne/cloud/network/BufferedChannel.java @@ -15,10 +15,8 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel private final ByteBuffer readBuffer; private final ByteBuffer writeBuffer; - private final ReentrantLock readLock = new ReentrantLock(); - private final ReentrantLock writeLock = new ReentrantLock(); - private final AtomicBoolean closed = new AtomicBoolean(false); + // private final AtomicBoolean closed = new AtomicBoolean(false); private final AtomicBoolean inputShutdown = new AtomicBoolean(false); private final AtomicBoolean outputShutdown = new AtomicBoolean(false); @@ -43,12 +41,11 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel @Override public int read(ByteBuffer dst) throws IOException { - if (closed.get() || inputShutdown.get()) { + if ( inputShutdown.get()) { throw new ClosedChannelException(); } - readLock.lock(); - try { + // 检查底层通道是否仍然打开 if (inputChannel != null && !inputChannel.isOpen()) { inputShutdown.set(true); @@ -102,10 +99,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel } return totalRead; - - } finally { - readLock.unlock(); - } + } /** @@ -126,9 +120,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel @Override public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { - if (closed.get() || inputShutdown.get()) { - throw new ClosedChannelException(); - } + long totalRead = 0; for (int i = offset; i < offset + length; i++) { @@ -150,12 +142,9 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel @Override public int write(ByteBuffer src) throws IOException { - if (closed.get() || outputShutdown.get()) { - throw new ClosedChannelException(); - } + - writeLock.lock(); - try { + // 检查底层通道是否仍然打开 if (outputChannel != null && !outputChannel.isOpen()) { outputShutdown.set(true); @@ -188,9 +177,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel } return totalWritten; - } finally { - writeLock.unlock(); - } + } @Override @@ -200,9 +187,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel @Override public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { - if (closed.get() || outputShutdown.get()) { - throw new ClosedChannelException(); - } + long totalWritten = 0; for (int i = offset; i < offset + length; i++) { @@ -222,23 +207,18 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel * 安全的刷新方法 */ public void flush() throws IOException { - if (closed.get()) { - throw new ClosedChannelException(); - } + if (outputChannel == null || outputShutdown.get()) { return; } - writeLock.lock(); try { flushInternal(); } catch (IOException e) { outputShutdown.set(true); throw e; - } finally { - writeLock.unlock(); - } + } } /** @@ -274,16 +254,13 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel */ @Override public void close() throws IOException { - if (!closed.compareAndSet(false, true)) { - return; // 已经关闭 - } + IOException exception = null; // 先刷新输出缓冲区 if (outputChannel != null && !outputShutdown.get()) { - writeLock.lock(); - try { + if (writeBuffer.position() > 0) { try { flushInternal(); @@ -291,9 +268,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel exception = e; } } - } finally { - writeLock.unlock(); - } + } // 关闭底层通道 @@ -322,20 +297,14 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel } // 清理缓冲区状态 - readLock.lock(); - try { + readBuffer.clear(); readBuffer.limit(0); // 标记为已清空 - } finally { - readLock.unlock(); - } - writeLock.lock(); - try { + + writeBuffer.clear(); - } finally { - writeLock.unlock(); - } + // 设置关闭状态 inputShutdown.set(true); @@ -351,13 +320,10 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel */ public void shutdownInput() throws IOException { inputShutdown.set(true); - readLock.lock(); - try { + readBuffer.clear(); readBuffer.limit(0); - } finally { - readLock.unlock(); - } + if (inputChannel instanceof SocketChannel) { ((SocketChannel) inputChannel).shutdownInput(); @@ -366,14 +332,11 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel public void shutdownOutput() throws IOException { outputShutdown.set(true); - writeLock.lock(); - try { + if (writeBuffer.position() > 0) { flushInternal(); } - } finally { - writeLock.unlock(); - } + if (outputChannel instanceof SocketChannel) { ((SocketChannel) outputChannel).shutdownOutput(); @@ -382,7 +345,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel @Override public boolean isOpen() { - return !closed.get() && + return (inputChannel == null || inputChannel.isOpen()) && (outputChannel == null || outputChannel.isOpen()); } @@ -391,51 +354,39 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel * 检查是否还有可读数据(包括缓冲区中的) */ public boolean hasRemaining() throws IOException { - if (closed.get() || inputShutdown.get()) { + if ( inputShutdown.get()) { return false; } - readLock.lock(); - try { + return readBuffer.hasRemaining() || (inputChannel != null && inputChannel.isOpen()); - } finally { - readLock.unlock(); - } + } /** * 获取缓冲区状态信息(用于调试) */ public String getBufferState() { - readLock.lock(); - writeLock.lock(); - try { + return String.format( "ReadBuffer[pos=%d, lim=%d, cap=%d], WriteBuffer[pos=%d, lim=%d, cap=%d], " + "closed=%b, inputShutdown=%b, outputShutdown=%b", readBuffer.position(), readBuffer.limit(), readBuffer.capacity(), - writeBuffer.position(), writeBuffer.limit(), writeBuffer.capacity(), - closed.get(), inputShutdown.get(), outputShutdown.get() + writeBuffer.position(), writeBuffer.limit(), writeBuffer.capacity(), inputShutdown.get(), outputShutdown.get() ); - } finally { - writeLock.unlock(); - readLock.unlock(); - } + } // 其他方法保持不变... public int available() throws IOException { - if (closed.get() || inputShutdown.get()) { + if ( inputShutdown.get()) { return 0; } - readLock.lock(); - try { + return readBuffer.remaining(); - } finally { - readLock.unlock(); - } + } public long skip(long n) throws IOException { diff --git a/src/org/kne/cloud/network/ByteBufferAllocator.java b/src/org/kne/cloud/network/ByteBufferAllocator.java index 739246c..6a0e7c2 100644 --- a/src/org/kne/cloud/network/ByteBufferAllocator.java +++ b/src/org/kne/cloud/network/ByteBufferAllocator.java @@ -1,26 +1,10 @@ package org.kne.cloud.network; import java.lang.foreign.Arena; -import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentAllocator; -import java.lang.ref.Cleaner; -import java.lang.ref.PhantomReference; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.nio.BufferOverflowException; import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicReference; -import org.kne.debug.TimeDebugger; import org.kne.membandboost.MembandBoost; -import jdk.internal.misc.Unsafe; public class ByteBufferAllocator { public ByteBufferAllocator(boolean isDirect) { @@ -43,31 +27,8 @@ public class ByteBufferAllocator { throw new InternalError(); return buf; } - private static jdk.internal.misc.Unsafe usf; - private static Method meth; - static { - Class name; - try { - name = Class.forName("jdk.internal.misc.Unsafe"); - Field field = name.getDeclaredField("theUnsafe"); - field.setAccessible(true); - usf= (Unsafe) field.get(null); - meth=name.getMethod("allocateUninitializedArray", Class.class,int.class); - - } catch (java.lang.reflect.InaccessibleObjectException e) { - e.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } - } - public static byte[] allocateUninitializedArray(int capacity) { - if(usf!=null) { - return (byte[]) usf.allocateUninitializedArray(byte.class, capacity); - }else { - return new byte[capacity]; - } - } - + + public static ByteBuffer allocateHeap(int capacity) { /*if(capacity<=2048) { return MembandBoost.allocateUninitializedHeapBufferBlocked(capacity); @@ -75,10 +36,6 @@ public class ByteBufferAllocator { return MembandBoost.allocateUninitializedHeapBuffer(capacity); //} } - public static ByteBuffer allocateHeap0(int capacity) { - return ByteBuffer.wrap((byte[])allocateUninitializedArray(capacity)) ; - } - } diff --git a/src/org/kne/cloud/network/DatagramServerSocket.java b/src/org/kne/cloud/network/DatagramServerSocket.java index f2e999a..670dfce 100644 --- a/src/org/kne/cloud/network/DatagramServerSocket.java +++ b/src/org/kne/cloud/network/DatagramServerSocket.java @@ -1,34 +1,24 @@ package org.kne.cloud.network; import java.io.IOException; -import java.io.InterruptedIOException; import java.net.DatagramPacket; import java.net.DatagramSocket; -import java.net.DatagramSocketImpl; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; -import java.net.ServerSocket; import java.net.SocketAddress; import java.net.SocketException; import java.net.SocketTimeoutException; -import java.util.Collections; import java.util.Enumeration; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; -import java.util.Vector; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Flow.Subscriber; import java.util.concurrent.locks.LockSupport; -import org.kne.cloud.network.klalb.DATATPacket; -import org.kne.cloud.network.klalb.KLALBRemoteLine; - public class DatagramServerSocket implements java.io.Closeable{ public static final ByteArrayPool dataarraypool=new ByteArrayPool(100, 65535); @@ -93,10 +83,7 @@ public class DatagramServerSocket implements java.io.Closeable{ if (backlog < 1) backlog = 50; - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) - security.checkListen(epoint.getPort()); + synchronized (stateLock) { if (closed) diff --git a/src/org/kne/cloud/network/DirectBufferedArena.java b/src/org/kne/cloud/network/DirectBufferedArena.java deleted file mode 100644 index 9fb0fe2..0000000 --- a/src/org/kne/cloud/network/DirectBufferedArena.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.kne.cloud.network; - -import java.lang.foreign.Arena; -import java.lang.foreign.MemorySegment; -import java.lang.foreign.MemorySegment.Scope; -import java.lang.ref.PhantomReference; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.nio.ByteBuffer; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.ReentrantLock; - -public class DirectBufferedArena implements Arena{ - private static long blockSize=1024*1024L; - private volatile PreAlloc buffer; - public static long getBlockSize() { - return blockSize; - } - - - - public static void setBlockSize(long blockSizex) { - blockSize = blockSizex; - } - - - - - private class PreAlloc{ - private MemorySegment segment; - private AtomicLong pos=new AtomicLong(0); - private AtomicLong refs=new AtomicLong(0); - public MemorySegment getSegment() { - return segment; - } - public AtomicLong getPos() { - return pos; - } - public PreAlloc(MemorySegment segment) { - super(); - this.segment = segment; - } - public long byteSize() { - return segment.byteSize(); - } - public AtomicLong getRefs() { - return refs; - } - - } - - private void allocateNew(long blockSize2) { - MemorySegment raw=MemorySegment.ofArray(ByteBufferAllocator.allocateUninitializedArray((int) blockSize2)); - buffer=new PreAlloc(raw); - - } - - - public DirectBufferedArena() { - super(); - allocateNew(blockSize); - } - - @Override - public MemorySegment allocate(long byteSize, long byteAlignment) { - if(byteSize>blockSize) - throw new IndexOutOfBoundsException("byteSize can't large than buffer block"); - long pos; - PreAlloc bufferx; - do{ - bufferx=this.buffer; - pos=bufferx.getPos().getAndAdd(byteSize); - if(pos+byteSize>bufferx.byteSize()) { - allocateNew(blockSize); - }else { - break; - } - }while(true); - bufferx.getRefs().incrementAndGet(); - MemorySegment sliced=bufferx.getSegment().asSlice(pos, byteSize); - return sliced; - - } - - @Override - public Scope scope() { - return null; - } - - @Override - public void close() { - } - public static DirectBufferedArena ofBuffered() { - return new DirectBufferedArena(); - } - -} diff --git a/src/org/kne/cloud/network/HeapBufferedArena.java b/src/org/kne/cloud/network/HeapBufferedArena.java deleted file mode 100644 index c532219..0000000 --- a/src/org/kne/cloud/network/HeapBufferedArena.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.kne.cloud.network; - -import java.lang.foreign.Arena; -import java.lang.foreign.MemorySegment; -import java.lang.foreign.MemorySegment.Scope; -import java.lang.ref.PhantomReference; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.nio.ByteBuffer; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.ReentrantLock; - -public class HeapBufferedArena implements Arena{ - private static long blockSize=32768L; - private MemorySegment segment; - private long pos=0; - - - - - public static void setBlockSize(long blockSizex) { - blockSize = blockSizex; - } - - - - - private void allocateNew(long blockSize2) { - segment=MemorySegment.ofArray(ByteBufferAllocator.allocateUninitializedArray((int) blockSize2)); - pos=0; - } - - - public HeapBufferedArena() { - super(); - allocateNew(blockSize); - } - - @Override - public MemorySegment allocate(long byteSize, long byteAlignment) { - if(byteSize>blockSize) - return MemorySegment.ofArray(ByteBufferAllocator.allocateUninitializedArray((int) byteSize)); - do{ - long newpos=pos+byteSize; - if(newpos>blockSize) { - allocateNew(blockSize); - }else { - MemorySegment ms=segment.asSlice(pos, byteSize); - pos=newpos; - return ms; - } - }while(true); - - } - - @Override - public Scope scope() { - return null; - } - - @Override - public void close() { - } - public static HeapBufferedArena ofBuffered() { - return new HeapBufferedArena(); - } - -} diff --git a/src/org/kne/cloud/network/IPMulticastDiscovery.java b/src/org/kne/cloud/network/IPMulticastDiscovery.java index 0b491bf..f540110 100644 --- a/src/org/kne/cloud/network/IPMulticastDiscovery.java +++ b/src/org/kne/cloud/network/IPMulticastDiscovery.java @@ -15,16 +15,14 @@ import java.net.NetworkInterface; import java.net.NoRouteToHostException; import java.net.SocketException; import java.net.UnknownHostException; -import java.time.Duration; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Set; import java.util.UUID; import java.util.function.Consumer; -public class IPMulticastDiscovery extends Thread implements Closeable, AutoCloseable { +public class IPMulticastDiscovery implements Closeable, AutoCloseable { private static final boolean debug=false; private MulticastSocket soc; @@ -79,9 +77,7 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose this.timeInterval=timeInterval; } - @Override - public void run() { - Thread.currentThread().setName("线路发现线程"); + public void start() { ThreadTool.makeVDaemonThreadIfSupport("线路通知线程", () -> { try { @@ -143,6 +139,7 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose }).start(); + ThreadTool.makeVDaemonThreadIfSupport("线路发现线程",()->{ try { loop:while (!closed) { try { @@ -199,6 +196,7 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose e.printStackTrace(); } } + }); } @Override diff --git a/src/org/kne/cloud/network/MemorySegmentPool.java b/src/org/kne/cloud/network/MemorySegmentPool.java deleted file mode 100644 index 51ff5ff..0000000 --- a/src/org/kne/cloud/network/MemorySegmentPool.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.kne.cloud.network; - -import java.lang.foreign.Arena; -import java.lang.foreign.MemorySegment; -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 MemorySegmentPool { - private AtomicReferenceArray< MemorySegment> rec; - private volatile AtomicInteger pos=new AtomicInteger( 0); - //private Lock lock=new SpinLock(); - - private int maxcount; - private long length; - private int mcj; - private boolean direct; - public MemorySegmentPool(int maxcount, long length,boolean direct) { - super(); - this.maxcount = maxcount; - this.length = length; - this.direct=direct; - rec=new AtomicReferenceArray(maxcount); - mcj= rec.length()-1; - } - public MemorySegmentPool(int maxcount, int length) { - this(maxcount, length, true); - } - public void back(MemorySegment b) { - if(b.byteSize()!=length) - throw new IllegalArgumentException("wrong length"); - - - if(pos.get()<=mcj) { - int d=pos.getAndIncrement(); - if(d>mcj) - d=mcj; - if(d<0) - d=0; - rec.compareAndSet(d,null,b); - } - - } - public MemorySegment borrow() { - MemorySegment b=null; - - if(pos.get()>0) { - int d=pos.decrementAndGet(); - if(d>mcj) - d=mcj; - if(d<0) - d=0; - b=rec.getAndSet(d,null); - } - - if(b==null) { - //ByteBufferAllocator.t.interrupt(); - if(direct) { - b=((jdk.internal.foreign.ArenaImpl)Arena.ofAuto()).allocateNoInit(length,1); - System.out.println(length); - }else { - b=MemorySegment.ofArray(new byte[(int) length]); - } - } - return b; - } - public int getMaxCount() { - return maxcount; - } - public long getLength() { - return length; - } - -} diff --git a/src/org/kne/cloud/network/NetworkPacket.java b/src/org/kne/cloud/network/NetworkPacket.java index d0aef06..0815c0e 100644 --- a/src/org/kne/cloud/network/NetworkPacket.java +++ b/src/org/kne/cloud/network/NetworkPacket.java @@ -3,53 +3,12 @@ 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.KLALBPacket; -import org.kne.debug.TimeDebugger; public abstract class NetworkPacket{ - private static final boolean debugPassport=false; public static final ByteBufferAllocator bufferAllocator=new ByteBufferAllocator(true); - //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 final TimeDebugger passport; - { - if(debugPassport) { - passport=new TimeDebugger(); - passport.putTime(getClass().getSimpleName()+ "_create"); - }else { - passport=null; - } - } - - public final void putTimePassport(String label) { - if(passport!=null) { - passport.putTime(label); - } - } - - public final void printPassport() { - if(passport!=null) { - passport.printWithTimeFilter(100000000L); - } - - } - - - public abstract long getTotalLength(); diff --git a/src/org/kne/cloud/network/ProtocolDetectorServerSocket.java b/src/org/kne/cloud/network/ProtocolDetectorServerSocket.java index 4e0b766..af60406 100644 --- a/src/org/kne/cloud/network/ProtocolDetectorServerSocket.java +++ b/src/org/kne/cloud/network/ProtocolDetectorServerSocket.java @@ -29,7 +29,7 @@ public class ProtocolDetectorServerSocket extends FilterServerSocket { public ProtocolDetectorSocket accept() throws IOException { ProtocolDetectorSocket s=(ProtocolDetectorSocket) super.accept(); int sot=s.getSoTimeout(); - s.setSoTimeout(1000); + s.setSoTimeout(200); InputStream ins=s.getInputStream(); ProtocolStack psd= protocolDetector.detect(ins); s.setSoTimeout(sot); diff --git a/src/org/kne/cloud/network/SocketChannelListener.java b/src/org/kne/cloud/network/SocketChannelListener.java index 892d81b..8fb3702 100644 --- a/src/org/kne/cloud/network/SocketChannelListener.java +++ b/src/org/kne/cloud/network/SocketChannelListener.java @@ -2,17 +2,12 @@ package org.kne.cloud.network; import java.io.Closeable; import java.io.IOException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.function.Consumer; -import javax.net.ServerSocketFactory; - public class SocketChannelListener implements Closeable,AutoCloseable{ protected ServerSocketChannel serverSocketChannel; public ServerSocketChannel getServerSocketChannel() { @@ -28,7 +23,7 @@ public class SocketChannelListener implements Closeable,AutoCloseable{ while(flag){ try { SocketChannel soce=serverSocketChannel.accept(); - ThreadTool.makePThreadIfSupport("端口请求处理线程",()->{ + ThreadTool.makeVThreadIfSupport("端口请求处理线程",()->{ if(con!=null) { try { con.accept(soce); diff --git a/src/org/kne/cloud/network/SocketListener.java b/src/org/kne/cloud/network/SocketListener.java index be7298d..fd2213d 100644 --- a/src/org/kne/cloud/network/SocketListener.java +++ b/src/org/kne/cloud/network/SocketListener.java @@ -26,7 +26,7 @@ public class SocketListener implements Closeable,AutoCloseable{ while(flag){ try { Socket soce=serverSocket.accept(); - ThreadTool.makePThreadIfSupport("端口监听线程",()->{ + ThreadTool.makeVThreadIfSupport("端口监听线程",()->{ if(con!=null) { try { con.accept(soce); @@ -66,7 +66,7 @@ public class SocketListener implements Closeable,AutoCloseable{ protected void open() throws UnknownHostException, IOException { if(serverSocket==null) serverSocket=multipurposeSocketAddress.listenServerSocket(); - new Thread(r).start(); + ThreadTool.makeVThread("端口监听线程", r).start(); } public void close() { flag=false; diff --git a/src/org/kne/cloud/network/congestion/ArrayListMessageBatcher.java b/src/org/kne/cloud/network/congestion/ArrayListMessageBatcher.java index d5828e4..73445e5 100644 --- a/src/org/kne/cloud/network/congestion/ArrayListMessageBatcher.java +++ b/src/org/kne/cloud/network/congestion/ArrayListMessageBatcher.java @@ -2,13 +2,9 @@ package org.kne.cloud.network.congestion; import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; 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.ThreadTool; @@ -78,11 +74,11 @@ public class ArrayListMessageBatcher implements MessageBatcher{ impl.close(); } public static void main(String[] args) throws InterruptedException { - for(;;){ + /*for(;;){ ArrayListMessageBatchermes=new ArrayListMessageBatcher<>(10, 1000000L); System.gc(); - } - /*ArrayListMessageBatchermes=new ArrayListMessageBatcher<>(10, 1000000L); + }*/ + ArrayListMessageBatchermes=new ArrayListMessageBatcher<>(10, 1000000L); mes.setConsumer((x)->{System.out.println(x);}); int n=0; for(;;){ @@ -91,7 +87,7 @@ public class ArrayListMessageBatcher implements MessageBatcher{ mes.putMessage(n++); mes.putMessage(n++); Thread.sleep(1); - }*/ + } } } class ArrayListMessageBatcherReleaser extends Releaser>{ @@ -114,18 +110,17 @@ class ArrayListMessageBatcherReleaser extends Releaser> consumer; private final Thread batchThread; - private final AtomicBoolean closed; + private final AtomicBoolean closed = new AtomicBoolean(false); private long firstTime; /** * 构造函数 * @param batchSize 批量大小,当消息达到此数量时触发发送 - * @param maxDelayMillis 最大延迟时间(毫秒),即使消息数量不足也会触发发送 + * @param maxDelay 最大延迟时间(毫秒),即使消息数量不足也会触发发送 */ public ArrayListMessageBatcher0(int batchSize, long maxDelay) { this.batchSize = batchSize; this.maxDelay = maxDelay; - this.closed = new AtomicBoolean(false); // 创建并启动批量处理线程 this.batchThread = ThreadTool.makeVDaemonThread("ArrayListMessageBatcher Thread", this ); diff --git a/src/org/kne/cloud/network/congestion/BBRCongestionAlgorithm.java b/src/org/kne/cloud/network/congestion/BBRCongestionAlgorithm.java index a87d424..1317607 100644 --- a/src/org/kne/cloud/network/congestion/BBRCongestionAlgorithm.java +++ b/src/org/kne/cloud/network/congestion/BBRCongestionAlgorithm.java @@ -1,7 +1,5 @@ package org.kne.cloud.network.congestion; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.BiConsumer; import java.util.function.Consumer; public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetCongestionAlgorithm{ @@ -12,9 +10,7 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges private static long MIN_WINDOW = 16384; private Consumer windowControlConsumer; - private BiConsumer speedControlConsumer; - private AtomicBoolean firstUpdate = new AtomicBoolean(true); private long MIN_RTTVAR = 5000000L; private volatile long RTTMin = 1000000000L; private volatile long RTTVar = 1000000000L; @@ -26,23 +22,19 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges private volatile long window=MIN_WINDOW; - private volatile long speed=MIN_SPEED; private volatile long maxwindow=99999999999L; private long congressSpeed=MIN_SPEED; private double MIN_GAIN=1.05; private double MAX_GAIN=1.20;//2.8853900817779 private double windowGain=MIN_GAIN; - private double speedGain=MAX_GAIN;//1.20 MAX_GAIN + private double burstLimit=1.20; @Override public void reset() { window = MIN_WINDOW; if (windowControlConsumer != null) { windowControlConsumer.accept(window); } - speed = MIN_SPEED; - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } + windowGain=MAX_GAIN; } @@ -51,10 +43,7 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges this.windowControlConsumer = windowControlConsumer; } - @Override - public void setSpeedControlConsumer(BiConsumer speedControlConsumer) { - this.speedControlConsumer = speedControlConsumer; - } + private long RTTstartTime = System.nanoTime(); private long bandwidth; @@ -65,14 +54,9 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges } else { RTTMin = (RTTMin * 99999 + latencyns) / 100000; } - if (firstUpdate.compareAndSet(true, false)) { - RTTAvg = latencyns; - RTTVar = latencyns / 2; - RTTAvg2 = latencyns; - } else { - RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4; - RTTAvg = (RTTAvg * 7 + latencyns) / 8; - } + RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4; + RTTAvg = (RTTAvg * 7 + latencyns) / 8; + RTO = RTTAvg + Math.max(MIN_RTTVAR, RTTVar * 4);// RTTVar*4 RTTTotal += latencyns; @@ -100,14 +84,10 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges } else { congressSpeed = (congressSpeed * 49 + bandwidth) / 50; } - speed=(long) (congressSpeed * speedGain)+MIN_SPEED ; window= ((long) (congressSpeed*windowGain )*(RTTMin+BIAS)/1000000000L)+MIN_WINDOW; if (windowControlConsumer != null) { windowControlConsumer.accept(window); } - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } } } @@ -124,6 +104,7 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges @Override public void setCurrentWindowUsed(long used) { + this.maxwindow = (long) (used*burstLimit) + MIN_WINDOW; } @@ -138,7 +119,6 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges @Override public void setUpperDelayBound(double upper) { MAX_GAIN=upper; - speedGain=MAX_GAIN; } @Override @@ -146,5 +126,14 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges MIN_GAIN=lower; windowGain=MIN_GAIN; } + @Override + public void setBurstLimit(double limit) { + burstLimit=limit; + } + + @Override + public String getName() { + return "BBR"; + } } diff --git a/src/org/kne/cloud/network/congestion/BBRVegasCongressAlgorithm.java b/src/org/kne/cloud/network/congestion/BBRVegasCongressAlgorithm.java deleted file mode 100644 index c9068f6..0000000 --- a/src/org/kne/cloud/network/congestion/BBRVegasCongressAlgorithm.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.kne.cloud.network.congestion; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -public class BBRVegasCongressAlgorithm implements CongestionAlgorithm { - - private static final long BURST_TIME = 2000000L; - private static final long BIAS = 2000000L; - private static long MIN_SPEED = 128 * 1024L; - private static long MIN_WINDOW = 8192; - - private Consumer windowControlConsumer; - private BiConsumer speedControlConsumer; - - private AtomicBoolean firstUpdate = new AtomicBoolean(true); - private long MIN_RTTVAR = 50000000L; - private volatile long RTTMin = 1000000000L; - private volatile long RTTVar = 1000000000L; - private volatile long RTTAvg = 1000000000L; - private volatile long RTTAvg2 = 1000000000L; - private volatile long RTTTotal = 0; - private volatile long RTTCount = 0; - private volatile long RTO = 1000000000L; - - - private volatile long window=MIN_WINDOW; - private volatile long speed=MIN_SPEED; - private volatile long maxwindow=99999999999L; - private long congressSpeed=MIN_SPEED; - private double MAX_GAIN=2.8853900817779;//2.8853900817779 - private double MIN_GAIN=1.1; - private double gain=MAX_GAIN; - @Override - public void reset() { - window = MIN_WINDOW; - if (windowControlConsumer != null) { - windowControlConsumer.accept(window); - } - speed = MIN_SPEED; - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } - gain=MAX_GAIN; - } - - @Override - public void setWindowControlConsumer(Consumer windowControlConsumer) { - this.windowControlConsumer = windowControlConsumer; - } - - @Override - public void setSpeedControlConsumer(BiConsumer speedControlConsumer) { - this.speedControlConsumer = speedControlConsumer; - } - - private long RTTstartTime = System.nanoTime(); - @Override - public synchronized void putAck(long packetSize, long latencyns, boolean ecn) { - if (latencyns <= RTTMin) { - RTTMin = latencyns; - } else { - RTTMin = (RTTMin * 99999 + latencyns) / 100000; - } - if (firstUpdate.compareAndSet(true, false)) { - RTTAvg = latencyns; - RTTVar = latencyns / 2; - RTTAvg2 = latencyns; - } else { - RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4; - RTTAvg = (RTTAvg * 7 + latencyns) / 8; - } - RTO = RTTAvg + Math.max(MIN_RTTVAR, RTTVar * 4);// RTTVar*4 - - RTTTotal += latencyns; - RTTCount++; - long curr=System.nanoTime(); - if(curr-RTTstartTime>RTTMin) { - if(RTTCount>0) { - RTTAvg2=(RTTAvg2+RTTTotal/RTTCount)/2; - RTTTotal=0; - RTTCount=0; - } - long RTTAvg2x=Math.max(RTTAvg2-BIAS,RTTMin); - double excepted=window/(double)RTTMin; - double actual=window/(double)RTTAvg2x; - double diff=(excepted-actual)*RTTMin; - if(diff>65536*3+3) { - gain-=0.0005; - } - if(diff<65536*3+1) { - gain+=0.0005; - } - if(gain>=MAX_GAIN){ - gain=MAX_GAIN; - //System.out.println("window:"+window); - } - if(gain= congressSpeed) { - congressSpeed = (congressSpeed * 49 + bandwidth) / 50; - } else { - congressSpeed = (congressSpeed *2 + bandwidth) / 3; - }*/ - if (bandwidth >= congressSpeed) { - //congressSpeed = bandwidth; - congressSpeed = (congressSpeed + bandwidth) / 2; - } else { - congressSpeed = (congressSpeed * 49 + bandwidth) / 50; - } - speed=Math.max(MIN_SPEED,(long) (congressSpeed * gain)) ; - window=Math.max( (Math.max(MIN_SPEED,(long) (congressSpeed*gain ))*Math.max(2000000L,RTTMin)/1000000000L),MIN_WINDOW); - if (windowControlConsumer != null) { - windowControlConsumer.accept(window); - } - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } - //System.out.println(gain); - //System.out.println(bandwidth+" "+congressSpeed+" "+window); - } - -} diff --git a/src/org/kne/cloud/network/congestion/CongestionAlgorithm.java b/src/org/kne/cloud/network/congestion/CongestionAlgorithm.java index 9f46731..ec41593 100644 --- a/src/org/kne/cloud/network/congestion/CongestionAlgorithm.java +++ b/src/org/kne/cloud/network/congestion/CongestionAlgorithm.java @@ -1,16 +1,18 @@ package org.kne.cloud.network.congestion; -import java.util.function.BiConsumer; import java.util.function.Consumer; public interface CongestionAlgorithm { public void reset(); public void setWindowControlConsumer(ConsumerwindowControlConsumer); - public void setSpeedControlConsumer(BiConsumerspeedControlConsumer); - public void putAck(long packetSize,long latencyns,boolean ecn); + public void putAck(long packetSize,long RTTns,boolean ecn); + default public void putAck(long packetSize,long RTTns,long OWDup,boolean ecn) { + putAck(packetSize,RTTns,ecn); + } public void putLoss(long packetSize,long lossns,int losscounter); public void setCurrentWindowUsed(long maxwindow); public void setCurrentBandwidth(long bandwidth); public long getRTO(); + public String getName(); } diff --git a/src/org/kne/cloud/network/congestion/DCTCP2CongestionAlgorithm.java b/src/org/kne/cloud/network/congestion/DCTCP2CongestionAlgorithm.java index c6cf508..611b9e5 100644 --- a/src/org/kne/cloud/network/congestion/DCTCP2CongestionAlgorithm.java +++ b/src/org/kne/cloud/network/congestion/DCTCP2CongestionAlgorithm.java @@ -1,44 +1,33 @@ package org.kne.cloud.network.congestion; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.BiConsumer; import java.util.function.Consumer; +import org.jctools.counters.FixedSizeStripedLongCounter; +import org.kne.cloud.network.klalb.KLALBUtils; + public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm { private static final long BURST_TIME = 1000000L; private static final long BIAS = 2000000L; - private static long MIN_SPEED = 64 * 1024L; - private static long MIN_WINDOW = 32768; + private static long MIN_WINDOW = 8192; private Consumer windowControlConsumer; - private BiConsumer speedControlConsumer; - private AtomicBoolean firstUpdate = new AtomicBoolean(true); - private long MIN_RTTVAR = 400000000L; - private volatile long RTTMin = 1000000000L; + private long MIN_RTTVAR = 100000000L; private volatile long RTTVar = 1000000000L; private volatile long RTTAvg = 1000000000L; private double ECNAvg2 = 0L; private double alpha=0; - private volatile AtomicLong ECNSize = new AtomicLong(0); - private volatile AtomicLong TotalSize = new AtomicLong(0); - private volatile long RTO = 1000000000L; + private volatile FixedSizeStripedLongCounter ECNSize = KLALBUtils.createCounter(); + private volatile FixedSizeStripedLongCounter TotalSize = KLALBUtils.createCounter(); + private volatile long RTO = 500000000L; private volatile long window=MIN_WINDOW; - private volatile long windowUsed=MIN_WINDOW; + private volatile long maxwindow = 99999999999L; private volatile long congressWindowSize=MIN_WINDOW; - private volatile long speed=MIN_SPEED; - private long congressSpeed=MIN_SPEED; private long RTTstartTime = System.nanoTime(); - private long bandwidth=MIN_SPEED; - private double MAX_GAIN=1.5;//2.8853900817779 - private double MIN_GAIN=1.2; - private double gain=MAX_GAIN; @Override public void reset() { @@ -46,11 +35,6 @@ public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm { if (windowControlConsumer != null) { windowControlConsumer.accept(window); } - speed = MIN_SPEED; - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } - gain=MAX_GAIN; } @Override @@ -58,73 +42,44 @@ public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm { this.windowControlConsumer = windowControlConsumer; } - @Override - public void setSpeedControlConsumer(BiConsumer speedControlConsumer) { - this.speedControlConsumer = speedControlConsumer; - } @Override public synchronized void putAck(long packetSize, long latencyns, boolean ecn) { - if (latencyns <= RTTMin) { - RTTMin = latencyns; - } else { - RTTMin = (RTTMin * 99999 + latencyns) / 100000; - } - if (firstUpdate.compareAndSet(true, false)) { - RTTAvg = latencyns; - RTTVar = latencyns / 2; - } else { - RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4; - RTTAvg = (RTTAvg * 7 + latencyns) / 8; - } + + + RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4; + RTTAvg = (RTTAvg * 7 + latencyns) / 8; + RTO = RTTAvg + Math.max(MIN_RTTVAR, RTTVar * 4);// RTTVar*4 if(ecn) { - ECNSize.addAndGet(packetSize); + ECNSize.inc(packetSize); } - TotalSize.addAndGet(packetSize); + TotalSize.inc(packetSize); long curr=System.nanoTime(); if(curr-RTTstartTime>(RTTAvg+BIAS)) { RTTstartTime=curr; - long totalSize=TotalSize.getAndSet(0); - long ecnSize=ECNSize.getAndSet(0); + long totalSize=TotalSize.getAndReset(); + long ecnSize=ECNSize.getAndReset(); if(totalSize!=0) { ECNAvg2=ecnSize/(double)totalSize; - alpha=(alpha*15+ECNAvg2)/16; + alpha=(alpha*7+ECNAvg2)/8; } if(ECNAvg2>0.5) { - gain=MIN_GAIN; - if(congressWindowSize>MIN_WINDOW) { congressWindowSize-=200; - updateWindowSize(); - } - }else if(ECNAvg2>0.1){ - if(windowUsed*3L>=congressWindowSize) { + }else if(ECNAvg2>0.01){ congressWindowSize+=200; - updateWindowSize(); - } }else { - if(windowUsed*3L>=congressWindowSize) { - congressWindowSize+=8000; - updateWindowSize(); - } + congressWindowSize+=4000; } //System.out.println(ECNAvg2); //System.out.println(speed+" "+window); - if (bandwidth >= congressSpeed) { - congressSpeed = bandwidth; - } else { - congressSpeed = (congressSpeed * 99 + bandwidth) / 100; - } - speed=Math.max(MIN_SPEED,(long) (congressSpeed * gain)) ; - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } + updateWindowSize(); } @@ -132,6 +87,11 @@ public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm { } private void updateWindowSize() { + if(congressWindowSizemaxwindow) { + congressWindowSize=maxwindow; + } window=Math.max( congressWindowSize,MIN_WINDOW); if (windowControlConsumer != null) { windowControlConsumer.accept(window); @@ -150,12 +110,17 @@ public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm { @Override public void setCurrentWindowUsed(long used) { - this.windowUsed=used; + this.maxwindow=(long) (used*1.5)+MIN_WINDOW; } @Override public void setCurrentBandwidth(long bandwidth) { - this.bandwidth=bandwidth; + + } + + @Override + public String getName() { + return "DCTCP2"; } } diff --git a/src/org/kne/cloud/network/congestion/DCTCPCongestionAlgorithm.java b/src/org/kne/cloud/network/congestion/DCTCPCongestionAlgorithm.java index 361596c..936b431 100644 --- a/src/org/kne/cloud/network/congestion/DCTCPCongestionAlgorithm.java +++ b/src/org/kne/cloud/network/congestion/DCTCPCongestionAlgorithm.java @@ -2,8 +2,6 @@ package org.kne.cloud.network.congestion; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.BiConsumer; import java.util.function.Consumer; public class DCTCPCongestionAlgorithm implements CongestionAlgorithm { @@ -11,13 +9,12 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm { private static final long BURST_TIME = 1000000L; private static final long BIAS = 2000000L; private static long MIN_SPEED = 64 * 1024L; - private static long MIN_WINDOW = 32768; + private static long MIN_WINDOW = 8192; private Consumer windowControlConsumer; - private BiConsumer speedControlConsumer; private AtomicBoolean firstUpdate = new AtomicBoolean(true); - private long MIN_RTTVAR = 400000000L; + private long MIN_RTTVAR = 100000000L; private volatile long RTTMin = 1000000000L; private volatile long RTTVar = 1000000000L; private volatile long RTTAvg = 1000000000L; @@ -31,14 +28,10 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm { private volatile long window=MIN_WINDOW; private volatile long windowUsed=MIN_WINDOW; private volatile long congressWindowSize=MIN_WINDOW; - private volatile long speed=MIN_SPEED; - private long congressSpeed=MIN_SPEED; private long RTTstartTime = System.nanoTime(); - private long bandwidth=MIN_SPEED; private double MAX_GAIN=2.8853900817779;//2.8853900817779 private double MIN_GAIN=1.2; - private double gain=MAX_GAIN; @Override public void reset() { @@ -46,11 +39,6 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm { if (windowControlConsumer != null) { windowControlConsumer.accept(window); } - speed = MIN_SPEED; - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } - gain=MAX_GAIN; } @Override @@ -58,10 +46,6 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm { this.windowControlConsumer = windowControlConsumer; } - @Override - public void setSpeedControlConsumer(BiConsumer speedControlConsumer) { - this.speedControlConsumer = speedControlConsumer; - } @Override public synchronized void putAck(long packetSize, long latencyns, boolean ecn) { @@ -86,7 +70,7 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm { long curr=System.nanoTime(); - if(curr-RTTstartTime>(RTTAvg+BIAS)) { + if(curr-RTTstartTime>Math.max(BIAS, 2*RTTMin)) { RTTstartTime=curr; long totalSize=TotalSize.getAndSet(0); @@ -94,37 +78,23 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm { if(totalSize!=0) { ECNAvg2=ecnSize/(double)totalSize; alpha=(alpha*15+ECNAvg2)/16; + //System.out.println(ECNAvg2); } - if(ECNAvg2>0.6) { - gain=MIN_GAIN; + if(ECNAvg2>0.5) { if(congressWindowSize>MIN_WINDOW) { congressWindowSize=Math.max(MIN_WINDOW,(long) (congressWindowSize*(1-alpha/10))); updateWindowSize(); } - }else if(ECNAvg2>0.2){ - if(windowUsed*3L>=congressWindowSize) { - congressWindowSize+=200; - updateWindowSize(); - } }else { if(windowUsed*3L>=congressWindowSize) { - congressWindowSize+=8000; + congressWindowSize+=4000; updateWindowSize(); } } //System.out.println(ECNAvg2); //System.out.println(speed+" "+window); - if (bandwidth >= congressSpeed) { - congressSpeed = bandwidth; - } else { - congressSpeed = (congressSpeed * 99 + bandwidth) / 100; - } - speed=Math.max(MIN_SPEED,(long) (congressSpeed * gain)) ; - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } } @@ -155,7 +125,14 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm { @Override public void setCurrentBandwidth(long bandwidth) { - this.bandwidth=bandwidth; + } + @Override + public String getName() { + return "DCTCP"; + } + + + } diff --git a/src/org/kne/cloud/network/congestion/DetnetCongestionAlgorithm.java b/src/org/kne/cloud/network/congestion/DetnetCongestionAlgorithm.java index 9d2bce1..83d401a 100644 --- a/src/org/kne/cloud/network/congestion/DetnetCongestionAlgorithm.java +++ b/src/org/kne/cloud/network/congestion/DetnetCongestionAlgorithm.java @@ -3,4 +3,5 @@ package org.kne.cloud.network.congestion; public interface DetnetCongestionAlgorithm extends CongestionAlgorithm { public void setUpperDelayBound(double upper); public void setLowerDelayBound(double lower); + public void setBurstLimit(double limit); } diff --git a/src/org/kne/cloud/network/congestion/EmptyCongestionAlgorithm.java b/src/org/kne/cloud/network/congestion/NOCongestionAlgorithm.java similarity index 73% rename from src/org/kne/cloud/network/congestion/EmptyCongestionAlgorithm.java rename to src/org/kne/cloud/network/congestion/NOCongestionAlgorithm.java index 373aaab..a736748 100644 --- a/src/org/kne/cloud/network/congestion/EmptyCongestionAlgorithm.java +++ b/src/org/kne/cloud/network/congestion/NOCongestionAlgorithm.java @@ -1,9 +1,8 @@ package org.kne.cloud.network.congestion; -import java.util.function.BiConsumer; import java.util.function.Consumer; -public class EmptyCongestionAlgorithm implements CongestionAlgorithm{ +public class NOCongestionAlgorithm implements CongestionAlgorithm{ private long timeout; @@ -23,11 +22,7 @@ public class EmptyCongestionAlgorithm implements CongestionAlgorithm{ } - @Override - public void setSpeedControlConsumer(BiConsumer speedControlConsumer) { - // TODO 自动生成的方法存根 - - } + @Override public void putAck(long packetSize, long latencyns, boolean ecn) { @@ -53,7 +48,7 @@ public class EmptyCongestionAlgorithm implements CongestionAlgorithm{ } - public EmptyCongestionAlgorithm(long timeout) { + public NOCongestionAlgorithm(long timeout) { super(); this.timeout = timeout; } @@ -63,4 +58,9 @@ public class EmptyCongestionAlgorithm implements CongestionAlgorithm{ return timeout; } + @Override + public String getName() { + return "NO"; + } + } diff --git a/src/org/kne/cloud/network/congestion/ReceiveByteSlidingWindow.java b/src/org/kne/cloud/network/congestion/ReceiveByteSlidingWindow.java deleted file mode 100644 index 8185309..0000000 --- a/src/org/kne/cloud/network/congestion/ReceiveByteSlidingWindow.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.kne.cloud.network.congestion; - -import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReferenceArray; - -public class ReceiveByteSlidingWindow { - private AtomicReferenceArray array; - private AtomicInteger windowSize =new AtomicInteger(); - private AtomicLong windowPosition=new AtomicLong(); - - public int getWindowSize() { - return windowSize.get(); - } - - public void setWindowSize(int windowSize) { - this.windowSize.set(windowSize); - } - - public long getWindowPosition() { - return windowPosition.get(); - } - - public void setWindowPosition(long windowPosition) { - this.windowPosition.set(windowPosition); - } - - public ReceiveByteSlidingWindow(int capacity){ - array=new AtomicReferenceArray(capacity); - } - - public boolean push(E object) { - Objects.requireNonNull(object); - if(array.get((int) ((windowPosition.get()-windowSize.get())%array.length()))==null ) { - array.set((int) (windowPosition.getAndIncrement()%array.length()), object); - return true; - } - return false; - } - - public E pull(long number) { - return array.getAndSet((int) (number%array.length()), null); - } -} diff --git a/src/org/kne/cloud/network/congestion/SendByteSlidingWindow.java b/src/org/kne/cloud/network/congestion/SendByteSlidingWindow.java deleted file mode 100644 index 653443c..0000000 --- a/src/org/kne/cloud/network/congestion/SendByteSlidingWindow.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.kne.cloud.network.congestion; - -import java.util.Iterator; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReferenceArray; - -public class SendByteSlidingWindow implements Iterable{ - private Object[] array; - private volatile int windowSize ; - private volatile long windowPosition; - - public int getWindowSize() { - return windowSize; - } - - public void setWindowSize(int windowSize) { - this.windowSize=windowSize; - } - - public long getWindowPosition() { - return windowPosition; - } - - public void setWindowPosition(long windowPosition) { - this.windowPosition=windowPosition; - } - - public SendByteSlidingWindow(int capacity,int windowSize){ - if(windowSize>capacity) { - throw new IllegalArgumentException("windowSize>capacity!"); - } - array= new Object[capacity]; - this.windowSize=windowSize; - } - - public boolean checkPush() { - if(array[calcPosition(windowPosition-windowSize)]==null ) { - return true; - } - return false; - } - - public void push(E object) { - - array[calcPosition(windowPosition)]= object; - } - - public E remove(long number) { - if(number=windowPosition-windowSize) { - int indp=calcPosition(number); - E old=(E) array[indp]; - array[indp]=null; - return old; - }else { - return null; - } - } - - public boolean isEmpty() { - for (long i = windowPosition-windowSize; i < windowPosition; i++) { - if(array[calcPosition(i)]!=null) { - return false; - } - } - return true; - } - - public E get(long number) { - if(number=windowPosition-windowSize) { - return (E) array[calcPosition(number)]; - }else { - return null; - } - } - - @Override - public Iterator iterator() { - return new Iterator() { - private long pointer=windowPosition-windowSize; - @Override - public boolean hasNext() { - return pointer implements Closeable, AutoCloseable { - private Map> sendMap = new ConcurrentHashMap<>(1024, 0.2f); - private AtomicLong sendmapWindowUsed=new AtomicLong(0); - //private LongAdder sendmapWindowUsed = new LongAdder(); + private ThreadParker tp=new ThreadParker(); + + private Map> sendMap = new ConcurrentHashMap<>(2048); + private AtomicLong sendWindowUsed=new AtomicLong(0); + //private LongAdder sendWindowUsed = new LongAdder(); private int headerCalibrate = 0; @@ -36,14 +33,14 @@ public class SendPacketSlidingWindow implements Clos private Consumer resendConsumer; private Consumer closingConsumer; - private volatile boolean closed = false; private ResendChecker checker = new ResendChecker(); - private AtomicLong windowSize = new AtomicLong(); private Lock lock; private Condition condition; private boolean removeAtResend; + private volatile long windowSize =0; + private volatile boolean closed = false; public SendPacketSlidingWindow(CongestionAlgorithm algorithm, long windowSize) { this(algorithm, windowSize, 0, true); @@ -58,17 +55,17 @@ public class SendPacketSlidingWindow implements Clos this.headerCalibrate = headerCalibrate; this.removeAtResend = removeAtResend; this.algorithm = algorithm; - this.windowSize.set(windowSize); + this.windowSize=windowSize; Thread t = ThreadTool.makeVThread("重路由计时器线程", checker); t.start(); } public long getWindowSize() { - return windowSize.get(); + return windowSize; } public void setWindowSize(long windowSize) { - this.windowSize.set(windowSize); + this.windowSize=windowSize; } public Consumer getResendConsumer() { @@ -87,8 +84,8 @@ public class SendPacketSlidingWindow implements Clos this.closingConsumer = closingConsumer; } - public long getSendmapWindowUsed() { - return sendmapWindowUsed.get(); + public long getSendWindowUsed() { + return sendWindowUsed.get(); } public int getHeaderCalibrate() { @@ -99,20 +96,38 @@ public class SendPacketSlidingWindow implements Clos return algorithm; } - public boolean isCongress(IPv6Packet iPv6Packet, double scale) { - boolean congress = sendmapWindowUsed.get() > windowSize.get() * scale; + public boolean isCongestion( double scale) { + boolean congress = sendWindowUsed.get() > windowSize * scale; return congress; } + public boolean isCongestion() { + boolean congress = sendWindowUsed.get() > windowSize ; + return congress; + } + + public void waitForAvaliable() throws SocketException { + while(isCongestion()) { + if(closed) { + throw new SocketException("Send window closed!"); + } + tp.parkNanos(1000000L); + } + } + public void putBlocked(K sequence, V packet) throws SocketException { + waitForAvaliable(); + put(sequence,packet); + } + public void put(K sequence, V packet) { - SendItem newitem = new SendItem(packet); + SendItem newitem = new SendItem(packet,headerCalibrate); SendItem old = sendMap.put(sequence, newitem); long dx=0; if (old != null) { - dx=-(old.getPacketLength() + headerCalibrate); + dx=-old.getPacketLength() ; } - long newWindow =sendmapWindowUsed.addAndGet(newitem.getPacketLength() + headerCalibrate+dx); + long newWindow =sendWindowUsed.addAndGet(newitem.getPacketLength() +dx); algorithm.setCurrentWindowUsed(newWindow); } public V ack(K sequence) { @@ -122,10 +137,11 @@ public class SendPacketSlidingWindow implements Clos public V ack(K sequence,boolean ecn) { SendItem ipv6; if ((ipv6 = sendMap.remove(sequence)) != null) { - long newWindow =sendmapWindowUsed.addAndGet(-(ipv6.getPacketLength() + headerCalibrate)); + long newWindow =sendWindowUsed.addAndGet(-ipv6.getPacketLength() ); algorithm.setCurrentWindowUsed(newWindow); long RTTC = System.nanoTime() - ipv6.getSendtime(); algorithm.putAck(ipv6.getPacketLength(), RTTC, ecn); + tp.unpark(); // System.out.println("remove:"+aseq.getSequence()+" "+sendMap.size()); Lock lockx = lock; if (lockx != null) { @@ -146,6 +162,34 @@ public class SendPacketSlidingWindow implements Clos } } + public V ack(K sequence,boolean ecn,long OWDdown) { + SendItem ipv6; + if ((ipv6 = sendMap.remove(sequence)) != null) { + long newWindow =sendWindowUsed.addAndGet(-ipv6.getPacketLength() ); + algorithm.setCurrentWindowUsed(newWindow); + long RTTC = System.nanoTime() - ipv6.getSendtime(); + algorithm.putAck(ipv6.getPacketLength(), RTTC,OWDdown, ecn); + tp.unpark(); + // System.out.println("remove:"+aseq.getSequence()+" "+sendMap.size()); + Lock lockx = lock; + if (lockx != null) { + lockx.lock(); + try { + Condition cds = condition; + if (cds != null) { + cds.signalAll(); + } + } finally { + lockx.unlock(); + } + } + return ipv6.getPacket(); + } else { + // System.out.println("miss:"+aseq.getSequence()+" "+sendMap.size()); + return null; + } + } + private class ResendChecker implements Runnable { @Override @@ -159,8 +203,9 @@ public class SendPacketSlidingWindow implements Clos if (current - sitm.getSendtime() > algorithm.getRTO()) { if (removeAtResend) { iterator.remove(); - long newWindow = sendmapWindowUsed.addAndGet((int) -(sitm.getPacketLength() + headerCalibrate)); + long newWindow = sendWindowUsed.addAndGet((int) -sitm.getPacketLength() ); algorithm.setCurrentWindowUsed(newWindow); + tp.unpark(); } else { sitm.setSendtime(current); } @@ -183,7 +228,7 @@ public class SendPacketSlidingWindow implements Clos } } sendMap.clear(); - sendmapWindowUsed.set(0); + sendWindowUsed.set(0); } } @@ -215,7 +260,20 @@ public class SendPacketSlidingWindow implements Clos @Override public String toString() { - return "SendPacketSlidingWindow [sendmapWindowUsed=" + sendmapWindowUsed + ", windowSize=" + windowSize + "]"; + return "SendPacketSlidingWindow [sendWindowUsed=" + sendWindowUsed + ", windowSize=" + windowSize + ", closed=" + + closed + "]"; } + public void waitForEmpty() throws SocketException { + while(!isEmpty()) { + if(isClosed()) { + throw new SocketException("Send window closed!"); + } + tp.parkNanos(1000000L); + } + } + + + + } diff --git a/src/org/kne/cloud/network/congestion/Vegas2CongestionAlgorithm.java b/src/org/kne/cloud/network/congestion/Vegas2CongestionAlgorithm.java index f52d4ac..fc8bc39 100644 --- a/src/org/kne/cloud/network/congestion/Vegas2CongestionAlgorithm.java +++ b/src/org/kne/cloud/network/congestion/Vegas2CongestionAlgorithm.java @@ -1,7 +1,5 @@ package org.kne.cloud.network.congestion; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.BiConsumer; import java.util.function.Consumer; public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCongestionAlgorithm { @@ -9,19 +7,15 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong // 可配置的时延膨胀比上下限 - Vegas2.0核心参数 private double delayUpperBound = 1.20; // RTT上限为基础RTT的1.2倍 private double delayLowerBound = 1.15; // RTT下限为基础RTT的1.05倍 + private double burstLimit=1.20; private static final long BURST_TIME = 2000000L; - private static final long BIAS = 500000L; - private static long MIN_SPEED = 256 * 1024L; + private static final long BIAS = 1000000L; private static long MIN_WINDOW = 16384; - // 新增:窗口调整参数(可基于当前窗口大小动态调整) - private static final double WINDOW_ADJUST_FACTOR = 0.01; // 1%的窗口调整幅度 private Consumer windowControlConsumer; - private BiConsumer speedControlConsumer; - private AtomicBoolean firstUpdate = new AtomicBoolean(true); private long MIN_RTTVAR = 30000000L; private volatile long RTTMin = 1000000000L; // BaseRTT private volatile long RTTVar = 1000000000L; @@ -31,12 +25,15 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong private volatile long RTTCount = 0; private volatile long RTO = 1000000000L; + + private volatile long OWDTotal = 0; + private volatile long OWDCount = 0; + private volatile long OWDAvg2 = 1000000000L; // 当前平滑OWD + private volatile long OWDMin = 1000000000L; // BaseRTT + private volatile long window = MIN_WINDOW; private volatile long window2 = MIN_WINDOW; - private volatile long speed = MIN_SPEED; private volatile long maxwindow = 99999999999L; - private long congressSpeed=MIN_SPEED; - public Vegas2CongestionAlgorithm() { reset(); } @@ -47,10 +44,7 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong if (windowControlConsumer != null) { windowControlConsumer.accept(window); } - speed = MIN_SPEED; - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } + } @Override @@ -58,15 +52,17 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong this.windowControlConsumer = windowControlConsumer; } - @Override - public void setSpeedControlConsumer(BiConsumer speedControlConsumer) { - this.speedControlConsumer = speedControlConsumer; - } + private long RTTstartTime = System.nanoTime(); - @Override - public synchronized void putAck(long packetSize, long latencyns, boolean ecn) { + + + @Override + public void putAck(long packetSize, long RTTns, long OWDup, boolean ecn) { + if(RTTns<0) { + throw new IllegalArgumentException("RTT:"+ RTTns+" is negative!"); + } // 处理ECN信号 - 将其视为强烈的拥塞信号 if (ecn) { // 当收到ECN时,更激进地减少窗口 @@ -77,35 +73,128 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong } // 更新最小RTT(BaseRTT) - if (latencyns <= RTTMin) { - RTTMin = latencyns; + if (RTTns <= RTTMin) { + RTTMin = RTTns; } else { // 缓慢适应:当网络路径真正变化时,BaseRTT应能缓慢更新 // 这里使用极慢的衰减因子,只有在持续观测到更低RTT时才快速更新 - RTTMin = (RTTMin * 9999 + latencyns) / 10000; + RTTMin = (RTTMin * 999 + RTTns) / 1000; + } + + // 更新最小OWD(BaseOWD) + if (OWDup <= OWDMin) { + OWDMin = OWDup; + } else { + // 缓慢适应:当网络路径真正变化时,BaseRTT应能缓慢更新 + // 这里使用极慢的衰减因子,只有在持续观测到更低RTT时才快速更新 + OWDMin = (OWDMin * 999 + OWDup) / 1000; } // 更新平滑RTT估计 - if (firstUpdate.compareAndSet(true, false)) { - RTTAvg = latencyns; - RTTVar = latencyns / 2; - RTTAvg2 = latencyns; - } else { - RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4; - RTTAvg = (RTTAvg * 7 + latencyns) / 8; - } + + RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - RTTns)) / 4; + RTTAvg = (RTTAvg * 7 + RTTns) / 8; + RTO = RTTAvg + Math.max(MIN_RTTVAR, RTTVar * 4); - RTTTotal += latencyns; + RTTTotal += RTTns; + RTTCount++; + + OWDTotal += OWDup; + OWDCount++; + + long curr = System.nanoTime(); + // 每个RTT周期调整一次窗口(使用当前估计的RTT) + if (curr - RTTstartTime > Math.max(BIAS, 2*RTTMin)) { + long RTTCountx=RTTCount; + if (RTTCountx > 0) { + long currentRTT = RTTTotal / RTTCountx; + //RTTAvg2 = (RTTAvg2 * 3 + currentRTT) / 4; // 平滑当前RTT + RTTAvg2=currentRTT; + RTTTotal = 0; + RTTCount = 0; + } + + long OWDCountx=OWDCount; + if (OWDCountx > 0) { + long currentOWD = OWDTotal / OWDCountx; + OWDAvg2=currentOWD; + OWDTotal = 0; + OWDCount = 0; + } + + + // ================== Vegas2.0核心逻辑 ================== + // 1. 计算时延膨胀比 + double delayRatio = (double) OWDAvg2 / (double) Math.max(BIAS, OWDMin); + //System.out.println(delayRatio+" "+RTTAvg2/1000000.0+" "+RTTMin/1000000.0); + // 2. 基于比值的窗口调整(取代原来的基于差值的调整) + if (delayRatio > delayUpperBound) { + // 时延过高:减小窗口,减少幅度与超标程度成正比 + window2 -= 4096; + } else if (delayRatio < delayLowerBound) { + // 时延过低:增大窗口,增加幅度与低于目标程度成正比 + window2 += 4096; + } else { + + } + // =================================================== + + + + + updateWindowSize(); + RTTstartTime = curr; + + + + + } + } + + @Override + public void putAck(long packetSize, long RTTns, boolean ecn) { + if(RTTns<0) { + throw new IllegalArgumentException("RTT:"+ RTTns+" is negative!"); + } + // 处理ECN信号 - 将其视为强烈的拥塞信号 + if (ecn) { + // 当收到ECN时,更激进地减少窗口 + window2 = Math.max(0, window2 * 3 / 4); + if (windowControlConsumer != null) { + windowControlConsumer.accept(window2); + } + } + + // 更新最小RTT(BaseRTT) + if (RTTns <= RTTMin) { + RTTMin = RTTns; + } else { + // 缓慢适应:当网络路径真正变化时,BaseRTT应能缓慢更新 + // 这里使用极慢的衰减因子,只有在持续观测到更低RTT时才快速更新 + RTTMin = (RTTMin * 999 + RTTns) / 1000; + } + + // 更新平滑RTT估计 + + RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - RTTns)) / 4; + RTTAvg = (RTTAvg * 7 + RTTns) / 8; + + + RTO = RTTAvg + Math.max(MIN_RTTVAR, RTTVar * 4); + + RTTTotal += RTTns; RTTCount++; long curr = System.nanoTime(); // 每个RTT周期调整一次窗口(使用当前估计的RTT) - if (curr - RTTstartTime > Math.max(BIAS, RTTMin)) { - if (RTTCount > 0) { - long currentRTT = RTTTotal / RTTCount; - RTTAvg2 = (RTTAvg2 * 3 + currentRTT) / 4; // 平滑当前RTT + if (curr - RTTstartTime > Math.max(BIAS, 2*RTTMin)) { + long RTTCountx=RTTCount; + if (RTTCountx > 0) { + long currentRTT = RTTTotal / RTTCountx; + //RTTAvg2 = (RTTAvg2 * 3 + currentRTT) / 4; // 平滑当前RTT + RTTAvg2=currentRTT; RTTTotal = 0; RTTCount = 0; } @@ -113,64 +202,47 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong // ================== Vegas2.0核心逻辑 ================== // 1. 计算时延膨胀比 double delayRatio = (double) RTTAvg2 / (double) Math.max(BIAS, RTTMin); - + //System.out.println(delayRatio+" "+RTTAvg2/1000000.0+" "+RTTMin/1000000.0); // 2. 基于比值的窗口调整(取代原来的基于差值的调整) - long adjustStep = Math.max(512, (long)(window2 * WINDOW_ADJUST_FACTOR)); - if (delayRatio > delayUpperBound) { // 时延过高:减小窗口,减少幅度与超标程度成正比 - double exceedRatio = delayRatio / delayUpperBound; - window2 -= (long)(adjustStep * exceedRatio); + window2 -= 4096; } else if (delayRatio < delayLowerBound) { // 时延过低:增大窗口,增加幅度与低于目标程度成正比 - double belowRatio = delayLowerBound / delayRatio; - window2 += (long)(adjustStep * belowRatio); + window2 += 4096; } else { - // 在理想区间内:微调以维持稳定 - // 计算目标RTT = BaseRTT × 目标膨胀比 - long targetRTT = (long)(Math.max(BIAS, RTTMin) * (delayLowerBound + delayUpperBound) / 2.0); - - if (RTTAvg2 > targetRTT) { - // 略高于目标:小幅减少 - window2 = Math.max(0, window2 - 256); - } else if (RTTAvg2 < targetRTT) { - // 略低于目标:小幅增加 - window2 = Math.min(maxwindow, window2 + 256); - } - // 非常接近目标:保持窗口不变 + } // =================================================== - // 窗口边界检查 - if (window2 >= maxwindow) { - window2 = maxwindow; - } - if (window2 < 0) { - window2 = 0; - } + + + updateWindowSize(); RTTstartTime = curr; - if (bandwidth >= congressSpeed) { - congressSpeed = bandwidth; - //congressSpeed = (congressSpeed + bandwidth) / 2; - } else { - congressSpeed = (congressSpeed * 49 + bandwidth) / 50; - } - // 速度计算:基于当前窗口和RTT,考虑一个安全边界 - // 使用目标膨胀比而非固定1.2倍,确保与窗口控制逻辑一致 - window=window2+MIN_WINDOW; - speed=(long) (congressSpeed * delayUpperBound)+MIN_SPEED ; - if (windowControlConsumer != null) { - windowControlConsumer.accept(window); - } - if (speedControlConsumer != null) { - speedControlConsumer.accept(speed, BURST_TIME); - } + } } + + private void updateWindowSize() { + // 窗口边界检查 + if (window2 >= maxwindow) { + window2 = maxwindow; + } + if (window2 < 0) { + window2 = 0; + } + // 速度计算:基于当前窗口和RTT,考虑一个安全边界 + // 使用目标膨胀比而非固定1.2倍,确保与窗口控制逻辑一致 + window=window2+MIN_WINDOW; + + if (windowControlConsumer != null) { + windowControlConsumer.accept(window); + } + } @Override public void putLoss(long packetSize, long lossns, int losscounter) { @@ -183,14 +255,12 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong @Override public void setCurrentWindowUsed(long used) { - this.maxwindow = used * 16 + 65536; + this.maxwindow = (long) (used * burstLimit )+ MIN_WINDOW; } - private long bandwidth; @Override public void setCurrentBandwidth(long bandwidth) { // 可选:基于已知带宽信息调整参数 - this.bandwidth=bandwidth; } // 新增方法:获取当前状态信息(用于监控和调试) @@ -215,4 +285,14 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong public void setLowerDelayBound(double lower) { delayLowerBound=lower; } + + @Override + public void setBurstLimit(double limit) { + burstLimit=limit; + } + @Override + public String getName() { + return "Vegas2"; + } + } \ No newline at end of file diff --git a/src/org/kne/cloud/network/ipv6/AbstractIPv6NetworkLink.java b/src/org/kne/cloud/network/ipv6/AbstractIPv6NetworkLink.java index 778c40c..f6bafc6 100644 --- a/src/org/kne/cloud/network/ipv6/AbstractIPv6NetworkLink.java +++ b/src/org/kne/cloud/network/ipv6/AbstractIPv6NetworkLink.java @@ -1,16 +1,9 @@ package org.kne.cloud.network.ipv6; -import java.io.IOException; -import java.net.Inet6Address; -import java.util.List; import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; import java.util.function.BiConsumer; -import java.util.function.Consumer; import java.util.function.Supplier; -import org.kne.cloud.network.klalb.KLALBRemoteLine; import org.kne.cloud.network.srv6.SRv6Router; public abstract class AbstractIPv6NetworkLink implements IPv6NetworkLink { diff --git a/src/org/kne/cloud/network/ipv6/ControlledIPv6NetworkLink.java b/src/org/kne/cloud/network/ipv6/ControlledIPv6NetworkLink.java index 14b3884..ddcd3ff 100644 --- a/src/org/kne/cloud/network/ipv6/ControlledIPv6NetworkLink.java +++ b/src/org/kne/cloud/network/ipv6/ControlledIPv6NetworkLink.java @@ -6,11 +6,10 @@ import java.util.function.Consumer; public interface ControlledIPv6NetworkLink extends IPv6NetworkLink { - public boolean isCongress(IPv6Packet iPv6Packet,double scale); + public boolean isCongestion(IPv6Packet iPv6Packet,double scale); public default boolean isCongress(IPv6Packet iPv6Packet) { - return isCongress(iPv6Packet, 1.0); + return isCongestion(iPv6Packet, 1.0); } void setRerouteConsumer(Consumer rerouteConsumer); - public boolean isReachSpeedLimit(IPv6Packet iPv6Packet); public void setCongressCondition(Lock lock,Condition condition); } diff --git a/src/org/kne/cloud/network/ipv6/ICMPv6Packet.java b/src/org/kne/cloud/network/ipv6/ICMPv6Packet.java index 34c5ae2..785705c 100644 --- a/src/org/kne/cloud/network/ipv6/ICMPv6Packet.java +++ b/src/org/kne/cloud/network/ipv6/ICMPv6Packet.java @@ -34,7 +34,7 @@ public class ICMPv6Packet extends IPv6Payload { private boolean isDefault; protected ICMPv6Packet(ByteBuffer header,boolean isDefault) { - super(ICMPv6_PROTOCOL_NUMBER, false); + super(ICMPv6_PROTOCOL_NUMBER); this.header=header; this.isDefault=isDefault; @@ -45,7 +45,7 @@ public class ICMPv6Packet extends IPv6Payload { } protected ICMPv6Packet(int type, int code,boolean isDefault) { - super(ICMPv6_PROTOCOL_NUMBER, false); + super(ICMPv6_PROTOCOL_NUMBER); header = NetworkPacket.bufferAllocator.allocate(ICMPv6_HEADER_LENGTH); getHeader().put((byte) type); getHeader().put((byte) code); diff --git a/src/org/kne/cloud/network/ipv6/IPv6Packet.java b/src/org/kne/cloud/network/ipv6/IPv6Packet.java index ab94b65..f84638f 100644 --- a/src/org/kne/cloud/network/ipv6/IPv6Packet.java +++ b/src/org/kne/cloud/network/ipv6/IPv6Packet.java @@ -4,32 +4,21 @@ import java.io.EOFException; import java.io.IOException; import java.io.StreamCorruptedException; 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 java.util.UUID; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import org.kne.cloud.network.ByteBufferAllocator; import org.kne.cloud.network.NetworkPacket; -import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader; -import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader; import org.kne.cloud.network.klalb.KLALBPacket; +import org.kne.cloud.network.kltp.KLTPPacket; 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.kne.cloud.network.tcp.UDPPacket; import org.kne.io.KNEChannels; -import org.pcap4j.packet.namednumber.IpNumber; /** * IPv6数据包类,继承自NetworkPacket,用于处理IPv6网络数据包 @@ -231,15 +220,7 @@ public class IPv6Packet extends NetworkPacket { nextHeader == ICMPv6; } - private IPv6NetworkLink previousLink; - - public IPv6NetworkLink getPreviousLink() { - return previousLink; - } - - public void setPreviousLink(IPv6NetworkLink previousLink) { - this.previousLink = previousLink; - } + // TTL是否已减少的标志 private boolean TTLdecreased = false; @@ -318,7 +299,10 @@ public class IPv6Packet extends NetworkPacket { * @return 流量类别 */ public int getTrafficClass() { - return (IPv6header.get(0) << 4) & (IPv6header.get(1) >>> 4) & BIT_MASK_LOW_8_BITS; + // 读取字节 0 和字节 1 组成一个 short(16 位) + short firstTwoBytes = IPv6header.getShort(0); + // 提取 Traffic Class:高 4 位(Version)去掉,剩下就是 8 位 Traffic Class + return (firstTwoBytes & 0x0FF0) >>> 4; } /** @@ -326,8 +310,14 @@ public class IPv6Packet extends NetworkPacket { * @param trafficClass 流量类别 */ public void setTrafficClass(int trafficClass) { - IPv6header.put(0, (byte) (IPv6header.get(0) & BIT_MASK_HIGH_4_BITS | (trafficClass >>> 4))); - IPv6header.put(1, (byte) (IPv6header.get(1) & BIT_MASK_LOW_4_BITS | ((trafficClass & BIT_MASK_LOW_4_BITS) << 4))); + // 读取当前的两个字节 + short firstTwoBytes = IPv6header.getShort(0); + // 清除原来的 Traffic Class 位(将中间 8 位清零) + short cleared = (short) (firstTwoBytes & 0xF00F); // 保留高 4 位和低 4 位 + // 组合新的 Traffic Class + short newValue = (short) (cleared | ((trafficClass & 0xFF) << 4)); + // 一次性写回 + IPv6header.putShort(0, newValue); } /** @@ -349,7 +339,11 @@ public class IPv6Packet extends NetworkPacket { * 标记CE(拥塞经历) */ public void markCE() { - IPv6header.put(1, (byte) (IPv6header.get(1) | 0b00110000)); + byte g=IPv6header.get(1); + if((g& 0b00110000) != 0) { + // 启用ECN + IPv6header.put(1, (byte) ( g| 0b00110000)); + } // new Exception().printStackTrace(); } @@ -366,7 +360,10 @@ public class IPv6Packet extends NetworkPacket { * @return 流标签 */ public int getFlowLabel() { - return ((IPv6header.get(1) & BIT_MASK_LOW_4_BITS) << 16) | (IPv6header.getShort(2) & BIT_MASK_LOW_16_BITS); + // 读取前 4 个字节(32 位) + int firstWord = IPv6header.getInt(0); + // 提取 Flow Label:高 12 位(Version + Traffic Class)去掉,剩下低 20 位 + return firstWord & 0x000FFFFF; } /** @@ -374,8 +371,14 @@ public class IPv6Packet extends NetworkPacket { * @param flowLabel 流标签 */ public void setFlowLabel(int flowLabel) { - IPv6header.put(1, (byte) (IPv6header.get(1) & BIT_MASK_HIGH_4_BITS | (flowLabel >>> 16))); - IPv6header.putShort(2, (short) flowLabel); + // 读取当前前 4 个字节 + int firstWord = IPv6header.getInt(0); + // 清除原来的 Flow Label(将低 20 位清零) + int cleared = firstWord & 0xFFF00000; // 保留高 12 位 + // 组合新的 Flow Label(只取低 20 位) + int newWord = cleared | (flowLabel & 0x000FFFFF); + // 一次性写回 + IPv6header.putInt(0, newWord); } /** @@ -461,7 +464,6 @@ public class IPv6Packet extends NetworkPacket { /** * 获取原始源地址字节数组 - * @param sourceAddress 用于存储源地址的字节数组 * @return */ public IPv6Address getSourceAddress() { @@ -479,7 +481,6 @@ public class IPv6Packet extends NetworkPacket { /** * 获取原始目标地址字节数组 - * @param destinationAddress 用于存储目标地址的字节数组 */ public IPv6Address getDestinationAddress() { return IPv6Address.valueOf(DESTINATION_ADDRESS_OFFSET,IPv6header); @@ -707,13 +708,12 @@ public class IPv6Packet extends NetworkPacket { KLALBPacket kp = KLALBPacket.readKLALBPacketFromChannel(din); this.payload = kp; break loop; - case EXPERIMENTAL_1: // 空负载 - IPv6Payload epld = new IPv6EmptyPayload(); - epld.readFromChannel(din, payloadlength); + case KLTPPacket.KLTP_PROTOCOL_NUMBER: //KLTP协议 + IPv6Payload epld = KLTPPacket.readKLTPPacketFromChannel(din); this.payload = epld; break loop; default: // 其他协议类型 - IPv6Payload pld = new IPv6Payload(nextheader); + IPv6Payload pld = new IPv6DefaultPayload(nextheader); pld.readFromChannel(din, payloadlength); this.payload = pld; break loop; @@ -754,56 +754,28 @@ public class IPv6Packet extends NetworkPacket { /** * IPv6负载数据类 */ - public static class IPv6Payload extends NetworkPacket { - private ByteBuffer data; + public static abstract class IPv6Payload extends NetworkPacket { - private boolean onDefault = true; private IPv6Packet parent; - public ByteBuffer getData() { - return data; - } - private int protocolNumber; + + public IPv6Payload(int protocolNumber) { - this(protocolNumber, true); + this.protocolNumber=protocolNumber; } - protected IPv6Payload(int protocolNumber, boolean isonDefault) { - this.protocolNumber = protocolNumber; - this.onDefault = isonDefault; - if (onDefault) - this.data = NetworkPacket.bufferAllocator.allocate(65535); - } + public int getProtocolNumber() { return protocolNumber; } - public long getTotalLength() { - return data.limit(); - } - @Override - public void writeToChannel(WritableByteChannel dto) throws IOException { - if (onDefault) - dto.write(data.slice(0, data.limit())); - } - - @Override - public 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 protected boolean needEndPosition() { @@ -817,31 +789,37 @@ public class IPv6Packet extends NetworkPacket { return parent; } } + + public static class IPv6DefaultPayload extends IPv6Payload{ - /** - * 空IPv6负载数据类 - */ - public static class IPv6EmptyPayload extends IPv6Payload { - - public IPv6EmptyPayload() { - super(EXPERIMENTAL_1, false); + private ByteBuffer data; + public ByteBuffer getData() { + return data; } - - @Override + public IPv6DefaultPayload(int protocolNumber) { + super(protocolNumber); + this.data = NetworkPacket.bufferAllocator.allocate(65535); + } public long getTotalLength() { - return 0; + return data.limit(); } - @Override public void writeToChannel(WritableByteChannel dto) throws IOException { - + dto.write(data.slice(0, data.limit())); } @Override public void readFromChannel(ReadableByteChannel din, long length) throws IOException { - + data.limit((int) length); + while (data.hasRemaining()) { + if (din.read(data) == -1) { + throw new EOFException(); + } + } } } + + /** * IPv6扩展头部基类 @@ -1131,12 +1109,16 @@ public class IPv6Packet extends NetworkPacket { public IPv6SegmentRoutingHeader(List segs) { this(); this.addresses.addAll(segs); - int ln = addresses.size() - 1; - setLastEntry(ln); - setSegmentsLeft(ln); + resetSegmentPos(); } - public int getLastEntry() { + public void resetSegmentPos() { + int ln = addresses.size() - 1; + setLastEntry(ln); + setSegmentsLeft(ln); + } + + public int getLastEntry() { return getData().get(4) & BIT_MASK_LOW_8_BITS; } diff --git a/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java b/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java index fbd3cd6..33a8ea2 100644 --- a/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java +++ b/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.LockSupport; @@ -22,12 +21,7 @@ import org.kne.cloud.network.klalb.CONST; import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl; import org.kne.cloud.network.srv6.DetNetSRv6TLV; import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV; -import org.kne.cloud.network.srv6.IpV6RoutingSRHData; -import org.kne.cloud.network.srv6.PacketConsumer; -import org.kne.cloud.network.srv6.SRv6PacketReorder; import org.kne.cloud.network.srv6.SRv6Router; -import org.kne.cloud.network.srv6.SRv6StreamSequenceTLV; -import org.kne.cloud.network.srv6.SRv6TLV; import org.kne.cloud.network.tun.InetAddressRow; import org.kne.cloud.network.tun.TUNChannel; import org.kne.cloud.network.tun.TUNNetworkDevice; @@ -94,7 +88,7 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink con.accept(IPv6TUNLoopbackNetworkLink.this, () -> { UUID pid = ipp.getPacketID(); if (pid != null) { - monitor.getUploadBandwidth().recordPacket(pid, (int) ipp.getTotalLength()); + monitor.getUploadBandwidth().recordPacket(pid,1, (int) ipp.getTotalLength()); } // ipp.setDisposeAfterSend(true); // ipp.getPayload().setDisposeAfterSend(true); @@ -203,23 +197,14 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink pack.writeToChannel(KNEChannels.newWritableChannel(tmp)); UUID pid = pack.getPacketID(); if (pid != null) { - monitor.getUploadBandwidth().recordPacket(pid, (int) pack.getTotalLength()); + monitor.getUploadBandwidth().recordPacket(pid, 1,(int) pack.getTotalLength()); } tmp.flip(); sendQueue.add(tmp); LockSupport.unpark(tr); } - private SRv6StreamSequenceTLV getStreamSequenceTLV(IpV6RoutingSRHData srh) { - List stv = srh.getTlvs(); - for (Iterator iterator = stv.iterator(); iterator.hasNext();) { - SRv6TLV sRv6TLV = (SRv6TLV) iterator.next(); - if (sRv6TLV.getType() == SRv6TLV.SEQS) { - return (SRv6StreamSequenceTLV) sRv6TLV; - } - } - return null; - } + @Override public boolean isLoopBack() { @@ -282,11 +267,11 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink for (Iterator iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) { Neighbor addresses = (Neighbor) iteratorx.next(); RouteItem ri = new RouteItem(new IPv6AddressGroup(addresses.getAddress().getAddress(), 128), - addresses.getAddress().getAddress(), this, "Direct", 0, 128, addresses.getMonitor(), "D", false); + addresses.getAddress().getAddress(), this, "Direct", 0, 128, null, "D", false); rlist.add(ri); RouteItem ris = new RouteItem(addresses.getLocator(), addresses.getLocator().getAddress(), this, - "KLALB SRv6", 13, 128, addresses.getMonitor(), "D", false); + "KLALB SRv6", 13, 128, null, "D", false); rlist.add(ris); } diff --git a/src/org/kne/cloud/network/ipv6/LoopbackIPv6NetworkLink.java b/src/org/kne/cloud/network/ipv6/LoopbackIPv6NetworkLink.java index 33e8ef8..c8695f7 100644 --- a/src/org/kne/cloud/network/ipv6/LoopbackIPv6NetworkLink.java +++ b/src/org/kne/cloud/network/ipv6/LoopbackIPv6NetworkLink.java @@ -1,19 +1,13 @@ package org.kne.cloud.network.ipv6; import java.io.IOException; -import java.net.Inet6Address; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; -import org.kne.cloud.network.srv6.PacketConsumer; import org.kne.cloud.network.srv6.SRv6Router; public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements IPv6NetworkLink { @@ -28,9 +22,9 @@ public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements this.fallbackLink = fallbackLink; } - private Map protocolNumberRegister = new ConcurrentHashMap<>(256 * 2); + private IPv6ProtocolRegister[] protocolNumberRegister = new IPv6ProtocolRegister[256]; - public Map getProtocolNumberRegister() { + public IPv6ProtocolRegister[] getProtocolNumberRegister() { return protocolNumberRegister; } @@ -46,9 +40,9 @@ public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements @Override public void sendPacket(IPv6Packet pack, IPv6Address next) throws IOException { - PacketConsumer pcm= protocolNumberRegister.get(pack.getPayload().getProtocolNumber()); + IPv6ProtocolRegister pcm= protocolNumberRegister[pack.getPayload().getProtocolNumber()]; if (pcm != null) { - if(!pcm.accept(pack)) { + if(!pcm.onaccept(pack)) { if(fallbackLink!=null) { fallbackLink.sendPacket(pack, next); } @@ -110,13 +104,13 @@ public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements for (Iterator iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) { Neighbor addresses = (Neighbor) iteratorx.next(); RouteItem ri = new RouteItem(new IPv6AddressGroup(addresses.getAddress().getAddress(), 128), - addresses.getAddress().getAddress(), this, "Direct", 0, 128, addresses.getMonitor(), "D", + addresses.getAddress().getAddress(), this, "Direct", 0, 128, null, "D", false); rlist.add(ri); RouteItem ris = new RouteItem(addresses.getLocator(), addresses.getLocator().getAddress(), this, "KLALB SRv6", 13, 128, - addresses.getMonitor(), "D", false); + null, "D", false); rlist.add(ris); } diff --git a/src/org/kne/cloud/network/ipv6/RouteItem.java b/src/org/kne/cloud/network/ipv6/RouteItem.java index 2c51cc1..4e3c67f 100644 --- a/src/org/kne/cloud/network/ipv6/RouteItem.java +++ b/src/org/kne/cloud/network/ipv6/RouteItem.java @@ -1,14 +1,7 @@ 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.IPv6AddressGroup; -import org.kne.cloud.network.monitor.DelayMonitorData; -import org.kne.cloud.network.monitor.MonitorData; +import java.util.function.Supplier; public class RouteItem implements Comparable,Cloneable{ private IPv6AddressGroup destination; @@ -18,14 +11,11 @@ public class RouteItem implements Comparable,Cloneable{ private int pre; private long cost; private String flag; - private MonitorData monitor; + private Supplier costSupplier; private boolean isLoopback; public String getFlag() { return flag; } - public MonitorData getMonitor() { - return monitor; - } @Override public int hashCode() { return Objects.hash(cost, destination, destlink, flag, nexthop, pre, proto); @@ -56,7 +46,7 @@ public class RouteItem implements Comparable,Cloneable{ this.isLoopback=isLoopback; } public RouteItem(IPv6AddressGroup destination, IPv6Address nexthop, IPv6NetworkLink destlink, String proto, int pre, - long cost,MonitorData monitor,String flag,boolean isLoopback) { + long cost,Supplier costSupplier,String flag,boolean isLoopback) { super(); this.destination = destination; this.nexthop = nexthop; @@ -64,7 +54,7 @@ public class RouteItem implements Comparable,Cloneable{ this.proto = proto; this.pre = pre; this.cost = cost; - this.monitor=monitor; + this.costSupplier=costSupplier; this.flag=flag; this.isLoopback=isLoopback; } @@ -99,6 +89,7 @@ public class RouteItem implements Comparable,Cloneable{ public boolean checkMatch(byte[] ia) { return destination.checkMatch(ia); }*/ + @Override public int compareTo(RouteItem o) { int v1=destination.compareTo(o.destination); @@ -110,22 +101,23 @@ public class RouteItem implements Comparable,Cloneable{ int v3=Long.compare(cost, o.cost); return v3; } + public Supplier getCostSupplier() { + return costSupplier; + } @Override public Object clone() { try { RouteItem ri=(RouteItem) super.clone(); - if(monitor!=null) - ri.monitor=(MonitorData) monitor.clone(); return ri; } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } - - public void preSort() { - if(monitor!=null) { - cost=((DelayMonitorData)monitor).getOutDelay(); + //在排序前调用,计算cost + public void updateCost() { + if(costSupplier!=null) { + cost=costSupplier.get(); } } public boolean ECMPequals(RouteItem prevr) { diff --git a/src/org/kne/cloud/network/ipv6/TLV.java b/src/org/kne/cloud/network/ipv6/TLV.java index da83dda..20be70c 100644 --- a/src/org/kne/cloud/network/ipv6/TLV.java +++ b/src/org/kne/cloud/network/ipv6/TLV.java @@ -43,7 +43,7 @@ public static final int PAD1=0; private boolean isDefault; - protected volatile ByteBuffer header; + protected ByteBuffer header; private ByteBuffer data; diff --git a/src/org/kne/cloud/network/klalb/BindableKLALBPacketConsumer.java b/src/org/kne/cloud/network/klalb/BindableConsumer.java similarity index 69% rename from src/org/kne/cloud/network/klalb/BindableKLALBPacketConsumer.java rename to src/org/kne/cloud/network/klalb/BindableConsumer.java index 913d48e..4a5c7d4 100644 --- a/src/org/kne/cloud/network/klalb/BindableKLALBPacketConsumer.java +++ b/src/org/kne/cloud/network/klalb/BindableConsumer.java @@ -1,9 +1,9 @@ package org.kne.cloud.network.klalb; import java.net.InetAddress; -import java.net.ServerSocket; +import java.util.function.Consumer; -public interface BindableKLALBPacketConsumer extends PacketConsumer { +public interface BindableConsumer extends Consumer { public InetAddress getRemoteInetAddress() ; public InetAddress getLocalInetAddress() ; public int getPort() ; diff --git a/src/org/kne/cloud/network/klalb/CONST.java b/src/org/kne/cloud/network/klalb/CONST.java index 822420a..fbddc50 100644 --- a/src/org/kne/cloud/network/klalb/CONST.java +++ b/src/org/kne/cloud/network/klalb/CONST.java @@ -18,4 +18,6 @@ public class CONST { public static final int linepanelheight = 41; public static final int settingheight = 30; public static final int dialwidth = 150; + public static final int windowwidth = 1200; + public static final int windowheight = 800; } diff --git a/src/org/kne/cloud/network/klalb/DATATPacket.java b/src/org/kne/cloud/network/klalb/DATATPacket.java index f386468..ff76593 100644 --- a/src/org/kne/cloud/network/klalb/DATATPacket.java +++ b/src/org/kne/cloud/network/klalb/DATATPacket.java @@ -6,6 +6,7 @@ import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.util.Arrays; +import java.util.concurrent.atomic.AtomicInteger; import org.kne.cloud.network.NetworkPacket; @@ -101,7 +102,16 @@ public class DATATPacket extends KLALBPacket implements PortPacket{ public int getSize() { return dataBuffer.limit(); } + private int sendCounter=0; + public int getSendCounter() { + return sendCounter; + } + + public void incSendCounter() { + sendCounter++; + } + @Override public void writeToChannel(WritableByteChannel dto) throws IOException { klalbHeader.put(17, (byte) getSendCounter()); @@ -126,6 +136,6 @@ public class DATATPacket extends KLALBPacket implements PortPacket{ } dataBuffer.flip(); } - + } diff --git a/src/org/kne/cloud/network/klalb/KLALBController.java b/src/org/kne/cloud/network/klalb/KLALBController.java index 13e6750..4ad7189 100644 --- a/src/org/kne/cloud/network/klalb/KLALBController.java +++ b/src/org/kne/cloud/network/klalb/KLALBController.java @@ -7,42 +7,30 @@ import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; -import java.net.NoRouteToHostException; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; -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.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Map.Entry; -import java.util.Scanner; import java.util.Set; import java.util.Timer; import java.util.TimerTask; import java.util.UUID; 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.ThreadPoolExecutor; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; 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 org.kne.cloud.clock.AdjustedNanoClock; import org.kne.cloud.clock.HighAccuracyClock; import org.kne.cloud.network.IPMulticastDiscovery; import org.kne.cloud.network.MultipurposeSocketAddress; @@ -50,41 +38,27 @@ import org.kne.cloud.network.PortPair; import org.kne.cloud.network.SocketType; import org.kne.cloud.network.ThreadTool; import org.kne.cloud.network.ipv6.IPv6Address; +import org.kne.cloud.network.ipv6.IPv6AddressGroup; 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.IPv6AddressGroup; -import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink; import org.kne.cloud.network.ipv6.Neighbor; -import org.kne.cloud.network.ipv6.PacketID; +import org.kne.cloud.network.kltp.KLTPPacket; +import org.kne.cloud.network.kltp.KLTPProtocolRegister; import org.kne.cloud.network.monitor.HashMapTimestampMonitor; -import org.kne.cloud.network.monitor.MonitorData; import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl; -import org.kne.cloud.network.monitor.TimestampMonitor; import org.kne.cloud.network.ntp.NTPContext; import org.kne.cloud.network.ntp.NTPv4Packet; import org.kne.cloud.network.ntp.NTPv4Protocol; import org.kne.cloud.network.ntp.NTPv4Protocol.NTPPeer; -import org.kne.cloud.network.srv6.JsonDataPacket; import org.kne.cloud.network.srv6.KLALBRoutingProtocol; import org.kne.cloud.network.srv6.KLALBRoutingProtocolAPIClient; import org.kne.cloud.network.srv6.KLALBRoutingProtocolAPIServer; -import org.kne.cloud.network.srv6.KLALBRoutingProtocolJsonData; -import org.kne.cloud.network.srv6.PacketConsumer; import org.kne.cloud.network.srv6.SRv6Router; import org.kne.cloud.network.srv6.SRv6RouterListener; import org.kne.cloud.network.tcp.UDPPacket; +import org.kne.cloud.network.tcp.UDPProtocolRegister; import org.kne.cloud.network.te.BandwidthDistributer; -import org.kne.cloud.network.te.DWRRLoadingBalanceAlgorithm; -import org.kne.concurrent.DisruptorExecutor; -import org.kne.concurrent.HighPerformanceExecutor; -import org.kne.io.KNEChannels; -import org.pcap4j.packet.IpV6Packet.IpV6Header; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; public class KLALBController { private UUID nodeuuid=UUID.randomUUID(); @@ -93,14 +67,14 @@ public class KLALBController { public HighAccuracyClock getClock() { return clock; } - + private final long TIME_WINDOW=5000000000L; private SpeedAndTrafficMonitorDataImpl linkMonitor = new SpeedAndTrafficMonitorDataImpl( - new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "up", 100, 500000000L), - new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, 500000000L)); + new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "up", 100,TIME_WINDOW ), + new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, TIME_WINDOW)); private SpeedAndTrafficMonitorDataImpl datatMonitor = new SpeedAndTrafficMonitorDataImpl( - new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "up", 100, 500000000L), - new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, 500000000L)); + new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "up", 100, TIME_WINDOW), + new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, TIME_WINDOW)); private List selflineTable = new ArrayList<>(); @@ -123,6 +97,17 @@ public class KLALBController { public List getDnsAddresses() { return dnsAddresses; } + private ScheduledExecutorService scheduleTimer=Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(),new ThreadFactory() { + + @Override + public Thread newThread(Runnable r) { + return ThreadTool.makeVDaemonThreadIfSupport("计时器线程", r); + } + }); + + public ScheduledExecutorService getScheduleTimer() { + return scheduleTimer; + } private Timer twk = new Timer("网卡检测扫描计时器", true); @@ -193,8 +178,8 @@ public class KLALBController { Set st = new HashSet<>(); for (Iterator iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) { IPv6NetworkLink link = iterator.next(); - if (link instanceof KLALBRemoteLine) { - KLALBRemoteLine multipurposeSocketAddress = (KLALBRemoteLine) link; + if (link instanceof KLALBRemoteLink) { + KLALBRemoteLink multipurposeSocketAddress = (KLALBRemoteLink) link; if (multipurposeSocketAddress.getSocketAddress() != null) st.add(multipurposeSocketAddress.getSocketAddress()); } @@ -206,8 +191,8 @@ public class KLALBController { } for (Iterator iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) { IPv6NetworkLink link = iterator.next(); - if (link instanceof KLALBRemoteLine) { - KLALBRemoteLine reml = (KLALBRemoteLine) link; + if (link instanceof KLALBRemoteLink) { + KLALBRemoteLink reml = (KLALBRemoteLink) link; if (reml.getSocketAddress() != null) { if (reml.getBindAddress() != null || reml.getRemoteVaddr() != null) try { @@ -237,6 +222,8 @@ public class KLALBController { updateBroadcastNetworkInterface(); } catch (SocketException e) { + }catch (Exception e) { + e.printStackTrace(); } } @@ -448,21 +435,11 @@ public class KLALBController { return datagramSocketType; } - // private Supplier selflineTableSupplier=()->{return null;}; - - /* - * public Supplier getSelflineTableSupplier() { return - * selflineTableSupplier; } - * - * public void setSelflineTableSupplier(Supplier selflineTableSupplier) - * { this.selflineTableSupplier = selflineTableSupplier; } - */ public List getSelflineTable() { return selflineTable; } - // private Inet6AddressGroup self; public IPv6AddressGroup getSelf() { return srv6Router.getLocator(); @@ -474,30 +451,14 @@ public class KLALBController { return srv6Router.getLinkTabel(); } - private PortBinder streamPortBinder = new PortBinder(this); - private PortBinder datagramPortBinder = new PortBinder(this); - - private PortBinder rawPortBinder = new PortBinder(this); - - protected PortBinder getStreamPortBinder() { - return streamPortBinder; - } - - protected PortBinder getDatagramPortBinder() { - return datagramPortBinder; - } - - protected PortBinder getRawPortBinder() { - return rawPortBinder; - } public void reconnectImmediately() { for (Iterator iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) { IPv6NetworkLink val = iterator.next(); - if (val instanceof KLALBRemoteLine) { + if (val instanceof KLALBRemoteLink) { - KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) val; + KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) val; klalbRemoteLine.reconnectImmediately(); } } @@ -510,34 +471,17 @@ public class KLALBController { private KLALBRoutingProtocolAPIClient apiClient; private KLALBControllerConfigItem configItem; - - /* - * private PacketReceiver prc = new PacketReceiver(); private class - * PacketReceiver implements Consumer { - * - * @Override 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); - * - * } }).start(); break; default: break; - * - * } } - * - * } - */ + public void addRemoteLines(List select) { for (MultipurposeSocketAddress target : select) { addRemoteLines(target); } } - public List addRemoteLines(MultipurposeSocketAddress target) { + public List addRemoteLines(MultipurposeSocketAddress target) { lineslock.writeLock().lock(); try { - List added = new ArrayList<>(); + List added = new ArrayList<>(); try { Enumeration eu = NetworkInterface.getNetworkInterfaces(); while (eu.hasMoreElements()) { @@ -583,7 +527,7 @@ public class KLALBController { count=1; } for(int i=0;i removeRemoteLines(MultipurposeSocketAddress mpsa) { + public List removeRemoteLines(MultipurposeSocketAddress mpsa) { - List rmved = new ArrayList<>(); + List rmved = new ArrayList<>(); for (Iterator iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) { IPv6NetworkLink link = iterator.next(); - if (link instanceof KLALBRemoteLine) { - KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link; + if (link instanceof KLALBRemoteLink) { + KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link; if (mpsa.equals(klalbRemoteLine.getSocketAddress())) { klalbRemoteLine.close(); rmved.add(klalbRemoteLine); @@ -626,11 +570,11 @@ public class KLALBController { } public Inet6Address getRemoteVaddrBySocketAddress(MultipurposeSocketAddress target) throws SocketTimeoutException { - KLALBRemoteLine kr = null; + KLALBRemoteLink kr = null; for (Iterator iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) { IPv6NetworkLink link = iterator.next(); - if (link instanceof KLALBRemoteLine) { - KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link; + if (link instanceof KLALBRemoteLink) { + KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link; if (target.equals(klalbRemoteLine.getSocketAddress()) && klalbRemoteLine.getBindAddress() == null) { kr = klalbRemoteLine; break; @@ -639,7 +583,7 @@ public class KLALBController { } if (kr == null) { - kr = new KLALBRemoteLine(this, target); + kr = new KLALBRemoteLink(this, target); addRemoteLine(kr); kr.waitForRemoteVaddrAvaliable(20000); } else { @@ -653,8 +597,8 @@ public class KLALBController { boolean b = false; for (Iterator iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) { IPv6NetworkLink link = iterator.next(); - if (link instanceof KLALBRemoteLine) { - KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link; + if (link instanceof KLALBRemoteLink) { + KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link; if (bind.equals2(klalbRemoteLine.getBindAddress()) && target.equals2(klalbRemoteLine.getSocketAddress())) { b = true; @@ -669,8 +613,8 @@ public class KLALBController { boolean b = false; for (Iterator iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) { IPv6NetworkLink link = iterator.next(); - if (link instanceof KLALBRemoteLine) { - KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link; + if (link instanceof KLALBRemoteLink) { + KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link; if (target.equals(klalbRemoteLine.getSocketAddress())) { b = true; break; @@ -680,12 +624,9 @@ public class KLALBController { return b; } - public void addRemoteLine(KLALBRemoteLine krs) { + public void addRemoteLine(KLALBRemoteLink krs) { lineslock.writeLock().lock(); try { - krs.setLocalVaddrSupplier(() -> { - return getSelf(); - }); krs.startIO(); String selflineTable = generateSelfLineTable(); if (selflineTable != null && !selflineTable.equals("")) @@ -706,63 +647,26 @@ public class KLALBController { return sbd.toString(); } - private class UDPProtocolPacketConsumer implements PacketConsumer { - - @Override - public boolean accept(IPv6Packet packx) throws IOException { - - IPv6Payload pl = packx.getPayload(); - packx.putTimePassport("unpacked"); - packx.printPassport(); - if (pl instanceof UDPPacket) { - UDPPacket rec = (UDPPacket) pl; - if (showpacket) - System.out.println("UDP_RX:" + rec); - IPv6Address srcA = packx.getSourceAddress(); - PortPacket pt = (PortPacket) rec; - if (datagramPortBinder.distributePacketToConsumer(srcA, pt)) { - return true; - } - } - return false; - // packx.dispose(); - // }); - } + + + private UDPProtocolRegister udpr; + public UDPProtocolRegister getUDPregister() { + return udpr; + } + + private KLTPProtocolRegister kltpr; + public KLTPProtocolRegister getKLTPregister() { + return kltpr; } - private class KLALBProtocolPacketConsumer implements PacketConsumer { - @Override - public boolean accept(IPv6Packet packx) throws IOException { - IPv6Payload pl = packx.getPayload(); - packx.putTimePassport("unpacked"); - packx.printPassport(); - if (pl instanceof KLALBPacket) { - KLALBPacket rec = (KLALBPacket) pl; - if (showpacket) - System.out.println("KLALB_RX:" + rec); - if (rec instanceof PortPacket) { - rec.setCE(packx.isCE()); - IPv6Address srcA = packx.getSourceAddress(); - PortPacket pt = (PortPacket) rec; - if (streamPortBinder.distributePacketToConsumer(srcA, pt)) { - } else { - if (!(pt instanceof RSTPacket)) { - srv6Router.enqueuePacketSendTask(() -> { - return createPacketToAddress(srcA, 0, new RSTPacket(pt.getDstPort(), pt.getSrcPort()), - 2); - }); - } - } - } - } - return true; - // packx.dispose(); - } + private PortBinder rawPortBinder ; + protected PortBinder getRawPortBinder() { + return rawPortBinder; } - + private void loadSRv6ProtocolStack(IPv6AddressGroup selfx, boolean enableVirtualAdapter) { srv6Router = new SRv6Router(selfx, clock); srv6Router.runKLALBRouteProtocol(); @@ -770,11 +674,12 @@ public class KLALBController { routingProtocol.addReceiver((addr, packet) -> { }); - + rawPortBinder= new PortBinder(this.getSelf().getAddress()); System.out.println(" Loaded: SRv6 Stack"); String name=(configItem!=null)?configItem.getTUNName():CONST.KLALB_S_RV6; if (enableVirtualAdapter&&(name!=null)) { + Thread t=new Thread(()->{ try { IPv6TUNLoopbackNetworkLink tunlink = new IPv6TUNLoopbackNetworkLink(name, new IPv6AddressGroup(srv6Router.getLocator().getAddress(), 32), SRv6Router.MTU, dnsAddresses); @@ -787,18 +692,23 @@ public class KLALBController { System.err.println("挂载虚拟网卡失败,可能是无管理员权限?请尝试使用管理员权限运行软件"); e.printStackTrace(); } + }); + t.start(); }else { System.out.println(" Tun Adapter Disbaled"); } - srv6Router.getinLoopback().getProtocolNumberRegister().put(UDPPacket.UDP_PROTOCOL_NUMBER, - new UDPProtocolPacketConsumer()); + udpr=new UDPProtocolRegister(this); + srv6Router.getinLoopback().getProtocolNumberRegister()[UDPPacket.UDP_PROTOCOL_NUMBER]= + udpr; System.out.println(" Loaded: UDP Protocol"); - srv6Router.getinLoopback().getProtocolNumberRegister().put(KLALBPacket.KLALB_PROTOCOL_NUMBER, - new KLALBProtocolPacketConsumer()); - System.out.println(" Loaded: KLALB Protocol"); + kltpr=new KLTPProtocolRegister(this); + srv6Router.getinLoopback().getProtocolNumberRegister()[KLTPPacket.KLTP_PROTOCOL_NUMBER]= + kltpr; + System.out.println(" Loaded: KLTP Protocol"); String iproxyname = "KLALB_" + UUID.randomUUID(); registerToProxyTypeAs(iproxyname); + System.out.println(" Loaded: KLALB Protocol"); NTPContext context = new NTPContext(clock); context.syncToSystem(); @@ -812,7 +722,6 @@ public class KLALBController { public void onLinkChanged(SRv6Router router, IPv6NetworkLink link) { List nb = router.getNeighbors(); - // System.out.println("srv6 ip"+nb); Set sp = nvc.getPeers(); for (Neighbor neighbor : nb) { if (neighbor.getLocator() != null) @@ -873,6 +782,17 @@ public class KLALBController { } protected void initKLALB(boolean enableVirtualAdapter, IPv6AddressGroup selfg) { + ThreadTool.makeVDaemonThread("线路性能采样线程", ()->{ + while(true) { + linkMonitor.update(); + datatMonitor.update(); + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }).start(); loadSRv6ProtocolStack(selfg, enableVirtualAdapter); loadController(); } @@ -973,7 +893,7 @@ public class KLALBController { public void run() { if (srv6Router != null) { srv6Router.getLinkTabel().removeIf((v) -> { - return (v instanceof KLALBRemoteLine) && ((KLALBRemoteLine) v).isClosed(); + return (v instanceof KLALBRemoteLink) && ((KLALBRemoteLink) v).isClosed(); }); srv6Router.updateRouteTabel(); } @@ -992,13 +912,12 @@ public class KLALBController { }, 10, 10); } - protected IPv6Packet createPacketToAddress(IPv6Address addr, int flowlabel, IPv6Packet.IPv6Payload packet) { + public IPv6Packet createPacketToAddress(IPv6Address addr, int flowlabel, IPv6Packet.IPv6Payload packet) { return createPacketToAddress(addr, flowlabel, packet, 1); } - protected IPv6Packet createPacketToAddress(IPv6Address addr, int flowlabel, IPv6Packet.IPv6Payload packet, + public IPv6Packet createPacketToAddress(IPv6Address addr, int flowlabel, IPv6Packet.IPv6Payload packet, int count) { - // HighPerformanceExecutor.defaultExecutor.execute(() -> { IPv6Packet ipv = new IPv6Packet(); @@ -1006,23 +925,17 @@ public class KLALBController { System.out.println("KLALB_TX:" + packet); ipv.setVersion(6); - ipv.setTrafficClass(0); + ipv.setTrafficClass(0b10); ipv.setFlowLabel(flowlabel); ipv.setHopLimit(255); ipv.setSourceAddress(getSelf().getAddress()); ipv.setDestinationAddress(addr); - ipv.enableECN(); - ipv.setPayload(packet); packet.setParent(ipv); - if (packet instanceof KLALBPacket) - ((KLALBPacket) packet).incSendCounter(); + - packet.putTimePassport("packedInIPv6"); - packet.printPassport(); - ipv.putTimePassport("packed"); return ipv; } @@ -1088,19 +1001,11 @@ public class KLALBController { } - private Timer t = new Timer("数据包重传计时器", true); + - protected Timer getResendTimer() { - return t; - } - - private Timer t2 = new Timer("数据包粘包计时器", true); private List listens = new CopyOnWriteArrayList<>(); - public Timer getNagleTimer() { - return t2; - } public void registerToProxyTypeAs(String proxyname) { MultipurposeSocketAddress.getSocketTypeRegister().put(proxyname + "_Stream", streamSocketType); @@ -1117,34 +1022,15 @@ public class KLALBController { private KLALBRoutingProtocol routingProtocol; public List getNTPTable() { - return ntptable;// nvc2.getPeers().add(new NTPPeer("{UDP}106.55.184.199:123", - // NTPv4Packet.NTP_CLIENT)); + return ntptable; } public KLALBControllerConfigItem getConfigItem() { return configItem; } - /* - * @Override public void listen(MultipurposeSocketAddress msa) { // TODO - * 自动生成的方法存根 - * - * } - * - * @Override public void unlisten(MultipurposeSocketAddress msc) { // TODO - * 自动生成的方法存根 - * - * } - * - * @Override public void connect(MultipurposeSocketAddress msa) { // TODO - * 自动生成的方法存根 - * - * } - * - * @Override public void unconnect(MultipurposeSocketAddress msc) { // TODO - * 自动生成的方法存根 - * - * } - */ + + + } diff --git a/src/org/kne/cloud/network/klalb/KLALBControllerConfigItem.java b/src/org/kne/cloud/network/klalb/KLALBControllerConfigItem.java index 1043faf..0178a84 100644 --- a/src/org/kne/cloud/network/klalb/KLALBControllerConfigItem.java +++ b/src/org/kne/cloud/network/klalb/KLALBControllerConfigItem.java @@ -1,16 +1,11 @@ package org.kne.cloud.network.klalb; import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import org.kne.cloud.network.MultipurposeSocketAddress; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - public class KLALBControllerConfigItem extends KLALBConfigItem { private String language; private boolean nogui; @@ -26,6 +21,7 @@ public class KLALBControllerConfigItem extends KLALBConfigItem { private boolean denyLineTableQuery=false; private boolean denyLineTableBroadcast=false; private String congestionAlgorithm="BBR"; + private double burstLimit=1.20; private double delayUpperBound=1.20; private double delayLowerBound=1.15; private long nagleDelayTime=1000000L; @@ -205,6 +201,18 @@ public class KLALBControllerConfigItem extends KLALBConfigItem { } + + + + + public double getBurstLimit() { + return burstLimit; + } + + + public void setBurstLimit(double burstLimit) { + this.burstLimit = burstLimit; + } public double getDelayUpperBound() { diff --git a/src/org/kne/cloud/network/klalb/KLALBInputStream.java b/src/org/kne/cloud/network/klalb/KLALBInputStream.java index f431a5f..d1f36d2 100644 --- a/src/org/kne/cloud/network/klalb/KLALBInputStream.java +++ b/src/org/kne/cloud/network/klalb/KLALBInputStream.java @@ -1,13 +1,9 @@ package org.kne.cloud.network.klalb; -import static org.kne.cloud.network.klalb.KLALBPacket.*; -import java.io.DataInput; import java.io.DataInputStream; -import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.StreamCorruptedException; -import java.net.Inet6Address; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; @@ -24,7 +20,7 @@ public class KLALBInputStream extends DataInputStream { readFully(b); String s=new String(b,"ascii"); if(!s.equals("KLALB")) { - throw new StreamCorruptedException("no KLALB format"); + throw new StreamCorruptedException("remote protocol is no KLALB format"); } int bv=readInt(); int mv=readInt(); diff --git a/src/org/kne/cloud/network/klalb/KLALBMain.java b/src/org/kne/cloud/network/klalb/KLALBMain.java index 6df36ef..ba10b7e 100644 --- a/src/org/kne/cloud/network/klalb/KLALBMain.java +++ b/src/org/kne/cloud/network/klalb/KLALBMain.java @@ -4,7 +4,6 @@ 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; @@ -12,20 +11,17 @@ import java.util.List; import java.util.NoSuchElementException; 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.IPv6NetworkLink; import org.kne.cloud.network.ipv6.RouteItem; import org.kne.cloud.network.klalb.ui.KLALBStateGUI3; import org.kne.cloud.network.klalb.ui.UIEnv; import org.kne.cloud.network.perf.Kperf; import org.kne.cloud.network.perf.NodeBenchmark; -import org.kne.debug.Debuger; import org.kne.debug.TimeDebugger; import org.kne.membandboost.MembandBenchmark; +import org.kne.membandboost.ObjectPoolBandwidthTest; public class KLALBMain { public static KLALBStateGUI3 ksg; @@ -90,8 +86,9 @@ public class KLALBMain { System.out.println(" links-add : add link"); System.out.println(" links-remove : remove link"); System.out.println(" links-reconnect: reconnect all link"); + System.out.println(" kltp-state: query kltp states"); System.out.println(" route: display internal route table"); - System.out.println(" kperf : Porformance benchmark"); + System.out.println(" kperf : performance benchmark"); System.out.println(" exit: Exit"); break; @@ -104,12 +101,13 @@ public class KLALBMain { break; case "links-state": System.out.println("links state:"); - System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t上传延迟\t下载延迟\t上传抖动\t下载抖动"); + //System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t上传延迟\t下载延迟\t上传抖动\t下载抖动"); + System.out.println("state\tspd↑\tspd↓\tPPS↑\tPPS↓\tdelay↑\tdelay↓\tjitter↑\tjitter↓"); synchronized (kpcje.getKlalbController().getLines()) { for (Iterator iterator = kpcje.getKlalbController().getLines().iterator(); iterator.hasNext();) { IPv6NetworkLink link=iterator.next(); - if(link instanceof KLALBRemoteLine) { - KLALBRemoteLine hostPort = (KLALBRemoteLine) link; + if(link instanceof KLALBRemoteLink) { + KLALBRemoteLink hostPort = (KLALBRemoteLink) link; System.out.println(hostPort .toString()); } } @@ -118,31 +116,34 @@ public class KLALBMain { case "links-add": if(sc.length>=2) { MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(sc[1]); - Listaddl=kpcje.getKlalbController().addRemoteLines(mpsa); + Listaddl=kpcje.getKlalbController().addRemoteLines(mpsa); if(addl.isEmpty()) { - System.out.println("添加失败,线路已存在!"); + //System.out.println("添加失败,线路已存在!"); + System.out.println("link already exist!"); }else { - for (Iterator iterator = addl.iterator(); iterator.hasNext();) { - KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next(); + for (Iterator iterator = addl.iterator(); iterator.hasNext();) { + KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) iterator.next(); - System.out.println("添加成功:"+klalbRemoteLine.getMonitor().getName()); + //System.out.println("添加成功:"+klalbRemoteLine.getMonitor().getName()); + System.out.println("Successfully added: "+klalbRemoteLine.getName()); } } }else { - System.out.println("请输入要添加地址:端口!"); + // System.out.println("请输入要添加地址:端口!"); + System.out.println("Input Address:port"); } break; case "links-remove": if(sc.length>=2) { MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(sc[1]); - Listrmvl=kpcje.getKlalbController().removeRemoteLines(mpsa); + Listrmvl=kpcje.getKlalbController().removeRemoteLines(mpsa); if(rmvl.isEmpty()) { System.out.println("No matched link has been found."); }else { for (Iterator iterator = rmvl.iterator(); iterator.hasNext();) { - KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next(); + KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) iterator.next(); - System.out.println("Successfully removed: "+klalbRemoteLine.getMonitor().getName()); + System.out.println("Successfully removed: "+klalbRemoteLine.getName()); } } }else { @@ -157,6 +158,9 @@ public class KLALBMain { System.out.println("Trying to reconnect all links."); kpcje.getKlalbController().reconnectImmediately(); break; + case "kltp-state": + System.out.println(kpcje.getKlalbController().getKLTPregister().toString()); + break; case "route": List lri=new ArrayList<>( kpcje.getKlalbController().getIpv6Router().getCurrentRouteTabel()); Collections.sort(lri); @@ -178,9 +182,13 @@ public class KLALBMain { } break; - case "memcpy": + case "membandbenchmark": MembandBenchmark.main(args); break; + case "memqueuebenchmark": + + ObjectPoolBandwidthTest.main(args); + break; //case "$$SYSTEM:": //System.out.println(); //break; diff --git a/src/org/kne/cloud/network/klalb/KLALBPacket.java b/src/org/kne/cloud/network/klalb/KLALBPacket.java index 04815b4..03c8124 100644 --- a/src/org/kne/cloud/network/klalb/KLALBPacket.java +++ b/src/org/kne/cloud/network/klalb/KLALBPacket.java @@ -9,10 +9,6 @@ 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.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; import org.kne.cloud.network.NetworkPacket; import org.kne.cloud.network.ipv6.IPv6Packet; @@ -52,13 +48,13 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload { protected ByteBuffer klalbHeader; protected KLALBPacket(ByteBuffer klalbHeader,int headerLength) { - super(KLALB_PROTOCOL_NUMBER,false); + super(KLALB_PROTOCOL_NUMBER); this.klalbHeader = klalbHeader; this.headerLength=headerLength; } public KLALBPacket(int type,int headerLength) { - super(KLALB_PROTOCOL_NUMBER,false); + super(KLALB_PROTOCOL_NUMBER); klalbHeader=NetworkPacket.bufferAllocator.allocate(headerLength); klalbHeader.put((byte) type); this.headerLength=headerLength; @@ -113,24 +109,6 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload { return headerLength; } - - - //private List sendRecord=new ArrayList<>(2); - - private AtomicInteger sendCounter=new AtomicInteger(0); - - public int getSendCounter() { - return sendCounter.get(); - } - - public void incSendCounter() { - sendCounter.incrementAndGet(); - } - /*public List getSendRecord() { - return sendRecord; - }*/ - - protected ByteBuffer getKLALBHeader() { return klalbHeader; } diff --git a/src/org/kne/cloud/network/klalb/KLALBProtocolDetectSocketListener.java b/src/org/kne/cloud/network/klalb/KLALBProtocolDetectSocketListener.java index 9a40ec8..55a92e2 100644 --- a/src/org/kne/cloud/network/klalb/KLALBProtocolDetectSocketListener.java +++ b/src/org/kne/cloud/network/klalb/KLALBProtocolDetectSocketListener.java @@ -44,9 +44,9 @@ public class KLALBProtocolDetectSocketListener extends SocketListener { super.setCon((soc)->{ ProtocolDetectorSocket pds=(ProtocolDetectorSocket) soc; if(!pds.getProtocolStack().isEmpty()&&pds.getProtocolStack().pop().getName().equals("KLALB")) { - KLALBRemoteLine krs=null; + KLALBRemoteLink krs=null; try { - krs = new KLALBRemoteLine(klalbController,new StreamKLALBPacketLink(pds)); + krs = new KLALBRemoteLink(klalbController,new StreamKLALBPacketLink(pds)); klalbController.addRemoteLine(krs); } catch (Exception e) { e.printStackTrace(); diff --git a/src/org/kne/cloud/network/klalb/KLALBProxySystem.java b/src/org/kne/cloud/network/klalb/KLALBProxySystem.java index 73ed0f4..dadba00 100644 --- a/src/org/kne/cloud/network/klalb/KLALBProxySystem.java +++ b/src/org/kne/cloud/network/klalb/KLALBProxySystem.java @@ -5,39 +5,20 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; -import java.net.Inet6Address; -import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.NetworkInterface; -import java.net.Socket; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import org.kne.cloud.network.*; import org.kne.cloud.network.klalb.ui.KLALBStateGUI3; import org.kne.cloud.network.klalb.ui.Language; import org.kne.cloud.network.klalb.ui.UIEnv; -import org.kne.cloud.network.minecraft.MinecraftSocketBridge; import java.util.Set; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; public class KLALBProxySystem { private Set proxys=new HashSet<>(); @@ -158,9 +139,9 @@ public class KLALBProxySystem { tcpl.setCon((soc)->{ - KLALBRemoteLine krs=null; + KLALBRemoteLink krs=null; try { - krs = new KLALBRemoteLine(klalbController,new StreamChannelKLALBPacketLink(soc)); + krs = new KLALBRemoteLink(klalbController,new StreamChannelKLALBPacketLink(soc)); klalbController.addRemoteLine(krs); } catch (IOException e) { e.printStackTrace(); @@ -181,9 +162,9 @@ public class KLALBProxySystem { udpl.setCon((soc)->{ - KLALBRemoteLine krs=null; + KLALBRemoteLink krs=null; try { - krs = new KLALBRemoteLine(klalbController,new SplitedDatagramKLALBPacketLink(soc)); + krs = new KLALBRemoteLink(klalbController,new SplitedDatagramKLALBPacketLink(soc)); klalbController.addRemoteLine(krs); } catch (IOException e) { e.printStackTrace(); diff --git a/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java b/src/org/kne/cloud/network/klalb/KLALBRemoteLink.java similarity index 75% rename from src/org/kne/cloud/network/klalb/KLALBRemoteLine.java rename to src/org/kne/cloud/network/klalb/KLALBRemoteLink.java index e062b37..335a004 100644 --- a/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java +++ b/src/org/kne/cloud/network/klalb/KLALBRemoteLink.java @@ -1,80 +1,55 @@ package org.kne.cloud.network.klalb; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.PrintStream; import java.io.StreamCorruptedException; -import java.lang.ModuleLayer.Controller; -import java.math.BigInteger; -import java.net.Inet6Address; -import java.net.InetAddress; import java.net.SocketTimeoutException; -import java.net.UnknownHostException; import java.nio.channels.UnresolvedAddressException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Queue; import java.util.UUID; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.LongAdder; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; 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 org.jctools.queues.MpscArrayQueue; import org.kne.cloud.clock.HighAccuracyClock; import org.kne.cloud.clock.NTPTimestamps; import org.kne.cloud.clock.ReliabilityBackoffTimeClock; import org.kne.cloud.clock.WatchDogTimer; import org.kne.cloud.network.MultipurposeSocketAddress; -import org.kne.cloud.network.SpeedLimiter; import org.kne.cloud.network.ThreadTool; import org.kne.cloud.network.congestion.BBRCongestionAlgorithm; import org.kne.cloud.network.congestion.CongestionAlgorithm; +import org.kne.cloud.network.congestion.CongestionAlgorithms; import org.kne.cloud.network.congestion.DetnetCongestionAlgorithm; import org.kne.cloud.network.congestion.SendPacketSlidingWindow; -import org.kne.cloud.network.congestion.Vegas2CongestionAlgorithm; import org.kne.cloud.network.ipv6.ControlledIPv6NetworkLink; -import org.kne.cloud.network.ipv6.ICMPv6PostcardPacket; import org.kne.cloud.network.ipv6.IPv6Address; import org.kne.cloud.network.ipv6.IPv6HopByHopTLV; -import org.kne.cloud.network.ipv6.IPv6NetworkLink; import org.kne.cloud.network.ipv6.IPv6Packet; -import org.kne.cloud.network.ipv6.IPv6Packet.IPv6EmptyPayload; import org.kne.cloud.network.ipv6.IPv6Packet.IPv6HopByHopHeader; -import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader; import org.kne.cloud.network.ipv6.IPv6AddressGroup; import org.kne.cloud.network.ipv6.KLALBOAMHopByHopTLV; import org.kne.cloud.network.ipv6.KLALBPassportHopByHopTLV; import org.kne.cloud.network.ipv6.Neighbor; -import org.kne.cloud.network.ipv6.PacketID; -import org.kne.cloud.network.ipv6.PacketIDGenerator; import org.kne.cloud.network.ipv6.PostcardEntry; import org.kne.cloud.network.ipv6.RouteItem; -import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.CostSupplierFactory; +import org.kne.cloud.network.monitor.DelayMonitorData; +import org.kne.cloud.network.monitor.LinkStatus; import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; import org.kne.cloud.network.perf.TESTNPacket; -import org.kne.cloud.network.srv6.ACKSEQSSegmentRoutingTLV; -import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV; -import org.kne.cloud.network.srv6.SRv6Router; import org.kne.cloud.network.te.BandwidthDistributer; -import org.kne.concurrent.HighPerformanceExecutor; import org.kne.concurrent.SpinLock; import org.kne.concurrent.ThreadParker; import org.kne.math.Long128; -import com.github.f4b6a3.uuid.UuidCreator; - -public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implements ControlledIPv6NetworkLink { +public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implements ControlledIPv6NetworkLink { private static final int HEADER_CALIBRATE = 40; @@ -84,8 +59,6 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement private volatile boolean closed = false; - private volatile Supplier localVaddrSupplier; - private volatile KLALBController klalbController; public KLALBController getKlalbController() { @@ -93,14 +66,6 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement } - public Supplier getLocalVaddrSupplier() { - return localVaddrSupplier; - } - - public void setLocalVaddrSupplier(Supplier localVaddrSupplier) { - this.localVaddrSupplier = localVaddrSupplier; - } - private volatile IPv6AddressGroup remoteVaddr; public IPv6AddressGroup getRemoteVaddr() { @@ -128,9 +93,11 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement } public String toString() { - return remoteVaddr + "\t" + monitor.toString(); + return remoteVaddr + "\t" +name+"\n" +status+"\t"+monitor.toString(); } + private String name; + private LinkStatus status=new LinkStatus(); private SpeedAndTrafficAndDelayMonitorDataImpl monitor; private volatile KLALBPacketLink kplink; private MultipurposeSocketAddress bindAddress; @@ -167,20 +134,20 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement return peerAddress; } - public KLALBRemoteLine(KLALBController controller, MultipurposeSocketAddress mpa, IPv6AddressGroup address) { + public KLALBRemoteLink(KLALBController controller, MultipurposeSocketAddress mpa, IPv6AddressGroup address) { this(controller,mpa, null,address); } - public KLALBRemoteLine(KLALBController controller,KLALBPacketLink kpl, IPv6AddressGroup address) { + public KLALBRemoteLink(KLALBController controller,KLALBPacketLink kpl, IPv6AddressGroup address) { this.klalbController=controller; sysclk = klalbController.getClock(); this.kplink = kpl; this.addressGroup = address; monitor=new SpeedAndTrafficAndDelayMonitorDataImpl(sysclk); - monitor.setName(kpl.toString()); + name=kpl.toString(); } - private KLALBRemoteLine(KLALBController controller,MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr, IPv6AddressGroup address) { + private KLALBRemoteLink(KLALBController controller,MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr, IPv6AddressGroup address) { this.klalbController=controller; sysclk = klalbController.getClock(); this.socketAddress = mpa; @@ -188,22 +155,22 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement this.addressGroup = address; monitor=new SpeedAndTrafficAndDelayMonitorDataImpl(sysclk); if (bindaddr == null) { - monitor.setName("→" + mpa.toString()); + name="→" + mpa.toString(); } else { - monitor.setName(bindaddr.toString() + "→" + mpa.toString()); + name=bindaddr.toString() + "→" + mpa.toString(); } } - public KLALBRemoteLine(KLALBController controller,MultipurposeSocketAddress mpa, MultipurposeSocketAddress bind) { + public KLALBRemoteLink(KLALBController controller,MultipurposeSocketAddress mpa, MultipurposeSocketAddress bind) { this(controller,mpa, bind, null); } - public KLALBRemoteLine(KLALBController controller,MultipurposeSocketAddress mpa) { + public KLALBRemoteLink(KLALBController controller,MultipurposeSocketAddress mpa) { this(controller,mpa, (IPv6AddressGroup) null); } - public KLALBRemoteLine(KLALBController controller,KLALBPacketLink link) { + public KLALBRemoteLink(KLALBController controller,KLALBPacketLink link) { this(controller,link, (IPv6AddressGroup) null); } @@ -216,10 +183,8 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement private class RemoteSender implements Runnable { - - private SpeedLimiter speedLimit = new SpeedLimiter(256 * 1024L, 10 * 1000000L);// 50*1000000L - private ConcurrentLinkedQueue sendQueue = new ConcurrentLinkedQueue(); + private MpscArrayQueue sendQueue = new MpscArrayQueue(8192); private WatchDogTimer watchdog = new WatchDogTimer(400000000L); private ThreadParker tlock = new ThreadParker(); @@ -227,6 +192,8 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement private volatile long time = System.nanoTime(); private volatile long pingInterval = 100000000L; + private Lock sendLock=new SpinLock(); + private boolean checkPingTime() { long cu = System.nanoTime(); if (cu - time > pingInterval) { @@ -239,7 +206,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement } - public ConcurrentLinkedQueue getSendQueue() { + public Queue getSendQueue() { return sendQueue; } @@ -275,8 +242,8 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement } writeKLALBPacketToKPL(new VADDRREQPacket()); writeKLALBPacketToKPL(new VADDRREQPacket()); - writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get())); - writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get())); + writeKLALBPacketToKPL(new VADDRPacket(klalbController.getSelf())); + writeKLALBPacketToKPL(new VADDRPacket(klalbController.getSelf())); kplink.flush(); while ((!kplink.isClosed()) && (!closed)) { if (checkPingTime()) { @@ -286,22 +253,38 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement if (peerAddress == null) sendPacket(new ADDRREQPacket()); - } - KLALBPacket tkpp = sendQueue.poll(); - - if (tkpp != null) { - kplink.writeKLALBPacket(tkpp); - watchdog.feed(); + }/*sendLock.lock(); + int n; + try { + n = sendQueue.drain((tkpp)->{ + try { + kplink.writeKLALBPacket(tkpp); + } catch (IOException e) { + throw new RuntimeException(e); + } + },100); + }finally { + sendLock.unlock(); + } + if (n>0) { + watchdog.feed(); } else { tlock.parkNanos(1000000L); - } + }*/ long curr=System.nanoTime(); if(curr-flushTime>=flushInterval) { flushTime=curr; + sendLock.lock(); + try { kplink.flush(); + watchdog.feed(); + }finally { + sendLock.unlock(); + } } - Thread.yield(); + tlock.parkNanos(1000000L); + } } catch (StreamCorruptedException sce) { sce.printStackTrace(); @@ -323,10 +306,39 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement boolean b=sendQueue.add(blk); if(b) { tlock.unpark(); - speedLimit.forceTransmit(blk.getTotalLength()); } return b; } + + + public void sendDirect(KLALBPacket blk) { + sendLock.lock(); + try { + writeKLALBPacketToKPL(blk); + } catch (IOException | UnresolvedAddressException e) { + if (debug) + e.printStackTrace(); + try { + kplink.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + tpk.unpark(); + }finally { + sendLock.unlock(); + } + watchdog.feed(); + tlock.unpark(); + } + + + public long getQueueUsed() { + long used=0; + for(KLALBPacket pack:sendQueue) { + used+=pack.getTotalLength(); + } + return used; + } } @@ -334,6 +346,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement private WatchDogTimer watchdog = new WatchDogTimer(400000000L); private long rtt=Long.MAX_VALUE/1024; + private long rttMin=Long.MAX_VALUE/1024; AtomicBoolean fst = new AtomicBoolean(true); //ReentrantLock readLock = new ReentrantLock(); @@ -348,7 +361,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement } watchdog.feed(); KLALBPacket kpp = kppb; - SRv6Router.getDefaultExecutor().execute(() -> { + //SRv6Router.getDefaultExecutor().execute(() -> { debugShowPacket("RX", kpp); UUID val = null; long delay = Long.MAX_VALUE / 1024; @@ -402,19 +415,25 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement long DsndDelay = prcv.subtract(psnd).longValue(); long DrcvDelay = local.subtract(posnd).longValue(); - // System.out.println(DsndDelayFactor+" "+DrcvDelayFactor); + // System.out.println(DsndDelay+" "+DrcvDelay); rtt = DsndDelay + DrcvDelay; + if(rtt= 0 && DrcvDelay >= 0) { delay = DrcvDelay; - monitor.getUploadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), psnd, 0, DsndDelay); - // System.out.println(local); + monitor.recordUploadDelay(DsndDelay); + //sysclk.adjustClock(Long128.valueOf( DsndDelay-DrcvDelay), 0.001); } else { long Dfallback = rtt / 2; if (Dfallback >= 0) { delay = Dfallback; - monitor.getUploadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), psnd, 0, Dfallback); + monitor.recordUploadDelay(Dfallback); } + sysclk.adjustClock(Long128.valueOf( DsndDelay-DrcvDelay), 0.1); } algorithm.setCurrentBandwidth(png.getDownSpeed()); @@ -437,11 +456,11 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement if (ardg2 != null) addressGroup = ardg2; } - KLALBRemoteLine.this.onAddressUpdate(); + KLALBRemoteLink.this.onAddressUpdate(); break; case KLALBPacket.VADDRREQ: - sendPacket(new VADDRPacket(localVaddrSupplier.get())); + sendPacket(new VADDRPacket(klalbController.getSelf())); break; case KLALBPacket.VADDR: IPv6AddressGroup vdr = ((VADDRPacket) kpp).getVaddr(); @@ -450,10 +469,10 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement sendPacket(new VADDRACKPacket()); if (fst.compareAndSet(true, false)) { // coll.resetCoolingTime(); - monitor.setState(MonitorData.UP); - KLALBRemoteLine.this.onOnlineStateUpdate(); + status.setState(LinkStatus.UP); + KLALBRemoteLink.this.onOnlineStateUpdate(); } - KLALBRemoteLine.this.onLocatorUpdate(); + KLALBRemoteLink.this.onLocatorUpdate(); break; case KLALBPacket.VADDRACK: @@ -464,19 +483,16 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement IPv6OverKLALBPacket ivk = (IPv6OverKLALBPacket) kpp; IPv6Packet iv6 = ivk.getIPv6Packet(); - ivk.putTimePassport("unpacked"); - ivk.printPassport(); - iv6.putTimePassport("unpackFromLink"); if (getSrv6Router() != null) { - getSrv6Router().onReceive(KLALBRemoteLine.this, iv6); + getSrv6Router().onReceive(KLALBRemoteLink.this, iv6); } KLALBOAMHopByHopTLV ktlv = null; - List ptlv = new ArrayList<>(); long btimes = 0; IPv6HopByHopHeader hop = iv6.getHopByHopHeader(); if (hop != null) { + List ptlv = new ArrayList<>(); List tlvs = hop.getTlvs(); for (IPv6HopByHopTLV tlv : tlvs) { if (tlv instanceof KLALBOAMHopByHopTLV) { @@ -488,14 +504,13 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement ptlv.add(btimes + ((KLALBPassportHopByHopTLV) tlv).getTimestampOffsetLong()); } } - } if (ptlv.size() >= 2) { long delta = ptlv.get(ptlv.size() - 1) - ptlv.get(ptlv.size() - 2); long deltaxnanos = (long) (delta * 1000000000.0 / (1L << 32)); if (deltaxnanos > 0) - //System.out.println(deltaxnanos); delay = deltaxnanos; } + } break; @@ -503,12 +518,17 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement long length = kpp.getTotalLength(); UUID pid = val == null ? KLALBUtils.createGlobalUUID() : val; - monitor.getDownloadBandwidth().recordPacket(pid, (int) length, delay); - if (klalbController != null) { - klalbController.getLinkMonitor().getDownloadBandwidth().recordPacket(pid, (int) length, - delay); + //monitor.getDownloadBandwidth().recordPacket(pid,0,1, delay); + if(delay!=Long.MAX_VALUE / 1024) { + monitor.recordDownloadDelay(delay); + //System.out.println(name+" "+delay); } - }); + monitor.recordDownloadPacket((int)length); + if (klalbController != null) { + //klalbController.getLinkMonitor().getDownloadBandwidth().recordPacket(pid, (int) length,delay); + klalbController.getLinkMonitor().recordDownloadPacket((int)length); + } + //}); } } catch (StreamCorruptedException sce) { sce.printStackTrace(); @@ -533,16 +553,37 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement public long getRTT() { return rtt; } + public long getRTTMin() { + return rttMin; + } } private ThreadParker tpk=new ThreadParker(); private StateManager stateManager; + private MonitorUpdater monitorUpdater; + private class MonitorUpdater implements Runnable{ + @Override + public void run() { + while (!closed) { + status.updateReliability(); + monitor.update(); + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + } + + } + private RemoteSender sender; + private RemoteReceiver receiver; private class StateManager implements Runnable { private Thread currThread; - private RemoteSender sender; - private RemoteReceiver receiver; @Override public void run() { currThread = Thread.currentThread(); @@ -580,10 +621,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement sender = new RemoteSender(); receiver = new RemoteReceiver(); - algorithm.setSpeedControlConsumer((speed, bursttime) -> { - sender.speedLimit.setLimitspeed(speed); - sender.speedLimit.setBrustTime(bursttime); - }); + sendWindow = new SendPacketSlidingWindow(algorithm, 65535, HEADER_CALIBRATE); sendWindow.setResendConsumer(rerouteConsumer); @@ -604,6 +642,10 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement if(klalbController!=null&& klalbController.getConfigItem()!=null) { KLALBControllerConfigItem config=klalbController.getConfigItem(); if(algorithm instanceof DetnetCongestionAlgorithm) { + double v0=config.getBurstLimit(); + if(v0!=0) { + ((DetnetCongestionAlgorithm)algorithm).setBurstLimit(v0); + } double v1=config.getDelayUpperBound(); if(v1!=0) { ((DetnetCongestionAlgorithm)algorithm).setUpperDelayBound(v1); @@ -619,8 +661,13 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement } boolean b = sender.getWatchdog().isBarking() || receiver.getWatchdog().isBarking(); - boolean isup= (!b)&&(receiver.getRTT()<1000000000L); - monitor.setState(isup?MonitorData.UP:MonitorData.UNSTABLE); + boolean isup= (!b)&&(receiver.getRTT()<1000000000L);//&&(receiver.getRTT() bandwidthDistributer = new BandwidthDistributer(); - + BandwidthDistributer bandwidthDistributer=new BandwidthDistributer<>(); @Override public List getNeighborsInfo() { List hs = new ArrayList<>(1); if (peerAddress != null) { hs.add(new Neighbor(peerAddress, remoteVaddr, monitor, bandwidthDistributer)); - // System.out.println(peerAddress+" "+addressGroup); } return hs; } - private volatile int inputchachesize = 8192 * 4000; - private volatile int outputchachesize = 8192 * 240;// 500 private Consumer rerouteConsumer; @Override public void sendPacket(IPv6Packet pack, IPv6Address inet6Address) throws IOException { // 只有已连接的链路才能传输数据 - if (monitor.getState() == MonitorData.UP) { + if (status.getState() == LinkStatus.UP) { - // if(inet6Address.equals(remoteVaddr.getAddress())||inet6Address.equals(peerAddress.getAddress())) - // { - // 获得数据包的IPv6逐跳扩展头部 IPv6HopByHopHeader hop = pack.getHopByHopHeader(); UUID val = null; @@ -835,20 +870,15 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement } if (val != null) { - if (!(pack.getPayload() instanceof ICMPv6PostcardPacket)) { + //if (!(pack.getPayload() instanceof ICMPv6PostcardPacket)) { // 放入滑动窗口中并记录缓冲区大小占用 sendWindow.put(val, pack); - } + //} } } - // 捎带发送反方向的ACK给对方发送过来的数据包,减小设备性能开销 - /* - * if(srh!=null) { addACKSEQToSRH(srh,10); } - */ - // 发送数据包 - + sendIPv6PacketToLink(pack, val); - // } + } else { if (rerouteConsumer != null) { @@ -864,8 +894,6 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement private void sendIPv6PacketToLink(IPv6Packet pack, UUID val) { IPv6OverKLALBPacket kipv6 = new IPv6OverKLALBPacket(pack); - pack.putTimePassport("packdInLink"); - pack.printPassport(); sendPacketToLink(kipv6, val); } @@ -874,34 +902,25 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement } @Override - public boolean isCongress(IPv6Packet iPv6Packet, double scale) { + public boolean isCongestion(IPv6Packet iPv6Packet, double scale) { SendPacketSlidingWindow sw = sendWindow; if (sw != null) { - boolean cong = (scale <= 1.0) && (monitor.getOutDelay() / (monitor.getOutDelayMin() + 1000000L) > 2); - - return cong || sw.isCongress(iPv6Packet, scale); + return sw.isCongestion( scale); } else { return true; } } - @Override - public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) { - //boolean xcongress = !speedLimit.checkTransmit(iPv6Packet.getTotalLength()); - //return xcongress; - return false; - } - @Override public String getName() { - return monitor.getName(); + return name; } @Override public boolean isUp() { - return (!isClosed()) && (getMonitor().getState() == MonitorData.UP) ; + return (!isClosed()) && (status.getState() == LinkStatus.UP) ; } @Override @@ -916,12 +935,12 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement for (Iterator iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) { Neighbor addresses = (Neighbor) iteratorx.next(); RouteItem ri = new RouteItem(new IPv6AddressGroup(addresses.getAddress().getAddress(), 128), - addresses.getAddress().getAddress(), this, "Direct", 0, 128, addresses.getMonitor(), "D", false); + addresses.getAddress().getAddress(), this, "Direct", 0, 128,CostSupplierFactory.expectedDelaySupplier((DelayMonitorData) addresses.getMonitor(),status,algorithm::getRTO), "D", false); rlist.add(ri); if (addresses.getLocator() != null) { RouteItem ris = new RouteItem(addresses.getLocator(), addresses.getLocator().getAddress(), this, - "KLALB SRv6", 13, 128, addresses.getMonitor(), "D", false); + "KLALB SRv6", 13, 128,CostSupplierFactory.expectedDelaySupplier((DelayMonitorData) addresses.getMonitor(),status,algorithm::getRTO), "D", false); rlist.add(ris); } } @@ -939,9 +958,30 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement if (deltaxnanos > 0) { Long128 psnd = NTPTimestamps.ntp128BitToNanosTimestamp( NTPTimestamps.inferNtp64To128(postcard.getTimestampBase(), sysclk.getCurrentTimeNTP128())); - monitor.getUploadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), psnd, 0, deltaxnanos); + monitor.recordUploadDelay(deltaxnanos); } - sendWindow.ack(postcard.getPacketUUID()); + sendWindow.ack(postcard.getPacketUUID(),false,deltaxnanos); + } + + public int getState() { + return status.getState(); + } + + + public SendPacketSlidingWindow getWindow() { + return sendWindow; + } + + + public long getQueueUsed() { + if(sender==null) { + return 0; + } + return sender.getQueueUsed(); + } + + + } diff --git a/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java b/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java index 49592b1..34fcf96 100644 --- a/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java +++ b/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java @@ -1,21 +1,17 @@ package org.kne.cloud.network.klalb; import java.io.IOException; -import java.net.SocketException; import java.net.SocketTimeoutException; import java.nio.charset.Charset; import java.util.Iterator; import java.util.List; -import java.util.Set; import org.kne.cloud.network.MultipurposeSocketAddress; -import org.kne.cloud.network.Proxy; import org.kne.cloud.network.SocketListener; import org.kne.cloud.network.ipv6.IPv6NetworkLink; -import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.LinkStatus; import com.google.gson.JsonArray; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; @@ -69,15 +65,15 @@ public class KLALBRemoteManagement { synchronized (lineslist) { for (Iterator iterator = lineslist.iterator(); iterator.hasNext();) { IPv6NetworkLink link=iterator.next(); - if(!(link instanceof KLALBRemoteLine)) { + if(!(link instanceof KLALBRemoteLink)) { continue; } - KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link; + KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link; if(klalbRemoteLine.getSocketAddress()==null) continue; JsonObject jklbrl=new JsonObject(); jklbrl.addProperty("ipport", klalbRemoteLine.getSocketAddress().toString()); - jklbrl.addProperty("state",MonitorData.parseStateToString( klalbRemoteLine.getMonitor().getState())); + jklbrl.addProperty("state",LinkStatus.stateToString( klalbRemoteLine.getState())); jklbrl.addProperty("Vaddr", klalbRemoteLine.getRemoteVaddr().getAddress().toString()); diff --git a/src/org/kne/cloud/network/klalb/KLALBUtils.java b/src/org/kne/cloud/network/klalb/KLALBUtils.java index aa5e407..fdacab2 100644 --- a/src/org/kne/cloud/network/klalb/KLALBUtils.java +++ b/src/org/kne/cloud/network/klalb/KLALBUtils.java @@ -10,10 +10,11 @@ import java.net.UnknownHostException; import java.security.SecureRandom; import java.util.List; import java.util.UUID; -import java.util.concurrent.LinkedBlockingQueue; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jctools.counters.CountersFactory; +import org.jctools.counters.FixedSizeStripedLongCounter; import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.ipv6.IPv6Address; @@ -385,20 +386,17 @@ public static String parseAbbrIPv6(String IPv6Str) { private final long id; private long counter=0; - private UUID randUUID=UUID.randomUUID(); - private long time=System.nanoTime(); - private static final long INTERVAL=1000000L; + private long randUUIDh; + private long randUUIDl; + private static SecureRandom sr=new SecureRandom(); public UUIDGenarator(long threadId) { this.id=threadId; + randUUIDh=sr.nextLong(); + randUUIDl=sr.nextLong(); } public UUID genarateUUID() { - long curr=System.nanoTime(); - if(curr-time>INTERVAL) { - time=curr; - randUUID=UUID.randomUUID(); - } - long h=randUUID.getMostSignificantBits()^id; - long l=randUUID.getLeastSignificantBits()^counter; + long h=randUUIDh^id; + long l=randUUIDl^counter; UUID ret=new UUID(h, l); counter++; @@ -413,4 +411,9 @@ public static String parseAbbrIPv6(String IPv6Str) { //return UUID.randomUUID(); return gens.get().genarateUUID(); } + + + public static FixedSizeStripedLongCounter createCounter() { + return CountersFactory.createFixedSizeStripedCounter(Runtime.getRuntime().availableProcessors()); + } } diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualDatagramSocketImpl.java b/src/org/kne/cloud/network/klalb/KLALBVirtualDatagramSocketImpl.java index dd422cf..d9d13e0 100644 --- a/src/org/kne/cloud/network/klalb/KLALBVirtualDatagramSocketImpl.java +++ b/src/org/kne/cloud/network/klalb/KLALBVirtualDatagramSocketImpl.java @@ -3,7 +3,6 @@ package org.kne.cloud.network.klalb; import java.io.IOException; import java.net.BindException; import java.net.DatagramPacket; -import java.net.DatagramSocketImpl; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; @@ -18,15 +17,12 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; -import org.kne.cloud.network.NetworkPacket; import org.kne.cloud.network.VirtualDatagramSocketImpl; import org.kne.cloud.network.ipv6.IPv6Address; import org.kne.cloud.network.ipv6.IPv6Packet; import org.kne.cloud.network.tcp.UDPPacket; -import org.kne.concurrent.HighPerformanceExecutor; -import org.kne.io.KNEChannels; -public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl implements BindableKLALBPacketConsumer{ +public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl implements BindableConsumer{ private KLALBController controller; @@ -89,8 +85,8 @@ public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl im localaddr = (Inet6Address) host; localPort=port; if(!ignoreBindCheck) - controller.getDatagramPortBinder().bind(this); - controller.getDatagramPortBinder().listen(this); + controller.getUDPregister().bind(this); + controller.getUDPregister().listen(this); } @Override @@ -137,12 +133,10 @@ public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl im p.setLength(buffer.limit()); } - @Override protected void setTTL(byte ttl) throws IOException { this.ttl=ttl; } - @Override protected byte getTTL() throws IOException { return (byte) ttl; } @@ -183,9 +177,9 @@ public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl im @Override protected void close() { - controller.getDatagramPortBinder().unlisten(this); + controller.getUDPregister().unlisten(this); if(!ignoreBindCheck) - controller.getDatagramPortBinder().unbind(this); + controller.getUDPregister().unbind(this); closed=true; } @@ -218,14 +212,16 @@ public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl im private Queue recvQueue = new ConcurrentLinkedQueue(); private AtomicInteger recvQueueUsed=new AtomicInteger(0); @Override - public void accept(IPv6Address t,NetworkPacket np) { - UDPPacket u=(UDPPacket) np; + public void accept(IPv6Packet t) { + if(t.getPayload() instanceof UDPPacket) { + UDPPacket u=(UDPPacket) t.getPayload(); if(recvQueueUsed.get()<=inputchachesize) { if(recvQueue.offer(u)) { recvQueueUsed.addAndGet((int) u.getDataLength()); LockSupport.unpark(parkThread); } } + } } @Override diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocketImpl.java b/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocketImpl.java index d29ef9f..933b103 100644 --- a/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocketImpl.java +++ b/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocketImpl.java @@ -16,26 +16,19 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; import java.util.function.BiConsumer; -import java.util.function.Consumer; import java.util.function.Supplier; -import org.kne.cloud.network.ByteBufferAllocator; -import org.kne.cloud.network.NetworkPacket; -import org.kne.cloud.network.RawSocketImpl; -import org.kne.cloud.network.ThreadTool; import org.kne.cloud.network.VirtualRawSocketImpl; import org.kne.cloud.network.ipv6.IPv6Packet; -import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6DefaultPayload; +import org.kne.cloud.network.ipv6.IPv6ProtocolRegister; import org.kne.cloud.network.ipv6.IPv6Address; import org.kne.cloud.network.ipv6.IPv6AddressGroup; import org.kne.cloud.network.ipv6.IPv6NetworkLink; import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink; -import org.kne.cloud.network.srv6.PacketConsumer; -import org.kne.cloud.network.srv6.SRv6Router; -import org.kne.concurrent.HighPerformanceExecutor; import org.kne.io.KNEChannels; -public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements PacketConsumer{ +public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements IPv6ProtocolRegister{ private boolean ipHeaderInclude=false; @@ -123,7 +116,7 @@ public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements P @Override protected void close() { - link.getProtocolNumberRegister().remove(bindProtocolNumber); + link.getProtocolNumberRegister()[bindProtocolNumber]=null; } @Override @@ -156,8 +149,10 @@ public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements P localaddr=(Inet6Address) address; this.bindProtocolNumber=protocolNumber; - if(link.getProtocolNumberRegister().putIfAbsent(protocolNumber, this)!=null) { + if(link.getProtocolNumberRegister()[protocolNumber]!=null) { throw new BindException("protocol number already bind"); + }else { + link.getProtocolNumberRegister()[protocolNumber]=this; } } @@ -191,7 +186,7 @@ public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements P if(ipHeaderInclude) { }else { - IPv6Payload pl=new IPv6Payload(bindProtocolNumber); + IPv6DefaultPayload pl=new IPv6DefaultPayload(bindProtocolNumber); pl.getData().put(buf); pl.getData().flip(); BiConsumer>cons=link.getReceiveConsumer(); @@ -281,7 +276,7 @@ public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements P private AtomicInteger recvQueueUsed=new AtomicInteger(0); @Override - public boolean accept(IPv6Packet packx) throws IOException { + public boolean onaccept(IPv6Packet packx) throws IOException { if(recvQueueUsed.get()<=inputchachesize) { if(recvQueue.offer(packx)) { recvQueueUsed.addAndGet((int) packx.getPayload().getTotalLength()); diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java index 62321de..8e9a3fb 100644 --- a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java +++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java @@ -7,11 +7,9 @@ import java.net.SocketException; import java.net.SocketOption; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.nio.channels.spi.SelectorProvider; import java.util.Set; - -import org.kne.cloud.network.klalb.KLALBVirtualSocketImpl.KVSIInputStream; -import org.kne.cloud.network.klalb.KLALBVirtualSocketImpl.KVSIOutputStream; +import org.kne.cloud.network.kltp.KLTPInputStream; +import org.kne.cloud.network.kltp.KLTPOutputStream; public class KLALBVirtualSocketChannel extends SocketChannel{ @@ -110,22 +108,22 @@ public class KLALBVirtualSocketChannel extends SocketChannel{ @Override public int read(ByteBuffer dst) throws IOException { - return ((KVSIInputStream)socket.getInputStream()).read(dst); + return ((KLTPInputStream)socket.getInputStream()).read(dst); } @Override public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { - return ((KVSIInputStream)socket.getInputStream()).read(dsts,offset,length); + return ((KLTPInputStream)socket.getInputStream()).read(dsts,offset,length); } @Override public int write(ByteBuffer src) throws IOException { - return ((KVSIOutputStream)socket.getOutputStream()).write(src); + return ((KLTPOutputStream)socket.getOutputStream()).write(src); } @Override public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { - return ((KVSIOutputStream)socket.getOutputStream()).write(srcs,offset,length); + return ((KLTPOutputStream)socket.getOutputStream()).write(srcs,offset,length); } @Override @@ -146,13 +144,13 @@ public class KLALBVirtualSocketChannel extends SocketChannel{ } public boolean isAutoFlush() throws IOException { - return ((KVSIOutputStream)socket.getOutputStream()).isAutoFlush(); + return ((KLTPOutputStream)socket.getOutputStream()).isAutoFlush(); } public void setAutoFlush(boolean b) throws IOException { - ((KVSIOutputStream)socket.getOutputStream()).setAutoFlush(b); + ((KLTPOutputStream)socket.getOutputStream()).setAutoFlush(b); } public void flush() throws IOException { - ((KVSIOutputStream)socket.getOutputStream()).flush(); + ((KLTPOutputStream)socket.getOutputStream()).flush(); } } diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java index 66cc9ad..c1ec57b 100644 --- a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java +++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java @@ -15,205 +15,43 @@ import java.net.SocketException; import java.net.SocketImpl; import java.net.SocketOptions; import java.net.SocketTimeoutException; -import java.nio.ByteBuffer; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.WritableByteChannel; -import java.util.Iterator; -import java.util.Map; -import java.util.TimerTask; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.zip.Deflater; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.Inflater; -import java.util.zip.InflaterInputStream; -import org.kne.cloud.clock.HighAccuracyClock; -import org.kne.cloud.network.NetworkPacket; -import org.kne.cloud.network.PortPair; -import org.kne.cloud.network.SpeedLimiter; import org.kne.cloud.network.VirtualSocketImpl; -import org.kne.cloud.network.congestion.CongestionAlgorithm; -import org.kne.cloud.network.congestion.DCTCP2CongestionAlgorithm; -import org.kne.cloud.network.congestion.SendPacketSlidingWindow; import org.kne.cloud.network.ipv6.IPv6Address; -import org.kne.cloud.network.ipv6.PacketID; -import org.kne.cloud.network.ipv6.PacketIDGenerator; -import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; -import org.kne.concurrent.SpinLock; -import org.kne.concurrent.ThreadParker; - -import com.github.f4b6a3.uuid.UuidCreator; - -public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements BindableKLALBPacketConsumer{ - - private static final int HEADER_CALIBRATE = 100; - /* - private PrintStream dbg; - { - try { - dbg= new PrintStream("debug.csv"); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - } - */ +import org.kne.cloud.network.kltp.KLTPInputStream; +import org.kne.cloud.network.kltp.KLTPOutputStream; +import org.kne.cloud.network.kltp.KLTPSessionPacket; +public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements BindableConsumer{ private static final boolean debug = false; - //private SpeedAndTrafficAndDelayMonitorDataImpl socketMonitor=new SpeedAndTrafficAndDelayMonitorDataImpl(HighAccuracyClock.SYSTEM_CLOCK); - - //private SpeedAndTrafficAndDelayMonitorDataImpl socketRawMonitor=new SpeedAndTrafficAndDelayMonitorDataImpl(HighAccuracyClock.SYSTEM_CLOCK); + private static final int DEFAULT_TIMEOUT=10000; private KLALBController controller; - - //60000 30 30 - private final int MTU=8192; - private final long MIN_RTTVAR=200000000L; - private final long MIN_LIMIT_SPEED=128*1024L; - private final long REACK_INTERVAL = 100000000L; - - - private SpeedLimiter spdlmt=new SpeedLimiter(MIN_LIMIT_SPEED,1000000L); - protected IPv6Address remoteaddr; protected IPv6Address localaddr=IPv6Address.UNSPECIFIED; - private BlockingQueue backlogQueue; - private ReentrantLock backlogQueuelock=new ReentrantLock(); - private ThreadParker sendDequeLock=new ThreadParker(); - private Map recvMap = new ConcurrentHashMap(1024); - private AtomicInteger recvWindowUsed=new AtomicInteger(0); + private volatile KLTPInputStream vin; + private volatile KLTPOutputStream vout; - private ThreadParker sendthread=new ThreadParker(); + private boolean ignoreBindCheck; + private boolean connected; - - private boolean connectionPending; - private TimerTask flowControlTask=new FlowControlTask(); - private PortPair portp; - - private InputStream vin; - private OutputStream vout; - - private boolean closed; - private KVSIInputStream kvsii; - private KVSIOutputStream kvsio; + private BlockingQueue backlogQueue; - private boolean nodelay=false; - private long delaytime=2; - private int inputchachesize =128* 1024*1024; - private int outputchachesize = 128* 1024*1024; - - private CongestionAlgorithm algorithm=new DCTCP2CongestionAlgorithm(); - private SendPacketSlidingWindowsendMap=new SendPacketSlidingWindow<>(algorithm, 4*MTU,HEADER_CALIBRATE,false); - { - sendMap.setResendConsumer((dtp)->{ - if(dtp.getSendCounter()>=10) { - System.err.println("send error!"); - try { - close0(true); - } catch (IOException e) { - e.printStackTrace(); - } - } - - controller.getIpv6Router().enqueuePacketSendTask(()->{ - long length= dtp.getTotalLength(); - //socketRawMonitor.getUploadBandwidth().recordPacket(pidg.generate(), (int) length); - spdlmt.forceTransmit(length); - //System.out.println("第"+(dtp.getSendCounter()-1)+"次重传:"+dtp); - return controller.createPacketToAddress( remoteaddr,0,dtp,1); - }); - }); + protected boolean isListening() { + return backlogQueue != null; } - private volatile long requestSpeedOld=MIN_LIMIT_SPEED; - - - - - - - private long inputcount = 0; - private volatile long peerAvaliableRcvWindow = MTU*40; - private volatile long congestionWindow= MTU*40; - private long outputcount = 0; - - - - //private volatile long RunningSpeed=spdlmt.getLimitspeed(); - - - - - - - - protected int getInputchachesize() { - return inputchachesize; - } - - protected void setInputchachesize(int inputchachesize) { - this.inputchachesize = inputchachesize; - } - - protected int getOutputchachesize() { - return outputchachesize; - } - - protected void setOutputchachesize(int outputchachesize) { - this.outputchachesize = outputchachesize; - } - - - - public long getDelaytime() { - return delaytime; - } - - public void setDelaytime(long delaytime) { - this.delaytime = delaytime; - } - - - private class FlowControlTask extends TimerTask{ - - @Override - public void run() { - if(getLocalPort()!=0&&getPort()!=0) - if(!remoteaddr.isAnyLocalAddress()) - controller.getIpv6Router().enqueuePacketSendTask(()->{ - return controller.createPacketToAddress( remoteaddr,0, new ACKTPacket(getLocalPort(),getPort(), -1, - getAvaliableRcvWindow(),false,0,0)); - }); - - } - - - - } - - private long getAvaliableRcvWindow() { - return Math.max(0, inputchachesize-recvWindowUsed.get()); - } - - protected boolean isListening() { - return backlogQueue != null; - } public KLALBController getController() { return controller; @@ -221,13 +59,12 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl public KLALBVirtualSocketImpl(KLALBController kc) { super(); this.controller = kc; - this.delaytime=kc.getConfigItem().getNagleDelayTime(); } @Override public void setOption(int optID, Object value) throws SocketException { switch(optID) { - case SocketOptions.TCP_NODELAY: + /*case SocketOptions.TCP_NODELAY: nodelay=(boolean) value; break; case SocketOptions.SO_RCVBUF: @@ -235,6 +72,9 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl break; case SocketOptions.SO_SNDBUF: outputchachesize=(int)value; + break;*/ + case SocketOptions.SO_TIMEOUT: + vin.setSoTimeout((int)value); break; } } @@ -242,12 +82,14 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl @Override public Object getOption(int optID) throws SocketException { switch(optID) { - case SocketOptions.TCP_NODELAY: + /*case SocketOptions.TCP_NODELAY: return nodelay; case SocketOptions.SO_RCVBUF: return inputchachesize; case SocketOptions.SO_SNDBUF: - return outputchachesize; + return outputchachesize;*/ + case SocketOptions.SO_TIMEOUT: + return vin.getSoTimeout(); case SocketOptions.SO_BINDADDR: return localaddr; default: @@ -270,7 +112,7 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl @Override protected void connect(InetAddress address, int port) throws IOException { - connect(new InetSocketAddress(address, port), 10000); + connect(new InetSocketAddress(address, port), DEFAULT_TIMEOUT); } @@ -278,92 +120,49 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl @Override protected void connect(SocketAddress address, int timeout) throws IOException { if(!ignoreBindCheck) - if (!controller.getStreamPortBinder().checkIsBind(this)) { - bind(Inet6Address.getByName("::0"), 0); - } - port = ((InetSocketAddress) address).getPort(); - this.address = (Inet6Address) ((InetSocketAddress) address).getAddress(); - this.remoteaddr=IPv6Address.valueOf(this.address); - - if(connected) - throw new SocketException("already connected"); - controller.getStreamPortBinder().connect(this); - - connectionPending=true; - - //controller.sendPacketToAddress((Inet6Address) this.remoteaddr, new SYNTPacket(localport, port), 0,1); - try { - getKVSIOutputStream().write(compress); - if(compress==1) { - vout=new DeflaterOutputStream(getKVSIOutputStream(), new Deflater(Deflater.BEST_COMPRESSION, true), MTU, true); - }else { - vout = getKVSIOutputStream(); + if (!controller.getKLTPregister().checkIsBind(this)) { + bind(Inet6Address.getByName("::0"), 0); } - getKVSIOutputStream().forceFlush(); - getKVSIOutputStream().waitForAllAcknowledged(timeout); - getKVSIOutputStream().unlockNagle(); - - - int comp=getKVSIInputStream().read(); - if(comp==1) { - vin=new InflaterInputStream(getKVSIInputStream(),new Inflater(true),MTU); - }else { - vin = getKVSIInputStream(); - } - - 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(MIN_LIMIT_SPEED); - algorithm.setSpeedControlConsumer((speed,burst)->{ - if(debug) - System.out.println("speed:"+speed); - if(portp!=null) { - if(speed>requestSpeedOld*1.01||speed(timeout*1000000L)) { + throw new SocketTimeoutException("connect time out"); } } - spdlmt.setBrustTime(burst); - }); - algorithm.setWindowControlConsumer((window)->{ - if(debug) - System.out.println("window:"+window); - congestionWindow=window; - updateWindowSize(); - }); - algorithm.reset(); - this.portp=portpx; + + connected=true; + - }catch(SocketTimeoutException e) { - throw new SocketTimeoutException("connect time out"); - }catch(NoRouteToHostException e) { - throw e; - }catch(SocketException e) { - e.printStackTrace(); - throw new ConnectException("connect refused"); - }finally { - connectionPending=false; - } - controller.getResendTimer().schedule(flowControlTask, 5000, 5000); - } - private void updateBandwidthReq(long requestSpeed) { - if(remoteaddr!=null&&portp!=null) - controller.updateBandwidthRequest(remoteaddr, portp,requestSpeed ); + + }catch(NoRouteToHostException e) { + throw e; + }catch(SocketException e) { + e.printStackTrace(); + throw new ConnectException("connect refused"); + }finally { + //connectionPending=false; + } } - public boolean isConnectionPending() { - return connectionPending; - } - //private volatile boolean connecting = false; - - /*public boolean isConnecting() { - return connecting; - }*/ @Override protected void bind(InetAddress host, int port) throws IOException { bind(host,port,false); @@ -381,8 +180,10 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl localaddr = IPv6Address.valueOf( host); localport=port; this.ignoreBindCheck=ignoreBindCheck; - if(!ignoreBindCheck) - controller.getStreamPortBinder().bind(this); + if(!ignoreBindCheck) { + controller.getKLTPregister().bind(this); + } + //System.out.println("绑定:"+host.getHostAddress()+":"+localport); } @Override @@ -393,15 +194,16 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl @Override protected void listen(int backlog) throws IOException { backlogQueue = new ArrayBlockingQueue<>(backlog); - controller.getStreamPortBinder().listen(this); + controller.getKLTPregister().listen(this); address=localaddr.toInet6Address(); } @Override protected void accept(SocketImpl s) throws IOException { + //System.out.println("Enter accept============================="); KLALBVirtualSocketImpl kvsi = (KLALBVirtualSocketImpl) s; - Object[] p=null; + KLTPSessionPacket p=null; while(true) { if (isClosed()) throw new SocketException("Socket is closed"); @@ -415,605 +217,29 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl e.printStackTrace(); } } - InetSocketAddress isa = (InetSocketAddress) p[0]; - kvsi.inputchachesize=inputchachesize; - kvsi.outputchachesize=outputchachesize; - - kvsi.address = isa.getAddress(); - kvsi.remoteaddr=IPv6Address.valueOf( isa.getAddress()); + + System.out.println(p); + KLTPInputStream input=p.getInputstream(); + kvsi.address = input.getRemoteAddress().toInet6Address(); + kvsi.remoteaddr=input.getRemoteAddress(); kvsi.bind(localaddr.toInet6Address(), localport,true); - kvsi.accept((IPv6Address) p[1],(KLALBPacket) p[2]); - kvsi.connect(isa, 5000); - /*kvsi.port = isa.getPort(); - kvsi.localport = localport; - kvsi.localaddr = localaddr;*/ + kvsi.accept(p); + kvsi.connect(new InetSocketAddress(kvsi.address, p.getSrcPort()),10); + //System.out.println("Exit accept============================="); } - - protected class KVSIInputStream extends InputStream implements ReadableByteChannel{ - - private DATATPacket dataPack = null; - //private int count = 0; - - private boolean shutdown=false; - @Override - public int read() throws IOException { - if (dataPack == null ) { - nextPacket(); - } - if (dataPack.getSize() == 0) { - return -1; - } else { - int ret= dataPack.getDataBuffer().get() & 0xff; - if(!dataPack.getDataBuffer().hasRemaining()) { - //dataPack.dispose(); - dataPack=null; - } - //System.out.println("read:"+1); - return ret; - } - } - private long reAckTime=System.nanoTime(); - private DATATPacket nextPacket() throws IOException { - //count = 0; - while (true) { - if (isClosed()) - throw new SocketException("Socket is closed"); - - DATATPacket dtp2 = recvMap.get(inputcount); - if (dtp2 != null) { - long oldcount= inputcount++; - recvMap.remove(oldcount); - int g=recvWindowUsed.addAndGet(-dtp2.getSize()); - long curt=System.nanoTime(); - if(g<=0&(curt-reAckTime)>REACK_INTERVAL) { - reAckTime=curt; - flowControlTask.run(); - } - //System.out.println("PULL:"+dtp2); - dataPack = dtp2; - int size=dtp2.getSize(); - //socketMonitor.getDownloadBandwidth().recordPacket(pid, size); - controller.getDatatMonitor().getDownloadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), size); - //checkFlowControl(dtp2); - break; - - } - sendDequeLock.parkNanos(1000000); - } - //System.out.println("sorted:"+dataPack); - return dataPack; - } - /*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 - public int read(ByteBuffer dst) throws IOException { - int oldlmt=dst.limit(); - try { - - - if (dataPack == null ) { - nextPacket(); - } - if (dataPack.getSize() == 0) { - return -1; - } else { - int len = Math.min(dst.remaining(), available()); - dst.limit(dst.position()+len); - dst.put( dataPack.getDataBuffer().get()) ; - if(!dataPack.getDataBuffer().hasRemaining()) { - dataPack.putTimePassport("unpacked"); - dataPack.printPassport(); - //dataPack.dispose(); - dataPack=null; - } - } - int i = 1; - try { - while (dst.hasRemaining()) { - - if (dataPack == null ) { - nextPacket(); - } - if (dataPack.getSize() == 0) { - break; - } - int min=Math.min(dataPack.getDataBuffer().remaining(), dst.remaining()); - int oldlm=dataPack.getDataBuffer().limit(); - dataPack.getDataBuffer().limit(dataPack.getDataBuffer().position()+min); - dst.put(dataPack.getDataBuffer()); - dataPack.getDataBuffer().limit(oldlm); - i+=min; - //b[off + i]= dtp.getData()[count++] ; - if(!dataPack.getDataBuffer().hasRemaining()) { - dataPack.putTimePassport("unpacked"); - dataPack.printPassport(); - //dataPack.dispose(); - dataPack=null; - } - - } - } catch (IOException ee) { - } - return i; - }finally { - dst.limit(oldlmt); - } - } - - - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (b == null) { - throw new NullPointerException(); - } else if (off < 0 || len < 0 || len > b.length - off) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return 0; - } - - - - if (dataPack == null ) { - nextPacket(); - } - if (dataPack.getSize() == 0) { - return -1; - } else { - len = Math.min(len, available()); - b[off]= dataPack.getDataBuffer().get() ; - if(!dataPack.getDataBuffer().hasRemaining()) { - dataPack.putTimePassport("unpacked"); - dataPack.printPassport(); - //dataPack.dispose(); - dataPack=null; - } - } - int i = 1; - try { - while (i < len) { - - if (dataPack == null ) { - nextPacket(); - } - if (dataPack.getSize() == 0) { - break; - } - int remainD=len-i; - int min=Math.min(dataPack.getDataBuffer().remaining(), remainD); - dataPack.getDataBuffer().get(b, off+i, min); - i+=min; - //b[off + i]= dtp.getData()[count++] ; - if(!dataPack.getDataBuffer().hasRemaining()) { - dataPack.putTimePassport("unpacked"); - dataPack.printPassport(); - //dataPack.dispose(); - dataPack=null; - } - - } - } catch (IOException ee) { - } - return i; - } - - @Override - public void close() throws IOException { - try { - close0(); - }finally { - getKVSIOutputStream().close0(); - } - } - private void close0() throws IOException{ - - } - @Override - public int available() throws IOException { - int i = recvWindowUsed.get(); - /*for(DATATPacket V:recvQueue) { - i+=(V.getSize()); - }*/ - if (dataPack != null) - i+=dataPack.getDataBuffer().remaining(); - return i; - } - - @Override - public boolean isOpen() { - return !closed; - } - - - public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { - long lth=0; - for(int i=offset;i0) { - int remainD=dataPack.getDataBuffer().remaining(); - int min=Math.min(len, remainD); - dataPack.getDataBuffer().put(b, off, min); - - off+=min; - len-=min; - if (!dataPack.getDataBuffer().hasRemaining()) {//1429?5773?8669 - flush0(); - } - } - - if(dataPack!=null&& dataPack.getDataBuffer().position()>0) { - if(autoFlush) - delayFlush(); - } - }finally { - if(olock!=null) - olock.unlock(); - } - } - - private int writeWithoutFlush(ByteBuffer src)throws IOException { - if (isClosed()) - throw new SocketException("Socket is closed"); - int counter=0; - if(olock!=null) - olock.lock(); - try { - - while(src.hasRemaining()) { - int min=Math.min(src.remaining(), dataPack.getDataBuffer().remaining()); - int olm=src.limit(); - src.limit(src.position()+min); - dataPack.getDataBuffer().put(src); - counter+=min; - src.limit(olm); - - if (!dataPack.getDataBuffer().hasRemaining()) {//1429?5773?8669 - flush0(); - } - } - - - }finally { - if(olock!=null) - olock.unlock(); - } - return counter; - } - - @Override - public int write(ByteBuffer src) throws IOException { - if (isClosed()) - throw new SocketException("Socket is closed"); - int counter=0; - if(olock!=null) - olock.lock(); - try { - - while(src.hasRemaining()) { - int min=Math.min(src.remaining(), dataPack.getDataBuffer().remaining()); - int olm=src.limit(); - src.limit(src.position()+min); - dataPack.getDataBuffer().put(src); - counter+=min; - src.limit(olm); - - if (!dataPack.getDataBuffer().hasRemaining()) {//1429?5773?8669 - flush0(); - } - } - - if(dataPack!=null&& dataPack.getDataBuffer().position()>0) { - if(autoFlush) - delayFlush(); - } - }finally { - if(olock!=null) - olock.unlock(); - } - return counter; - } - - - private void createDataPack() { - if(dataPack==null) { - dataPack=new DATATPacket(localport, port, outputcount++, MTU); - dataPack.putTimePassport("buildHeader"); - } - } - public void waitForAllAcknowledged(int timeout) throws IOException { - long start=System.nanoTime(); - while(true){ - if (isClosed()) - throw new SocketException("Socket is closed"); - if(sendMap.isEmpty()) - break; - if(timeout!=0&&(System.nanoTime()-start>timeout*1000000L)) - throw new SocketTimeoutException("wait for acknowledged timout"); - sendthread.parkNanos(1000000L); - } - } - AtomicReference ioe=new AtomicReference<>(); - private volatile TimerTask tt; - - @Override - public void flush() throws IOException { - if(olock!=null) - olock.lock(); - try { - if((delaytime<=0)||locked) { - flush0(); - }else { - delayFlush(); - } - }finally { - if(olock!=null) - olock.unlock(); - } - } - public void forceFlush() throws IOException{ - if(olock!=null) - olock.lock(); - try { - flush0(); - }finally { - if(olock!=null) - olock.unlock(); - } - } - public void delayFlush()throws IOException{ - if(tt==null) { - tt= new TimerTask() { - - @Override - public void run() { - if(isClosed()) - cancel(); - try { - if(olock!=null) - olock.lock(); - try { - flush0(); - }finally { - if(olock!=null) - olock.unlock(); - } - } catch (IOException e) { - ioe.set(e); - } - } - }; - getController().getNagleTimer().schedule(tt, delaytime/1000000L); - } - - IOException ioex=ioe.get(); - if(ioex!=null) { - ioex.fillInStackTrace(); - throw ioex; - } - } - - private void flush0() throws IOException { - if (dataPack!=null&&dataPack.getDataBuffer().position() > 0) { - if(tt!=null) { - tt.cancel(); - tt=null; - } - dataPack.putTimePassport("packed"); - dataPack.putTimePassport("waitForAvaliable"); - while(true){ - if (isClosed()) - throw new SocketException("Socket is closed"); - boolean b=sendMap.isCongress(null, 1.0); - if(!b) - break; - sendthread.parkNanos(1000000L); - } - dataPack.putTimePassport("waitForWindow"); - DATATPacket pack=dataPack; - dataPack=null; - pack.getDataBuffer().flip(); - - - //spdlmt.transmit(pack.getDataBuffer().limit()); - controller.getIpv6Router().enqueuePacketSendTask(()->{ - sendMap.put(pack.getNumber(),pack); - - int size= pack.getDataBuffer().limit(); - //socketMonitor.getUploadBandwidth().recordPacket(pid, size); - controller.getDatatMonitor().getUploadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), size); - - //socketRawMonitor.getUploadBandwidth().recordPacket(pid, size); - return controller.createPacketToAddress(remoteaddr,0,pack); - - }); - - createDataPack(); - - - - - } - } - @Override - public void close() throws IOException { - try { - close0(); - }finally { - getKVSIInputStream().close0(); - } - } - private void close0() throws IOException { - //outputclosed=true; - if(isClosed()) - return; - if(olock!=null) - olock.lock(); - try { - flush0(); - }finally { - if(olock!=null) - olock.unlock(); - } - - DATATPacket pack=new DATATPacket(localport, port, outputcount++,MTU); - pack.getDataBuffer(). flip(); - controller.getIpv6Router().enqueuePacketSendTask(()->{ - return controller.createPacketToAddress(remoteaddr,0,pack); - }); - /*sendmaplock.readLock().lock(); - try{*/ - sendMap.put(pack.getNumber(),pack); - /*}finally { - sendmaplock.readLock().unlock(); - }*/ - try { - while(true){ - if (isClosed()) - throw new SocketException("Socket is closed"); - //System.out.println(sendmap.size()); - if(sendMap.isEmpty()) - break; - sendthread.parkNanos(1000000L); - } - - }finally { - if(tt!=null) - tt.cancel(); - } - } - @Override - public boolean isOpen() { - return !closed; - } - public boolean isAutoFlush() { - return autoFlush; - } - public void setAutoFlush(boolean b) { - autoFlush=b; - } - public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { - long lth=0; - for(int i=offset;i0) { - if(autoFlush) - flush(); - } - return lth; - } - - } - - private KVSIInputStream getKVSIInputStream() { - if(kvsii==null) - kvsii=new KVSIInputStream(); - return kvsii; - } @Override public InputStream getInputStream() throws IOException { - /*if (vin == null) { - vin = getKVSIInputStream(); - int val= vin.read(); - if(val==1) { - vin=new InflaterInputStream(vin,new Inflater(true),LIMIT); - } - }*/ + return vin; } - private KVSIOutputStream getKVSIOutputStream() { - if(kvsio==null) - kvsio=new KVSIOutputStream(); - return kvsio; - } + @Override public OutputStream getOutputStream() throws IOException { - /*if (vout == null) { - vout = getKVSIOutputStream(); - vout.write(compress); - ((KVSIOutputStream) vout).forceFlush(); - if(compress==1) { - vout=new DeflaterOutputStream(vout, new Deflater(Deflater.BEST_COMPRESSION, true), LIMIT, true); - } - }*/ return vout; } @@ -1035,48 +261,41 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl } @Override - protected void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { - super.setPerformancePreferences(connectionTime, latency, bandwidth); + public String toString() { + return "KLALBVirtualSocketImpl [vin=" + vin + ", vout=" + vout + "]"; } + + @Override protected void close() throws IOException { - close0(true); - } - - private void close0(boolean b) throws IOException { -//new Exception().printStackTrace(); - if ( !isClosed()) { - closed = true; - - if(!isListening() ) { - flowControlTask.cancel(); - sendMap.close(); - if(b) - if(remoteaddr!=null) { - controller.getIpv6Router().enqueuePacketSendTask(()->{ - return controller.createPacketToAddress(remoteaddr,0, new RSTPacket(super.localport, super.port), - 2); - }); - } - 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); - } - if(!ignoreBindCheck) - controller.getStreamPortBinder() .unbind(this); + //new Exception().printStackTrace(); + closed=true; + try { + if(vout!=null) + vout.close(); + }finally { + if(vin!=null) + vin.close(); + + if(!isListening() ) { + + controller.getKLTPregister().disconnect(this); + + }else { + //System.out.println("unlisten"+getLocalPort()); + controller.getKLTPregister().unlisten(this); + } + if(!ignoreBindCheck) + controller.getKLTPregister() .unbind(this); } + } - private boolean isClosed() { + + + private boolean isClosed() {//||(vin!=null&&vin.isClosed())&&(vout!=null&&vout.isClosed()) return closed; } @@ -1093,154 +312,22 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl @Override - public void accept(IPv6Address from,NetworkPacket np) { - KLALBPacket u=(KLALBPacket) np; - try { - //System.out.println(this+" "+u); - switch (u.getType()) { - case KLALBPacket.RST: - //reseted.countDown(); - if(!isListening()) - close0(false); - break; - case KLALBPacket.DATAT: - DATATPacket dtp = (DATATPacket) u; - - acceptDATA(from, dtp); - break; - case KLALBPacket.ACKT: - ACKTPacket ackt = (ACKTPacket) u; - acceptACK(from, ackt); - break; - - default: - break; - } - } catch (IOException e) { - e.printStackTrace(); - } + public void accept(KLTPSessionPacket stream) { + if(isListening()) { + if(!backlogQueue.contains(stream)) { + backlogQueue.add(stream); + System.out.println("添加到监听队列:"+stream); + } + }else { + System.out.println("匹配反向连接:"+stream); + if(this.vin==null) { + this.vin=stream.getInputstream(); + } + } } - private void acceptDATA(IPv6Address from, DATATPacket dtp) throws BindException, IOException { - //socketRawMonitor.getDownloadBandwidth().recordPacket(pidg.generate(), length); - if(isListening()) { - if(dtp.getNumber()==0) { - backlogQueuelock.lock(); - try{ - - //controller.getStreamPortBinder().checkIsConnected(new Pair); - InetSocketAddress is=new InetSocketAddress(from.toInet6Address(), dtp.getSrcPort()); - AtomicBoolean ab=new AtomicBoolean(true); - for (Iterator iterator = backlogQueue.iterator(); iterator.hasNext();) { - Object[] objects = (Object[]) iterator.next(); - if(is.equals(objects[0])) { - ab.set(false); - break; - } - } - if(ab.get()) { - if(controller.getStreamPortBinder().checkIsConnect(this,new InetSocketAddress(from.toInet6Address(), dtp.getSrcPort()))) { - ab.set(false); - } - } - - - if(ab.get()) - if(backlogQueue.offer(new Object[] { is,from,dtp})) { - /* controller.sendPacketToAddress(from.getRemoteVaddr(), new ACKTPacket(dtp.getDport(), dtp.getSport(),dtp.getNumber(),true,0), - 0,2);*/ - }else { - controller.getIpv6Router().enqueuePacketSendTask(()->{ - return controller.createPacketToAddress(from,0, new RSTPacket(dtp.getDstPort(), dtp.getSrcPort()), - 2); - }); - } - - }finally { - backlogQueuelock.unlock(); - } - }else { - controller.getIpv6Router().enqueuePacketSendTask(()->{ - return controller.createPacketToAddress(from,0, new RSTPacket(dtp.getDstPort(), dtp.getSrcPort()), - 2); - }); - } - }else { - //System.out.println(dtp.isCE()); - controller.getIpv6Router().enqueuePacketSendTask(()->{ - return controller.createPacketToAddress(from,0, new ACKTPacket(dtp.getDstPort(), dtp.getSrcPort(), dtp.getNumber(), - getAvaliableRcvWindow(),dtp.isCE(),0,dtp.getSendcount()), 1); - }); - boolean added=false; - - long number=dtp.getNumber(); - - /*inputchachelock.lock(); - try {*/ - if (number >= inputcount) { - - recvWindowUsed.addAndGet(dtp.getSize()); - if(recvMap.putIfAbsent (dtp.getNumber(), dtp)!=null) { - recvWindowUsed.addAndGet(-dtp.getSize()); - } - added=true; - - - - - - - }else { - //dtp.dispose(); - } - - - - if(added) { - sendDequeLock.unpark(); - } - - //dbg.println(from.getMonitor()+","+dtp.getNumber()); - } - } - - private void acceptACK(IPv6Address from, ACKTPacket ackt) throws IOException { - if(isListening()) { - controller.getIpv6Router().enqueuePacketSendTask(()->{ - return controller.createPacketToAddress(from,0, new RSTPacket(ackt.getDstPort(), ackt.getSrcPort()), - 2); - }); - }else { - peerAvaliableRcvWindow = ackt.getAvaliableRcvWindow(); - updateWindowSize(); - long bwrcv=ackt.getRcvSpeed(); - if(debug) - System.out.println("bwrcv:"+bwrcv); - algorithm.setCurrentBandwidth(bwrcv); - - - - - - - DATATPacket kl=null; - - - kl=sendMap.ack(ackt.getNumber(),ackt.isCongress()); - - - - - } - } - - private void updateWindowSize() { - sendMap.setWindowSize(Math.min(peerAvaliableRcvWindow, congestionWindow)); - - if(sendthread!=null) - sendthread.unpark(); - } + @Override public InetAddress getRemoteInetAddress() { @@ -1256,6 +343,20 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl public void setLocalPort(int i) { localport=i; } + + + public void setCompress(int i) { + // TODO 自动生成的方法存根 + + } + public int getCompress() { + // TODO 自动生成的方法存根 + return 0; + } + public boolean isConnectionPending() { + // TODO 自动生成的方法存根 + return false; + } diff --git a/src/org/kne/cloud/network/klalb/LineDecitionComparator.java b/src/org/kne/cloud/network/klalb/LineDecitionComparator.java index edc5af2..a1e719c 100644 --- a/src/org/kne/cloud/network/klalb/LineDecitionComparator.java +++ b/src/org/kne/cloud/network/klalb/LineDecitionComparator.java @@ -1,18 +1,16 @@ package org.kne.cloud.network.klalb; -import java.net.SocketException; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; -public class LineDecitionComparator implements Comparator { - private Map predictedlatencys=new HashMap<>(); - public LineDecitionComparator (List krs,KLALBPacket curr,int priority) { - for (Iterator iterator = krs.iterator(); iterator.hasNext();) { - KLALBRemoteLine klalbRemoteSocket = (KLALBRemoteLine) iterator.next(); +public class LineDecitionComparator implements Comparator { + private Map predictedlatencys=new HashMap<>(); + public LineDecitionComparator (List krs,KLALBPacket curr,int priority) { + for (Iterator iterator = krs.iterator(); iterator.hasNext();) { + KLALBRemoteLink klalbRemoteSocket = (KLALBRemoteLink) iterator.next(); long x=klalbRemoteSocket.getMonitor().getOutDelay(); //long x=klalbRemoteSocket.getMonitor().getLatency()>>1; /*long al=0; @@ -32,12 +30,12 @@ public class LineDecitionComparator implements Comparator { predictedlatencys.put(klalbRemoteSocket, x); } } - public Map getPredictedlatencys() { + public Map getPredictedlatencys() { return predictedlatencys; } @Override - public int compare(KLALBRemoteLine o1, KLALBRemoteLine o2) { + public int compare(KLALBRemoteLink o1, KLALBRemoteLink o2) { long t1=predictedlatencys.get(o1); long t2=predictedlatencys.get(o2); if(t1>t2) { diff --git a/src/org/kne/cloud/network/klalb/PacketConsumer.java b/src/org/kne/cloud/network/klalb/PacketConsumer.java deleted file mode 100644 index 8d62a68..0000000 --- a/src/org/kne/cloud/network/klalb/PacketConsumer.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.kne.cloud.network.klalb; - -import java.net.Inet6Address; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -import org.kne.cloud.network.NetworkPacket; -import org.kne.cloud.network.ipv6.IPv6Address; - -public interface PacketConsumer extends BiConsumer { - -} diff --git a/src/org/kne/cloud/network/klalb/PortBinder.java b/src/org/kne/cloud/network/klalb/PortBinder.java index 02627a1..7bf70c4 100644 --- a/src/org/kne/cloud/network/klalb/PortBinder.java +++ b/src/org/kne/cloud/network/klalb/PortBinder.java @@ -1,43 +1,34 @@ package org.kne.cloud.network.klalb; import java.net.BindException; -import java.net.Inet6Address; -import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketTimeoutException; -import java.net.UnknownHostException; -import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; -import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.kne.cloud.network.IPv6SocketAddress; -import org.kne.cloud.network.NetworkPacket; import org.kne.cloud.network.ipv6.IPv6Address; import com.google.gson.internal.Pair; -public class PortBinder { - private KLALBController controller; - public PortBinder(KLALBController controller) { +public class PortBinder { + private IPv6Address selfAddress; + public PortBinder(IPv6Address selfAddress) { super(); - this.controller = controller; + this.selfAddress = selfAddress; } private ReentrantReadWriteLock bindMaplock=new ReentrantReadWriteLock(); - private MapbindMap=new ConcurrentHashMap<>(1024,0.2f); + private Map>bindMap=new ConcurrentHashMap<>(2048); private ReentrantReadWriteLock listenMaplock=new ReentrantReadWriteLock(); - private MaplistenMap=new ConcurrentHashMap<>(1024,0.2f); + private Map>listenMap=new ConcurrentHashMap<>(2048); private ReentrantReadWriteLock connectMaplock=new ReentrantReadWriteLock(); - private Map,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>(1024,0.2f); + private Map,BindableConsumer>connectMap=new ConcurrentHashMap<>(2048); private volatile int portn=65535; - public void bind(BindableKLALBPacketConsumer ks) throws BindException { + public void bind(BindableConsumer ks) throws BindException { bindMaplock.writeLock().lock(); try { int pold=ks.getLocalPort(); @@ -86,7 +77,7 @@ public class PortBinder { } } - public void unbind(BindableKLALBPacketConsumer ks) { + public void unbind(BindableConsumer ks) { bindMaplock.writeLock().lock(); try { removeAsValue(bindMap, ks); @@ -94,7 +85,7 @@ public class PortBinder { bindMaplock.writeLock().unlock(); } } - public void connect(BindableKLALBPacketConsumer ks) throws BindException { + public void connect(BindableConsumer ks) throws BindException { connectMaplock.writeLock().lock(); try { connectMap.put(new Pair( new IPv6SocketAddress(IPv6Address.valueOf(ks.getLocalInetAddress()), ks.getLocalPort()), new IPv6SocketAddress(IPv6Address.valueOf(ks.getRemoteInetAddress()), ks.getPort())),ks); @@ -102,7 +93,7 @@ public class PortBinder { connectMaplock.writeLock().unlock(); } } - public void disconnect(BindableKLALBPacketConsumer ks) { + public void disconnect(BindableConsumer ks) { connectMaplock.writeLock().lock(); try { removeAsValue(connectMap, ks); @@ -111,7 +102,7 @@ public class PortBinder { } } - public void listen(BindableKLALBPacketConsumer ks) throws BindException { + public void listen(BindableConsumer ks) throws BindException { listenMaplock.writeLock().lock(); try { listenMap.put(new IPv6SocketAddress(IPv6Address.valueOf(ks.getLocalInetAddress()), ks.getLocalPort()),ks); @@ -119,7 +110,7 @@ public class PortBinder { listenMaplock.writeLock().unlock(); } } - public void unlisten(BindableKLALBPacketConsumer ks) { + public void unlisten(BindableConsumer ks) { /*System.out.println(listenMap); new RuntimeException("!").printStackTrace();*/ listenMaplock.writeLock().lock(); @@ -201,40 +192,68 @@ public class PortBinder { } return b; }*/ - public boolean distributePacketToConsumer(IPv6Address srcAddr,PortPacket packet) { - IPv6SocketAddress local=new IPv6SocketAddress(controller.getSelf().getAddress(), packet.getDstPort()); - IPv6SocketAddress remote=new IPv6SocketAddress(srcAddr, packet.getSrcPort()); - BindableKLALBPacketConsumer bkc=connectMap.get(new Pair(local, remote)); + public BindableConsumer distributePacketToConsumer(IPv6Address srcAddr, PortPacket packet) { + int dst=packet.getDstPort(); + int src=packet.getSrcPort(); + IPv6SocketAddress local=new IPv6SocketAddress( selfAddress,dst); + IPv6SocketAddress remote=new IPv6SocketAddress(srcAddr, src); + BindableConsumer bkc=connectMap.get(new Pair(local, remote)); if(bkc!=null) { - bkc.accept(srcAddr, (NetworkPacket) packet); - return true; + return bkc; } - IPv6SocketAddress localany=new IPv6SocketAddress(IPv6Address.UNSPECIFIED, packet.getDstPort()); + IPv6SocketAddress localany=new IPv6SocketAddress(IPv6Address.UNSPECIFIED, dst); bkc=connectMap.get(new Pair(localany, remote)); if(bkc!=null) { - bkc.accept(srcAddr, (NetworkPacket) packet); - return true; + return bkc; } bkc=listenMap.get(local); if(bkc!=null) { - bkc.accept(srcAddr, (NetworkPacket) packet); - return true; + return bkc; } bkc=listenMap.get(localany); if(bkc!=null) { - bkc.accept(srcAddr, (NetworkPacket) packet); - return true; + return bkc; } - return false; + return null; } - public boolean checkIsBind(BindableKLALBPacketConsumer klalbVirtualSocketImpl) { + public boolean checkIsBind(BindableConsumer klalbVirtualSocketImpl) { return bindMap.containsValue(klalbVirtualSocketImpl); } - public boolean checkIsConnect(BindableKLALBPacketConsumer kservers,InetSocketAddress isaf) throws BindException { + public boolean checkIsConnect(BindableConsumer kservers,InetSocketAddress isaf) throws BindException { return connectMap.containsKey(new Pair( new IPv6SocketAddress(IPv6Address.valueOf( kservers.getLocalInetAddress()), kservers.getLocalPort()),IPv6SocketAddress.valueOf( isaf))); } + public String toString() { + StringBuilder sb=new StringBuilder(); + sb.append("connectMap: Local<->Remote\n"); + for(Entry, BindableConsumer> p:connectMap.entrySet()) { + sb.append(p.getKey().first); + sb.append("<->"); + sb.append(p.getKey().second); + sb.append(" "); + sb.append(p.getValue()); + sb.append('\n'); + } + + sb.append("bindMap: Local\n"); + for(Entry> p:bindMap.entrySet()) { + sb.append(p); + sb.append(" "); + sb.append(p.getValue()); + sb.append('\n'); + } + + sb.append("listenMap: Local\n"); + for(Entry> p:listenMap.entrySet()) { + sb.append(p); + sb.append(" "); + sb.append(p.getValue()); + sb.append('\n'); + } + return sb.toString(); + + } } \ No newline at end of file diff --git a/src/org/kne/cloud/network/klalb/SendItem.java b/src/org/kne/cloud/network/klalb/SendItem.java index 82ef2e4..ecc79ee 100644 --- a/src/org/kne/cloud/network/klalb/SendItem.java +++ b/src/org/kne/cloud/network/klalb/SendItem.java @@ -14,6 +14,11 @@ public class SendItem { this.packetLength=packet.getTotalLength(); } + public SendItem(T packet,int headerCalibrate) { + this.packet=packet; + this.packetLength=packet.getTotalLength()+headerCalibrate; + } + public T getPacket() { return packet; } @@ -29,5 +34,10 @@ public class SendItem { public void setSendtime(long sendtimex) { this.sendtime=sendtimex; } + + @Override + public String toString() { + return "SendItem [packetLength=" + packetLength + ", packet=" + packet + ", sendtime=" + sendtime + "]"; + } } diff --git a/src/org/kne/cloud/network/klalb/StreamChannelKLALBPacketLink.java b/src/org/kne/cloud/network/klalb/StreamChannelKLALBPacketLink.java index 15153f0..405dd65 100644 --- a/src/org/kne/cloud/network/klalb/StreamChannelKLALBPacketLink.java +++ b/src/org/kne/cloud/network/klalb/StreamChannelKLALBPacketLink.java @@ -1,39 +1,21 @@ package org.kne.cloud.network.klalb; -import java.io.BufferedOutputStream; -import java.io.EOFException; import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; import java.io.StreamCorruptedException; import java.net.InetSocketAddress; -import java.net.ProtocolFamily; -import java.net.Socket; import java.net.SocketException; -import java.net.SocketOption; -import java.net.SocketOptions; -import java.net.StandardProtocolFamily; import java.net.StandardSocketOptions; -import java.nio.Buffer; import java.nio.ByteBuffer; -import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.Channels; import java.nio.channels.GatheringByteChannel; -import java.nio.channels.ReadableByteChannel; import java.nio.channels.ScatteringByteChannel; import java.nio.channels.SocketChannel; -import java.nio.channels.WritableByteChannel; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; import java.util.concurrent.atomic.AtomicLong; import org.kne.cloud.network.BufferedChannel; -import org.kne.cloud.network.ByteBufferAllocator; import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.NetworkPacket; import org.kne.cloud.network.ThreadTool; -import org.kne.cloud.network.TimeoutTimer; import org.kne.io.KNEChannels; public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink { @@ -64,7 +46,8 @@ public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implem public String toString() { try { return new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getLocalAddress())+"←"+new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getRemoteAddress()); - } catch (IOException e) { + } catch (Exception e) { + e.printStackTrace(); return "?←?"; } } @@ -184,19 +167,20 @@ public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implem @Override public void writeKLALBPacket(KLALBPacket kp) throws IOException { - ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4); + /*ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4); szeWrite.limit(4); //szeWrite.clear(); int length=(int) kp.getTotalLength(); - szeWrite.putInt(length); + szeWrite.putInt(0,length); szeWrite.flip(); - writableChannel.write(szeWrite); + writableChannel.write(szeWrite);*/ if(debug) { + int length=(int) kp.getTotalLength(); AtomicLong al=new AtomicLong(0); KLALBPacket.writeKLALBPacketToChannel(new MonitoredChannel(writableChannel,null,new AtomicLong[] { al}), kp); if(length!=al.get()) { @@ -212,19 +196,23 @@ public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implem private void checkflush() throws IOException { if(writableChannel instanceof BufferedChannel) { ((BufferedChannel) writableChannel).flush(); + }else if(writableChannel instanceof KLALBVirtualSocketChannel) { + ((KLALBVirtualSocketChannel) writableChannel).flush(); + } } @Override public KLALBPacket readKLALBPacket() throws IOException { - ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4); + /*ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4); szeWrite.limit(4); KNEChannels.readFully(readableChannel, szeWrite); szeWrite.flip(); - int readSize=szeWrite.getInt(); + int readSize=szeWrite.getInt();*/ KLALBPacket kp=KLALBPacket.readKLALBPacketFromChannel(readableChannel); if(debug) { + int readSize=0; long kpl=kp.getTotalLength(); if(kpl!=readSize) { throw new StreamCorruptedException(kp+" packet length error:"+kpl+"!="+readSize); diff --git a/src/org/kne/cloud/network/klalb/ui/DialPanel.java b/src/org/kne/cloud/network/klalb/ui/DialPanel.java index a7d264d..44974de 100644 --- a/src/org/kne/cloud/network/klalb/ui/DialPanel.java +++ b/src/org/kne/cloud/network/klalb/ui/DialPanel.java @@ -3,8 +3,8 @@ package org.kne.cloud.network.klalb.ui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; +import java.awt.FlowLayout; -import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingConstants; @@ -20,101 +20,114 @@ import org.jfree.chart.plot.dial.StandardDialRange; import org.jfree.chart.plot.dial.StandardDialScale; import org.jfree.chart.title.TextTitle; import org.jfree.data.general.DefaultValueDataset; +import org.kne.ui.LinearGradientColor; public class DialPanel extends JPanel { - private DialTextAnnotation textAnnotation; - private DialPlot plot; + private static final int SEGMENTS = 100; // 渐变色分段数,越高越平滑 + private static final double INNER_RADIUS = 0.85; + private static final double OUTER_RADIUS = 0.90; - public DialPanel(int size,String title,DefaultValueDataset primary, DefaultValueDataset secondary, - Color pointerColor, Color outlineColor) { - plot=createDialPlot(primary,secondary,pointerColor,outlineColor); + private DialTextAnnotation textAnnotation; + private DialPlot plot; + + public DialPanel(int size, String title, DefaultValueDataset primary, + DefaultValueDataset secondary, Color pointerColor, Color outlineColor) { + JPanel jp = new JPanel(); + jp.setLayout(new FlowLayout(FlowLayout.CENTER, 1, 1)); + plot = createDialPlot(primary, secondary, pointerColor, outlineColor); textAnnotation = new DialTextAnnotation(""); textAnnotation.setFont(UIEnv.getFont().deriveFont(20.0f)); plot.addLayer(textAnnotation); - setLayout(new BorderLayout()); - add(createChartPanel (createChart(plot),new Dimension(size, size)),BorderLayout.CENTER); - JLabel jlb=new JLabel(title); - jlb.setFont(UIEnv.getFont().deriveFont(16.0f)); - jlb.setHorizontalAlignment(SwingConstants.CENTER); - add(jlb,BorderLayout.SOUTH); - } - - public DialTextAnnotation getTextAnnotation() { - return textAnnotation; - } + jp.setLayout(new BorderLayout()); + Dimension dim = new Dimension(size, size); + jp.add(createChartPanel(createChart(plot), dim), BorderLayout.CENTER); + JLabel jlb = new JLabel(title); + jlb.setFont(UIEnv.getFont().deriveFont(16.0f)); + jlb.setHorizontalAlignment(SwingConstants.CENTER); + jp.add(jlb, BorderLayout.SOUTH); + add(jp); + } - /** + public DialTextAnnotation getTextAnnotation() { + return textAnnotation; + } + + /** * 创建图表面板 - * @param dashSize */ private ChartPanel createChartPanel(JFreeChart chart, Dimension dashSize) { ChartPanel panel = new ChartPanel(chart); panel.setPreferredSize(dashSize); - panel.setSize(panel.getPreferredSize()); + panel.setSize(dashSize); panel.setBackground(Color.WHITE); panel.setBorder(new LineBorder(Color.LIGHT_GRAY)); return panel; } - /** + + /** * 创建图表 */ private JFreeChart createChart(DialPlot plot) { JFreeChart chart = new JFreeChart(plot); chart.setBorderPaint(Color.WHITE); - chart.setTitle((TextTitle)null); + chart.setTitle((TextTitle) null); plot.setView(0, 0, 1, 1); return chart; } - /** + + /** * 创建仪表盘图表 */ - private DialPlot createDialPlot(DefaultValueDataset primary, DefaultValueDataset secondary, - Color pointerColor, Color outlineColor) { + private DialPlot createDialPlot(DefaultValueDataset primary, DefaultValueDataset secondary, + Color pointerColor, Color outlineColor) { DialPlot plot = new DialPlot(); plot.setDataset(1, primary); plot.setDataset(0, secondary); - + StandardDialFrame frame = new StandardDialFrame(); frame.setVisible(false); plot.setDialFrame(frame); - + // 添加刻度 StandardDialScale scale = new StandardDialScale(0, 100, -120, -300, 10, 5); scale.setTickRadius(0.80); scale.setTickLabelsVisible(false); plot.addScale(0, scale); - - + + // 添加指针 addDialPointers(plot, pointerColor, outlineColor); - + return plot; } + /** - * 为仪表盘添加颜色范围 + * 添加渐变色范围(平滑过渡) + * 从绿色 → 黄色 → 红色,基于 KLALBUtils.getColorByLoadPercentage() */ - public void addDefaultDialRanges() { - // 绿色范围: 0-70% - StandardDialRange greenRange = new StandardDialRange(0, 70, Color.GREEN); - addDialRange( greenRange); - - // 黄色范围: 70-90% - StandardDialRange yellowRange = new StandardDialRange(70, 90, Color.YELLOW); - addDialRange( yellowRange); - - // 红色范围: 90-100% - StandardDialRange redRange = new StandardDialRange(90, 100, Color.RED); - addDialRange( redRange); + public void addGradientRanges(LinearGradientColor lgc) { + double segmentAngle = 100.0 / SEGMENTS; // 每个分段的角度跨度 + + for (int i = 0; i < SEGMENTS; i++) { + double start = i * segmentAngle; + double end = (i + 1) * segmentAngle; + // 计算当前分段对应的负载百分比(取分段的中点) + float loadPercent = (float) (start + segmentAngle / 2); + Color color = lgc.getColor(loadPercent/100); + + StandardDialRange range = new StandardDialRange(start, end, color); + addDialRange(range); + } } - private static final double INNER=0.85; - private static final double OUTER=0.90; - public void addDialRange( StandardDialRange greenRange) { - greenRange.setInnerRadius(INNER); - greenRange.setOuterRadius(OUTER); - plot.addLayer(greenRange); - } + + + public void addDialRange(StandardDialRange range) { + range.setInnerRadius(INNER_RADIUS); + range.setOuterRadius(OUTER_RADIUS); + plot.addLayer(range); + } /** * 为仪表盘添加指针 @@ -123,12 +136,12 @@ public class DialPanel extends JPanel { // 次要指针(透明) DialPointer.Pointer secondaryPointer = new DialPointer.Pointer(); secondaryPointer.setRadius(0.8); - secondaryPointer.setFillPaint(new Color(secondaryColor.getRed(), secondaryColor.getGreen(), - secondaryColor.getBlue(), 0)); + secondaryPointer.setFillPaint(new Color(secondaryColor.getRed(), secondaryColor.getGreen(), + secondaryColor.getBlue(), 0)); secondaryPointer.setOutlinePaint(secondaryColor); secondaryPointer.setDatasetIndex(0); plot.addLayer(secondaryPointer); - + // 主要指针 DialPointer.Pointer primaryPointer = new DialPointer.Pointer(); primaryPointer.setRadius(0.8); @@ -137,4 +150,4 @@ public class DialPanel extends JPanel { primaryPointer.setDatasetIndex(1); plot.addLayer(primaryPointer); } -} +} \ No newline at end of file diff --git a/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI3.java b/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI3.java index 7c99bd9..c96998b 100644 --- a/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI3.java +++ b/src/org/kne/cloud/network/klalb/ui/KLALBStateGUI3.java @@ -16,11 +16,7 @@ import javax.swing.border.LineBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import org.jfree.chart.ChartPanel; -import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.dial.*; -import org.jfree.chart.title.TextTitle; -import org.jfree.chart.ui.RectangleEdge; import org.jfree.data.general.DefaultValueDataset; import org.kne.cloud.clock.HighAccuracyClock; import org.kne.cloud.klalb.uitool.*; @@ -29,7 +25,8 @@ import org.kne.cloud.network.ipv6.IPv6Address; import org.kne.cloud.network.ipv6.IPv6NetworkLink; import org.kne.cloud.network.klalb.*; import org.kne.cloud.network.klalb.ui.GraphPanel.GraphNode; -import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.LinkStatus; +import org.kne.cloud.network.srv6.SRv6Router; import org.kne.ui.XFrame; import org.kne.ui.YScrollPane; @@ -58,6 +55,8 @@ public class KLALBStateGUI3 extends XFrame { private DefaultValueDataset downDataPPS; // 下行数据包速率 private DefaultValueDataset backplaneDelay; private DefaultValueDataset backplanePPS; + private DefaultValueDataset backplaneECNRate; + private DefaultValueDataset backplaneLossRate; // ==================== 仪表盘文本标注 ==================== private DialTextAnnotation upSpeedText; // 上行速度文本标注 @@ -66,6 +65,8 @@ public class KLALBStateGUI3 extends XFrame { private DialTextAnnotation downPPSText; // 下行包速率文本标注 private DialTextAnnotation backplaneDelayText; private DialTextAnnotation backplanePPSText; + private DialTextAnnotation backplaneECNRateText; + private DialTextAnnotation backplaneLossRateText; // ==================== UI组件 ==================== private YScrollPane ysp, yspc; // 可垂直滚动的面板 @@ -79,7 +80,8 @@ public class KLALBStateGUI3 extends XFrame { private JTextField textFieldLocate; // 定位地址输入框 private JTextField asnField2; // ASN显示框 private JTextArea dnsAreaSet; // DNS服务器设置区域 - private JComboBox comboCongress; // 拥塞控制算法选择框 + private JComboBox comboPerformance; // 性能策略选择框 + private JComboBox comboCongestion; // 拥塞控制算法选择框 private JTextField tcpListeningSet; // TCP监听设置 private JTextField udpListeningSet; // UDP监听设置 private JTextArea openLineTabelSet; // 开放线路表设置 @@ -105,8 +107,10 @@ public class KLALBStateGUI3 extends XFrame { private SliderSettingItem linkConnectionsCount; private SliderSettingItem nagleDelayTime; private SliderSettingItem linkNagleDelayTime; + private SliderSettingItem burstLimit; private SliderSettingItem delayHbound; private SliderSettingItem delayLbound; + private ComboSettingItem performanceStrategy; private ComboSettingItem congestions; // ==================== 构造方法 ==================== @@ -345,7 +349,7 @@ public class KLALBStateGUI3 extends XFrame { upSpeed = new DefaultValueDataset(0); upDataSpeed = new DefaultValueDataset(0); DialPanel dialup=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("uploadspeed"), upSpeed, upDataSpeed, Color.RED, new Color(127, 0, 0)); - dialup.addDefaultDialRanges(); + dialup.addGradientRanges(UIEnv.RANGE_1); upSpeedText =dialup.getTextAnnotation(); @@ -355,7 +359,7 @@ public class KLALBStateGUI3 extends XFrame { downSpeed = new DefaultValueDataset(0); downDataSpeed = new DefaultValueDataset(0); DialPanel dialdown=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("downloadspeed"), downSpeed, downDataSpeed, Color.GREEN, new Color(0, 127, 0)); - dialdown.addDefaultDialRanges(); + dialdown.addGradientRanges(UIEnv.RANGE_1); downSpeedText =dialdown.getTextAnnotation(); dashs.add(dialdown); @@ -369,7 +373,7 @@ public class KLALBStateGUI3 extends XFrame { upPPS = new DefaultValueDataset(0); upDataPPS = new DefaultValueDataset(0); DialPanel dialupPPS=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("uploadpps"), upPPS, upDataPPS, Color.RED, new Color(127, 0, 0)); - dialupPPS.addDefaultDialRanges(); + dialupPPS.addGradientRanges(UIEnv.RANGE_1); upPPSText = dialupPPS.getTextAnnotation(); dashs.add(dialupPPS); @@ -378,7 +382,7 @@ public class KLALBStateGUI3 extends XFrame { downPPS = new DefaultValueDataset(0); downDataPPS = new DefaultValueDataset(0); DialPanel dialdownPPS=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("downloadpps"), downPPS, downDataPPS, Color.GREEN, new Color(0, 127, 0)); - dialdownPPS.addDefaultDialRanges(); + dialdownPPS.addGradientRanges(UIEnv.RANGE_1); downPPSText = dialdownPPS.getTextAnnotation(); dashs.add(dialdownPPS); @@ -391,21 +395,8 @@ public class KLALBStateGUI3 extends XFrame { // 背板转发延迟仪表盘 backplaneDelay = new DefaultValueDataset(0); DialPanel dialupPPS=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("backplanedelay"), backplaneDelay, null, Color.BLUE, new Color(0, 0, 127)); - // 绿色范围: 0-1% - StandardDialRange greenRange = new StandardDialRange(0, 1, Color.GREEN); - dialupPPS.addDialRange( greenRange); - - // 黄色范围: 1-10% - StandardDialRange yellowRange = new StandardDialRange(1, 10, Color.YELLOW); - dialupPPS.addDialRange( yellowRange); - - // 红色范围: 10-50% - StandardDialRange redRange = new StandardDialRange(10, 50, Color.RED); - dialupPPS.addDialRange( redRange); - - StandardDialRange redblackRange = new StandardDialRange(50, 100, new Color(128, 0, 0)); - dialupPPS.addDialRange( redblackRange); + dialupPPS.addGradientRanges(UIEnv.RANGE_2); backplaneDelayText = dialupPPS.getTextAnnotation(); dashs.add(dialupPPS); @@ -413,10 +404,28 @@ public class KLALBStateGUI3 extends XFrame { // 背板PPS仪表盘 backplanePPS = new DefaultValueDataset(0); DialPanel backPPS=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("backplanepps"), backplanePPS, null, Color.BLUE, new Color(0, 0, 127)); - backPPS.addDefaultDialRanges(); + backPPS.addGradientRanges(UIEnv.RANGE_1); backplanePPSText = backPPS.getTextAnnotation(); dashs.add(backPPS); + + + backplaneECNRate = new DefaultValueDataset(0); + DialPanel ecnRate=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("backplaneecnrate"), backplaneECNRate, null, Color.BLUE, new Color(0, 0, 127)); + + ecnRate.addGradientRanges(UIEnv.RANGE_3); + + backplaneECNRateText = ecnRate.getTextAnnotation(); + dashs.add(ecnRate); + + + backplaneLossRate = new DefaultValueDataset(0); + DialPanel lossRate1=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("backplanelossrate"), backplaneLossRate, null, Color.BLUE, new Color(0, 0, 127)); + + lossRate1.addGradientRanges(UIEnv.RANGE_4); + backplaneLossRateText = lossRate1.getTextAnnotation(); + + dashs.add(lossRate1); } @@ -869,6 +878,21 @@ public class KLALBStateGUI3 extends XFrame { denyBroadcast=denyBroadcastc.getCheckBox(); settings.getView().add(denyBroadcastc); + //性能设置标题 + + SettingItem pshi = new SettingItem(UIEnv.getRsb().getString("performancesettings"), + UIEnv.getFont().deriveFont(20.0f).deriveFont(Font.BOLD), CONST.itemwidth, CONST.settingheight); + settings.getView().add(pshi); + + + performanceStrategy = new ComboSettingItem(UIEnv.getRsb().getString("performancestrategy"), + CONST.itemwidth, CONST.settingheight); + comboPerformance = performanceStrategy.getComboBox(); + comboPerformance.addItem("BBR"); + comboPerformance.addItem("Vegas2"); + settings.getView().add(performanceStrategy); + + // 高级设置标题 SettingItem hi = new SettingItem(UIEnv.getRsb().getString("advancedsettings"), UIEnv.getFont().deriveFont(20.0f).deriveFont(Font.BOLD), CONST.itemwidth, CONST.settingheight); @@ -909,27 +933,42 @@ public class KLALBStateGUI3 extends XFrame { congestions = new ComboSettingItem(UIEnv.getRsb().getString("congresscontrolalgorithm"), CONST.itemwidth, CONST.settingheight); - comboCongress = congestions.getComboBox(); - comboCongress.addItem("BBR"); - comboCongress.addItem("Vegas2"); + comboCongestion = congestions.getComboBox(); + comboCongestion.addItem("BBR"); + comboCongestion.addItem("Vegas2"); settings.getView().add(congestions); settings.updateScrool(); - + burstLimit= new SliderSettingItem(UIEnv.getRsb().getString("burstlimit"), + CONST.itemwidth, CONST.settingheight); + burstLimit.getSlider().setMaximum(1000); + burstLimit.getSlider().setValue(200); + settings.getView().add(burstLimit); delayHbound = new SliderSettingItem(UIEnv.getRsb().getString("delayupperbound"), CONST.itemwidth, CONST.settingheight); - delayHbound.getSlider().setMaximum(1000); + delayHbound.getSlider().setMaximum(300); delayHbound.getSlider().setValue(200); settings.getView().add(delayHbound); delayLbound = new SliderSettingItem(UIEnv.getRsb().getString("delaylowerbound"), CONST.itemwidth, CONST.settingheight); - delayLbound.getSlider().setMaximum(500); + delayLbound.getSlider().setMaximum(300); delayLbound.getSlider().setValue(150); settings.getView().add(delayLbound); + ChangeListener clb= new ChangeListener() { + + @Override + public void stateChanged(ChangeEvent e) { + int val=burstLimit.getSlider().getValue(); + burstLimit.getLabelx().setText(String.format("%.3f",1.0+val/1000.0)); + } + }; + clb.stateChanged(null); + burstLimit.getSlider().addChangeListener(clb); + ChangeListener clh= new ChangeListener() { @Override @@ -1142,6 +1181,8 @@ public class KLALBStateGUI3 extends XFrame { kck.setDenyLineTableBroadcast(denyBroadcast.isSelected()); kck.setCongestionAlgorithm((String) congestions.getComboBox().getSelectedItem()); + + kck.setBurstLimit(1.0+burstLimit.getSlider().getValue()/1000.0); kck.setDelayUpperBound(1.0+delayHbound.getSlider().getValue()/1000.0); @@ -1177,10 +1218,10 @@ public class KLALBStateGUI3 extends XFrame { // 遍历所有线路,更新或添加TPanel2 for (Object obj : kll) { IPv6NetworkLink link = (IPv6NetworkLink) obj; - if (!(link instanceof KLALBRemoteLine)) { + if (!(link instanceof KLALBRemoteLink)) { continue; } - KLALBRemoteLine ent = (KLALBRemoteLine) link; + KLALBRemoteLink ent = (KLALBRemoteLink) link; Component[] count = ysp.getView().getComponents(); boolean found = false; @@ -1190,7 +1231,7 @@ public class KLALBStateGUI3 extends XFrame { if (tp instanceof TPanel2) { if (((TPanel2) tp).getTunnel().equals(ent)) { tp.setVisible(showoffline.isSelected() || ( - ent.getMonitor().getState() != MonitorData.DOWN)); + ent.getState() != LinkStatus.DOWN)); found = true; break; } @@ -1201,7 +1242,7 @@ public class KLALBStateGUI3 extends XFrame { if (!found) { TPanel2 tp = new TPanel2(ent, kc); tp.setVisible(showoffline.isSelected() || ( - ent.getMonitor().getState()!= MonitorData.DOWN)); + ent.getState()!= LinkStatus.DOWN)); ysp.getView().add(tp); } } @@ -1318,6 +1359,37 @@ public class KLALBStateGUI3 extends XFrame { downDataPPS.setValue(Math.min(downDataPPS.getValue().doubleValue() * 0.98 + inPPSload1 * 0.02, 101.0)); } + SRv6Router router= kc.getIpv6Router(); + if(router!=null) { + // 更新背板延迟 + double backplaneTimev = router.getBackplaneTime()* 100.0/100000.0; + if (Double.isFinite(backplaneTimev)) { + backplaneDelayText.setLabel(KLALBUtils.convertUintNanoDefalut(router.getBackplaneTime()) + "s"); + backplaneDelay.setValue(Math.min(backplaneDelay.getValue().doubleValue() * 0.98 + backplaneTimev * 0.02, 101.0)); + } + + // 更新背板转发率 + double backplanePPSv = router.getBackplanePPS() * 100.0 / router.getBackplanePPSMax(); + if (Double.isFinite(backplanePPSv)) { + backplanePPSText.setLabel(KLALBUtils.convertUintDefalut(router.getBackplanePPS()) + "PPS"); + backplanePPS.setValue(Math.min(backplanePPS.getValue().doubleValue() * 0.98 + backplanePPSv * 0.02, 101.0)); + } + + // 更新背板ECN率 + double backplaneECNv = router.getECNRate() * 100.0 ; + if (Double.isFinite(backplaneECNv)) { + backplaneECNRateText.setLabel(String.format("%.1f",backplaneECNv) + "%"); + backplaneECNRate.setValue(Math.min(backplaneECNRate.getValue().doubleValue() * 0.98 + backplaneECNv * 0.02, 101.0)); + } + + // 更新背板ECN率 + double backplaneLossv = router.getLossRate() * 100.0 ; + if (Double.isFinite(backplaneLossv)) { + backplaneLossRateText.setLabel(String.format("%.1f",backplaneLossv) + "%"); + backplaneLossRate.setValue(Math.min(backplaneLossRate.getValue().doubleValue() * 0.98 + backplaneLossv * 0.02, 101.0)); + } + } + // 更新在线设备数 String contt = Long.toString(kc.getIpv6Router().getKlalbRouteProtol().getDevicesFound()); if (!contt.equals(devicesOnline.getText())) { @@ -1431,6 +1503,10 @@ public class KLALBStateGUI3 extends XFrame { }else { congestions.getComboBox().setSelectedItem(con); } + double ubb=kck.getBurstLimit(); + if(ubb!=0) + burstLimit.getSlider().setValue((int) Math.round((ubb-1.0)*1000)); + double ub=kck.getDelayUpperBound(); if(ub!=0) delayHbound.getSlider().setValue((int) Math.round((ub-1.0)*1000)); diff --git a/src/org/kne/cloud/network/klalb/ui/KperfGUI.java b/src/org/kne/cloud/network/klalb/ui/KperfGUI.java index 712ecb3..e1f6e06 100644 --- a/src/org/kne/cloud/network/klalb/ui/KperfGUI.java +++ b/src/org/kne/cloud/network/klalb/ui/KperfGUI.java @@ -6,17 +6,10 @@ import java.awt.Dimension; import javax.swing.border.LineBorder; -import org.jfree.chart.ChartPanel; -import org.jfree.chart.JFreeChart; -import org.jfree.chart.plot.dial.DialPlot; -import org.jfree.chart.plot.dial.DialPointer; import org.jfree.chart.plot.dial.DialTextAnnotation; -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.data.general.DefaultValueDataset; import org.kne.cloud.network.MultipurposeSocketAddress; +import org.kne.cloud.network.klalb.CONST; import org.kne.cloud.network.klalb.KLALBUtils; import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; import org.kne.cloud.network.perf.Kperf; @@ -24,12 +17,10 @@ import org.kne.cloud.network.perf.KperfReports; import org.kne.ui.XFrame; import javax.swing.JTabbedPane; import java.awt.BorderLayout; -import javax.swing.JMenuBar; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.JButton; -import javax.swing.JMenu; import java.awt.GridLayout; import java.awt.Image; @@ -43,7 +34,6 @@ import java.util.TimerTask; import java.awt.event.ActionEvent; import javax.swing.JLabel; import javax.imageio.ImageIO; -import javax.swing.BoxLayout; import java.awt.Font; import javax.swing.SwingConstants; import javax.swing.ImageIcon; @@ -59,7 +49,6 @@ public class KperfGUI extends XFrame{ private DefaultValueDataset upSpeed; private DefaultValueDataset upDataSpeed; private DialTextAnnotation upSpeedText; - private Dimension dashSize=new Dimension((int) (145 * 0.7), (int) (165 * 0.7)); private DefaultValueDataset downSpeed; private DefaultValueDataset downDataSpeed; private DialTextAnnotation downSpeedText; @@ -227,6 +216,8 @@ public class KperfGUI extends XFrame{ panel_6.add(downPPSLabel, BorderLayout.EAST); + + /* { upSpeed = new DefaultValueDataset(0); upDataSpeed = new DefaultValueDataset(0); @@ -466,7 +457,48 @@ public class KperfGUI extends XFrame{ cpup1.setBackground(Color.WHITE); cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY)); panel_6.add(cpup1, BorderLayout.WEST); - } + }*/ + + + // 上行速度仪表盘 + upSpeed = new DefaultValueDataset(0); + upDataSpeed = new DefaultValueDataset(0); + DialPanel dialup=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("uploadspeed"), upSpeed, upDataSpeed, Color.RED, new Color(127, 0, 0)); + dialup.addGradientRanges(UIEnv.RANGE_1); + upSpeedText =dialup.getTextAnnotation(); + + + panel_3.add(dialup, BorderLayout.WEST); + + + // 下行速度仪表盘 + downSpeed = new DefaultValueDataset(0); + downDataSpeed = new DefaultValueDataset(0); + DialPanel dialdown=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("downloadspeed"), downSpeed, downDataSpeed, Color.GREEN, new Color(0, 127, 0)); + dialdown.addGradientRanges(UIEnv.RANGE_1); + downSpeedText =dialdown.getTextAnnotation(); + + panel_4.add(dialdown, BorderLayout.WEST); + + + // 上行包速率仪表盘 + upPPS = new DefaultValueDataset(0); + upDataPPS = new DefaultValueDataset(0); + DialPanel dialupPPS=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("uploadpps"), upPPS, upDataPPS, Color.RED, new Color(127, 0, 0)); + dialupPPS.addGradientRanges(UIEnv.RANGE_1); + upPPSText = dialupPPS.getTextAnnotation(); + + panel_5.add(dialupPPS, BorderLayout.WEST); + + // 下行包速率仪表盘 + downPPS = new DefaultValueDataset(0); + downDataPPS = new DefaultValueDataset(0); + DialPanel dialdownPPS=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("downloadpps"), downPPS, downDataPPS, Color.GREEN, new Color(0, 127, 0)); + dialdownPPS.addGradientRanges(UIEnv.RANGE_1); + downPPSText = dialdownPPS.getTextAnnotation(); + + panel_6.add(dialdownPPS, BorderLayout.WEST); + JPanel panel_top = new JPanel(); panel_1.add(panel_top, BorderLayout.NORTH); panel_top.setLayout(new GridLayout(0, 2, 0, 0)); @@ -497,7 +529,8 @@ public class KperfGUI extends XFrame{ getTitlelabel().setForeground(Color.WHITE); setTitle(UIEnv.getRsb().getString("klalbperf")); - setSize((int)(1200*0.7),(int)( 800*0.7)); + setSize(CONST.windowwidth,CONST.windowheight ); + setResizable(false); setLocationRelativeTo(comp); tsk=new TimerTask() { @@ -576,6 +609,9 @@ public class KperfGUI extends XFrame{ } }); } + + + private Image icon2; private Image getIcon2() { if(icon2==null) diff --git a/src/org/kne/cloud/network/klalb/ui/LineMonitorGUI.java b/src/org/kne/cloud/network/klalb/ui/LineMonitorGUI.java index fbecc29..1cbfe79 100644 --- a/src/org/kne/cloud/network/klalb/ui/LineMonitorGUI.java +++ b/src/org/kne/cloud/network/klalb/ui/LineMonitorGUI.java @@ -1,37 +1,29 @@ package org.kne.cloud.network.klalb.ui; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.GridLayout; -import java.awt.Image; -import java.awt.Stroke; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.net.Inet6Address; import java.util.Date; import java.util.Timer; import java.util.TimerTask; +import java.util.UUID; -import javax.imageio.ImageIO; import javax.swing.JPanel; import javax.swing.border.LineBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; 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.congestion.SendPacketSlidingWindow; import org.kne.cloud.network.ipv6.IPv6Address; import org.kne.cloud.network.ipv6.IPv6AddressGroup; -import org.kne.cloud.network.klalb.KLALBRemoteLine; -import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.ipv6.IPv6Packet; +import org.kne.cloud.network.klalb.KLALBRemoteLink; +import org.kne.cloud.network.monitor.LinkStatus; import org.kne.cloud.network.monitor.TimestampMonitorValue; import org.kne.math.Long128; import org.kne.ui.XFrame; @@ -41,39 +33,42 @@ import java.awt.BorderLayout; import javax.swing.ImageIcon; import javax.swing.JLabel; -import javax.swing.JTextField; -import javax.swing.JButton; -import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; -import java.awt.event.ActionEvent; -import java.awt.Font; -import javax.swing.SwingConstants; import javax.swing.JSlider; public class LineMonitorGUI extends XFrame { private Timer timer; private Timer timer1; private Timer timer2; + private Timer timer3; private TimerTask tsk3; - private TimerTask tsk4, tsk5; + private TimerTask tsk4, tsk5,tsk6; private TimerTask d1; private TimerTask d2; + private TimerTask d3; private TimeSeries spdup = new TimeSeries(UIEnv.getRsb().getString("uploadspeed")); private TimeSeries spddown = new TimeSeries(UIEnv.getRsb().getString("downloadspeed")); private TimeSeries delayup = new TimeSeries(UIEnv.getRsb().getString("uploaddelay")); private TimeSeries delaydown = new TimeSeries(UIEnv.getRsb().getString("downloaddelay")); - // private TimeSeries delayupmin=new TimeSeries("Upload delay minimum"); - // private TimeSeries delaydownmin=new TimeSeries("Download delay minimum"); + private TimeSeries delayupmin=new TimeSeries(UIEnv.getRsb().getString("uploadbasedelay")); + private TimeSeries delaydownmin=new TimeSeries(UIEnv.getRsb().getString("downloadbasedelay")); + - private KLALBRemoteLine tr; + private TimeSeries bufferused = new TimeSeries(UIEnv.getRsb().getString("usedbuffer")); + private TimeSeries queueused = new TimeSeries(UIEnv.getRsb().getString("queueused")); + private TimeSeries buffermax = new TimeSeries(UIEnv.getRsb().getString("maxbuffer")); + + private KLALBRemoteLink tr; private JFreeChart jfc; private JFreeChart jfce; + private JFreeChart jbfc; private JLabel spdp; private JLabel delp; + private JLabel sbpdp; private long timeRange = 5000; private long[] values = new long[] { 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000 }; private JPanel panel_1; @@ -81,20 +76,20 @@ public class LineMonitorGUI extends XFrame { // private ChartPanel delp; // private ChartPanel spdp; - public LineMonitorGUI(KLALBRemoteLine t) { + public LineMonitorGUI(KLALBRemoteLink t) { this.tr = t; setSize(1200, 780); setLocationRelativeTo(null); setIconImage(UIEnv.getIcon()); - setTitle("Line Monitor:" + t.getMonitor().getName()); + setTitle("Line Monitor:" + t.getName()); 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(); - jp.setLayout(new GridLayout(2, 1)); + jp.setLayout(new GridLayout(2, 2)); getContentPane().add(jp); TimeSeriesCollection tsc = new TimeSeriesCollection(); @@ -110,12 +105,17 @@ public class LineMonitorGUI extends XFrame { spdp.setBorder(new LineBorder(Color.DARK_GRAY)); jp.add(spdp); + + + + TimeSeriesCollection tsce = new TimeSeriesCollection(); tsce.addSeries(delayup); tsce.addSeries(delaydown); - // tsce.addSeries(delayupmin); - // tsce.addSeries(delaydownmin); + tsce.addSeries(delayupmin); + tsce.addSeries(delaydownmin); + jfce = ChartFactory.createTimeSeriesChart(UIEnv.getRsb().getString("delaymonitor"), UIEnv.getRsb().getString("time") + "(s)", UIEnv.getRsb().getString("delay") + "(ms)", tsce); jfce.getXYPlot().setBackgroundPaint(Color.BLACK); @@ -124,17 +124,40 @@ public class LineMonitorGUI extends XFrame { 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().setSeriesStroke(2, dotted); - * jfce.getXYPlot().getRenderer().setSeriesPaint(3,Color.GREEN); - * jfce.getXYPlot().getRenderer().setSeriesStroke(3, dotted); - */ + + 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); + changeFont(jfce); delp = new JLabel(); delp.setBorder(new LineBorder(Color.DARK_GRAY)); jp.add(delp); + + + + + TimeSeriesCollection tbsc = new TimeSeriesCollection(); + tbsc.addSeries(bufferused); + tbsc.addSeries(queueused); + tbsc.addSeries(buffermax); + jbfc = ChartFactory.createTimeSeriesChart(UIEnv.getRsb().getString("bufferusagemonitor"), + UIEnv.getRsb().getString("time") + "(s)", UIEnv.getRsb().getString("buffer") + "(KB)", tbsc); + jbfc.getXYPlot().setBackgroundPaint(Color.BLACK); + jbfc.getXYPlot().getRenderer().setSeriesPaint(0, Color.BLUE); + jbfc.getXYPlot().getRenderer().setSeriesPaint(1, Color.MAGENTA); + jbfc.getXYPlot().getRenderer().setSeriesPaint(2, Color.CYAN); + changeFont(jbfc); + sbpdp = new JLabel(); + sbpdp.setBorder(new LineBorder(Color.DARK_GRAY)); + jp.add(sbpdp); + + + + + JPanel panel = new JPanel(); panel.setOpaque(false); getContentPane().add(panel, BorderLayout.NORTH); @@ -219,14 +242,25 @@ public class LineMonitorGUI extends XFrame { synchronized (jfc) { jfc.getXYPlot().getDomainAxis().setFixedAutoRange(timeRange); - spdup.setMaximumItemCount((int) timeRange); - spddown.setMaximumItemCount((int) timeRange); + spdup.setMaximumItemCount((int) timeRange/5); + spddown.setMaximumItemCount((int) timeRange/5); } synchronized (jfce) { jfce.getXYPlot().getDomainAxis().setFixedAutoRange(timeRange); - delayup.setMaximumItemCount((int) timeRange); - delaydown.setMaximumItemCount((int) timeRange); + delayup.setMaximumItemCount((int) timeRange/5); + delaydown.setMaximumItemCount((int) timeRange/5); + delayupmin.setMaximumItemCount((int) timeRange/5); + delaydownmin.setMaximumItemCount((int) timeRange/5); + } + + + synchronized (jbfc) { + + jbfc.getXYPlot().getDomainAxis().setFixedAutoRange(timeRange); + bufferused.setMaximumItemCount((int) timeRange/5); + buffermax.setMaximumItemCount((int) timeRange/5); + queueused.setMaximumItemCount((int) timeRange/5); } windowSelect.setText(timeRange / 1000 + "s"); } @@ -269,11 +303,31 @@ public class LineMonitorGUI extends XFrame { new Date(valdown.getTimestamp().divide(new Long128(1000000L)).longValue())); delaydown.addOrUpdate(ms2, valdown.getDelay() / 1000000.0); } + + Millisecond ms = new Millisecond( + new Date(tr.getMonitor().getClock().getCurrentTimeMillis())); + delayupmin.addOrUpdate(ms, tr.getMonitor().getOutDelayMin() / 1000000.0); + delaydownmin.addOrUpdate(ms, tr.getMonitor().getInDelayMin() / 1000000.0); } } } + private void recordBufferData() { + if (isVisible()) { + Millisecond ms = new Millisecond( + new Date(tr.getMonitor().getClock().getCurrentTimeMillis())); + synchronized (jbfc) { + SendPacketSlidingWindow window=tr.getWindow(); + if(window !=null) { + bufferused.addOrUpdate(ms, window.getSendWindowUsed() / 1024.0); + //queueused.addOrUpdate(ms, tr.getQueueUsed() / 1024.0); + buffermax.addOrUpdate(ms, window.getWindowSize() / 1024.0); + + } + } + } + } @Override public void setVisible(boolean b) { if (b) { @@ -281,6 +335,7 @@ public class LineMonitorGUI extends XFrame { timer = new Timer(); timer1 = new Timer(); timer2 = new Timer(); + timer3 = new Timer(); tsk3 = new TimerTask() { @Override @@ -303,6 +358,13 @@ public class LineMonitorGUI extends XFrame { recordDelayData(); } }; + tsk6 = new TimerTask() { + + @Override + public void run() { + recordBufferData(); + } + }; d1 = new TimerTask() { @Override @@ -330,11 +392,27 @@ public class LineMonitorGUI extends XFrame { } } }; + d3 = new TimerTask() { + + @Override + public void run() { + if (isVisible()) { + synchronized (jbfc) { + ImageIcon i3 = new ImageIcon( + jbfc.createBufferedImage(sbpdp.getWidth(), sbpdp.getHeight())); + sbpdp.setIcon(i3); + } + + } + } + }; timer.scheduleAtFixedRate(tsk3, 25, 25); - timer1.scheduleAtFixedRate(tsk4, 5, 5); + timer1.scheduleAtFixedRate(tsk4, 10, 10); timer1.scheduleAtFixedRate(d1, 25, 25); - timer2.scheduleAtFixedRate(tsk5, 1, 1); + timer2.scheduleAtFixedRate(tsk5, 10, 10); timer2.scheduleAtFixedRate(d2, 25, 25); + timer3.scheduleAtFixedRate(tsk6, 10, 10); + timer3.scheduleAtFixedRate(d3, 25, 25); } } else { @@ -348,6 +426,8 @@ public class LineMonitorGUI extends XFrame { d1.cancel(); if (d2 != null) d2.cancel(); + if (d3 != null) + d3.cancel(); if (timer != null) timer.cancel(); if (timer1 != null) @@ -355,20 +435,23 @@ public class LineMonitorGUI extends XFrame { if (timer2 != null) timer2.cancel(); + + if (timer3 != null) + timer3.cancel(); timer = null; } super.setVisible(b); } public void updateTraffic() { - switch (tr.getMonitor().getState()) { - case MonitorData.DOWN: + switch (tr.getState()) { + case LinkStatus.DOWN: getTitlelabel().setForeground(Color.RED); break; - case MonitorData.UNSTABLE: + case LinkStatus.UNSTABLE: getTitlelabel().setForeground(Color.YELLOW); break; - case MonitorData.UP: + case LinkStatus.UP: getTitlelabel().setForeground(Color.GREEN); break; diff --git a/src/org/kne/cloud/network/klalb/ui/TPanel2.java b/src/org/kne/cloud/network/klalb/ui/TPanel2.java index 44ddf93..eaac332 100644 --- a/src/org/kne/cloud/network/klalb/ui/TPanel2.java +++ b/src/org/kne/cloud/network/klalb/ui/TPanel2.java @@ -3,7 +3,6 @@ package org.kne.cloud.network.klalb.ui; import javax.swing.JPanel; import javax.swing.JLabel; import java.awt.BorderLayout; -import java.awt.Button; import java.awt.Color; import java.awt.Dimension; @@ -11,27 +10,22 @@ import javax.swing.SwingConstants; import javax.swing.border.LineBorder; import org.kne.cloud.network.MultipurposeSocketAddress; -import org.kne.cloud.network.ipv6.IPv6Address; import org.kne.cloud.network.ipv6.IPv6AddressGroup; 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.KLALBRemoteLink; import org.kne.cloud.network.klalb.KLALBUtils; -import org.kne.cloud.network.monitor.MonitorData; +import org.kne.cloud.network.monitor.LinkStatus; 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; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; -import java.awt.image.BufferedImage; import java.io.IOException; -import java.net.Inet6Address; -import java.net.SocketTimeoutException; import java.util.Objects; import javax.imageio.ImageIO; @@ -42,7 +36,7 @@ import javax.swing.JMenuItem; public class TPanel2 extends JPanel { private JLabel tname; private JLabel targup; - private KLALBRemoteLine tunnel; + private KLALBRemoteLink tunnel; private LineMonitorGUI mdg; private JMenuItem mntmNewMenuItem2; private JMenuItem mntmNewMenuItem3; @@ -75,14 +69,14 @@ public class TPanel2 extends JPanel { /** * @wbp.parser.constructor */ - public TPanel2(KLALBRemoteLine t,KLALBController kc) { + public TPanel2(KLALBRemoteLink t,KLALBController kc) { this.tunnel = t; //setOpaque(false); setBackground(Color.WHITE); setLayout(new BorderLayout(0, 0)); tname = new JLabel(); - tname.setText(t.getMonitor().getName()); + tname.setText(t.getName()); tname.setFont(new Font("宋体", Font.BOLD, 14)); targup = new JLabel(); @@ -311,8 +305,8 @@ public class TPanel2 extends JPanel { private void updateText() { - targup.setText(KLALBUtils. convertIBUint(tunnel.getMonitor().getOutTraffic()) + " " + KLALBUtils. convertIBUint(tunnel.getMonitor().getOutSpeed()) + "/s "+ KLALBUtils.convertUintNanoDefalut(tunnel.getMonitor().getOutDelay()) + "s"); - targdown.setText(KLALBUtils. convertIBUint(tunnel.getMonitor().getInTraffic()) + " " + KLALBUtils. convertIBUint(tunnel.getMonitor().getInSpeed()) + "/s " + KLALBUtils.convertUintNanoDefalut( tunnel.getMonitor().getInDelay()) + "s"); + targup.setText( KLALBUtils. convertIBUint(tunnel.getMonitor().getOutSpeed()) + "/s "+KLALBUtils. convertUintDefalut(tunnel.getMonitor().getOutPPS()) + "PPS "+ KLALBUtils.convertUintNanoDefalut(tunnel.getMonitor().getOutDelay()) + "s"); + targdown.setText(KLALBUtils. convertIBUint(tunnel.getMonitor().getInSpeed()) + "/s "+KLALBUtils. convertUintDefalut(tunnel.getMonitor().getInPPS()) + "PPS " + KLALBUtils.convertUintNanoDefalut( tunnel.getMonitor().getInDelay()) + "s"); if(tunnel.getMonitor().getOutSpeed()>4096||tunnel.getMonitor().getInSpeed()>4096) { lblNewLabel_2.setBackground(Color.ORANGE); @@ -321,22 +315,22 @@ public class TPanel2 extends JPanel { } } - public KLALBRemoteLine getTunnel() { + public KLALBRemoteLink getTunnel() { return tunnel; } public void updateTraffic() { - switch (tunnel.getMonitor().getState()) { - case MonitorData.DOWN: + switch (tunnel.getState()) { + case LinkStatus.DOWN: tname.setForeground(Color.RED); lblNewLabel_1.setBackground(Color.LIGHT_GRAY); break; - case MonitorData.UNSTABLE: + case LinkStatus.UNSTABLE: tname.setForeground(Color.YELLOW); lblNewLabel_1.setBackground(Color.LIGHT_GRAY); break; - case MonitorData.UP: + case LinkStatus.UP: tname.setForeground(Color.GREEN); lblNewLabel_1.setBackground(Color.GREEN); @@ -344,7 +338,7 @@ public class TPanel2 extends JPanel { default: break; } - if(tunnel.getMonitor().getState()!=MonitorData.DOWN) { + if(tunnel.getState()!=LinkStatus.DOWN) { IPv6AddressGroup unvar=tunnel.getRemoteVaddr(); diff --git a/src/org/kne/cloud/network/klalb/ui/UIEnv.java b/src/org/kne/cloud/network/klalb/ui/UIEnv.java index a526789..eabfc6b 100644 --- a/src/org/kne/cloud/network/klalb/ui/UIEnv.java +++ b/src/org/kne/cloud/network/klalb/ui/UIEnv.java @@ -1,32 +1,29 @@ 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; + +import org.kne.ui.LinearGradientColor; 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); + static final LinearGradientColor RANGE_1=new LinearGradientColor(new float[] {0.0f,0.5f,0.8f,1.0f},new Color[] {Color.GREEN,Color.GREEN,Color.YELLOW,Color.RED}); + static final LinearGradientColor RANGE_2=new LinearGradientColor(new float[] {0.0f,0.05f,0.3f,0.6f,1.0f},new Color[] {Color.GREEN,Color.GREEN,Color.YELLOW,Color.RED,Color.BLACK}); + static final LinearGradientColor RANGE_3=new LinearGradientColor(new float[] {0.0f,0.02f,0.15f,0.5f,1.0f},new Color[] {Color.GREEN,Color.GREEN,Color.YELLOW,Color.RED,Color.BLACK}); + static final LinearGradientColor RANGE_4=new LinearGradientColor(new float[] {0.0f,0.01f,0.1f,1.0f},new Color[] {Color.GREEN,Color.YELLOW,Color.RED,Color.BLACK}); + + private static ResourceBundle rsb; public static void setRsb(String xrsb) throws IOException { rsb=new PropertyResourceBundle(UIEnv.class.getResourceAsStream("/klalb_"+xrsb+".properties")); diff --git a/src/org/kne/cloud/network/monitor/ArrayListTimestampMonitor.java b/src/org/kne/cloud/network/monitor/ArrayListTimestampMonitor.java index 60a18a6..a3549e0 100644 --- a/src/org/kne/cloud/network/monitor/ArrayListTimestampMonitor.java +++ b/src/org/kne/cloud/network/monitor/ArrayListTimestampMonitor.java @@ -1,13 +1,10 @@ package org.kne.cloud.network.monitor; -import java.math.BigInteger; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.LongAdder; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -63,28 +60,32 @@ public class ArrayListTimestampMonitor implements TimestampMonitor { private volatile long prev = System.nanoTime(); - public boolean recordPacket(K key, int length) { - return recordPacket(key, clock.getCurrentTimeNanos(), length, Long.MAX_VALUE / 1024); + /*public boolean recordPacket(K key,int count, int length) { + return recordPacket(key, clock.getCurrentTimeNanos(),count, length, Long.MAX_VALUE / 1024); + }*/ + public boolean recordPacket(K key,int count, int length) { + return recordPacket(key,clock.getCurrentTimeNanos(),count,length); + } + + public boolean recordPacket(K key,int count, int length, long delay) { + return recordPacket(key, clock.getCurrentTimeNanos(),count, length, delay); } - public boolean recordPacket(K key, int length, long delay) { - return recordPacket(key, clock.getCurrentTimeNanos(), length, delay); - } - - public boolean recordPacket(K key, Long128 timestamp, int length) { - return recordPacket(key, timestamp, length, Long.MAX_VALUE / 1024); + public boolean recordPacket(K key, Long128 timestamp,int count, int length) { + return recordPacket(key, timestamp,count, length, Long.MAX_VALUE / 1024); } + /** * 记录数据包 - 使用插入排序保持列表有序,添加时间戳验证 */ - public boolean recordPacket(K key, Long128 timestamp, int length, long delay) { + public boolean recordPacket(K key, Long128 timestamp,int count, int length, long delay) { // 验证时间戳的合理性 validateTimestamp(timestamp); // 快速路径:尝试sequence=0 TimestampMonitorKey monitorKey = new TimestampMonitorKey<>(key, 0); - TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey, timestamp, length, delay); + TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey, timestamp,count, length, delay); autoCleanup(cleanupThreshold); rwLock.writeLock().lock(); @@ -327,7 +328,7 @@ public class ArrayListTimestampMonitor implements TimestampMonitor { /** * 从已排序的列表中计算包数 - 优化版本,只需要startTime */ - private long calculatePacketCountFromSortedList(List sortedList, Long128 startTime) { + /*private long calculatePacketCountFromSortedList(List sortedList, Long128 startTime) { if (sortedList.isEmpty()) { return 0; } @@ -340,8 +341,30 @@ public class ArrayListTimestampMonitor implements TimestampMonitor { // 计算从startIndex到末尾的所有包数(因为数据包不会来自未来) return sortedList.size() - startIndex; + }*/ + + private long calculatePacketCountFromSortedList(List sortedList, Long128 startTime) { + + if (sortedList.isEmpty()) { + return 0; } + // 使用二分查找找到第一个 >= startTime 的元素位置 + int startIndex = findFirstValidIndexFromSorted(sortedList, startTime); + + if (startIndex >= sortedList.size()) { + return 0; + } + + // 计算从startIndex到末尾的所有数据量(因为数据包不会来自未来) + long sum = 0; + for (int i = startIndex; i < sortedList.size(); i++) { + sum += sortedList.get(i).getCount(); + } + + return sum; + } + public long calculateBandwidth(long timeWindowNs) { return calculateBandwidth(clock.getCurrentTimeNanos(), timeWindowNs); } @@ -413,7 +436,7 @@ public class ArrayListTimestampMonitor implements TimestampMonitor { // 计算从startIndex到末尾的所有数据(因为数据包不会来自未来) for (int i = startIndex; i < sortedList.size(); i++) { TimestampMonitorValue value = sortedList.get(i); - stats.packetCount++; + stats.packetCount+=value.getCount(); stats.totalBytes += value.getLength(); if (stats.earliestTimestamp.equals(Long128.ZERO) @@ -490,7 +513,7 @@ public class ArrayListTimestampMonitor implements TimestampMonitor { 100, 200000000L); Thread t = new Thread(() -> { while (true) { - monitor.recordPacket(along.getAndIncrement(), 1000); + monitor.recordPacket(along.getAndIncrement(),1, 1000); } }); t.start(); diff --git a/src/org/kne/cloud/network/monitor/HashMapTimestampMonitor.java b/src/org/kne/cloud/network/monitor/HashMapTimestampMonitor.java index b46adca..b786b03 100644 --- a/src/org/kne/cloud/network/monitor/HashMapTimestampMonitor.java +++ b/src/org/kne/cloud/network/monitor/HashMapTimestampMonitor.java @@ -1,14 +1,9 @@ package org.kne.cloud.network.monitor; -import java.math.BigInteger; -import java.util.List; -import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAdder; -import java.util.stream.Collectors; import org.kne.cloud.clock.HighAccuracyClock; import org.kne.cloud.network.klalb.KLALBUtils; @@ -65,27 +60,31 @@ private String name; - public boolean recordPacket(K key, int length) { - return recordPacket(key,clock.getCurrentTimeNanos(),length); + public boolean recordPacket(K key, int count,int length) { + return recordPacket(key,clock.getCurrentTimeNanos(),count,length); } + + + @Override - public boolean recordPacket(K key, Long128 timestamp, int length) { - return recordPacket(key, timestamp, length, Long.MAX_VALUE/1024); + public boolean recordPacket(K key, Long128 timestamp, int count,int length) { + return recordPacket(key, timestamp,count, length, Long.MAX_VALUE/1024); } @Override - public boolean recordPacket(K key, int length, long delay) { - return recordPacket(key,clock.getCurrentTimeNanos(),length,delay); + public boolean recordPacket(K key,int count, int length, long delay) { + return recordPacket(key,clock.getCurrentTimeNanos(),count,length,delay); } + /** * 超高性能记录数据包 - 针对路由器优化 */ - public boolean recordPacket(K key, Long128 timestamp, int length, long delay) { + public boolean recordPacket(K key, Long128 timestamp,int count, int length, long delay) { autoCleanup(cleanupThreshold); // 快速路径:尝试sequence=0 TimestampMonitorKey monitorKey = new TimestampMonitorKey<>(key, 0); - TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey,timestamp, length,delay); + TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey,timestamp, count,length,delay); if (entries.putIfAbsent(monitorKey, monitorValue) == null) { totalDataSize.add(length); @@ -96,7 +95,7 @@ private String name; // 重试路径(极少执行) for (int sequence = 0; sequence < maxRetry; sequence++) { monitorKey = new TimestampMonitorKey<>(key, sequence); - monitorValue = new TimestampMonitorValue(monitorKey,timestamp, length); + monitorValue = new TimestampMonitorValue(monitorKey,timestamp,count, length); if (entries.putIfAbsent(monitorKey, monitorValue) == null) { totalDataSize.add(length); totalPackets.increment(); @@ -174,8 +173,9 @@ private String name; return entries.values().stream() .filter(value -> (value.getTimestamp() .compareTo( startTime )>=0)&& - (value.getTimestamp().compareTo( currentTime) <=0) ) - .count(); + (value.getTimestamp().compareTo( currentTime) <=0) ).mapToLong(TimestampMonitorValue::getCount) + .sum(); + // .count(); } public long calculateBandwidth(long timeWindowNs) { @@ -226,7 +226,7 @@ private String name; .collect( TrafficStats::new, (ts, value) -> { - ts.packetCount++; + ts.packetCount+=value.getCount(); ts.totalBytes += value.getLength(); if (ts.earliestTimestamp .equals(Long128.ZERO) || (value.getTimestamp() .compareTo( ts.earliestTimestamp)<0)) { ts.earliestTimestamp = value.getTimestamp(); @@ -277,7 +277,7 @@ private String name; Thread t=new Thread(()->{ long l=0; while(true) { - monitor.recordPacket(l++, 1000); + monitor.recordPacket(l++,1, 1000); } }); t.start(); diff --git a/src/org/kne/cloud/network/monitor/MonitorData.java b/src/org/kne/cloud/network/monitor/MonitorData.java index ee1f083..52ddaae 100644 --- a/src/org/kne/cloud/network/monitor/MonitorData.java +++ b/src/org/kne/cloud/network/monitor/MonitorData.java @@ -3,33 +3,12 @@ package org.kne.cloud.network.monitor; import java.util.function.Consumer; public interface MonitorData extends Cloneable { - public static final int DOWN=0; - public static final int UNSTABLE=1; - public static final int UP=2; public Consumer getChangeListener(); public void setChangeListener(Consumer changeListener); -public String getName(); -public void setName(String name); @Override public String toString(); -public int getState(); -public void setState(int state); - -public double getReliability(); - - public static String parseStateToString(int state) { - switch (state) { - case DOWN: - return "offline"; - case UNSTABLE: - return "unstable"; - case UP: - return "online"; - default: - throw new IllegalArgumentException("Unknown state:"+state); - } - } +public void update(); public Object clone() throws CloneNotSupportedException; } diff --git a/src/org/kne/cloud/network/monitor/MonitorDataImpl.java b/src/org/kne/cloud/network/monitor/MonitorDataImpl.java index 97c7741..2bfc368 100644 --- a/src/org/kne/cloud/network/monitor/MonitorDataImpl.java +++ b/src/org/kne/cloud/network/monitor/MonitorDataImpl.java @@ -1,45 +1,11 @@ package org.kne.cloud.network.monitor; -import java.util.Timer; -import java.util.TimerTask; import java.util.function.Consumer; -public class MonitorDataImpl implements MonitorData { - private String name; - - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - private static Timer timer=new Timer("Monitor Update Thread",true); - public MonitorDataImpl() { - timer.scheduleAtFixedRate(ptt, 0, 100); - } - public MonitorDataImpl(long period) { - timer.scheduleAtFixedRate(ptt, 0, period); - } -private TimerTask ptt=new TimerTask() { - - @Override - public void run() { +public abstract class MonitorDataImpl implements MonitorData { - reliability=(reliability*999+(state==UP?1:0))/1000; - } - }; - - @Override - protected void finalize() throws Throwable { - ptt.cancel(); - } - - - public static Timer getTimer() { - return timer; - } private ConsumerchangeListener; public Consumer getChangeListener() { @@ -48,42 +14,11 @@ private TimerTask ptt=new TimerTask() { public void setChangeListener(Consumer changeListener) { this.changeListener = changeListener; } - private volatile int state=0; - private double reliability=0.0; - public int getState() { - return state; - } - public void setState(int state) { - this.state = state; - } - private String getDsc() { - switch(state) { - case DOWN: - return "○离线"; - case UNSTABLE: - return "◐不稳定"; - case UP: - return "●在线"; - } - return null; - } + + -@Override - public String toString() { - StringBuilder sb=new StringBuilder(); - sb.append(name); - sb.append('\n'); - sb.append(getDsc()); - /*sb.append('\t'); - sb.append((int)(reliability*100)); - sb.append('%');*/ - return sb.toString(); - } -@Override -public double getReliability() { - return reliability; -} + @Override public Object clone() throws CloneNotSupportedException { return super.clone(); diff --git a/src/org/kne/cloud/network/monitor/SpeedAndTrafficAndDelayMonitorDataImpl.java b/src/org/kne/cloud/network/monitor/SpeedAndTrafficAndDelayMonitorDataImpl.java index ef0c017..19cfc4d 100644 --- a/src/org/kne/cloud/network/monitor/SpeedAndTrafficAndDelayMonitorDataImpl.java +++ b/src/org/kne/cloud/network/monitor/SpeedAndTrafficAndDelayMonitorDataImpl.java @@ -1,41 +1,49 @@ package org.kne.cloud.network.monitor; -import java.util.TimerTask; import java.util.UUID; import org.kne.cloud.clock.HighAccuracyClock; -import org.kne.cloud.network.ipv6.PacketID; import org.kne.cloud.network.klalb.KLALBUtils; public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonitorDataImpl implements SpeedAndTrafficMonitorData,DelayMonitorData{ private long timewindowmax=500000000L; + + private DelaySampler upSampler=new DelaySampler(); + private DelaySampler downSampler=new DelaySampler(); -private TimerTask pttxr=new TimerTask() { - - @Override - public void run() { - long idelay=getInDelay(); - if(inDelayMin==Long.MAX_VALUE||idelay<=inDelayMin) { - inDelayMin=idelay; - }else{ - inDelayMin=(inDelayMin*9999+idelay)/10000; - } - long odelay=getOutDelay(); - if(outDelayMin==Long.MAX_VALUE||odelay<=outDelayMin) { - outDelayMin=odelay; - }else{ - outDelayMin=(outDelayMin*9999+odelay)/10000; - } + long stime=System.nanoTime(); +@Override + public void update() { + super.update(); + upSampler.update(); + downSampler.update(); + if(upSampler.getSnapshotPacketCount()>0&&upSampler.getSnapshotTotalDelay()>0) { + getUploadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, upSampler.getAvgDelayNanos()); + } + if(downSampler.getSnapshotPacketCount()>0&&downSampler.getSnapshotTotalDelay()>0) { + getDownloadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, downSampler.getAvgDelayNanos()); + } + + long time=System.nanoTime(); + if(time-stime>timewindowmax) { + stime=time; + long idelay=getInDelay(); + if(inDelayMin==Long.MAX_VALUE||idelay<=inDelayMin) { + inDelayMin=idelay; + }else{ + inDelayMin=(inDelayMin*99+idelay)/100; + } + long odelay=getOutDelay(); + if(outDelayMin==Long.MAX_VALUE||odelay<=outDelayMin) { + outDelayMin=odelay; + }else{ + outDelayMin=(outDelayMin*99+odelay)/100; + } } - }; - { - getTimer().scheduleAtFixedRate(pttxr, timewindowmax/1000000, timewindowmax/1000000); - } - @Override - protected void finalize() throws Throwable { - pttxr.cancel(); } + + @Override public String toString() { @@ -62,6 +70,13 @@ private TimerTask pttxr=new TimerTask() { + public void recordUploadDelay(long delay) { + upSampler.recordDelay(delay); + } + + public void recordDownloadDelay(long delay) { + downSampler.recordDelay(delay); + } @Override diff --git a/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorDataImpl.java b/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorDataImpl.java index c8a49b2..0b5457f 100644 --- a/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorDataImpl.java +++ b/src/org/kne/cloud/network/monitor/SpeedAndTrafficMonitorDataImpl.java @@ -1,30 +1,27 @@ package org.kne.cloud.network.monitor; -import java.util.TimerTask; import java.util.UUID; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.LongAdder; import org.kne.cloud.clock.HighAccuracyClock; -import org.kne.cloud.network.ipv6.PacketID; import org.kne.cloud.network.klalb.KLALBUtils; public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements SpeedAndTrafficMonitorData { private TimestampMonitoruploadBandwidth; private TimestampMonitordownloadBandwidth; - private long timewindow=200000000L; - private long timewindowmax=200000000L; + private long timewindow=1000000000L; + private long timewindowmax=1000000000L; + private BandwidthSampler upSampler=new BandwidthSampler(); + private BandwidthSampler downSampler=new BandwidthSampler(); + - private static final long CALC_TIMEOUT=50000000; public SpeedAndTrafficMonitorDataImpl(HighAccuracyClock clock) { super(); this.clock=clock; - uploadBandwidth=new ArrayListTimestampMonitor(clock,"UploadMonitor", 100, 500000000L); - downloadBandwidth=new ArrayListTimestampMonitor(clock,"DownloadMonitor", 100, 500000000L); + uploadBandwidth=new ArrayListTimestampMonitor(clock,"UploadMonitor", 100, 5000000000L); + downloadBandwidth=new ArrayListTimestampMonitor(clock,"DownloadMonitor", 100, 5000000000L); - getTimer().scheduleAtFixedRate(pttx, timewindowmax/1000000, timewindowmax/1000000); } private HighAccuracyClock clock; @@ -42,7 +39,6 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S this.uploadBandwidth = uploadBandwidth; this.downloadBandwidth = downloadBandwidth; - getTimer().scheduleAtFixedRate(pttx, timewindowmax/1000000, timewindowmax/1000000); } @@ -70,9 +66,11 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S @Override public String toString() { - StringBuilder sb=new StringBuilder(super.toString()); - sb.append('\t'); - sb.append(KLALBUtils. convertIBUint(uploadBandwidth.getTotalDataSize())).append("\t").append(KLALBUtils.convertIBUint(downloadBandwidth.getTotalDataSize())).append("\t").append(KLALBUtils.convertIBUint(uploadBandwidth.calculateBandwidth(timewindow))).append("/s\t").append(KLALBUtils.convertIBUint(downloadBandwidth.calculateBandwidth(timewindow))).append("/s\t"); + StringBuilder sb=new StringBuilder(); + sb.append(KLALBUtils.convertIBUint(uploadBandwidth.calculateBandwidth(timewindow))).append("/s\t"); + sb.append(KLALBUtils.convertIBUint(downloadBandwidth.calculateBandwidth(timewindow))).append("/s\t"); + sb.append(KLALBUtils.convertUintDefalut(uploadBandwidth.calculatePacketRate(timewindow))).append("PPS\t"); + sb.append(KLALBUtils.convertUintDefalut(downloadBandwidth.calculatePacketRate(timewindow))).append("PPS\t"); /*if(getState()==OFFLINE) { sb.append((coolingTime-(System.currentTimeMillis()-mls))/1000L); @@ -89,24 +87,11 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S - - private volatile long outspeedTimeout=System.nanoTime(); public long getOutSpeed() { - long curr=System.nanoTime(); - if(curr-outspeedTimeout>CALC_TIMEOUT) { - outspeedTimeout=curr; - outSpeed=uploadBandwidth.calculateBandwidth(timewindow); - } - return outSpeed; + return uploadBandwidth.calculateBandwidth(timewindow); } - private volatile long inspeedTimeout=System.nanoTime(); public long getInSpeed() { - long curr=System.nanoTime(); - if(curr-inspeedTimeout>CALC_TIMEOUT) { - inspeedTimeout=curr; - inSpeed=downloadBandwidth.calculateBandwidth(timewindow); - } - return inSpeed; + return downloadBandwidth.calculateBandwidth(timewindow); } @@ -161,40 +146,49 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S return inPPSMax; } -private TimerTask pttx=new TimerTask() { - - @Override - public void run() { - long os=uploadBandwidth.calculateBandwidth(timewindowmax); - long is=downloadBandwidth.calculateBandwidth(timewindowmax); - long op=uploadBandwidth.calculatePacketRate(timewindowmax); - long ip=uploadBandwidth.calculatePacketRate(timewindowmax); - if(os>outSpeeedMax) { - outSpeeedMax=(outSpeeedMax+os)/2; - }else { - outSpeeedMax=(outSpeeedMax*999+os)/1000; - } - if(is>inSpeedMax) { - inSpeedMax=(inSpeedMax+is)/2; - }else { - inSpeedMax=(inSpeedMax*999+is)/1000; - } - if(op>outPPSMax) { - outPPSMax=(outPPSMax+op)/2; - }else { - outPPSMax=(outPPSMax*999+op)/1000; - } - if(ip>inPPSMax) { - inPPSMax=(inPPSMax+ip)/2; - }else { - inPPSMax=(inPPSMax*999+ip)/1000; - } - } - }; - + public void recordUploadPacket(int databytes) { + upSampler.recordPacket(databytes); + } + public void recordDownloadPacket(int databytes) { + downSampler.recordPacket(databytes); + } + + long stime=System.nanoTime(); @Override - protected void finalize() throws Throwable { - pttx.cancel(); + public void update() { + upSampler.update(); + downSampler.update(); + uploadBandwidth.recordPacket(KLALBUtils.createGlobalUUID(),(int)upSampler.getPacketCountSinceLastSnapshot() ,(int)upSampler.getByteCountSinceLastSnapshot()); + downloadBandwidth.recordPacket(KLALBUtils.createGlobalUUID(),(int)downSampler.getPacketCountSinceLastSnapshot() ,(int) downSampler.getByteCountSinceLastSnapshot()); + + long time=System.nanoTime(); + if(time-stime>timewindowmax) { + stime=time; + long os=uploadBandwidth.calculateBandwidth(timewindowmax); + long is=downloadBandwidth.calculateBandwidth(timewindowmax); + long op=uploadBandwidth.calculatePacketRate(timewindowmax); + long ip=uploadBandwidth.calculatePacketRate(timewindowmax); + if(os>outSpeeedMax) { + outSpeeedMax=(outSpeeedMax+os)/2; + }else { + outSpeeedMax=(outSpeeedMax*999+os)/1000; + } + if(is>inSpeedMax) { + inSpeedMax=(inSpeedMax+is)/2; + }else { + inSpeedMax=(inSpeedMax*999+is)/1000; + } + if(op>outPPSMax) { + outPPSMax=(outPPSMax+op)/2; + }else { + outPPSMax=(outPPSMax*999+op)/1000; + } + if(ip>inPPSMax) { + inPPSMax=(inPPSMax+ip)/2; + }else { + inPPSMax=(inPPSMax*999+ip)/1000; + } + } } } diff --git a/src/org/kne/cloud/network/monitor/TimestampMonitor.java b/src/org/kne/cloud/network/monitor/TimestampMonitor.java index 810861b..37a3a12 100644 --- a/src/org/kne/cloud/network/monitor/TimestampMonitor.java +++ b/src/org/kne/cloud/network/monitor/TimestampMonitor.java @@ -35,7 +35,7 @@ public interface TimestampMonitor { * @param length 数据包长度 * @return 是否记录成功 */ - boolean recordPacket(K key, int length); + boolean recordPacket(K key,int count, int length); /** * 记录数据包(使用指定时间戳) @@ -44,12 +44,12 @@ public interface TimestampMonitor { * @param length 数据包长度 * @return 是否记录成功 */ - boolean recordPacket(K key, Long128 timestamp, int length); + boolean recordPacket(K key, Long128 timestamp,int count, int length); - boolean recordPacket(K key, Long128 timestamp, int length, long dsndDelay); + boolean recordPacket(K key, Long128 timestamp, int count,int length, long dsndDelay); - boolean recordPacket(K key, int length, long dsndDelay); + boolean recordPacket(K key, int count,int length, long dsndDelay); // ==================== 清理维护方法 ==================== diff --git a/src/org/kne/cloud/network/monitor/TimestampMonitorValue.java b/src/org/kne/cloud/network/monitor/TimestampMonitorValue.java index 70df7a7..c9d06c4 100644 --- a/src/org/kne/cloud/network/monitor/TimestampMonitorValue.java +++ b/src/org/kne/cloud/network/monitor/TimestampMonitorValue.java @@ -1,20 +1,20 @@ package org.kne.cloud.network.monitor; -import java.math.BigInteger; - import org.kne.math.Long128; public class TimestampMonitorValue implements Comparable { private final Long128 timestamp; + private final int count; private final int length; private final TimestampMonitorKey key; private long delay; - public TimestampMonitorValue(TimestampMonitorKey key, Long128 timestamp, int length) { - this(key,timestamp,length,Long.MAX_VALUE/1024); + public TimestampMonitorValue(TimestampMonitorKey key, Long128 timestamp,int count, int length) { + this(key,timestamp,count,length,Long.MAX_VALUE/1024); } - public TimestampMonitorValue(TimestampMonitorKey key, Long128 timestamp, int length,long delay) { + public TimestampMonitorValue(TimestampMonitorKey key, Long128 timestamp,int count, int length,long delay) { this.key = key; this.timestamp = timestamp; + this.count=count; this.length = length; this.delay=delay; } @@ -57,7 +57,11 @@ public class TimestampMonitorValue implements Comparable } public Long128 getTimestamp() { return timestamp; } - public int getLength() { return length; } + + public int getCount() { + return count; + } + public int getLength() { return length; } public TimestampMonitorKey getKey() { return key; } diff --git a/src/org/kne/cloud/network/ntp/NTPContext.java b/src/org/kne/cloud/network/ntp/NTPContext.java index 5ea4a6e..4afac3d 100644 --- a/src/org/kne/cloud/network/ntp/NTPContext.java +++ b/src/org/kne/cloud/network/ntp/NTPContext.java @@ -3,8 +3,6 @@ package org.kne.cloud.network.ntp; import java.io.Closeable; import java.io.IOException; import java.math.BigDecimal; -import java.net.InetSocketAddress; -import java.security.Timestamp; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -16,13 +14,8 @@ import java.util.Map.Entry; import java.util.Set; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.ReentrantLock; -import org.fusesource.jansi.io.AnsiOutputStream.ZeroWidthSupplier; import org.kne.cloud.clock.HighAccuracyClock; import org.kne.cloud.clock.NTPTimestamps; import org.kne.cloud.network.MultipurposeSocketAddress; @@ -33,12 +26,12 @@ import org.kne.math.Long128; public class NTPContext implements Closeable, AutoCloseable { private HighAccuracyClock clock; private static final boolean debug = false; - private static final int REQUEST_COUNT = 10; + private static final int REQUEST_COUNT = 5; private Long128 systemFrequencyOffset = NTPTimestamps.nanosToNtp128BitTimeInterval(new Long128(5000)); private Long128 localPrecision = NTPTimestamps.nanosToNtp128BitTimeInterval(new Long128(1000)); private static final Long128 adjustThreshold0 = Long128.valueOf(1000000000L); - private static final Long128 adjustThreshold1 = Long128.valueOf(2000000L); + private static final Long128 adjustThreshold1 = Long128.valueOf(100000000L); private AtomicBoolean firstSync=new AtomicBoolean(true); private int minStratum = 16; @@ -74,7 +67,7 @@ public class NTPContext implements Closeable, AutoCloseable { Thread.sleep(100); } - Thread.sleep(1000); + Thread.sleep(500); if (!mlp.isEmpty()) mergeAndApply(); @@ -222,9 +215,8 @@ public class NTPContext implements Closeable, AutoCloseable { selectAndApply(peerInfo); } - private AtomicLong prevAdjustTime = new AtomicLong(System.nanoTime()); - private volatile Long128 deltaRemaining; private long avgAdj=0; + private Long128 inte=new Long128(0); private void selectAndApply(List peerInfo) { Collections.sort(peerInfo); if(debug) @@ -240,31 +232,34 @@ public class NTPContext implements Closeable, AutoCloseable { Long128 adjt = pi.getAdj(); bi = bi.add(adjt); } - Long128 adj = bi.divide(Long128.valueOf(i)); - avgAdj=(avgAdj*7+adj.abs().longValue())/8; - Long128 adjustment; - Long128 adjabs=adj.abs(); - if (adjabs.compareTo(adjustThreshold0) > 0&&firstSync.compareAndSet(true, false)) { - adjustment=adj; - }else if (adjabs.compareTo(adjustThreshold1) > 0) { - adjustment = Long128.valueOf(new BigDecimal(adj.toBigInteger()).multiply(BigDecimal.valueOf(0.5)).toBigInteger()); + Long128 delta = bi.divide(Long128.valueOf(i)); + avgAdj=(avgAdj*7+delta.abs().longValue())/8; + Long128 deltaabs=delta.abs(); + if (deltaabs.compareTo(adjustThreshold0) > 0&&firstSync.compareAndSet(true, false)) { + Long128 adjustment=delta; + clock.adjustClock( adjustment); + if(debug) + System.out.println("adj:"+delta); + }else if (deltaabs.compareTo(adjustThreshold1) > 0) { + Long128 adjustment = Long128.valueOf(new BigDecimal(delta.toBigInteger()).multiply(BigDecimal.valueOf(0.5)).toBigInteger()); + clock.adjustClock( adjustment); + if(debug) + System.out.println("adj:"+delta); } else { - adjustment = Long128.valueOf(new BigDecimal(adj.toBigInteger()).multiply(BigDecimal.valueOf(0.0625/2)).toBigInteger()); - if (deltaRemaining != null) { - long curr = System.nanoTime(); - long old = prevAdjustTime.getAndSet(curr); - Long128 fadj = adjustment.multiply(Long128.valueOf(TimeUnit.SECONDS.toNanos(1))) - .divide(Long128.valueOf(curr - old)); - Long128 fadjustment = Long128.valueOf( new BigDecimal(fadj.toBigInteger()).multiply(BigDecimal.valueOf(0.015625/4)).toBigInteger()); - clock.adjustFrequency(fadjustment.longValue()); + Long128 fadj = delta.divide(20).add(inte.divide(200)); + clock.setFrequency(1000000000L+fadj.longValue()); + inte=inte.add(delta); + if(inte.compareTo(Long128.valueOf(5000000))>0) { + inte=Long128.valueOf(5000000); + }else if(inte.compareTo(Long128.valueOf(-5000000))<0) { + inte=Long128.valueOf(-5000000); + } if(debug) - System.out.println("fadj:" + fadjustment + " f:" + clock.getFrequency()); - } - deltaRemaining = adj.subtract(adjustment); + System.out.println("inte:"+inte+" fadj:" + fadj); + } - clock.adjustClock( adjustment); if(debug) - System.out.println("delta:" + adjustment + " deltaRemaining:" + deltaRemaining); + System.out.println("delta:"+delta); } } diff --git a/src/org/kne/cloud/network/ntp/NTPv4Protocol.java b/src/org/kne/cloud/network/ntp/NTPv4Protocol.java index f7db548..a27d895 100644 --- a/src/org/kne/cloud/network/ntp/NTPv4Protocol.java +++ b/src/org/kne/cloud/network/ntp/NTPv4Protocol.java @@ -2,7 +2,6 @@ package org.kne.cloud.network.ntp; import java.io.Closeable; import java.io.IOException; -import java.math.BigInteger; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; @@ -14,10 +13,8 @@ import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; @@ -30,7 +27,7 @@ import org.kne.math.Long128; public class NTPv4Protocol implements Closeable, AutoCloseable { private static final boolean showPacket = false; public static final int NTP_DEFAULT_PORT = 123; - private static final long DEFAULT_POLL_INTERVAL = 2000000000L; + private static final long DEFAULT_POLL_INTERVAL = 1000000000L; private static final long REQUEST_TIMEOUT = 10000000000L; private static final long EPHEMERAL_TIMEOUT = 60000000000L; diff --git a/src/org/kne/cloud/network/perf/Kperf.java b/src/org/kne/cloud/network/perf/Kperf.java index 3ae42e9..ae2f604 100644 --- a/src/org/kne/cloud/network/perf/Kperf.java +++ b/src/org/kne/cloud/network/perf/Kperf.java @@ -1,39 +1,23 @@ 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.clock.HighAccuracyClock; 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.PacketID; -import org.kne.cloud.network.ipv6.PacketIDGenerator; -import org.kne.cloud.network.ipv6.IPv6AddressGroup; -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.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.LinkStatus; import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; - -import com.github.f4b6a3.uuid.UuidCreator; +import org.kne.concurrent.ThreadParker; public class Kperf implements Runnable{ @@ -52,11 +36,13 @@ public class Kperf implements Runnable{ private MultipurposeSocketAddress bindAddress; private volatile boolean connected=false; private volatile KLALBPacketLink link; + + private LinkStatus status=new LinkStatus(); private SpeedAndTrafficAndDelayMonitorDataImpl monitor=new SpeedAndTrafficAndDelayMonitorDataImpl(HighAccuracyClock.SYSTEM_CLOCK); private volatile boolean closed = false; - private volatile Thread tlock; + private volatile ThreadParker tlock=new ThreadParker(); public Kperf(MultipurposeSocketAddress targetAddress,MultipurposeSocketAddress bindAddress) { Objects.requireNonNull(targetAddress); this.targetAddress=targetAddress; @@ -90,9 +76,6 @@ public class Kperf implements Runnable{ private SpeedLimiter test = new SpeedLimiter(MIN_SPEED,10000000L); private static long MIN_SPEED=64*1024L; - private SpeedLimiter congress = new SpeedLimiter(10000000L); - private long congressSpeed = 0; - private double loadPercent = 1.01; @@ -101,10 +84,46 @@ public class Kperf implements Runnable{ private long starttime=System.nanoTime(); long totaltime=1000; long usedtime=0; + + + private MonitorUpdater monitorUpdater; + private class MonitorUpdater implements Runnable{ + @Override + public void run() { + while (!closed) { + status.updateReliability(); + monitor.update(); + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + } + + } + //kperf {KLALB_Stream}[2486:1:f189:7589:f1f7:6f5e:b2eb:1]:4564 //kperf {KLALB_Stream}[2486:1::8888]:4564 @Override + + + public void run() { + + Thread tcc = ThreadTool.makeVDaemonThreadIfSupport("测速控制线程", () -> { + long startTime=System.nanoTime(); + try { + System.out.println("time\tspd↑\tspd↓\tPPS↑\tPPS↓\tdelay↑\tdelay↓\tjitter↑\tjitter↓"); + while(!closed) { + System.out.printf("%.2fs\t%s\n", (System.nanoTime()- startTime)/1000000000.0,monitor.toString()); + Thread.sleep(1000); + } + } catch (InterruptedException e) { + } + }); Thread tc = ThreadTool.makeVDaemonThreadIfSupport("测速控制线程", () -> { final int wtimes=5; totaltime=(20*1000*1+20*1000*4+wtimes*1000*5)*1000000L; @@ -113,12 +132,10 @@ public class Kperf implements Runnable{ try { long startTime; - System.out.println("测试1/5:延迟测试"); + System.out.println("测试1/3:延迟测试"); test.setLimitspeed(0); startTime=System.nanoTime(); for (int i = 0; i < 20; 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); updateUsedTime(); } @@ -133,131 +150,39 @@ public class Kperf implements Runnable{ startTime=System.nanoTime(); - if(targetAddress!=null) { - System.out.println("测试2/5:下载带宽测试"); - test.setLimitspeed(0); - testPacket=new TESTNPacket(60000); - for (int i = 0; i < 20; i++) { - System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); - System.out.printf("下载带宽:%s/s\n", KLALBUtils.convertIBUint(monitor.getInSpeed())); + + System.out.println("测试2/3:带宽测试"); + test.setLimitspeed(1000L*1024L*1024L*1024L); + testPacket=new TESTNPacket(65535); + for (int i = 0; i < 60; i++) { Thread.sleep(1000); } - System.out.printf("下载带宽:%s/s",KLALBUtils.convertIBUint(monitor.getInSpeed())); + System.out.printf("上传带宽:%s/s\t",KLALBUtils.convertIBUint(monitor.getOutSpeed())); + System.out.printf("下载带宽:%s/s\n",KLALBUtils.convertIBUint(monitor.getInSpeed())); if(reports!=null) { reports.downloadSpeedFinish(monitor.getInSpeed()); - } - }else { - System.out.println("测试2/5:上传带宽测试"); - test.setLimitspeed(1000L*1024L*1024L*1024L); - testPacket=new TESTNPacket(60000); - for (int i = 0; i < 20; i++) { - System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); - System.out.printf("上传带宽:%s/s\n", KLALBUtils.convertIBUint(monitor.getOutSpeed())); - Thread.sleep(1000); - } - System.out.printf("上传带宽:%s/s\n",KLALBUtils.convertIBUint(monitor.getOutSpeed())); - if(reports!=null) { - reports.uploadSpeedFinish(monitor.getOutSpeed()); - } - } - System.out.println("等待时间"+wtimes+"s"); - Thread.sleep(wtimes*1000); - - - - startTime=System.nanoTime(); - if(targetAddress!=null) { - System.out.println("测试3/5:上传带宽测试"); - test.setLimitspeed(1000L*1024L*1024L*1024L); - testPacket=new TESTNPacket(60000); - for (int i = 0; i < 20; i++) { - System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); - System.out.printf("上传带宽:%s/s\n", KLALBUtils.convertIBUint(monitor.getOutSpeed())); - Thread.sleep(1000); - } - System.out.printf("上传带宽:%s/s\n",KLALBUtils.convertIBUint(monitor.getOutSpeed())); - if(reports!=null) { reports.uploadSpeedFinish(monitor.getOutSpeed()); } - }else { - System.out.println("测试3/5:下载带宽测试"); - test.setLimitspeed(0); - testPacket=new TESTNPacket(60000); - for (int i = 0; i < 20; i++) { - System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); - System.out.printf("下载带宽:%s/s\n", KLALBUtils.convertIBUint(monitor.getInSpeed())); - Thread.sleep(1000); - } - System.out.printf("下载带宽:%s/s\n",KLALBUtils.convertIBUint(monitor.getInSpeed())); - if(reports!=null) { - reports.downloadSpeedFinish(monitor.getInSpeed()); - } - } - + System.out.println("等待时间"+wtimes+"s"); Thread.sleep(wtimes*1000); + startTime=System.nanoTime(); - if(targetAddress!=null) { - System.out.println("测试4/5:下载包转发率测试"); - test.setLimitspeed(0); - testPacket=new TEST1Packet(); - for (int i = 0; i < 20; i++) { - System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); - System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.convertUintDefalut(monitor.getInPPS())); - Thread.sleep(1000); - } - if(reports!=null) { - reports.downloadPPSFinish(monitor.getInPPS()); - } - }else { - System.out.println("测试4/5:上传包转发率测试"); - test.setLimitspeed(1000L*1024L*1024L*1024L); - testPacket=new TEST1Packet(); - for (int i = 0; i < 20; i++) { - System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); - System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.convertUintDefalut(monitor.getOutPPS())); - Thread.sleep(1000); - } - if(reports!=null) { - reports.uploadPPSFinish(monitor.getOutPPS()); - } - } - System.out.println("等待时间"+wtimes+"s"); - Thread.sleep(wtimes*1000); - - startTime=System.nanoTime(); - if(targetAddress!=null) { - System.out.println("测试5/5:上传包转发率测试"); + System.out.println("测试3/3:包转发率测试"); test.setLimitspeed(1000L*1024L*1024L*1024L); testPacket=new TEST1Packet(); for (int i = 0; i < 20; i++) { - System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); - System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.convertUintDefalut(monitor.getOutPPS())); Thread.sleep(1000); } - if(reports!=null) { reports.uploadPPSFinish(monitor.getOutPPS()); - } - }else { - System.out.println("测试5/5:下载包转发率测试"); - test.setLimitspeed(0); - testPacket=new TEST1Packet(); - for (int i = 0; i < 20; i++) { - System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); - System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.convertUintDefalut(monitor.getInPPS())); - Thread.sleep(1000); - } - if(reports!=null) { - reports.downloadPPSFinish(monitor.getInPPS()); - } - + reports.downloadPPSFinish(monitor.getInPPS()); } System.out.println("等待时间"+wtimes+"s"); Thread.sleep(wtimes*1000); - + } catch (InterruptedException e) { //System.out.println("测速被中断!"); @@ -269,7 +194,7 @@ public class Kperf implements Runnable{ } }); try { - monitor.setState(MonitorData.UNSTABLE); + status.setState(LinkStatus.UNSTABLE); if(link==null) link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,false,20000); @@ -278,18 +203,12 @@ public class Kperf implements Runnable{ 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.getOutSpeed(), monitor.getInSpeed())); - } if (checkPingTimeSleep()) { - writePacketToKPL(new PINGPacket(System.nanoTime(),monitor.getOutSpeed(), monitor.getInSpeed())); + writePacketToKPL(new PINGPacket(System.nanoTime(),0, 0)); }else { KLALBPacket kpip = IsendDequeList.poll(); @@ -305,12 +224,10 @@ public class Kperf implements Runnable{ }else { - LockSupport.parkNanos(1000000); + tlock.parkNanos(1000000); } } } - - Thread.yield(); } } catch (IOException | UnresolvedAddressException e) { if (debug) @@ -334,19 +251,20 @@ public class Kperf implements Runnable{ } switch (kpp.getType()) { case KLALBPacket.PING: - sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime(),monitor.getOutSpeed(), monitor.getInSpeed())); + sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime(),0, 0)); break; case KLALBPacket.PONG: if (fst) { // coll.resetCoolingTime(); - monitor.setState(MonitorData.UP); + status.setState(LinkStatus.UP); connected=true; if(targetAddress!=null) { System.out.println("连接地址"+targetAddress+"成功!"); }else { System.out.println("接受地址"+link.toString()+"连接成功!"); } + tcc.start(); tc.start(); fst = false; } @@ -383,41 +301,24 @@ public class Kperf implements Runnable{ adjnc.getLock().unlock(); } - if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) { - //pingInterval = monitor.getLatencyAvg()+2000000L; - - //double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay(); - loadPercent =Math.max( 1.2,0.4); - } - LockSupport.unpark(tlock); + tlock.unpark(); updateUsedTime() ; if(reports!=null) reports.updateDial(monitor); 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.TESTN: break; } - Thread.yield(); } } catch (IOException e) { - if(monitor.getState()==MonitorData.UNSTABLE) + if(status.getState()==LinkStatus.UNSTABLE) System.out.println("连接目标地址失败!"); if(debug) e.printStackTrace(); }finally { - monitor.setState(MonitorData.DOWN); + status.setState(LinkStatus.DOWN); if(link!=null) { try { link.close(); @@ -426,6 +327,7 @@ public class Kperf implements Runnable{ } } tc.interrupt(); + tcc.interrupt(); } } private void updateUsedTime() { @@ -485,7 +387,7 @@ public class Kperf implements Runnable{ public void close() { closed = true; - monitor.setState(MonitorData.DOWN); + status.setState(LinkStatus.DOWN); try { if (link != null) link.close(); @@ -503,7 +405,7 @@ public class Kperf implements Runnable{ private void sendIPacket(KLALBPacket blk) { IsendDequeList.add(blk); - LockSupport.unpark(tlock); + tlock.unpark(); } private KLALBPacket readPacketFromKPL() throws IOException { @@ -513,20 +415,19 @@ public class Kperf implements Runnable{ System.out.println("RX:" + packet); } if (packet != null) { - packet.putTimePassport("received"); long length=packet.getTotalLength(); - monitor.getDownloadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), (int)length); + //monitor.getDownloadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), (int)length); + monitor.recordDownloadPacket((int)length); } return packet; } private void writePacketToKPL(KLALBPacket packet) throws IOException { long length=packet.getTotalLength(); - monitor.getUploadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), (int)length); + //monitor.getUploadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), (int)length); + monitor.recordUploadPacket((int) length); link.writeKLALBPacket(packet); link.flush(); - packet.putTimePassport("sended"); - packet.printPassport(); if (showpacket) { System.err.println("TX:" + packet); @@ -535,6 +436,8 @@ public class Kperf implements Runnable{ public void startPerfing() { - ThreadTool.makeVThreadIfSupport("测速接收线程" ,this).start(); + monitorUpdater=new MonitorUpdater(); + ThreadTool.makeVDaemonThread("线路性能采样线程", monitorUpdater).start(); + ThreadTool.makeVDaemonThreadIfSupport("测速接收线程" ,this).start(); } } diff --git a/src/org/kne/cloud/network/perf/NodeBenchmark.java b/src/org/kne/cloud/network/perf/NodeBenchmark.java index 996e18e..aaf3cab 100644 --- a/src/org/kne/cloud/network/perf/NodeBenchmark.java +++ b/src/org/kne/cloud/network/perf/NodeBenchmark.java @@ -4,16 +4,14 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.ServerSocketChannel; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Random; import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.SocketChannelListener; import org.kne.cloud.network.ThreadTool; import org.kne.cloud.network.klalb.KLALBController; -import org.kne.cloud.network.klalb.KLALBRemoteLine; +import org.kne.cloud.network.klalb.KLALBRemoteLink; import org.kne.cloud.network.klalb.StreamChannelKLALBPacketLink; public class NodeBenchmark implements Runnable{ @@ -49,7 +47,7 @@ for (int i = 0; i < nodes; i++) { SocketChannelListener scl=new SocketChannelListener(ServerSocketChannel.open().bind(new InetSocketAddress("127.0.0.8",0))); scl.setCon((c)->{ try { - kct.addRemoteLine(new KLALBRemoteLine(klalbController,new StreamChannelKLALBPacketLink(c))); + kct.addRemoteLine(new KLALBRemoteLink(klalbController,new StreamChannelKLALBPacketLink(c))); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/org/kne/cloud/network/srv6/IPv6PacketConsumer.java b/src/org/kne/cloud/network/srv6/IPv6PacketConsumer.java new file mode 100644 index 0000000..86e815f --- /dev/null +++ b/src/org/kne/cloud/network/srv6/IPv6PacketConsumer.java @@ -0,0 +1,9 @@ +package org.kne.cloud.network.srv6; + +import java.io.IOException; + +import org.kne.cloud.network.ipv6.IPv6Packet; + +public interface IPv6PacketConsumer { + public void accept(IPv6Packet packx)throws IOException; +} diff --git a/src/org/kne/cloud/network/srv6/IpV6RoutingSRHData.java b/src/org/kne/cloud/network/srv6/IpV6RoutingSRHData.java deleted file mode 100644 index d195459..0000000 --- a/src/org/kne/cloud/network/srv6/IpV6RoutingSRHData.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.kne.cloud.network.srv6; - -import static org.pcap4j.util.ByteArrays.*; - -import java.net.Inet6Address; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.pcap4j.packet.IllegalRawDataException; -import org.pcap4j.packet.IpV6ExtRoutingPacket.IpV6RoutingData; -import org.pcap4j.util.ByteArrays; - - -public final class IpV6RoutingSRHData implements IpV6RoutingData { - - /** */ - private static final long serialVersionUID = -7972526977248222954L; - - private final int lastEntry; - private final int flags; - private final int tag; - private final List addresses; - private final List tlvs; - - /** - * A static factory method. This method validates the arguments by {@link - * ByteArrays#validateBounds(byte[], int, int)}, which may throw exceptions undocumented here. - * - * @param rawData rawData - * @param offset offset - * @param length length - * @return a new IpV6RoutingSourceRouteData object. - * @throws IllegalRawDataException if parsing the raw data fails. - */ - public static IpV6RoutingSRHData newInstance(byte[] rawData, int offset, int length) - throws IllegalRawDataException { - return new IpV6RoutingSRHData(rawData, offset, length); - } - - private IpV6RoutingSRHData(byte[] rawData, int offset, int length) - throws IllegalRawDataException { - - this.lastEntry = rawData[ offset]&0xff; - this.flags=rawData[offset+1]&0xff; - this.tag=ByteArrays.getShort(rawData, offset+2); - this.addresses = new ArrayList(); - this.tlvs=new ArrayList<>(); - - int endv=INT_SIZE_IN_BYTES+(lastEntry+1)*INET6_ADDRESS_SIZE_IN_BYTES; - for (int i = INT_SIZE_IN_BYTES; i < endv; i += INET6_ADDRESS_SIZE_IN_BYTES) { - addresses.add(ByteArrays.getInet6Address(rawData, i + offset)); - } - for(int itlv=endv;itlv getTlvs() { - return tlvs; -} - -public int getLastEntry() { - return lastEntry; -} - -public int getFlags() { - return flags; -} - -public int getTag() { - return tag; -} - -public List getAddresses() { - return addresses; -} - -public IpV6RoutingSRHData(List addresses) { - this(0,0,addresses,new ArrayList<>()); -} -public IpV6RoutingSRHData(List addresses,Listtlvs) { - this(0,0,addresses,tlvs); -} -/** - * @param reserved reserved - * @param addresses addresses - */ - public IpV6RoutingSRHData(int flags,int tag, List addresses,Listtlvs) { - if (addresses == null) { - throw new NullPointerException("addresses must not be null"); - } - this.lastEntry = addresses.size()-1; - this.flags=flags; - this.tag=tag; - this.addresses = new ArrayList(addresses); - this.tlvs=tlvs; - } - - - -@Override - public int length() { - int tlvsize=0; - for (int i = 0; i < tlvs.size(); i++) { - tlvsize+=tlvs.get(i).getTotalLength(); - } - return INT_SIZE_IN_BYTES+addresses.size() * INET6_ADDRESS_SIZE_IN_BYTES + tlvsize; - } - - @Override - public byte[] getRawData() { - byte[] rawData = new byte[length()]; - rawData[0]=(byte) lastEntry; - rawData[1]=(byte) flags; - rawData[2]=(byte) (tag>>8); - rawData[3]=(byte) tag; - ; - int i = INT_SIZE_IN_BYTES; - for ( Iterator iter = addresses.iterator(); iter.hasNext(); i += INET6_ADDRESS_SIZE_IN_BYTES) { - System.arraycopy( - ByteArrays.toByteArray(iter.next()), 0, rawData, i, INET6_ADDRESS_SIZE_IN_BYTES); - } - for (int j = 0; j < tlvs.size(); j++) { - SRv6TLV srt=tlvs.get(j); - switch(srt.getType()) { - case SRv6TLV.PAD1: - rawData[i++]=(byte) srt.getType(); - break; - case SRv6TLV.PADN: - rawData[i++]=(byte) srt.getType(); - int plth=srt.getLength(); - rawData[i++]=(byte) plth; - i+=plth; - break; - default: - rawData[i++]=(byte) srt.getType(); - int dlth=srt.getLength(); - rawData[i++]=(byte) dlth; - System.arraycopy(srt.getValue(), 0, rawData, i, dlth); - i+=dlth; - break; - } - } - return rawData; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("[lastentry: ").append(lastEntry).append("][flags: ").append(flags).append("][tag: ").append(tag).append("] [addresses:"); - for (Inet6Address addr : addresses) { - sb.append(" ").append(addr); - } - sb.append("]"); - return sb.toString(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!this.getClass().isInstance(obj)) { - return false; - } - - IpV6RoutingSRHData other = (IpV6RoutingSRHData) obj; - return lastEntry == other.lastEntry&&flags==other.flags&&tag==other.tag && addresses.equals(other.addresses); - } - - @Override - public int hashCode() { - int result = 17; - result = 31 * result + lastEntry; - result = 31 * result + flags; - result = 31 * result + tag; - result = 31 * result + addresses.hashCode(); - return result; - } -} diff --git a/src/org/kne/cloud/network/srv6/KLALBRoutingProtocol.java b/src/org/kne/cloud/network/srv6/KLALBRoutingProtocol.java index f5f032a..db71a24 100644 --- a/src/org/kne/cloud/network/srv6/KLALBRoutingProtocol.java +++ b/src/org/kne/cloud/network/srv6/KLALBRoutingProtocol.java @@ -2,22 +2,15 @@ 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; @@ -30,11 +23,10 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiConsumer; -import java.util.function.Consumer; -import org.kne.cloud.network.ByteBufferAllocator; import org.kne.cloud.network.ipv6.IPv6Address; import org.kne.cloud.network.ipv6.IPv6NetworkLink; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader; import org.kne.cloud.network.ipv6.IPv6AddressGroup; import org.kne.cloud.network.ipv6.Neighbor; import org.kne.cloud.network.klalb.KLALBVirtualRawSocket; @@ -43,10 +35,7 @@ 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; -import org.kne.cloud.network.te.BandwidthDistributer; - -import com.google.gson.internal.Pair; +import org.kne.membandboost.MembandBoost; public class KLALBRoutingProtocol extends Thread{ @@ -218,7 +207,7 @@ public class KLALBRoutingProtocol extends Thread{ while(true) { try { - byte[]ca=ByteBufferAllocator.allocateUninitializedArray(65535); + byte[]ca=MembandBoost.allocateUninitializedArray(65535); DatagramPacket dgp=new DatagramPacket(ca, ca.length); ds.receive(dgp); //System.out.println(Arrays.toString( Arrays.copyOf( dgp.getData(),dgp.getLength()))); @@ -609,7 +598,7 @@ public class KLALBRoutingProtocol extends Thread{ public Map> getPaths() { return paths; } - public List createSegmentList(IPv6Address dest) { + public IPv6SegmentRoutingHeader createSegmentList(IPv6Address dest) { NetmapDirections directionsx=directions; if(directionsx==null) { return null; @@ -618,14 +607,16 @@ public class KLALBRoutingProtocol extends Thread{ if(dn==null) { return null; } - Listsegments=new ArrayList<>(); + IPv6SegmentRoutingHeader segs=new IPv6SegmentRoutingHeader(); + Listsegments=segs.getAddresses(); while(true) { long idx=directionsx.getDirection()[(int) dn.longValue()]; if(idx==-1) { return null; } if(idx==dn) { - return segments; + segs. resetSegmentPos(); + return segs; } segments.add(directionsx.getDirection_rias().get(dn.intValue())); dn=idx; diff --git a/src/org/kne/cloud/network/srv6/KLALBRoutingProtocolAPIClient.java b/src/org/kne/cloud/network/srv6/KLALBRoutingProtocolAPIClient.java index f0f1e64..4b0df24 100644 --- a/src/org/kne/cloud/network/srv6/KLALBRoutingProtocolAPIClient.java +++ b/src/org/kne/cloud/network/srv6/KLALBRoutingProtocolAPIClient.java @@ -11,16 +11,14 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import org.kne.cloud.network.MultipurposeSocketAddress; -import org.kne.cloud.network.ThreadTool; -import org.kne.cloud.network.congestion.DCTCPCongestionAlgorithm; -import org.kne.cloud.network.congestion.EmptyCongestionAlgorithm; +import org.kne.cloud.network.congestion.NOCongestionAlgorithm; import org.kne.cloud.network.congestion.SendPacketSlidingWindow; import org.kne.opencl64.Releaser; public class KLALBRoutingProtocolAPIClient { private KLALBRoutingProtocol routingProtocol; private SendPacketSlidingWindow window = new SendPacketSlidingWindow( - new EmptyCongestionAlgorithm(3000000000L), 1024 * 1024); + new NOCongestionAlgorithm(3000000000L), 1024 * 1024); private static final Cleaner clr = Cleaner.create(); diff --git a/src/org/kne/cloud/network/srv6/PacketConsumer.java b/src/org/kne/cloud/network/srv6/PacketConsumer.java deleted file mode 100644 index 12055c4..0000000 --- a/src/org/kne/cloud/network/srv6/PacketConsumer.java +++ /dev/null @@ -1,10 +0,0 @@ -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 boolean accept(IPv6Packet packx)throws IOException; -} diff --git a/src/org/kne/cloud/network/srv6/PacketReorder.java b/src/org/kne/cloud/network/srv6/PacketReorder.java index 153d68b..fa89055 100644 --- a/src/org/kne/cloud/network/srv6/PacketReorder.java +++ b/src/org/kne/cloud/network/srv6/PacketReorder.java @@ -5,11 +5,8 @@ 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) { @@ -48,7 +45,7 @@ public class PacketReorder { } } - public void sortPackets(IPv6Packet pack,long seq, PacketConsumer packconsumer) throws IOException { + public void sortPackets(IPv6Packet pack,long seq, IPv6PacketConsumer packconsumer) throws IOException { rlock.lock(); try { //System.out.println("包序号:"+seq); diff --git a/src/org/kne/cloud/network/srv6/SRv6PacketReorder.java b/src/org/kne/cloud/network/srv6/SRv6PacketReorder.java index f2c1055..5d26d93 100644 --- a/src/org/kne/cloud/network/srv6/SRv6PacketReorder.java +++ b/src/org/kne/cloud/network/srv6/SRv6PacketReorder.java @@ -12,9 +12,9 @@ import org.kne.cloud.network.ipv6.IPv6Packet; public class SRv6PacketReorder { - private PacketConsumer packetConsumer; + private IPv6PacketConsumer packetConsumer; - public SRv6PacketReorder(PacketConsumer packetConsumer) { + public SRv6PacketReorder(IPv6PacketConsumer packetConsumer) { this.packetConsumer=packetConsumer; } diff --git a/src/org/kne/cloud/network/srv6/SRv6Router.java b/src/org/kne/cloud/network/srv6/SRv6Router.java index 43f070c..08daeec 100644 --- a/src/org/kne/cloud/network/srv6/SRv6Router.java +++ b/src/org/kne/cloud/network/srv6/SRv6Router.java @@ -11,32 +11,22 @@ import java.util.HashSet; 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 java.util.Timer; +import java.util.TimerTask; import java.util.UUID; -import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; -import javax.swing.plaf.synth.SynthOptionPaneUI; - +import org.jctools.counters.FixedSizeStripedLongCounter; import org.kne.cloud.clock.HighAccuracyClock; -import org.kne.cloud.network.ThreadTool; -import org.kne.cloud.network.congestion.ArrayListMessageBatcher; import org.kne.cloud.network.congestion.MessageBatcher; import org.kne.cloud.network.ipv6.ControlledIPv6NetworkLink; -import org.kne.cloud.network.ipv6.FlowSession; -import org.kne.cloud.network.ipv6.ICMPv6Packet; import org.kne.cloud.network.ipv6.ICMPv6PostcardPacket; import org.kne.cloud.network.ipv6.ICMPv6TimeExceededPacket; import org.kne.cloud.network.ipv6.IPv6Address; @@ -46,24 +36,20 @@ import org.kne.cloud.network.ipv6.IPv6NetworkLink; import org.kne.cloud.network.ipv6.IPv6Packet; import org.kne.cloud.network.ipv6.IPv6Packet.IPv6HopByHopHeader; import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader; -import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink; import org.kne.cloud.network.ipv6.IPv6AddressGroup; import org.kne.cloud.network.ipv6.KLALBOAMHopByHopTLV; import org.kne.cloud.network.ipv6.KLALBPassportHopByHopTLV; import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink; import org.kne.cloud.network.ipv6.Neighbor; -import org.kne.cloud.network.ipv6.PacketID; -import org.kne.cloud.network.ipv6.PacketIDGenerator; import org.kne.cloud.network.ipv6.PadNHopByHopTLV; import org.kne.cloud.network.ipv6.PostcardEntry; import org.kne.cloud.network.ipv6.RouteItem; -import org.kne.cloud.network.klalb.KLALBRemoteLine; +import org.kne.cloud.network.klalb.KLALBRemoteLink; import org.kne.cloud.network.klalb.KLALBUtils; -import org.kne.concurrent.HighPerformanceExecutor; +import org.kne.concurrent.HighPerformanceExecutor2; import org.kne.concurrent.TimeoutConcurrentHashMap; import org.pcap4j.packet.IllegalRawDataException; -import com.github.f4b6a3.uuid.UuidCreator; import com.google.gson.internal.Pair; // SRv6路由器主类,实现IPv6段路由功能 @@ -132,7 +118,6 @@ public class SRv6Router { public void accept(IPv6Packet t) { // HighPerformanceExecutor.defaultExecutor.execute(() -> { routePacket(null, t, true); // 执行重路由 - t.putTimePassport("rerouted"); // 标记重路由时间点 // }); } }; @@ -268,7 +253,7 @@ public class SRv6Router { // 预处理和排序路由项 for (Iterator iterator = routeTabel0x.iterator(); iterator.hasNext();) { RouteItem routeItem = (RouteItem) iterator.next(); - routeItem.preSort(); // 预排序 + routeItem.updateCost(); // 预排序 } Collections.sort(routeTabel0x); // 排序路由表 @@ -319,15 +304,11 @@ public class SRv6Router { // 插入SRH并路由数据包 public void insertSRHandRoutePacket(IPv6NetworkLink link, IPv6Packet ipp) { insertHopByHopHeader(ipp); - ipp.putTimePassport("Hop inserted"); insertSRHeader(ipp); // 插入段路由头 - ipp.putTimePassport("SRH inserted"); // 标记SRH插入时间点 routePacket(link, ipp); // 路由数据包 - ipp.putTimePassport("routed"); // 标记路由时间点 } - private PacketIDGenerator defaultGen = new PacketIDGenerator(); private static final PadNHopByHopTLV pad4 = new PadNHopByHopTLV(4); // 插入逐跳路由头 @@ -353,16 +334,15 @@ public class SRv6Router { } // 如果KLALB路由协议可用,创建段列表 if (klalbRouteProtol != null) { - List segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress()); + IPv6SegmentRoutingHeader segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress()); // System.out.println(segs); - if (segs != null && (!segs.isEmpty())) { + if (segs != null && (!segs.getAddresses().isEmpty())) { // 创建SRH头 - IPv6SegmentRoutingHeader irh = new IPv6SegmentRoutingHeader(segs); - ipp.getHeaders().add(irh); // 添加SRH头 - ipp.setRoutingHeader(irh); - ipp.setDestinationAddress(segs.get(segs.size() - 1)); // 更新目的地址为最后一个段 + ipp.getHeaders().add(segs); // 添加SRH头 + ipp.setRoutingHeader(segs); + ipp.setDestinationAddress(segs.getAddresses().get(segs.getAddresses().size() - 1)); // 更新目的地址为最后一个段 return true; } @@ -401,8 +381,9 @@ public class SRv6Router { int hop = iPv6Packet.getHopLimit(); // 获取跳数限制 if (hop > 0) { // 检查TTL值,只有大于0才会被转发 // 搜索匹配的路由表项 - List searchResult = searchTable(iPv6Packet, reroute, dbg); - if (!searchResult.isEmpty()) { + IPv6Address dest=iPv6Packet.getDestinationAddress(); + List searchResult = getTabelByAddress(dest); + if (searchResult!=null&&(!searchResult.isEmpty())) { // 匹配到路由表,执行负载均衡路由 routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult); return; @@ -421,15 +402,15 @@ public class SRv6Router { segmentsLeft--; } // 创建修复段列表 - List repairSegments = klalbRouteProtol + IPv6SegmentRoutingHeader repairSegments = klalbRouteProtol .createSegmentList(srh.getAddresses().get(segmentsLeft)); - if (repairSegments == null || repairSegments.isEmpty()) { + if (repairSegments == null ||repairSegments.getAddresses().isEmpty()) { System.out.println("FRR保护失败"); return; } - repairSegments.remove(0); // 移除第一个段(当前节点) - srh.getAddresses().addAll(segmentsLeft + 1, repairSegments); // 添加修复段 - segmentsLeft += repairSegments.size(); // 更新剩余段数 + repairSegments.getAddresses().remove(0); // 移除第一个段(当前节点) + srh.getAddresses().addAll(segmentsLeft + 1, repairSegments.getAddresses()); // 添加修复段 + segmentsLeft += repairSegments.getAddresses().size(); // 更新剩余段数 srh.setSegmentsLeft(segmentsLeft); iPv6Packet.setDestinationAddress(srh.getAddresses().get(segmentsLeft)); // 更新目的地址 } else { @@ -437,8 +418,8 @@ public class SRv6Router { } System.out.println("FRR修复SRH:" + srh); // 重新搜索路由表 - List searchResult2 = searchTable(iPv6Packet, reroute, dbg); - if (!searchResult2.isEmpty()) { + List searchResult2 = getTabelByAddress(dest); + if (searchResult2!=null&&(!searchResult2.isEmpty())) { routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult2); return; } @@ -457,7 +438,7 @@ public class SRv6Router { } // 搜索路由表找到匹配的路由项 - private List searchTable(IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg) + /*private List searchTable(IPv6Packet iPv6Packet, StringBuilder dbg) throws IllegalRawDataException, IOException { if (debug) { dbg.append("----------------------------------------\n"); @@ -476,17 +457,7 @@ public class SRv6Router { // 遍历路由表,筛选可用路由 for (RouteItem tri : table) { - if (!tri.getDestlink().isUp()) { // 检查链路状态 - if (debug) { - dbg.append(tri + "\n"); - dbg.append("linkdown.\n"); - } - continue; // 跳过断开连接的链路 - } - if (debug) { - dbg.append(tri + "\n"); - dbg.append("matched.\n"); - } + // 检查ECMP(等价多路径)条件 if (prevr != null) { if (!tri.ECMPequals(prevr)) { @@ -497,7 +468,7 @@ public class SRv6Router { prevr = tri; } return routes; - } + }*/ private List getTabelByAddress(IPv6Address rk6) { List table = null; @@ -519,35 +490,25 @@ public class SRv6Router { private boolean routingLoadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg, List routes) throws IllegalRawDataException, IOException { - double cscale = 1.0; // 拥塞检测比例因子 - if (iPv6Packet.getPayload().getProtocolNumber() == 6) { // TCP协议 - cscale = 15.0; // TCP使用更高的拥塞检测阈值 + if(routes==null||routes.isEmpty()) { + //System.out.println("Route not found:" + iPv6Packet); + return false; } - - if (iPv6Packet.getPreviousLink() != null) { - List prev = new ArrayList<>(); - for (Iterator iterator = routes.iterator(); iterator.hasNext();) { - RouteItem routeItem = (RouteItem) iterator.next(); - if (routeItem.getDestlink().equals(iPv6Packet.getPreviousLink())) { - prev.add(routeItem); - iterator.remove(); - } - } - routes.addAll(prev); - } - for (double i = 1; i < 10; i += 0.1) { - if (loadBalance(linkfrom, iPv6Packet, reroute, dbg, routes, cscale * i)) { + + for (double i = 1; i < 100; i += 0.1) { + if (loadBalance(linkfrom, iPv6Packet, reroute, dbg, routes, i)) { return true; } - if (iPv6Packet.isEnableECN()) { // 启用ECN iPv6Packet.markCE(); // 标记拥塞 if (debug) { dbg.append("ECN enabled.\n"); } - } + } - System.out.println("Send failed:" + iPv6Packet); + //System.out.println("Send failed:" + iPv6Packet); + LosscountAdder.inc(1); + if (debug) { dbg.append("miss.\n"); // 路由失败 } @@ -568,7 +529,7 @@ public class SRv6Router { continue; // 跳过断开链路 } if (link instanceof ControlledIPv6NetworkLink) { - if (((ControlledIPv6NetworkLink) link).isCongress(iPv6Packet, cscale)) { // 检查拥塞 + if (((ControlledIPv6NetworkLink) link).isCongestion(iPv6Packet, cscale)) { // 检查拥塞 if (debug) { dbg.append(tri + "\n"); dbg.append("congress.\n"); @@ -623,12 +584,6 @@ public class SRv6Router { if (iPv6Packet.getPayload() instanceof ICMPv6PostcardPacket && ri.getDestlink().isLoopBack()) { onPostcardReceive(iPv6Packet); } else { - IPv6NetworkLink oldLink = iPv6Packet.getPreviousLink(); - /* - * if(oldLink!=null) { - * System.out.println("重传:"+!oldLink.equals(ri.getDestlink())); } - */ - iPv6Packet.setPreviousLink(ri.getDestlink()); ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop()); } } @@ -642,8 +597,8 @@ public class SRv6Router { if (ris != null) { for (RouteItem ri : ris) { if (ri.getNexthop().equals(sid)) { - if (ri.getDestlink() instanceof KLALBRemoteLine) { - KLALBRemoteLine rem = (KLALBRemoteLine) ri.getDestlink(); + if (ri.getDestlink() instanceof KLALBRemoteLink) { + KLALBRemoteLink rem = (KLALBRemoteLink) ri.getDestlink(); rem.onPostcardReceive(postcard); } } @@ -683,9 +638,9 @@ public class SRv6Router { int sl = srhh.getSegmentsLeft(); // IPv6Address prevSID // =sl+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(sl+1); - if (linkfrom instanceof KLALBRemoteLine) { + if (linkfrom instanceof KLALBRemoteLink) { processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(), - ((KLALBRemoteLine) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader); + ((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader); } } // System.out.println(iPv6HopByHopHeader); @@ -698,9 +653,9 @@ public class SRv6Router { if (iPv6HopByHopHeader != null) { // IPv6Address prevSID // =oldSL+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(oldSL+1); - if (linkfrom instanceof KLALBRemoteLine) { + if (linkfrom instanceof KLALBRemoteLink) { processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(), - ((KLALBRemoteLine) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader); + ((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader); } } // 正常SRv6处理:移动到下一个段 @@ -762,8 +717,9 @@ public class SRv6Router { private void putPostcard(IPv6Address src, IPv6Address dst, IPv6Address srcSID, UUID uuid, long timeStamp, long delta, int packetLength) { + PostcardEntry pn = new PostcardEntry(srcSID, uuid, timeStamp, (int) (delta >> 4), packetLength); - Pair addressPair = new Pair(src, dst); + /*Pair addressPair = new Pair(src, dst); MessageBatcher batch = postcardBatch.computeIfAbsent(addressPair, (k) -> { MessageBatcher mb = new ArrayListMessageBatcher(30, 2000000L); mb.setConsumer((list) -> { @@ -786,13 +742,30 @@ public class SRv6Router { return mb; }); postcardBatch.refresh(addressPair); - batch.putMessage(pn); + batch.putMessage(pn);*/ + enqueuePacketSendTask(() -> { + IPv6Packet icmpv = new IPv6Packet(); + icmpv.setSourceAddress(src); + icmpv.setDestinationAddress(dst); + icmpv.setTrafficClass(0); + icmpv.setVersion(6); + icmpv.setFlowLabel(0); + icmpv.setHopLimit(255); // ICMP消息TTL设为最大值 + ICMPv6PostcardPacket ipl = new ICMPv6PostcardPacket(); + ipl.getPostcards().addAll(List.of(pn)); + ipl.setParent(icmpv); + ipl.updateChecksum(); + icmpv.setPayload(ipl); + return icmpv; + }); } - private static HighPerformanceExecutor defaultExecutor = new HighPerformanceExecutor( - Runtime.getRuntime().availableProcessors() + 1, Thread.ofPlatform().name("SRv6 Routing").factory());//Runtime.getRuntime().availableProcessors() + 1 + private static HighPerformanceExecutor2 defaultExecutor = new HighPerformanceExecutor2( + (int) (Runtime.getRuntime().availableProcessors()), Thread.ofVirtual().name("SRv6 Routing").factory()); + + //private static HighPerformanceExecutor2 defaultExecutor = new HighPerformanceExecutor2(4, Thread.ofVirtual().name("SRv6 Routing").factory()); - public static HighPerformanceExecutor getDefaultExecutor() { + public static HighPerformanceExecutor2 getDefaultExecutor() { return defaultExecutor; } @@ -802,38 +775,52 @@ public class SRv6Router { // packetQueue.add(object); defaultExecutor.executeWithCongestionReport((state) -> { try { + long start=System.nanoTime(); IPv6Packet packet=sendTask.get(); if(state) { - if(packet.isEnableECN()) { packet.markCE(); - //System.out.println("mce"); - } } insertSRHandRoutePacket(null, packet); // 插入SRH并路由 + long time=System.nanoTime()-start; + backplaneCount(time,state); } catch (Exception e) { e.printStackTrace(); } },20); } + public void runPacketSendTask(Supplier sendTask) { + try { + boolean state=false; + long start=System.nanoTime(); + IPv6Packet packet=sendTask.get(); + if(state) { + packet.markCE(); + } + insertSRHandRoutePacket(null, packet); // 插入SRH并路由 + long time=System.nanoTime()-start; + backplaneCount(time,state); + } catch (Exception e) { + e.printStackTrace(); + } + } public void onReceive(IPv6NetworkLink link,IPv6Packet t){ if (unduplicate(t)) { insertSRHandRoutePacket(link, t); // 插入SRH并路由数据包 - t.putTimePassport("routed"); // 标记路由时间点 } } public void enqueuePacketReceiveTask(IPv6NetworkLink link, Supplier pack) { defaultExecutor.executeWithCongestionReport((state) -> { try { + long start=System.nanoTime(); IPv6Packet packet = pack.get(); if(state) { - if(packet.isEnableECN()) { packet.markCE(); - //System.out.println("mce"); - } } onReceive(link ,packet); + long time=System.nanoTime()-start; + backplaneCount(time,state); } catch (Exception e) { e.printStackTrace(); } @@ -845,6 +832,67 @@ public class SRv6Router { return packet; }); } + + //private BandwidthSampler sampler=new BandwidthSampler(); + private FixedSizeStripedLongCounter timeAdder=KLALBUtils.createCounter(); + private FixedSizeStripedLongCounter countAdder=KLALBUtils.createCounter(); + private FixedSizeStripedLongCounter ECNcountAdder=KLALBUtils.createCounter(); + private FixedSizeStripedLongCounter LosscountAdder=KLALBUtils.createCounter(); + private void backplaneCount(long time,boolean ECN) { + timeAdder.inc(time); + countAdder.inc(1); + if(ECN) { + ECNcountAdder.inc(1); + } + } + private volatile long backplaneTime=0; + private volatile double ECNRate=0; + private volatile double LossRate=0; + private volatile long backplanePPS=0; + private volatile long backplanePPSMax=0; + private volatile long prevTime=System.nanoTime(); + + private Timer backplaneTimer=new Timer(); + private void updateBackplaneCounter() { + long curr=System.nanoTime(); + long totalTime=timeAdder.getAndReset(); + long totalCount=countAdder.getAndReset(); + long ECNCount=ECNcountAdder.getAndReset(); + long LossCount=LosscountAdder.getAndReset(); + if(totalCount!=0) { + backplaneTime=totalTime/totalCount; + ECNRate=((double)ECNCount)/totalCount; + LossRate=((double)LossCount)/totalCount; + } + backplanePPS=totalCount*1000000000L/(curr-prevTime); + if(backplanePPSMax neis = nl.getNeighborsInfo(); for (Iterator iteratorx = neis.iterator(); iteratorx.hasNext();) { Neighbor addresses = (Neighbor) iteratorx.next(); @@ -903,7 +958,7 @@ public class SRv6Router { return result; } - // 获取所有定位器 + // 获取所有SID public Set getLocators() { Set result = new HashSet<>(); List links = getLinkTabel(); @@ -915,10 +970,14 @@ public class SRv6Router { for (Iterator iteratorx = neis.iterator(); iteratorx.hasNext();) { Neighbor addresses = (Neighbor) iteratorx.next(); if (addresses.getLocator() != null) - result.add(addresses.getLocator()); // 添加邻居定位器 + result.add(addresses.getLocator()); // 添加邻居SID } } } return result; } + + + + } \ No newline at end of file diff --git a/src/org/kne/cloud/network/srv6/SlidingWindowInformation.java b/src/org/kne/cloud/network/srv6/SlidingWindowInformation.java index ae34e19..8c30d90 100644 --- a/src/org/kne/cloud/network/srv6/SlidingWindowInformation.java +++ b/src/org/kne/cloud/network/srv6/SlidingWindowInformation.java @@ -5,11 +5,8 @@ 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 SlidingWindowInformation { public SlidingWindowInformation(long sequenceNumber) { @@ -57,7 +54,7 @@ public class SlidingWindowInformation { + ", addtime=" + addtime + "]"; } } - public void sortPackets(IPv6Packet pack,long seq,int length, PacketConsumer packconsumer) throws IOException { + public void sortPackets(IPv6Packet pack,long seq,int length, IPv6PacketConsumer packconsumer) throws IOException { rlock.lock(); try { //System.out.println("包序号:"+seq+" 长度:"+length); diff --git a/src/org/kne/cloud/network/srv6/TCPTransimitAgent.java b/src/org/kne/cloud/network/srv6/TCPTransimitAgent.java index 03a8afa..6323df9 100644 --- a/src/org/kne/cloud/network/srv6/TCPTransimitAgent.java +++ b/src/org/kne/cloud/network/srv6/TCPTransimitAgent.java @@ -1,20 +1,14 @@ package org.kne.cloud.network.srv6; import java.io.IOException; -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.Set; import java.util.concurrent.ConcurrentHashMap; 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 TCPTransimitAgent { public TCPTransimitAgent() { @@ -57,7 +51,7 @@ public class TCPTransimitAgent { + ", addtime=" + addtime + "]"; } } - public boolean sortPackets(IPv6Packet pack,long seq,int length, PacketConsumer packconsumer) throws IOException { + public boolean sortPackets(IPv6Packet pack,long seq,int length, IPv6PacketConsumer packconsumer) throws IOException { if(length<=0) { packconsumer.accept(pack); return true; diff --git a/src/org/kne/cloud/network/tcp/TCPPacket.java b/src/org/kne/cloud/network/tcp/TCPPacket.java index 63f1132..f55cb55 100644 --- a/src/org/kne/cloud/network/tcp/TCPPacket.java +++ b/src/org/kne/cloud/network/tcp/TCPPacket.java @@ -9,9 +9,9 @@ import java.util.ArrayList; import java.util.List; import org.kne.cloud.network.NetworkPacket; -import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload; +import org.kne.cloud.network.ipv6.IPv6Packet.IPv6DefaultPayload; -public class TCPPacket extends IPv6Payload { +public class TCPPacket extends IPv6DefaultPayload { public static final int TCP_PROTOCOL_NUMBER = 6; // TCP头部常量 @@ -33,7 +33,7 @@ public class TCPPacket extends IPv6Payload { private List options = new ArrayList<>(); public TCPPacket() { - super(TCP_PROTOCOL_NUMBER, false); + super(TCP_PROTOCOL_NUMBER); // 设置默认数据偏移量(头部长度) setDataOffset(5); // 5 * 4 = 20字节 } diff --git a/src/org/kne/cloud/network/tcp/UDPPacket.java b/src/org/kne/cloud/network/tcp/UDPPacket.java index 1fb994f..3a1fb76 100644 --- a/src/org/kne/cloud/network/tcp/UDPPacket.java +++ b/src/org/kne/cloud/network/tcp/UDPPacket.java @@ -1,16 +1,12 @@ package org.kne.cloud.network.tcp; -import java.io.EOFException; import java.io.IOException; -import java.net.Inet6Address; -import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.util.Arrays; import org.kne.cloud.network.NetworkPacket; -import org.kne.cloud.network.ipv6.IPv6Packet; import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload; import org.kne.cloud.network.klalb.PortPacket; import org.kne.io.KNEChannels; @@ -23,11 +19,11 @@ public class UDPPacket extends IPv6Payload implements PortPacket { private ByteBuffer data; public UDPPacket() { - super(UDP_PROTOCOL_NUMBER, false); + super(UDP_PROTOCOL_NUMBER); } public UDPPacket(int srcPort,int dstPort) { - super(UDP_PROTOCOL_NUMBER, false); + super(UDP_PROTOCOL_NUMBER); header.putChar((char) srcPort); header.putChar((char) dstPort); data = NetworkPacket.bufferAllocator.allocate(65535); diff --git a/src/org/kne/cloud/network/te/DWRRLoadingBalanceAlgorithm.java b/src/org/kne/cloud/network/te/DWRRLoadingBalanceAlgorithm.java index 5efe748..a457d2d 100644 --- a/src/org/kne/cloud/network/te/DWRRLoadingBalanceAlgorithm.java +++ b/src/org/kne/cloud/network/te/DWRRLoadingBalanceAlgorithm.java @@ -1,11 +1,7 @@ package org.kne.cloud.network.te; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; -import java.util.Random; - -import org.kne.cloud.network.klalb.KLALBRemoteLine; public class DWRRLoadingBalanceAlgorithm> { private Listentries;