Compare commits

...
12 Commits
48 changed files with 455 additions and 527 deletions
+3 -1
View File
@@ -4,7 +4,6 @@
<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"/>
<classpathentry kind="lib" path="lib/JFreeChart1.5.2.jar"/>
<classpathentry kind="lib" path="lib/toml4j-0.7.1.jar"/> <classpathentry kind="lib" path="lib/toml4j-0.7.1.jar"/>
<classpathentry kind="lib" path="lib/pcap4j-core-1.8.2.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1725520274095/source/pcap4j-core-1.8.2-sources.jar"/> <classpathentry kind="lib" path="lib/pcap4j-core-1.8.2.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1725520274095/source/pcap4j-core-1.8.2-sources.jar"/>
<classpathentry kind="lib" path="lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar"/> <classpathentry kind="lib" path="lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar"/>
@@ -29,5 +28,8 @@
<attribute name="module" value="true"/> <attribute name="module" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="lib/jfreechart-1.5.3.jar"/>
<classpathentry kind="lib" path="lib/jfreechart-1.5.3-javadoc.jar"/>
<classpathentry kind="lib" path="lib/jfreechart-1.5.3-sources.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>
+2
View File
@@ -14,3 +14,5 @@ dashboard/.env.*.local
/klalb-config.json /klalb-config.json
/klalbconfig-old.json /klalbconfig-old.json
/.slim/
+38
View File
@@ -0,0 +1,38 @@
<component name="libraryTable">
<library name="jfreechart-1.5.3">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/jfreechart-1.5.3.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/disruptor-4.0.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/gson-2.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/ini4j.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/javassist.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/JavaTUN0.3.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/jctools-core-4.0.6.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/KNElib1.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/KNEOptimize.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/pcap4j-core-1.8.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/pcap4j-packetfactory-static-1.8.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/pcap4j-packettest-1.8.2-tests.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/pcap4j-sample-1.8.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/slf4j-api-2.0.9.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/slf4j-api-2.0.9-tests.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/toml4j-0.7.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/uuid-creator-6.1.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/lib/jctools-core-4.0.6-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/jfreechart-1.5.3-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/disruptor-4.0.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/ini4j.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/JavaTUN0.3.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/jctools-core-4.0.6-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/KNElib1.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/slf4j-api-2.0.9-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/toml4j-0.7.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/uuid-creator-6.1.1-sources.jar!/" />
</SOURCES>
</library>
</component>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectRootManager" version="2"> <component name="ProjectRootManager" version="2" languageLevel="JDK_26" project-jdk-name="jdk-26.0.1" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/classes" /> <output url="file://$PROJECT_DIR$/classes" />
</component> </component>
</project> </project>
+4 -2
View File
@@ -39,7 +39,7 @@ No test suite, no CI. Classes named `*Test*` (`nathole/`, `ntp/`) are manual `ma
- Entrypoint `org.kne.cloud.network.klalb.KLALBMain`: load config → build `KLALBProxySystem` → open Swing GUI (`KLALBStateGUI3`) unless `"nogui": true` → start `KLALBWebServer` (if `"webUI": true` or web server enabled, default port `4665`) → interactive console (`help`, `links-state`, `route`, `kperf`, ...). - Entrypoint `org.kne.cloud.network.klalb.KLALBMain`: load config → build `KLALBProxySystem` → open Swing GUI (`KLALBStateGUI3`) unless `"nogui": true` → start `KLALBWebServer` (if `"webUI": true` or web server enabled, default port `4665`) → interactive console (`help`, `links-state`, `route`, `kperf`, ...).
- `org.kne.cloud.network.klalb.web.KLALBWebServer` — built-in HTTP/SSE server (JDK `HttpServer`): - `org.kne.cloud.network.klalb.web.KLALBWebServer` — built-in HTTP/SSE server (JDK `HttpServer`):
- API endpoints: `/api/status`, `/api/events` (SSE stream, 200ms intervals), `/api/links`, `/api/links/action`, `/api/links/reconnect`, `/api/routes`, `/api/nodes` (topology graph), `/api/interfaces`, `/api/config`. - API endpoints: `/api/status`, `/api/events` (SSE stream, 200ms intervals), `/api/links`, `/api/links/action`, `/api/links/reconnect`, `/api/routing-table`, `/api/nodes` (topology graph), `/api/node-info?address=<ipv6>` (on-demand full node info), `/api/config`.
- Static file hosting / SPA fallback: serves `dashboard/dist/` assets directly. - Static file hosting / SPA fallback: serves `dashboard/dist/` assets directly.
- `org.kne.cloud.network` — generic socket framework: `VirtualSocket*` hierarchy, `SocketBridge` port-forwarding proxies, `ProtocolDetector` (multi-protocol mux on one port), `MultiProtocolSocketAddress` = URI-style addresses (`tcp://`, `udp://`, `kltp://`, `ntp://`) dispatched through the `SocketType` registry. - `org.kne.cloud.network` — generic socket framework: `VirtualSocket*` hierarchy, `SocketBridge` port-forwarding proxies, `ProtocolDetector` (multi-protocol mux on one port), `MultiProtocolSocketAddress` = URI-style addresses (`tcp://`, `udp://`, `kltp://`, `ntp://`) dispatched through the `SocketType` registry.
- `...network.klalb` — app core: `KLALBController` (the virtual SRv6 network), `KLALBRemoteLink` (WAN lines), `*Packet` wire-format classes, virtual socket implementations. - `...network.klalb` — app core: `KLALBController` (the virtual SRv6 network), `KLALBRemoteLink` (WAN lines), `*Packet` wire-format classes, virtual socket implementations.
@@ -59,7 +59,7 @@ No test suite, no CI. Classes named `*Test*` (`nathole/`, `ntp/`) are manual `ma
Located in `dashboard/`: Located in `dashboard/`:
- **Git layout**: `dashboard/` is a separate git repo wired in as a submodule (own origin on `git.code.cq.cn`). Commit frontend changes inside `dashboard/` first, then bump the submodule pointer in the parent repo — parent-repo commits alone do not capture them. - **Git layout**: `dashboard/` is a separate git repo wired in as a submodule (own origin on `git.code.cq.cn`). Commit frontend changes inside `dashboard/` first, then bump the submodule pointer in the parent repo — parent-repo commits alone do not capture them.
- **Stack**: Vite + React 19 + TypeScript + Tailwind CSS v4 + `@base-ui/react` (style: `base-nova`, icons: `lucide-react`, toasts: `@base-ui/react/toast`). - **Stack**: Vite + React 19 + TypeScript + Tailwind CSS v4 + `@base-ui/react` (style: `base-nova`, icons: `lucide-react`, toasts: `@base-ui/react/toast`).
- **Routing**: Hash-based routing (`#/overview`, `#/connections`, `#/topology`, `#/settings`, etc.) for seamless SPA hosting under Java `KLALBWebServer`. - **Routing**: Hash-based routing (`#/overview`, `#/connections`, `#/routing-table`, `#/topology`, `#/settings`) for seamless SPA hosting under Java `KLALBWebServer`.
- **Package Manager**: `pnpm` (run all commands from `dashboard/` directory). - **Package Manager**: `pnpm` (run all commands from `dashboard/` directory).
- **Component installation**: **Must** use CLI via `pnpm dlx shadcn@latest add <component>` (e.g. `pnpm dlx shadcn@latest add alert card badge toast`). Never create or fake shadcn components manually. Non-shadcn libs (`@xyflow/react`, `d3-force`) are installed via plain `pnpm add`. - **Component installation**: **Must** use CLI via `pnpm dlx shadcn@latest add <component>` (e.g. `pnpm dlx shadcn@latest add alert card badge toast`). Never create or fake shadcn components manually. Non-shadcn libs (`@xyflow/react`, `d3-force`) are installed via plain `pnpm add`.
- **Commands**: - **Commands**:
@@ -69,7 +69,9 @@ Located in `dashboard/`:
- **Pages & data flow**: - **Pages & data flow**:
- Overview / Connections read the SSE stream (`use-klalb-sse.ts`, 200ms pushes of status + links). - Overview / Connections read the SSE stream (`use-klalb-sse.ts`, 200ms pushes of status + links).
- Settings loads/saves `/api/config` (`use-klalb-config.ts`); save payload must keep legacy field aliases alongside new names for compatibility. - Settings loads/saves `/api/config` (`use-klalb-config.ts`); save payload must keep legacy field aliases alongside new names for compatibility.
- Routing table polls `/api/routing-table` every 1s (`use-routing-table.ts`); `cost` is delay-derived and displayed in milliseconds.
- Topology polls `/api/nodes` every 1s (`use-topology.ts`) — SSE does NOT carry topology. - Topology polls `/api/nodes` every 1s (`use-topology.ts`) — SSE does NOT carry topology.
- Selecting a topology node queries `/api/node-info`; remote node descriptions require a full SRv6 node-info request and can time out after 3s.
- Topology layout: `d3-force` headless simulation (recomputed only when node/edge structure changes) rendered by `@xyflow/react` with custom `device-node` / `link-edge` components in `src/components/topology/`. - Topology layout: `d3-force` headless simulation (recomputed only when node/edge structure changes) rendered by `@xyflow/react` with custom `device-node` / `link-edge` components in `src/components/topology/`.
- React hooks lint rule forbids `setState` synchronously inside effects — initialize form state via component `key` remount + lazy `useState(() => ...)` initializers (see `SettingsForm` pattern). - React hooks lint rule forbids `setState` synchronously inside effects — initialize form state via component `key` remount + lazy `useState(() => ...)` initializers (see `SettingsForm` pattern).
+1
View File
@@ -249,5 +249,6 @@
</library> </library>
</orderEntry> </orderEntry>
<orderEntry type="jdk" jdkName="jdk-26.0.1" jdkType="JavaSDK" /> <orderEntry type="jdk" jdkName="jdk-26.0.1" jdkType="JavaSDK" />
<orderEntry type="library" name="jfreechart-1.5.3" level="project" />
</component> </component>
</module> </module>
-20
View File
@@ -1,20 +0,0 @@
//加速线路
{KLALBRemote}->43.248.189.107:35000
{KLALBRemote}->cn-bj-bgp-3.openfrp.top:65529
{KLALBRemote}->180.76.147.250:65529
{KLALBRemote}->cn-ah-dx-1.natfrp.cloud:65529
{KLALBRemote}->cn-nn-dx-1.natfrp.cloud:65529
{KLALBRemote}->cn-wh-dx-1.natfrp.cloud:65529
{KLALBRemote}->cn-zz-bgp-10.natfrp.cloud:23330
{KLALBRemote}->cn-zz-bgp-7.natfrp.cloud:33336
{KLALBRemote}->43.143.109.64:49965
{KLALBRemote}->frp.104300.xyz:49965
{KLALBRemote}->us.afrps.cn:49966
{KLALBRemote}->hk.afrps.cn:49966
{KLALBRemote}->la.afrps.cn:49966
{KLALBRemote}->frp.freefrp.net:49965
{KLALBRemote}->frp1.freefrp.net:49965
{KLALBRemote}->frp2.freefrp.net:49965
{KLALBRemote}->frp4.freefrp.net:49965
0.0.0.0:25565->{KLALBVirtual}[171d:a999:e697:4b23:ae52:9f29:4532:e1ee]:25565
-79
View File
@@ -1,79 +0,0 @@
[
{"Type":"KLALBController" ,
"TCPListen" : "0.0.0.0:4565",
"UDPListen" : "{UDP}0.0.0.0:4572",
"VirtualSocketName" : "KLALB_Stream",
"LineTable":["43.248.189.107:65529",
"cn-bj-bgp-3.openfrp.top:65529",
"180.76.147.250:65529",
"cn-ah-dx-1.natfrp.cloud:65529",
"cn-nn-dx-1.natfrp.cloud:65529",
"cn-wh-dx-1.natfrp.cloud:65529",
"cn-zz-bgp-10.natfrp.cloud:23330",
"cn-zz-bgp-7.natfrp.cloud:33336",
"43.143.109.64:49965",
"frp.104300.xyz:49965",
"us.afrps.cn:49966",
"hk.afrps.cn:49966",
"la.afrps.cn:49966",
"frp.freefrp.net:49965",
"frp1.freefrp.net:49965",
"frp2.freefrp.net:49965",
"frp4.freefrp.net:49965",
"cn-he-plc-2.openfrp.top:4572",
"{UDP}cn-he-plc-2.openfrp.top:4572",
"frp-mom.top:22226",
"frp-man.top:36555",
"us-sjc-bgp-2.openfrp.top:36555",
"us-sjc-bgp-1.openfrp.top:36555",
"[240e:340:d856:b700:6d02:6a6a:f9fc:865b]:4572"]
},
{"Type":"SocketBridge" ,
"Listen" : "0.0.0.0:4572",
"Bridge":{
"KLALB" : "SocketBridge",
"RDP":"SocketBridge",
"HTTP":"SocketBridge",
"HTTPS":"SocketBridge",
"DEFAULT":"MinecraftSocketBridge23332"
} ,
"Connect" : {
"KLALB" : "127.0.0.1:4565",
"RDP":"127.0.0.1:3389",
"HTTP":"127.0.0.1:5212",
"HTTPS":"192.168.1.235:443",
"DEFAULT":"127.0.0.1:36555"
}
},
{"Type":"SocketBridge" ,
"Listen" : "{KLALB_Stream}[::0]:23332",
"Bridge":"MinecraftSocketBridge23332",
"Connect" : "127.0.0.1:36555"
},
{ "Type":"SocketBridge" ,
"Listen" : "{KLALB_Stream}[::0]:23333",
"Bridge":"SocketBridge",
"Connect" : "127.0.0.1:5212"
},
{"Type":"SocketBridge" ,
"Listen" : "0.0.0.0:25561",
"Bridge":{
"KLALB" : "SocketBridge",
"DEFAULT":"MinecraftSocketBridge23330"
} ,
"Connect" : {
"KLALB" : "127.0.0.1:4565",
"DEFAULT":"127.0.0.1:25562"
}
},
{"Type":"SocketBridge" ,
"Listen" : "{KLALB_Stream}[::0]:23330",
"Bridge":"MinecraftSocketBridge23330",
"Connect" : "127.0.0.1:25562"
}
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-29
View File
@@ -1,29 +0,0 @@
0.0.0.0:35000(RDP)->192.168.1.233:3389
0.0.0.0:35000(HTTPS)->192.168.1.233:8444
0.0.0.0:35000(HTTP)->192.168.1.233:5212
0.0.0.0:35000(SSH)->192.168.1.236:22
0.0.0.0:35000(KLALB)->{KLALBRemote}
0.0.0.0:35000->127.0.0.1:35001 //Winds服(普通线路)
{KLALBVirtual}[::0]:25565->127.0.0.1:35001 //Winds服(加速线路)
//加速线路
{KLALBRemote}->43.248.189.107:35000
{KLALBRemote}->cn-bj-bgp-3.openfrp.top:65529
{KLALBRemote}->180.76.147.250:65529
{KLALBRemote}->cn-ah-dx-1.natfrp.cloud:65529
{KLALBRemote}->cn-nn-dx-1.natfrp.cloud:65529
{KLALBRemote}->cn-wh-dx-1.natfrp.cloud:65529
{KLALBRemote}->cn-zz-bgp-10.natfrp.cloud:23330
{KLALBRemote}->cn-zz-bgp-7.natfrp.cloud:33336
{KLALBRemote}->43.143.109.64:49965
{KLALBRemote}->frp.104300.xyz:49965
{KLALBRemote}->us.afrps.cn:49966
{KLALBRemote}->hk.afrps.cn:49966
{KLALBRemote}->la.afrps.cn:49966
{KLALBRemote}->frp.freefrp.net:49965
{KLALBRemote}->frp1.freefrp.net:49965
{KLALBRemote}->frp2.freefrp.net:49965
{KLALBRemote}->frp4.freefrp.net:49965
0.0.0.0:25565->{KLALBVirtual}[171d:a999:e697:4b23:ae52:9f29:4532:e1ee]:25565
-18
View File
@@ -1,18 +0,0 @@
43.248.189.107:65529
cn-bj-bgp-3.openfrp.top:65529
180.76.147.250:65529
cn-ah-dx-1.natfrp.cloud:65529
cn-nn-dx-1.natfrp.cloud:65529
cn-wh-dx-1.natfrp.cloud:65529
cn-zz-bgp-10.natfrp.cloud:23330
cn-zz-bgp-7.natfrp.cloud:33336
43.143.109.64:49965
frp.104300.xyz:49965
us.afrps.cn:49966
hk.afrps.cn:49966
la.afrps.cn:49966
frp.freefrp.net:49965
frp1.freefrp.net:49965
frp2.freefrp.net:49965
frp4.freefrp.net:49965
cn-he-plc-2.openfrp.top:4569
View File
-8
View File
@@ -1,8 +0,0 @@
0.0.0.0:35000(RDP)->192.168.1.233:3389
0.0.0.0:35000(HTTPS)->192.168.1.233:8444
0.0.0.0:35000(HTTP)->192.168.1.233:5212
0.0.0.0:35000(SSH)->192.168.1.236:22
0.0.0.0:35000(KLALB)->{KLALBRemote}
0.0.0.0:35000->127.0.0.1:35001 //Winds服(普通线路)
{KLALBVirtual}[::0]:25565->127.0.0.1:35001 //Winds服(加速线路)
+5
View File
@@ -117,3 +117,8 @@ enablewebapi=Enable Web API
weblistenaddr=Web API listen address weblistenaddr=Web API listen address
invaildweblistenaddr=Invalid Web API listen address invaildweblistenaddr=Invalid Web API listen address
enabletun=Enable TUN adapter enabletun=Enable TUN adapter
congestionmonitor=Congestion control monitor
rttbaseline=RTT baseline
rtt=RTT
rttmax=RTT max
rttmin=RTT min
+5
View File
@@ -117,3 +117,8 @@ enablewebapi=启用 Web API
weblistenaddr=Web API 监听地址:端口 weblistenaddr=Web API 监听地址:端口
invaildweblistenaddr=无效的 Web API 监听地址:端口 invaildweblistenaddr=无效的 Web API 监听地址:端口
enabletun=启用TUN虚拟网卡 enabletun=启用TUN虚拟网卡
congestionmonitor=拥塞控制监视器
rttbaseline=往返延迟基线
rtt=往返延迟
rttmax=往返延迟上限
rttmin=往返延迟下限
@@ -5,6 +5,9 @@ import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.kne.math.Long128; import org.kne.math.Long128;
@@ -256,4 +259,27 @@ public class NTPTimestamps {
.setBit(63); .setBit(63);
} }
} }
public static Long128 median(List<Long128> values) {
Objects.requireNonNull(values);
if ( values.isEmpty()) {
throw new IllegalArgumentException("列表不能为空");
}
// 1. 创建副本并排序
List<Long128> sorted = new ArrayList<>(values);
sorted.sort(Long128::compareTo);
// 2. 计算中位数
int size = sorted.size();
if (size % 2 == 1) {
// 奇数个:取中间值
return sorted.get(size / 2);
} else {
// 偶数个:取中间两个的平均值
Long128 left = sorted.get(size / 2 - 1);
Long128 right = sorted.get(size / 2);
return left.add(right).divide(Long128.valueOf(2));
}
}
} }
@@ -136,4 +136,19 @@ public class BBRCongestionAlgorithm implements CongestionAlgorithm ,DetnetConges
return "BBR"; return "BBR";
} }
@Override
public double getUpperDelayBound() {
return MAX_GAIN;
}
@Override
public double getLowerDelayBound() {
return MIN_GAIN;
}
@Override
public double getBurstLimit() {
return burstLimit;
}
} }
@@ -88,7 +88,7 @@ public class DCTCPCongestionAlgorithm implements CongestionAlgorithm {
} }
}else { }else {
if(windowUsed*3L>=congressWindowSize) { if(windowUsed*3L>=congressWindowSize) {
congressWindowSize+=4000; congressWindowSize+=4096;
updateWindowSize(); updateWindowSize();
} }
} }
@@ -4,4 +4,7 @@ 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); public void setBurstLimit(double limit);
public double getUpperDelayBound( );
public double getLowerDelayBound();
public double getBurstLimit();
} }
@@ -2,6 +2,8 @@ package org.kne.cloud.network.congestion;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.kne.cloud.network.monitor.DelaySampler;
public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCongestionAlgorithm { public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCongestionAlgorithm {
// 可配置的时延膨胀比上下限 - Vegas2.0核心参数 // 可配置的时延膨胀比上下限 - Vegas2.0核心参数
@@ -17,6 +19,7 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
private Consumer<Long> windowControlConsumer; private Consumer<Long> windowControlConsumer;
private long MIN_RTTVAR = 30000000L; private long MIN_RTTVAR = 30000000L;
private volatile long RTTCurr = 1000000000L; // RTT
private volatile long RTTMin = 1000000000L; // BaseRTT private volatile long RTTMin = 1000000000L; // BaseRTT
private volatile long RTTVar = 1000000000L; private volatile long RTTVar = 1000000000L;
private volatile long RTTAvg = 1000000000L; private volatile long RTTAvg = 1000000000L;
@@ -26,11 +29,6 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
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 maxwindow = 99999999999L; private volatile long maxwindow = 99999999999L;
@@ -58,106 +56,14 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
@Override private DelaySampler dsp=new DelaySampler();
public void putAck(long packetSize, long RTTns, long OWDup, boolean ecn) {
if(RTTns<0) {
throw new IllegalArgumentException("RTT:"+ RTTns+" is negative!");
}
// 处理ECN信号 - 将其视为强烈的拥塞信号
if (ecn) {
// 当收到ECN时,更激进地减少窗口
window2 = Math.max(0, window2 * 3 / 4);
if (windowControlConsumer != null) {
windowControlConsumer.accept(window2);
}
}
// 更新最小RTTBaseRTT
if (RTTns <= RTTMin) {
RTTMin = RTTns;
} else {
// 缓慢适应:当网络路径真正变化时,BaseRTT应能缓慢更新
// 这里使用极慢的衰减因子,只有在持续观测到更低RTT时才快速更新
RTTMin = (RTTMin * 999 + RTTns) / 1000;
}
// 更新最小OWDBaseOWD
if (OWDup <= OWDMin) {
OWDMin = OWDup;
} else {
// 缓慢适应:当网络路径真正变化时,BaseRTT应能缓慢更新
// 这里使用极慢的衰减因子,只有在持续观测到更低RTT时才快速更新
OWDMin = (OWDMin * 999 + OWDup) / 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++;
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 @Override
public void putAck(long packetSize, long RTTns, boolean ecn) { public void putAck(long packetSize, long RTTns, boolean ecn) {
if(RTTns<0) { if(RTTns<0) {
throw new IllegalArgumentException("RTT:"+ RTTns+" is negative!"); throw new IllegalArgumentException("RTT:"+ RTTns+" is negative!");
} }
this.RTTCurr=RTTns;
// 处理ECN信号 - 将其视为强烈的拥塞信号 // 处理ECN信号 - 将其视为强烈的拥塞信号
if (ecn) { if (ecn) {
// 当收到ECN时,更激进地减少窗口 // 当收到ECN时,更激进地减少窗口
@@ -167,14 +73,7 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
} }
} }
// 更新最小RTTBaseRTT dsp.recordDelay(RTTns);
if (RTTns <= RTTMin) {
RTTMin = RTTns;
} else {
// 缓慢适应:当网络路径真正变化时,BaseRTT应能缓慢更新
// 这里使用极慢的衰减因子,只有在持续观测到更低RTT时才快速更新
RTTMin = (RTTMin * 999 + RTTns) / 1000;
}
// 更新平滑RTT估计 // 更新平滑RTT估计
@@ -190,6 +89,15 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
long curr = System.nanoTime(); long curr = System.nanoTime();
// 每个RTT周期调整一次窗口(使用当前估计的RTT) // 每个RTT周期调整一次窗口(使用当前估计的RTT)
if (curr - RTTstartTime > Math.max(BIAS, 2*RTTMin)) { if (curr - RTTstartTime > Math.max(BIAS, 2*RTTMin)) {
dsp.update();
long rmin=dsp.getMinDelayNanos();
if(rmin<=RTTMin) {
RTTMin=rmin;
}else {
RTTMin=Math.min(rmin, RTTMin+1000);
}
long RTTCountx=RTTCount; long RTTCountx=RTTCount;
if (RTTCountx > 0) { if (RTTCountx > 0) {
long currentRTT = RTTTotal / RTTCountx; long currentRTT = RTTTotal / RTTCountx;
@@ -206,12 +114,12 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
// 2. 基于比值的窗口调整(取代原来的基于差值的调整) // 2. 基于比值的窗口调整(取代原来的基于差值的调整)
if (delayRatio > delayUpperBound) { if (delayRatio > delayUpperBound) {
// 时延过高:减小窗口,减少幅度与超标程度成正比 // 时延过高:减小窗口,减少幅度与超标程度成正比
window2 -= 4096; window2 =window2-4096;
} else if (delayRatio < delayLowerBound) { } else if (delayRatio < delayLowerBound) {
// 时延过低:增大窗口,增加幅度与低于目标程度成正比 // 时延过低:增大窗口,增加幅度与低于目标程度成正比
window2 += 4096; window2 =window2+4096;
} else { } else {
//window2=window2+4096
} }
// =================================================== // ===================================================
@@ -271,10 +179,12 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
public long getBaseRTT() { public long getBaseRTT() {
return RTTMin; return RTTMin;
} }
public long getAvgRTT() {
public long getCurrentRTT() {
return RTTAvg2; return RTTAvg2;
} }
public long getCurrentRTT() {
return RTTCurr;
}
@Override @Override
public void setUpperDelayBound(double upper) { public void setUpperDelayBound(double upper) {
@@ -295,4 +205,19 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
return "Vegas2"; return "Vegas2";
} }
@Override
public double getUpperDelayBound() {
return delayUpperBound;
}
@Override
public double getLowerDelayBound() {
return delayLowerBound;
}
@Override
public double getBurstLimit() {
return burstLimit;
}
} }
@@ -1,5 +1,8 @@
package org.kne.cloud.network.ipv6; package org.kne.cloud.network.ipv6;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -10,8 +13,15 @@ public abstract class AbstractIPv6NetworkLink implements IPv6NetworkLink {
private CopyOnWriteArraySet<IPv6LinkStateListener> listeners = new CopyOnWriteArraySet<>(); private CopyOnWriteArraySet<IPv6LinkStateListener> listeners = new CopyOnWriteArraySet<>();
private SRv6Router srv6Router; private SRv6Router srv6Router;
private final boolean loopback;
public AbstractIPv6NetworkLink(boolean loopback) {
super();
this.loopback = loopback;
}
public SRv6Router getSrv6Router() { public SRv6Router getSrv6Router() {
return srv6Router; return srv6Router;
} }
@@ -53,8 +63,49 @@ public abstract class AbstractIPv6NetworkLink implements IPv6NetworkLink {
} }
private BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>> receiveConsumer; private BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>> receiveConsumer;
private Supplier<Long> costSupplier;
@Override @Override
public void setReceiveConsumer(BiConsumer<IPv6NetworkLink,Supplier< IPv6Packet>> receiveConsumer) { public void setReceiveConsumer(BiConsumer<IPv6NetworkLink,Supplier< IPv6Packet>> receiveConsumer) {
this.receiveConsumer = receiveConsumer; this.receiveConsumer = receiveConsumer;
} }
@Override
public boolean isLoopBack() {
return loopback;
}
public Supplier<Long> getCostSupplier() {
return costSupplier;
}
public void setCostSupplier(Supplier<Long> costSupplier) {
this.costSupplier = costSupplier;
}
@Override
public List<RouteItem> getRouteItems() {
List<RouteItem> rlist = new ArrayList<>();
if(isLoopBack()) {
for(IPv6AddressGroup group:getAddressGroups()) {
rlist.add(new RouteItem(new IPv6AddressGroup(group.getAddress(), 128),
group.getAddress(), this, RouteItem.DIRECT, 0, 0, null, "D"));
}
}
if(isUp()) {
for (Iterator<Neighbor> iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
RouteItem ri = new RouteItem(new IPv6AddressGroup(addresses.getAddress().getAddress(), 128),
addresses.getAddress().getAddress(), this,RouteItem.SRv6_ENDXSID, 0, 128, costSupplier, "D");
rlist.add(ri);
RouteItem ris = new RouteItem(addresses.getLocator(),
addresses.getLocator().getAddress(), this, RouteItem.SRv6_ENDSID, 13, 128,
costSupplier, "D");
rlist.add(ris);
}
}
return rlist;
}
} }
@@ -61,6 +61,10 @@ public final class IPv6Address implements Comparable<IPv6Address> {
((long)(bytes[15] & 0xFF)); ((long)(bytes[15] & 0xFF));
} }
public IPv6Address(String string) throws UnknownHostException {
this((Inet6Address) Inet6Address.getByName(string));
}
/** /**
* 从两个long创建IPv6地址 * 从两个long创建IPv6地址
*/ */
@@ -67,7 +67,16 @@ public class IPv6AddressGroup implements Comparable<IPv6AddressGroup>{
prefixLength=in.read(); prefixLength=in.read();
} }
public boolean checkMatch(IPv6Address address2) { public boolean checkMatch(IPv6Address address2) {
return address2.equals(address.maskWith(IPv6Address.createMask(prefixLength))); IPv6Address cmsk= IPv6Address.createMask(prefixLength);
return address2.maskWith(cmsk).equals(address.maskWith(cmsk));
}
/**
* 返回裁剪后的路由表地址(主机位清零)。
* 例如 2001:db8:1::100/64 → 2001:db8:1::/64
*/
public IPv6AddressGroup toNetworkRoute() {
IPv6Address mask = IPv6Address.createMask(prefixLength);
IPv6Address maskedAddr = address.maskWith(mask);
return new IPv6AddressGroup(maskedAddr, prefixLength);
} }
} }
@@ -1378,7 +1378,7 @@ public class IPv6Packet extends NetworkPacket {
// 重路由计数器 // 重路由计数器
private AtomicInteger rerouteCounter = new AtomicInteger(0); private AtomicInteger rerouteCounter = new AtomicInteger(0);
public AtomicInteger getRerouteCounter() { public AtomicInteger getRouteCounter() {
return rerouteCounter; return rerouteCounter;
} }
@@ -41,6 +41,7 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
private Lock slok = new SpinLock(); private Lock slok = new SpinLock();
public IPv6TUNLoopbackNetworkLink(String name,IPv6AddressGroup hostAddress, int mtu, List<InetAddress> dns) throws IOException { public IPv6TUNLoopbackNetworkLink(String name,IPv6AddressGroup hostAddress, int mtu, List<InetAddress> dns) throws IOException {
super(true);
if (tun != null) if (tun != null)
throw new IllegalStateException("already open!"); throw new IllegalStateException("already open!");
try { try {
@@ -204,13 +205,6 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
LockSupport.unpark(tr); LockSupport.unpark(tr);
} }
@Override
public boolean isLoopBack() {
return true;
}
@Override @Override
public List<Neighbor> getNeighborsInfo() { public List<Neighbor> getNeighborsInfo() {
List<Neighbor> hs = new ArrayList<>(); List<Neighbor> hs = new ArrayList<>();
@@ -219,10 +213,6 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
return hs; return hs;
} }
/*
* @Override public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
* return sendQueue.size() > 1000*scale; }
*/
@Override @Override
public String getName() { public String getName() {
@@ -255,27 +245,4 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
return List.of(hostAddress); return List.of(hostAddress);
} }
@Override
public List<RouteItem> getRouteItems() {
List<RouteItem> rlist = new ArrayList<>();
for (IPv6AddressGroup grp : getAddressGroups()) {
rlist.add(new RouteItem(new IPv6AddressGroup(grp.getAddress(), 128), grp.getAddress(), this, "Direct", 0, 1,
null, "D", true));
}
for (Iterator<Neighbor> iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
RouteItem ri = new RouteItem(new IPv6AddressGroup(addresses.getAddress().getAddress(), 128),
addresses.getAddress().getAddress(), this, "Direct", 0, 128, null, "D", false);
rlist.add(ri);
RouteItem ris = new RouteItem(addresses.getLocator(), addresses.getLocator().getAddress(), this,
"KLALB SRv6", 13, 128, null, "D", false);
rlist.add(ris);
}
return rlist;
}
} }
@@ -32,6 +32,7 @@ public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements
//new Inet6AddressGroup(loopbackAddress, 128) new Inet6AddressGroup((Inet6Address) Inet6Address.getByName("::1"), 128) //new Inet6AddressGroup(loopbackAddress, 128) new Inet6AddressGroup((Inet6Address) Inet6Address.getByName("::1"), 128)
public LoopbackIPv6NetworkLink(List<IPv6AddressGroup> addressGroupsx,SRv6Router router) { public LoopbackIPv6NetworkLink(List<IPv6AddressGroup> addressGroupsx,SRv6Router router) {
super(true);
this.addressGroups .addAll( addressGroupsx); this.addressGroups .addAll( addressGroupsx);
} }
@@ -54,10 +55,7 @@ public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements
} }
} }
@Override
public boolean isLoopBack() {
return true;
}
@Override @Override
public List<Neighbor> getNeighborsInfo() { public List<Neighbor> getNeighborsInfo() {
@@ -93,29 +91,6 @@ public class LoopbackIPv6NetworkLink extends AbstractIPv6NetworkLink implements
return rerouteConsumer; return rerouteConsumer;
} }
@Override
public List<RouteItem> getRouteItems() {
List<RouteItem> rlist = new ArrayList<>();
for(IPv6AddressGroup group:addressGroups) {
rlist.add(new RouteItem(new IPv6AddressGroup(group.getAddress(), 128),
group.getAddress(), this, "Direct", 0, 0, null, "D", true));
}
for (Iterator<Neighbor> iteratorx = getNeighborsInfo().iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
RouteItem ri = new RouteItem(new IPv6AddressGroup(addresses.getAddress().getAddress(), 128),
addresses.getAddress().getAddress(), this, "Direct", 0, 128, null, "D",
false);
rlist.add(ri);
RouteItem ris = new RouteItem(addresses.getLocator(),
addresses.getLocator().getAddress(), this, "KLALB SRv6", 13, 128,
null, "D", false);
rlist.add(ris);
}
return rlist;
}
public SRv6Router getRouter() { public SRv6Router getRouter() {
+9 -10
View File
@@ -4,6 +4,11 @@ import java.util.Objects;
import java.util.function.Supplier; import java.util.function.Supplier;
public class RouteItem implements Comparable<RouteItem>,Cloneable{ public class RouteItem implements Comparable<RouteItem>,Cloneable{
public static final String DIRECT="Direct";
public static final String SRv6_ENDSID="SRv6 ENDSID";
public static final String SRv6_ENDXSID="SRv6 ENDXSID";
public static final String KLALB_SRv6 = "KLALB_SRv6";
private IPv6AddressGroup destination; private IPv6AddressGroup destination;
private IPv6Address nexthop; private IPv6Address nexthop;
private IPv6NetworkLink destlink; private IPv6NetworkLink destlink;
@@ -12,7 +17,6 @@ public class RouteItem implements Comparable<RouteItem>,Cloneable{
private long cost; private long cost;
private String flag; private String flag;
private Supplier<Long> costSupplier; private Supplier<Long> costSupplier;
private boolean isLoopback;
public String getFlag() { public String getFlag() {
return flag; return flag;
} }
@@ -34,21 +38,20 @@ public class RouteItem implements Comparable<RouteItem>,Cloneable{
&& pre == other.pre && Objects.equals(proto, other.proto); && pre == other.pre && Objects.equals(proto, other.proto);
} }
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,String flag,boolean isLoopback) { long cost,String flag) {
super(); super();
this.destination = destination; this.destination = destination.toNetworkRoute();
this.nexthop = nexthop; this.nexthop = nexthop;
this.destlink = destlink; this.destlink = destlink;
this.proto = proto; this.proto = proto;
this.pre = pre; this.pre = pre;
this.cost = cost; this.cost = cost;
this.flag=flag; this.flag=flag;
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,Supplier<Long> costSupplier,String flag,boolean isLoopback) { long cost,Supplier<Long> costSupplier,String flag) {
super(); super();
this.destination = destination; this.destination = destination.toNetworkRoute();
this.nexthop = nexthop; this.nexthop = nexthop;
this.destlink = destlink; this.destlink = destlink;
this.proto = proto; this.proto = proto;
@@ -56,7 +59,6 @@ public class RouteItem implements Comparable<RouteItem>,Cloneable{
this.cost = cost; this.cost = cost;
this.costSupplier=costSupplier; this.costSupplier=costSupplier;
this.flag=flag; this.flag=flag;
this.isLoopback=isLoopback;
} }
public IPv6AddressGroup getDestination() { public IPv6AddressGroup getDestination() {
return destination; return destination;
@@ -73,9 +75,6 @@ public class RouteItem implements Comparable<RouteItem>,Cloneable{
public int getPre() { public int getPre() {
return pre; return pre;
} }
public boolean isLoopback() {
return isLoopback;
}
@Override @Override
public String toString() { public String toString() {
return getDestination()+"\t"+getProto()+"\t"+getPre()+"\t"+getCost()+"\t"+getFlag()+"\t"+getNexthop()+"\t"+getDestlink().getName(); return getDestination()+"\t"+getProto()+"\t"+getPre()+"\t"+getCost()+"\t"+getFlag()+"\t"+getNexthop()+"\t"+getDestlink().getName();
@@ -13,6 +13,10 @@ import org.kne.cloud.network.ipv6.RouteItem;
public abstract class AbstractControlledIPv6NetworkLink extends AbstractIPv6NetworkLink implements ControlledIPv6NetworkLink{ public abstract class AbstractControlledIPv6NetworkLink extends AbstractIPv6NetworkLink implements ControlledIPv6NetworkLink{
public AbstractControlledIPv6NetworkLink(boolean loopback) {
super(loopback);
}
} }
+1 -1
View File
@@ -12,7 +12,7 @@ public class CONST {
public static final String KLALB_S_RV6 = "KLALB_SRv6"; public static final String KLALB_S_RV6 = "KLALB_SRv6";
public static final String KLTP_VIRTUAL_SOCKET_NAME="kltp";
public static final int itemwidth = 1000; public static final int itemwidth = 1000;
public static final int linepanelheight = 41; public static final int linepanelheight = 41;
@@ -86,7 +86,7 @@ public class KLALBController {
private static final boolean debug=false; private static final boolean debug=false;
private static final boolean showpacket = false; private static final boolean showpacket = false;
private static final int PREFIX = 128;// 112 private static final int PREFIX = 128;
private static final int DISCOVERY_PORT = 4569; private static final int DISCOVERY_PORT = 4569;
private static List<IPMulticastDiscovery> ipmd = new ArrayList<>(); private static List<IPMulticastDiscovery> ipmd = new ArrayList<>();
@@ -634,7 +634,8 @@ public class KLALBController {
private void loadSRv6ProtocolStack(IPv6AddressGroup selfx, boolean enableVirtualAdapter) { private void loadSRv6ProtocolStack(IPv6AddressGroup selfx, boolean enableVirtualAdapter) {
networkInterfaceManager.getInetAddressesExcept().add(selfx.getAddress().toInet6Address()); networkInterfaceManager.getInetAddressesExcept().add(selfx.getAddress().toInet6Address());
srv6Router = new SRv6Router(selfx, clock); IPv6AddressGroup group=new IPv6AddressGroup(selfx.getAddress(),32);
srv6Router = new SRv6Router(selfx,group, clock);
if(configItem!=null) { if(configItem!=null) {
srv6Router.setPerformanceStrategy(PerformanceStrategy.fromDescription(configItem.getPerformanceStrategy())); srv6Router.setPerformanceStrategy(PerformanceStrategy.fromDescription(configItem.getPerformanceStrategy()));
srv6Router.setDeviceName(configItem.getDeviceName()); srv6Router.setDeviceName(configItem.getDeviceName());
@@ -653,8 +654,7 @@ public class KLALBController {
if (enableTUN) { if (enableTUN) {
Thread t=new Thread(()->{ Thread t=new Thread(()->{
try { try {
IPv6TUNLoopbackNetworkLink tunlink = new IPv6TUNLoopbackNetworkLink(name.trim(), IPv6TUNLoopbackNetworkLink tunlink = new IPv6TUNLoopbackNetworkLink(name.trim(),group, SRv6Router.MTU, dnsAddresses);
new IPv6AddressGroup(srv6Router.getLocator().getAddress(), 32), SRv6Router.MTU, dnsAddresses);
tunlink.setMonitor(datatMonitor); tunlink.setMonitor(datatMonitor);
// srv6Router.getLinkTabel().add(tunlink); // srv6Router.getLinkTabel().add(tunlink);
srv6Router.getinLoopback().setFallbackLink(tunlink); srv6Router.getinLoopback().setFallbackLink(tunlink);
@@ -687,7 +687,7 @@ public class KLALBController {
// System.out.println(context); // System.out.println(context);
try { try {
NTPv4Protocol nvc = new NTPv4Protocol(context, NTPv4Protocol nvc = new NTPv4Protocol(context,
new MultiProtocolSocketAddress(iproxyname + "_Datagram","0.0.0.0",123)); new MultiProtocolSocketAddress(iproxyname + "datagram","0.0.0.0",123));
srv6Router.addSRv6RouterListener(new SRv6RouterListener() { srv6Router.addSRv6RouterListener(new SRv6RouterListener() {
@Override @Override
@@ -698,7 +698,7 @@ public class KLALBController {
for (Neighbor neighbor : nb) { for (Neighbor neighbor : nb) {
if (neighbor.getLocator() != null) if (neighbor.getLocator() != null)
sp.add(new NTPPeer( sp.add(new NTPPeer(
new MultiProtocolSocketAddress(iproxyname + "_Datagram", new MultiProtocolSocketAddress(iproxyname + "datagram",
neighbor.getLocator().getAddress().toString(), 123), neighbor.getLocator().getAddress().toString(), 123),
NTPv4Packet.NTP_SYMMETRIC_ACTIVE)); NTPv4Packet.NTP_SYMMETRIC_ACTIVE));
@@ -978,8 +978,8 @@ public class KLALBController {
public void registerToProxyTypeAs(String proxyname) { public void registerToProxyTypeAs(String proxyname) {
MultiProtocolSocketAddress.getSocketTypeRegister().put(proxyname + "_Stream", streamSocketType); MultiProtocolSocketAddress.getSocketTypeRegister().put(proxyname + "stream", streamSocketType);
MultiProtocolSocketAddress.getSocketTypeRegister().put(proxyname + "_Datagram", datagramSocketType); MultiProtocolSocketAddress.getSocketTypeRegister().put(proxyname + "datagram", datagramSocketType);
// ProxyProfileEntry.getRegister().put(proxyname, this); // ProxyProfileEntry.getRegister().put(proxyname, this);
} }
@@ -22,8 +22,7 @@ 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.TimeDebugger; import org.kne.debug.TimeDebugger;
import org.kne.membandboost.MembandBenchmark; import org.kne.membandboost.benchmark.*;;
import org.kne.membandboost.ObjectPoolBandwidthTest;
public class KLALBMain { public class KLALBMain {
public static KLALBStateGUI3 ksg; public static KLALBStateGUI3 ksg;
@@ -239,10 +238,6 @@ public class KLALBMain {
case "membandbenchmark": 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;
@@ -168,9 +168,11 @@ public class KLALBProxySystem {
String vsne=kcci.getVirtualSocketName(); String vsne=kcci.getVirtualSocketName();
//if(vsne!=null) { if(vsne!=null) {
MultiProtocolSocketAddress.getSocketTypeRegister().put(vsne, klalbController.getStreamSocketType()); MultiProtocolSocketAddress.getSocketTypeRegister().put(vsne, klalbController.getStreamSocketType());
//} }else{
MultiProtocolSocketAddress.getSocketTypeRegister().put(CONST.KLTP_VIRTUAL_SOCKET_NAME, klalbController.getStreamSocketType());
}
MultiProtocolSocketAddress tcple=kcci.getTCPListen(); MultiProtocolSocketAddress tcple=kcci.getTCPListen();
if(tcple!=null) { if(tcple!=null) {
@@ -142,15 +142,18 @@ public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implement
} }
public KLALBRemoteLink(KLALBController controller,KLALBPacketLink kpl, IPv6AddressGroup address) { public KLALBRemoteLink(KLALBController controller,KLALBPacketLink kpl, IPv6AddressGroup address) {
super(false);
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);
name=kpl.toString(); name=kpl.toString();
setCostSupplier( CostSupplierFactory.owdSupplier(monitor));
} }
private KLALBRemoteLink(KLALBController controller, MultiProtocolSocketAddress mpa, MultiProtocolSocketAddress bindaddr, IPv6AddressGroup address) { private KLALBRemoteLink(KLALBController controller, MultiProtocolSocketAddress mpa, MultiProtocolSocketAddress bindaddr, IPv6AddressGroup address) {
super(false);
this.klalbController=controller; this.klalbController=controller;
sysclk = klalbController.getClock(); sysclk = klalbController.getClock();
this.socketAddress = mpa; this.socketAddress = mpa;
@@ -162,6 +165,7 @@ public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implement
} else { } else {
name=bindaddr.toString() + "" + mpa.toString(); name=bindaddr.toString() + "" + mpa.toString();
} }
setCostSupplier( CostSupplierFactory.owdSupplier( monitor));
} }
@@ -854,10 +858,6 @@ public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implement
} }
} }
@Override
public boolean isLoopBack() {
return false;
}
BandwidthDistributer bandwidthDistributer=new BandwidthDistributer<>(); BandwidthDistributer bandwidthDistributer=new BandwidthDistributer<>();
@Override @Override
public List<Neighbor> getNeighborsInfo() { public List<Neighbor> getNeighborsInfo() {
@@ -946,31 +946,28 @@ public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implement
return (!isClosed()) && (status.getState() == LinkStatus.UP) ; return (!isClosed()) && (status.getState() == LinkStatus.UP) ;
} }
@Override /*@Override
public List<RouteItem> getRouteItems() { public List<RouteItem> getRouteItems() {
List<RouteItem> rlist = new ArrayList<>(); List<RouteItem> rlist = new ArrayList<>();
if(isUp()) { if(isUp()) {
IPv6AddressGroup adg = addressGroup;
/*if (adg != null)
rlist.add(new RouteItem(new IPv6AddressGroup(adg.getAddress(), 128), adg.getAddress(), this, "Direct", 0, 0,
null, "D", true));*/
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, CostSupplierFactory.expectedDelaySupplier((DelayMonitorData) addresses.getMonitor(), status, algorithm::getRTO), "D", false); addresses.getAddress().getAddress(), this, RouteItem.SRv6_ENDXSID, 0, 128, CostSupplierFactory.expectedDelaySupplier((DelayMonitorData) addresses.getMonitor(), status, algorithm::getRTO), "D");
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, CostSupplierFactory.expectedDelaySupplier((DelayMonitorData) addresses.getMonitor(), status, algorithm::getRTO), "D", false); RouteItem.SRv6_ENDSID, 13, 128, CostSupplierFactory.expectedDelaySupplier((DelayMonitorData) addresses.getMonitor(), status, algorithm::getRTO), "D");
rlist.add(ris); rlist.add(ris);
} }
} }
} }
return rlist; return rlist;
} }*/
@Override @Override
public void setCongressCondition(Lock lock, Condition condition) { public void setCongressCondition(Lock lock, Condition condition) {
@@ -18,7 +18,10 @@ import org.jfree.chart.JFreeChart;
import org.jfree.data.time.Millisecond; import org.jfree.data.time.Millisecond;
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.CongestionAlgorithm;
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.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.IPv6Packet; import org.kne.cloud.network.ipv6.IPv6Packet;
@@ -42,12 +45,14 @@ public class LineMonitorGUI extends XFrame {
private Timer timer1; private Timer timer1;
private Timer timer2; private Timer timer2;
private Timer timer3; private Timer timer3;
private Timer timer4;
private TimerTask tsk3; private TimerTask tsk3;
private TimerTask tsk4, tsk5,tsk6; private TimerTask tsk4, tsk5,tsk6,tsk7;
private TimerTask d1; private TimerTask d1;
private TimerTask d2; private TimerTask d2;
private TimerTask d3; private TimerTask d3;
private TimerTask d4;
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"));
@@ -62,13 +67,21 @@ public class LineMonitorGUI extends XFrame {
private TimeSeries queueused = new TimeSeries(UIEnv.getRsb().getString("queueused")); private TimeSeries queueused = new TimeSeries(UIEnv.getRsb().getString("queueused"));
private TimeSeries buffermax = new TimeSeries(UIEnv.getRsb().getString("maxbuffer")); private TimeSeries buffermax = new TimeSeries(UIEnv.getRsb().getString("maxbuffer"));
private TimeSeries rttbaseline = new TimeSeries(UIEnv.getRsb().getString("rttbaseline"));
private TimeSeries rtt = new TimeSeries(UIEnv.getRsb().getString("rtt"));
private TimeSeries rttmin=new TimeSeries(UIEnv.getRsb().getString("rttmin"));
private TimeSeries rttmax=new TimeSeries(UIEnv.getRsb().getString("rttmax"));
private KLALBRemoteLink tr; private KLALBRemoteLink tr;
private JFreeChart jfc; private JFreeChart jfc;
private JFreeChart jfce; private JFreeChart jfce;
private JFreeChart jbfc; private JFreeChart jbfc;
private JFreeChart jbfcv;
private JLabel spdp; private JLabel spdp;
private JLabel delp; private JLabel delp;
private JLabel sbpdp; private JLabel sbpdp;
private JLabel sbpdpv;
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;
@@ -155,6 +168,22 @@ public class LineMonitorGUI extends XFrame {
jp.add(sbpdp); jp.add(sbpdp);
TimeSeriesCollection tbsc1 = new TimeSeriesCollection();
tbsc1.addSeries(rttbaseline);
tbsc1.addSeries(rtt);
tbsc1.addSeries(rttmax);
tbsc1.addSeries(rttmin);
jbfcv = ChartFactory.createTimeSeriesChart(UIEnv.getRsb().getString("congestionmonitor"),
UIEnv.getRsb().getString("time") + "(s)", UIEnv.getRsb().getString("delay") + "(ms)", tbsc1);
jbfcv.getXYPlot().setBackgroundPaint(Color.BLACK);
jbfcv.getXYPlot().getRenderer().setSeriesPaint(0, Color.CYAN);
jbfcv.getXYPlot().getRenderer().setSeriesPaint(1, Color.YELLOW);
jbfcv.getXYPlot().getRenderer().setSeriesPaint(2, Color.RED);
jbfcv.getXYPlot().getRenderer().setSeriesPaint(3, Color.GREEN);
changeFont(jbfcv);
sbpdpv = new JLabel();
sbpdpv.setBorder(new LineBorder(Color.DARK_GRAY));
jp.add(sbpdpv);
@@ -262,6 +291,14 @@ public class LineMonitorGUI extends XFrame {
buffermax.setMaximumItemCount((int) timeRange/5); buffermax.setMaximumItemCount((int) timeRange/5);
queueused.setMaximumItemCount((int) timeRange/5); queueused.setMaximumItemCount((int) timeRange/5);
} }
synchronized (jbfcv) {
jbfcv.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");
} }
@@ -328,6 +365,24 @@ public class LineMonitorGUI extends XFrame {
} }
} }
} }
private void recordCongestionData() {
if (isVisible()) {
Millisecond ms = new Millisecond(
new Date(tr.getMonitor().getClock().getCurrentTimeMillis()));
synchronized (jbfcv) {
CongestionAlgorithm window=tr.getWindow().getAlgorithm();
if(window !=null&&window instanceof DetnetCongestionAlgorithm) {
Vegas2CongestionAlgorithm deta=(Vegas2CongestionAlgorithm) window;
double baseRTT=deta.getBaseRTT();
rttbaseline.addOrUpdate(ms, baseRTT / 1000000.0);
rtt.addOrUpdate(ms, deta.getCurrentRTT() / 1000000.0);
rttmax.addOrUpdate(ms, baseRTT*deta.getUpperDelayBound() / 1000000.0);
rttmin.addOrUpdate(ms, baseRTT*deta.getLowerDelayBound() / 1000000.0);
}
}
}
}
@Override @Override
public void setVisible(boolean b) { public void setVisible(boolean b) {
if (b) { if (b) {
@@ -336,6 +391,7 @@ public class LineMonitorGUI extends XFrame {
timer1 = new Timer(); timer1 = new Timer();
timer2 = new Timer(); timer2 = new Timer();
timer3 = new Timer(); timer3 = new Timer();
timer4 = new Timer();
tsk3 = new TimerTask() { tsk3 = new TimerTask() {
@Override @Override
@@ -365,6 +421,13 @@ public class LineMonitorGUI extends XFrame {
recordBufferData(); recordBufferData();
} }
}; };
tsk7 = new TimerTask() {
@Override
public void run() {
recordCongestionData();
}
};
d1 = new TimerTask() { d1 = new TimerTask() {
@Override @Override
@@ -406,6 +469,20 @@ public class LineMonitorGUI extends XFrame {
} }
} }
}; };
d4 = new TimerTask() {
@Override
public void run() {
if (isVisible()) {
synchronized (jbfcv) {
ImageIcon i3 = new ImageIcon(
jbfcv.createBufferedImage(sbpdpv.getWidth(), sbpdpv.getHeight()));
sbpdpv.setIcon(i3);
}
}
}
};
timer.scheduleAtFixedRate(tsk3, 25, 25); timer.scheduleAtFixedRate(tsk3, 25, 25);
timer1.scheduleAtFixedRate(tsk4, 10, 10); timer1.scheduleAtFixedRate(tsk4, 10, 10);
timer1.scheduleAtFixedRate(d1, 25, 25); timer1.scheduleAtFixedRate(d1, 25, 25);
@@ -413,6 +490,8 @@ public class LineMonitorGUI extends XFrame {
timer2.scheduleAtFixedRate(d2, 25, 25); timer2.scheduleAtFixedRate(d2, 25, 25);
timer3.scheduleAtFixedRate(tsk6, 10, 10); timer3.scheduleAtFixedRate(tsk6, 10, 10);
timer3.scheduleAtFixedRate(d3, 25, 25); timer3.scheduleAtFixedRate(d3, 25, 25);
timer4.scheduleAtFixedRate(tsk7, 25, 25);
timer4.scheduleAtFixedRate(d4, 25, 25);
} }
} else { } else {
@@ -422,12 +501,18 @@ public class LineMonitorGUI extends XFrame {
tsk4.cancel(); tsk4.cancel();
if (tsk5 != null) if (tsk5 != null)
tsk5.cancel(); tsk5.cancel();
if (tsk6 != null)
tsk6.cancel();
if (tsk7 != null)
tsk7.cancel();
if (d1 != null) if (d1 != null)
d1.cancel(); d1.cancel();
if (d2 != null) if (d2 != null)
d2.cancel(); d2.cancel();
if (d3 != null) if (d3 != null)
d3.cancel(); d3.cancel();
if (d4 != null)
d4.cancel();
if (timer != null) if (timer != null)
timer.cancel(); timer.cancel();
if (timer1 != null) if (timer1 != null)
@@ -438,6 +523,9 @@ public class LineMonitorGUI extends XFrame {
if (timer3 != null) if (timer3 != null)
timer3.cancel(); timer3.cancel();
if (timer4 != null)
timer4.cancel();
timer = null; timer = null;
} }
super.setVisible(b); super.setVisible(b);
@@ -82,8 +82,8 @@ public class NetworkGraphPanel extends GraphPanel {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
KperfGUI kpfg=new KperfGUI(); KperfGUI kpfg=new KperfGUI();
kpfg.setVisible(true); kpfg.setVisible(true);
MultiProtocolSocketAddress source=new MultiProtocolSocketAddress("KLALB_Stream",controller.getIpv6Router().getLocator().getAddress().toString(),0); MultiProtocolSocketAddress source=new MultiProtocolSocketAddress("kltp",controller.getIpv6Router().getLocator().getAddress().toString(),0);
MultiProtocolSocketAddress target=new MultiProtocolSocketAddress("KLALB_Stream", address.toString(), 4564); MultiProtocolSocketAddress target=new MultiProtocolSocketAddress("kltp", address.toString(), 4564);
kpfg.setTarget(target,source); kpfg.setTarget(target,source);
} }
}); });
@@ -68,10 +68,9 @@ public class KLALBWebServer {
server.createContext("/api/links", this::handleLinks); server.createContext("/api/links", this::handleLinks);
server.createContext("/api/links/action", this::handleLinkAction); server.createContext("/api/links/action", this::handleLinkAction);
server.createContext("/api/links/reconnect", this::handleReconnectAll); server.createContext("/api/links/reconnect", this::handleReconnectAll);
server.createContext("/api/routes", this::handleRoutes); server.createContext("/api/routing-table", this::handleRoutingTable);
server.createContext("/api/nodes", this::handleNodes); server.createContext("/api/nodes", this::handleNodes);
server.createContext("/api/node-info", this::handleNodeInfo); server.createContext("/api/node-info", this::handleNodeInfo);
server.createContext("/api/interfaces", this::handleInterfaces);
server.createContext("/api/config", this::handleConfig); server.createContext("/api/config", this::handleConfig);
// Static Files / SPA Fallback Handler // Static Files / SPA Fallback Handler
@@ -429,7 +428,7 @@ public class KLALBWebServer {
} }
} }
private void handleRoutes(HttpExchange exchange) throws IOException { private void handleRoutingTable(HttpExchange exchange) throws IOException {
if (handleCorsPreflight(exchange)) return; if (handleCorsPreflight(exchange)) return;
if (!"GET".equalsIgnoreCase(exchange.getRequestMethod())) { if (!"GET".equalsIgnoreCase(exchange.getRequestMethod())) {
sendError(exchange, 405, "Method not allowed"); sendError(exchange, 405, "Method not allowed");
@@ -633,33 +632,6 @@ public class KLALBWebServer {
sendJsonResponse(exchange, 200, result); sendJsonResponse(exchange, 200, result);
} }
private void handleInterfaces(HttpExchange exchange) throws IOException {
if (handleCorsPreflight(exchange)) return;
if (!"GET".equalsIgnoreCase(exchange.getRequestMethod())) {
sendError(exchange, 405, "Method not allowed");
return;
}
KLALBController kc = proxySystem.getKlalbController();
JsonArray ifacesArray = new JsonArray();
if (kc != null && kc.getNetworkInterfaceManager() != null) {
List<NetworkInterface> ifaces = kc.getNetworkInterfaceManager().getAllAvaliableNetworkInterface();
for (NetworkInterface nif : ifaces) {
JsonObject obj = new JsonObject();
obj.addProperty("name", nif.getName());
obj.addProperty("displayName", nif.getDisplayName());
JsonArray ips = new JsonArray();
List<InetAddress> addrs = kc.getNetworkInterfaceManager().getNetworkInterfaceAddress(nif);
for (InetAddress a : addrs) {
ips.add(new JsonPrimitive(a.getHostAddress()));
}
obj.add("addresses", ips);
ifacesArray.add(obj);
}
}
sendJsonResponse(exchange, 200, ifacesArray);
}
private void handleConfig(HttpExchange exchange) throws IOException { private void handleConfig(HttpExchange exchange) throws IOException {
if (handleCorsPreflight(exchange)) return; if (handleCorsPreflight(exchange)) return;
String method = exchange.getRequestMethod(); String method = exchange.getRequestMethod();
@@ -20,26 +20,26 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit
downSampler.update(); downSampler.update();
if(upSampler.getSnapshotPacketCount()>0&&upSampler.getSnapshotTotalDelay()>0) { if(upSampler.getSnapshotPacketCount()>0&&upSampler.getSnapshotTotalDelay()>0) {
getUploadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, upSampler.getAvgDelayNanos()); getUploadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, upSampler.getAvgDelayNanos());
long odelay=upSampler.getMinDelayNanos();
if(outDelayMin==Long.MAX_VALUE||odelay<=outDelayMin) {
outDelayMin=odelay;
}else{
outDelayMin=Math.min(odelay, outDelayMin+10000);
}
} }
if(downSampler.getSnapshotPacketCount()>0&&downSampler.getSnapshotTotalDelay()>0) { if(downSampler.getSnapshotPacketCount()>0&&downSampler.getSnapshotTotalDelay()>0) {
getDownloadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, downSampler.getAvgDelayNanos()); getDownloadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, downSampler.getAvgDelayNanos());
long idelay=downSampler.getMinDelayNanos();
if(inDelayMin==Long.MAX_VALUE||idelay<=inDelayMin) {
inDelayMin=idelay;
}else{
inDelayMin=Math.min(idelay, inDelayMin+10000);
}
} }
long time=System.nanoTime(); long time=System.nanoTime();
if(time-stime>timewindowmax) { if(time-stime>timewindowmax) {
stime=time; 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;
}
} }
} }
+6 -27
View File
@@ -117,7 +117,7 @@ public class NTPContext implements Closeable, AutoCloseable {
} }
protected void putPacket(NTPv4Packet nv4, MultiProtocolSocketAddress inetSocketAddress) { protected void putPacket(NTPv4Packet nv4, MultiProtocolSocketAddress inetSocketAddress) {
checkIP(); //checkIP();
List<NTPv4Packet> newv = new Vector<NTPv4Packet>(); List<NTPv4Packet> newv = new Vector<NTPv4Packet>();
List<NTPv4Packet> oldv = recvmap.putIfAbsent(inetSocketAddress, newv); List<NTPv4Packet> oldv = recvmap.putIfAbsent(inetSocketAddress, newv);
if (oldv == null) { if (oldv == null) {
@@ -132,25 +132,6 @@ public class NTPContext implements Closeable, AutoCloseable {
} }
} }
private void checkIP() {
Set<Entry<MultiProtocolSocketAddress, List<NTPv4Packet>>> ens = recvmap.entrySet();
for (Iterator<Entry<MultiProtocolSocketAddress, List<NTPv4Packet>>> iterator = ens.iterator(); iterator
.hasNext();) {
Entry<MultiProtocolSocketAddress, List<NTPv4Packet>> entry = (Entry<MultiProtocolSocketAddress, List<NTPv4Packet>>) iterator
.next();
AtomicBoolean ab = new AtomicBoolean(false);
ios.forEach((x) -> {
if (!ab.get())
if (x.findPeer(entry.getKey()) != null) {
ab.set(true);
return;
}
});
if (!ab.get()) {
iterator.remove();
}
}
}
private class PeerInfo implements Comparable<PeerInfo> { private class PeerInfo implements Comparable<PeerInfo> {
private MultiProtocolSocketAddress address; private MultiProtocolSocketAddress address;
@@ -225,14 +206,12 @@ public class NTPContext implements Closeable, AutoCloseable {
PeerInfo pix = peerInfo.get(0); PeerInfo pix = peerInfo.get(0);
currentClock = pix; currentClock = pix;
int i; int i;
int m = Math.min(peerInfo.size(), 3); List<Long128> adjts = new ArrayList<>();
Long128 bi = Long128.ZERO; for (i = 0; i < peerInfo.size(); i++) {
for (i = 0; i < m; i++) { adjts.add(peerInfo.get(i).getAdj());
PeerInfo pi = peerInfo.get(i);
Long128 adjt = pi.getAdj();
bi = bi.add(adjt);
} }
Long128 delta = bi.divide(Long128.valueOf(i)); Long128 delta = NTPTimestamps. median(adjts);
//System.out.println(adjts+":"+delta);
avgAdj=(avgAdj*7+delta.abs().longValue())/8; avgAdj=(avgAdj*7+delta.abs().longValue())/8;
Long128 deltaabs=delta.abs(); Long128 deltaabs=delta.abs();
if (deltaabs.compareTo(adjustThreshold0) > 0&&firstSync.compareAndSet(true, false)) { if (deltaabs.compareTo(adjustThreshold0) > 0&&firstSync.compareAndSet(true, false)) {
@@ -405,18 +405,5 @@ public class NTPv4Protocol implements Closeable, AutoCloseable {
return dgs.isClosed(); return dgs.isClosed();
} }
public static void main(String[] args) throws IOException, InterruptedException {
HighAccuracyClock hac = new HighAccuracyClock();
NTPContext context = new NTPContext(hac);
System.out.println(context);
NTPv4Protocol nvc = new NTPv4Protocol(context, new MultiProtocolSocketAddress("{UDP}0.0.0.0:123"));// 106.55.184.199
nvc.getPeers().add(new NTPPeer("{UDP}106.55.184.199:123", NTPv4Packet.NTP_CLIENT));
nvc.getPeers().add(new NTPPeer("{UDP}time.windows.com:123", NTPv4Packet.NTP_CLIENT));
nvc.getPeers().add(new NTPPeer("{UDP}127.0.0.1:123", NTPv4Packet.NTP_SYMMETRIC_ACTIVE));
/*
* for (int i = 0; i < 10000; i++) { Thread.sleep(1000);
* System.out.println(context.getCurrentSelfDispersion128());
* System.out.println(context); }
*/
}
} }
@@ -211,7 +211,7 @@ public class KLALBRoutingProtocol extends Thread{
while(true) { while(true) {
try { try {
byte[]ca=MembandBoost.allocateUninitializedArray(65535); byte[]ca=MembandBoost.allocateUninitializedByteArray(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())));
@@ -0,0 +1,50 @@
package org.kne.cloud.network.srv6;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.kne.cloud.network.ipv6.*;
public class SRHInsertNetworkLink extends AbstractIPv6NetworkLink {
private IPv6AddressGroup ipgroup;
public SRHInsertNetworkLink(SRv6Router sRv6Router,IPv6AddressGroup ipgroup) {
super(false);
setSRv6Router(sRv6Router);
this.ipgroup=ipgroup;
}
@Override
public List<IPv6AddressGroup> getAddressGroups() {
return new ArrayList<>();
}
@Override
public List<Neighbor> getNeighborsInfo() {
return new ArrayList<>();
}
@Override
public void sendPacket(IPv6Packet pack, IPv6Address inet6Address) throws IOException {
getSrv6Router().insertSRHeader( pack);
getSrv6Router().insertHeaderAndRoutePacket(null, pack);
}
@Override
public List<RouteItem> getRouteItems() {
return List.of(new RouteItem(ipgroup, null, this, RouteItem.KLALB_SRv6, 30, 0,"G"));
}
@Override
public String getName() {
return "SRHInsertNetworkLink";
}
@Override
public boolean isUp() {
return true;
}
}
+42 -63
View File
@@ -60,7 +60,7 @@ public class SRv6Router {
// public static final int MTU = 16384; // public static final int MTU = 16384;
public static final int MTU = 16384; // 最大传输单元 public static final int MTU = 16384; // 最大传输单元
public static final int MAX_REROUTE_COUNT = 2;// 1 // 最大重路由次数 public static final int MAX_REROUTE_COUNT = 2;// 最大重路由次数
private static final int IPv6_BITS = 128; // IPv6地址位数 private static final int IPv6_BITS = 128; // IPv6地址位数
@@ -104,7 +104,7 @@ public class SRv6Router {
// 环回网络链路 // 环回网络链路
private final LoopbackIPv6NetworkLink inLoopBack; private final LoopbackIPv6NetworkLink inLoopBack;
private final SRHInsertNetworkLink srhInserter;
// 获取路由表 // 获取路由表
public List<RouteItem> getRouteTabel() { public List<RouteItem> getRouteTabel() {
return routeTabel; return routeTabel;
@@ -121,7 +121,7 @@ public class SRv6Router {
@Override @Override
public void accept(IPv6Packet t) { public void accept(IPv6Packet t) {
// HighPerformanceExecutor.defaultExecutor.execute(() -> { // HighPerformanceExecutor.defaultExecutor.execute(() -> {
routePacket(null, t, true); // 执行重路由 routePacket(null, t); // 执行重路由
// }); // });
} }
}; };
@@ -142,21 +142,11 @@ public class SRv6Router {
if (oamtlv == null) if (oamtlv == null)
return true; return true;
boolean bool = unduplicateSet.add(oamtlv.getUUID()); boolean bool = unduplicateSet.add(oamtlv.getUUID());
// System.out.println(bool);
return bool; return bool;
} }
// 默认接收处理器
/*
* private BiConsumer<IPv6NetworkLink,IPv6Packet> defaultReceive = new
* BiConsumer<IPv6NetworkLink,IPv6Packet>() {
*
* @Override public void accept(IPv6NetworkLink link,IPv6Packet t) { //
* HighPerformanceExecutor.defaultExecutor.execute(() -> { if(unduplicate(t)) {
* routePacket(t); // 执行路由 t.putTimePassport("routed"); // 标记路由时间点 } // }); } };
*/
// SRH接收处理器 // 接收处理器
private BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>> srhReceive = new BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>>() { private BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>> receiveConsumer = new BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>>() {
@Override @Override
public void accept(IPv6NetworkLink link, Supplier<IPv6Packet> pack) { public void accept(IPv6NetworkLink link, Supplier<IPv6Packet> pack) {
@@ -255,7 +245,7 @@ public class SRv6Router {
nlink.setSRv6Router(this); nlink.setSRv6Router(this);
nlink.addIPv6LinkStateListener(listener); // 添加链路状态监听器 nlink.addIPv6LinkStateListener(listener); // 添加链路状态监听器
nlink.setReceiveConsumer(srhReceive); // 设置接收处理器 nlink.setReceiveConsumer(receiveConsumer); // 设置接收处理器
if (nlink instanceof ControlledIPv6NetworkLink) { if (nlink instanceof ControlledIPv6NetworkLink) {
((ControlledIPv6NetworkLink) nlink).setRerouteConsumer(defaultReroute); // 设置重路由处理器 ((ControlledIPv6NetworkLink) nlink).setRerouteConsumer(defaultReroute); // 设置重路由处理器
((ControlledIPv6NetworkLink) nlink).setCongressCondition(congressLock, congressCondition); // 设置拥塞条件 ((ControlledIPv6NetworkLink) nlink).setCongressCondition(congressLock, congressCondition); // 设置拥塞条件
@@ -323,9 +313,9 @@ public class SRv6Router {
} }
// 插入SRH并路由数据包 // 插入SRH并路由数据包
public void insertSRHandRoutePacket(IPv6NetworkLink link, IPv6Packet ipp) { public void insertHeaderAndRoutePacket(IPv6NetworkLink link, IPv6Packet ipp) {
insertHopByHopHeader(ipp); insertHopByHopHeader(ipp);//插入逐跳头
insertSRHeader(ipp); // 插入段路由头 //insertSRHeader(ipp); // 插入段路由头
routePacket(link, ipp); // 路由数据包 routePacket(link, ipp); // 路由数据包
} }
@@ -384,16 +374,13 @@ public class SRv6Router {
} }
private void routePacket(IPv6Packet iPv6Packet) { private void routePacket(IPv6Packet iPv6Packet) {
routePacket(null, iPv6Packet, false); routePacket(null, iPv6Packet);
} }
// 路由数据包默认非重路由
private void routePacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet) {
routePacket(linkfrom, iPv6Packet, false);
}
// 路由数据包主方法 // 路由数据包主方法
private void routePacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute) { private void routePacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet) {
StringBuilder dbg = null; StringBuilder dbg = null;
if (debug) { if (debug) {
dbg = new StringBuilder(); // 调试信息 dbg = new StringBuilder(); // 调试信息
@@ -406,7 +393,7 @@ public class SRv6Router {
List<RouteItem> searchResult = getTabelByAddress(dest); List<RouteItem> searchResult = getTabelByAddress(dest);
if (searchResult!=null&&(!searchResult.isEmpty())) { if (searchResult!=null&&(!searchResult.isEmpty())) {
// 匹配到路由表执行负载均衡路由 // 匹配到路由表执行负载均衡路由
routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult); routingLoadBalance(linkfrom, iPv6Packet, dbg, searchResult);
return; return;
} }
@@ -441,7 +428,7 @@ public class SRv6Router {
// 重新搜索路由表 // 重新搜索路由表
List<RouteItem> searchResult2 = getTabelByAddress(dest); List<RouteItem> searchResult2 = getTabelByAddress(dest);
if (searchResult2!=null&&(!searchResult2.isEmpty())) { if (searchResult2!=null&&(!searchResult2.isEmpty())) {
routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult2); routingLoadBalance(linkfrom, iPv6Packet, dbg, searchResult2);
return; return;
} }
@@ -508,7 +495,7 @@ public class SRv6Router {
private Condition congressCondition = congressLock.newCondition(); // 拥塞条件 private Condition congressCondition = congressLock.newCondition(); // 拥塞条件
// 负载均衡路由 // 负载均衡路由
private boolean routingLoadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute, private boolean routingLoadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet,
StringBuilder dbg, List<RouteItem> routes) throws IllegalRawDataException, IOException { StringBuilder dbg, List<RouteItem> routes) throws IllegalRawDataException, IOException {
if(routes==null||routes.isEmpty()) { if(routes==null||routes.isEmpty()) {
@@ -517,7 +504,7 @@ public class SRv6Router {
} }
for (double i = 1; i < 100; i += 0.1) { for (double i = 1; i < 100; i += 0.1) {
if (loadBalance(linkfrom, iPv6Packet, reroute, dbg, routes, i)) { if (loadBalance(linkfrom, iPv6Packet, dbg, routes, i)) {
return true; return true;
} }
@@ -536,7 +523,7 @@ public class SRv6Router {
return false; // 路由失败 return false; // 路由失败
} }
private boolean loadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg, private boolean loadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, StringBuilder dbg,
List<RouteItem> routes, double cscale) List<RouteItem> routes, double cscale)
throws IllegalRawDataException, IOException { throws IllegalRawDataException, IOException {
// 遍历可用路由进行负载均衡 // 遍历可用路由进行负载均衡
@@ -564,31 +551,39 @@ public class SRv6Router {
dbg.append("matched.\n"); dbg.append("matched.\n");
} }
// 找到可用链路处理数据包 // 找到可用链路处理数据包
processPacket(linkfrom, iPv6Packet, tri, reroute); processPacket(linkfrom, iPv6Packet, tri);
return true; return true;
} }
return false; return false;
} }
// 处理数据包转发 // 处理数据包转发
private void processPacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, RouteItem ri, boolean reroute) private void processPacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, RouteItem ri)
throws IllegalRawDataException, IOException { throws IllegalRawDataException, IOException {
int hop = iPv6Packet.getHopLimit(); int hop = iPv6Packet.getHopLimit();
if (ri.getDestlink().isLoopBack()) { // 环回链路处理 if (ri.getDestlink().isLoopBack()) { // 环回链路处理
IPv6HopByHopHeader iPv6HopByHopHeader=iPv6Packet.getHopByHopHeader();
if(iPv6Packet.getRouteCounter().get()<=0) {
if (iPv6HopByHopHeader != null&&linkfrom instanceof KLALBRemoteLink) {
processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(),
((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
}
}
IPv6SegmentRoutingHeader srhh = iPv6Packet.getSegmentRoutingHeader(); IPv6SegmentRoutingHeader srhh = iPv6Packet.getSegmentRoutingHeader();
if (srhh != null) { if (srhh != null) {
processSRv6Packet(linkfrom, iPv6Packet, ri, srhh, iPv6Packet.getHopByHopHeader(), reroute); // SRv6特殊处理 processSRv6Packet(linkfrom, iPv6Packet, ri, srhh); // SRv6特殊处理
} else { } else {
sendPacketToRouteItem(iPv6Packet, ri); sendPacketToRouteItem(iPv6Packet, ri);
} }
} else { // 普通链路处理 } else { // 普通链路处理
// 检查重路由计数 // 检查重路由计数
if (iPv6Packet.getRerouteCounter().getAndIncrement() >= MAX_REROUTE_COUNT) { int count=iPv6Packet.getRouteCounter().getAndIncrement();
if (count >= MAX_REROUTE_COUNT) {
return; // 超过最大重路由次数丢弃 return; // 超过最大重路由次数丢弃
} }
if (!reroute) { if (count<=0) {
hop--; // 减少TTL非重路由时 hop--; // 减少TTL非重路由时
} }
@@ -651,34 +646,16 @@ public class SRv6Router {
// 处理SRv6数据包 // 处理SRv6数据包
private void processSRv6Packet(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, RouteItem ri, private void processSRv6Packet(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, RouteItem ri,
IPv6SegmentRoutingHeader srhh, IPv6HopByHopHeader iPv6HopByHopHeader, boolean reroute) IPv6SegmentRoutingHeader srhh)
throws IllegalRawDataException, IOException { throws IllegalRawDataException, IOException {
if (srhh.getSegmentsLeft() <= 0) { // 所有段已处理完毕 if (srhh.getSegmentsLeft() <= 0) { // 所有段已处理完毕
if (iPv6HopByHopHeader != null) {
int sl = srhh.getSegmentsLeft();
// IPv6Address prevSID
// =sl+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(sl+1);
if (linkfrom instanceof KLALBRemoteLink) {
processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(),
((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
}
}
// System.out.println(iPv6HopByHopHeader);
sendPacketToRouteItem(iPv6Packet, ri); sendPacketToRouteItem(iPv6Packet, ri);
} else { } else {
if (reroute) { if (iPv6Packet.getRouteCounter().get()<=0) {
// 重路由处理 // 重路由处理
} else {
int oldSL = srhh.getSegmentsLeft(); int oldSL = srhh.getSegmentsLeft();
if (iPv6HopByHopHeader != null) {
// IPv6Address prevSID
// =oldSL+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(oldSL+1);
if (linkfrom instanceof KLALBRemoteLink) {
processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(),
((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
}
}
// 正常SRv6处理移动到下一个段 // 正常SRv6处理移动到下一个段
int newSL = oldSL - 1; int newSL = oldSL - 1;
srhh.setSegmentsLeft(newSL); // 更新剩余段数 srhh.setSegmentsLeft(newSL); // 更新剩余段数
@@ -687,7 +664,7 @@ public class SRv6Router {
// 记录热点地址用于流量工程 // 记录热点地址用于流量工程
if (iPv6Packet.getPayload().getProtocolNumber() != KLALBRoutingProtocol.DEFAULT_PROTOCOL_NUMBER) if (iPv6Packet.getPayload().getProtocolNumber() != KLALBRoutingProtocol.DEFAULT_PROTOCOL_NUMBER)
klalbRouteProtol.putHotspotAddress(iPv6Packet.getSourceAddress()); klalbRouteProtol.putHotspotAddress(iPv6Packet.getSourceAddress());
routePacket(linkfrom, iPv6Packet, reroute); // 继续路由 routePacket(linkfrom, iPv6Packet); // 继续路由
} }
} }
@@ -814,7 +791,7 @@ public class SRv6Router {
if(ecn) { if(ecn) {
packet.markCE(); packet.markCE();
} }
insertSRHandRoutePacket(null, packet); // 插入SRH并路由 insertHeaderAndRoutePacket(null, packet); // 插入SRH并路由
long time=System.nanoTime()-start; long time=System.nanoTime()-start;
backplaneCount(time,ecn); backplaneCount(time,ecn);
} catch (Exception e) { } catch (Exception e) {
@@ -827,7 +804,7 @@ public class SRv6Router {
public void onReceive(IPv6NetworkLink link,IPv6Packet t){ public void onReceive(IPv6NetworkLink link,IPv6Packet t){
if (unduplicate(t)) { if (unduplicate(t)) {
insertSRHandRoutePacket(link, t); // 插入SRH并路由数据包 insertHeaderAndRoutePacket(link, t); // 插入SRH并路由数据包
} }
} }
@@ -916,15 +893,17 @@ public class SRv6Router {
} }
// 构造函数 // 构造函数
public SRv6Router(IPv6AddressGroup hostAddress, HighAccuracyClock clock) { public SRv6Router(IPv6AddressGroup endSID,IPv6AddressGroup networkGroup, HighAccuracyClock clock) {
super(); super();
this.locator = hostAddress; this.locator = endSID;
this.clock = clock; this.clock = clock;
// initWorkerThreads(); // initWorkerThreads();
// 创建环回链路 // 创建环回链路
this.inLoopBack = new LoopbackIPv6NetworkLink( this.inLoopBack = new LoopbackIPv6NetworkLink(
List.of(new IPv6AddressGroup(IPv6Address.LOOPBACK, 128), hostAddress), this); List.of(new IPv6AddressGroup(IPv6Address.LOOPBACK, 128), endSID), this);
linkTabel.add(inLoopBack); // 添加到链路表 linkTabel.add(inLoopBack); // 添加到链路表
this.srhInserter=new SRHInsertNetworkLink(this,networkGroup);
linkTabel.add(srhInserter);
backplaneTimer.scheduleAtFixedRate(new TimerTask() { backplaneTimer.scheduleAtFixedRate(new TimerTask() {
@Override @Override
Binary file not shown.