KLALB 3.6.0开发一半的状态
This commit is contained in:
+8
-6
@@ -1,12 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/graalvm-jdk-25.0.1+8.1">
|
|
||||||
<attributes>
|
|
||||||
<attribute name="module" value="true"/>
|
|
||||||
<attribute name="add-exports" value="java.base/jdk.internal.misc=ALL-UNNAMED:java.base/jdk.internal.foreign=ALL-UNNAMED"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="lib" path="lib/gson-2.1.jar"/>
|
<classpathentry kind="lib" path="lib/gson-2.1.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/javassist.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1686963856070/source/javassist-3.29.2-GA-sources.jar"/>
|
<classpathentry kind="lib" path="lib/javassist.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1686963856070/source/javassist-3.29.2-GA-sources.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/ini4j.jar"/>
|
<classpathentry kind="lib" path="lib/ini4j.jar"/>
|
||||||
@@ -27,5 +21,13 @@
|
|||||||
<classpathentry kind="lib" path="lib/KNEOptimize.jar"/>
|
<classpathentry kind="lib" path="lib/KNEOptimize.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/JavaTUN0.3.jar"/>
|
<classpathentry kind="lib" path="lib/JavaTUN0.3.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/uuid-creator-6.1.1.jar"/>
|
<classpathentry kind="lib" path="lib/uuid-creator-6.1.1.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/jctools-core-4.0.6.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/jctools-core-4.0.6-javadoc.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/jctools-core-4.0.6-sources.jar"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-26.0.1">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="module" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
+7
-6
@@ -1,7 +1,7 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"language": "ZH_CN",
|
"language": "ZH_CN",
|
||||||
"nogui": true,
|
"nogui": false,
|
||||||
"VirtualAddress": "2486:1:0:0:0:0:0:8888",
|
"VirtualAddress": "2486:1:0:0:0:0:0:8888",
|
||||||
"VirtualASN": 2142606939373348329,
|
"VirtualASN": 2142606939373348329,
|
||||||
"DNS": [
|
"DNS": [
|
||||||
@@ -37,13 +37,14 @@
|
|||||||
"{UDP}ntp.ntsc.ac.cn:123",
|
"{UDP}ntp.ntsc.ac.cn:123",
|
||||||
"{UDP}us.ntp.org.cn:123"
|
"{UDP}us.ntp.org.cn:123"
|
||||||
],
|
],
|
||||||
"denyLineTableQuery": false,
|
"denyLineTableQuery": true,
|
||||||
"denyLineTableBroadcast": false,
|
"denyLineTableBroadcast": true,
|
||||||
"congestionAlgorithm": "BBR",
|
"congestionAlgorithm": "BBR",
|
||||||
"delayUpperBound": 1.506,
|
"burstLimit": 1.5,
|
||||||
"delayLowerBound": 1.25,
|
"delayUpperBound": 1.3,
|
||||||
|
"delayLowerBound": 1.3,
|
||||||
"nagleDelayTime": 1000000,
|
"nagleDelayTime": 1000000,
|
||||||
"linkNagleDelayTime": 1000000,
|
"linkNagleDelayTime": 0,
|
||||||
"linkConnectionsCount": 1,
|
"linkConnectionsCount": 1,
|
||||||
"TUNName": "KLALB_SRv6",
|
"TUNName": "KLALB_SRv6",
|
||||||
"NetworkInterfaceExcepts": [],
|
"NetworkInterfaceExcepts": [],
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -55,7 +55,7 @@ delay=Delay
|
|||||||
virtualnetsettings=Virtual network settings
|
virtualnetsettings=Virtual network settings
|
||||||
tunnelnetsettings=Tunnel network settings
|
tunnelnetsettings=Tunnel network settings
|
||||||
linksettings=Link settings
|
linksettings=Link settings
|
||||||
klalbperf=KLALB-perf Speedtest tool
|
klalbperf=KLALB-perf Speedtest
|
||||||
speedtest=Network speed test
|
speedtest=Network speed test
|
||||||
starttest=Start test
|
starttest=Start test
|
||||||
testreport=Test report
|
testreport=Test report
|
||||||
@@ -91,5 +91,17 @@ tunname=Virtual network device name
|
|||||||
dashboard=Dashboard
|
dashboard=Dashboard
|
||||||
backplanedelay=Backplane delay
|
backplanedelay=Backplane delay
|
||||||
backplanepps=Backplane PPS
|
backplanepps=Backplane PPS
|
||||||
|
backplaneecnrate=Backplane ECN rate
|
||||||
|
backplanelossrate=Backplane Loss rate
|
||||||
uisettings=UI settings
|
uisettings=UI settings
|
||||||
nogui=No GUI mode
|
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
|
||||||
@@ -55,7 +55,7 @@ delay=延迟
|
|||||||
virtualnetsettings=虚拟网络设置
|
virtualnetsettings=虚拟网络设置
|
||||||
tunnelnetsettings=隧道网络设置
|
tunnelnetsettings=隧道网络设置
|
||||||
linksettings=链路设置
|
linksettings=链路设置
|
||||||
klalbperf=KLALB-perf测速工具
|
klalbperf=KLALB-perf网速测试
|
||||||
speedtest=网速测试
|
speedtest=网速测试
|
||||||
starttest=开始测试
|
starttest=开始测试
|
||||||
testreport=测速报告
|
testreport=测速报告
|
||||||
@@ -91,5 +91,17 @@ tunname=虚拟网卡名称
|
|||||||
dashboard=仪表盘
|
dashboard=仪表盘
|
||||||
backplanedelay=背板处理延迟
|
backplanedelay=背板处理延迟
|
||||||
backplanepps=背板包转发率
|
backplanepps=背板包转发率
|
||||||
|
backplaneecnrate=背板ECN率
|
||||||
|
backplanelossrate=背板丢包率
|
||||||
uisettings=UI设置
|
uisettings=UI设置
|
||||||
nogui=无GUI模式
|
nogui=无GUI模式
|
||||||
|
bufferusagemonitor=缓冲区监视器
|
||||||
|
buffer=缓冲区
|
||||||
|
usedbuffer=已用缓冲区
|
||||||
|
maxbuffer=最大缓冲区
|
||||||
|
queueused=已用队列
|
||||||
|
downloadbasedelay=下载延迟基线
|
||||||
|
uploadbasedelay=上传延迟基线
|
||||||
|
burstlimit=突发限制
|
||||||
|
performancesettings=性能设置
|
||||||
|
performancestrategy=性能策略
|
||||||
@@ -15,10 +15,8 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
private final ByteBuffer readBuffer;
|
private final ByteBuffer readBuffer;
|
||||||
private final ByteBuffer writeBuffer;
|
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 inputShutdown = new AtomicBoolean(false);
|
||||||
private final AtomicBoolean outputShutdown = new AtomicBoolean(false);
|
private final AtomicBoolean outputShutdown = new AtomicBoolean(false);
|
||||||
|
|
||||||
@@ -43,12 +41,11 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(ByteBuffer dst) throws IOException {
|
public int read(ByteBuffer dst) throws IOException {
|
||||||
if (closed.get() || inputShutdown.get()) {
|
if ( inputShutdown.get()) {
|
||||||
throw new ClosedChannelException();
|
throw new ClosedChannelException();
|
||||||
}
|
}
|
||||||
|
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
// 检查底层通道是否仍然打开
|
// 检查底层通道是否仍然打开
|
||||||
if (inputChannel != null && !inputChannel.isOpen()) {
|
if (inputChannel != null && !inputChannel.isOpen()) {
|
||||||
inputShutdown.set(true);
|
inputShutdown.set(true);
|
||||||
@@ -102,10 +99,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
}
|
}
|
||||||
|
|
||||||
return totalRead;
|
return totalRead;
|
||||||
|
|
||||||
} finally {
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,9 +120,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
||||||
if (closed.get() || inputShutdown.get()) {
|
|
||||||
throw new ClosedChannelException();
|
|
||||||
}
|
|
||||||
|
|
||||||
long totalRead = 0;
|
long totalRead = 0;
|
||||||
for (int i = offset; i < offset + length; i++) {
|
for (int i = offset; i < offset + length; i++) {
|
||||||
@@ -150,12 +142,9 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int write(ByteBuffer src) throws IOException {
|
public int write(ByteBuffer src) throws IOException {
|
||||||
if (closed.get() || outputShutdown.get()) {
|
|
||||||
throw new ClosedChannelException();
|
|
||||||
}
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// 检查底层通道是否仍然打开
|
// 检查底层通道是否仍然打开
|
||||||
if (outputChannel != null && !outputChannel.isOpen()) {
|
if (outputChannel != null && !outputChannel.isOpen()) {
|
||||||
outputShutdown.set(true);
|
outputShutdown.set(true);
|
||||||
@@ -188,9 +177,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
}
|
}
|
||||||
return totalWritten;
|
return totalWritten;
|
||||||
|
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -200,9 +187,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
||||||
if (closed.get() || outputShutdown.get()) {
|
|
||||||
throw new ClosedChannelException();
|
|
||||||
}
|
|
||||||
|
|
||||||
long totalWritten = 0;
|
long totalWritten = 0;
|
||||||
for (int i = offset; i < offset + length; i++) {
|
for (int i = offset; i < offset + length; i++) {
|
||||||
@@ -222,23 +207,18 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
* 安全的刷新方法
|
* 安全的刷新方法
|
||||||
*/
|
*/
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
if (closed.get()) {
|
|
||||||
throw new ClosedChannelException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outputChannel == null || outputShutdown.get()) {
|
if (outputChannel == null || outputShutdown.get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
try {
|
||||||
flushInternal();
|
flushInternal();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
outputShutdown.set(true);
|
outputShutdown.set(true);
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
}
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -274,16 +254,13 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (!closed.compareAndSet(false, true)) {
|
|
||||||
return; // 已经关闭
|
|
||||||
}
|
|
||||||
|
|
||||||
IOException exception = null;
|
IOException exception = null;
|
||||||
|
|
||||||
// 先刷新输出缓冲区
|
// 先刷新输出缓冲区
|
||||||
if (outputChannel != null && !outputShutdown.get()) {
|
if (outputChannel != null && !outputShutdown.get()) {
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
if (writeBuffer.position() > 0) {
|
if (writeBuffer.position() > 0) {
|
||||||
try {
|
try {
|
||||||
flushInternal();
|
flushInternal();
|
||||||
@@ -291,9 +268,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
exception = e;
|
exception = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭底层通道
|
// 关闭底层通道
|
||||||
@@ -322,20 +297,14 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 清理缓冲区状态
|
// 清理缓冲区状态
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
readBuffer.clear();
|
readBuffer.clear();
|
||||||
readBuffer.limit(0); // 标记为已清空
|
readBuffer.limit(0); // 标记为已清空
|
||||||
} finally {
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
writeBuffer.clear();
|
writeBuffer.clear();
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置关闭状态
|
// 设置关闭状态
|
||||||
inputShutdown.set(true);
|
inputShutdown.set(true);
|
||||||
@@ -351,13 +320,10 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
*/
|
*/
|
||||||
public void shutdownInput() throws IOException {
|
public void shutdownInput() throws IOException {
|
||||||
inputShutdown.set(true);
|
inputShutdown.set(true);
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
readBuffer.clear();
|
readBuffer.clear();
|
||||||
readBuffer.limit(0);
|
readBuffer.limit(0);
|
||||||
} finally {
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inputChannel instanceof SocketChannel) {
|
if (inputChannel instanceof SocketChannel) {
|
||||||
((SocketChannel) inputChannel).shutdownInput();
|
((SocketChannel) inputChannel).shutdownInput();
|
||||||
@@ -366,14 +332,11 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
|
|
||||||
public void shutdownOutput() throws IOException {
|
public void shutdownOutput() throws IOException {
|
||||||
outputShutdown.set(true);
|
outputShutdown.set(true);
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
if (writeBuffer.position() > 0) {
|
if (writeBuffer.position() > 0) {
|
||||||
flushInternal();
|
flushInternal();
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outputChannel instanceof SocketChannel) {
|
if (outputChannel instanceof SocketChannel) {
|
||||||
((SocketChannel) outputChannel).shutdownOutput();
|
((SocketChannel) outputChannel).shutdownOutput();
|
||||||
@@ -382,7 +345,7 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpen() {
|
public boolean isOpen() {
|
||||||
return !closed.get() &&
|
return
|
||||||
(inputChannel == null || inputChannel.isOpen()) &&
|
(inputChannel == null || inputChannel.isOpen()) &&
|
||||||
(outputChannel == null || outputChannel.isOpen());
|
(outputChannel == null || outputChannel.isOpen());
|
||||||
}
|
}
|
||||||
@@ -391,51 +354,39 @@ public class BufferedChannel implements ReadableByteChannel, WritableByteChannel
|
|||||||
* 检查是否还有可读数据(包括缓冲区中的)
|
* 检查是否还有可读数据(包括缓冲区中的)
|
||||||
*/
|
*/
|
||||||
public boolean hasRemaining() throws IOException {
|
public boolean hasRemaining() throws IOException {
|
||||||
if (closed.get() || inputShutdown.get()) {
|
if ( inputShutdown.get()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
return readBuffer.hasRemaining() ||
|
return readBuffer.hasRemaining() ||
|
||||||
(inputChannel != null && inputChannel.isOpen());
|
(inputChannel != null && inputChannel.isOpen());
|
||||||
} finally {
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取缓冲区状态信息(用于调试)
|
* 获取缓冲区状态信息(用于调试)
|
||||||
*/
|
*/
|
||||||
public String getBufferState() {
|
public String getBufferState() {
|
||||||
readLock.lock();
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
return String.format(
|
return String.format(
|
||||||
"ReadBuffer[pos=%d, lim=%d, cap=%d], WriteBuffer[pos=%d, lim=%d, cap=%d], " +
|
"ReadBuffer[pos=%d, lim=%d, cap=%d], WriteBuffer[pos=%d, lim=%d, cap=%d], " +
|
||||||
"closed=%b, inputShutdown=%b, outputShutdown=%b",
|
"closed=%b, inputShutdown=%b, outputShutdown=%b",
|
||||||
readBuffer.position(), readBuffer.limit(), readBuffer.capacity(),
|
readBuffer.position(), readBuffer.limit(), readBuffer.capacity(),
|
||||||
writeBuffer.position(), writeBuffer.limit(), writeBuffer.capacity(),
|
writeBuffer.position(), writeBuffer.limit(), writeBuffer.capacity(), inputShutdown.get(), outputShutdown.get()
|
||||||
closed.get(), inputShutdown.get(), outputShutdown.get()
|
|
||||||
);
|
);
|
||||||
} finally {
|
|
||||||
writeLock.unlock();
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 其他方法保持不变...
|
// 其他方法保持不变...
|
||||||
public int available() throws IOException {
|
public int available() throws IOException {
|
||||||
if (closed.get() || inputShutdown.get()) {
|
if ( inputShutdown.get()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
return readBuffer.remaining();
|
return readBuffer.remaining();
|
||||||
} finally {
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long skip(long n) throws IOException {
|
public long skip(long n) throws IOException {
|
||||||
|
|||||||
@@ -1,26 +1,10 @@
|
|||||||
package org.kne.cloud.network;
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
import java.lang.foreign.Arena;
|
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.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 org.kne.membandboost.MembandBoost;
|
||||||
|
|
||||||
import jdk.internal.misc.Unsafe;
|
|
||||||
public class ByteBufferAllocator {
|
public class ByteBufferAllocator {
|
||||||
|
|
||||||
public ByteBufferAllocator(boolean isDirect) {
|
public ByteBufferAllocator(boolean isDirect) {
|
||||||
@@ -43,31 +27,8 @@ public class ByteBufferAllocator {
|
|||||||
throw new InternalError();
|
throw new InternalError();
|
||||||
return buf;
|
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) {
|
public static ByteBuffer allocateHeap(int capacity) {
|
||||||
/*if(capacity<=2048) {
|
/*if(capacity<=2048) {
|
||||||
return MembandBoost.allocateUninitializedHeapBufferBlocked(capacity);
|
return MembandBoost.allocateUninitializedHeapBufferBlocked(capacity);
|
||||||
@@ -75,10 +36,6 @@ public class ByteBufferAllocator {
|
|||||||
return MembandBoost.allocateUninitializedHeapBuffer(capacity);
|
return MembandBoost.allocateUninitializedHeapBuffer(capacity);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
public static ByteBuffer allocateHeap0(int capacity) {
|
|
||||||
return ByteBuffer.wrap((byte[])allocateUninitializedArray(capacity)) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,24 @@
|
|||||||
package org.kne.cloud.network;
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InterruptedIOException;
|
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
import java.net.DatagramSocket;
|
||||||
import java.net.DatagramSocketImpl;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.Flow.Subscriber;
|
|
||||||
import java.util.concurrent.locks.LockSupport;
|
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 class DatagramServerSocket implements java.io.Closeable{
|
||||||
public static final ByteArrayPool dataarraypool=new ByteArrayPool(100, 65535);
|
public static final ByteArrayPool dataarraypool=new ByteArrayPool(100, 65535);
|
||||||
|
|
||||||
@@ -93,10 +83,7 @@ public class DatagramServerSocket implements java.io.Closeable{
|
|||||||
if (backlog < 1)
|
if (backlog < 1)
|
||||||
backlog = 50;
|
backlog = 50;
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager security = System.getSecurityManager();
|
|
||||||
if (security != null)
|
|
||||||
security.checkListen(epoint.getPort());
|
|
||||||
|
|
||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
if (closed)
|
if (closed)
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -15,16 +15,14 @@ import java.net.NetworkInterface;
|
|||||||
import java.net.NoRouteToHostException;
|
import java.net.NoRouteToHostException;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
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 static final boolean debug=false;
|
||||||
|
|
||||||
private MulticastSocket soc;
|
private MulticastSocket soc;
|
||||||
@@ -79,9 +77,7 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
|
|||||||
this.timeInterval=timeInterval;
|
this.timeInterval=timeInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void start() {
|
||||||
public void run() {
|
|
||||||
Thread.currentThread().setName("线路发现线程");
|
|
||||||
|
|
||||||
ThreadTool.makeVDaemonThreadIfSupport("线路通知线程", () -> {
|
ThreadTool.makeVDaemonThreadIfSupport("线路通知线程", () -> {
|
||||||
try {
|
try {
|
||||||
@@ -143,6 +139,7 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
|
|||||||
|
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
|
ThreadTool.makeVDaemonThreadIfSupport("线路发现线程",()->{
|
||||||
try {
|
try {
|
||||||
loop:while (!closed) {
|
loop:while (!closed) {
|
||||||
try {
|
try {
|
||||||
@@ -199,6 +196,7 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -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<MemorySegment>(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,53 +3,12 @@ package org.kne.cloud.network;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.nio.channels.WritableByteChannel;
|
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{
|
public abstract class NetworkPacket{
|
||||||
private static final boolean debugPassport=false;
|
|
||||||
|
|
||||||
public static final ByteBufferAllocator bufferAllocator=new ByteBufferAllocator(true);
|
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();
|
public abstract long getTotalLength();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class ProtocolDetectorServerSocket extends FilterServerSocket {
|
|||||||
public ProtocolDetectorSocket accept() throws IOException {
|
public ProtocolDetectorSocket accept() throws IOException {
|
||||||
ProtocolDetectorSocket s=(ProtocolDetectorSocket) super.accept();
|
ProtocolDetectorSocket s=(ProtocolDetectorSocket) super.accept();
|
||||||
int sot=s.getSoTimeout();
|
int sot=s.getSoTimeout();
|
||||||
s.setSoTimeout(1000);
|
s.setSoTimeout(200);
|
||||||
InputStream ins=s.getInputStream();
|
InputStream ins=s.getInputStream();
|
||||||
ProtocolStack psd= protocolDetector.detect(ins);
|
ProtocolStack psd= protocolDetector.detect(ins);
|
||||||
s.setSoTimeout(sot);
|
s.setSoTimeout(sot);
|
||||||
|
|||||||
@@ -2,17 +2,12 @@ package org.kne.cloud.network;
|
|||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.channels.ServerSocketChannel;
|
import java.nio.channels.ServerSocketChannel;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import javax.net.ServerSocketFactory;
|
|
||||||
|
|
||||||
public class SocketChannelListener implements Closeable,AutoCloseable{
|
public class SocketChannelListener implements Closeable,AutoCloseable{
|
||||||
protected ServerSocketChannel serverSocketChannel;
|
protected ServerSocketChannel serverSocketChannel;
|
||||||
public ServerSocketChannel getServerSocketChannel() {
|
public ServerSocketChannel getServerSocketChannel() {
|
||||||
@@ -28,7 +23,7 @@ public class SocketChannelListener implements Closeable,AutoCloseable{
|
|||||||
while(flag){
|
while(flag){
|
||||||
try {
|
try {
|
||||||
SocketChannel soce=serverSocketChannel.accept();
|
SocketChannel soce=serverSocketChannel.accept();
|
||||||
ThreadTool.makePThreadIfSupport("端口请求处理线程",()->{
|
ThreadTool.makeVThreadIfSupport("端口请求处理线程",()->{
|
||||||
if(con!=null) {
|
if(con!=null) {
|
||||||
try {
|
try {
|
||||||
con.accept(soce);
|
con.accept(soce);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class SocketListener implements Closeable,AutoCloseable{
|
|||||||
while(flag){
|
while(flag){
|
||||||
try {
|
try {
|
||||||
Socket soce=serverSocket.accept();
|
Socket soce=serverSocket.accept();
|
||||||
ThreadTool.makePThreadIfSupport("端口监听线程",()->{
|
ThreadTool.makeVThreadIfSupport("端口监听线程",()->{
|
||||||
if(con!=null) {
|
if(con!=null) {
|
||||||
try {
|
try {
|
||||||
con.accept(soce);
|
con.accept(soce);
|
||||||
@@ -66,7 +66,7 @@ public class SocketListener implements Closeable,AutoCloseable{
|
|||||||
protected void open() throws UnknownHostException, IOException {
|
protected void open() throws UnknownHostException, IOException {
|
||||||
if(serverSocket==null)
|
if(serverSocket==null)
|
||||||
serverSocket=multipurposeSocketAddress.listenServerSocket();
|
serverSocket=multipurposeSocketAddress.listenServerSocket();
|
||||||
new Thread(r).start();
|
ThreadTool.makeVThread("端口监听线程", r).start();
|
||||||
}
|
}
|
||||||
public void close() {
|
public void close() {
|
||||||
flag=false;
|
flag=false;
|
||||||
|
|||||||
@@ -2,13 +2,9 @@ package org.kne.cloud.network.congestion;
|
|||||||
import java.lang.ref.Cleaner;
|
import java.lang.ref.Cleaner;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.kne.cloud.network.ThreadTool;
|
import org.kne.cloud.network.ThreadTool;
|
||||||
@@ -78,11 +74,11 @@ public class ArrayListMessageBatcher<T> implements MessageBatcher<T>{
|
|||||||
impl.close();
|
impl.close();
|
||||||
}
|
}
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
for(;;){
|
/*for(;;){
|
||||||
ArrayListMessageBatcher<Integer>mes=new ArrayListMessageBatcher<>(10, 1000000L);
|
ArrayListMessageBatcher<Integer>mes=new ArrayListMessageBatcher<>(10, 1000000L);
|
||||||
System.gc();
|
System.gc();
|
||||||
}
|
}*/
|
||||||
/*ArrayListMessageBatcher<Integer>mes=new ArrayListMessageBatcher<>(10, 1000000L);
|
ArrayListMessageBatcher<Integer>mes=new ArrayListMessageBatcher<>(10, 1000000L);
|
||||||
mes.setConsumer((x)->{System.out.println(x);});
|
mes.setConsumer((x)->{System.out.println(x);});
|
||||||
int n=0;
|
int n=0;
|
||||||
for(;;){
|
for(;;){
|
||||||
@@ -91,7 +87,7 @@ public class ArrayListMessageBatcher<T> implements MessageBatcher<T>{
|
|||||||
mes.putMessage(n++);
|
mes.putMessage(n++);
|
||||||
mes.putMessage(n++);
|
mes.putMessage(n++);
|
||||||
Thread.sleep(1);
|
Thread.sleep(1);
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ArrayListMessageBatcherReleaser<T> extends Releaser<ArrayListMessageBatcher0<T>>{
|
class ArrayListMessageBatcherReleaser<T> extends Releaser<ArrayListMessageBatcher0<T>>{
|
||||||
@@ -114,18 +110,17 @@ class ArrayListMessageBatcherReleaser<T> extends Releaser<ArrayListMessageBatche
|
|||||||
private final long maxDelay;
|
private final long maxDelay;
|
||||||
private Consumer<List<T>> consumer;
|
private Consumer<List<T>> consumer;
|
||||||
private final Thread batchThread;
|
private final Thread batchThread;
|
||||||
private final AtomicBoolean closed;
|
private final AtomicBoolean closed = new AtomicBoolean(false);
|
||||||
private long firstTime;
|
private long firstTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造函数
|
* 构造函数
|
||||||
* @param batchSize 批量大小,当消息达到此数量时触发发送
|
* @param batchSize 批量大小,当消息达到此数量时触发发送
|
||||||
* @param maxDelayMillis 最大延迟时间(毫秒),即使消息数量不足也会触发发送
|
* @param maxDelay 最大延迟时间(毫秒),即使消息数量不足也会触发发送
|
||||||
*/
|
*/
|
||||||
public ArrayListMessageBatcher0(int batchSize, long maxDelay) {
|
public ArrayListMessageBatcher0(int batchSize, long maxDelay) {
|
||||||
this.batchSize = batchSize;
|
this.batchSize = batchSize;
|
||||||
this.maxDelay = maxDelay;
|
this.maxDelay = maxDelay;
|
||||||
this.closed = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
// 创建并启动批量处理线程
|
// 创建并启动批量处理线程
|
||||||
this.batchThread = ThreadTool.makeVDaemonThread("ArrayListMessageBatcher Thread", this );
|
this.batchThread = ThreadTool.makeVDaemonThread("ArrayListMessageBatcher Thread", this );
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package org.kne.cloud.network.congestion;
|
package org.kne.cloud.network.congestion;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetCongestionAlgorithm{
|
public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetCongestionAlgorithm{
|
||||||
@@ -12,9 +10,7 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges
|
|||||||
private static long MIN_WINDOW = 16384;
|
private static long MIN_WINDOW = 16384;
|
||||||
|
|
||||||
private Consumer<Long> windowControlConsumer;
|
private Consumer<Long> windowControlConsumer;
|
||||||
private BiConsumer<Long, Long> speedControlConsumer;
|
|
||||||
|
|
||||||
private AtomicBoolean firstUpdate = new AtomicBoolean(true);
|
|
||||||
private long MIN_RTTVAR = 5000000L;
|
private long MIN_RTTVAR = 5000000L;
|
||||||
private volatile long RTTMin = 1000000000L;
|
private volatile long RTTMin = 1000000000L;
|
||||||
private volatile long RTTVar = 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 window=MIN_WINDOW;
|
||||||
private volatile long speed=MIN_SPEED;
|
|
||||||
private volatile long maxwindow=99999999999L;
|
private volatile long maxwindow=99999999999L;
|
||||||
private long congressSpeed=MIN_SPEED;
|
private long congressSpeed=MIN_SPEED;
|
||||||
private double MIN_GAIN=1.05;
|
private double MIN_GAIN=1.05;
|
||||||
private double MAX_GAIN=1.20;//2.8853900817779
|
private double MAX_GAIN=1.20;//2.8853900817779
|
||||||
private double windowGain=MIN_GAIN;
|
private double windowGain=MIN_GAIN;
|
||||||
private double speedGain=MAX_GAIN;//1.20 MAX_GAIN
|
private double burstLimit=1.20;
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
window = MIN_WINDOW;
|
window = MIN_WINDOW;
|
||||||
if (windowControlConsumer != null) {
|
if (windowControlConsumer != null) {
|
||||||
windowControlConsumer.accept(window);
|
windowControlConsumer.accept(window);
|
||||||
}
|
}
|
||||||
speed = MIN_SPEED;
|
|
||||||
if (speedControlConsumer != null) {
|
|
||||||
speedControlConsumer.accept(speed, BURST_TIME);
|
|
||||||
}
|
|
||||||
windowGain=MAX_GAIN;
|
windowGain=MAX_GAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,10 +43,7 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges
|
|||||||
this.windowControlConsumer = windowControlConsumer;
|
this.windowControlConsumer = windowControlConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSpeedControlConsumer(BiConsumer<Long, Long> speedControlConsumer) {
|
|
||||||
this.speedControlConsumer = speedControlConsumer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private long RTTstartTime = System.nanoTime();
|
private long RTTstartTime = System.nanoTime();
|
||||||
private long bandwidth;
|
private long bandwidth;
|
||||||
@@ -65,14 +54,9 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges
|
|||||||
} else {
|
} else {
|
||||||
RTTMin = (RTTMin * 99999 + latencyns) / 100000;
|
RTTMin = (RTTMin * 99999 + latencyns) / 100000;
|
||||||
}
|
}
|
||||||
if (firstUpdate.compareAndSet(true, false)) {
|
RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4;
|
||||||
RTTAvg = latencyns;
|
RTTAvg = (RTTAvg * 7 + latencyns) / 8;
|
||||||
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
|
RTO = RTTAvg + Math.max(MIN_RTTVAR, RTTVar * 4);// RTTVar*4
|
||||||
|
|
||||||
RTTTotal += latencyns;
|
RTTTotal += latencyns;
|
||||||
@@ -100,14 +84,10 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges
|
|||||||
} else {
|
} else {
|
||||||
congressSpeed = (congressSpeed * 49 + bandwidth) / 50;
|
congressSpeed = (congressSpeed * 49 + bandwidth) / 50;
|
||||||
}
|
}
|
||||||
speed=(long) (congressSpeed * speedGain)+MIN_SPEED ;
|
|
||||||
window= ((long) (congressSpeed*windowGain )*(RTTMin+BIAS)/1000000000L)+MIN_WINDOW;
|
window= ((long) (congressSpeed*windowGain )*(RTTMin+BIAS)/1000000000L)+MIN_WINDOW;
|
||||||
if (windowControlConsumer != null) {
|
if (windowControlConsumer != null) {
|
||||||
windowControlConsumer.accept(window);
|
windowControlConsumer.accept(window);
|
||||||
}
|
}
|
||||||
if (speedControlConsumer != null) {
|
|
||||||
speedControlConsumer.accept(speed, BURST_TIME);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -124,6 +104,7 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCurrentWindowUsed(long used) {
|
public void setCurrentWindowUsed(long used) {
|
||||||
|
this.maxwindow = (long) (used*burstLimit) + MIN_WINDOW;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +119,6 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges
|
|||||||
@Override
|
@Override
|
||||||
public void setUpperDelayBound(double upper) {
|
public void setUpperDelayBound(double upper) {
|
||||||
MAX_GAIN=upper;
|
MAX_GAIN=upper;
|
||||||
speedGain=MAX_GAIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -146,5 +126,14 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges
|
|||||||
MIN_GAIN=lower;
|
MIN_GAIN=lower;
|
||||||
windowGain=MIN_GAIN;
|
windowGain=MIN_GAIN;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public void setBurstLimit(double limit) {
|
||||||
|
burstLimit=limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "BBR";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<Long> windowControlConsumer;
|
|
||||||
private BiConsumer<Long, Long> 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<Long> windowControlConsumer) {
|
|
||||||
this.windowControlConsumer = windowControlConsumer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSpeedControlConsumer(BiConsumer<Long, Long> 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<MIN_GAIN) {
|
|
||||||
gain=MIN_GAIN;
|
|
||||||
//System.out.println("window:"+window);
|
|
||||||
}
|
|
||||||
RTTstartTime=curr;
|
|
||||||
|
|
||||||
}
|
|
||||||
//System.out.println(speed+" "+window);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putLoss(long packetSize, long lossns, int losscounter) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getRTO() {
|
|
||||||
return RTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCurrentWindowUsed(long used) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCurrentBandwidth(long bandwidth) {
|
|
||||||
/*if (bandwidth >= 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,16 +1,18 @@
|
|||||||
package org.kne.cloud.network.congestion;
|
package org.kne.cloud.network.congestion;
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public interface CongestionAlgorithm {
|
public interface CongestionAlgorithm {
|
||||||
public void reset();
|
public void reset();
|
||||||
public void setWindowControlConsumer(Consumer<Long>windowControlConsumer);
|
public void setWindowControlConsumer(Consumer<Long>windowControlConsumer);
|
||||||
public void setSpeedControlConsumer(BiConsumer<Long,Long>speedControlConsumer);
|
public void putAck(long packetSize,long RTTns,boolean ecn);
|
||||||
public void putAck(long packetSize,long latencyns,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 putLoss(long packetSize,long lossns,int losscounter);
|
||||||
public void setCurrentWindowUsed(long maxwindow);
|
public void setCurrentWindowUsed(long maxwindow);
|
||||||
public void setCurrentBandwidth(long bandwidth);
|
public void setCurrentBandwidth(long bandwidth);
|
||||||
public long getRTO();
|
public long getRTO();
|
||||||
|
public String getName();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,33 @@
|
|||||||
package org.kne.cloud.network.congestion;
|
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 java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.jctools.counters.FixedSizeStripedLongCounter;
|
||||||
|
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||||
|
|
||||||
public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm {
|
public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm {
|
||||||
|
|
||||||
private static final long BURST_TIME = 1000000L;
|
private static final long BURST_TIME = 1000000L;
|
||||||
private static final long BIAS = 2000000L;
|
private static final long BIAS = 2000000L;
|
||||||
private static long MIN_SPEED = 64 * 1024L;
|
private static long MIN_WINDOW = 8192;
|
||||||
private static long MIN_WINDOW = 32768;
|
|
||||||
|
|
||||||
private Consumer<Long> windowControlConsumer;
|
private Consumer<Long> windowControlConsumer;
|
||||||
private BiConsumer<Long, Long> speedControlConsumer;
|
|
||||||
|
|
||||||
private AtomicBoolean firstUpdate = new AtomicBoolean(true);
|
private long MIN_RTTVAR = 100000000L;
|
||||||
private long MIN_RTTVAR = 400000000L;
|
|
||||||
private volatile long RTTMin = 1000000000L;
|
|
||||||
private volatile long RTTVar = 1000000000L;
|
private volatile long RTTVar = 1000000000L;
|
||||||
private volatile long RTTAvg = 1000000000L;
|
private volatile long RTTAvg = 1000000000L;
|
||||||
private double ECNAvg2 = 0L;
|
private double ECNAvg2 = 0L;
|
||||||
private double alpha=0;
|
private double alpha=0;
|
||||||
private volatile AtomicLong ECNSize = new AtomicLong(0);
|
private volatile FixedSizeStripedLongCounter ECNSize = KLALBUtils.createCounter();
|
||||||
private volatile AtomicLong TotalSize = new AtomicLong(0);
|
private volatile FixedSizeStripedLongCounter TotalSize = KLALBUtils.createCounter();
|
||||||
private volatile long RTO = 1000000000L;
|
private volatile long RTO = 500000000L;
|
||||||
|
|
||||||
|
|
||||||
private volatile long window=MIN_WINDOW;
|
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 congressWindowSize=MIN_WINDOW;
|
||||||
private volatile long speed=MIN_SPEED;
|
|
||||||
private long congressSpeed=MIN_SPEED;
|
|
||||||
|
|
||||||
private long RTTstartTime = System.nanoTime();
|
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
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
@@ -46,11 +35,6 @@ public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm {
|
|||||||
if (windowControlConsumer != null) {
|
if (windowControlConsumer != null) {
|
||||||
windowControlConsumer.accept(window);
|
windowControlConsumer.accept(window);
|
||||||
}
|
}
|
||||||
speed = MIN_SPEED;
|
|
||||||
if (speedControlConsumer != null) {
|
|
||||||
speedControlConsumer.accept(speed, BURST_TIME);
|
|
||||||
}
|
|
||||||
gain=MAX_GAIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,73 +42,44 @@ public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm {
|
|||||||
this.windowControlConsumer = windowControlConsumer;
|
this.windowControlConsumer = windowControlConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSpeedControlConsumer(BiConsumer<Long, Long> speedControlConsumer) {
|
|
||||||
this.speedControlConsumer = speedControlConsumer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void putAck(long packetSize, long latencyns, boolean ecn) {
|
public synchronized void putAck(long packetSize, long latencyns, boolean ecn) {
|
||||||
if (latencyns <= RTTMin) {
|
|
||||||
RTTMin = latencyns;
|
|
||||||
} else {
|
RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4;
|
||||||
RTTMin = (RTTMin * 99999 + latencyns) / 100000;
|
RTTAvg = (RTTAvg * 7 + latencyns) / 8;
|
||||||
}
|
|
||||||
if (firstUpdate.compareAndSet(true, false)) {
|
|
||||||
RTTAvg = latencyns;
|
|
||||||
RTTVar = latencyns / 2;
|
|
||||||
} else {
|
|
||||||
RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4;
|
|
||||||
RTTAvg = (RTTAvg * 7 + latencyns) / 8;
|
|
||||||
}
|
|
||||||
RTO = RTTAvg + Math.max(MIN_RTTVAR, RTTVar * 4);// RTTVar*4
|
RTO = RTTAvg + Math.max(MIN_RTTVAR, RTTVar * 4);// RTTVar*4
|
||||||
|
|
||||||
if(ecn) {
|
if(ecn) {
|
||||||
ECNSize.addAndGet(packetSize);
|
ECNSize.inc(packetSize);
|
||||||
}
|
}
|
||||||
TotalSize.addAndGet(packetSize);
|
TotalSize.inc(packetSize);
|
||||||
|
|
||||||
|
|
||||||
long curr=System.nanoTime();
|
long curr=System.nanoTime();
|
||||||
if(curr-RTTstartTime>(RTTAvg+BIAS)) {
|
if(curr-RTTstartTime>(RTTAvg+BIAS)) {
|
||||||
RTTstartTime=curr;
|
RTTstartTime=curr;
|
||||||
|
|
||||||
long totalSize=TotalSize.getAndSet(0);
|
long totalSize=TotalSize.getAndReset();
|
||||||
long ecnSize=ECNSize.getAndSet(0);
|
long ecnSize=ECNSize.getAndReset();
|
||||||
if(totalSize!=0) {
|
if(totalSize!=0) {
|
||||||
ECNAvg2=ecnSize/(double)totalSize;
|
ECNAvg2=ecnSize/(double)totalSize;
|
||||||
alpha=(alpha*15+ECNAvg2)/16;
|
alpha=(alpha*7+ECNAvg2)/8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ECNAvg2>0.5) {
|
if(ECNAvg2>0.5) {
|
||||||
gain=MIN_GAIN;
|
|
||||||
if(congressWindowSize>MIN_WINDOW) {
|
|
||||||
congressWindowSize-=200;
|
congressWindowSize-=200;
|
||||||
updateWindowSize();
|
}else if(ECNAvg2>0.01){
|
||||||
}
|
|
||||||
}else if(ECNAvg2>0.1){
|
|
||||||
if(windowUsed*3L>=congressWindowSize) {
|
|
||||||
congressWindowSize+=200;
|
congressWindowSize+=200;
|
||||||
updateWindowSize();
|
|
||||||
}
|
|
||||||
}else {
|
}else {
|
||||||
if(windowUsed*3L>=congressWindowSize) {
|
congressWindowSize+=4000;
|
||||||
congressWindowSize+=8000;
|
|
||||||
updateWindowSize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//System.out.println(ECNAvg2);
|
//System.out.println(ECNAvg2);
|
||||||
//System.out.println(speed+" "+window);
|
//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) {
|
updateWindowSize();
|
||||||
speedControlConsumer.accept(speed, BURST_TIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +87,11 @@ public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateWindowSize() {
|
private void updateWindowSize() {
|
||||||
|
if(congressWindowSize<MIN_WINDOW) {
|
||||||
|
congressWindowSize=MIN_WINDOW;
|
||||||
|
}else if(congressWindowSize>maxwindow) {
|
||||||
|
congressWindowSize=maxwindow;
|
||||||
|
}
|
||||||
window=Math.max( congressWindowSize,MIN_WINDOW);
|
window=Math.max( congressWindowSize,MIN_WINDOW);
|
||||||
if (windowControlConsumer != null) {
|
if (windowControlConsumer != null) {
|
||||||
windowControlConsumer.accept(window);
|
windowControlConsumer.accept(window);
|
||||||
@@ -150,12 +110,17 @@ public class DCTCP2CongestionAlgorithm implements CongestionAlgorithm {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCurrentWindowUsed(long used) {
|
public void setCurrentWindowUsed(long used) {
|
||||||
this.windowUsed=used;
|
this.maxwindow=(long) (used*1.5)+MIN_WINDOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCurrentBandwidth(long bandwidth) {
|
public void setCurrentBandwidth(long bandwidth) {
|
||||||
this.bandwidth=bandwidth;
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DCTCP2";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package org.kne.cloud.network.congestion;
|
|||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class DCTCPCongestionAlgorithm implements CongestionAlgorithm {
|
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 BURST_TIME = 1000000L;
|
||||||
private static final long BIAS = 2000000L;
|
private static final long BIAS = 2000000L;
|
||||||
private static long MIN_SPEED = 64 * 1024L;
|
private static long MIN_SPEED = 64 * 1024L;
|
||||||
private static long MIN_WINDOW = 32768;
|
private static long MIN_WINDOW = 8192;
|
||||||
|
|
||||||
private Consumer<Long> windowControlConsumer;
|
private Consumer<Long> windowControlConsumer;
|
||||||
private BiConsumer<Long, Long> speedControlConsumer;
|
|
||||||
|
|
||||||
private AtomicBoolean firstUpdate = new AtomicBoolean(true);
|
private AtomicBoolean firstUpdate = new AtomicBoolean(true);
|
||||||
private long MIN_RTTVAR = 400000000L;
|
private long MIN_RTTVAR = 100000000L;
|
||||||
private volatile long RTTMin = 1000000000L;
|
private volatile long RTTMin = 1000000000L;
|
||||||
private volatile long RTTVar = 1000000000L;
|
private volatile long RTTVar = 1000000000L;
|
||||||
private volatile long RTTAvg = 1000000000L;
|
private volatile long RTTAvg = 1000000000L;
|
||||||
@@ -31,14 +28,10 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm {
|
|||||||
private volatile long window=MIN_WINDOW;
|
private volatile long window=MIN_WINDOW;
|
||||||
private volatile long windowUsed=MIN_WINDOW;
|
private volatile long windowUsed=MIN_WINDOW;
|
||||||
private volatile long congressWindowSize=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 RTTstartTime = System.nanoTime();
|
||||||
private long bandwidth=MIN_SPEED;
|
|
||||||
private double MAX_GAIN=2.8853900817779;//2.8853900817779
|
private double MAX_GAIN=2.8853900817779;//2.8853900817779
|
||||||
private double MIN_GAIN=1.2;
|
private double MIN_GAIN=1.2;
|
||||||
private double gain=MAX_GAIN;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
@@ -46,11 +39,6 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm {
|
|||||||
if (windowControlConsumer != null) {
|
if (windowControlConsumer != null) {
|
||||||
windowControlConsumer.accept(window);
|
windowControlConsumer.accept(window);
|
||||||
}
|
}
|
||||||
speed = MIN_SPEED;
|
|
||||||
if (speedControlConsumer != null) {
|
|
||||||
speedControlConsumer.accept(speed, BURST_TIME);
|
|
||||||
}
|
|
||||||
gain=MAX_GAIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,10 +46,6 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm {
|
|||||||
this.windowControlConsumer = windowControlConsumer;
|
this.windowControlConsumer = windowControlConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSpeedControlConsumer(BiConsumer<Long, Long> speedControlConsumer) {
|
|
||||||
this.speedControlConsumer = speedControlConsumer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void putAck(long packetSize, long latencyns, boolean ecn) {
|
public synchronized void putAck(long packetSize, long latencyns, boolean ecn) {
|
||||||
@@ -86,7 +70,7 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm {
|
|||||||
|
|
||||||
|
|
||||||
long curr=System.nanoTime();
|
long curr=System.nanoTime();
|
||||||
if(curr-RTTstartTime>(RTTAvg+BIAS)) {
|
if(curr-RTTstartTime>Math.max(BIAS, 2*RTTMin)) {
|
||||||
RTTstartTime=curr;
|
RTTstartTime=curr;
|
||||||
|
|
||||||
long totalSize=TotalSize.getAndSet(0);
|
long totalSize=TotalSize.getAndSet(0);
|
||||||
@@ -94,37 +78,23 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm {
|
|||||||
if(totalSize!=0) {
|
if(totalSize!=0) {
|
||||||
ECNAvg2=ecnSize/(double)totalSize;
|
ECNAvg2=ecnSize/(double)totalSize;
|
||||||
alpha=(alpha*15+ECNAvg2)/16;
|
alpha=(alpha*15+ECNAvg2)/16;
|
||||||
|
//System.out.println(ECNAvg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ECNAvg2>0.6) {
|
if(ECNAvg2>0.5) {
|
||||||
gain=MIN_GAIN;
|
|
||||||
if(congressWindowSize>MIN_WINDOW) {
|
if(congressWindowSize>MIN_WINDOW) {
|
||||||
congressWindowSize=Math.max(MIN_WINDOW,(long) (congressWindowSize*(1-alpha/10)));
|
congressWindowSize=Math.max(MIN_WINDOW,(long) (congressWindowSize*(1-alpha/10)));
|
||||||
updateWindowSize();
|
updateWindowSize();
|
||||||
}
|
}
|
||||||
}else if(ECNAvg2>0.2){
|
|
||||||
if(windowUsed*3L>=congressWindowSize) {
|
|
||||||
congressWindowSize+=200;
|
|
||||||
updateWindowSize();
|
|
||||||
}
|
|
||||||
}else {
|
}else {
|
||||||
if(windowUsed*3L>=congressWindowSize) {
|
if(windowUsed*3L>=congressWindowSize) {
|
||||||
congressWindowSize+=8000;
|
congressWindowSize+=4000;
|
||||||
updateWindowSize();
|
updateWindowSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//System.out.println(ECNAvg2);
|
//System.out.println(ECNAvg2);
|
||||||
//System.out.println(speed+" "+window);
|
//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
|
@Override
|
||||||
public void setCurrentBandwidth(long bandwidth) {
|
public void setCurrentBandwidth(long bandwidth) {
|
||||||
this.bandwidth=bandwidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DCTCP";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ package org.kne.cloud.network.congestion;
|
|||||||
public interface DetnetCongestionAlgorithm extends CongestionAlgorithm {
|
public interface DetnetCongestionAlgorithm extends CongestionAlgorithm {
|
||||||
public void setUpperDelayBound(double upper);
|
public void setUpperDelayBound(double upper);
|
||||||
public void setLowerDelayBound(double lower);
|
public void setLowerDelayBound(double lower);
|
||||||
|
public void setBurstLimit(double limit);
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -1,9 +1,8 @@
|
|||||||
package org.kne.cloud.network.congestion;
|
package org.kne.cloud.network.congestion;
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class EmptyCongestionAlgorithm implements CongestionAlgorithm{
|
public class NOCongestionAlgorithm implements CongestionAlgorithm{
|
||||||
|
|
||||||
private long timeout;
|
private long timeout;
|
||||||
|
|
||||||
@@ -23,11 +22,7 @@ public class EmptyCongestionAlgorithm implements CongestionAlgorithm{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSpeedControlConsumer(BiConsumer<Long, Long> speedControlConsumer) {
|
|
||||||
// TODO 自动生成的方法存根
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putAck(long packetSize, long latencyns, boolean ecn) {
|
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();
|
super();
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
}
|
}
|
||||||
@@ -63,4 +58,9 @@ public class EmptyCongestionAlgorithm implements CongestionAlgorithm{
|
|||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "NO";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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<E> {
|
|
||||||
private AtomicReferenceArray<E> 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<E>(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<E> implements Iterable<E>{
|
|
||||||
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&&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&&number>=windowPosition-windowSize) {
|
|
||||||
return (E) array[calcPosition(number)];
|
|
||||||
}else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<E> iterator() {
|
|
||||||
return new Iterator<E>() {
|
|
||||||
private long pointer=windowPosition-windowSize;
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
return pointer<windowPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E next() {
|
|
||||||
return (E) array[calcPosition(pointer++)];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
private int calcPosition(long number) {
|
|
||||||
return (int) ((number+array.length)%array.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +1,27 @@
|
|||||||
package org.kne.cloud.network.congestion;
|
package org.kne.cloud.network.congestion;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
|
||||||
import java.util.concurrent.locks.Condition;
|
import java.util.concurrent.locks.Condition;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.kne.cloud.network.NetworkPacket;
|
import org.kne.cloud.network.NetworkPacket;
|
||||||
import org.kne.cloud.network.ThreadTool;
|
import org.kne.cloud.network.ThreadTool;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
|
||||||
import org.kne.cloud.network.klalb.SendItem;
|
import org.kne.cloud.network.klalb.SendItem;
|
||||||
|
import org.kne.concurrent.ThreadParker;
|
||||||
|
|
||||||
public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Closeable, AutoCloseable {
|
public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Closeable, AutoCloseable {
|
||||||
private Map<K, SendItem<V>> sendMap = new ConcurrentHashMap<>(1024, 0.2f);
|
private ThreadParker tp=new ThreadParker();
|
||||||
private AtomicLong sendmapWindowUsed=new AtomicLong(0);
|
|
||||||
//private LongAdder sendmapWindowUsed = new LongAdder();
|
private Map<K, SendItem<V>> sendMap = new ConcurrentHashMap<>(2048);
|
||||||
|
private AtomicLong sendWindowUsed=new AtomicLong(0);
|
||||||
|
//private LongAdder sendWindowUsed = new LongAdder();
|
||||||
|
|
||||||
private int headerCalibrate = 0;
|
private int headerCalibrate = 0;
|
||||||
|
|
||||||
@@ -36,14 +33,14 @@ public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Clos
|
|||||||
|
|
||||||
private Consumer<V> resendConsumer;
|
private Consumer<V> resendConsumer;
|
||||||
private Consumer<V> closingConsumer;
|
private Consumer<V> closingConsumer;
|
||||||
private volatile boolean closed = false;
|
|
||||||
private ResendChecker checker = new ResendChecker();
|
private ResendChecker checker = new ResendChecker();
|
||||||
private AtomicLong windowSize = new AtomicLong();
|
|
||||||
|
|
||||||
private Lock lock;
|
private Lock lock;
|
||||||
|
|
||||||
private Condition condition;
|
private Condition condition;
|
||||||
private boolean removeAtResend;
|
private boolean removeAtResend;
|
||||||
|
private volatile long windowSize =0;
|
||||||
|
private volatile boolean closed = false;
|
||||||
|
|
||||||
public SendPacketSlidingWindow(CongestionAlgorithm algorithm, long windowSize) {
|
public SendPacketSlidingWindow(CongestionAlgorithm algorithm, long windowSize) {
|
||||||
this(algorithm, windowSize, 0, true);
|
this(algorithm, windowSize, 0, true);
|
||||||
@@ -58,17 +55,17 @@ public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Clos
|
|||||||
this.headerCalibrate = headerCalibrate;
|
this.headerCalibrate = headerCalibrate;
|
||||||
this.removeAtResend = removeAtResend;
|
this.removeAtResend = removeAtResend;
|
||||||
this.algorithm = algorithm;
|
this.algorithm = algorithm;
|
||||||
this.windowSize.set(windowSize);
|
this.windowSize=windowSize;
|
||||||
Thread t = ThreadTool.makeVThread("重路由计时器线程", checker);
|
Thread t = ThreadTool.makeVThread("重路由计时器线程", checker);
|
||||||
t.start();
|
t.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getWindowSize() {
|
public long getWindowSize() {
|
||||||
return windowSize.get();
|
return windowSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWindowSize(long windowSize) {
|
public void setWindowSize(long windowSize) {
|
||||||
this.windowSize.set(windowSize);
|
this.windowSize=windowSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Consumer<V> getResendConsumer() {
|
public Consumer<V> getResendConsumer() {
|
||||||
@@ -87,8 +84,8 @@ public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Clos
|
|||||||
this.closingConsumer = closingConsumer;
|
this.closingConsumer = closingConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getSendmapWindowUsed() {
|
public long getSendWindowUsed() {
|
||||||
return sendmapWindowUsed.get();
|
return sendWindowUsed.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeaderCalibrate() {
|
public int getHeaderCalibrate() {
|
||||||
@@ -99,20 +96,38 @@ public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Clos
|
|||||||
return algorithm;
|
return algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCongress(IPv6Packet iPv6Packet, double scale) {
|
public boolean isCongestion( double scale) {
|
||||||
boolean congress = sendmapWindowUsed.get() > windowSize.get() * scale;
|
boolean congress = sendWindowUsed.get() > windowSize * scale;
|
||||||
return congress;
|
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) {
|
public void put(K sequence, V packet) {
|
||||||
SendItem<V> newitem = new SendItem<V>(packet);
|
SendItem<V> newitem = new SendItem<V>(packet,headerCalibrate);
|
||||||
SendItem<V> old = sendMap.put(sequence, newitem);
|
SendItem<V> old = sendMap.put(sequence, newitem);
|
||||||
long dx=0;
|
long dx=0;
|
||||||
if (old != null) {
|
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);
|
algorithm.setCurrentWindowUsed(newWindow);
|
||||||
}
|
}
|
||||||
public V ack(K sequence) {
|
public V ack(K sequence) {
|
||||||
@@ -122,10 +137,11 @@ public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Clos
|
|||||||
public V ack(K sequence,boolean ecn) {
|
public V ack(K sequence,boolean ecn) {
|
||||||
SendItem<V> ipv6;
|
SendItem<V> ipv6;
|
||||||
if ((ipv6 = sendMap.remove(sequence)) != null) {
|
if ((ipv6 = sendMap.remove(sequence)) != null) {
|
||||||
long newWindow =sendmapWindowUsed.addAndGet(-(ipv6.getPacketLength() + headerCalibrate));
|
long newWindow =sendWindowUsed.addAndGet(-ipv6.getPacketLength() );
|
||||||
algorithm.setCurrentWindowUsed(newWindow);
|
algorithm.setCurrentWindowUsed(newWindow);
|
||||||
long RTTC = System.nanoTime() - ipv6.getSendtime();
|
long RTTC = System.nanoTime() - ipv6.getSendtime();
|
||||||
algorithm.putAck(ipv6.getPacketLength(), RTTC, ecn);
|
algorithm.putAck(ipv6.getPacketLength(), RTTC, ecn);
|
||||||
|
tp.unpark();
|
||||||
// System.out.println("remove:"+aseq.getSequence()+" "+sendMap.size());
|
// System.out.println("remove:"+aseq.getSequence()+" "+sendMap.size());
|
||||||
Lock lockx = lock;
|
Lock lockx = lock;
|
||||||
if (lockx != null) {
|
if (lockx != null) {
|
||||||
@@ -146,6 +162,34 @@ public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Clos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public V ack(K sequence,boolean ecn,long OWDdown) {
|
||||||
|
SendItem<V> 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 {
|
private class ResendChecker implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -159,8 +203,9 @@ public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Clos
|
|||||||
if (current - sitm.getSendtime() > algorithm.getRTO()) {
|
if (current - sitm.getSendtime() > algorithm.getRTO()) {
|
||||||
if (removeAtResend) {
|
if (removeAtResend) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
long newWindow = sendmapWindowUsed.addAndGet((int) -(sitm.getPacketLength() + headerCalibrate));
|
long newWindow = sendWindowUsed.addAndGet((int) -sitm.getPacketLength() );
|
||||||
algorithm.setCurrentWindowUsed(newWindow);
|
algorithm.setCurrentWindowUsed(newWindow);
|
||||||
|
tp.unpark();
|
||||||
} else {
|
} else {
|
||||||
sitm.setSendtime(current);
|
sitm.setSendtime(current);
|
||||||
}
|
}
|
||||||
@@ -183,7 +228,7 @@ public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Clos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendMap.clear();
|
sendMap.clear();
|
||||||
sendmapWindowUsed.set(0);
|
sendWindowUsed.set(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +260,20 @@ public class SendPacketSlidingWindow<K, V extends NetworkPacket> implements Clos
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package org.kne.cloud.network.congestion;
|
package org.kne.cloud.network.congestion;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCongestionAlgorithm {
|
public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCongestionAlgorithm {
|
||||||
@@ -9,19 +7,15 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
|
|||||||
// 可配置的时延膨胀比上下限 - Vegas2.0核心参数
|
// 可配置的时延膨胀比上下限 - Vegas2.0核心参数
|
||||||
private double delayUpperBound = 1.20; // RTT上限为基础RTT的1.2倍
|
private double delayUpperBound = 1.20; // RTT上限为基础RTT的1.2倍
|
||||||
private double delayLowerBound = 1.15; // RTT下限为基础RTT的1.05倍
|
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 BURST_TIME = 2000000L;
|
||||||
private static final long BIAS = 500000L;
|
private static final long BIAS = 1000000L;
|
||||||
private static long MIN_SPEED = 256 * 1024L;
|
|
||||||
private static long MIN_WINDOW = 16384;
|
private static long MIN_WINDOW = 16384;
|
||||||
|
|
||||||
// 新增:窗口调整参数(可基于当前窗口大小动态调整)
|
|
||||||
private static final double WINDOW_ADJUST_FACTOR = 0.01; // 1%的窗口调整幅度
|
|
||||||
|
|
||||||
private Consumer<Long> windowControlConsumer;
|
private Consumer<Long> windowControlConsumer;
|
||||||
private BiConsumer<Long, Long> speedControlConsumer;
|
|
||||||
|
|
||||||
private AtomicBoolean firstUpdate = new AtomicBoolean(true);
|
|
||||||
private long MIN_RTTVAR = 30000000L;
|
private long MIN_RTTVAR = 30000000L;
|
||||||
private volatile long RTTMin = 1000000000L; // BaseRTT
|
private volatile long RTTMin = 1000000000L; // BaseRTT
|
||||||
private volatile long RTTVar = 1000000000L;
|
private volatile long RTTVar = 1000000000L;
|
||||||
@@ -31,12 +25,15 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
|
|||||||
private volatile long RTTCount = 0;
|
private volatile long RTTCount = 0;
|
||||||
private volatile long RTO = 1000000000L;
|
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 window = MIN_WINDOW;
|
||||||
private volatile long window2 = MIN_WINDOW;
|
private volatile long window2 = MIN_WINDOW;
|
||||||
private volatile long speed = MIN_SPEED;
|
|
||||||
private volatile long maxwindow = 99999999999L;
|
private volatile long maxwindow = 99999999999L;
|
||||||
private long congressSpeed=MIN_SPEED;
|
|
||||||
|
|
||||||
public Vegas2CongestionAlgorithm() {
|
public Vegas2CongestionAlgorithm() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@@ -47,10 +44,7 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
|
|||||||
if (windowControlConsumer != null) {
|
if (windowControlConsumer != null) {
|
||||||
windowControlConsumer.accept(window);
|
windowControlConsumer.accept(window);
|
||||||
}
|
}
|
||||||
speed = MIN_SPEED;
|
|
||||||
if (speedControlConsumer != null) {
|
|
||||||
speedControlConsumer.accept(speed, BURST_TIME);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,15 +52,17 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
|
|||||||
this.windowControlConsumer = windowControlConsumer;
|
this.windowControlConsumer = windowControlConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSpeedControlConsumer(BiConsumer<Long, Long> speedControlConsumer) {
|
|
||||||
this.speedControlConsumer = speedControlConsumer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private long RTTstartTime = System.nanoTime();
|
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信号 - 将其视为强烈的拥塞信号
|
// 处理ECN信号 - 将其视为强烈的拥塞信号
|
||||||
if (ecn) {
|
if (ecn) {
|
||||||
// 当收到ECN时,更激进地减少窗口
|
// 当收到ECN时,更激进地减少窗口
|
||||||
@@ -77,35 +73,128 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新最小RTT(BaseRTT)
|
// 更新最小RTT(BaseRTT)
|
||||||
if (latencyns <= RTTMin) {
|
if (RTTns <= RTTMin) {
|
||||||
RTTMin = latencyns;
|
RTTMin = RTTns;
|
||||||
} else {
|
} else {
|
||||||
// 缓慢适应:当网络路径真正变化时,BaseRTT应能缓慢更新
|
// 缓慢适应:当网络路径真正变化时,BaseRTT应能缓慢更新
|
||||||
// 这里使用极慢的衰减因子,只有在持续观测到更低RTT时才快速更新
|
// 这里使用极慢的衰减因子,只有在持续观测到更低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估计
|
// 更新平滑RTT估计
|
||||||
if (firstUpdate.compareAndSet(true, false)) {
|
|
||||||
RTTAvg = latencyns;
|
RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - RTTns)) / 4;
|
||||||
RTTVar = latencyns / 2;
|
RTTAvg = (RTTAvg * 7 + RTTns) / 8;
|
||||||
RTTAvg2 = latencyns;
|
|
||||||
} else {
|
|
||||||
RTTVar = (RTTVar * 3 + Math.abs(RTTAvg - latencyns)) / 4;
|
|
||||||
RTTAvg = (RTTAvg * 7 + latencyns) / 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
RTO = RTTAvg + Math.max(MIN_RTTVAR, RTTVar * 4);
|
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++;
|
RTTCount++;
|
||||||
|
|
||||||
long curr = System.nanoTime();
|
long curr = System.nanoTime();
|
||||||
// 每个RTT周期调整一次窗口(使用当前估计的RTT)
|
// 每个RTT周期调整一次窗口(使用当前估计的RTT)
|
||||||
if (curr - RTTstartTime > Math.max(BIAS, RTTMin)) {
|
if (curr - RTTstartTime > Math.max(BIAS, 2*RTTMin)) {
|
||||||
if (RTTCount > 0) {
|
long RTTCountx=RTTCount;
|
||||||
long currentRTT = RTTTotal / RTTCount;
|
if (RTTCountx > 0) {
|
||||||
RTTAvg2 = (RTTAvg2 * 3 + currentRTT) / 4; // 平滑当前RTT
|
long currentRTT = RTTTotal / RTTCountx;
|
||||||
|
//RTTAvg2 = (RTTAvg2 * 3 + currentRTT) / 4; // 平滑当前RTT
|
||||||
|
RTTAvg2=currentRTT;
|
||||||
RTTTotal = 0;
|
RTTTotal = 0;
|
||||||
RTTCount = 0;
|
RTTCount = 0;
|
||||||
}
|
}
|
||||||
@@ -113,64 +202,47 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
|
|||||||
// ================== Vegas2.0核心逻辑 ==================
|
// ================== Vegas2.0核心逻辑 ==================
|
||||||
// 1. 计算时延膨胀比
|
// 1. 计算时延膨胀比
|
||||||
double delayRatio = (double) RTTAvg2 / (double) Math.max(BIAS, RTTMin);
|
double delayRatio = (double) RTTAvg2 / (double) Math.max(BIAS, RTTMin);
|
||||||
|
//System.out.println(delayRatio+" "+RTTAvg2/1000000.0+" "+RTTMin/1000000.0);
|
||||||
// 2. 基于比值的窗口调整(取代原来的基于差值的调整)
|
// 2. 基于比值的窗口调整(取代原来的基于差值的调整)
|
||||||
long adjustStep = Math.max(512, (long)(window2 * WINDOW_ADJUST_FACTOR));
|
|
||||||
|
|
||||||
if (delayRatio > delayUpperBound) {
|
if (delayRatio > delayUpperBound) {
|
||||||
// 时延过高:减小窗口,减少幅度与超标程度成正比
|
// 时延过高:减小窗口,减少幅度与超标程度成正比
|
||||||
double exceedRatio = delayRatio / delayUpperBound;
|
window2 -= 4096;
|
||||||
window2 -= (long)(adjustStep * exceedRatio);
|
|
||||||
} else if (delayRatio < delayLowerBound) {
|
} else if (delayRatio < delayLowerBound) {
|
||||||
// 时延过低:增大窗口,增加幅度与低于目标程度成正比
|
// 时延过低:增大窗口,增加幅度与低于目标程度成正比
|
||||||
double belowRatio = delayLowerBound / delayRatio;
|
window2 += 4096;
|
||||||
window2 += (long)(adjustStep * belowRatio);
|
|
||||||
} else {
|
} 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;
|
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
|
@Override
|
||||||
public void putLoss(long packetSize, long lossns, int losscounter) {
|
public void putLoss(long packetSize, long lossns, int losscounter) {
|
||||||
@@ -183,14 +255,12 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCurrentWindowUsed(long used) {
|
public void setCurrentWindowUsed(long used) {
|
||||||
this.maxwindow = used * 16 + 65536;
|
this.maxwindow = (long) (used * burstLimit )+ MIN_WINDOW;
|
||||||
}
|
}
|
||||||
private long bandwidth;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCurrentBandwidth(long bandwidth) {
|
public void setCurrentBandwidth(long bandwidth) {
|
||||||
// 可选:基于已知带宽信息调整参数
|
// 可选:基于已知带宽信息调整参数
|
||||||
this.bandwidth=bandwidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增方法:获取当前状态信息(用于监控和调试)
|
// 新增方法:获取当前状态信息(用于监控和调试)
|
||||||
@@ -215,4 +285,14 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
|
|||||||
public void setLowerDelayBound(double lower) {
|
public void setLowerDelayBound(double lower) {
|
||||||
delayLowerBound=lower;
|
delayLowerBound=lower;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBurstLimit(double limit) {
|
||||||
|
burstLimit=limit;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Vegas2";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,9 @@
|
|||||||
package org.kne.cloud.network.ipv6;
|
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.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.locks.Condition;
|
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
|
||||||
import org.kne.cloud.network.srv6.SRv6Router;
|
import org.kne.cloud.network.srv6.SRv6Router;
|
||||||
|
|
||||||
public abstract class AbstractIPv6NetworkLink implements IPv6NetworkLink {
|
public abstract class AbstractIPv6NetworkLink implements IPv6NetworkLink {
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
public interface ControlledIPv6NetworkLink extends IPv6NetworkLink {
|
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) {
|
public default boolean isCongress(IPv6Packet iPv6Packet) {
|
||||||
return isCongress(iPv6Packet, 1.0);
|
return isCongestion(iPv6Packet, 1.0);
|
||||||
}
|
}
|
||||||
void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer);
|
void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer);
|
||||||
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet);
|
|
||||||
public void setCongressCondition(Lock lock,Condition condition);
|
public void setCongressCondition(Lock lock,Condition condition);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class ICMPv6Packet extends IPv6Payload {
|
|||||||
private boolean isDefault;
|
private boolean isDefault;
|
||||||
|
|
||||||
protected ICMPv6Packet(ByteBuffer header,boolean isDefault) {
|
protected ICMPv6Packet(ByteBuffer header,boolean isDefault) {
|
||||||
super(ICMPv6_PROTOCOL_NUMBER, false);
|
super(ICMPv6_PROTOCOL_NUMBER);
|
||||||
this.header=header;
|
this.header=header;
|
||||||
this.isDefault=isDefault;
|
this.isDefault=isDefault;
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ public class ICMPv6Packet extends IPv6Payload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected ICMPv6Packet(int type, int code,boolean isDefault) {
|
protected ICMPv6Packet(int type, int code,boolean isDefault) {
|
||||||
super(ICMPv6_PROTOCOL_NUMBER, false);
|
super(ICMPv6_PROTOCOL_NUMBER);
|
||||||
header = NetworkPacket.bufferAllocator.allocate(ICMPv6_HEADER_LENGTH);
|
header = NetworkPacket.bufferAllocator.allocate(ICMPv6_HEADER_LENGTH);
|
||||||
getHeader().put((byte) type);
|
getHeader().put((byte) type);
|
||||||
getHeader().put((byte) code);
|
getHeader().put((byte) code);
|
||||||
|
|||||||
@@ -4,32 +4,21 @@ import java.io.EOFException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StreamCorruptedException;
|
import java.io.StreamCorruptedException;
|
||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.kne.cloud.network.ByteBufferAllocator;
|
|
||||||
import org.kne.cloud.network.NetworkPacket;
|
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.klalb.KLALBPacket;
|
||||||
|
import org.kne.cloud.network.kltp.KLTPPacket;
|
||||||
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
|
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.cloud.network.tcp.UDPPacket;
|
||||||
import org.kne.io.KNEChannels;
|
import org.kne.io.KNEChannels;
|
||||||
import org.pcap4j.packet.namednumber.IpNumber;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IPv6数据包类,继承自NetworkPacket,用于处理IPv6网络数据包
|
* IPv6数据包类,继承自NetworkPacket,用于处理IPv6网络数据包
|
||||||
@@ -231,15 +220,7 @@ public class IPv6Packet extends NetworkPacket {
|
|||||||
nextHeader == ICMPv6;
|
nextHeader == ICMPv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPv6NetworkLink previousLink;
|
|
||||||
|
|
||||||
public IPv6NetworkLink getPreviousLink() {
|
|
||||||
return previousLink;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPreviousLink(IPv6NetworkLink previousLink) {
|
|
||||||
this.previousLink = previousLink;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TTL是否已减少的标志
|
// TTL是否已减少的标志
|
||||||
private boolean TTLdecreased = false;
|
private boolean TTLdecreased = false;
|
||||||
@@ -318,7 +299,10 @@ public class IPv6Packet extends NetworkPacket {
|
|||||||
* @return 流量类别
|
* @return 流量类别
|
||||||
*/
|
*/
|
||||||
public int getTrafficClass() {
|
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 流量类别
|
* @param trafficClass 流量类别
|
||||||
*/
|
*/
|
||||||
public void setTrafficClass(int 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(拥塞经历)
|
* 标记CE(拥塞经历)
|
||||||
*/
|
*/
|
||||||
public void markCE() {
|
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();
|
// new Exception().printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +360,10 @@ public class IPv6Packet extends NetworkPacket {
|
|||||||
* @return 流标签
|
* @return 流标签
|
||||||
*/
|
*/
|
||||||
public int getFlowLabel() {
|
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 流标签
|
* @param flowLabel 流标签
|
||||||
*/
|
*/
|
||||||
public void setFlowLabel(int flowLabel) {
|
public void setFlowLabel(int flowLabel) {
|
||||||
IPv6header.put(1, (byte) (IPv6header.get(1) & BIT_MASK_HIGH_4_BITS | (flowLabel >>> 16)));
|
// 读取当前前 4 个字节
|
||||||
IPv6header.putShort(2, (short) flowLabel);
|
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
|
* @return
|
||||||
*/
|
*/
|
||||||
public IPv6Address getSourceAddress() {
|
public IPv6Address getSourceAddress() {
|
||||||
@@ -479,7 +481,6 @@ public class IPv6Packet extends NetworkPacket {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取原始目标地址字节数组
|
* 获取原始目标地址字节数组
|
||||||
* @param destinationAddress 用于存储目标地址的字节数组
|
|
||||||
*/
|
*/
|
||||||
public IPv6Address getDestinationAddress() {
|
public IPv6Address getDestinationAddress() {
|
||||||
return IPv6Address.valueOf(DESTINATION_ADDRESS_OFFSET,IPv6header);
|
return IPv6Address.valueOf(DESTINATION_ADDRESS_OFFSET,IPv6header);
|
||||||
@@ -707,13 +708,12 @@ public class IPv6Packet extends NetworkPacket {
|
|||||||
KLALBPacket kp = KLALBPacket.readKLALBPacketFromChannel(din);
|
KLALBPacket kp = KLALBPacket.readKLALBPacketFromChannel(din);
|
||||||
this.payload = kp;
|
this.payload = kp;
|
||||||
break loop;
|
break loop;
|
||||||
case EXPERIMENTAL_1: // 空负载
|
case KLTPPacket.KLTP_PROTOCOL_NUMBER: //KLTP协议
|
||||||
IPv6Payload epld = new IPv6EmptyPayload();
|
IPv6Payload epld = KLTPPacket.readKLTPPacketFromChannel(din);
|
||||||
epld.readFromChannel(din, payloadlength);
|
|
||||||
this.payload = epld;
|
this.payload = epld;
|
||||||
break loop;
|
break loop;
|
||||||
default: // 其他协议类型
|
default: // 其他协议类型
|
||||||
IPv6Payload pld = new IPv6Payload(nextheader);
|
IPv6Payload pld = new IPv6DefaultPayload(nextheader);
|
||||||
pld.readFromChannel(din, payloadlength);
|
pld.readFromChannel(din, payloadlength);
|
||||||
this.payload = pld;
|
this.payload = pld;
|
||||||
break loop;
|
break loop;
|
||||||
@@ -754,56 +754,28 @@ public class IPv6Packet extends NetworkPacket {
|
|||||||
/**
|
/**
|
||||||
* IPv6负载数据类
|
* IPv6负载数据类
|
||||||
*/
|
*/
|
||||||
public static class IPv6Payload extends NetworkPacket {
|
public static abstract class IPv6Payload extends NetworkPacket {
|
||||||
private ByteBuffer data;
|
|
||||||
|
|
||||||
private boolean onDefault = true;
|
|
||||||
|
|
||||||
|
|
||||||
private IPv6Packet parent;
|
private IPv6Packet parent;
|
||||||
|
|
||||||
public ByteBuffer getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int protocolNumber;
|
private int protocolNumber;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public IPv6Payload(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() {
|
public int getProtocolNumber() {
|
||||||
return protocolNumber;
|
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
|
@Override
|
||||||
protected boolean needEndPosition() {
|
protected boolean needEndPosition() {
|
||||||
@@ -817,31 +789,37 @@ public class IPv6Packet extends NetworkPacket {
|
|||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class IPv6DefaultPayload extends IPv6Payload{
|
||||||
|
|
||||||
/**
|
private ByteBuffer data;
|
||||||
* 空IPv6负载数据类
|
public ByteBuffer getData() {
|
||||||
*/
|
return data;
|
||||||
public static class IPv6EmptyPayload extends IPv6Payload {
|
|
||||||
|
|
||||||
public IPv6EmptyPayload() {
|
|
||||||
super(EXPERIMENTAL_1, false);
|
|
||||||
}
|
}
|
||||||
|
public IPv6DefaultPayload(int protocolNumber) {
|
||||||
@Override
|
super(protocolNumber);
|
||||||
|
this.data = NetworkPacket.bufferAllocator.allocate(65535);
|
||||||
|
}
|
||||||
public long getTotalLength() {
|
public long getTotalLength() {
|
||||||
return 0;
|
return data.limit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||||
|
dto.write(data.slice(0, data.limit()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
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扩展头部基类
|
* IPv6扩展头部基类
|
||||||
@@ -1131,12 +1109,16 @@ public class IPv6Packet extends NetworkPacket {
|
|||||||
public IPv6SegmentRoutingHeader(List<IPv6Address> segs) {
|
public IPv6SegmentRoutingHeader(List<IPv6Address> segs) {
|
||||||
this();
|
this();
|
||||||
this.addresses.addAll(segs);
|
this.addresses.addAll(segs);
|
||||||
int ln = addresses.size() - 1;
|
resetSegmentPos();
|
||||||
setLastEntry(ln);
|
|
||||||
setSegmentsLeft(ln);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
return getData().get(4) & BIT_MASK_LOW_8_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
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.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||||
import org.kne.cloud.network.srv6.DetNetSRv6TLV;
|
import org.kne.cloud.network.srv6.DetNetSRv6TLV;
|
||||||
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
|
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.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.InetAddressRow;
|
||||||
import org.kne.cloud.network.tun.TUNChannel;
|
import org.kne.cloud.network.tun.TUNChannel;
|
||||||
import org.kne.cloud.network.tun.TUNNetworkDevice;
|
import org.kne.cloud.network.tun.TUNNetworkDevice;
|
||||||
@@ -94,7 +88,7 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
|
|||||||
con.accept(IPv6TUNLoopbackNetworkLink.this, () -> {
|
con.accept(IPv6TUNLoopbackNetworkLink.this, () -> {
|
||||||
UUID pid = ipp.getPacketID();
|
UUID pid = ipp.getPacketID();
|
||||||
if (pid != null) {
|
if (pid != null) {
|
||||||
monitor.getUploadBandwidth().recordPacket(pid, (int) ipp.getTotalLength());
|
monitor.getUploadBandwidth().recordPacket(pid,1, (int) ipp.getTotalLength());
|
||||||
}
|
}
|
||||||
// ipp.setDisposeAfterSend(true);
|
// ipp.setDisposeAfterSend(true);
|
||||||
// ipp.getPayload().setDisposeAfterSend(true);
|
// ipp.getPayload().setDisposeAfterSend(true);
|
||||||
@@ -203,23 +197,14 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
|
|||||||
pack.writeToChannel(KNEChannels.newWritableChannel(tmp));
|
pack.writeToChannel(KNEChannels.newWritableChannel(tmp));
|
||||||
UUID pid = pack.getPacketID();
|
UUID pid = pack.getPacketID();
|
||||||
if (pid != null) {
|
if (pid != null) {
|
||||||
monitor.getUploadBandwidth().recordPacket(pid, (int) pack.getTotalLength());
|
monitor.getUploadBandwidth().recordPacket(pid, 1,(int) pack.getTotalLength());
|
||||||
}
|
}
|
||||||
tmp.flip();
|
tmp.flip();
|
||||||
sendQueue.add(tmp);
|
sendQueue.add(tmp);
|
||||||
LockSupport.unpark(tr);
|
LockSupport.unpark(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SRv6StreamSequenceTLV getStreamSequenceTLV(IpV6RoutingSRHData srh) {
|
|
||||||
List<SRv6TLV> stv = srh.getTlvs();
|
|
||||||
for (Iterator iterator = stv.iterator(); iterator.hasNext();) {
|
|
||||||
SRv6TLV sRv6TLV = (SRv6TLV) iterator.next();
|
|
||||||
if (sRv6TLV.getType() == SRv6TLV.SEQS) {
|
|
||||||
return (SRv6StreamSequenceTLV) sRv6TLV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoopBack() {
|
public boolean isLoopBack() {
|
||||||
@@ -282,11 +267,11 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
|
|||||||
for (Iterator<Neighbor> iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) {
|
for (Iterator<Neighbor> iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) {
|
||||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||||
RouteItem ri = new RouteItem(new IPv6AddressGroup(addresses.getAddress().getAddress(), 128),
|
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);
|
rlist.add(ri);
|
||||||
|
|
||||||
RouteItem ris = new RouteItem(addresses.getLocator(), addresses.getLocator().getAddress(), this,
|
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);
|
rlist.add(ris);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
package org.kne.cloud.network.ipv6;
|
package org.kne.cloud.network.ipv6;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
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.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.kne.cloud.network.srv6.PacketConsumer;
|
|
||||||
import org.kne.cloud.network.srv6.SRv6Router;
|
import org.kne.cloud.network.srv6.SRv6Router;
|
||||||
|
|
||||||
public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements IPv6NetworkLink {
|
public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements IPv6NetworkLink {
|
||||||
@@ -28,9 +22,9 @@ public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements
|
|||||||
this.fallbackLink = fallbackLink;
|
this.fallbackLink = fallbackLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Integer, PacketConsumer> protocolNumberRegister = new ConcurrentHashMap<>(256 * 2);
|
private IPv6ProtocolRegister[] protocolNumberRegister = new IPv6ProtocolRegister[256];
|
||||||
|
|
||||||
public Map<Integer, PacketConsumer> getProtocolNumberRegister() {
|
public IPv6ProtocolRegister[] getProtocolNumberRegister() {
|
||||||
return protocolNumberRegister;
|
return protocolNumberRegister;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,9 +40,9 @@ public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendPacket(IPv6Packet pack, IPv6Address next) throws IOException {
|
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 != null) {
|
||||||
if(!pcm.accept(pack)) {
|
if(!pcm.onaccept(pack)) {
|
||||||
if(fallbackLink!=null) {
|
if(fallbackLink!=null) {
|
||||||
fallbackLink.sendPacket(pack, next);
|
fallbackLink.sendPacket(pack, next);
|
||||||
}
|
}
|
||||||
@@ -110,13 +104,13 @@ public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements
|
|||||||
for (Iterator<Neighbor> iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) {
|
for (Iterator<Neighbor> iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) {
|
||||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||||
RouteItem ri = new RouteItem(new IPv6AddressGroup(addresses.getAddress().getAddress(), 128),
|
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);
|
false);
|
||||||
rlist.add(ri);
|
rlist.add(ri);
|
||||||
|
|
||||||
RouteItem ris = new RouteItem(addresses.getLocator(),
|
RouteItem ris = new RouteItem(addresses.getLocator(),
|
||||||
addresses.getLocator().getAddress(), this, "KLALB SRv6", 13, 128,
|
addresses.getLocator().getAddress(), this, "KLALB SRv6", 13, 128,
|
||||||
addresses.getMonitor(), "D", false);
|
null, "D", false);
|
||||||
rlist.add(ris);
|
rlist.add(ris);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
package org.kne.cloud.network.ipv6;
|
package org.kne.cloud.network.ipv6;
|
||||||
|
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
public class RouteItem implements Comparable<RouteItem>,Cloneable{
|
public class RouteItem implements Comparable<RouteItem>,Cloneable{
|
||||||
private IPv6AddressGroup destination;
|
private IPv6AddressGroup destination;
|
||||||
@@ -18,14 +11,11 @@ public class RouteItem implements Comparable<RouteItem>,Cloneable{
|
|||||||
private int pre;
|
private int pre;
|
||||||
private long cost;
|
private long cost;
|
||||||
private String flag;
|
private String flag;
|
||||||
private MonitorData monitor;
|
private Supplier<Long> costSupplier;
|
||||||
private boolean isLoopback;
|
private boolean isLoopback;
|
||||||
public String getFlag() {
|
public String getFlag() {
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
public MonitorData getMonitor() {
|
|
||||||
return monitor;
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(cost, destination, destlink, flag, nexthop, pre, proto);
|
return Objects.hash(cost, destination, destlink, flag, nexthop, pre, proto);
|
||||||
@@ -56,7 +46,7 @@ public class RouteItem implements Comparable<RouteItem>,Cloneable{
|
|||||||
this.isLoopback=isLoopback;
|
this.isLoopback=isLoopback;
|
||||||
}
|
}
|
||||||
public RouteItem(IPv6AddressGroup destination, IPv6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
|
public RouteItem(IPv6AddressGroup destination, IPv6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
|
||||||
long cost,MonitorData monitor,String flag,boolean isLoopback) {
|
long cost,Supplier<Long> costSupplier,String flag,boolean isLoopback) {
|
||||||
super();
|
super();
|
||||||
this.destination = destination;
|
this.destination = destination;
|
||||||
this.nexthop = nexthop;
|
this.nexthop = nexthop;
|
||||||
@@ -64,7 +54,7 @@ public class RouteItem implements Comparable<RouteItem>,Cloneable{
|
|||||||
this.proto = proto;
|
this.proto = proto;
|
||||||
this.pre = pre;
|
this.pre = pre;
|
||||||
this.cost = cost;
|
this.cost = cost;
|
||||||
this.monitor=monitor;
|
this.costSupplier=costSupplier;
|
||||||
this.flag=flag;
|
this.flag=flag;
|
||||||
this.isLoopback=isLoopback;
|
this.isLoopback=isLoopback;
|
||||||
}
|
}
|
||||||
@@ -99,6 +89,7 @@ public class RouteItem implements Comparable<RouteItem>,Cloneable{
|
|||||||
public boolean checkMatch(byte[] ia) {
|
public boolean checkMatch(byte[] ia) {
|
||||||
return destination.checkMatch(ia);
|
return destination.checkMatch(ia);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(RouteItem o) {
|
public int compareTo(RouteItem o) {
|
||||||
int v1=destination.compareTo(o.destination);
|
int v1=destination.compareTo(o.destination);
|
||||||
@@ -110,22 +101,23 @@ public class RouteItem implements Comparable<RouteItem>,Cloneable{
|
|||||||
int v3=Long.compare(cost, o.cost);
|
int v3=Long.compare(cost, o.cost);
|
||||||
return v3;
|
return v3;
|
||||||
}
|
}
|
||||||
|
public Supplier<Long> getCostSupplier() {
|
||||||
|
return costSupplier;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public Object clone() {
|
public Object clone() {
|
||||||
try {
|
try {
|
||||||
RouteItem ri=(RouteItem) super.clone();
|
RouteItem ri=(RouteItem) super.clone();
|
||||||
if(monitor!=null)
|
|
||||||
ri.monitor=(MonitorData) monitor.clone();
|
|
||||||
return ri;
|
return ri;
|
||||||
} catch (CloneNotSupportedException e) {
|
} catch (CloneNotSupportedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//在排序前调用,计算cost
|
||||||
public void preSort() {
|
public void updateCost() {
|
||||||
if(monitor!=null) {
|
if(costSupplier!=null) {
|
||||||
cost=((DelayMonitorData)monitor).getOutDelay();
|
cost=costSupplier.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public boolean ECMPequals(RouteItem prevr) {
|
public boolean ECMPequals(RouteItem prevr) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public static final int PAD1=0;
|
|||||||
|
|
||||||
private boolean isDefault;
|
private boolean isDefault;
|
||||||
|
|
||||||
protected volatile ByteBuffer header;
|
protected ByteBuffer header;
|
||||||
|
|
||||||
private ByteBuffer data;
|
private ByteBuffer data;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.ServerSocket;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public interface BindableKLALBPacketConsumer extends PacketConsumer {
|
public interface BindableConsumer<T> extends Consumer<T> {
|
||||||
public InetAddress getRemoteInetAddress() ;
|
public InetAddress getRemoteInetAddress() ;
|
||||||
public InetAddress getLocalInetAddress() ;
|
public InetAddress getLocalInetAddress() ;
|
||||||
public int getPort() ;
|
public int getPort() ;
|
||||||
@@ -18,4 +18,6 @@ public class CONST {
|
|||||||
public static final int linepanelheight = 41;
|
public static final int linepanelheight = 41;
|
||||||
public static final int settingheight = 30;
|
public static final int settingheight = 30;
|
||||||
public static final int dialwidth = 150;
|
public static final int dialwidth = 150;
|
||||||
|
public static final int windowwidth = 1200;
|
||||||
|
public static final int windowheight = 800;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.kne.cloud.network.NetworkPacket;
|
import org.kne.cloud.network.NetworkPacket;
|
||||||
|
|
||||||
@@ -101,7 +102,16 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
|||||||
public int getSize() {
|
public int getSize() {
|
||||||
return dataBuffer.limit();
|
return dataBuffer.limit();
|
||||||
}
|
}
|
||||||
|
private int sendCounter=0;
|
||||||
|
|
||||||
|
public int getSendCounter() {
|
||||||
|
return sendCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incSendCounter() {
|
||||||
|
sendCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||||
klalbHeader.put(17, (byte) getSendCounter());
|
klalbHeader.put(17, (byte) getSendCounter());
|
||||||
@@ -126,6 +136,6 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
|||||||
}
|
}
|
||||||
dataBuffer.flip();
|
dataBuffer.flip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,42 +7,30 @@ import java.net.Inet6Address;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
import java.net.NoRouteToHostException;
|
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.UnknownHostException;
|
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.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
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.Lock;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.kne.cloud.clock.AdjustedNanoClock;
|
|
||||||
import org.kne.cloud.clock.HighAccuracyClock;
|
import org.kne.cloud.clock.HighAccuracyClock;
|
||||||
import org.kne.cloud.network.IPMulticastDiscovery;
|
import org.kne.cloud.network.IPMulticastDiscovery;
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
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.SocketType;
|
||||||
import org.kne.cloud.network.ThreadTool;
|
import org.kne.cloud.network.ThreadTool;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Address;
|
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.IPv6NetworkLink;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
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.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.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.HashMapTimestampMonitor;
|
||||||
import org.kne.cloud.network.monitor.MonitorData;
|
|
||||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
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.NTPContext;
|
||||||
import org.kne.cloud.network.ntp.NTPv4Packet;
|
import org.kne.cloud.network.ntp.NTPv4Packet;
|
||||||
import org.kne.cloud.network.ntp.NTPv4Protocol;
|
import org.kne.cloud.network.ntp.NTPv4Protocol;
|
||||||
import org.kne.cloud.network.ntp.NTPv4Protocol.NTPPeer;
|
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.KLALBRoutingProtocol;
|
||||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocolAPIClient;
|
import org.kne.cloud.network.srv6.KLALBRoutingProtocolAPIClient;
|
||||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocolAPIServer;
|
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.SRv6Router;
|
||||||
import org.kne.cloud.network.srv6.SRv6RouterListener;
|
import org.kne.cloud.network.srv6.SRv6RouterListener;
|
||||||
import org.kne.cloud.network.tcp.UDPPacket;
|
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.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 {
|
public class KLALBController {
|
||||||
private UUID nodeuuid=UUID.randomUUID();
|
private UUID nodeuuid=UUID.randomUUID();
|
||||||
@@ -93,14 +67,14 @@ public class KLALBController {
|
|||||||
public HighAccuracyClock getClock() {
|
public HighAccuracyClock getClock() {
|
||||||
return clock;
|
return clock;
|
||||||
}
|
}
|
||||||
|
private final long TIME_WINDOW=5000000000L;
|
||||||
private SpeedAndTrafficMonitorDataImpl linkMonitor = new SpeedAndTrafficMonitorDataImpl(
|
private SpeedAndTrafficMonitorDataImpl linkMonitor = new SpeedAndTrafficMonitorDataImpl(
|
||||||
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "up", 100, 500000000L),
|
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "up", 100,TIME_WINDOW ),
|
||||||
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, 500000000L));
|
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, TIME_WINDOW));
|
||||||
|
|
||||||
private SpeedAndTrafficMonitorDataImpl datatMonitor = new SpeedAndTrafficMonitorDataImpl(
|
private SpeedAndTrafficMonitorDataImpl datatMonitor = new SpeedAndTrafficMonitorDataImpl(
|
||||||
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "up", 100, 500000000L),
|
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "up", 100, TIME_WINDOW),
|
||||||
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, 500000000L));
|
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, TIME_WINDOW));
|
||||||
|
|
||||||
private List<MultipurposeSocketAddress> selflineTable = new ArrayList<>();
|
private List<MultipurposeSocketAddress> selflineTable = new ArrayList<>();
|
||||||
|
|
||||||
@@ -123,6 +97,17 @@ public class KLALBController {
|
|||||||
public List<InetAddress> getDnsAddresses() {
|
public List<InetAddress> getDnsAddresses() {
|
||||||
return dnsAddresses;
|
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);
|
private Timer twk = new Timer("网卡检测扫描计时器", true);
|
||||||
|
|
||||||
@@ -193,8 +178,8 @@ public class KLALBController {
|
|||||||
Set<MultipurposeSocketAddress> st = new HashSet<>();
|
Set<MultipurposeSocketAddress> st = new HashSet<>();
|
||||||
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
||||||
IPv6NetworkLink link = iterator.next();
|
IPv6NetworkLink link = iterator.next();
|
||||||
if (link instanceof KLALBRemoteLine) {
|
if (link instanceof KLALBRemoteLink) {
|
||||||
KLALBRemoteLine multipurposeSocketAddress = (KLALBRemoteLine) link;
|
KLALBRemoteLink multipurposeSocketAddress = (KLALBRemoteLink) link;
|
||||||
if (multipurposeSocketAddress.getSocketAddress() != null)
|
if (multipurposeSocketAddress.getSocketAddress() != null)
|
||||||
st.add(multipurposeSocketAddress.getSocketAddress());
|
st.add(multipurposeSocketAddress.getSocketAddress());
|
||||||
}
|
}
|
||||||
@@ -206,8 +191,8 @@ public class KLALBController {
|
|||||||
}
|
}
|
||||||
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
||||||
IPv6NetworkLink link = iterator.next();
|
IPv6NetworkLink link = iterator.next();
|
||||||
if (link instanceof KLALBRemoteLine) {
|
if (link instanceof KLALBRemoteLink) {
|
||||||
KLALBRemoteLine reml = (KLALBRemoteLine) link;
|
KLALBRemoteLink reml = (KLALBRemoteLink) link;
|
||||||
if (reml.getSocketAddress() != null) {
|
if (reml.getSocketAddress() != null) {
|
||||||
if (reml.getBindAddress() != null || reml.getRemoteVaddr() != null)
|
if (reml.getBindAddress() != null || reml.getRemoteVaddr() != null)
|
||||||
try {
|
try {
|
||||||
@@ -237,6 +222,8 @@ public class KLALBController {
|
|||||||
|
|
||||||
updateBroadcastNetworkInterface();
|
updateBroadcastNetworkInterface();
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
|
}catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,21 +435,11 @@ public class KLALBController {
|
|||||||
return datagramSocketType;
|
return datagramSocketType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private Supplier<String> selflineTableSupplier=()->{return null;};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* public Supplier<String> getSelflineTableSupplier() { return
|
|
||||||
* selflineTableSupplier; }
|
|
||||||
*
|
|
||||||
* public void setSelflineTableSupplier(Supplier<String> selflineTableSupplier)
|
|
||||||
* { this.selflineTableSupplier = selflineTableSupplier; }
|
|
||||||
*/
|
|
||||||
|
|
||||||
public List<MultipurposeSocketAddress> getSelflineTable() {
|
public List<MultipurposeSocketAddress> getSelflineTable() {
|
||||||
return selflineTable;
|
return selflineTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private Inet6AddressGroup self;
|
|
||||||
|
|
||||||
public IPv6AddressGroup getSelf() {
|
public IPv6AddressGroup getSelf() {
|
||||||
return srv6Router.getLocator();
|
return srv6Router.getLocator();
|
||||||
@@ -474,30 +451,14 @@ public class KLALBController {
|
|||||||
return srv6Router.getLinkTabel();
|
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() {
|
public void reconnectImmediately() {
|
||||||
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
||||||
IPv6NetworkLink val = iterator.next();
|
IPv6NetworkLink val = iterator.next();
|
||||||
if (val instanceof KLALBRemoteLine) {
|
if (val instanceof KLALBRemoteLink) {
|
||||||
|
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) val;
|
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) val;
|
||||||
klalbRemoteLine.reconnectImmediately();
|
klalbRemoteLine.reconnectImmediately();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -510,34 +471,17 @@ public class KLALBController {
|
|||||||
private KLALBRoutingProtocolAPIClient apiClient;
|
private KLALBRoutingProtocolAPIClient apiClient;
|
||||||
|
|
||||||
private KLALBControllerConfigItem configItem;
|
private KLALBControllerConfigItem configItem;
|
||||||
|
|
||||||
/*
|
|
||||||
* private PacketReceiver prc = new PacketReceiver(); private class
|
|
||||||
* PacketReceiver implements Consumer<KLALBPacket> {
|
|
||||||
*
|
|
||||||
* @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<MultipurposeSocketAddress> select) {
|
public void addRemoteLines(List<MultipurposeSocketAddress> select) {
|
||||||
for (MultipurposeSocketAddress target : select) {
|
for (MultipurposeSocketAddress target : select) {
|
||||||
addRemoteLines(target);
|
addRemoteLines(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KLALBRemoteLine> addRemoteLines(MultipurposeSocketAddress target) {
|
public List<KLALBRemoteLink> addRemoteLines(MultipurposeSocketAddress target) {
|
||||||
lineslock.writeLock().lock();
|
lineslock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
List<KLALBRemoteLine> added = new ArrayList<>();
|
List<KLALBRemoteLink> added = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
Enumeration<NetworkInterface> eu = NetworkInterface.getNetworkInterfaces();
|
Enumeration<NetworkInterface> eu = NetworkInterface.getNetworkInterfaces();
|
||||||
while (eu.hasMoreElements()) {
|
while (eu.hasMoreElements()) {
|
||||||
@@ -583,7 +527,7 @@ public class KLALBController {
|
|||||||
count=1;
|
count=1;
|
||||||
}
|
}
|
||||||
for(int i=0;i<count;i++) {
|
for(int i=0;i<count;i++) {
|
||||||
KLALBRemoteLine line = new KLALBRemoteLine(this, target, bind);
|
KLALBRemoteLink line = new KLALBRemoteLink(this, target, bind);
|
||||||
addRemoteLine(line);
|
addRemoteLine(line);
|
||||||
added.add(line);
|
added.add(line);
|
||||||
}
|
}
|
||||||
@@ -596,7 +540,7 @@ public class KLALBController {
|
|||||||
}
|
}
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
if (!checkContainsTarget(target)) {
|
if (!checkContainsTarget(target)) {
|
||||||
KLALBRemoteLine line = new KLALBRemoteLine(this, target);
|
KLALBRemoteLink line = new KLALBRemoteLink(this, target);
|
||||||
addRemoteLine(line);
|
addRemoteLine(line);
|
||||||
added.add(line);
|
added.add(line);
|
||||||
}
|
}
|
||||||
@@ -609,13 +553,13 @@ public class KLALBController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KLALBRemoteLine> removeRemoteLines(MultipurposeSocketAddress mpsa) {
|
public List<KLALBRemoteLink> removeRemoteLines(MultipurposeSocketAddress mpsa) {
|
||||||
|
|
||||||
List<KLALBRemoteLine> rmved = new ArrayList<>();
|
List<KLALBRemoteLink> rmved = new ArrayList<>();
|
||||||
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
||||||
IPv6NetworkLink link = iterator.next();
|
IPv6NetworkLink link = iterator.next();
|
||||||
if (link instanceof KLALBRemoteLine) {
|
if (link instanceof KLALBRemoteLink) {
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link;
|
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
|
||||||
if (mpsa.equals(klalbRemoteLine.getSocketAddress())) {
|
if (mpsa.equals(klalbRemoteLine.getSocketAddress())) {
|
||||||
klalbRemoteLine.close();
|
klalbRemoteLine.close();
|
||||||
rmved.add(klalbRemoteLine);
|
rmved.add(klalbRemoteLine);
|
||||||
@@ -626,11 +570,11 @@ public class KLALBController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Inet6Address getRemoteVaddrBySocketAddress(MultipurposeSocketAddress target) throws SocketTimeoutException {
|
public Inet6Address getRemoteVaddrBySocketAddress(MultipurposeSocketAddress target) throws SocketTimeoutException {
|
||||||
KLALBRemoteLine kr = null;
|
KLALBRemoteLink kr = null;
|
||||||
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
||||||
IPv6NetworkLink link = iterator.next();
|
IPv6NetworkLink link = iterator.next();
|
||||||
if (link instanceof KLALBRemoteLine) {
|
if (link instanceof KLALBRemoteLink) {
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link;
|
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
|
||||||
if (target.equals(klalbRemoteLine.getSocketAddress()) && klalbRemoteLine.getBindAddress() == null) {
|
if (target.equals(klalbRemoteLine.getSocketAddress()) && klalbRemoteLine.getBindAddress() == null) {
|
||||||
kr = klalbRemoteLine;
|
kr = klalbRemoteLine;
|
||||||
break;
|
break;
|
||||||
@@ -639,7 +583,7 @@ public class KLALBController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kr == null) {
|
if (kr == null) {
|
||||||
kr = new KLALBRemoteLine(this, target);
|
kr = new KLALBRemoteLink(this, target);
|
||||||
addRemoteLine(kr);
|
addRemoteLine(kr);
|
||||||
kr.waitForRemoteVaddrAvaliable(20000);
|
kr.waitForRemoteVaddrAvaliable(20000);
|
||||||
} else {
|
} else {
|
||||||
@@ -653,8 +597,8 @@ public class KLALBController {
|
|||||||
boolean b = false;
|
boolean b = false;
|
||||||
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
||||||
IPv6NetworkLink link = iterator.next();
|
IPv6NetworkLink link = iterator.next();
|
||||||
if (link instanceof KLALBRemoteLine) {
|
if (link instanceof KLALBRemoteLink) {
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link;
|
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
|
||||||
if (bind.equals2(klalbRemoteLine.getBindAddress())
|
if (bind.equals2(klalbRemoteLine.getBindAddress())
|
||||||
&& target.equals2(klalbRemoteLine.getSocketAddress())) {
|
&& target.equals2(klalbRemoteLine.getSocketAddress())) {
|
||||||
b = true;
|
b = true;
|
||||||
@@ -669,8 +613,8 @@ public class KLALBController {
|
|||||||
boolean b = false;
|
boolean b = false;
|
||||||
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
|
||||||
IPv6NetworkLink link = iterator.next();
|
IPv6NetworkLink link = iterator.next();
|
||||||
if (link instanceof KLALBRemoteLine) {
|
if (link instanceof KLALBRemoteLink) {
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link;
|
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
|
||||||
if (target.equals(klalbRemoteLine.getSocketAddress())) {
|
if (target.equals(klalbRemoteLine.getSocketAddress())) {
|
||||||
b = true;
|
b = true;
|
||||||
break;
|
break;
|
||||||
@@ -680,12 +624,9 @@ public class KLALBController {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRemoteLine(KLALBRemoteLine krs) {
|
public void addRemoteLine(KLALBRemoteLink krs) {
|
||||||
lineslock.writeLock().lock();
|
lineslock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
krs.setLocalVaddrSupplier(() -> {
|
|
||||||
return getSelf();
|
|
||||||
});
|
|
||||||
krs.startIO();
|
krs.startIO();
|
||||||
String selflineTable = generateSelfLineTable();
|
String selflineTable = generateSelfLineTable();
|
||||||
if (selflineTable != null && !selflineTable.equals(""))
|
if (selflineTable != null && !selflineTable.equals(""))
|
||||||
@@ -706,63 +647,26 @@ public class KLALBController {
|
|||||||
return sbd.toString();
|
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
|
private PortBinder rawPortBinder ;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
protected PortBinder getRawPortBinder() {
|
||||||
|
return rawPortBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadSRv6ProtocolStack(IPv6AddressGroup selfx, boolean enableVirtualAdapter) {
|
private void loadSRv6ProtocolStack(IPv6AddressGroup selfx, boolean enableVirtualAdapter) {
|
||||||
srv6Router = new SRv6Router(selfx, clock);
|
srv6Router = new SRv6Router(selfx, clock);
|
||||||
srv6Router.runKLALBRouteProtocol();
|
srv6Router.runKLALBRouteProtocol();
|
||||||
@@ -770,11 +674,12 @@ public class KLALBController {
|
|||||||
routingProtocol.addReceiver((addr, packet) -> {
|
routingProtocol.addReceiver((addr, packet) -> {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
rawPortBinder= new PortBinder(this.getSelf().getAddress());
|
||||||
System.out.println(" Loaded: SRv6 Stack");
|
System.out.println(" Loaded: SRv6 Stack");
|
||||||
|
|
||||||
String name=(configItem!=null)?configItem.getTUNName():CONST.KLALB_S_RV6;
|
String name=(configItem!=null)?configItem.getTUNName():CONST.KLALB_S_RV6;
|
||||||
if (enableVirtualAdapter&&(name!=null)) {
|
if (enableVirtualAdapter&&(name!=null)) {
|
||||||
|
Thread t=new Thread(()->{
|
||||||
try {
|
try {
|
||||||
IPv6TUNLoopbackNetworkLink tunlink = new IPv6TUNLoopbackNetworkLink(name,
|
IPv6TUNLoopbackNetworkLink tunlink = new IPv6TUNLoopbackNetworkLink(name,
|
||||||
new IPv6AddressGroup(srv6Router.getLocator().getAddress(), 32), SRv6Router.MTU, dnsAddresses);
|
new IPv6AddressGroup(srv6Router.getLocator().getAddress(), 32), SRv6Router.MTU, dnsAddresses);
|
||||||
@@ -787,18 +692,23 @@ public class KLALBController {
|
|||||||
System.err.println("挂载虚拟网卡失败,可能是无管理员权限?请尝试使用管理员权限运行软件");
|
System.err.println("挂载虚拟网卡失败,可能是无管理员权限?请尝试使用管理员权限运行软件");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
t.start();
|
||||||
}else {
|
}else {
|
||||||
System.out.println(" Tun Adapter Disbaled");
|
System.out.println(" Tun Adapter Disbaled");
|
||||||
|
|
||||||
}
|
}
|
||||||
srv6Router.getinLoopback().getProtocolNumberRegister().put(UDPPacket.UDP_PROTOCOL_NUMBER,
|
udpr=new UDPProtocolRegister(this);
|
||||||
new UDPProtocolPacketConsumer());
|
srv6Router.getinLoopback().getProtocolNumberRegister()[UDPPacket.UDP_PROTOCOL_NUMBER]=
|
||||||
|
udpr;
|
||||||
System.out.println(" Loaded: UDP Protocol");
|
System.out.println(" Loaded: UDP Protocol");
|
||||||
srv6Router.getinLoopback().getProtocolNumberRegister().put(KLALBPacket.KLALB_PROTOCOL_NUMBER,
|
kltpr=new KLTPProtocolRegister(this);
|
||||||
new KLALBProtocolPacketConsumer());
|
srv6Router.getinLoopback().getProtocolNumberRegister()[KLTPPacket.KLTP_PROTOCOL_NUMBER]=
|
||||||
System.out.println(" Loaded: KLALB Protocol");
|
kltpr;
|
||||||
|
System.out.println(" Loaded: KLTP Protocol");
|
||||||
String iproxyname = "KLALB_" + UUID.randomUUID();
|
String iproxyname = "KLALB_" + UUID.randomUUID();
|
||||||
registerToProxyTypeAs(iproxyname);
|
registerToProxyTypeAs(iproxyname);
|
||||||
|
System.out.println(" Loaded: KLALB Protocol");
|
||||||
|
|
||||||
NTPContext context = new NTPContext(clock);
|
NTPContext context = new NTPContext(clock);
|
||||||
context.syncToSystem();
|
context.syncToSystem();
|
||||||
@@ -812,7 +722,6 @@ public class KLALBController {
|
|||||||
public void onLinkChanged(SRv6Router router, IPv6NetworkLink link) {
|
public void onLinkChanged(SRv6Router router, IPv6NetworkLink link) {
|
||||||
|
|
||||||
List<Neighbor> nb = router.getNeighbors();
|
List<Neighbor> nb = router.getNeighbors();
|
||||||
// System.out.println("srv6 ip"+nb);
|
|
||||||
Set<NTPPeer> sp = nvc.getPeers();
|
Set<NTPPeer> sp = nvc.getPeers();
|
||||||
for (Neighbor neighbor : nb) {
|
for (Neighbor neighbor : nb) {
|
||||||
if (neighbor.getLocator() != null)
|
if (neighbor.getLocator() != null)
|
||||||
@@ -873,6 +782,17 @@ public class KLALBController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void initKLALB(boolean enableVirtualAdapter, IPv6AddressGroup selfg) {
|
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);
|
loadSRv6ProtocolStack(selfg, enableVirtualAdapter);
|
||||||
loadController();
|
loadController();
|
||||||
}
|
}
|
||||||
@@ -973,7 +893,7 @@ public class KLALBController {
|
|||||||
public void run() {
|
public void run() {
|
||||||
if (srv6Router != null) {
|
if (srv6Router != null) {
|
||||||
srv6Router.getLinkTabel().removeIf((v) -> {
|
srv6Router.getLinkTabel().removeIf((v) -> {
|
||||||
return (v instanceof KLALBRemoteLine) && ((KLALBRemoteLine) v).isClosed();
|
return (v instanceof KLALBRemoteLink) && ((KLALBRemoteLink) v).isClosed();
|
||||||
});
|
});
|
||||||
srv6Router.updateRouteTabel();
|
srv6Router.updateRouteTabel();
|
||||||
}
|
}
|
||||||
@@ -992,13 +912,12 @@ public class KLALBController {
|
|||||||
}, 10, 10);
|
}, 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);
|
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) {
|
int count) {
|
||||||
// HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
|
||||||
|
|
||||||
IPv6Packet ipv = new IPv6Packet();
|
IPv6Packet ipv = new IPv6Packet();
|
||||||
|
|
||||||
@@ -1006,23 +925,17 @@ public class KLALBController {
|
|||||||
System.out.println("KLALB_TX:" + packet);
|
System.out.println("KLALB_TX:" + packet);
|
||||||
|
|
||||||
ipv.setVersion(6);
|
ipv.setVersion(6);
|
||||||
ipv.setTrafficClass(0);
|
ipv.setTrafficClass(0b10);
|
||||||
ipv.setFlowLabel(flowlabel);
|
ipv.setFlowLabel(flowlabel);
|
||||||
ipv.setHopLimit(255);
|
ipv.setHopLimit(255);
|
||||||
ipv.setSourceAddress(getSelf().getAddress());
|
ipv.setSourceAddress(getSelf().getAddress());
|
||||||
ipv.setDestinationAddress(addr);
|
ipv.setDestinationAddress(addr);
|
||||||
|
|
||||||
ipv.enableECN();
|
|
||||||
|
|
||||||
ipv.setPayload(packet);
|
ipv.setPayload(packet);
|
||||||
packet.setParent(ipv);
|
packet.setParent(ipv);
|
||||||
|
|
||||||
if (packet instanceof KLALBPacket)
|
|
||||||
((KLALBPacket) packet).incSendCounter();
|
|
||||||
|
|
||||||
packet.putTimePassport("packedInIPv6");
|
|
||||||
packet.printPassport();
|
|
||||||
ipv.putTimePassport("packed");
|
|
||||||
return ipv;
|
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<MultipurposeSocketAddress> listens = new CopyOnWriteArrayList<>();
|
private List<MultipurposeSocketAddress> listens = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
public Timer getNagleTimer() {
|
|
||||||
return t2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerToProxyTypeAs(String proxyname) {
|
public void registerToProxyTypeAs(String proxyname) {
|
||||||
MultipurposeSocketAddress.getSocketTypeRegister().put(proxyname + "_Stream", streamSocketType);
|
MultipurposeSocketAddress.getSocketTypeRegister().put(proxyname + "_Stream", streamSocketType);
|
||||||
@@ -1117,34 +1022,15 @@ public class KLALBController {
|
|||||||
private KLALBRoutingProtocol routingProtocol;
|
private KLALBRoutingProtocol routingProtocol;
|
||||||
|
|
||||||
public List<MultipurposeSocketAddress> getNTPTable() {
|
public List<MultipurposeSocketAddress> getNTPTable() {
|
||||||
return ntptable;// nvc2.getPeers().add(new NTPPeer("{UDP}106.55.184.199:123",
|
return ntptable;
|
||||||
// NTPv4Packet.NTP_CLIENT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLALBControllerConfigItem getConfigItem() {
|
public KLALBControllerConfigItem getConfigItem() {
|
||||||
return configItem;
|
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
|
|
||||||
* 自动生成的方法存根
|
|
||||||
*
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
|
|
||||||
public class KLALBControllerConfigItem extends KLALBConfigItem {
|
public class KLALBControllerConfigItem extends KLALBConfigItem {
|
||||||
private String language;
|
private String language;
|
||||||
private boolean nogui;
|
private boolean nogui;
|
||||||
@@ -26,6 +21,7 @@ public class KLALBControllerConfigItem extends KLALBConfigItem {
|
|||||||
private boolean denyLineTableQuery=false;
|
private boolean denyLineTableQuery=false;
|
||||||
private boolean denyLineTableBroadcast=false;
|
private boolean denyLineTableBroadcast=false;
|
||||||
private String congestionAlgorithm="BBR";
|
private String congestionAlgorithm="BBR";
|
||||||
|
private double burstLimit=1.20;
|
||||||
private double delayUpperBound=1.20;
|
private double delayUpperBound=1.20;
|
||||||
private double delayLowerBound=1.15;
|
private double delayLowerBound=1.15;
|
||||||
private long nagleDelayTime=1000000L;
|
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() {
|
public double getDelayUpperBound() {
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
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.DataInputStream;
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StreamCorruptedException;
|
import java.io.StreamCorruptedException;
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
@@ -24,7 +20,7 @@ public class KLALBInputStream extends DataInputStream {
|
|||||||
readFully(b);
|
readFully(b);
|
||||||
String s=new String(b,"ascii");
|
String s=new String(b,"ascii");
|
||||||
if(!s.equals("KLALB")) {
|
if(!s.equals("KLALB")) {
|
||||||
throw new StreamCorruptedException("no KLALB format");
|
throw new StreamCorruptedException("remote protocol is no KLALB format");
|
||||||
}
|
}
|
||||||
int bv=readInt();
|
int bv=readInt();
|
||||||
int mv=readInt();
|
int mv=readInt();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.channels.ServerSocketChannel;
|
import java.nio.channels.ServerSocketChannel;
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -12,20 +11,17 @@ import java.util.List;
|
|||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
|
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.SocketChannelListener;
|
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.IPv6NetworkLink;
|
||||||
import org.kne.cloud.network.ipv6.RouteItem;
|
import org.kne.cloud.network.ipv6.RouteItem;
|
||||||
import org.kne.cloud.network.klalb.ui.KLALBStateGUI3;
|
import org.kne.cloud.network.klalb.ui.KLALBStateGUI3;
|
||||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||||
import org.kne.cloud.network.perf.Kperf;
|
import org.kne.cloud.network.perf.Kperf;
|
||||||
import org.kne.cloud.network.perf.NodeBenchmark;
|
import org.kne.cloud.network.perf.NodeBenchmark;
|
||||||
import org.kne.debug.Debuger;
|
|
||||||
import org.kne.debug.TimeDebugger;
|
import org.kne.debug.TimeDebugger;
|
||||||
import org.kne.membandboost.MembandBenchmark;
|
import org.kne.membandboost.MembandBenchmark;
|
||||||
|
import org.kne.membandboost.ObjectPoolBandwidthTest;
|
||||||
|
|
||||||
public class KLALBMain {
|
public class KLALBMain {
|
||||||
public static KLALBStateGUI3 ksg;
|
public static KLALBStateGUI3 ksg;
|
||||||
@@ -90,8 +86,9 @@ public class KLALBMain {
|
|||||||
System.out.println(" links-add <addr:port>: add link");
|
System.out.println(" links-add <addr:port>: add link");
|
||||||
System.out.println(" links-remove <addr:port>: remove link");
|
System.out.println(" links-remove <addr:port>: remove link");
|
||||||
System.out.println(" links-reconnect: reconnect all 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(" route: display internal route table");
|
||||||
System.out.println(" kperf <addr:port>: Porformance benchmark");
|
System.out.println(" kperf <addr:port>: performance benchmark");
|
||||||
System.out.println(" exit: Exit");
|
System.out.println(" exit: Exit");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -104,12 +101,13 @@ public class KLALBMain {
|
|||||||
break;
|
break;
|
||||||
case "links-state":
|
case "links-state":
|
||||||
System.out.println("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()) {
|
synchronized (kpcje.getKlalbController().getLines()) {
|
||||||
for (Iterator<IPv6NetworkLink> iterator = kpcje.getKlalbController().getLines().iterator(); iterator.hasNext();) {
|
for (Iterator<IPv6NetworkLink> iterator = kpcje.getKlalbController().getLines().iterator(); iterator.hasNext();) {
|
||||||
IPv6NetworkLink link=iterator.next();
|
IPv6NetworkLink link=iterator.next();
|
||||||
if(link instanceof KLALBRemoteLine) {
|
if(link instanceof KLALBRemoteLink) {
|
||||||
KLALBRemoteLine hostPort = (KLALBRemoteLine) link;
|
KLALBRemoteLink hostPort = (KLALBRemoteLink) link;
|
||||||
System.out.println(hostPort .toString());
|
System.out.println(hostPort .toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,31 +116,34 @@ public class KLALBMain {
|
|||||||
case "links-add":
|
case "links-add":
|
||||||
if(sc.length>=2) {
|
if(sc.length>=2) {
|
||||||
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(sc[1]);
|
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(sc[1]);
|
||||||
List<KLALBRemoteLine>addl=kpcje.getKlalbController().addRemoteLines(mpsa);
|
List<KLALBRemoteLink>addl=kpcje.getKlalbController().addRemoteLines(mpsa);
|
||||||
if(addl.isEmpty()) {
|
if(addl.isEmpty()) {
|
||||||
System.out.println("添加失败,线路已存在!");
|
//System.out.println("添加失败,线路已存在!");
|
||||||
|
System.out.println("link already exist!");
|
||||||
}else {
|
}else {
|
||||||
for (Iterator<KLALBRemoteLine> iterator = addl.iterator(); iterator.hasNext();) {
|
for (Iterator<KLALBRemoteLink> iterator = addl.iterator(); iterator.hasNext();) {
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
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 {
|
}else {
|
||||||
System.out.println("请输入要添加地址:端口!");
|
// System.out.println("请输入要添加地址:端口!");
|
||||||
|
System.out.println("Input Address:port");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "links-remove":
|
case "links-remove":
|
||||||
if(sc.length>=2) {
|
if(sc.length>=2) {
|
||||||
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(sc[1]);
|
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(sc[1]);
|
||||||
List<KLALBRemoteLine>rmvl=kpcje.getKlalbController().removeRemoteLines(mpsa);
|
List<KLALBRemoteLink>rmvl=kpcje.getKlalbController().removeRemoteLines(mpsa);
|
||||||
if(rmvl.isEmpty()) {
|
if(rmvl.isEmpty()) {
|
||||||
System.out.println("No matched link has been found.");
|
System.out.println("No matched link has been found.");
|
||||||
}else {
|
}else {
|
||||||
for (Iterator iterator = rmvl.iterator(); iterator.hasNext();) {
|
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 {
|
}else {
|
||||||
@@ -157,6 +158,9 @@ public class KLALBMain {
|
|||||||
System.out.println("Trying to reconnect all links.");
|
System.out.println("Trying to reconnect all links.");
|
||||||
kpcje.getKlalbController().reconnectImmediately();
|
kpcje.getKlalbController().reconnectImmediately();
|
||||||
break;
|
break;
|
||||||
|
case "kltp-state":
|
||||||
|
System.out.println(kpcje.getKlalbController().getKLTPregister().toString());
|
||||||
|
break;
|
||||||
case "route":
|
case "route":
|
||||||
List<RouteItem> lri=new ArrayList<>( kpcje.getKlalbController().getIpv6Router().getCurrentRouteTabel());
|
List<RouteItem> lri=new ArrayList<>( kpcje.getKlalbController().getIpv6Router().getCurrentRouteTabel());
|
||||||
Collections.sort(lri);
|
Collections.sort(lri);
|
||||||
@@ -178,9 +182,13 @@ public class KLALBMain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "memcpy":
|
case "membandbenchmark":
|
||||||
MembandBenchmark.main(args);
|
MembandBenchmark.main(args);
|
||||||
break;
|
break;
|
||||||
|
case "memqueuebenchmark":
|
||||||
|
|
||||||
|
ObjectPoolBandwidthTest.main(args);
|
||||||
|
break;
|
||||||
//case "$$SYSTEM:":
|
//case "$$SYSTEM:":
|
||||||
//System.out.println();
|
//System.out.println();
|
||||||
//break;
|
//break;
|
||||||
|
|||||||
@@ -9,10 +9,6 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.nio.channels.WritableByteChannel;
|
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.NetworkPacket;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||||
@@ -52,13 +48,13 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
|||||||
protected ByteBuffer klalbHeader;
|
protected ByteBuffer klalbHeader;
|
||||||
|
|
||||||
protected KLALBPacket(ByteBuffer klalbHeader,int headerLength) {
|
protected KLALBPacket(ByteBuffer klalbHeader,int headerLength) {
|
||||||
super(KLALB_PROTOCOL_NUMBER,false);
|
super(KLALB_PROTOCOL_NUMBER);
|
||||||
this.klalbHeader = klalbHeader;
|
this.klalbHeader = klalbHeader;
|
||||||
this.headerLength=headerLength;
|
this.headerLength=headerLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLALBPacket(int type,int headerLength) {
|
public KLALBPacket(int type,int headerLength) {
|
||||||
super(KLALB_PROTOCOL_NUMBER,false);
|
super(KLALB_PROTOCOL_NUMBER);
|
||||||
klalbHeader=NetworkPacket.bufferAllocator.allocate(headerLength);
|
klalbHeader=NetworkPacket.bufferAllocator.allocate(headerLength);
|
||||||
klalbHeader.put((byte) type);
|
klalbHeader.put((byte) type);
|
||||||
this.headerLength=headerLength;
|
this.headerLength=headerLength;
|
||||||
@@ -113,24 +109,6 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
|||||||
return headerLength;
|
return headerLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//private List<KLALBRemoteLine> sendRecord=new ArrayList<>(2);
|
|
||||||
|
|
||||||
private AtomicInteger sendCounter=new AtomicInteger(0);
|
|
||||||
|
|
||||||
public int getSendCounter() {
|
|
||||||
return sendCounter.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incSendCounter() {
|
|
||||||
sendCounter.incrementAndGet();
|
|
||||||
}
|
|
||||||
/*public List<KLALBRemoteLine> getSendRecord() {
|
|
||||||
return sendRecord;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
protected ByteBuffer getKLALBHeader() {
|
protected ByteBuffer getKLALBHeader() {
|
||||||
return klalbHeader;
|
return klalbHeader;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ public class KLALBProtocolDetectSocketListener extends SocketListener {
|
|||||||
super.setCon((soc)->{
|
super.setCon((soc)->{
|
||||||
ProtocolDetectorSocket pds=(ProtocolDetectorSocket) soc;
|
ProtocolDetectorSocket pds=(ProtocolDetectorSocket) soc;
|
||||||
if(!pds.getProtocolStack().isEmpty()&&pds.getProtocolStack().pop().getName().equals("KLALB")) {
|
if(!pds.getProtocolStack().isEmpty()&&pds.getProtocolStack().pop().getName().equals("KLALB")) {
|
||||||
KLALBRemoteLine krs=null;
|
KLALBRemoteLink krs=null;
|
||||||
try {
|
try {
|
||||||
krs = new KLALBRemoteLine(klalbController,new StreamKLALBPacketLink(pds));
|
krs = new KLALBRemoteLink(klalbController,new StreamKLALBPacketLink(pds));
|
||||||
klalbController.addRemoteLine(krs);
|
klalbController.addRemoteLine(krs);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -5,39 +5,20 @@ import java.io.FileReader;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
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.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.*;
|
||||||
import org.kne.cloud.network.klalb.ui.KLALBStateGUI3;
|
import org.kne.cloud.network.klalb.ui.KLALBStateGUI3;
|
||||||
import org.kne.cloud.network.klalb.ui.Language;
|
import org.kne.cloud.network.klalb.ui.Language;
|
||||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||||
import org.kne.cloud.network.minecraft.MinecraftSocketBridge;
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
|
|
||||||
public class KLALBProxySystem {
|
public class KLALBProxySystem {
|
||||||
private Set<Proxy> proxys=new HashSet<>();
|
private Set<Proxy> proxys=new HashSet<>();
|
||||||
@@ -158,9 +139,9 @@ public class KLALBProxySystem {
|
|||||||
|
|
||||||
tcpl.setCon((soc)->{
|
tcpl.setCon((soc)->{
|
||||||
|
|
||||||
KLALBRemoteLine krs=null;
|
KLALBRemoteLink krs=null;
|
||||||
try {
|
try {
|
||||||
krs = new KLALBRemoteLine(klalbController,new StreamChannelKLALBPacketLink(soc));
|
krs = new KLALBRemoteLink(klalbController,new StreamChannelKLALBPacketLink(soc));
|
||||||
klalbController.addRemoteLine(krs);
|
klalbController.addRemoteLine(krs);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -181,9 +162,9 @@ public class KLALBProxySystem {
|
|||||||
|
|
||||||
udpl.setCon((soc)->{
|
udpl.setCon((soc)->{
|
||||||
|
|
||||||
KLALBRemoteLine krs=null;
|
KLALBRemoteLink krs=null;
|
||||||
try {
|
try {
|
||||||
krs = new KLALBRemoteLine(klalbController,new SplitedDatagramKLALBPacketLink(soc));
|
krs = new KLALBRemoteLink(klalbController,new SplitedDatagramKLALBPacketLink(soc));
|
||||||
klalbController.addRemoteLine(krs);
|
klalbController.addRemoteLine(krs);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+192
-152
@@ -1,80 +1,55 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
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.IOException;
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.io.StreamCorruptedException;
|
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.SocketTimeoutException;
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.nio.channels.UnresolvedAddressException;
|
import java.nio.channels.UnresolvedAddressException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.UUID;
|
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.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
|
||||||
import java.util.concurrent.locks.Condition;
|
import java.util.concurrent.locks.Condition;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
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.Consumer;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
|
import org.jctools.queues.MpscArrayQueue;
|
||||||
import org.kne.cloud.clock.HighAccuracyClock;
|
import org.kne.cloud.clock.HighAccuracyClock;
|
||||||
import org.kne.cloud.clock.NTPTimestamps;
|
import org.kne.cloud.clock.NTPTimestamps;
|
||||||
import org.kne.cloud.clock.ReliabilityBackoffTimeClock;
|
import org.kne.cloud.clock.ReliabilityBackoffTimeClock;
|
||||||
import org.kne.cloud.clock.WatchDogTimer;
|
import org.kne.cloud.clock.WatchDogTimer;
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.SpeedLimiter;
|
|
||||||
import org.kne.cloud.network.ThreadTool;
|
import org.kne.cloud.network.ThreadTool;
|
||||||
import org.kne.cloud.network.congestion.BBRCongestionAlgorithm;
|
import org.kne.cloud.network.congestion.BBRCongestionAlgorithm;
|
||||||
import org.kne.cloud.network.congestion.CongestionAlgorithm;
|
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.DetnetCongestionAlgorithm;
|
||||||
import org.kne.cloud.network.congestion.SendPacketSlidingWindow;
|
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.ControlledIPv6NetworkLink;
|
||||||
import org.kne.cloud.network.ipv6.ICMPv6PostcardPacket;
|
|
||||||
import org.kne.cloud.network.ipv6.IPv6Address;
|
import org.kne.cloud.network.ipv6.IPv6Address;
|
||||||
import org.kne.cloud.network.ipv6.IPv6HopByHopTLV;
|
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;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6EmptyPayload;
|
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6HopByHopHeader;
|
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.IPv6AddressGroup;
|
||||||
import org.kne.cloud.network.ipv6.KLALBOAMHopByHopTLV;
|
import org.kne.cloud.network.ipv6.KLALBOAMHopByHopTLV;
|
||||||
import org.kne.cloud.network.ipv6.KLALBPassportHopByHopTLV;
|
import org.kne.cloud.network.ipv6.KLALBPassportHopByHopTLV;
|
||||||
import org.kne.cloud.network.ipv6.Neighbor;
|
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.PostcardEntry;
|
||||||
import org.kne.cloud.network.ipv6.RouteItem;
|
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.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||||
import org.kne.cloud.network.perf.TESTNPacket;
|
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.cloud.network.te.BandwidthDistributer;
|
||||||
import org.kne.concurrent.HighPerformanceExecutor;
|
|
||||||
import org.kne.concurrent.SpinLock;
|
import org.kne.concurrent.SpinLock;
|
||||||
import org.kne.concurrent.ThreadParker;
|
import org.kne.concurrent.ThreadParker;
|
||||||
import org.kne.math.Long128;
|
import org.kne.math.Long128;
|
||||||
|
|
||||||
import com.github.f4b6a3.uuid.UuidCreator;
|
public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implements ControlledIPv6NetworkLink {
|
||||||
|
|
||||||
public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implements ControlledIPv6NetworkLink {
|
|
||||||
|
|
||||||
private static final int HEADER_CALIBRATE = 40;
|
private static final int HEADER_CALIBRATE = 40;
|
||||||
|
|
||||||
@@ -84,8 +59,6 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
|
|
||||||
private volatile boolean closed = false;
|
private volatile boolean closed = false;
|
||||||
|
|
||||||
private volatile Supplier<IPv6AddressGroup> localVaddrSupplier;
|
|
||||||
|
|
||||||
private volatile KLALBController klalbController;
|
private volatile KLALBController klalbController;
|
||||||
|
|
||||||
public KLALBController getKlalbController() {
|
public KLALBController getKlalbController() {
|
||||||
@@ -93,14 +66,6 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Supplier<IPv6AddressGroup> getLocalVaddrSupplier() {
|
|
||||||
return localVaddrSupplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocalVaddrSupplier(Supplier<IPv6AddressGroup> localVaddrSupplier) {
|
|
||||||
this.localVaddrSupplier = localVaddrSupplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
private volatile IPv6AddressGroup remoteVaddr;
|
private volatile IPv6AddressGroup remoteVaddr;
|
||||||
|
|
||||||
public IPv6AddressGroup getRemoteVaddr() {
|
public IPv6AddressGroup getRemoteVaddr() {
|
||||||
@@ -128,9 +93,11 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
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 SpeedAndTrafficAndDelayMonitorDataImpl monitor;
|
||||||
private volatile KLALBPacketLink kplink;
|
private volatile KLALBPacketLink kplink;
|
||||||
private MultipurposeSocketAddress bindAddress;
|
private MultipurposeSocketAddress bindAddress;
|
||||||
@@ -167,20 +134,20 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
return peerAddress;
|
return peerAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLALBRemoteLine(KLALBController controller, MultipurposeSocketAddress mpa, IPv6AddressGroup address) {
|
public KLALBRemoteLink(KLALBController controller, MultipurposeSocketAddress mpa, IPv6AddressGroup address) {
|
||||||
this(controller,mpa, null,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;
|
this.klalbController=controller;
|
||||||
sysclk = klalbController.getClock();
|
sysclk = klalbController.getClock();
|
||||||
this.kplink = kpl;
|
this.kplink = kpl;
|
||||||
this.addressGroup = address;
|
this.addressGroup = address;
|
||||||
monitor=new SpeedAndTrafficAndDelayMonitorDataImpl(sysclk);
|
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;
|
this.klalbController=controller;
|
||||||
sysclk = klalbController.getClock();
|
sysclk = klalbController.getClock();
|
||||||
this.socketAddress = mpa;
|
this.socketAddress = mpa;
|
||||||
@@ -188,22 +155,22 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
this.addressGroup = address;
|
this.addressGroup = address;
|
||||||
monitor=new SpeedAndTrafficAndDelayMonitorDataImpl(sysclk);
|
monitor=new SpeedAndTrafficAndDelayMonitorDataImpl(sysclk);
|
||||||
if (bindaddr == null) {
|
if (bindaddr == null) {
|
||||||
monitor.setName("→" + mpa.toString());
|
name="→" + mpa.toString();
|
||||||
} else {
|
} 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);
|
this(controller,mpa, bind, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLALBRemoteLine(KLALBController controller,MultipurposeSocketAddress mpa) {
|
public KLALBRemoteLink(KLALBController controller,MultipurposeSocketAddress mpa) {
|
||||||
this(controller,mpa, (IPv6AddressGroup) null);
|
this(controller,mpa, (IPv6AddressGroup) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLALBRemoteLine(KLALBController controller,KLALBPacketLink link) {
|
public KLALBRemoteLink(KLALBController controller,KLALBPacketLink link) {
|
||||||
this(controller,link, (IPv6AddressGroup) null);
|
this(controller,link, (IPv6AddressGroup) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,10 +183,8 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
|
|
||||||
|
|
||||||
private class RemoteSender implements Runnable {
|
private class RemoteSender implements Runnable {
|
||||||
|
|
||||||
private SpeedLimiter speedLimit = new SpeedLimiter(256 * 1024L, 10 * 1000000L);// 50*1000000L
|
|
||||||
|
|
||||||
private ConcurrentLinkedQueue<KLALBPacket> sendQueue = new ConcurrentLinkedQueue<KLALBPacket>();
|
private MpscArrayQueue<KLALBPacket> sendQueue = new MpscArrayQueue<KLALBPacket>(8192);
|
||||||
private WatchDogTimer watchdog = new WatchDogTimer(400000000L);
|
private WatchDogTimer watchdog = new WatchDogTimer(400000000L);
|
||||||
|
|
||||||
private ThreadParker tlock = new ThreadParker();
|
private ThreadParker tlock = new ThreadParker();
|
||||||
@@ -227,6 +192,8 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
private volatile long time = System.nanoTime();
|
private volatile long time = System.nanoTime();
|
||||||
private volatile long pingInterval = 100000000L;
|
private volatile long pingInterval = 100000000L;
|
||||||
|
|
||||||
|
private Lock sendLock=new SpinLock();
|
||||||
|
|
||||||
private boolean checkPingTime() {
|
private boolean checkPingTime() {
|
||||||
long cu = System.nanoTime();
|
long cu = System.nanoTime();
|
||||||
if (cu - time > pingInterval) {
|
if (cu - time > pingInterval) {
|
||||||
@@ -239,7 +206,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ConcurrentLinkedQueue<KLALBPacket> getSendQueue() {
|
public Queue<KLALBPacket> getSendQueue() {
|
||||||
return sendQueue;
|
return sendQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,8 +242,8 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
}
|
}
|
||||||
writeKLALBPacketToKPL(new VADDRREQPacket());
|
writeKLALBPacketToKPL(new VADDRREQPacket());
|
||||||
writeKLALBPacketToKPL(new VADDRREQPacket());
|
writeKLALBPacketToKPL(new VADDRREQPacket());
|
||||||
writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
writeKLALBPacketToKPL(new VADDRPacket(klalbController.getSelf()));
|
||||||
writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
writeKLALBPacketToKPL(new VADDRPacket(klalbController.getSelf()));
|
||||||
kplink.flush();
|
kplink.flush();
|
||||||
while ((!kplink.isClosed()) && (!closed)) {
|
while ((!kplink.isClosed()) && (!closed)) {
|
||||||
if (checkPingTime()) {
|
if (checkPingTime()) {
|
||||||
@@ -286,22 +253,38 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
if (peerAddress == null)
|
if (peerAddress == null)
|
||||||
sendPacket(new ADDRREQPacket());
|
sendPacket(new ADDRREQPacket());
|
||||||
|
|
||||||
}
|
}/*sendLock.lock();
|
||||||
KLALBPacket tkpp = sendQueue.poll();
|
int n;
|
||||||
|
try {
|
||||||
if (tkpp != null) {
|
n = sendQueue.drain((tkpp)->{
|
||||||
kplink.writeKLALBPacket(tkpp);
|
|
||||||
watchdog.feed();
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
kplink.writeKLALBPacket(tkpp);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
},100);
|
||||||
|
}finally {
|
||||||
|
sendLock.unlock();
|
||||||
|
}
|
||||||
|
if (n>0) {
|
||||||
|
watchdog.feed();
|
||||||
} else {
|
} else {
|
||||||
tlock.parkNanos(1000000L);
|
tlock.parkNanos(1000000L);
|
||||||
}
|
}*/
|
||||||
long curr=System.nanoTime();
|
long curr=System.nanoTime();
|
||||||
if(curr-flushTime>=flushInterval) {
|
if(curr-flushTime>=flushInterval) {
|
||||||
flushTime=curr;
|
flushTime=curr;
|
||||||
|
sendLock.lock();
|
||||||
|
try {
|
||||||
kplink.flush();
|
kplink.flush();
|
||||||
|
watchdog.feed();
|
||||||
|
}finally {
|
||||||
|
sendLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Thread.yield();
|
tlock.parkNanos(1000000L);
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (StreamCorruptedException sce) {
|
} catch (StreamCorruptedException sce) {
|
||||||
sce.printStackTrace();
|
sce.printStackTrace();
|
||||||
@@ -323,10 +306,39 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
boolean b=sendQueue.add(blk);
|
boolean b=sendQueue.add(blk);
|
||||||
if(b) {
|
if(b) {
|
||||||
tlock.unpark();
|
tlock.unpark();
|
||||||
speedLimit.forceTransmit(blk.getTotalLength());
|
|
||||||
}
|
}
|
||||||
return b;
|
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 WatchDogTimer watchdog = new WatchDogTimer(400000000L);
|
||||||
private long rtt=Long.MAX_VALUE/1024;
|
private long rtt=Long.MAX_VALUE/1024;
|
||||||
|
private long rttMin=Long.MAX_VALUE/1024;
|
||||||
AtomicBoolean fst = new AtomicBoolean(true);
|
AtomicBoolean fst = new AtomicBoolean(true);
|
||||||
//ReentrantLock readLock = new ReentrantLock();
|
//ReentrantLock readLock = new ReentrantLock();
|
||||||
|
|
||||||
@@ -348,7 +361,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
}
|
}
|
||||||
watchdog.feed();
|
watchdog.feed();
|
||||||
KLALBPacket kpp = kppb;
|
KLALBPacket kpp = kppb;
|
||||||
SRv6Router.getDefaultExecutor().execute(() -> {
|
//SRv6Router.getDefaultExecutor().execute(() -> {
|
||||||
debugShowPacket("RX", kpp);
|
debugShowPacket("RX", kpp);
|
||||||
UUID val = null;
|
UUID val = null;
|
||||||
long delay = Long.MAX_VALUE / 1024;
|
long delay = Long.MAX_VALUE / 1024;
|
||||||
@@ -402,19 +415,25 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
|
|
||||||
long DsndDelay = prcv.subtract(psnd).longValue();
|
long DsndDelay = prcv.subtract(psnd).longValue();
|
||||||
long DrcvDelay = local.subtract(posnd).longValue();
|
long DrcvDelay = local.subtract(posnd).longValue();
|
||||||
// System.out.println(DsndDelayFactor+" "+DrcvDelayFactor);
|
// System.out.println(DsndDelay+" "+DrcvDelay);
|
||||||
|
|
||||||
rtt = DsndDelay + DrcvDelay;
|
rtt = DsndDelay + DrcvDelay;
|
||||||
|
if(rtt<rttMin) {
|
||||||
|
rttMin=rtt;
|
||||||
|
}else {
|
||||||
|
rttMin=(rttMin*99+rtt)/100;
|
||||||
|
}
|
||||||
if (DsndDelay >= 0 && DrcvDelay >= 0) {
|
if (DsndDelay >= 0 && DrcvDelay >= 0) {
|
||||||
delay = DrcvDelay;
|
delay = DrcvDelay;
|
||||||
monitor.getUploadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), psnd, 0, DsndDelay);
|
monitor.recordUploadDelay(DsndDelay);
|
||||||
// System.out.println(local);
|
//sysclk.adjustClock(Long128.valueOf( DsndDelay-DrcvDelay), 0.001);
|
||||||
} else {
|
} else {
|
||||||
long Dfallback = rtt / 2;
|
long Dfallback = rtt / 2;
|
||||||
if (Dfallback >= 0) {
|
if (Dfallback >= 0) {
|
||||||
delay = Dfallback;
|
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());
|
algorithm.setCurrentBandwidth(png.getDownSpeed());
|
||||||
@@ -437,11 +456,11 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
if (ardg2 != null)
|
if (ardg2 != null)
|
||||||
addressGroup = ardg2;
|
addressGroup = ardg2;
|
||||||
}
|
}
|
||||||
KLALBRemoteLine.this.onAddressUpdate();
|
KLALBRemoteLink.this.onAddressUpdate();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case KLALBPacket.VADDRREQ:
|
case KLALBPacket.VADDRREQ:
|
||||||
sendPacket(new VADDRPacket(localVaddrSupplier.get()));
|
sendPacket(new VADDRPacket(klalbController.getSelf()));
|
||||||
break;
|
break;
|
||||||
case KLALBPacket.VADDR:
|
case KLALBPacket.VADDR:
|
||||||
IPv6AddressGroup vdr = ((VADDRPacket) kpp).getVaddr();
|
IPv6AddressGroup vdr = ((VADDRPacket) kpp).getVaddr();
|
||||||
@@ -450,10 +469,10 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
sendPacket(new VADDRACKPacket());
|
sendPacket(new VADDRACKPacket());
|
||||||
if (fst.compareAndSet(true, false)) {
|
if (fst.compareAndSet(true, false)) {
|
||||||
// coll.resetCoolingTime();
|
// coll.resetCoolingTime();
|
||||||
monitor.setState(MonitorData.UP);
|
status.setState(LinkStatus.UP);
|
||||||
KLALBRemoteLine.this.onOnlineStateUpdate();
|
KLALBRemoteLink.this.onOnlineStateUpdate();
|
||||||
}
|
}
|
||||||
KLALBRemoteLine.this.onLocatorUpdate();
|
KLALBRemoteLink.this.onLocatorUpdate();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case KLALBPacket.VADDRACK:
|
case KLALBPacket.VADDRACK:
|
||||||
@@ -464,19 +483,16 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
|
|
||||||
IPv6OverKLALBPacket ivk = (IPv6OverKLALBPacket) kpp;
|
IPv6OverKLALBPacket ivk = (IPv6OverKLALBPacket) kpp;
|
||||||
IPv6Packet iv6 = ivk.getIPv6Packet();
|
IPv6Packet iv6 = ivk.getIPv6Packet();
|
||||||
ivk.putTimePassport("unpacked");
|
|
||||||
ivk.printPassport();
|
|
||||||
iv6.putTimePassport("unpackFromLink");
|
|
||||||
if (getSrv6Router() != null) {
|
if (getSrv6Router() != null) {
|
||||||
getSrv6Router().onReceive(KLALBRemoteLine.this, iv6);
|
getSrv6Router().onReceive(KLALBRemoteLink.this, iv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
KLALBOAMHopByHopTLV ktlv = null;
|
KLALBOAMHopByHopTLV ktlv = null;
|
||||||
List<Long> ptlv = new ArrayList<>();
|
|
||||||
|
|
||||||
long btimes = 0;
|
long btimes = 0;
|
||||||
IPv6HopByHopHeader hop = iv6.getHopByHopHeader();
|
IPv6HopByHopHeader hop = iv6.getHopByHopHeader();
|
||||||
if (hop != null) {
|
if (hop != null) {
|
||||||
|
List<Long> ptlv = new ArrayList<>();
|
||||||
List<IPv6HopByHopTLV> tlvs = hop.getTlvs();
|
List<IPv6HopByHopTLV> tlvs = hop.getTlvs();
|
||||||
for (IPv6HopByHopTLV tlv : tlvs) {
|
for (IPv6HopByHopTLV tlv : tlvs) {
|
||||||
if (tlv instanceof KLALBOAMHopByHopTLV) {
|
if (tlv instanceof KLALBOAMHopByHopTLV) {
|
||||||
@@ -488,14 +504,13 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
ptlv.add(btimes + ((KLALBPassportHopByHopTLV) tlv).getTimestampOffsetLong());
|
ptlv.add(btimes + ((KLALBPassportHopByHopTLV) tlv).getTimestampOffsetLong());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (ptlv.size() >= 2) {
|
if (ptlv.size() >= 2) {
|
||||||
long delta = ptlv.get(ptlv.size() - 1) - ptlv.get(ptlv.size() - 2);
|
long delta = ptlv.get(ptlv.size() - 1) - ptlv.get(ptlv.size() - 2);
|
||||||
long deltaxnanos = (long) (delta * 1000000000.0 / (1L << 32));
|
long deltaxnanos = (long) (delta * 1000000000.0 / (1L << 32));
|
||||||
if (deltaxnanos > 0)
|
if (deltaxnanos > 0)
|
||||||
//System.out.println(deltaxnanos);
|
|
||||||
delay = deltaxnanos;
|
delay = deltaxnanos;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -503,12 +518,17 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
|
|
||||||
long length = kpp.getTotalLength();
|
long length = kpp.getTotalLength();
|
||||||
UUID pid = val == null ? KLALBUtils.createGlobalUUID() : val;
|
UUID pid = val == null ? KLALBUtils.createGlobalUUID() : val;
|
||||||
monitor.getDownloadBandwidth().recordPacket(pid, (int) length, delay);
|
//monitor.getDownloadBandwidth().recordPacket(pid,0,1, delay);
|
||||||
if (klalbController != null) {
|
if(delay!=Long.MAX_VALUE / 1024) {
|
||||||
klalbController.getLinkMonitor().getDownloadBandwidth().recordPacket(pid, (int) length,
|
monitor.recordDownloadDelay(delay);
|
||||||
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) {
|
} catch (StreamCorruptedException sce) {
|
||||||
sce.printStackTrace();
|
sce.printStackTrace();
|
||||||
@@ -533,16 +553,37 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
public long getRTT() {
|
public long getRTT() {
|
||||||
return rtt;
|
return rtt;
|
||||||
}
|
}
|
||||||
|
public long getRTTMin() {
|
||||||
|
return rttMin;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
private ThreadParker tpk=new ThreadParker();
|
private ThreadParker tpk=new ThreadParker();
|
||||||
|
|
||||||
private StateManager stateManager;
|
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 class StateManager implements Runnable {
|
||||||
|
|
||||||
private Thread currThread;
|
private Thread currThread;
|
||||||
private RemoteSender sender;
|
|
||||||
private RemoteReceiver receiver;
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
currThread = Thread.currentThread();
|
currThread = Thread.currentThread();
|
||||||
@@ -580,10 +621,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
sender = new RemoteSender();
|
sender = new RemoteSender();
|
||||||
receiver = new RemoteReceiver();
|
receiver = new RemoteReceiver();
|
||||||
|
|
||||||
algorithm.setSpeedControlConsumer((speed, bursttime) -> {
|
|
||||||
sender.speedLimit.setLimitspeed(speed);
|
|
||||||
sender.speedLimit.setBrustTime(bursttime);
|
|
||||||
});
|
|
||||||
|
|
||||||
sendWindow = new SendPacketSlidingWindow<UUID, IPv6Packet>(algorithm, 65535, HEADER_CALIBRATE);
|
sendWindow = new SendPacketSlidingWindow<UUID, IPv6Packet>(algorithm, 65535, HEADER_CALIBRATE);
|
||||||
sendWindow.setResendConsumer(rerouteConsumer);
|
sendWindow.setResendConsumer(rerouteConsumer);
|
||||||
@@ -604,6 +642,10 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
if(klalbController!=null&& klalbController.getConfigItem()!=null) {
|
if(klalbController!=null&& klalbController.getConfigItem()!=null) {
|
||||||
KLALBControllerConfigItem config=klalbController.getConfigItem();
|
KLALBControllerConfigItem config=klalbController.getConfigItem();
|
||||||
if(algorithm instanceof DetnetCongestionAlgorithm) {
|
if(algorithm instanceof DetnetCongestionAlgorithm) {
|
||||||
|
double v0=config.getBurstLimit();
|
||||||
|
if(v0!=0) {
|
||||||
|
((DetnetCongestionAlgorithm)algorithm).setBurstLimit(v0);
|
||||||
|
}
|
||||||
double v1=config.getDelayUpperBound();
|
double v1=config.getDelayUpperBound();
|
||||||
if(v1!=0) {
|
if(v1!=0) {
|
||||||
((DetnetCongestionAlgorithm)algorithm).setUpperDelayBound(v1);
|
((DetnetCongestionAlgorithm)algorithm).setUpperDelayBound(v1);
|
||||||
@@ -619,8 +661,13 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
}
|
}
|
||||||
boolean b = sender.getWatchdog().isBarking()
|
boolean b = sender.getWatchdog().isBarking()
|
||||||
|| receiver.getWatchdog().isBarking();
|
|| receiver.getWatchdog().isBarking();
|
||||||
boolean isup= (!b)&&(receiver.getRTT()<1000000000L);
|
boolean isup= (!b)&&(receiver.getRTT()<1000000000L);//&&(receiver.getRTT()<receiver.getRTTMin()*5+50000000L)
|
||||||
monitor.setState(isup?MonitorData.UP:MonitorData.UNSTABLE);
|
int oldstate=status.getState();
|
||||||
|
int newstate=isup?LinkStatus.UP:LinkStatus.UNSTABLE;
|
||||||
|
status.setState(newstate);
|
||||||
|
if(oldstate!=newstate) {
|
||||||
|
onOnlineStateUpdate();
|
||||||
|
}
|
||||||
tpk.parkNanos(10000000L);
|
tpk.parkNanos(10000000L);
|
||||||
}
|
}
|
||||||
} catch (StreamCorruptedException sce) {
|
} catch (StreamCorruptedException sce) {
|
||||||
@@ -631,7 +678,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
monitor.setState(MonitorData.DOWN);
|
status.setState(LinkStatus.DOWN);
|
||||||
try {
|
try {
|
||||||
if (kplink != null)
|
if (kplink != null)
|
||||||
kplink.close();
|
kplink.close();
|
||||||
@@ -646,7 +693,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
if (closed) {
|
if (closed) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LockSupport.parkNanos(coll.getCoolingTime(monitor.getReliability()));
|
LockSupport.parkNanos(coll.getCoolingTime(status.getReliability()));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -655,14 +702,11 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
KLALBControllerConfigItem config=klalbController.getConfigItem();
|
KLALBControllerConfigItem config=klalbController.getConfigItem();
|
||||||
String cong=config.getCongestionAlgorithm();
|
String cong=config.getCongestionAlgorithm();
|
||||||
if(cong!=null) {
|
if(cong!=null) {
|
||||||
switch(cong) {
|
CongestionAlgorithm alg=CongestionAlgorithms.get(cong);
|
||||||
case "BBR":
|
if(alg==null) {
|
||||||
return new BBRCongestionAlgorithm();
|
alg=new BBRCongestionAlgorithm();
|
||||||
case "Vegas2":
|
|
||||||
return new Vegas2CongestionAlgorithm();
|
|
||||||
default:
|
|
||||||
return new BBRCongestionAlgorithm();
|
|
||||||
}
|
}
|
||||||
|
return alg;
|
||||||
}else {
|
}else {
|
||||||
return new BBRCongestionAlgorithm();
|
return new BBRCongestionAlgorithm();
|
||||||
}
|
}
|
||||||
@@ -684,8 +728,10 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
|
|
||||||
protected void startIO() {
|
protected void startIO() {
|
||||||
stateManager=new StateManager();
|
stateManager=new StateManager();
|
||||||
|
monitorUpdater=new MonitorUpdater();
|
||||||
|
ThreadTool.makeVDaemonThread("线路性能采样线程", monitorUpdater).start();
|
||||||
ThreadTool.makeVDaemonThread("远程线路状态线程", stateManager).start();
|
ThreadTool.makeVDaemonThread("远程线路状态线程", stateManager).start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ping() throws IOException {
|
public void ping() throws IOException {
|
||||||
@@ -706,7 +752,6 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
KLALBPacket packet = kplink.readKLALBPacket();
|
KLALBPacket packet = kplink.readKLALBPacket();
|
||||||
debugShowPacket("RX", packet);
|
debugShowPacket("RX", packet);
|
||||||
if (packet != null) {
|
if (packet != null) {
|
||||||
packet.putTimePassport("received");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return packet;
|
return packet;
|
||||||
@@ -716,8 +761,6 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
if (packet instanceof TESTNPacket)
|
if (packet instanceof TESTNPacket)
|
||||||
System.err.println(packet);
|
System.err.println(packet);
|
||||||
kplink.writeKLALBPacket(packet);
|
kplink.writeKLALBPacket(packet);
|
||||||
packet.putTimePassport("sended");
|
|
||||||
packet.printPassport();
|
|
||||||
|
|
||||||
debugShowPacket("TX", packet);
|
debugShowPacket("TX", packet);
|
||||||
}
|
}
|
||||||
@@ -733,7 +776,7 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
closed = true;
|
closed = true;
|
||||||
monitor.setState(MonitorData.DOWN);
|
status.setState(LinkStatus.DOWN);
|
||||||
try {
|
try {
|
||||||
if (kplink != null)
|
if (kplink != null)
|
||||||
kplink.close();
|
kplink.close();
|
||||||
@@ -763,11 +806,11 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
blk.markJoinqueuetime();
|
blk.markJoinqueuetime();
|
||||||
long length = blk.getTotalLength();
|
long length = blk.getTotalLength();
|
||||||
UUID pid = val == null ? KLALBUtils.createGlobalUUID() : val;
|
UUID pid = val == null ? KLALBUtils.createGlobalUUID() : val;
|
||||||
monitor.getUploadBandwidth().recordPacket(pid, (int) length);
|
monitor.recordUploadPacket((int) length);
|
||||||
if (klalbController != null) {
|
if (klalbController != null) {
|
||||||
klalbController.getLinkMonitor().getUploadBandwidth().recordPacket(pid, (int) length);
|
klalbController.getLinkMonitor().recordUploadPacket((int) length);
|
||||||
}
|
}
|
||||||
sender.send(blk);
|
sender.sendDirect(blk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,32 +835,24 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
public boolean isLoopBack() {
|
public boolean isLoopBack() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
BandwidthDistributer bandwidthDistributer=new BandwidthDistributer<>();
|
||||||
private BandwidthDistributer<Inet6Address> bandwidthDistributer = new BandwidthDistributer<Inet6Address>();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Neighbor> getNeighborsInfo() {
|
public List<Neighbor> getNeighborsInfo() {
|
||||||
List<Neighbor> hs = new ArrayList<>(1);
|
List<Neighbor> hs = new ArrayList<>(1);
|
||||||
if (peerAddress != null) {
|
if (peerAddress != null) {
|
||||||
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor, bandwidthDistributer));
|
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor, bandwidthDistributer));
|
||||||
// System.out.println(peerAddress+" "+addressGroup);
|
|
||||||
}
|
}
|
||||||
return hs;
|
return hs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private volatile int inputchachesize = 8192 * 4000;
|
|
||||||
private volatile int outputchachesize = 8192 * 240;// 500
|
|
||||||
|
|
||||||
private Consumer<IPv6Packet> rerouteConsumer;
|
private Consumer<IPv6Packet> rerouteConsumer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendPacket(IPv6Packet pack, IPv6Address inet6Address) throws IOException {
|
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();
|
IPv6HopByHopHeader hop = pack.getHopByHopHeader();
|
||||||
|
|
||||||
UUID val = null;
|
UUID val = null;
|
||||||
@@ -835,20 +870,15 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
if (!(pack.getPayload() instanceof ICMPv6PostcardPacket)) {
|
//if (!(pack.getPayload() instanceof ICMPv6PostcardPacket)) {
|
||||||
// 放入滑动窗口中并记录缓冲区大小占用
|
// 放入滑动窗口中并记录缓冲区大小占用
|
||||||
sendWindow.put(val, pack);
|
sendWindow.put(val, pack);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 捎带发送反方向的ACK给对方发送过来的数据包,减小设备性能开销
|
|
||||||
/*
|
|
||||||
* if(srh!=null) { addACKSEQToSRH(srh,10); }
|
|
||||||
*/
|
|
||||||
// 发送数据包
|
|
||||||
|
|
||||||
sendIPv6PacketToLink(pack, val);
|
sendIPv6PacketToLink(pack, val);
|
||||||
// }
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (rerouteConsumer != null) {
|
if (rerouteConsumer != null) {
|
||||||
@@ -864,8 +894,6 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
|
|
||||||
private void sendIPv6PacketToLink(IPv6Packet pack, UUID val) {
|
private void sendIPv6PacketToLink(IPv6Packet pack, UUID val) {
|
||||||
IPv6OverKLALBPacket kipv6 = new IPv6OverKLALBPacket(pack);
|
IPv6OverKLALBPacket kipv6 = new IPv6OverKLALBPacket(pack);
|
||||||
pack.putTimePassport("packdInLink");
|
|
||||||
pack.printPassport();
|
|
||||||
sendPacketToLink(kipv6, val);
|
sendPacketToLink(kipv6, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -874,34 +902,25 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCongress(IPv6Packet iPv6Packet, double scale) {
|
public boolean isCongestion(IPv6Packet iPv6Packet, double scale) {
|
||||||
SendPacketSlidingWindow<UUID, IPv6Packet> sw = sendWindow;
|
SendPacketSlidingWindow<UUID, IPv6Packet> sw = sendWindow;
|
||||||
if (sw != null) {
|
if (sw != null) {
|
||||||
boolean cong = (scale <= 1.0) && (monitor.getOutDelay() / (monitor.getOutDelayMin() + 1000000L) > 2);
|
return sw.isCongestion( scale);
|
||||||
|
|
||||||
return cong || sw.isCongress(iPv6Packet, scale);
|
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) {
|
|
||||||
//boolean xcongress = !speedLimit.checkTransmit(iPv6Packet.getTotalLength());
|
|
||||||
//return xcongress;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return monitor.getName();
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isUp() {
|
public boolean isUp() {
|
||||||
return (!isClosed()) && (getMonitor().getState() == MonitorData.UP) ;
|
return (!isClosed()) && (status.getState() == LinkStatus.UP) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -916,12 +935,12 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
for (Iterator<Neighbor> iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) {
|
for (Iterator<Neighbor> iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) {
|
||||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||||
RouteItem ri = new RouteItem(new IPv6AddressGroup(addresses.getAddress().getAddress(), 128),
|
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);
|
rlist.add(ri);
|
||||||
|
|
||||||
if (addresses.getLocator() != null) {
|
if (addresses.getLocator() != null) {
|
||||||
RouteItem ris = new RouteItem(addresses.getLocator(), addresses.getLocator().getAddress(), this,
|
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);
|
rlist.add(ris);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -939,9 +958,30 @@ public class KLALBRemoteLine extends AbstractControlledIPv6NetworkLink implement
|
|||||||
if (deltaxnanos > 0) {
|
if (deltaxnanos > 0) {
|
||||||
Long128 psnd = NTPTimestamps.ntp128BitToNanosTimestamp(
|
Long128 psnd = NTPTimestamps.ntp128BitToNanosTimestamp(
|
||||||
NTPTimestamps.inferNtp64To128(postcard.getTimestampBase(), sysclk.getCurrentTimeNTP128()));
|
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<UUID, IPv6Packet> getWindow() {
|
||||||
|
return sendWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long getQueueUsed() {
|
||||||
|
if(sender==null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sender.getQueueUsed();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,17 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketException;
|
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.Proxy;
|
|
||||||
import org.kne.cloud.network.SocketListener;
|
import org.kne.cloud.network.SocketListener;
|
||||||
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
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.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
@@ -69,15 +65,15 @@ public class KLALBRemoteManagement {
|
|||||||
synchronized (lineslist) {
|
synchronized (lineslist) {
|
||||||
for (Iterator<IPv6NetworkLink> iterator = lineslist.iterator(); iterator.hasNext();) {
|
for (Iterator<IPv6NetworkLink> iterator = lineslist.iterator(); iterator.hasNext();) {
|
||||||
IPv6NetworkLink link=iterator.next();
|
IPv6NetworkLink link=iterator.next();
|
||||||
if(!(link instanceof KLALBRemoteLine)) {
|
if(!(link instanceof KLALBRemoteLink)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link;
|
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
|
||||||
if(klalbRemoteLine.getSocketAddress()==null)
|
if(klalbRemoteLine.getSocketAddress()==null)
|
||||||
continue;
|
continue;
|
||||||
JsonObject jklbrl=new JsonObject();
|
JsonObject jklbrl=new JsonObject();
|
||||||
jklbrl.addProperty("ipport", klalbRemoteLine.getSocketAddress().toString());
|
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());
|
jklbrl.addProperty("Vaddr", klalbRemoteLine.getRemoteVaddr().getAddress().toString());
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ import java.net.UnknownHostException;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Address;
|
import org.kne.cloud.network.ipv6.IPv6Address;
|
||||||
|
|
||||||
@@ -385,20 +386,17 @@ public static String parseAbbrIPv6(String IPv6Str) {
|
|||||||
|
|
||||||
private final long id;
|
private final long id;
|
||||||
private long counter=0;
|
private long counter=0;
|
||||||
private UUID randUUID=UUID.randomUUID();
|
private long randUUIDh;
|
||||||
private long time=System.nanoTime();
|
private long randUUIDl;
|
||||||
private static final long INTERVAL=1000000L;
|
private static SecureRandom sr=new SecureRandom();
|
||||||
public UUIDGenarator(long threadId) {
|
public UUIDGenarator(long threadId) {
|
||||||
this.id=threadId;
|
this.id=threadId;
|
||||||
|
randUUIDh=sr.nextLong();
|
||||||
|
randUUIDl=sr.nextLong();
|
||||||
}
|
}
|
||||||
public UUID genarateUUID() {
|
public UUID genarateUUID() {
|
||||||
long curr=System.nanoTime();
|
long h=randUUIDh^id;
|
||||||
if(curr-time>INTERVAL) {
|
long l=randUUIDl^counter;
|
||||||
time=curr;
|
|
||||||
randUUID=UUID.randomUUID();
|
|
||||||
}
|
|
||||||
long h=randUUID.getMostSignificantBits()^id;
|
|
||||||
long l=randUUID.getLeastSignificantBits()^counter;
|
|
||||||
|
|
||||||
UUID ret=new UUID(h, l);
|
UUID ret=new UUID(h, l);
|
||||||
counter++;
|
counter++;
|
||||||
@@ -413,4 +411,9 @@ public static String parseAbbrIPv6(String IPv6Str) {
|
|||||||
//return UUID.randomUUID();
|
//return UUID.randomUUID();
|
||||||
return gens.get().genarateUUID();
|
return gens.get().genarateUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static FixedSizeStripedLongCounter createCounter() {
|
||||||
|
return CountersFactory.createFixedSizeStripedCounter(Runtime.getRuntime().availableProcessors());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.kne.cloud.network.klalb;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.BindException;
|
import java.net.BindException;
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocketImpl;
|
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
@@ -18,15 +17,12 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import org.kne.cloud.network.NetworkPacket;
|
|
||||||
import org.kne.cloud.network.VirtualDatagramSocketImpl;
|
import org.kne.cloud.network.VirtualDatagramSocketImpl;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Address;
|
import org.kne.cloud.network.ipv6.IPv6Address;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||||
import org.kne.cloud.network.tcp.UDPPacket;
|
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<IPv6Packet>{
|
||||||
|
|
||||||
private KLALBController controller;
|
private KLALBController controller;
|
||||||
|
|
||||||
@@ -89,8 +85,8 @@ public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl im
|
|||||||
localaddr = (Inet6Address) host;
|
localaddr = (Inet6Address) host;
|
||||||
localPort=port;
|
localPort=port;
|
||||||
if(!ignoreBindCheck)
|
if(!ignoreBindCheck)
|
||||||
controller.getDatagramPortBinder().bind(this);
|
controller.getUDPregister().bind(this);
|
||||||
controller.getDatagramPortBinder().listen(this);
|
controller.getUDPregister().listen(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -137,12 +133,10 @@ public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl im
|
|||||||
p.setLength(buffer.limit());
|
p.setLength(buffer.limit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setTTL(byte ttl) throws IOException {
|
protected void setTTL(byte ttl) throws IOException {
|
||||||
this.ttl=ttl;
|
this.ttl=ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected byte getTTL() throws IOException {
|
protected byte getTTL() throws IOException {
|
||||||
return (byte) ttl;
|
return (byte) ttl;
|
||||||
}
|
}
|
||||||
@@ -183,9 +177,9 @@ public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl im
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void close() {
|
protected void close() {
|
||||||
controller.getDatagramPortBinder().unlisten(this);
|
controller.getUDPregister().unlisten(this);
|
||||||
if(!ignoreBindCheck)
|
if(!ignoreBindCheck)
|
||||||
controller.getDatagramPortBinder().unbind(this);
|
controller.getUDPregister().unbind(this);
|
||||||
closed=true;
|
closed=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,14 +212,16 @@ public class KLALBVirtualDatagramSocketImpl extends VirtualDatagramSocketImpl im
|
|||||||
private Queue<UDPPacket> recvQueue = new ConcurrentLinkedQueue<UDPPacket>();
|
private Queue<UDPPacket> recvQueue = new ConcurrentLinkedQueue<UDPPacket>();
|
||||||
private AtomicInteger recvQueueUsed=new AtomicInteger(0);
|
private AtomicInteger recvQueueUsed=new AtomicInteger(0);
|
||||||
@Override
|
@Override
|
||||||
public void accept(IPv6Address t,NetworkPacket np) {
|
public void accept(IPv6Packet t) {
|
||||||
UDPPacket u=(UDPPacket) np;
|
if(t.getPayload() instanceof UDPPacket) {
|
||||||
|
UDPPacket u=(UDPPacket) t.getPayload();
|
||||||
if(recvQueueUsed.get()<=inputchachesize) {
|
if(recvQueueUsed.get()<=inputchachesize) {
|
||||||
if(recvQueue.offer(u)) {
|
if(recvQueue.offer(u)) {
|
||||||
recvQueueUsed.addAndGet((int) u.getDataLength());
|
recvQueueUsed.addAndGet((int) u.getDataLength());
|
||||||
LockSupport.unpark(parkThread);
|
LockSupport.unpark(parkThread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,26 +16,19 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
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.VirtualRawSocketImpl;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
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.IPv6Address;
|
||||||
import org.kne.cloud.network.ipv6.IPv6AddressGroup;
|
import org.kne.cloud.network.ipv6.IPv6AddressGroup;
|
||||||
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
||||||
import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink;
|
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;
|
import org.kne.io.KNEChannels;
|
||||||
|
|
||||||
public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements PacketConsumer{
|
public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements IPv6ProtocolRegister{
|
||||||
|
|
||||||
private boolean ipHeaderInclude=false;
|
private boolean ipHeaderInclude=false;
|
||||||
|
|
||||||
@@ -123,7 +116,7 @@ public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements P
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void close() {
|
protected void close() {
|
||||||
link.getProtocolNumberRegister().remove(bindProtocolNumber);
|
link.getProtocolNumberRegister()[bindProtocolNumber]=null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -156,8 +149,10 @@ public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements P
|
|||||||
|
|
||||||
localaddr=(Inet6Address) address;
|
localaddr=(Inet6Address) address;
|
||||||
this.bindProtocolNumber=protocolNumber;
|
this.bindProtocolNumber=protocolNumber;
|
||||||
if(link.getProtocolNumberRegister().putIfAbsent(protocolNumber, this)!=null) {
|
if(link.getProtocolNumberRegister()[protocolNumber]!=null) {
|
||||||
throw new BindException("protocol number already bind");
|
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) {
|
if(ipHeaderInclude) {
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
IPv6Payload pl=new IPv6Payload(bindProtocolNumber);
|
IPv6DefaultPayload pl=new IPv6DefaultPayload(bindProtocolNumber);
|
||||||
pl.getData().put(buf);
|
pl.getData().put(buf);
|
||||||
pl.getData().flip();
|
pl.getData().flip();
|
||||||
BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>>cons=link.getReceiveConsumer();
|
BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>>cons=link.getReceiveConsumer();
|
||||||
@@ -281,7 +276,7 @@ public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements P
|
|||||||
private AtomicInteger recvQueueUsed=new AtomicInteger(0);
|
private AtomicInteger recvQueueUsed=new AtomicInteger(0);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(IPv6Packet packx) throws IOException {
|
public boolean onaccept(IPv6Packet packx) throws IOException {
|
||||||
if(recvQueueUsed.get()<=inputchachesize) {
|
if(recvQueueUsed.get()<=inputchachesize) {
|
||||||
if(recvQueue.offer(packx)) {
|
if(recvQueue.offer(packx)) {
|
||||||
recvQueueUsed.addAndGet((int) packx.getPayload().getTotalLength());
|
recvQueueUsed.addAndGet((int) packx.getPayload().getTotalLength());
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ import java.net.SocketException;
|
|||||||
import java.net.SocketOption;
|
import java.net.SocketOption;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.nio.channels.spi.SelectorProvider;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.kne.cloud.network.kltp.KLTPInputStream;
|
||||||
import org.kne.cloud.network.klalb.KLALBVirtualSocketImpl.KVSIInputStream;
|
import org.kne.cloud.network.kltp.KLTPOutputStream;
|
||||||
import org.kne.cloud.network.klalb.KLALBVirtualSocketImpl.KVSIOutputStream;
|
|
||||||
|
|
||||||
public class KLALBVirtualSocketChannel extends SocketChannel{
|
public class KLALBVirtualSocketChannel extends SocketChannel{
|
||||||
|
|
||||||
@@ -110,22 +108,22 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(ByteBuffer dst) throws IOException {
|
public int read(ByteBuffer dst) throws IOException {
|
||||||
return ((KVSIInputStream)socket.getInputStream()).read(dst);
|
return ((KLTPInputStream)socket.getInputStream()).read(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
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
|
@Override
|
||||||
public int write(ByteBuffer src) throws IOException {
|
public int write(ByteBuffer src) throws IOException {
|
||||||
return ((KVSIOutputStream)socket.getOutputStream()).write(src);
|
return ((KLTPOutputStream)socket.getOutputStream()).write(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
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
|
@Override
|
||||||
@@ -146,13 +144,13 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAutoFlush() throws IOException {
|
public boolean isAutoFlush() throws IOException {
|
||||||
return ((KVSIOutputStream)socket.getOutputStream()).isAutoFlush();
|
return ((KLTPOutputStream)socket.getOutputStream()).isAutoFlush();
|
||||||
}
|
}
|
||||||
public void setAutoFlush(boolean b) throws IOException {
|
public void setAutoFlush(boolean b) throws IOException {
|
||||||
((KVSIOutputStream)socket.getOutputStream()).setAutoFlush(b);
|
((KLTPOutputStream)socket.getOutputStream()).setAutoFlush(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
((KVSIOutputStream)socket.getOutputStream()).flush();
|
((KLTPOutputStream)socket.getOutputStream()).flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,16 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.net.SocketException;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
|
|
||||||
public class LineDecitionComparator implements Comparator<KLALBRemoteLine> {
|
public class LineDecitionComparator implements Comparator<KLALBRemoteLink> {
|
||||||
private Map<KLALBRemoteLine,Long> predictedlatencys=new HashMap<>();
|
private Map<KLALBRemoteLink,Long> predictedlatencys=new HashMap<>();
|
||||||
public LineDecitionComparator (List<KLALBRemoteLine> krs,KLALBPacket curr,int priority) {
|
public LineDecitionComparator (List<KLALBRemoteLink> krs,KLALBPacket curr,int priority) {
|
||||||
for (Iterator<KLALBRemoteLine> iterator = krs.iterator(); iterator.hasNext();) {
|
for (Iterator<KLALBRemoteLink> iterator = krs.iterator(); iterator.hasNext();) {
|
||||||
KLALBRemoteLine klalbRemoteSocket = (KLALBRemoteLine) iterator.next();
|
KLALBRemoteLink klalbRemoteSocket = (KLALBRemoteLink) iterator.next();
|
||||||
long x=klalbRemoteSocket.getMonitor().getOutDelay();
|
long x=klalbRemoteSocket.getMonitor().getOutDelay();
|
||||||
//long x=klalbRemoteSocket.getMonitor().getLatency()>>1;
|
//long x=klalbRemoteSocket.getMonitor().getLatency()>>1;
|
||||||
/*long al=0;
|
/*long al=0;
|
||||||
@@ -32,12 +30,12 @@ public class LineDecitionComparator implements Comparator<KLALBRemoteLine> {
|
|||||||
predictedlatencys.put(klalbRemoteSocket, x);
|
predictedlatencys.put(klalbRemoteSocket, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Map<KLALBRemoteLine, Long> getPredictedlatencys() {
|
public Map<KLALBRemoteLink, Long> getPredictedlatencys() {
|
||||||
return predictedlatencys;
|
return predictedlatencys;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(KLALBRemoteLine o1, KLALBRemoteLine o2) {
|
public int compare(KLALBRemoteLink o1, KLALBRemoteLink o2) {
|
||||||
long t1=predictedlatencys.get(o1);
|
long t1=predictedlatencys.get(o1);
|
||||||
long t2=predictedlatencys.get(o2);
|
long t2=predictedlatencys.get(o2);
|
||||||
if(t1>t2) {
|
if(t1>t2) {
|
||||||
|
|||||||
@@ -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<IPv6Address, NetworkPacket> {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,43 +1,34 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.net.BindException;
|
import java.net.BindException;
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
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.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
import org.kne.cloud.network.IPv6SocketAddress;
|
import org.kne.cloud.network.IPv6SocketAddress;
|
||||||
import org.kne.cloud.network.NetworkPacket;
|
|
||||||
import org.kne.cloud.network.ipv6.IPv6Address;
|
import org.kne.cloud.network.ipv6.IPv6Address;
|
||||||
|
|
||||||
import com.google.gson.internal.Pair;
|
import com.google.gson.internal.Pair;
|
||||||
|
|
||||||
public class PortBinder {
|
public class PortBinder<T> {
|
||||||
private KLALBController controller;
|
private IPv6Address selfAddress;
|
||||||
public PortBinder(KLALBController controller) {
|
public PortBinder(IPv6Address selfAddress) {
|
||||||
super();
|
super();
|
||||||
this.controller = controller;
|
this.selfAddress = selfAddress;
|
||||||
}
|
}
|
||||||
private ReentrantReadWriteLock bindMaplock=new ReentrantReadWriteLock();
|
private ReentrantReadWriteLock bindMaplock=new ReentrantReadWriteLock();
|
||||||
private Map<IPv6SocketAddress,BindableKLALBPacketConsumer>bindMap=new ConcurrentHashMap<>(1024,0.2f);
|
private Map<IPv6SocketAddress,BindableConsumer<T>>bindMap=new ConcurrentHashMap<>(2048);
|
||||||
private ReentrantReadWriteLock listenMaplock=new ReentrantReadWriteLock();
|
private ReentrantReadWriteLock listenMaplock=new ReentrantReadWriteLock();
|
||||||
private Map<IPv6SocketAddress,BindableKLALBPacketConsumer>listenMap=new ConcurrentHashMap<>(1024,0.2f);
|
private Map<IPv6SocketAddress,BindableConsumer<T>>listenMap=new ConcurrentHashMap<>(2048);
|
||||||
private ReentrantReadWriteLock connectMaplock=new ReentrantReadWriteLock();
|
private ReentrantReadWriteLock connectMaplock=new ReentrantReadWriteLock();
|
||||||
private Map<Pair<IPv6SocketAddress,IPv6SocketAddress>,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>(1024,0.2f);
|
private Map<Pair<IPv6SocketAddress,IPv6SocketAddress>,BindableConsumer<T>>connectMap=new ConcurrentHashMap<>(2048);
|
||||||
private volatile int portn=65535;
|
private volatile int portn=65535;
|
||||||
public void bind(BindableKLALBPacketConsumer ks) throws BindException {
|
public void bind(BindableConsumer<T> ks) throws BindException {
|
||||||
bindMaplock.writeLock().lock();
|
bindMaplock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
int pold=ks.getLocalPort();
|
int pold=ks.getLocalPort();
|
||||||
@@ -86,7 +77,7 @@ public class PortBinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unbind(BindableKLALBPacketConsumer ks) {
|
public void unbind(BindableConsumer<T> ks) {
|
||||||
bindMaplock.writeLock().lock();
|
bindMaplock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
removeAsValue(bindMap, ks);
|
removeAsValue(bindMap, ks);
|
||||||
@@ -94,7 +85,7 @@ public class PortBinder {
|
|||||||
bindMaplock.writeLock().unlock();
|
bindMaplock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void connect(BindableKLALBPacketConsumer ks) throws BindException {
|
public void connect(BindableConsumer<T> ks) throws BindException {
|
||||||
connectMaplock.writeLock().lock();
|
connectMaplock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
connectMap.put(new Pair<IPv6SocketAddress, IPv6SocketAddress>( new IPv6SocketAddress(IPv6Address.valueOf(ks.getLocalInetAddress()), ks.getLocalPort()), new IPv6SocketAddress(IPv6Address.valueOf(ks.getRemoteInetAddress()), ks.getPort())),ks);
|
connectMap.put(new Pair<IPv6SocketAddress, IPv6SocketAddress>( 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();
|
connectMaplock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void disconnect(BindableKLALBPacketConsumer ks) {
|
public void disconnect(BindableConsumer<T> ks) {
|
||||||
connectMaplock.writeLock().lock();
|
connectMaplock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
removeAsValue(connectMap, ks);
|
removeAsValue(connectMap, ks);
|
||||||
@@ -111,7 +102,7 @@ public class PortBinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void listen(BindableKLALBPacketConsumer ks) throws BindException {
|
public void listen(BindableConsumer<T> ks) throws BindException {
|
||||||
listenMaplock.writeLock().lock();
|
listenMaplock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
listenMap.put(new IPv6SocketAddress(IPv6Address.valueOf(ks.getLocalInetAddress()), ks.getLocalPort()),ks);
|
listenMap.put(new IPv6SocketAddress(IPv6Address.valueOf(ks.getLocalInetAddress()), ks.getLocalPort()),ks);
|
||||||
@@ -119,7 +110,7 @@ public class PortBinder {
|
|||||||
listenMaplock.writeLock().unlock();
|
listenMaplock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void unlisten(BindableKLALBPacketConsumer ks) {
|
public void unlisten(BindableConsumer<T> ks) {
|
||||||
/*System.out.println(listenMap);
|
/*System.out.println(listenMap);
|
||||||
new RuntimeException("!").printStackTrace();*/
|
new RuntimeException("!").printStackTrace();*/
|
||||||
listenMaplock.writeLock().lock();
|
listenMaplock.writeLock().lock();
|
||||||
@@ -201,40 +192,68 @@ public class PortBinder {
|
|||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
}*/
|
}*/
|
||||||
public boolean distributePacketToConsumer(IPv6Address srcAddr,PortPacket packet) {
|
public BindableConsumer<T> distributePacketToConsumer(IPv6Address srcAddr, PortPacket packet) {
|
||||||
IPv6SocketAddress local=new IPv6SocketAddress(controller.getSelf().getAddress(), packet.getDstPort());
|
int dst=packet.getDstPort();
|
||||||
IPv6SocketAddress remote=new IPv6SocketAddress(srcAddr, packet.getSrcPort());
|
int src=packet.getSrcPort();
|
||||||
BindableKLALBPacketConsumer bkc=connectMap.get(new Pair<IPv6SocketAddress, IPv6SocketAddress>(local, remote));
|
IPv6SocketAddress local=new IPv6SocketAddress( selfAddress,dst);
|
||||||
|
IPv6SocketAddress remote=new IPv6SocketAddress(srcAddr, src);
|
||||||
|
BindableConsumer<T> bkc=connectMap.get(new Pair<IPv6SocketAddress, IPv6SocketAddress>(local, remote));
|
||||||
if(bkc!=null) {
|
if(bkc!=null) {
|
||||||
bkc.accept(srcAddr, (NetworkPacket) packet);
|
return bkc;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
IPv6SocketAddress localany=new IPv6SocketAddress(IPv6Address.UNSPECIFIED, packet.getDstPort());
|
IPv6SocketAddress localany=new IPv6SocketAddress(IPv6Address.UNSPECIFIED, dst);
|
||||||
bkc=connectMap.get(new Pair<IPv6SocketAddress, IPv6SocketAddress>(localany, remote));
|
bkc=connectMap.get(new Pair<IPv6SocketAddress, IPv6SocketAddress>(localany, remote));
|
||||||
if(bkc!=null) {
|
if(bkc!=null) {
|
||||||
bkc.accept(srcAddr, (NetworkPacket) packet);
|
return bkc;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bkc=listenMap.get(local);
|
bkc=listenMap.get(local);
|
||||||
if(bkc!=null) {
|
if(bkc!=null) {
|
||||||
bkc.accept(srcAddr, (NetworkPacket) packet);
|
return bkc;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
bkc=listenMap.get(localany);
|
bkc=listenMap.get(localany);
|
||||||
if(bkc!=null) {
|
if(bkc!=null) {
|
||||||
bkc.accept(srcAddr, (NetworkPacket) packet);
|
return bkc;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
public boolean checkIsBind(BindableKLALBPacketConsumer klalbVirtualSocketImpl) {
|
public boolean checkIsBind(BindableConsumer<T> klalbVirtualSocketImpl) {
|
||||||
return bindMap.containsValue(klalbVirtualSocketImpl);
|
return bindMap.containsValue(klalbVirtualSocketImpl);
|
||||||
}
|
}
|
||||||
public boolean checkIsConnect(BindableKLALBPacketConsumer kservers,InetSocketAddress isaf) throws BindException {
|
public boolean checkIsConnect(BindableConsumer<T> kservers,InetSocketAddress isaf) throws BindException {
|
||||||
return connectMap.containsKey(new Pair<IPv6SocketAddress, IPv6SocketAddress>( new IPv6SocketAddress(IPv6Address.valueOf( kservers.getLocalInetAddress()), kservers.getLocalPort()),IPv6SocketAddress.valueOf( isaf)));
|
return connectMap.containsKey(new Pair<IPv6SocketAddress, IPv6SocketAddress>( 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<Pair<IPv6SocketAddress, IPv6SocketAddress>, BindableConsumer<T>> 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<IPv6SocketAddress, BindableConsumer<T>> p:bindMap.entrySet()) {
|
||||||
|
sb.append(p);
|
||||||
|
sb.append(" ");
|
||||||
|
sb.append(p.getValue());
|
||||||
|
sb.append('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append("listenMap: Local\n");
|
||||||
|
for(Entry<IPv6SocketAddress, BindableConsumer<T>> p:listenMap.entrySet()) {
|
||||||
|
sb.append(p);
|
||||||
|
sb.append(" ");
|
||||||
|
sb.append(p.getValue());
|
||||||
|
sb.append('\n');
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,11 @@ public class SendItem<T extends NetworkPacket> {
|
|||||||
this.packetLength=packet.getTotalLength();
|
this.packetLength=packet.getTotalLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SendItem(T packet,int headerCalibrate) {
|
||||||
|
this.packet=packet;
|
||||||
|
this.packetLength=packet.getTotalLength()+headerCalibrate;
|
||||||
|
}
|
||||||
|
|
||||||
public T getPacket() {
|
public T getPacket() {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
@@ -29,5 +34,10 @@ public class SendItem<T extends NetworkPacket> {
|
|||||||
public void setSendtime(long sendtimex) {
|
public void setSendtime(long sendtimex) {
|
||||||
this.sendtime=sendtimex;
|
this.sendtime=sendtimex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SendItem [packetLength=" + packetLength + ", packet=" + packet + ", sendtime=" + sendtime + "]";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,21 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InterruptedIOException;
|
|
||||||
import java.io.StreamCorruptedException;
|
import java.io.StreamCorruptedException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.ProtocolFamily;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.SocketOption;
|
|
||||||
import java.net.SocketOptions;
|
|
||||||
import java.net.StandardProtocolFamily;
|
|
||||||
import java.net.StandardSocketOptions;
|
import java.net.StandardSocketOptions;
|
||||||
import java.nio.Buffer;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.AsynchronousSocketChannel;
|
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.GatheringByteChannel;
|
import java.nio.channels.GatheringByteChannel;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
|
||||||
import java.nio.channels.ScatteringByteChannel;
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
import java.nio.channels.SocketChannel;
|
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 java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.kne.cloud.network.BufferedChannel;
|
import org.kne.cloud.network.BufferedChannel;
|
||||||
import org.kne.cloud.network.ByteBufferAllocator;
|
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.NetworkPacket;
|
import org.kne.cloud.network.NetworkPacket;
|
||||||
import org.kne.cloud.network.ThreadTool;
|
import org.kne.cloud.network.ThreadTool;
|
||||||
import org.kne.cloud.network.TimeoutTimer;
|
|
||||||
import org.kne.io.KNEChannels;
|
import org.kne.io.KNEChannels;
|
||||||
|
|
||||||
public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||||
@@ -64,7 +46,8 @@ public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implem
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
try {
|
try {
|
||||||
return new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getLocalAddress())+"←"+new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getRemoteAddress());
|
return new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getLocalAddress())+"←"+new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getRemoteAddress());
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
return "?←?";
|
return "?←?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,19 +167,20 @@ public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implem
|
|||||||
@Override
|
@Override
|
||||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||||
|
|
||||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
/*ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||||
szeWrite.limit(4);
|
szeWrite.limit(4);
|
||||||
//szeWrite.clear();
|
//szeWrite.clear();
|
||||||
int length=(int) kp.getTotalLength();
|
int length=(int) kp.getTotalLength();
|
||||||
szeWrite.putInt(length);
|
szeWrite.putInt(0,length);
|
||||||
szeWrite.flip();
|
szeWrite.flip();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
writableChannel.write(szeWrite);
|
writableChannel.write(szeWrite);*/
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
|
|
||||||
|
int length=(int) kp.getTotalLength();
|
||||||
AtomicLong al=new AtomicLong(0);
|
AtomicLong al=new AtomicLong(0);
|
||||||
KLALBPacket.writeKLALBPacketToChannel(new MonitoredChannel(writableChannel,null,new AtomicLong[] { al}), kp);
|
KLALBPacket.writeKLALBPacketToChannel(new MonitoredChannel(writableChannel,null,new AtomicLong[] { al}), kp);
|
||||||
if(length!=al.get()) {
|
if(length!=al.get()) {
|
||||||
@@ -212,19 +196,23 @@ public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implem
|
|||||||
private void checkflush() throws IOException {
|
private void checkflush() throws IOException {
|
||||||
if(writableChannel instanceof BufferedChannel) {
|
if(writableChannel instanceof BufferedChannel) {
|
||||||
((BufferedChannel) writableChannel).flush();
|
((BufferedChannel) writableChannel).flush();
|
||||||
|
}else if(writableChannel instanceof KLALBVirtualSocketChannel) {
|
||||||
|
((KLALBVirtualSocketChannel) writableChannel).flush();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KLALBPacket readKLALBPacket() throws IOException {
|
public KLALBPacket readKLALBPacket() throws IOException {
|
||||||
|
|
||||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
/*ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||||
szeWrite.limit(4);
|
szeWrite.limit(4);
|
||||||
KNEChannels.readFully(readableChannel, szeWrite);
|
KNEChannels.readFully(readableChannel, szeWrite);
|
||||||
szeWrite.flip();
|
szeWrite.flip();
|
||||||
int readSize=szeWrite.getInt();
|
int readSize=szeWrite.getInt();*/
|
||||||
KLALBPacket kp=KLALBPacket.readKLALBPacketFromChannel(readableChannel);
|
KLALBPacket kp=KLALBPacket.readKLALBPacketFromChannel(readableChannel);
|
||||||
if(debug) {
|
if(debug) {
|
||||||
|
int readSize=0;
|
||||||
long kpl=kp.getTotalLength();
|
long kpl=kp.getTotalLength();
|
||||||
if(kpl!=readSize) {
|
if(kpl!=readSize) {
|
||||||
throw new StreamCorruptedException(kp+" packet length error:"+kpl+"!="+readSize);
|
throw new StreamCorruptedException(kp+" packet length error:"+kpl+"!="+readSize);
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package org.kne.cloud.network.klalb.ui;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.FlowLayout;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.SwingConstants;
|
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.plot.dial.StandardDialScale;
|
||||||
import org.jfree.chart.title.TextTitle;
|
import org.jfree.chart.title.TextTitle;
|
||||||
import org.jfree.data.general.DefaultValueDataset;
|
import org.jfree.data.general.DefaultValueDataset;
|
||||||
|
import org.kne.ui.LinearGradientColor;
|
||||||
|
|
||||||
public class DialPanel extends JPanel {
|
public class DialPanel extends JPanel {
|
||||||
|
|
||||||
private DialTextAnnotation textAnnotation;
|
private static final int SEGMENTS = 100; // 渐变色分段数,越高越平滑
|
||||||
private DialPlot plot;
|
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,
|
private DialTextAnnotation textAnnotation;
|
||||||
Color pointerColor, Color outlineColor) {
|
private DialPlot plot;
|
||||||
plot=createDialPlot(primary,secondary,pointerColor,outlineColor);
|
|
||||||
|
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 = new DialTextAnnotation("");
|
||||||
textAnnotation.setFont(UIEnv.getFont().deriveFont(20.0f));
|
textAnnotation.setFont(UIEnv.getFont().deriveFont(20.0f));
|
||||||
plot.addLayer(textAnnotation);
|
plot.addLayer(textAnnotation);
|
||||||
setLayout(new BorderLayout());
|
jp.setLayout(new BorderLayout());
|
||||||
add(createChartPanel (createChart(plot),new Dimension(size, size)),BorderLayout.CENTER);
|
Dimension dim = new Dimension(size, size);
|
||||||
JLabel jlb=new JLabel(title);
|
jp.add(createChartPanel(createChart(plot), dim), BorderLayout.CENTER);
|
||||||
jlb.setFont(UIEnv.getFont().deriveFont(16.0f));
|
JLabel jlb = new JLabel(title);
|
||||||
jlb.setHorizontalAlignment(SwingConstants.CENTER);
|
jlb.setFont(UIEnv.getFont().deriveFont(16.0f));
|
||||||
add(jlb,BorderLayout.SOUTH);
|
jlb.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
}
|
jp.add(jlb, BorderLayout.SOUTH);
|
||||||
|
add(jp);
|
||||||
public DialTextAnnotation getTextAnnotation() {
|
}
|
||||||
return textAnnotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public DialTextAnnotation getTextAnnotation() {
|
||||||
|
return textAnnotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* 创建图表面板
|
* 创建图表面板
|
||||||
* @param dashSize
|
|
||||||
*/
|
*/
|
||||||
private ChartPanel createChartPanel(JFreeChart chart, Dimension dashSize) {
|
private ChartPanel createChartPanel(JFreeChart chart, Dimension dashSize) {
|
||||||
ChartPanel panel = new ChartPanel(chart);
|
ChartPanel panel = new ChartPanel(chart);
|
||||||
panel.setPreferredSize(dashSize);
|
panel.setPreferredSize(dashSize);
|
||||||
panel.setSize(panel.getPreferredSize());
|
panel.setSize(dashSize);
|
||||||
panel.setBackground(Color.WHITE);
|
panel.setBackground(Color.WHITE);
|
||||||
panel.setBorder(new LineBorder(Color.LIGHT_GRAY));
|
panel.setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* 创建图表
|
* 创建图表
|
||||||
*/
|
*/
|
||||||
private JFreeChart createChart(DialPlot plot) {
|
private JFreeChart createChart(DialPlot plot) {
|
||||||
JFreeChart chart = new JFreeChart(plot);
|
JFreeChart chart = new JFreeChart(plot);
|
||||||
chart.setBorderPaint(Color.WHITE);
|
chart.setBorderPaint(Color.WHITE);
|
||||||
chart.setTitle((TextTitle)null);
|
chart.setTitle((TextTitle) null);
|
||||||
plot.setView(0, 0, 1, 1);
|
plot.setView(0, 0, 1, 1);
|
||||||
return chart;
|
return chart;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* 创建仪表盘图表
|
* 创建仪表盘图表
|
||||||
*/
|
*/
|
||||||
private DialPlot createDialPlot(DefaultValueDataset primary, DefaultValueDataset secondary,
|
private DialPlot createDialPlot(DefaultValueDataset primary, DefaultValueDataset secondary,
|
||||||
Color pointerColor, Color outlineColor) {
|
Color pointerColor, Color outlineColor) {
|
||||||
DialPlot plot = new DialPlot();
|
DialPlot plot = new DialPlot();
|
||||||
plot.setDataset(1, primary);
|
plot.setDataset(1, primary);
|
||||||
plot.setDataset(0, secondary);
|
plot.setDataset(0, secondary);
|
||||||
|
|
||||||
StandardDialFrame frame = new StandardDialFrame();
|
StandardDialFrame frame = new StandardDialFrame();
|
||||||
frame.setVisible(false);
|
frame.setVisible(false);
|
||||||
plot.setDialFrame(frame);
|
plot.setDialFrame(frame);
|
||||||
|
|
||||||
// 添加刻度
|
// 添加刻度
|
||||||
StandardDialScale scale = new StandardDialScale(0, 100, -120, -300, 10, 5);
|
StandardDialScale scale = new StandardDialScale(0, 100, -120, -300, 10, 5);
|
||||||
scale.setTickRadius(0.80);
|
scale.setTickRadius(0.80);
|
||||||
scale.setTickLabelsVisible(false);
|
scale.setTickLabelsVisible(false);
|
||||||
plot.addScale(0, scale);
|
plot.addScale(0, scale);
|
||||||
|
|
||||||
|
|
||||||
// 添加指针
|
// 添加指针
|
||||||
addDialPointers(plot, pointerColor, outlineColor);
|
addDialPointers(plot, pointerColor, outlineColor);
|
||||||
|
|
||||||
return plot;
|
return plot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为仪表盘添加颜色范围
|
* 添加渐变色范围(平滑过渡)
|
||||||
|
* 从绿色 → 黄色 → 红色,基于 KLALBUtils.getColorByLoadPercentage()
|
||||||
*/
|
*/
|
||||||
public void addDefaultDialRanges() {
|
public void addGradientRanges(LinearGradientColor lgc) {
|
||||||
// 绿色范围: 0-70%
|
double segmentAngle = 100.0 / SEGMENTS; // 每个分段的角度跨度
|
||||||
StandardDialRange greenRange = new StandardDialRange(0, 70, Color.GREEN);
|
|
||||||
addDialRange( greenRange);
|
for (int i = 0; i < SEGMENTS; i++) {
|
||||||
|
double start = i * segmentAngle;
|
||||||
// 黄色范围: 70-90%
|
double end = (i + 1) * segmentAngle;
|
||||||
StandardDialRange yellowRange = new StandardDialRange(70, 90, Color.YELLOW);
|
// 计算当前分段对应的负载百分比(取分段的中点)
|
||||||
addDialRange( yellowRange);
|
float loadPercent = (float) (start + segmentAngle / 2);
|
||||||
|
Color color = lgc.getColor(loadPercent/100);
|
||||||
// 红色范围: 90-100%
|
|
||||||
StandardDialRange redRange = new StandardDialRange(90, 100, Color.RED);
|
StandardDialRange range = new StandardDialRange(start, end, color);
|
||||||
addDialRange( redRange);
|
addDialRange(range);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final double INNER=0.85;
|
|
||||||
private static final double OUTER=0.90;
|
|
||||||
public void addDialRange( StandardDialRange greenRange) {
|
public void addDialRange(StandardDialRange range) {
|
||||||
greenRange.setInnerRadius(INNER);
|
range.setInnerRadius(INNER_RADIUS);
|
||||||
greenRange.setOuterRadius(OUTER);
|
range.setOuterRadius(OUTER_RADIUS);
|
||||||
plot.addLayer(greenRange);
|
plot.addLayer(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为仪表盘添加指针
|
* 为仪表盘添加指针
|
||||||
@@ -123,12 +136,12 @@ public class DialPanel extends JPanel {
|
|||||||
// 次要指针(透明)
|
// 次要指针(透明)
|
||||||
DialPointer.Pointer secondaryPointer = new DialPointer.Pointer();
|
DialPointer.Pointer secondaryPointer = new DialPointer.Pointer();
|
||||||
secondaryPointer.setRadius(0.8);
|
secondaryPointer.setRadius(0.8);
|
||||||
secondaryPointer.setFillPaint(new Color(secondaryColor.getRed(), secondaryColor.getGreen(),
|
secondaryPointer.setFillPaint(new Color(secondaryColor.getRed(), secondaryColor.getGreen(),
|
||||||
secondaryColor.getBlue(), 0));
|
secondaryColor.getBlue(), 0));
|
||||||
secondaryPointer.setOutlinePaint(secondaryColor);
|
secondaryPointer.setOutlinePaint(secondaryColor);
|
||||||
secondaryPointer.setDatasetIndex(0);
|
secondaryPointer.setDatasetIndex(0);
|
||||||
plot.addLayer(secondaryPointer);
|
plot.addLayer(secondaryPointer);
|
||||||
|
|
||||||
// 主要指针
|
// 主要指针
|
||||||
DialPointer.Pointer primaryPointer = new DialPointer.Pointer();
|
DialPointer.Pointer primaryPointer = new DialPointer.Pointer();
|
||||||
primaryPointer.setRadius(0.8);
|
primaryPointer.setRadius(0.8);
|
||||||
@@ -137,4 +150,4 @@ public class DialPanel extends JPanel {
|
|||||||
primaryPointer.setDatasetIndex(1);
|
primaryPointer.setDatasetIndex(1);
|
||||||
plot.addLayer(primaryPointer);
|
plot.addLayer(primaryPointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,11 +16,7 @@ import javax.swing.border.LineBorder;
|
|||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
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.plot.dial.*;
|
||||||
import org.jfree.chart.title.TextTitle;
|
|
||||||
import org.jfree.chart.ui.RectangleEdge;
|
|
||||||
import org.jfree.data.general.DefaultValueDataset;
|
import org.jfree.data.general.DefaultValueDataset;
|
||||||
import org.kne.cloud.clock.HighAccuracyClock;
|
import org.kne.cloud.clock.HighAccuracyClock;
|
||||||
import org.kne.cloud.klalb.uitool.*;
|
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.ipv6.IPv6NetworkLink;
|
||||||
import org.kne.cloud.network.klalb.*;
|
import org.kne.cloud.network.klalb.*;
|
||||||
import org.kne.cloud.network.klalb.ui.GraphPanel.GraphNode;
|
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.XFrame;
|
||||||
import org.kne.ui.YScrollPane;
|
import org.kne.ui.YScrollPane;
|
||||||
|
|
||||||
@@ -58,6 +55,8 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
private DefaultValueDataset downDataPPS; // 下行数据包速率
|
private DefaultValueDataset downDataPPS; // 下行数据包速率
|
||||||
private DefaultValueDataset backplaneDelay;
|
private DefaultValueDataset backplaneDelay;
|
||||||
private DefaultValueDataset backplanePPS;
|
private DefaultValueDataset backplanePPS;
|
||||||
|
private DefaultValueDataset backplaneECNRate;
|
||||||
|
private DefaultValueDataset backplaneLossRate;
|
||||||
|
|
||||||
// ==================== 仪表盘文本标注 ====================
|
// ==================== 仪表盘文本标注 ====================
|
||||||
private DialTextAnnotation upSpeedText; // 上行速度文本标注
|
private DialTextAnnotation upSpeedText; // 上行速度文本标注
|
||||||
@@ -66,6 +65,8 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
private DialTextAnnotation downPPSText; // 下行包速率文本标注
|
private DialTextAnnotation downPPSText; // 下行包速率文本标注
|
||||||
private DialTextAnnotation backplaneDelayText;
|
private DialTextAnnotation backplaneDelayText;
|
||||||
private DialTextAnnotation backplanePPSText;
|
private DialTextAnnotation backplanePPSText;
|
||||||
|
private DialTextAnnotation backplaneECNRateText;
|
||||||
|
private DialTextAnnotation backplaneLossRateText;
|
||||||
|
|
||||||
// ==================== UI组件 ====================
|
// ==================== UI组件 ====================
|
||||||
private YScrollPane ysp, yspc; // 可垂直滚动的面板
|
private YScrollPane ysp, yspc; // 可垂直滚动的面板
|
||||||
@@ -79,7 +80,8 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
private JTextField textFieldLocate; // 定位地址输入框
|
private JTextField textFieldLocate; // 定位地址输入框
|
||||||
private JTextField asnField2; // ASN显示框
|
private JTextField asnField2; // ASN显示框
|
||||||
private JTextArea dnsAreaSet; // DNS服务器设置区域
|
private JTextArea dnsAreaSet; // DNS服务器设置区域
|
||||||
private JComboBox comboCongress; // 拥塞控制算法选择框
|
private JComboBox comboPerformance; // 性能策略选择框
|
||||||
|
private JComboBox comboCongestion; // 拥塞控制算法选择框
|
||||||
private JTextField tcpListeningSet; // TCP监听设置
|
private JTextField tcpListeningSet; // TCP监听设置
|
||||||
private JTextField udpListeningSet; // UDP监听设置
|
private JTextField udpListeningSet; // UDP监听设置
|
||||||
private JTextArea openLineTabelSet; // 开放线路表设置
|
private JTextArea openLineTabelSet; // 开放线路表设置
|
||||||
@@ -105,8 +107,10 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
private SliderSettingItem linkConnectionsCount;
|
private SliderSettingItem linkConnectionsCount;
|
||||||
private SliderSettingItem nagleDelayTime;
|
private SliderSettingItem nagleDelayTime;
|
||||||
private SliderSettingItem linkNagleDelayTime;
|
private SliderSettingItem linkNagleDelayTime;
|
||||||
|
private SliderSettingItem burstLimit;
|
||||||
private SliderSettingItem delayHbound;
|
private SliderSettingItem delayHbound;
|
||||||
private SliderSettingItem delayLbound;
|
private SliderSettingItem delayLbound;
|
||||||
|
private ComboSettingItem performanceStrategy;
|
||||||
private ComboSettingItem congestions;
|
private ComboSettingItem congestions;
|
||||||
|
|
||||||
// ==================== 构造方法 ====================
|
// ==================== 构造方法 ====================
|
||||||
@@ -345,7 +349,7 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
upSpeed = new DefaultValueDataset(0);
|
upSpeed = new DefaultValueDataset(0);
|
||||||
upDataSpeed = 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));
|
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();
|
upSpeedText =dialup.getTextAnnotation();
|
||||||
|
|
||||||
|
|
||||||
@@ -355,7 +359,7 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
downSpeed = new DefaultValueDataset(0);
|
downSpeed = new DefaultValueDataset(0);
|
||||||
downDataSpeed = 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));
|
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();
|
downSpeedText =dialdown.getTextAnnotation();
|
||||||
|
|
||||||
dashs.add(dialdown);
|
dashs.add(dialdown);
|
||||||
@@ -369,7 +373,7 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
upPPS = new DefaultValueDataset(0);
|
upPPS = new DefaultValueDataset(0);
|
||||||
upDataPPS = 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));
|
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();
|
upPPSText = dialupPPS.getTextAnnotation();
|
||||||
|
|
||||||
dashs.add(dialupPPS);
|
dashs.add(dialupPPS);
|
||||||
@@ -378,7 +382,7 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
downPPS = new DefaultValueDataset(0);
|
downPPS = new DefaultValueDataset(0);
|
||||||
downDataPPS = 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));
|
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();
|
downPPSText = dialdownPPS.getTextAnnotation();
|
||||||
|
|
||||||
dashs.add(dialdownPPS);
|
dashs.add(dialdownPPS);
|
||||||
@@ -391,21 +395,8 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
// 背板转发延迟仪表盘
|
// 背板转发延迟仪表盘
|
||||||
backplaneDelay = new DefaultValueDataset(0);
|
backplaneDelay = new DefaultValueDataset(0);
|
||||||
DialPanel dialupPPS=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("backplanedelay"), backplaneDelay, null, Color.BLUE, new Color(0, 0, 127));
|
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.addGradientRanges(UIEnv.RANGE_2);
|
||||||
dialupPPS.addDialRange( redblackRange);
|
|
||||||
backplaneDelayText = dialupPPS.getTextAnnotation();
|
backplaneDelayText = dialupPPS.getTextAnnotation();
|
||||||
|
|
||||||
dashs.add(dialupPPS);
|
dashs.add(dialupPPS);
|
||||||
@@ -413,10 +404,28 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
// 背板PPS仪表盘
|
// 背板PPS仪表盘
|
||||||
backplanePPS = new DefaultValueDataset(0);
|
backplanePPS = new DefaultValueDataset(0);
|
||||||
DialPanel backPPS=new DialPanel(CONST.dialwidth, UIEnv.getRsb().getString("backplanepps"), backplanePPS, null, Color.BLUE, new Color(0, 0, 127));
|
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();
|
backplanePPSText = backPPS.getTextAnnotation();
|
||||||
|
|
||||||
dashs.add(backPPS);
|
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();
|
denyBroadcast=denyBroadcastc.getCheckBox();
|
||||||
settings.getView().add(denyBroadcastc);
|
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"),
|
SettingItem hi = new SettingItem(UIEnv.getRsb().getString("advancedsettings"),
|
||||||
UIEnv.getFont().deriveFont(20.0f).deriveFont(Font.BOLD), CONST.itemwidth, CONST.settingheight);
|
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"),
|
congestions = new ComboSettingItem(UIEnv.getRsb().getString("congresscontrolalgorithm"),
|
||||||
CONST.itemwidth, CONST.settingheight);
|
CONST.itemwidth, CONST.settingheight);
|
||||||
comboCongress = congestions.getComboBox();
|
comboCongestion = congestions.getComboBox();
|
||||||
comboCongress.addItem("BBR");
|
comboCongestion.addItem("BBR");
|
||||||
comboCongress.addItem("Vegas2");
|
comboCongestion.addItem("Vegas2");
|
||||||
settings.getView().add(congestions);
|
settings.getView().add(congestions);
|
||||||
settings.updateScrool();
|
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"),
|
delayHbound = new SliderSettingItem(UIEnv.getRsb().getString("delayupperbound"),
|
||||||
CONST.itemwidth, CONST.settingheight);
|
CONST.itemwidth, CONST.settingheight);
|
||||||
delayHbound.getSlider().setMaximum(1000);
|
delayHbound.getSlider().setMaximum(300);
|
||||||
delayHbound.getSlider().setValue(200);
|
delayHbound.getSlider().setValue(200);
|
||||||
settings.getView().add(delayHbound);
|
settings.getView().add(delayHbound);
|
||||||
|
|
||||||
|
|
||||||
delayLbound = new SliderSettingItem(UIEnv.getRsb().getString("delaylowerbound"),
|
delayLbound = new SliderSettingItem(UIEnv.getRsb().getString("delaylowerbound"),
|
||||||
CONST.itemwidth, CONST.settingheight);
|
CONST.itemwidth, CONST.settingheight);
|
||||||
delayLbound.getSlider().setMaximum(500);
|
delayLbound.getSlider().setMaximum(300);
|
||||||
delayLbound.getSlider().setValue(150);
|
delayLbound.getSlider().setValue(150);
|
||||||
settings.getView().add(delayLbound);
|
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() {
|
ChangeListener clh= new ChangeListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1142,6 +1181,8 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
kck.setDenyLineTableBroadcast(denyBroadcast.isSelected());
|
kck.setDenyLineTableBroadcast(denyBroadcast.isSelected());
|
||||||
|
|
||||||
kck.setCongestionAlgorithm((String) congestions.getComboBox().getSelectedItem());
|
kck.setCongestionAlgorithm((String) congestions.getComboBox().getSelectedItem());
|
||||||
|
|
||||||
|
kck.setBurstLimit(1.0+burstLimit.getSlider().getValue()/1000.0);
|
||||||
|
|
||||||
kck.setDelayUpperBound(1.0+delayHbound.getSlider().getValue()/1000.0);
|
kck.setDelayUpperBound(1.0+delayHbound.getSlider().getValue()/1000.0);
|
||||||
|
|
||||||
@@ -1177,10 +1218,10 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
// 遍历所有线路,更新或添加TPanel2
|
// 遍历所有线路,更新或添加TPanel2
|
||||||
for (Object obj : kll) {
|
for (Object obj : kll) {
|
||||||
IPv6NetworkLink link = (IPv6NetworkLink) obj;
|
IPv6NetworkLink link = (IPv6NetworkLink) obj;
|
||||||
if (!(link instanceof KLALBRemoteLine)) {
|
if (!(link instanceof KLALBRemoteLink)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
KLALBRemoteLine ent = (KLALBRemoteLine) link;
|
KLALBRemoteLink ent = (KLALBRemoteLink) link;
|
||||||
|
|
||||||
Component[] count = ysp.getView().getComponents();
|
Component[] count = ysp.getView().getComponents();
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
@@ -1190,7 +1231,7 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
if (tp instanceof TPanel2) {
|
if (tp instanceof TPanel2) {
|
||||||
if (((TPanel2) tp).getTunnel().equals(ent)) {
|
if (((TPanel2) tp).getTunnel().equals(ent)) {
|
||||||
tp.setVisible(showoffline.isSelected() || (
|
tp.setVisible(showoffline.isSelected() || (
|
||||||
ent.getMonitor().getState() != MonitorData.DOWN));
|
ent.getState() != LinkStatus.DOWN));
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1201,7 +1242,7 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
TPanel2 tp = new TPanel2(ent, kc);
|
TPanel2 tp = new TPanel2(ent, kc);
|
||||||
tp.setVisible(showoffline.isSelected() || (
|
tp.setVisible(showoffline.isSelected() || (
|
||||||
ent.getMonitor().getState()!= MonitorData.DOWN));
|
ent.getState()!= LinkStatus.DOWN));
|
||||||
ysp.getView().add(tp);
|
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));
|
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());
|
String contt = Long.toString(kc.getIpv6Router().getKlalbRouteProtol().getDevicesFound());
|
||||||
if (!contt.equals(devicesOnline.getText())) {
|
if (!contt.equals(devicesOnline.getText())) {
|
||||||
@@ -1431,6 +1503,10 @@ public class KLALBStateGUI3 extends XFrame {
|
|||||||
}else {
|
}else {
|
||||||
congestions.getComboBox().setSelectedItem(con);
|
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();
|
double ub=kck.getDelayUpperBound();
|
||||||
if(ub!=0)
|
if(ub!=0)
|
||||||
delayHbound.getSlider().setValue((int) Math.round((ub-1.0)*1000));
|
delayHbound.getSlider().setValue((int) Math.round((ub-1.0)*1000));
|
||||||
|
|||||||
@@ -6,17 +6,10 @@ import java.awt.Dimension;
|
|||||||
|
|
||||||
import javax.swing.border.LineBorder;
|
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.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.jfree.data.general.DefaultValueDataset;
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
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.klalb.KLALBUtils;
|
||||||
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||||
import org.kne.cloud.network.perf.Kperf;
|
import org.kne.cloud.network.perf.Kperf;
|
||||||
@@ -24,12 +17,10 @@ import org.kne.cloud.network.perf.KperfReports;
|
|||||||
import org.kne.ui.XFrame;
|
import org.kne.ui.XFrame;
|
||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import javax.swing.JMenuBar;
|
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JMenu;
|
|
||||||
import java.awt.GridLayout;
|
import java.awt.GridLayout;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
|
|
||||||
@@ -43,7 +34,6 @@ import java.util.TimerTask;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.BoxLayout;
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
@@ -59,7 +49,6 @@ public class KperfGUI extends XFrame{
|
|||||||
private DefaultValueDataset upSpeed;
|
private DefaultValueDataset upSpeed;
|
||||||
private DefaultValueDataset upDataSpeed;
|
private DefaultValueDataset upDataSpeed;
|
||||||
private DialTextAnnotation upSpeedText;
|
private DialTextAnnotation upSpeedText;
|
||||||
private Dimension dashSize=new Dimension((int) (145 * 0.7), (int) (165 * 0.7));
|
|
||||||
private DefaultValueDataset downSpeed;
|
private DefaultValueDataset downSpeed;
|
||||||
private DefaultValueDataset downDataSpeed;
|
private DefaultValueDataset downDataSpeed;
|
||||||
private DialTextAnnotation downSpeedText;
|
private DialTextAnnotation downSpeedText;
|
||||||
@@ -227,6 +216,8 @@ public class KperfGUI extends XFrame{
|
|||||||
panel_6.add(downPPSLabel, BorderLayout.EAST);
|
panel_6.add(downPPSLabel, BorderLayout.EAST);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
upSpeed = new DefaultValueDataset(0);
|
upSpeed = new DefaultValueDataset(0);
|
||||||
upDataSpeed = new DefaultValueDataset(0);
|
upDataSpeed = new DefaultValueDataset(0);
|
||||||
@@ -466,7 +457,48 @@ public class KperfGUI extends XFrame{
|
|||||||
cpup1.setBackground(Color.WHITE);
|
cpup1.setBackground(Color.WHITE);
|
||||||
cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY));
|
cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
panel_6.add(cpup1, BorderLayout.WEST);
|
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();
|
JPanel panel_top = new JPanel();
|
||||||
panel_1.add(panel_top, BorderLayout.NORTH);
|
panel_1.add(panel_top, BorderLayout.NORTH);
|
||||||
panel_top.setLayout(new GridLayout(0, 2, 0, 0));
|
panel_top.setLayout(new GridLayout(0, 2, 0, 0));
|
||||||
@@ -497,7 +529,8 @@ public class KperfGUI extends XFrame{
|
|||||||
getTitlelabel().setForeground(Color.WHITE);
|
getTitlelabel().setForeground(Color.WHITE);
|
||||||
|
|
||||||
setTitle(UIEnv.getRsb().getString("klalbperf"));
|
setTitle(UIEnv.getRsb().getString("klalbperf"));
|
||||||
setSize((int)(1200*0.7),(int)( 800*0.7));
|
setSize(CONST.windowwidth,CONST.windowheight );
|
||||||
|
setResizable(false);
|
||||||
setLocationRelativeTo(comp);
|
setLocationRelativeTo(comp);
|
||||||
tsk=new TimerTask() {
|
tsk=new TimerTask() {
|
||||||
|
|
||||||
@@ -576,6 +609,9 @@ public class KperfGUI extends XFrame{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Image icon2;
|
private Image icon2;
|
||||||
private Image getIcon2() {
|
private Image getIcon2() {
|
||||||
if(icon2==null)
|
if(icon2==null)
|
||||||
|
|||||||
@@ -1,37 +1,29 @@
|
|||||||
package org.kne.cloud.network.klalb.ui;
|
package org.kne.cloud.network.klalb.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.GridLayout;
|
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.Date;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.border.LineBorder;
|
import javax.swing.border.LineBorder;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
import org.jfree.chart.ChartFactory;
|
import org.jfree.chart.ChartFactory;
|
||||||
import org.jfree.chart.ChartPanel;
|
|
||||||
import org.jfree.chart.ChartRenderingInfo;
|
|
||||||
import org.jfree.chart.JFreeChart;
|
import org.jfree.chart.JFreeChart;
|
||||||
import org.jfree.data.time.Millisecond;
|
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.TimeSeries;
|
||||||
import org.jfree.data.time.TimeSeriesCollection;
|
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.IPv6Address;
|
||||||
import org.kne.cloud.network.ipv6.IPv6AddressGroup;
|
import org.kne.cloud.network.ipv6.IPv6AddressGroup;
|
||||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||||
import org.kne.cloud.network.monitor.MonitorData;
|
import org.kne.cloud.network.klalb.KLALBRemoteLink;
|
||||||
|
import org.kne.cloud.network.monitor.LinkStatus;
|
||||||
import org.kne.cloud.network.monitor.TimestampMonitorValue;
|
import org.kne.cloud.network.monitor.TimestampMonitorValue;
|
||||||
import org.kne.math.Long128;
|
import org.kne.math.Long128;
|
||||||
import org.kne.ui.XFrame;
|
import org.kne.ui.XFrame;
|
||||||
@@ -41,39 +33,42 @@ import java.awt.BorderLayout;
|
|||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JLabel;
|
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.WindowEvent;
|
||||||
import java.awt.event.WindowListener;
|
import java.awt.event.WindowListener;
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.Font;
|
|
||||||
import javax.swing.SwingConstants;
|
|
||||||
import javax.swing.JSlider;
|
import javax.swing.JSlider;
|
||||||
|
|
||||||
public class LineMonitorGUI extends XFrame {
|
public class LineMonitorGUI extends XFrame {
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
private Timer timer1;
|
private Timer timer1;
|
||||||
private Timer timer2;
|
private Timer timer2;
|
||||||
|
private Timer timer3;
|
||||||
private TimerTask tsk3;
|
private TimerTask tsk3;
|
||||||
|
|
||||||
private TimerTask tsk4, tsk5;
|
private TimerTask tsk4, tsk5,tsk6;
|
||||||
private TimerTask d1;
|
private TimerTask d1;
|
||||||
private TimerTask d2;
|
private TimerTask d2;
|
||||||
|
private TimerTask d3;
|
||||||
|
|
||||||
private TimeSeries spdup = new TimeSeries(UIEnv.getRsb().getString("uploadspeed"));
|
private TimeSeries spdup = new TimeSeries(UIEnv.getRsb().getString("uploadspeed"));
|
||||||
private TimeSeries spddown = new TimeSeries(UIEnv.getRsb().getString("downloadspeed"));
|
private TimeSeries spddown = new TimeSeries(UIEnv.getRsb().getString("downloadspeed"));
|
||||||
|
|
||||||
private TimeSeries delayup = new TimeSeries(UIEnv.getRsb().getString("uploaddelay"));
|
private TimeSeries delayup = new TimeSeries(UIEnv.getRsb().getString("uploaddelay"));
|
||||||
private TimeSeries delaydown = new TimeSeries(UIEnv.getRsb().getString("downloaddelay"));
|
private TimeSeries delaydown = new TimeSeries(UIEnv.getRsb().getString("downloaddelay"));
|
||||||
// private TimeSeries delayupmin=new TimeSeries("Upload delay minimum");
|
private TimeSeries delayupmin=new TimeSeries(UIEnv.getRsb().getString("uploadbasedelay"));
|
||||||
// private TimeSeries delaydownmin=new TimeSeries("Download delay minimum");
|
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 jfc;
|
||||||
private JFreeChart jfce;
|
private JFreeChart jfce;
|
||||||
|
private JFreeChart jbfc;
|
||||||
private JLabel spdp;
|
private JLabel spdp;
|
||||||
private JLabel delp;
|
private JLabel delp;
|
||||||
|
private JLabel sbpdp;
|
||||||
private long timeRange = 5000;
|
private long timeRange = 5000;
|
||||||
private long[] values = new long[] { 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000 };
|
private long[] values = new long[] { 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000 };
|
||||||
private JPanel panel_1;
|
private JPanel panel_1;
|
||||||
@@ -81,20 +76,20 @@ public class LineMonitorGUI extends XFrame {
|
|||||||
|
|
||||||
// private ChartPanel delp;
|
// private ChartPanel delp;
|
||||||
// private ChartPanel spdp;
|
// private ChartPanel spdp;
|
||||||
public LineMonitorGUI(KLALBRemoteLine t) {
|
public LineMonitorGUI(KLALBRemoteLink t) {
|
||||||
this.tr = t;
|
this.tr = t;
|
||||||
setSize(1200, 780);
|
setSize(1200, 780);
|
||||||
setLocationRelativeTo(null);
|
setLocationRelativeTo(null);
|
||||||
|
|
||||||
setIconImage(UIEnv.getIcon());
|
setIconImage(UIEnv.getIcon());
|
||||||
setTitle("Line Monitor:" + t.getMonitor().getName());
|
setTitle("Line Monitor:" + t.getName());
|
||||||
setTitleColor(UIEnv.getDefaultTitleColor());
|
setTitleColor(UIEnv.getDefaultTitleColor());
|
||||||
getContentPane().setBackground(UIEnv.getDefaultBackgroundColor());
|
getContentPane().setBackground(UIEnv.getDefaultBackgroundColor());
|
||||||
getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f));
|
getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f));
|
||||||
getTitlepanel().setBorder(new LineBorder(Color.LIGHT_GRAY));
|
getTitlepanel().setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
|
|
||||||
JPanel jp = new JPanel();
|
JPanel jp = new JPanel();
|
||||||
jp.setLayout(new GridLayout(2, 1));
|
jp.setLayout(new GridLayout(2, 2));
|
||||||
getContentPane().add(jp);
|
getContentPane().add(jp);
|
||||||
|
|
||||||
TimeSeriesCollection tsc = new TimeSeriesCollection();
|
TimeSeriesCollection tsc = new TimeSeriesCollection();
|
||||||
@@ -110,12 +105,17 @@ public class LineMonitorGUI extends XFrame {
|
|||||||
spdp.setBorder(new LineBorder(Color.DARK_GRAY));
|
spdp.setBorder(new LineBorder(Color.DARK_GRAY));
|
||||||
jp.add(spdp);
|
jp.add(spdp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TimeSeriesCollection tsce = new TimeSeriesCollection();
|
TimeSeriesCollection tsce = new TimeSeriesCollection();
|
||||||
tsce.addSeries(delayup);
|
tsce.addSeries(delayup);
|
||||||
tsce.addSeries(delaydown);
|
tsce.addSeries(delaydown);
|
||||||
|
|
||||||
// tsce.addSeries(delayupmin);
|
tsce.addSeries(delayupmin);
|
||||||
// tsce.addSeries(delaydownmin);
|
tsce.addSeries(delaydownmin);
|
||||||
|
|
||||||
jfce = ChartFactory.createTimeSeriesChart(UIEnv.getRsb().getString("delaymonitor"),
|
jfce = ChartFactory.createTimeSeriesChart(UIEnv.getRsb().getString("delaymonitor"),
|
||||||
UIEnv.getRsb().getString("time") + "(s)", UIEnv.getRsb().getString("delay") + "(ms)", tsce);
|
UIEnv.getRsb().getString("time") + "(s)", UIEnv.getRsb().getString("delay") + "(ms)", tsce);
|
||||||
jfce.getXYPlot().setBackgroundPaint(Color.BLACK);
|
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,
|
BasicStroke dotted = new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0,
|
||||||
new float[] { 0, 6, 0, 6 }, 0);
|
new float[] { 0, 6, 0, 6 }, 0);
|
||||||
/*
|
|
||||||
* jfce.getXYPlot().getRenderer().setSeriesPaint(2,Color.RED);
|
jfce.getXYPlot().getRenderer().setSeriesPaint(2,Color.RED);
|
||||||
* jfce.getXYPlot().getRenderer().setSeriesStroke(2, dotted);
|
jfce.getXYPlot().getRenderer().setSeriesStroke(2, dotted);
|
||||||
* jfce.getXYPlot().getRenderer().setSeriesPaint(3,Color.GREEN);
|
jfce.getXYPlot().getRenderer().setSeriesPaint(3,Color.GREEN);
|
||||||
* jfce.getXYPlot().getRenderer().setSeriesStroke(3, dotted);
|
jfce.getXYPlot().getRenderer().setSeriesStroke(3, dotted);
|
||||||
*/
|
|
||||||
changeFont(jfce);
|
changeFont(jfce);
|
||||||
delp = new JLabel();
|
delp = new JLabel();
|
||||||
delp.setBorder(new LineBorder(Color.DARK_GRAY));
|
delp.setBorder(new LineBorder(Color.DARK_GRAY));
|
||||||
jp.add(delp);
|
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();
|
JPanel panel = new JPanel();
|
||||||
panel.setOpaque(false);
|
panel.setOpaque(false);
|
||||||
getContentPane().add(panel, BorderLayout.NORTH);
|
getContentPane().add(panel, BorderLayout.NORTH);
|
||||||
@@ -219,14 +242,25 @@ public class LineMonitorGUI extends XFrame {
|
|||||||
synchronized (jfc) {
|
synchronized (jfc) {
|
||||||
|
|
||||||
jfc.getXYPlot().getDomainAxis().setFixedAutoRange(timeRange);
|
jfc.getXYPlot().getDomainAxis().setFixedAutoRange(timeRange);
|
||||||
spdup.setMaximumItemCount((int) timeRange);
|
spdup.setMaximumItemCount((int) timeRange/5);
|
||||||
spddown.setMaximumItemCount((int) timeRange);
|
spddown.setMaximumItemCount((int) timeRange/5);
|
||||||
}
|
}
|
||||||
synchronized (jfce) {
|
synchronized (jfce) {
|
||||||
|
|
||||||
jfce.getXYPlot().getDomainAxis().setFixedAutoRange(timeRange);
|
jfce.getXYPlot().getDomainAxis().setFixedAutoRange(timeRange);
|
||||||
delayup.setMaximumItemCount((int) timeRange);
|
delayup.setMaximumItemCount((int) timeRange/5);
|
||||||
delaydown.setMaximumItemCount((int) timeRange);
|
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");
|
windowSelect.setText(timeRange / 1000 + "s");
|
||||||
}
|
}
|
||||||
@@ -269,11 +303,31 @@ public class LineMonitorGUI extends XFrame {
|
|||||||
new Date(valdown.getTimestamp().divide(new Long128(1000000L)).longValue()));
|
new Date(valdown.getTimestamp().divide(new Long128(1000000L)).longValue()));
|
||||||
delaydown.addOrUpdate(ms2, valdown.getDelay() / 1000000.0);
|
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<UUID, IPv6Packet> 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
|
@Override
|
||||||
public void setVisible(boolean b) {
|
public void setVisible(boolean b) {
|
||||||
if (b) {
|
if (b) {
|
||||||
@@ -281,6 +335,7 @@ public class LineMonitorGUI extends XFrame {
|
|||||||
timer = new Timer();
|
timer = new Timer();
|
||||||
timer1 = new Timer();
|
timer1 = new Timer();
|
||||||
timer2 = new Timer();
|
timer2 = new Timer();
|
||||||
|
timer3 = new Timer();
|
||||||
tsk3 = new TimerTask() {
|
tsk3 = new TimerTask() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -303,6 +358,13 @@ public class LineMonitorGUI extends XFrame {
|
|||||||
recordDelayData();
|
recordDelayData();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
tsk6 = new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
recordBufferData();
|
||||||
|
}
|
||||||
|
};
|
||||||
d1 = new TimerTask() {
|
d1 = new TimerTask() {
|
||||||
|
|
||||||
@Override
|
@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);
|
timer.scheduleAtFixedRate(tsk3, 25, 25);
|
||||||
timer1.scheduleAtFixedRate(tsk4, 5, 5);
|
timer1.scheduleAtFixedRate(tsk4, 10, 10);
|
||||||
timer1.scheduleAtFixedRate(d1, 25, 25);
|
timer1.scheduleAtFixedRate(d1, 25, 25);
|
||||||
timer2.scheduleAtFixedRate(tsk5, 1, 1);
|
timer2.scheduleAtFixedRate(tsk5, 10, 10);
|
||||||
timer2.scheduleAtFixedRate(d2, 25, 25);
|
timer2.scheduleAtFixedRate(d2, 25, 25);
|
||||||
|
timer3.scheduleAtFixedRate(tsk6, 10, 10);
|
||||||
|
timer3.scheduleAtFixedRate(d3, 25, 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -348,6 +426,8 @@ public class LineMonitorGUI extends XFrame {
|
|||||||
d1.cancel();
|
d1.cancel();
|
||||||
if (d2 != null)
|
if (d2 != null)
|
||||||
d2.cancel();
|
d2.cancel();
|
||||||
|
if (d3 != null)
|
||||||
|
d3.cancel();
|
||||||
if (timer != null)
|
if (timer != null)
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
if (timer1 != null)
|
if (timer1 != null)
|
||||||
@@ -355,20 +435,23 @@ public class LineMonitorGUI extends XFrame {
|
|||||||
|
|
||||||
if (timer2 != null)
|
if (timer2 != null)
|
||||||
timer2.cancel();
|
timer2.cancel();
|
||||||
|
|
||||||
|
if (timer3 != null)
|
||||||
|
timer3.cancel();
|
||||||
timer = null;
|
timer = null;
|
||||||
}
|
}
|
||||||
super.setVisible(b);
|
super.setVisible(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateTraffic() {
|
public void updateTraffic() {
|
||||||
switch (tr.getMonitor().getState()) {
|
switch (tr.getState()) {
|
||||||
case MonitorData.DOWN:
|
case LinkStatus.DOWN:
|
||||||
getTitlelabel().setForeground(Color.RED);
|
getTitlelabel().setForeground(Color.RED);
|
||||||
break;
|
break;
|
||||||
case MonitorData.UNSTABLE:
|
case LinkStatus.UNSTABLE:
|
||||||
getTitlelabel().setForeground(Color.YELLOW);
|
getTitlelabel().setForeground(Color.YELLOW);
|
||||||
break;
|
break;
|
||||||
case MonitorData.UP:
|
case LinkStatus.UP:
|
||||||
getTitlelabel().setForeground(Color.GREEN);
|
getTitlelabel().setForeground(Color.GREEN);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.kne.cloud.network.klalb.ui;
|
|||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Button;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
|
||||||
@@ -11,27 +10,22 @@ import javax.swing.SwingConstants;
|
|||||||
import javax.swing.border.LineBorder;
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
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.ipv6.IPv6AddressGroup;
|
||||||
import org.kne.cloud.network.klalb.CONST;
|
import org.kne.cloud.network.klalb.CONST;
|
||||||
import org.kne.cloud.network.klalb.KLALBController;
|
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.klalb.KLALBUtils;
|
||||||
import org.kne.cloud.network.monitor.MonitorData;
|
import org.kne.cloud.network.monitor.LinkStatus;
|
||||||
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.MenuItem;
|
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.datatransfer.StringSelection;
|
import java.awt.datatransfer.StringSelection;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.SocketTimeoutException;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
@@ -42,7 +36,7 @@ import javax.swing.JMenuItem;
|
|||||||
public class TPanel2 extends JPanel {
|
public class TPanel2 extends JPanel {
|
||||||
private JLabel tname;
|
private JLabel tname;
|
||||||
private JLabel targup;
|
private JLabel targup;
|
||||||
private KLALBRemoteLine tunnel;
|
private KLALBRemoteLink tunnel;
|
||||||
private LineMonitorGUI mdg;
|
private LineMonitorGUI mdg;
|
||||||
private JMenuItem mntmNewMenuItem2;
|
private JMenuItem mntmNewMenuItem2;
|
||||||
private JMenuItem mntmNewMenuItem3;
|
private JMenuItem mntmNewMenuItem3;
|
||||||
@@ -75,14 +69,14 @@ public class TPanel2 extends JPanel {
|
|||||||
/**
|
/**
|
||||||
* @wbp.parser.constructor
|
* @wbp.parser.constructor
|
||||||
*/
|
*/
|
||||||
public TPanel2(KLALBRemoteLine t,KLALBController kc) {
|
public TPanel2(KLALBRemoteLink t,KLALBController kc) {
|
||||||
this.tunnel = t;
|
this.tunnel = t;
|
||||||
//setOpaque(false);
|
//setOpaque(false);
|
||||||
setBackground(Color.WHITE);
|
setBackground(Color.WHITE);
|
||||||
setLayout(new BorderLayout(0, 0));
|
setLayout(new BorderLayout(0, 0));
|
||||||
|
|
||||||
tname = new JLabel();
|
tname = new JLabel();
|
||||||
tname.setText(t.getMonitor().getName());
|
tname.setText(t.getName());
|
||||||
tname.setFont(new Font("宋体", Font.BOLD, 14));
|
tname.setFont(new Font("宋体", Font.BOLD, 14));
|
||||||
|
|
||||||
targup = new JLabel();
|
targup = new JLabel();
|
||||||
@@ -311,8 +305,8 @@ public class TPanel2 extends JPanel {
|
|||||||
|
|
||||||
|
|
||||||
private void updateText() {
|
private void updateText() {
|
||||||
targup.setText(KLALBUtils. convertIBUint(tunnel.getMonitor().getOutTraffic()) + " " + KLALBUtils. convertIBUint(tunnel.getMonitor().getOutSpeed()) + "/s "+ KLALBUtils.convertUintNanoDefalut(tunnel.getMonitor().getOutDelay()) + "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().getInTraffic()) + " " + KLALBUtils. convertIBUint(tunnel.getMonitor().getInSpeed()) + "/s " + KLALBUtils.convertUintNanoDefalut( tunnel.getMonitor().getInDelay()) + "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) {
|
if(tunnel.getMonitor().getOutSpeed()>4096||tunnel.getMonitor().getInSpeed()>4096) {
|
||||||
lblNewLabel_2.setBackground(Color.ORANGE);
|
lblNewLabel_2.setBackground(Color.ORANGE);
|
||||||
@@ -321,22 +315,22 @@ public class TPanel2 extends JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLALBRemoteLine getTunnel() {
|
public KLALBRemoteLink getTunnel() {
|
||||||
return tunnel;
|
return tunnel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void updateTraffic() {
|
public void updateTraffic() {
|
||||||
switch (tunnel.getMonitor().getState()) {
|
switch (tunnel.getState()) {
|
||||||
case MonitorData.DOWN:
|
case LinkStatus.DOWN:
|
||||||
tname.setForeground(Color.RED);
|
tname.setForeground(Color.RED);
|
||||||
lblNewLabel_1.setBackground(Color.LIGHT_GRAY);
|
lblNewLabel_1.setBackground(Color.LIGHT_GRAY);
|
||||||
break;
|
break;
|
||||||
case MonitorData.UNSTABLE:
|
case LinkStatus.UNSTABLE:
|
||||||
tname.setForeground(Color.YELLOW);
|
tname.setForeground(Color.YELLOW);
|
||||||
lblNewLabel_1.setBackground(Color.LIGHT_GRAY);
|
lblNewLabel_1.setBackground(Color.LIGHT_GRAY);
|
||||||
break;
|
break;
|
||||||
case MonitorData.UP:
|
case LinkStatus.UP:
|
||||||
tname.setForeground(Color.GREEN);
|
tname.setForeground(Color.GREEN);
|
||||||
lblNewLabel_1.setBackground(Color.GREEN);
|
lblNewLabel_1.setBackground(Color.GREEN);
|
||||||
|
|
||||||
@@ -344,7 +338,7 @@ public class TPanel2 extends JPanel {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(tunnel.getMonitor().getState()!=MonitorData.DOWN) {
|
if(tunnel.getState()!=LinkStatus.DOWN) {
|
||||||
|
|
||||||
|
|
||||||
IPv6AddressGroup unvar=tunnel.getRemoteVaddr();
|
IPv6AddressGroup unvar=tunnel.getRemoteVaddr();
|
||||||
|
|||||||
@@ -1,32 +1,29 @@
|
|||||||
package org.kne.cloud.network.klalb.ui;
|
package org.kne.cloud.network.klalb.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Cursor;
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontFormatException;
|
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.Point;
|
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.geom.AffineTransform;
|
|
||||||
import java.io.IOException;
|
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.PropertyResourceBundle;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JColorChooser;
|
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.UnsupportedLookAndFeelException;
|
|
||||||
import javax.swing.plaf.ColorChooserUI;
|
import org.kne.ui.LinearGradientColor;
|
||||||
public class UIEnv {
|
public class UIEnv {
|
||||||
private static Font font;
|
private static Font font;
|
||||||
private static Image icon ;
|
private static Image icon ;
|
||||||
private static Color defaultcolor=new Color(207,218,223);//new Color(207,218,223)
|
private static Color defaultcolor=new Color(207,218,223);//new Color(207,218,223)
|
||||||
private static Color selectedcolor=new Color(207/2,218/2,223/2);
|
private static 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;
|
private static ResourceBundle rsb;
|
||||||
public static void setRsb(String xrsb) throws IOException {
|
public static void setRsb(String xrsb) throws IOException {
|
||||||
rsb=new PropertyResourceBundle(UIEnv.class.getResourceAsStream("/klalb_"+xrsb+".properties"));
|
rsb=new PropertyResourceBundle(UIEnv.class.getResourceAsStream("/klalb_"+xrsb+".properties"));
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
package org.kne.cloud.network.monitor;
|
package org.kne.cloud.network.monitor;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
@@ -63,28 +60,32 @@ public class ArrayListTimestampMonitor<K> implements TimestampMonitor<K> {
|
|||||||
|
|
||||||
private volatile long prev = System.nanoTime();
|
private volatile long prev = System.nanoTime();
|
||||||
|
|
||||||
public boolean recordPacket(K key, int length) {
|
/*public boolean recordPacket(K key,int count, int length) {
|
||||||
return recordPacket(key, clock.getCurrentTimeNanos(), length, Long.MAX_VALUE / 1024);
|
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) {
|
public boolean recordPacket(K key, Long128 timestamp,int count, int length) {
|
||||||
return recordPacket(key, clock.getCurrentTimeNanos(), length, delay);
|
return recordPacket(key, timestamp,count, length, Long.MAX_VALUE / 1024);
|
||||||
}
|
|
||||||
|
|
||||||
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 length, long delay) {
|
public boolean recordPacket(K key, Long128 timestamp,int count, int length, long delay) {
|
||||||
// 验证时间戳的合理性
|
// 验证时间戳的合理性
|
||||||
validateTimestamp(timestamp);
|
validateTimestamp(timestamp);
|
||||||
|
|
||||||
// 快速路径:尝试sequence=0
|
// 快速路径:尝试sequence=0
|
||||||
TimestampMonitorKey<K> monitorKey = new TimestampMonitorKey<>(key, 0);
|
TimestampMonitorKey<K> monitorKey = new TimestampMonitorKey<>(key, 0);
|
||||||
TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey, timestamp, length, delay);
|
TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey, timestamp,count, length, delay);
|
||||||
autoCleanup(cleanupThreshold);
|
autoCleanup(cleanupThreshold);
|
||||||
|
|
||||||
rwLock.writeLock().lock();
|
rwLock.writeLock().lock();
|
||||||
@@ -327,7 +328,7 @@ public class ArrayListTimestampMonitor<K> implements TimestampMonitor<K> {
|
|||||||
/**
|
/**
|
||||||
* 从已排序的列表中计算包数 - 优化版本,只需要startTime
|
* 从已排序的列表中计算包数 - 优化版本,只需要startTime
|
||||||
*/
|
*/
|
||||||
private long calculatePacketCountFromSortedList(List<TimestampMonitorValue> sortedList, Long128 startTime) {
|
/*private long calculatePacketCountFromSortedList(List<TimestampMonitorValue> sortedList, Long128 startTime) {
|
||||||
if (sortedList.isEmpty()) {
|
if (sortedList.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -340,8 +341,30 @@ public class ArrayListTimestampMonitor<K> implements TimestampMonitor<K> {
|
|||||||
|
|
||||||
// 计算从startIndex到末尾的所有包数(因为数据包不会来自未来)
|
// 计算从startIndex到末尾的所有包数(因为数据包不会来自未来)
|
||||||
return sortedList.size() - startIndex;
|
return sortedList.size() - startIndex;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
private long calculatePacketCountFromSortedList(List<TimestampMonitorValue> 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) {
|
public long calculateBandwidth(long timeWindowNs) {
|
||||||
return calculateBandwidth(clock.getCurrentTimeNanos(), timeWindowNs);
|
return calculateBandwidth(clock.getCurrentTimeNanos(), timeWindowNs);
|
||||||
}
|
}
|
||||||
@@ -413,7 +436,7 @@ public class ArrayListTimestampMonitor<K> implements TimestampMonitor<K> {
|
|||||||
// 计算从startIndex到末尾的所有数据(因为数据包不会来自未来)
|
// 计算从startIndex到末尾的所有数据(因为数据包不会来自未来)
|
||||||
for (int i = startIndex; i < sortedList.size(); i++) {
|
for (int i = startIndex; i < sortedList.size(); i++) {
|
||||||
TimestampMonitorValue value = sortedList.get(i);
|
TimestampMonitorValue value = sortedList.get(i);
|
||||||
stats.packetCount++;
|
stats.packetCount+=value.getCount();
|
||||||
stats.totalBytes += value.getLength();
|
stats.totalBytes += value.getLength();
|
||||||
|
|
||||||
if (stats.earliestTimestamp.equals(Long128.ZERO)
|
if (stats.earliestTimestamp.equals(Long128.ZERO)
|
||||||
@@ -490,7 +513,7 @@ public class ArrayListTimestampMonitor<K> implements TimestampMonitor<K> {
|
|||||||
100, 200000000L);
|
100, 200000000L);
|
||||||
Thread t = new Thread(() -> {
|
Thread t = new Thread(() -> {
|
||||||
while (true) {
|
while (true) {
|
||||||
monitor.recordPacket(along.getAndIncrement(), 1000);
|
monitor.recordPacket(along.getAndIncrement(),1, 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
t.start();
|
t.start();
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
package org.kne.cloud.network.monitor;
|
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.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.kne.cloud.clock.HighAccuracyClock;
|
import org.kne.cloud.clock.HighAccuracyClock;
|
||||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||||
@@ -65,27 +60,31 @@ private String name;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean recordPacket(K key, int length) {
|
public boolean recordPacket(K key, int count,int length) {
|
||||||
return recordPacket(key,clock.getCurrentTimeNanos(),length);
|
return recordPacket(key,clock.getCurrentTimeNanos(),count,length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean recordPacket(K key, Long128 timestamp, int length) {
|
public boolean recordPacket(K key, Long128 timestamp, int count,int length) {
|
||||||
return recordPacket(key, timestamp, length, Long.MAX_VALUE/1024);
|
return recordPacket(key, timestamp,count, length, Long.MAX_VALUE/1024);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean recordPacket(K key, int length, long delay) {
|
public boolean recordPacket(K key,int count, int length, long delay) {
|
||||||
return recordPacket(key,clock.getCurrentTimeNanos(),length,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);
|
autoCleanup(cleanupThreshold);
|
||||||
// 快速路径:尝试sequence=0
|
// 快速路径:尝试sequence=0
|
||||||
TimestampMonitorKey<K> monitorKey = new TimestampMonitorKey<>(key, 0);
|
TimestampMonitorKey<K> 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) {
|
if (entries.putIfAbsent(monitorKey, monitorValue) == null) {
|
||||||
totalDataSize.add(length);
|
totalDataSize.add(length);
|
||||||
@@ -96,7 +95,7 @@ private String name;
|
|||||||
// 重试路径(极少执行)
|
// 重试路径(极少执行)
|
||||||
for (int sequence = 0; sequence < maxRetry; sequence++) {
|
for (int sequence = 0; sequence < maxRetry; sequence++) {
|
||||||
monitorKey = new TimestampMonitorKey<>(key, 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) {
|
if (entries.putIfAbsent(monitorKey, monitorValue) == null) {
|
||||||
totalDataSize.add(length);
|
totalDataSize.add(length);
|
||||||
totalPackets.increment();
|
totalPackets.increment();
|
||||||
@@ -174,8 +173,9 @@ private String name;
|
|||||||
|
|
||||||
return entries.values().stream()
|
return entries.values().stream()
|
||||||
.filter(value -> (value.getTimestamp() .compareTo( startTime )>=0)&&
|
.filter(value -> (value.getTimestamp() .compareTo( startTime )>=0)&&
|
||||||
(value.getTimestamp().compareTo( currentTime) <=0) )
|
(value.getTimestamp().compareTo( currentTime) <=0) ).mapToLong(TimestampMonitorValue::getCount)
|
||||||
.count();
|
.sum();
|
||||||
|
// .count();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long calculateBandwidth(long timeWindowNs) {
|
public long calculateBandwidth(long timeWindowNs) {
|
||||||
@@ -226,7 +226,7 @@ private String name;
|
|||||||
.collect(
|
.collect(
|
||||||
TrafficStats::new,
|
TrafficStats::new,
|
||||||
(ts, value) -> {
|
(ts, value) -> {
|
||||||
ts.packetCount++;
|
ts.packetCount+=value.getCount();
|
||||||
ts.totalBytes += value.getLength();
|
ts.totalBytes += value.getLength();
|
||||||
if (ts.earliestTimestamp .equals(Long128.ZERO) || (value.getTimestamp() .compareTo( ts.earliestTimestamp)<0)) {
|
if (ts.earliestTimestamp .equals(Long128.ZERO) || (value.getTimestamp() .compareTo( ts.earliestTimestamp)<0)) {
|
||||||
ts.earliestTimestamp = value.getTimestamp();
|
ts.earliestTimestamp = value.getTimestamp();
|
||||||
@@ -277,7 +277,7 @@ private String name;
|
|||||||
Thread t=new Thread(()->{
|
Thread t=new Thread(()->{
|
||||||
long l=0;
|
long l=0;
|
||||||
while(true) {
|
while(true) {
|
||||||
monitor.recordPacket(l++, 1000);
|
monitor.recordPacket(l++,1, 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
t.start();
|
t.start();
|
||||||
|
|||||||
@@ -3,33 +3,12 @@ package org.kne.cloud.network.monitor;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public interface MonitorData extends Cloneable {
|
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<MonitorData> getChangeListener();
|
public Consumer<MonitorData> getChangeListener();
|
||||||
public void setChangeListener(Consumer<MonitorData> changeListener);
|
public void setChangeListener(Consumer<MonitorData> changeListener);
|
||||||
public String getName();
|
|
||||||
public void setName(String name);
|
|
||||||
@Override
|
@Override
|
||||||
public String toString();
|
public String toString();
|
||||||
|
|
||||||
public int getState();
|
public void update();
|
||||||
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 Object clone() throws CloneNotSupportedException;
|
public Object clone() throws CloneNotSupportedException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,11 @@
|
|||||||
package org.kne.cloud.network.monitor;
|
package org.kne.cloud.network.monitor;
|
||||||
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
|
||||||
public class MonitorDataImpl implements MonitorData {
|
public abstract 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() {
|
|
||||||
|
|
||||||
reliability=(reliability*999+(state==UP?1:0))/1000;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws Throwable {
|
|
||||||
ptt.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Timer getTimer() {
|
|
||||||
return timer;
|
|
||||||
}
|
|
||||||
private Consumer<MonitorData>changeListener;
|
private Consumer<MonitorData>changeListener;
|
||||||
|
|
||||||
public Consumer<MonitorData> getChangeListener() {
|
public Consumer<MonitorData> getChangeListener() {
|
||||||
@@ -48,42 +14,11 @@ private TimerTask ptt=new TimerTask() {
|
|||||||
public void setChangeListener(Consumer<MonitorData> changeListener) {
|
public void setChangeListener(Consumer<MonitorData> changeListener) {
|
||||||
this.changeListener = 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
|
@Override
|
||||||
public Object clone() throws CloneNotSupportedException {
|
public Object clone() throws CloneNotSupportedException {
|
||||||
return super.clone();
|
return super.clone();
|
||||||
|
|||||||
@@ -1,41 +1,49 @@
|
|||||||
package org.kne.cloud.network.monitor;
|
package org.kne.cloud.network.monitor;
|
||||||
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.kne.cloud.clock.HighAccuracyClock;
|
import org.kne.cloud.clock.HighAccuracyClock;
|
||||||
import org.kne.cloud.network.ipv6.PacketID;
|
|
||||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||||
|
|
||||||
public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonitorDataImpl implements SpeedAndTrafficMonitorData,DelayMonitorData{
|
public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonitorDataImpl implements SpeedAndTrafficMonitorData,DelayMonitorData{
|
||||||
|
|
||||||
private long timewindowmax=500000000L;
|
private long timewindowmax=500000000L;
|
||||||
|
|
||||||
|
private DelaySampler upSampler=new DelaySampler();
|
||||||
|
private DelaySampler downSampler=new DelaySampler();
|
||||||
|
|
||||||
private TimerTask pttxr=new TimerTask() {
|
long stime=System.nanoTime();
|
||||||
|
@Override
|
||||||
@Override
|
public void update() {
|
||||||
public void run() {
|
super.update();
|
||||||
long idelay=getInDelay();
|
upSampler.update();
|
||||||
if(inDelayMin==Long.MAX_VALUE||idelay<=inDelayMin) {
|
downSampler.update();
|
||||||
inDelayMin=idelay;
|
if(upSampler.getSnapshotPacketCount()>0&&upSampler.getSnapshotTotalDelay()>0) {
|
||||||
}else{
|
getUploadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, upSampler.getAvgDelayNanos());
|
||||||
inDelayMin=(inDelayMin*9999+idelay)/10000;
|
}
|
||||||
}
|
if(downSampler.getSnapshotPacketCount()>0&&downSampler.getSnapshotTotalDelay()>0) {
|
||||||
long odelay=getOutDelay();
|
getDownloadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, downSampler.getAvgDelayNanos());
|
||||||
if(outDelayMin==Long.MAX_VALUE||odelay<=outDelayMin) {
|
}
|
||||||
outDelayMin=odelay;
|
|
||||||
}else{
|
long time=System.nanoTime();
|
||||||
outDelayMin=(outDelayMin*9999+odelay)/10000;
|
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
|
@Override
|
||||||
public String toString() {
|
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
|
@Override
|
||||||
|
|||||||
@@ -1,30 +1,27 @@
|
|||||||
package org.kne.cloud.network.monitor;
|
package org.kne.cloud.network.monitor;
|
||||||
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.UUID;
|
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.clock.HighAccuracyClock;
|
||||||
import org.kne.cloud.network.ipv6.PacketID;
|
|
||||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||||
|
|
||||||
public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements SpeedAndTrafficMonitorData {
|
public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements SpeedAndTrafficMonitorData {
|
||||||
|
|
||||||
private TimestampMonitor<UUID>uploadBandwidth;
|
private TimestampMonitor<UUID>uploadBandwidth;
|
||||||
private TimestampMonitor<UUID>downloadBandwidth;
|
private TimestampMonitor<UUID>downloadBandwidth;
|
||||||
private long timewindow=200000000L;
|
private long timewindow=1000000000L;
|
||||||
private long timewindowmax=200000000L;
|
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) {
|
public SpeedAndTrafficMonitorDataImpl(HighAccuracyClock clock) {
|
||||||
super();
|
super();
|
||||||
this.clock=clock;
|
this.clock=clock;
|
||||||
uploadBandwidth=new ArrayListTimestampMonitor<UUID>(clock,"UploadMonitor", 100, 500000000L);
|
uploadBandwidth=new ArrayListTimestampMonitor<UUID>(clock,"UploadMonitor", 100, 5000000000L);
|
||||||
downloadBandwidth=new ArrayListTimestampMonitor<UUID>(clock,"DownloadMonitor", 100, 500000000L);
|
downloadBandwidth=new ArrayListTimestampMonitor<UUID>(clock,"DownloadMonitor", 100, 5000000000L);
|
||||||
|
|
||||||
getTimer().scheduleAtFixedRate(pttx, timewindowmax/1000000, timewindowmax/1000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HighAccuracyClock clock;
|
private HighAccuracyClock clock;
|
||||||
@@ -42,7 +39,6 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
|
|||||||
this.uploadBandwidth = uploadBandwidth;
|
this.uploadBandwidth = uploadBandwidth;
|
||||||
this.downloadBandwidth = downloadBandwidth;
|
this.downloadBandwidth = downloadBandwidth;
|
||||||
|
|
||||||
getTimer().scheduleAtFixedRate(pttx, timewindowmax/1000000, timewindowmax/1000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -70,9 +66,11 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb=new StringBuilder(super.toString());
|
StringBuilder sb=new StringBuilder();
|
||||||
sb.append('\t');
|
sb.append(KLALBUtils.convertIBUint(uploadBandwidth.calculateBandwidth(timewindow))).append("/s\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");
|
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) {
|
/*if(getState()==OFFLINE) {
|
||||||
sb.append((coolingTime-(System.currentTimeMillis()-mls))/1000L);
|
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() {
|
public long getOutSpeed() {
|
||||||
long curr=System.nanoTime();
|
return uploadBandwidth.calculateBandwidth(timewindow);
|
||||||
if(curr-outspeedTimeout>CALC_TIMEOUT) {
|
|
||||||
outspeedTimeout=curr;
|
|
||||||
outSpeed=uploadBandwidth.calculateBandwidth(timewindow);
|
|
||||||
}
|
|
||||||
return outSpeed;
|
|
||||||
}
|
}
|
||||||
private volatile long inspeedTimeout=System.nanoTime();
|
|
||||||
public long getInSpeed() {
|
public long getInSpeed() {
|
||||||
long curr=System.nanoTime();
|
return downloadBandwidth.calculateBandwidth(timewindow);
|
||||||
if(curr-inspeedTimeout>CALC_TIMEOUT) {
|
|
||||||
inspeedTimeout=curr;
|
|
||||||
inSpeed=downloadBandwidth.calculateBandwidth(timewindow);
|
|
||||||
}
|
|
||||||
return inSpeed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -161,40 +146,49 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
|
|||||||
return inPPSMax;
|
return inPPSMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimerTask pttx=new TimerTask() {
|
public void recordUploadPacket(int databytes) {
|
||||||
|
upSampler.recordPacket(databytes);
|
||||||
@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 recordDownloadPacket(int databytes) {
|
||||||
|
downSampler.recordPacket(databytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
long stime=System.nanoTime();
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
public void update() {
|
||||||
pttx.cancel();
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public interface TimestampMonitor<K> {
|
|||||||
* @param length 数据包长度
|
* @param length 数据包长度
|
||||||
* @return 是否记录成功
|
* @return 是否记录成功
|
||||||
*/
|
*/
|
||||||
boolean recordPacket(K key, int length);
|
boolean recordPacket(K key,int count, int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录数据包(使用指定时间戳)
|
* 记录数据包(使用指定时间戳)
|
||||||
@@ -44,12 +44,12 @@ public interface TimestampMonitor<K> {
|
|||||||
* @param length 数据包长度
|
* @param length 数据包长度
|
||||||
* @return 是否记录成功
|
* @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);
|
||||||
|
|
||||||
// ==================== 清理维护方法 ====================
|
// ==================== 清理维护方法 ====================
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
package org.kne.cloud.network.monitor;
|
package org.kne.cloud.network.monitor;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import org.kne.math.Long128;
|
import org.kne.math.Long128;
|
||||||
|
|
||||||
public class TimestampMonitorValue implements Comparable<TimestampMonitorValue> {
|
public class TimestampMonitorValue implements Comparable<TimestampMonitorValue> {
|
||||||
private final Long128 timestamp;
|
private final Long128 timestamp;
|
||||||
|
private final int count;
|
||||||
private final int length;
|
private final int length;
|
||||||
private final TimestampMonitorKey<?> key;
|
private final TimestampMonitorKey<?> key;
|
||||||
private long delay;
|
private long delay;
|
||||||
public TimestampMonitorValue(TimestampMonitorKey<?> key, Long128 timestamp, int length) {
|
public TimestampMonitorValue(TimestampMonitorKey<?> key, Long128 timestamp,int count, int length) {
|
||||||
this(key,timestamp,length,Long.MAX_VALUE/1024);
|
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.key = key;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
|
this.count=count;
|
||||||
this.length = length;
|
this.length = length;
|
||||||
this.delay=delay;
|
this.delay=delay;
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,11 @@ public class TimestampMonitorValue implements Comparable<TimestampMonitorValue>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Long128 getTimestamp() { return timestamp; }
|
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; }
|
public TimestampMonitorKey<?> getKey() { return key; }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package org.kne.cloud.network.ntp;
|
|||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.security.Timestamp;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -16,13 +14,8 @@ import java.util.Map.Entry;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
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.HighAccuracyClock;
|
||||||
import org.kne.cloud.clock.NTPTimestamps;
|
import org.kne.cloud.clock.NTPTimestamps;
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
@@ -33,12 +26,12 @@ import org.kne.math.Long128;
|
|||||||
public class NTPContext implements Closeable, AutoCloseable {
|
public class NTPContext implements Closeable, AutoCloseable {
|
||||||
private HighAccuracyClock clock;
|
private HighAccuracyClock clock;
|
||||||
private static final boolean debug = false;
|
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 systemFrequencyOffset = NTPTimestamps.nanosToNtp128BitTimeInterval(new Long128(5000));
|
||||||
private Long128 localPrecision = NTPTimestamps.nanosToNtp128BitTimeInterval(new Long128(1000));
|
private Long128 localPrecision = NTPTimestamps.nanosToNtp128BitTimeInterval(new Long128(1000));
|
||||||
private static final Long128 adjustThreshold0 = Long128.valueOf(1000000000L);
|
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 AtomicBoolean firstSync=new AtomicBoolean(true);
|
||||||
|
|
||||||
private int minStratum = 16;
|
private int minStratum = 16;
|
||||||
@@ -74,7 +67,7 @@ public class NTPContext implements Closeable, AutoCloseable {
|
|||||||
|
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
}
|
}
|
||||||
Thread.sleep(1000);
|
Thread.sleep(500);
|
||||||
|
|
||||||
if (!mlp.isEmpty())
|
if (!mlp.isEmpty())
|
||||||
mergeAndApply();
|
mergeAndApply();
|
||||||
@@ -222,9 +215,8 @@ public class NTPContext implements Closeable, AutoCloseable {
|
|||||||
selectAndApply(peerInfo);
|
selectAndApply(peerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AtomicLong prevAdjustTime = new AtomicLong(System.nanoTime());
|
|
||||||
private volatile Long128 deltaRemaining;
|
|
||||||
private long avgAdj=0;
|
private long avgAdj=0;
|
||||||
|
private Long128 inte=new Long128(0);
|
||||||
private void selectAndApply(List<PeerInfo> peerInfo) {
|
private void selectAndApply(List<PeerInfo> peerInfo) {
|
||||||
Collections.sort(peerInfo);
|
Collections.sort(peerInfo);
|
||||||
if(debug)
|
if(debug)
|
||||||
@@ -240,31 +232,34 @@ public class NTPContext implements Closeable, AutoCloseable {
|
|||||||
Long128 adjt = pi.getAdj();
|
Long128 adjt = pi.getAdj();
|
||||||
bi = bi.add(adjt);
|
bi = bi.add(adjt);
|
||||||
}
|
}
|
||||||
Long128 adj = bi.divide(Long128.valueOf(i));
|
Long128 delta = bi.divide(Long128.valueOf(i));
|
||||||
avgAdj=(avgAdj*7+adj.abs().longValue())/8;
|
avgAdj=(avgAdj*7+delta.abs().longValue())/8;
|
||||||
Long128 adjustment;
|
Long128 deltaabs=delta.abs();
|
||||||
Long128 adjabs=adj.abs();
|
if (deltaabs.compareTo(adjustThreshold0) > 0&&firstSync.compareAndSet(true, false)) {
|
||||||
if (adjabs.compareTo(adjustThreshold0) > 0&&firstSync.compareAndSet(true, false)) {
|
Long128 adjustment=delta;
|
||||||
adjustment=adj;
|
clock.adjustClock( adjustment);
|
||||||
}else if (adjabs.compareTo(adjustThreshold1) > 0) {
|
if(debug)
|
||||||
adjustment = Long128.valueOf(new BigDecimal(adj.toBigInteger()).multiply(BigDecimal.valueOf(0.5)).toBigInteger());
|
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 {
|
} else {
|
||||||
adjustment = Long128.valueOf(new BigDecimal(adj.toBigInteger()).multiply(BigDecimal.valueOf(0.0625/2)).toBigInteger());
|
Long128 fadj = delta.divide(20).add(inte.divide(200));
|
||||||
if (deltaRemaining != null) {
|
clock.setFrequency(1000000000L+fadj.longValue());
|
||||||
long curr = System.nanoTime();
|
inte=inte.add(delta);
|
||||||
long old = prevAdjustTime.getAndSet(curr);
|
if(inte.compareTo(Long128.valueOf(5000000))>0) {
|
||||||
Long128 fadj = adjustment.multiply(Long128.valueOf(TimeUnit.SECONDS.toNanos(1)))
|
inte=Long128.valueOf(5000000);
|
||||||
.divide(Long128.valueOf(curr - old));
|
}else if(inte.compareTo(Long128.valueOf(-5000000))<0) {
|
||||||
Long128 fadjustment = Long128.valueOf( new BigDecimal(fadj.toBigInteger()).multiply(BigDecimal.valueOf(0.015625/4)).toBigInteger());
|
inte=Long128.valueOf(-5000000);
|
||||||
clock.adjustFrequency(fadjustment.longValue());
|
}
|
||||||
if(debug)
|
if(debug)
|
||||||
System.out.println("fadj:" + fadjustment + " f:" + clock.getFrequency());
|
System.out.println("inte:"+inte+" fadj:" + fadj);
|
||||||
}
|
|
||||||
deltaRemaining = adj.subtract(adjustment);
|
|
||||||
}
|
}
|
||||||
clock.adjustClock( adjustment);
|
|
||||||
if(debug)
|
if(debug)
|
||||||
System.out.println("delta:" + adjustment + " deltaRemaining:" + deltaRemaining);
|
System.out.println("delta:"+delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.kne.cloud.network.ntp;
|
|||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
import java.net.DatagramSocket;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@@ -14,10 +13,8 @@ import java.util.Collections;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@@ -30,7 +27,7 @@ import org.kne.math.Long128;
|
|||||||
public class NTPv4Protocol implements Closeable, AutoCloseable {
|
public class NTPv4Protocol implements Closeable, AutoCloseable {
|
||||||
private static final boolean showPacket = false;
|
private static final boolean showPacket = false;
|
||||||
public static final int NTP_DEFAULT_PORT = 123;
|
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 REQUEST_TIMEOUT = 10000000000L;
|
||||||
private static final long EPHEMERAL_TIMEOUT = 60000000000L;
|
private static final long EPHEMERAL_TIMEOUT = 60000000000L;
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +1,23 @@
|
|||||||
package org.kne.cloud.network.perf;
|
package org.kne.cloud.network.perf;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.nio.channels.UnresolvedAddressException;
|
import java.nio.channels.UnresolvedAddressException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
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.AdjustedNanoClock;
|
||||||
import org.kne.cloud.clock.HighAccuracyClock;
|
import org.kne.cloud.clock.HighAccuracyClock;
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.SpeedLimiter;
|
import org.kne.cloud.network.SpeedLimiter;
|
||||||
import org.kne.cloud.network.ThreadTool;
|
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.KLALBPacket;
|
||||||
import org.kne.cloud.network.klalb.KLALBPacketLink;
|
import org.kne.cloud.network.klalb.KLALBPacketLink;
|
||||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||||
import org.kne.cloud.network.klalb.PINGPacket;
|
import org.kne.cloud.network.klalb.PINGPacket;
|
||||||
import org.kne.cloud.network.klalb.PONGPacket;
|
import org.kne.cloud.network.klalb.PONGPacket;
|
||||||
import org.kne.cloud.network.klalb.VADDRACKPacket;
|
import org.kne.cloud.network.monitor.LinkStatus;
|
||||||
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.SpeedAndTrafficAndDelayMonitorDataImpl;
|
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||||
|
import org.kne.concurrent.ThreadParker;
|
||||||
import com.github.f4b6a3.uuid.UuidCreator;
|
|
||||||
|
|
||||||
public class Kperf implements Runnable{
|
public class Kperf implements Runnable{
|
||||||
|
|
||||||
@@ -52,11 +36,13 @@ public class Kperf implements Runnable{
|
|||||||
private MultipurposeSocketAddress bindAddress;
|
private MultipurposeSocketAddress bindAddress;
|
||||||
private volatile boolean connected=false;
|
private volatile boolean connected=false;
|
||||||
private volatile KLALBPacketLink link;
|
private volatile KLALBPacketLink link;
|
||||||
|
|
||||||
|
private LinkStatus status=new LinkStatus();
|
||||||
private SpeedAndTrafficAndDelayMonitorDataImpl monitor=new SpeedAndTrafficAndDelayMonitorDataImpl(HighAccuracyClock.SYSTEM_CLOCK);
|
private SpeedAndTrafficAndDelayMonitorDataImpl monitor=new SpeedAndTrafficAndDelayMonitorDataImpl(HighAccuracyClock.SYSTEM_CLOCK);
|
||||||
|
|
||||||
private volatile boolean closed = false;
|
private volatile boolean closed = false;
|
||||||
|
|
||||||
private volatile Thread tlock;
|
private volatile ThreadParker tlock=new ThreadParker();
|
||||||
public Kperf(MultipurposeSocketAddress targetAddress,MultipurposeSocketAddress bindAddress) {
|
public Kperf(MultipurposeSocketAddress targetAddress,MultipurposeSocketAddress bindAddress) {
|
||||||
Objects.requireNonNull(targetAddress);
|
Objects.requireNonNull(targetAddress);
|
||||||
this.targetAddress=targetAddress;
|
this.targetAddress=targetAddress;
|
||||||
@@ -90,9 +76,6 @@ public class Kperf implements Runnable{
|
|||||||
private SpeedLimiter test = new SpeedLimiter(MIN_SPEED,10000000L);
|
private SpeedLimiter test = new SpeedLimiter(MIN_SPEED,10000000L);
|
||||||
|
|
||||||
private static long MIN_SPEED=64*1024L;
|
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();
|
private long starttime=System.nanoTime();
|
||||||
long totaltime=1000;
|
long totaltime=1000;
|
||||||
long usedtime=0;
|
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:f189:7589:f1f7:6f5e:b2eb:1]:4564
|
||||||
//kperf {KLALB_Stream}[2486:1::8888]:4564
|
//kperf {KLALB_Stream}[2486:1::8888]:4564
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void run() {
|
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("测速控制线程", () -> {
|
Thread tc = ThreadTool.makeVDaemonThreadIfSupport("测速控制线程", () -> {
|
||||||
final int wtimes=5;
|
final int wtimes=5;
|
||||||
totaltime=(20*1000*1+20*1000*4+wtimes*1000*5)*1000000L;
|
totaltime=(20*1000*1+20*1000*4+wtimes*1000*5)*1000000L;
|
||||||
@@ -113,12 +132,10 @@ public class Kperf implements Runnable{
|
|||||||
try {
|
try {
|
||||||
long startTime;
|
long startTime;
|
||||||
|
|
||||||
System.out.println("测试1/5:延迟测试");
|
System.out.println("测试1/3:延迟测试");
|
||||||
test.setLimitspeed(0);
|
test.setLimitspeed(0);
|
||||||
startTime=System.nanoTime();
|
startTime=System.nanoTime();
|
||||||
for (int i = 0; i < 20; i++) {
|
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);
|
Thread.sleep(1000);
|
||||||
updateUsedTime();
|
updateUsedTime();
|
||||||
}
|
}
|
||||||
@@ -133,131 +150,39 @@ public class Kperf implements Runnable{
|
|||||||
|
|
||||||
|
|
||||||
startTime=System.nanoTime();
|
startTime=System.nanoTime();
|
||||||
if(targetAddress!=null) {
|
|
||||||
System.out.println("测试2/5:下载带宽测试");
|
System.out.println("测试2/3:带宽测试");
|
||||||
test.setLimitspeed(0);
|
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||||
testPacket=new TESTNPacket(60000);
|
testPacket=new TESTNPacket(65535);
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 60; i++) {
|
||||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
|
||||||
System.out.printf("下载带宽:%s/s\n", KLALBUtils.convertIBUint(monitor.getInSpeed()));
|
|
||||||
Thread.sleep(1000);
|
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) {
|
if(reports!=null) {
|
||||||
reports.downloadSpeedFinish(monitor.getInSpeed());
|
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());
|
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");
|
System.out.println("等待时间"+wtimes+"s");
|
||||||
Thread.sleep(wtimes*1000);
|
Thread.sleep(wtimes*1000);
|
||||||
|
|
||||||
|
|
||||||
startTime=System.nanoTime();
|
startTime=System.nanoTime();
|
||||||
if(targetAddress!=null) {
|
System.out.println("测试3/3:包转发率测试");
|
||||||
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:上传包转发率测试");
|
|
||||||
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||||
testPacket=new TEST1Packet();
|
testPacket=new TEST1Packet();
|
||||||
for (int i = 0; i < 20; i++) {
|
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);
|
Thread.sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(reports!=null) {
|
if(reports!=null) {
|
||||||
reports.uploadPPSFinish(monitor.getOutPPS());
|
reports.uploadPPSFinish(monitor.getOutPPS());
|
||||||
}
|
reports.downloadPPSFinish(monitor.getInPPS());
|
||||||
}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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
System.out.println("等待时间"+wtimes+"s");
|
System.out.println("等待时间"+wtimes+"s");
|
||||||
Thread.sleep(wtimes*1000);
|
Thread.sleep(wtimes*1000);
|
||||||
|
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
//System.out.println("测速被中断!");
|
//System.out.println("测速被中断!");
|
||||||
@@ -269,7 +194,7 @@ public class Kperf implements Runnable{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
monitor.setState(MonitorData.UNSTABLE);
|
status.setState(LinkStatus.UNSTABLE);
|
||||||
if(link==null)
|
if(link==null)
|
||||||
link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,false,20000);
|
link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,false,20000);
|
||||||
|
|
||||||
@@ -278,18 +203,12 @@ public class Kperf implements Runnable{
|
|||||||
|
|
||||||
|
|
||||||
Thread t = ThreadTool.makeVDaemonThreadIfSupport("测速发送线程", () -> {
|
Thread t = ThreadTool.makeVDaemonThreadIfSupport("测速发送线程", () -> {
|
||||||
tlock = Thread.currentThread();
|
|
||||||
try {
|
try {
|
||||||
KLALBPacket kpp = null;
|
KLALBPacket kpp = null;
|
||||||
|
|
||||||
while ((!link.isClosed()) && (!closed)) {
|
while ((!link.isClosed()) && (!closed)) {
|
||||||
// TimeDebugger tdb=new TimeDebugger();
|
|
||||||
// tdb.putTime("start");
|
|
||||||
if(checkBandwidthReportTime()) {
|
|
||||||
writePacketToKPL(new BWINFPacket(monitor.getOutSpeed(), monitor.getInSpeed()));
|
|
||||||
}
|
|
||||||
if (checkPingTimeSleep()) {
|
if (checkPingTimeSleep()) {
|
||||||
writePacketToKPL(new PINGPacket(System.nanoTime(),monitor.getOutSpeed(), monitor.getInSpeed()));
|
writePacketToKPL(new PINGPacket(System.nanoTime(),0, 0));
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
KLALBPacket kpip = IsendDequeList.poll();
|
KLALBPacket kpip = IsendDequeList.poll();
|
||||||
@@ -305,12 +224,10 @@ public class Kperf implements Runnable{
|
|||||||
|
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
LockSupport.parkNanos(1000000);
|
tlock.parkNanos(1000000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.yield();
|
|
||||||
}
|
}
|
||||||
} catch (IOException | UnresolvedAddressException e) {
|
} catch (IOException | UnresolvedAddressException e) {
|
||||||
if (debug)
|
if (debug)
|
||||||
@@ -334,19 +251,20 @@ public class Kperf implements Runnable{
|
|||||||
}
|
}
|
||||||
switch (kpp.getType()) {
|
switch (kpp.getType()) {
|
||||||
case KLALBPacket.PING:
|
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;
|
break;
|
||||||
case KLALBPacket.PONG:
|
case KLALBPacket.PONG:
|
||||||
if (fst) {
|
if (fst) {
|
||||||
// coll.resetCoolingTime();
|
// coll.resetCoolingTime();
|
||||||
|
|
||||||
monitor.setState(MonitorData.UP);
|
status.setState(LinkStatus.UP);
|
||||||
connected=true;
|
connected=true;
|
||||||
if(targetAddress!=null) {
|
if(targetAddress!=null) {
|
||||||
System.out.println("连接地址"+targetAddress+"成功!");
|
System.out.println("连接地址"+targetAddress+"成功!");
|
||||||
}else {
|
}else {
|
||||||
System.out.println("接受地址"+link.toString()+"连接成功!");
|
System.out.println("接受地址"+link.toString()+"连接成功!");
|
||||||
}
|
}
|
||||||
|
tcc.start();
|
||||||
tc.start();
|
tc.start();
|
||||||
fst = false;
|
fst = false;
|
||||||
}
|
}
|
||||||
@@ -383,41 +301,24 @@ public class Kperf implements Runnable{
|
|||||||
adjnc.getLock().unlock();
|
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() ;
|
updateUsedTime() ;
|
||||||
if(reports!=null)
|
if(reports!=null)
|
||||||
reports.updateDial(monitor);
|
reports.updateDial(monitor);
|
||||||
break;
|
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:
|
case KLALBPacket.TESTN:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Thread.yield();
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if(monitor.getState()==MonitorData.UNSTABLE)
|
if(status.getState()==LinkStatus.UNSTABLE)
|
||||||
System.out.println("连接目标地址失败!");
|
System.out.println("连接目标地址失败!");
|
||||||
if(debug)
|
if(debug)
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
||||||
}finally {
|
}finally {
|
||||||
monitor.setState(MonitorData.DOWN);
|
status.setState(LinkStatus.DOWN);
|
||||||
if(link!=null) {
|
if(link!=null) {
|
||||||
try {
|
try {
|
||||||
link.close();
|
link.close();
|
||||||
@@ -426,6 +327,7 @@ public class Kperf implements Runnable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tc.interrupt();
|
tc.interrupt();
|
||||||
|
tcc.interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void updateUsedTime() {
|
private void updateUsedTime() {
|
||||||
@@ -485,7 +387,7 @@ public class Kperf implements Runnable{
|
|||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
closed = true;
|
closed = true;
|
||||||
monitor.setState(MonitorData.DOWN);
|
status.setState(LinkStatus.DOWN);
|
||||||
try {
|
try {
|
||||||
if (link != null)
|
if (link != null)
|
||||||
link.close();
|
link.close();
|
||||||
@@ -503,7 +405,7 @@ public class Kperf implements Runnable{
|
|||||||
|
|
||||||
private void sendIPacket(KLALBPacket blk) {
|
private void sendIPacket(KLALBPacket blk) {
|
||||||
IsendDequeList.add(blk);
|
IsendDequeList.add(blk);
|
||||||
LockSupport.unpark(tlock);
|
tlock.unpark();
|
||||||
}
|
}
|
||||||
|
|
||||||
private KLALBPacket readPacketFromKPL() throws IOException {
|
private KLALBPacket readPacketFromKPL() throws IOException {
|
||||||
@@ -513,20 +415,19 @@ public class Kperf implements Runnable{
|
|||||||
System.out.println("RX:" + packet);
|
System.out.println("RX:" + packet);
|
||||||
}
|
}
|
||||||
if (packet != null) {
|
if (packet != null) {
|
||||||
packet.putTimePassport("received");
|
|
||||||
long length=packet.getTotalLength();
|
long length=packet.getTotalLength();
|
||||||
monitor.getDownloadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), (int)length);
|
//monitor.getDownloadBandwidth().recordPacket(KLALBUtils.createGlobalUUID(), (int)length);
|
||||||
|
monitor.recordDownloadPacket((int)length);
|
||||||
}
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writePacketToKPL(KLALBPacket packet) throws IOException {
|
private void writePacketToKPL(KLALBPacket packet) throws IOException {
|
||||||
long length=packet.getTotalLength();
|
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.writeKLALBPacket(packet);
|
||||||
link.flush();
|
link.flush();
|
||||||
packet.putTimePassport("sended");
|
|
||||||
packet.printPassport();
|
|
||||||
|
|
||||||
if (showpacket) {
|
if (showpacket) {
|
||||||
System.err.println("TX:" + packet);
|
System.err.println("TX:" + packet);
|
||||||
@@ -535,6 +436,8 @@ public class Kperf implements Runnable{
|
|||||||
|
|
||||||
|
|
||||||
public void startPerfing() {
|
public void startPerfing() {
|
||||||
ThreadTool.makeVThreadIfSupport("测速接收线程" ,this).start();
|
monitorUpdater=new MonitorUpdater();
|
||||||
|
ThreadTool.makeVDaemonThread("线路性能采样线程", monitorUpdater).start();
|
||||||
|
ThreadTool.makeVDaemonThreadIfSupport("测速接收线程" ,this).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,14 @@ import java.io.IOException;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.channels.ServerSocketChannel;
|
import java.nio.channels.ServerSocketChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.SocketChannelListener;
|
import org.kne.cloud.network.SocketChannelListener;
|
||||||
import org.kne.cloud.network.ThreadTool;
|
import org.kne.cloud.network.ThreadTool;
|
||||||
import org.kne.cloud.network.klalb.KLALBController;
|
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;
|
import org.kne.cloud.network.klalb.StreamChannelKLALBPacketLink;
|
||||||
|
|
||||||
public class NodeBenchmark implements Runnable{
|
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)));
|
SocketChannelListener scl=new SocketChannelListener(ServerSocketChannel.open().bind(new InetSocketAddress("127.0.0.8",0)));
|
||||||
scl.setCon((c)->{
|
scl.setCon((c)->{
|
||||||
try {
|
try {
|
||||||
kct.addRemoteLine(new KLALBRemoteLine(klalbController,new StreamChannelKLALBPacketLink(c)));
|
kct.addRemoteLine(new KLALBRemoteLink(klalbController,new StreamChannelKLALBPacketLink(c)));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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<Inet6Address> addresses;
|
|
||||||
private final List<SRv6TLV> tlvs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A static factory method. This method validates the arguments by {@link
|
|
||||||
* ByteArrays#validateBounds(byte[], int, int)}, which may throw exceptions undocumented here.
|
|
||||||
*
|
|
||||||
* @param rawData rawData
|
|
||||||
* @param offset offset
|
|
||||||
* @param length length
|
|
||||||
* @return a new IpV6RoutingSourceRouteData object.
|
|
||||||
* @throws IllegalRawDataException if parsing the raw data fails.
|
|
||||||
*/
|
|
||||||
public static IpV6RoutingSRHData newInstance(byte[] rawData, int offset, int length)
|
|
||||||
throws IllegalRawDataException {
|
|
||||||
return new IpV6RoutingSRHData(rawData, offset, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IpV6RoutingSRHData(byte[] rawData, int offset, int length)
|
|
||||||
throws IllegalRawDataException {
|
|
||||||
|
|
||||||
this.lastEntry = rawData[ offset]&0xff;
|
|
||||||
this.flags=rawData[offset+1]&0xff;
|
|
||||||
this.tag=ByteArrays.getShort(rawData, offset+2);
|
|
||||||
this.addresses = new ArrayList<Inet6Address>();
|
|
||||||
this.tlvs=new ArrayList<>();
|
|
||||||
|
|
||||||
int endv=INT_SIZE_IN_BYTES+(lastEntry+1)*INET6_ADDRESS_SIZE_IN_BYTES;
|
|
||||||
for (int i = INT_SIZE_IN_BYTES; i < endv; i += INET6_ADDRESS_SIZE_IN_BYTES) {
|
|
||||||
addresses.add(ByteArrays.getInet6Address(rawData, i + offset));
|
|
||||||
}
|
|
||||||
for(int itlv=endv;itlv<length;) {
|
|
||||||
int type=rawData[itlv+offset]&0xff;
|
|
||||||
switch(type) {
|
|
||||||
case SRv6TLV.PAD1:
|
|
||||||
itlv++;
|
|
||||||
tlvs.add(new SRv6Pad1TLV());
|
|
||||||
break;
|
|
||||||
case SRv6TLV.PADN:
|
|
||||||
itlv++;
|
|
||||||
int lengthPN=rawData[itlv+offset]&0xff;
|
|
||||||
tlvs.add(new SRv6PadNTLV(lengthPN));
|
|
||||||
itlv+=1+lengthPN;
|
|
||||||
break;
|
|
||||||
case SRv6TLV.SEQS:
|
|
||||||
itlv++;
|
|
||||||
int lengthQTLV=rawData[itlv+offset]&0xff;
|
|
||||||
byte[]rawQTLV=new byte[lengthQTLV];
|
|
||||||
System.arraycopy(rawData, itlv+offset+1, rawQTLV, 0, lengthQTLV);
|
|
||||||
tlvs.add(new SRv6StreamSequenceTLV( lengthQTLV, rawQTLV));
|
|
||||||
itlv+=1+lengthQTLV;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
itlv++;
|
|
||||||
int lengthTLV=rawData[itlv+offset]&0xff;
|
|
||||||
byte[]rawTLV=new byte[lengthTLV];
|
|
||||||
System.arraycopy(rawData, itlv+offset+1, rawTLV, 0, lengthTLV);
|
|
||||||
tlvs.add(new SRv6TLV(type, lengthTLV, rawTLV));
|
|
||||||
itlv+=1+lengthTLV;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SRv6TLV> getTlvs() {
|
|
||||||
return tlvs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastEntry() {
|
|
||||||
return lastEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFlags() {
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTag() {
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Inet6Address> getAddresses() {
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IpV6RoutingSRHData(List<Inet6Address> addresses) {
|
|
||||||
this(0,0,addresses,new ArrayList<>());
|
|
||||||
}
|
|
||||||
public IpV6RoutingSRHData(List<Inet6Address> addresses,List<SRv6TLV>tlvs) {
|
|
||||||
this(0,0,addresses,tlvs);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param reserved reserved
|
|
||||||
* @param addresses addresses
|
|
||||||
*/
|
|
||||||
public IpV6RoutingSRHData(int flags,int tag, List<Inet6Address> addresses,List<SRv6TLV>tlvs) {
|
|
||||||
if (addresses == null) {
|
|
||||||
throw new NullPointerException("addresses must not be null");
|
|
||||||
}
|
|
||||||
this.lastEntry = addresses.size()-1;
|
|
||||||
this.flags=flags;
|
|
||||||
this.tag=tag;
|
|
||||||
this.addresses = new ArrayList<Inet6Address>(addresses);
|
|
||||||
this.tlvs=tlvs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int length() {
|
|
||||||
int tlvsize=0;
|
|
||||||
for (int i = 0; i < tlvs.size(); i++) {
|
|
||||||
tlvsize+=tlvs.get(i).getTotalLength();
|
|
||||||
}
|
|
||||||
return INT_SIZE_IN_BYTES+addresses.size() * INET6_ADDRESS_SIZE_IN_BYTES + tlvsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getRawData() {
|
|
||||||
byte[] rawData = new byte[length()];
|
|
||||||
rawData[0]=(byte) lastEntry;
|
|
||||||
rawData[1]=(byte) flags;
|
|
||||||
rawData[2]=(byte) (tag>>8);
|
|
||||||
rawData[3]=(byte) tag;
|
|
||||||
;
|
|
||||||
int i = INT_SIZE_IN_BYTES;
|
|
||||||
for ( Iterator<Inet6Address> iter = addresses.iterator(); iter.hasNext(); i += INET6_ADDRESS_SIZE_IN_BYTES) {
|
|
||||||
System.arraycopy(
|
|
||||||
ByteArrays.toByteArray(iter.next()), 0, rawData, i, INET6_ADDRESS_SIZE_IN_BYTES);
|
|
||||||
}
|
|
||||||
for (int j = 0; j < tlvs.size(); j++) {
|
|
||||||
SRv6TLV srt=tlvs.get(j);
|
|
||||||
switch(srt.getType()) {
|
|
||||||
case SRv6TLV.PAD1:
|
|
||||||
rawData[i++]=(byte) srt.getType();
|
|
||||||
break;
|
|
||||||
case SRv6TLV.PADN:
|
|
||||||
rawData[i++]=(byte) srt.getType();
|
|
||||||
int plth=srt.getLength();
|
|
||||||
rawData[i++]=(byte) plth;
|
|
||||||
i+=plth;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rawData[i++]=(byte) srt.getType();
|
|
||||||
int dlth=srt.getLength();
|
|
||||||
rawData[i++]=(byte) dlth;
|
|
||||||
System.arraycopy(srt.getValue(), 0, rawData, i, dlth);
|
|
||||||
i+=dlth;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rawData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("[lastentry: ").append(lastEntry).append("][flags: ").append(flags).append("][tag: ").append(tag).append("] [addresses:");
|
|
||||||
for (Inet6Address addr : addresses) {
|
|
||||||
sb.append(" ").append(addr);
|
|
||||||
}
|
|
||||||
sb.append("]");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!this.getClass().isInstance(obj)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IpV6RoutingSRHData other = (IpV6RoutingSRHData) obj;
|
|
||||||
return lastEntry == other.lastEntry&&flags==other.flags&&tag==other.tag && addresses.equals(other.addresses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 17;
|
|
||||||
result = 31 * result + lastEntry;
|
|
||||||
result = 31 * result + flags;
|
|
||||||
result = 31 * result + tag;
|
|
||||||
result = 31 * result + addresses.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,22 +2,15 @@ package org.kne.cloud.network.srv6;
|
|||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.net.BindException;
|
import java.net.BindException;
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
|
||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -30,11 +23,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.BiConsumer;
|
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.IPv6Address;
|
||||||
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
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.IPv6AddressGroup;
|
||||||
import org.kne.cloud.network.ipv6.Neighbor;
|
import org.kne.cloud.network.ipv6.Neighbor;
|
||||||
import org.kne.cloud.network.klalb.KLALBVirtualRawSocket;
|
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.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorData;
|
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorData;
|
||||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||||
import org.kne.cloud.network.scanner.InetAddressRange;
|
import org.kne.membandboost.MembandBoost;
|
||||||
import org.kne.cloud.network.te.BandwidthDistributer;
|
|
||||||
|
|
||||||
import com.google.gson.internal.Pair;
|
|
||||||
|
|
||||||
public class KLALBRoutingProtocol extends Thread{
|
public class KLALBRoutingProtocol extends Thread{
|
||||||
|
|
||||||
@@ -218,7 +207,7 @@ public class KLALBRoutingProtocol extends Thread{
|
|||||||
while(true) {
|
while(true) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
byte[]ca=ByteBufferAllocator.allocateUninitializedArray(65535);
|
byte[]ca=MembandBoost.allocateUninitializedArray(65535);
|
||||||
DatagramPacket dgp=new DatagramPacket(ca, ca.length);
|
DatagramPacket dgp=new DatagramPacket(ca, ca.length);
|
||||||
ds.receive(dgp);
|
ds.receive(dgp);
|
||||||
//System.out.println(Arrays.toString( Arrays.copyOf( dgp.getData(),dgp.getLength())));
|
//System.out.println(Arrays.toString( Arrays.copyOf( dgp.getData(),dgp.getLength())));
|
||||||
@@ -609,7 +598,7 @@ public class KLALBRoutingProtocol extends Thread{
|
|||||||
public Map<IPv6Address, List<LinkDirection>> getPaths() {
|
public Map<IPv6Address, List<LinkDirection>> getPaths() {
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
public List<IPv6Address> createSegmentList(IPv6Address dest) {
|
public IPv6SegmentRoutingHeader createSegmentList(IPv6Address dest) {
|
||||||
NetmapDirections directionsx=directions;
|
NetmapDirections directionsx=directions;
|
||||||
if(directionsx==null) {
|
if(directionsx==null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -618,14 +607,16 @@ public class KLALBRoutingProtocol extends Thread{
|
|||||||
if(dn==null) {
|
if(dn==null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
List<IPv6Address>segments=new ArrayList<>();
|
IPv6SegmentRoutingHeader segs=new IPv6SegmentRoutingHeader();
|
||||||
|
List<IPv6Address>segments=segs.getAddresses();
|
||||||
while(true) {
|
while(true) {
|
||||||
long idx=directionsx.getDirection()[(int) dn.longValue()];
|
long idx=directionsx.getDirection()[(int) dn.longValue()];
|
||||||
if(idx==-1) {
|
if(idx==-1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if(idx==dn) {
|
if(idx==dn) {
|
||||||
return segments;
|
segs. resetSegmentPos();
|
||||||
|
return segs;
|
||||||
}
|
}
|
||||||
segments.add(directionsx.getDirection_rias().get(dn.intValue()));
|
segments.add(directionsx.getDirection_rias().get(dn.intValue()));
|
||||||
dn=idx;
|
dn=idx;
|
||||||
|
|||||||
@@ -11,16 +11,14 @@ import java.util.function.BiConsumer;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.ThreadTool;
|
import org.kne.cloud.network.congestion.NOCongestionAlgorithm;
|
||||||
import org.kne.cloud.network.congestion.DCTCPCongestionAlgorithm;
|
|
||||||
import org.kne.cloud.network.congestion.EmptyCongestionAlgorithm;
|
|
||||||
import org.kne.cloud.network.congestion.SendPacketSlidingWindow;
|
import org.kne.cloud.network.congestion.SendPacketSlidingWindow;
|
||||||
import org.kne.opencl64.Releaser;
|
import org.kne.opencl64.Releaser;
|
||||||
|
|
||||||
public class KLALBRoutingProtocolAPIClient {
|
public class KLALBRoutingProtocolAPIClient {
|
||||||
private KLALBRoutingProtocol routingProtocol;
|
private KLALBRoutingProtocol routingProtocol;
|
||||||
private SendPacketSlidingWindow<UUID, JsonDataPacket> window = new SendPacketSlidingWindow<UUID, JsonDataPacket>(
|
private SendPacketSlidingWindow<UUID, JsonDataPacket> window = new SendPacketSlidingWindow<UUID, JsonDataPacket>(
|
||||||
new EmptyCongestionAlgorithm(3000000000L), 1024 * 1024);
|
new NOCongestionAlgorithm(3000000000L), 1024 * 1024);
|
||||||
|
|
||||||
private static final Cleaner clr = Cleaner.create();
|
private static final Cleaner clr = Cleaner.create();
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -5,11 +5,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||||
import org.pcap4j.packet.IpV6Packet;
|
|
||||||
import org.pcap4j.packet.TcpPacket;
|
|
||||||
|
|
||||||
public class PacketReorder {
|
public class PacketReorder {
|
||||||
public PacketReorder(long sequenceNumber) {
|
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();
|
rlock.lock();
|
||||||
try {
|
try {
|
||||||
//System.out.println("包序号:"+seq);
|
//System.out.println("包序号:"+seq);
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import org.kne.cloud.network.ipv6.IPv6Packet;
|
|||||||
|
|
||||||
public class SRv6PacketReorder {
|
public class SRv6PacketReorder {
|
||||||
|
|
||||||
private PacketConsumer packetConsumer;
|
private IPv6PacketConsumer packetConsumer;
|
||||||
|
|
||||||
public SRv6PacketReorder(PacketConsumer packetConsumer) {
|
public SRv6PacketReorder(IPv6PacketConsumer packetConsumer) {
|
||||||
this.packetConsumer=packetConsumer;
|
this.packetConsumer=packetConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,32 +11,22 @@ import java.util.HashSet;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
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.Condition;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
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.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.congestion.MessageBatcher;
|
||||||
import org.kne.cloud.network.ipv6.ControlledIPv6NetworkLink;
|
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.ICMPv6PostcardPacket;
|
||||||
import org.kne.cloud.network.ipv6.ICMPv6TimeExceededPacket;
|
import org.kne.cloud.network.ipv6.ICMPv6TimeExceededPacket;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Address;
|
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;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6HopByHopHeader;
|
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6HopByHopHeader;
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
|
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.IPv6AddressGroup;
|
||||||
import org.kne.cloud.network.ipv6.KLALBOAMHopByHopTLV;
|
import org.kne.cloud.network.ipv6.KLALBOAMHopByHopTLV;
|
||||||
import org.kne.cloud.network.ipv6.KLALBPassportHopByHopTLV;
|
import org.kne.cloud.network.ipv6.KLALBPassportHopByHopTLV;
|
||||||
import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink;
|
import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink;
|
||||||
import org.kne.cloud.network.ipv6.Neighbor;
|
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.PadNHopByHopTLV;
|
||||||
import org.kne.cloud.network.ipv6.PostcardEntry;
|
import org.kne.cloud.network.ipv6.PostcardEntry;
|
||||||
import org.kne.cloud.network.ipv6.RouteItem;
|
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.cloud.network.klalb.KLALBUtils;
|
||||||
import org.kne.concurrent.HighPerformanceExecutor;
|
import org.kne.concurrent.HighPerformanceExecutor2;
|
||||||
import org.kne.concurrent.TimeoutConcurrentHashMap;
|
import org.kne.concurrent.TimeoutConcurrentHashMap;
|
||||||
import org.pcap4j.packet.IllegalRawDataException;
|
import org.pcap4j.packet.IllegalRawDataException;
|
||||||
|
|
||||||
import com.github.f4b6a3.uuid.UuidCreator;
|
|
||||||
import com.google.gson.internal.Pair;
|
import com.google.gson.internal.Pair;
|
||||||
|
|
||||||
// SRv6路由器主类,实现IPv6段路由功能
|
// SRv6路由器主类,实现IPv6段路由功能
|
||||||
@@ -132,7 +118,6 @@ public class SRv6Router {
|
|||||||
public void accept(IPv6Packet t) {
|
public void accept(IPv6Packet t) {
|
||||||
// HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
// HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||||
routePacket(null, t, true); // 执行重路由
|
routePacket(null, t, true); // 执行重路由
|
||||||
t.putTimePassport("rerouted"); // 标记重路由时间点
|
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -268,7 +253,7 @@ public class SRv6Router {
|
|||||||
// 预处理和排序路由项
|
// 预处理和排序路由项
|
||||||
for (Iterator<RouteItem> iterator = routeTabel0x.iterator(); iterator.hasNext();) {
|
for (Iterator<RouteItem> iterator = routeTabel0x.iterator(); iterator.hasNext();) {
|
||||||
RouteItem routeItem = (RouteItem) iterator.next();
|
RouteItem routeItem = (RouteItem) iterator.next();
|
||||||
routeItem.preSort(); // 预排序
|
routeItem.updateCost(); // 预排序
|
||||||
}
|
}
|
||||||
Collections.sort(routeTabel0x); // 排序路由表
|
Collections.sort(routeTabel0x); // 排序路由表
|
||||||
|
|
||||||
@@ -319,15 +304,11 @@ public class SRv6Router {
|
|||||||
// 插入SRH并路由数据包
|
// 插入SRH并路由数据包
|
||||||
public void insertSRHandRoutePacket(IPv6NetworkLink link, IPv6Packet ipp) {
|
public void insertSRHandRoutePacket(IPv6NetworkLink link, IPv6Packet ipp) {
|
||||||
insertHopByHopHeader(ipp);
|
insertHopByHopHeader(ipp);
|
||||||
ipp.putTimePassport("Hop inserted");
|
|
||||||
insertSRHeader(ipp); // 插入段路由头
|
insertSRHeader(ipp); // 插入段路由头
|
||||||
ipp.putTimePassport("SRH inserted"); // 标记SRH插入时间点
|
|
||||||
routePacket(link, ipp); // 路由数据包
|
routePacket(link, ipp); // 路由数据包
|
||||||
ipp.putTimePassport("routed"); // 标记路由时间点
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private PacketIDGenerator defaultGen = new PacketIDGenerator();
|
|
||||||
private static final PadNHopByHopTLV pad4 = new PadNHopByHopTLV(4);
|
private static final PadNHopByHopTLV pad4 = new PadNHopByHopTLV(4);
|
||||||
|
|
||||||
// 插入逐跳路由头
|
// 插入逐跳路由头
|
||||||
@@ -353,16 +334,15 @@ public class SRv6Router {
|
|||||||
}
|
}
|
||||||
// 如果KLALB路由协议可用,创建段列表
|
// 如果KLALB路由协议可用,创建段列表
|
||||||
if (klalbRouteProtol != null) {
|
if (klalbRouteProtol != null) {
|
||||||
List<IPv6Address> segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress());
|
IPv6SegmentRoutingHeader segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress());
|
||||||
// System.out.println(segs);
|
// System.out.println(segs);
|
||||||
if (segs != null && (!segs.isEmpty())) {
|
if (segs != null && (!segs.getAddresses().isEmpty())) {
|
||||||
|
|
||||||
// 创建SRH头
|
// 创建SRH头
|
||||||
IPv6SegmentRoutingHeader irh = new IPv6SegmentRoutingHeader(segs);
|
|
||||||
|
|
||||||
ipp.getHeaders().add(irh); // 添加SRH头
|
ipp.getHeaders().add(segs); // 添加SRH头
|
||||||
ipp.setRoutingHeader(irh);
|
ipp.setRoutingHeader(segs);
|
||||||
ipp.setDestinationAddress(segs.get(segs.size() - 1)); // 更新目的地址为最后一个段
|
ipp.setDestinationAddress(segs.getAddresses().get(segs.getAddresses().size() - 1)); // 更新目的地址为最后一个段
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -401,8 +381,9 @@ public class SRv6Router {
|
|||||||
int hop = iPv6Packet.getHopLimit(); // 获取跳数限制
|
int hop = iPv6Packet.getHopLimit(); // 获取跳数限制
|
||||||
if (hop > 0) { // 检查TTL值,只有大于0才会被转发
|
if (hop > 0) { // 检查TTL值,只有大于0才会被转发
|
||||||
// 搜索匹配的路由表项
|
// 搜索匹配的路由表项
|
||||||
List<RouteItem> searchResult = searchTable(iPv6Packet, reroute, dbg);
|
IPv6Address dest=iPv6Packet.getDestinationAddress();
|
||||||
if (!searchResult.isEmpty()) {
|
List<RouteItem> searchResult = getTabelByAddress(dest);
|
||||||
|
if (searchResult!=null&&(!searchResult.isEmpty())) {
|
||||||
// 匹配到路由表,执行负载均衡路由
|
// 匹配到路由表,执行负载均衡路由
|
||||||
routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult);
|
routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult);
|
||||||
return;
|
return;
|
||||||
@@ -421,15 +402,15 @@ public class SRv6Router {
|
|||||||
segmentsLeft--;
|
segmentsLeft--;
|
||||||
}
|
}
|
||||||
// 创建修复段列表
|
// 创建修复段列表
|
||||||
List<IPv6Address> repairSegments = klalbRouteProtol
|
IPv6SegmentRoutingHeader repairSegments = klalbRouteProtol
|
||||||
.createSegmentList(srh.getAddresses().get(segmentsLeft));
|
.createSegmentList(srh.getAddresses().get(segmentsLeft));
|
||||||
if (repairSegments == null || repairSegments.isEmpty()) {
|
if (repairSegments == null ||repairSegments.getAddresses().isEmpty()) {
|
||||||
System.out.println("FRR保护失败");
|
System.out.println("FRR保护失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
repairSegments.remove(0); // 移除第一个段(当前节点)
|
repairSegments.getAddresses().remove(0); // 移除第一个段(当前节点)
|
||||||
srh.getAddresses().addAll(segmentsLeft + 1, repairSegments); // 添加修复段
|
srh.getAddresses().addAll(segmentsLeft + 1, repairSegments.getAddresses()); // 添加修复段
|
||||||
segmentsLeft += repairSegments.size(); // 更新剩余段数
|
segmentsLeft += repairSegments.getAddresses().size(); // 更新剩余段数
|
||||||
srh.setSegmentsLeft(segmentsLeft);
|
srh.setSegmentsLeft(segmentsLeft);
|
||||||
iPv6Packet.setDestinationAddress(srh.getAddresses().get(segmentsLeft)); // 更新目的地址
|
iPv6Packet.setDestinationAddress(srh.getAddresses().get(segmentsLeft)); // 更新目的地址
|
||||||
} else {
|
} else {
|
||||||
@@ -437,8 +418,8 @@ public class SRv6Router {
|
|||||||
}
|
}
|
||||||
System.out.println("FRR修复SRH:" + srh);
|
System.out.println("FRR修复SRH:" + srh);
|
||||||
// 重新搜索路由表
|
// 重新搜索路由表
|
||||||
List<RouteItem> searchResult2 = searchTable(iPv6Packet, reroute, dbg);
|
List<RouteItem> searchResult2 = getTabelByAddress(dest);
|
||||||
if (!searchResult2.isEmpty()) {
|
if (searchResult2!=null&&(!searchResult2.isEmpty())) {
|
||||||
routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult2);
|
routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -457,7 +438,7 @@ public class SRv6Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 搜索路由表找到匹配的路由项
|
// 搜索路由表找到匹配的路由项
|
||||||
private List<RouteItem> searchTable(IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg)
|
/*private List<RouteItem> searchTable(IPv6Packet iPv6Packet, StringBuilder dbg)
|
||||||
throws IllegalRawDataException, IOException {
|
throws IllegalRawDataException, IOException {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
dbg.append("----------------------------------------\n");
|
dbg.append("----------------------------------------\n");
|
||||||
@@ -476,17 +457,7 @@ public class SRv6Router {
|
|||||||
|
|
||||||
// 遍历路由表,筛选可用路由
|
// 遍历路由表,筛选可用路由
|
||||||
for (RouteItem tri : table) {
|
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(等价多路径)条件
|
// 检查ECMP(等价多路径)条件
|
||||||
if (prevr != null) {
|
if (prevr != null) {
|
||||||
if (!tri.ECMPequals(prevr)) {
|
if (!tri.ECMPequals(prevr)) {
|
||||||
@@ -497,7 +468,7 @@ public class SRv6Router {
|
|||||||
prevr = tri;
|
prevr = tri;
|
||||||
}
|
}
|
||||||
return routes;
|
return routes;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private List<RouteItem> getTabelByAddress(IPv6Address rk6) {
|
private List<RouteItem> getTabelByAddress(IPv6Address rk6) {
|
||||||
List<RouteItem> table = null;
|
List<RouteItem> table = null;
|
||||||
@@ -519,35 +490,25 @@ public class SRv6Router {
|
|||||||
private boolean routingLoadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute,
|
private boolean routingLoadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute,
|
||||||
StringBuilder dbg, List<RouteItem> routes) throws IllegalRawDataException, IOException {
|
StringBuilder dbg, List<RouteItem> routes) throws IllegalRawDataException, IOException {
|
||||||
|
|
||||||
double cscale = 1.0; // 拥塞检测比例因子
|
if(routes==null||routes.isEmpty()) {
|
||||||
if (iPv6Packet.getPayload().getProtocolNumber() == 6) { // TCP协议
|
//System.out.println("Route not found:" + iPv6Packet);
|
||||||
cscale = 15.0; // TCP使用更高的拥塞检测阈值
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iPv6Packet.getPreviousLink() != null) {
|
for (double i = 1; i < 100; i += 0.1) {
|
||||||
List<RouteItem> prev = new ArrayList<>();
|
if (loadBalance(linkfrom, iPv6Packet, reroute, dbg, routes, i)) {
|
||||||
for (Iterator<RouteItem> 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)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iPv6Packet.isEnableECN()) { // 启用ECN
|
|
||||||
iPv6Packet.markCE(); // 标记拥塞
|
iPv6Packet.markCE(); // 标记拥塞
|
||||||
if (debug) {
|
if (debug) {
|
||||||
dbg.append("ECN enabled.\n");
|
dbg.append("ECN enabled.\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
System.out.println("Send failed:" + iPv6Packet);
|
//System.out.println("Send failed:" + iPv6Packet);
|
||||||
|
LosscountAdder.inc(1);
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
dbg.append("miss.\n"); // 路由失败
|
dbg.append("miss.\n"); // 路由失败
|
||||||
}
|
}
|
||||||
@@ -568,7 +529,7 @@ public class SRv6Router {
|
|||||||
continue; // 跳过断开链路
|
continue; // 跳过断开链路
|
||||||
}
|
}
|
||||||
if (link instanceof ControlledIPv6NetworkLink) {
|
if (link instanceof ControlledIPv6NetworkLink) {
|
||||||
if (((ControlledIPv6NetworkLink) link).isCongress(iPv6Packet, cscale)) { // 检查拥塞
|
if (((ControlledIPv6NetworkLink) link).isCongestion(iPv6Packet, cscale)) { // 检查拥塞
|
||||||
if (debug) {
|
if (debug) {
|
||||||
dbg.append(tri + "\n");
|
dbg.append(tri + "\n");
|
||||||
dbg.append("congress.\n");
|
dbg.append("congress.\n");
|
||||||
@@ -623,12 +584,6 @@ public class SRv6Router {
|
|||||||
if (iPv6Packet.getPayload() instanceof ICMPv6PostcardPacket && ri.getDestlink().isLoopBack()) {
|
if (iPv6Packet.getPayload() instanceof ICMPv6PostcardPacket && ri.getDestlink().isLoopBack()) {
|
||||||
onPostcardReceive(iPv6Packet);
|
onPostcardReceive(iPv6Packet);
|
||||||
} else {
|
} 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());
|
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -642,8 +597,8 @@ public class SRv6Router {
|
|||||||
if (ris != null) {
|
if (ris != null) {
|
||||||
for (RouteItem ri : ris) {
|
for (RouteItem ri : ris) {
|
||||||
if (ri.getNexthop().equals(sid)) {
|
if (ri.getNexthop().equals(sid)) {
|
||||||
if (ri.getDestlink() instanceof KLALBRemoteLine) {
|
if (ri.getDestlink() instanceof KLALBRemoteLink) {
|
||||||
KLALBRemoteLine rem = (KLALBRemoteLine) ri.getDestlink();
|
KLALBRemoteLink rem = (KLALBRemoteLink) ri.getDestlink();
|
||||||
rem.onPostcardReceive(postcard);
|
rem.onPostcardReceive(postcard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -683,9 +638,9 @@ public class SRv6Router {
|
|||||||
int sl = srhh.getSegmentsLeft();
|
int sl = srhh.getSegmentsLeft();
|
||||||
// IPv6Address prevSID
|
// IPv6Address prevSID
|
||||||
// =sl+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(sl+1);
|
// =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(),
|
processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(),
|
||||||
((KLALBRemoteLine) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
|
((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// System.out.println(iPv6HopByHopHeader);
|
// System.out.println(iPv6HopByHopHeader);
|
||||||
@@ -698,9 +653,9 @@ public class SRv6Router {
|
|||||||
if (iPv6HopByHopHeader != null) {
|
if (iPv6HopByHopHeader != null) {
|
||||||
// IPv6Address prevSID
|
// IPv6Address prevSID
|
||||||
// =oldSL+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(oldSL+1);
|
// =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(),
|
processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(),
|
||||||
((KLALBRemoteLine) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
|
((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 正常SRv6处理:移动到下一个段
|
// 正常SRv6处理:移动到下一个段
|
||||||
@@ -762,8 +717,9 @@ public class SRv6Router {
|
|||||||
|
|
||||||
private void putPostcard(IPv6Address src, IPv6Address dst, IPv6Address srcSID, UUID uuid, long timeStamp,
|
private void putPostcard(IPv6Address src, IPv6Address dst, IPv6Address srcSID, UUID uuid, long timeStamp,
|
||||||
long delta, int packetLength) {
|
long delta, int packetLength) {
|
||||||
|
|
||||||
PostcardEntry pn = new PostcardEntry(srcSID, uuid, timeStamp, (int) (delta >> 4), packetLength);
|
PostcardEntry pn = new PostcardEntry(srcSID, uuid, timeStamp, (int) (delta >> 4), packetLength);
|
||||||
Pair<IPv6Address, IPv6Address> addressPair = new Pair<IPv6Address, IPv6Address>(src, dst);
|
/*Pair<IPv6Address, IPv6Address> addressPair = new Pair<IPv6Address, IPv6Address>(src, dst);
|
||||||
MessageBatcher<PostcardEntry> batch = postcardBatch.computeIfAbsent(addressPair, (k) -> {
|
MessageBatcher<PostcardEntry> batch = postcardBatch.computeIfAbsent(addressPair, (k) -> {
|
||||||
MessageBatcher<PostcardEntry> mb = new ArrayListMessageBatcher<PostcardEntry>(30, 2000000L);
|
MessageBatcher<PostcardEntry> mb = new ArrayListMessageBatcher<PostcardEntry>(30, 2000000L);
|
||||||
mb.setConsumer((list) -> {
|
mb.setConsumer((list) -> {
|
||||||
@@ -786,13 +742,30 @@ public class SRv6Router {
|
|||||||
return mb;
|
return mb;
|
||||||
});
|
});
|
||||||
postcardBatch.refresh(addressPair);
|
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(
|
private static HighPerformanceExecutor2 defaultExecutor = new HighPerformanceExecutor2(
|
||||||
Runtime.getRuntime().availableProcessors() + 1, Thread.ofPlatform().name("SRv6 Routing").factory());//Runtime.getRuntime().availableProcessors() + 1
|
(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;
|
return defaultExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -802,38 +775,52 @@ public class SRv6Router {
|
|||||||
// packetQueue.add(object);
|
// packetQueue.add(object);
|
||||||
defaultExecutor.executeWithCongestionReport((state) -> {
|
defaultExecutor.executeWithCongestionReport((state) -> {
|
||||||
try {
|
try {
|
||||||
|
long start=System.nanoTime();
|
||||||
IPv6Packet packet=sendTask.get();
|
IPv6Packet packet=sendTask.get();
|
||||||
if(state) {
|
if(state) {
|
||||||
if(packet.isEnableECN()) {
|
|
||||||
packet.markCE();
|
packet.markCE();
|
||||||
//System.out.println("mce");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
insertSRHandRoutePacket(null, packet); // 插入SRH并路由
|
insertSRHandRoutePacket(null, packet); // 插入SRH并路由
|
||||||
|
long time=System.nanoTime()-start;
|
||||||
|
backplaneCount(time,state);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
},20);
|
},20);
|
||||||
}
|
}
|
||||||
|
public void runPacketSendTask(Supplier<IPv6Packet> 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){
|
public void onReceive(IPv6NetworkLink link,IPv6Packet t){
|
||||||
if (unduplicate(t)) {
|
if (unduplicate(t)) {
|
||||||
insertSRHandRoutePacket(link, t); // 插入SRH并路由数据包
|
insertSRHandRoutePacket(link, t); // 插入SRH并路由数据包
|
||||||
t.putTimePassport("routed"); // 标记路由时间点
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enqueuePacketReceiveTask(IPv6NetworkLink link, Supplier<IPv6Packet> pack) {
|
public void enqueuePacketReceiveTask(IPv6NetworkLink link, Supplier<IPv6Packet> pack) {
|
||||||
defaultExecutor.executeWithCongestionReport((state) -> {
|
defaultExecutor.executeWithCongestionReport((state) -> {
|
||||||
try {
|
try {
|
||||||
|
long start=System.nanoTime();
|
||||||
IPv6Packet packet = pack.get();
|
IPv6Packet packet = pack.get();
|
||||||
if(state) {
|
if(state) {
|
||||||
if(packet.isEnableECN()) {
|
|
||||||
packet.markCE();
|
packet.markCE();
|
||||||
//System.out.println("mce");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
onReceive(link ,packet);
|
onReceive(link ,packet);
|
||||||
|
long time=System.nanoTime()-start;
|
||||||
|
backplaneCount(time,state);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -845,6 +832,67 @@ public class SRv6Router {
|
|||||||
return packet;
|
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<backplanePPS) {
|
||||||
|
backplanePPSMax=backplanePPS;
|
||||||
|
}else {
|
||||||
|
backplanePPSMax=(backplanePPSMax*999+backplanePPS)/1000;
|
||||||
|
}
|
||||||
|
prevTime=curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long getBackplaneTime() {
|
||||||
|
return backplaneTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBackplanePPS() {
|
||||||
|
return backplanePPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBackplanePPSMax() {
|
||||||
|
return backplanePPSMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getECNRate() {
|
||||||
|
return ECNRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLossRate() {
|
||||||
|
return LossRate;
|
||||||
|
}
|
||||||
|
|
||||||
// 构造函数
|
// 构造函数
|
||||||
public SRv6Router(IPv6AddressGroup hostAddress, HighAccuracyClock clock) {
|
public SRv6Router(IPv6AddressGroup hostAddress, HighAccuracyClock clock) {
|
||||||
@@ -856,6 +904,13 @@ public class SRv6Router {
|
|||||||
this.inLoopBack = new LoopbackIPv6NetworkLink(
|
this.inLoopBack = new LoopbackIPv6NetworkLink(
|
||||||
List.of(new IPv6AddressGroup(IPv6Address.LOOPBACK, 128), hostAddress), this);
|
List.of(new IPv6AddressGroup(IPv6Address.LOOPBACK, 128), hostAddress), this);
|
||||||
linkTabel.add(inLoopBack); // 添加到链路表
|
linkTabel.add(inLoopBack); // 添加到链路表
|
||||||
|
backplaneTimer.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
updateBackplaneCounter();
|
||||||
|
}
|
||||||
|
}, 100, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -892,7 +947,7 @@ public class SRv6Router {
|
|||||||
Object[] nls = links.toArray();
|
Object[] nls = links.toArray();
|
||||||
for (int i = 0; i < nls.length; i++) {
|
for (int i = 0; i < nls.length; i++) {
|
||||||
IPv6NetworkLink nl = (IPv6NetworkLink) nls[i];
|
IPv6NetworkLink nl = (IPv6NetworkLink) nls[i];
|
||||||
if (!nl.isLoopBack()) { // 排除环回接口
|
if ((!nl.isLoopBack())&&nl.isUp()) { // 排除环回接口
|
||||||
List<Neighbor> neis = nl.getNeighborsInfo();
|
List<Neighbor> neis = nl.getNeighborsInfo();
|
||||||
for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
|
for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
|
||||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||||
@@ -903,7 +958,7 @@ public class SRv6Router {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有定位器
|
// 获取所有SID
|
||||||
public Set<IPv6AddressGroup> getLocators() {
|
public Set<IPv6AddressGroup> getLocators() {
|
||||||
Set<IPv6AddressGroup> result = new HashSet<>();
|
Set<IPv6AddressGroup> result = new HashSet<>();
|
||||||
List<IPv6NetworkLink> links = getLinkTabel();
|
List<IPv6NetworkLink> links = getLinkTabel();
|
||||||
@@ -915,10 +970,14 @@ public class SRv6Router {
|
|||||||
for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
|
for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
|
||||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||||
if (addresses.getLocator() != null)
|
if (addresses.getLocator() != null)
|
||||||
result.add(addresses.getLocator()); // 添加邻居定位器
|
result.add(addresses.getLocator()); // 添加邻居SID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,11 +5,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||||
import org.pcap4j.packet.IpV6Packet;
|
|
||||||
import org.pcap4j.packet.TcpPacket;
|
|
||||||
|
|
||||||
public class SlidingWindowInformation {
|
public class SlidingWindowInformation {
|
||||||
public SlidingWindowInformation(long sequenceNumber) {
|
public SlidingWindowInformation(long sequenceNumber) {
|
||||||
@@ -57,7 +54,7 @@ public class SlidingWindowInformation {
|
|||||||
+ ", addtime=" + addtime + "]";
|
+ ", 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();
|
rlock.lock();
|
||||||
try {
|
try {
|
||||||
//System.out.println("包序号:"+seq+" 长度:"+length);
|
//System.out.println("包序号:"+seq+" 长度:"+length);
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
package org.kne.cloud.network.srv6;
|
package org.kne.cloud.network.srv6;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||||
import org.pcap4j.packet.IpV6Packet;
|
|
||||||
import org.pcap4j.packet.TcpPacket;
|
|
||||||
|
|
||||||
public class TCPTransimitAgent {
|
public class TCPTransimitAgent {
|
||||||
public TCPTransimitAgent() {
|
public TCPTransimitAgent() {
|
||||||
@@ -57,7 +51,7 @@ public class TCPTransimitAgent {
|
|||||||
+ ", addtime=" + addtime + "]";
|
+ ", 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) {
|
if(length<=0) {
|
||||||
packconsumer.accept(pack);
|
packconsumer.accept(pack);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.kne.cloud.network.NetworkPacket;
|
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;
|
public static final int TCP_PROTOCOL_NUMBER = 6;
|
||||||
|
|
||||||
// TCP头部常量
|
// TCP头部常量
|
||||||
@@ -33,7 +33,7 @@ public class TCPPacket extends IPv6Payload {
|
|||||||
private List<TCPOptionTLV> options = new ArrayList<>();
|
private List<TCPOptionTLV> options = new ArrayList<>();
|
||||||
|
|
||||||
public TCPPacket() {
|
public TCPPacket() {
|
||||||
super(TCP_PROTOCOL_NUMBER, false);
|
super(TCP_PROTOCOL_NUMBER);
|
||||||
// 设置默认数据偏移量(头部长度)
|
// 设置默认数据偏移量(头部长度)
|
||||||
setDataOffset(5); // 5 * 4 = 20字节
|
setDataOffset(5); // 5 * 4 = 20字节
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
package org.kne.cloud.network.tcp;
|
package org.kne.cloud.network.tcp;
|
||||||
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.kne.cloud.network.NetworkPacket;
|
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.ipv6.IPv6Packet.IPv6Payload;
|
||||||
import org.kne.cloud.network.klalb.PortPacket;
|
import org.kne.cloud.network.klalb.PortPacket;
|
||||||
import org.kne.io.KNEChannels;
|
import org.kne.io.KNEChannels;
|
||||||
@@ -23,11 +19,11 @@ public class UDPPacket extends IPv6Payload implements PortPacket {
|
|||||||
private ByteBuffer data;
|
private ByteBuffer data;
|
||||||
|
|
||||||
public UDPPacket() {
|
public UDPPacket() {
|
||||||
super(UDP_PROTOCOL_NUMBER, false);
|
super(UDP_PROTOCOL_NUMBER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UDPPacket(int srcPort,int dstPort) {
|
public UDPPacket(int srcPort,int dstPort) {
|
||||||
super(UDP_PROTOCOL_NUMBER, false);
|
super(UDP_PROTOCOL_NUMBER);
|
||||||
header.putChar((char) srcPort);
|
header.putChar((char) srcPort);
|
||||||
header.putChar((char) dstPort);
|
header.putChar((char) dstPort);
|
||||||
data = NetworkPacket.bufferAllocator.allocate(65535);
|
data = NetworkPacket.bufferAllocator.allocate(65535);
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
package org.kne.cloud.network.te;
|
package org.kne.cloud.network.te;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
|
||||||
|
|
||||||
public class DWRRLoadingBalanceAlgorithm<T extends LoadingBalanceEntry<T>> {
|
public class DWRRLoadingBalanceAlgorithm<T extends LoadingBalanceEntry<T>> {
|
||||||
private List<T>entries;
|
private List<T>entries;
|
||||||
|
|||||||
Reference in New Issue
Block a user