feat(srv6)!: replace openlines query with tiny/full node-info API

- routing-protocol JSON API: nodeinfotinyreq/resp returns device name
  only and is never gated; nodeinfofullreq/resp returns external
  endpoints + device name + description, where denyExternalEndpointQuery
  hides only the endpoint list (name/description always answer);
  legacy openlines* wire types removed - upgrade the whole mesh together
- rename misnamed openConnections -> externalEndpoints and
  denyConnection{Query,Broadcast} -> denyExternalEndpoint{Query,Broadcast};
  legacy config keys normalized on load because gson-2.1 lacks
  @SerializedName(alternate=...)
- remove TCP-based KLALBRemoteManagement, superseded by the HTTP API
- dashboard settings follow the renamed keys; update AGENTS.md
This commit is contained in:
2026-08-26 00:23:21 +08:00
parent 9cea74943c
commit e0296e0ccd
16 changed files with 265 additions and 322 deletions
@@ -0,0 +1,52 @@
package org.kne.cloud.network.srv6;
import java.util.List;
import org.kne.cloud.network.MultiProtocolSocketAddress;
/**
* 节点信息(开放线路 + 设备名称 + 设备描述),由路由协议 JSON API 查询获得。
*/
public class KLALBNodeInformation {
private List<MultiProtocolSocketAddress> openLines;
private String deviceName;
private String deviceDescription;
public KLALBNodeInformation(List<MultiProtocolSocketAddress> openLines, String deviceName,
String deviceDescription) {
super();
this.openLines = openLines;
this.deviceName = deviceName;
this.deviceDescription = deviceDescription;
}
public List<MultiProtocolSocketAddress> getOpenLines() {
return openLines;
}
public void setOpenLines(List<MultiProtocolSocketAddress> openLines) {
this.openLines = openLines;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getDeviceDescription() {
return deviceDescription;
}
public void setDeviceDescription(String deviceDescription) {
this.deviceDescription = deviceDescription;
}
@Override
public String toString() {
return "KLALBNodeInformation [openLines=" + openLines + ", deviceName=" + deviceName
+ ", deviceDescription=" + deviceDescription + "]";
}
}
@@ -29,20 +29,27 @@ public class KLALBRoutingProtocolAPIClient {
JsonDataPacket relate = null;
//System.out.println(ruid + " " + window.getSendmap());
switch (dataobj.getType()) {
case KLALBRoutingProtocolJsonData.OPEN_LINES_RESP:
case KLALBRoutingProtocolJsonData.NODE_INFO_FULL_RESP:
case KLALBRoutingProtocolJsonData.NODE_INFO_TINY_RESP:
if ((relate = window.ack(ruid)) != null) {
List<?> connects = (List<?>) dataobj.getData();
List<MultiProtocolSocketAddress> connectsm = new ArrayList<MultiProtocolSocketAddress>(connects.size());
for (Object open : connects) {
if (open instanceof MultiProtocolSocketAddress) {
connectsm.add((MultiProtocolSocketAddress) open);
} else {
connectsm.add(new MultiProtocolSocketAddress((String) open));
List<MultiProtocolSocketAddress> connectsm = new ArrayList<MultiProtocolSocketAddress>(
connects == null ? 0 : connects.size());
if (connects != null) {
for (Object open : connects) {
if (open instanceof MultiProtocolSocketAddress) {
connectsm.add((MultiProtocolSocketAddress) open);
} else {
connectsm.add(new MultiProtocolSocketAddress((String) open));
}
}
}
((Consumer<List<MultiProtocolSocketAddress>>) relate.getUserCallback()).accept(connectsm);
// 组装节点信息(线路 + 设备名称 + 设备描述,精简模式下线路与描述为 null)
KLALBNodeInformation info = new KLALBNodeInformation(connectsm, dataobj.getDeviceName(),
dataobj.getDeviceDescription());
((Consumer<KLALBNodeInformation>) relate.getUserCallback()).accept(info);
}
break;
}
@@ -56,11 +63,26 @@ public class KLALBRoutingProtocolAPIClient {
clr.register(this, releaser);
}
public void requestOpenLines(SocketAddress addr, Consumer<List<MultiProtocolSocketAddress>> callback)
/**
* 精简查询:仅获取对端设备名称(开销最小,适用于未查看节点详情的场景)。
*/
public void requestNodeInfoTiny(SocketAddress addr, Consumer<KLALBNodeInformation> callback)
throws IOException {
sendNodeInfoRequest(KLALBRoutingProtocolJsonData.NODE_INFO_TINY_REQ, addr, callback);
}
/**
* 完整查询:获取对端开放线路 + 设备名称 + 设备描述(查看节点信息时使用)。
*/
public void requestNodeInfoFull(SocketAddress addr, Consumer<KLALBNodeInformation> callback)
throws IOException {
sendNodeInfoRequest(KLALBRoutingProtocolJsonData.NODE_INFO_FULL_REQ, addr, callback);
}
private void sendNodeInfoRequest(String type, SocketAddress addr, Consumer<KLALBNodeInformation> callback)
throws IOException {
UUID suid = UUID.randomUUID();
KLALBRoutingProtocolJsonData json = new KLALBRoutingProtocolJsonData(
KLALBRoutingProtocolJsonData.OPEN_LINES_REQ, suid, null);
KLALBRoutingProtocolJsonData json = new KLALBRoutingProtocolJsonData(type, suid, null);
JsonDataPacket packet = new JsonDataPacket(json);
packet.setUserCallback(callback);
window.put(suid, packet);
@@ -21,11 +21,21 @@ public class KLALBRoutingProtocolAPIServer {
KLALBRoutingProtocolJsonData dataobj= data.getDecodedData();
InetSocketAddress addrs=(InetSocketAddress) addr;
switch(dataobj.getType()){
case KLALBRoutingProtocolJsonData.OPEN_LINES_REQ:
if(controller.getConfigItem()==null||(!controller.getConfigItem().isDenyConnectionQuery())) {
KLALBRoutingProtocolJsonData json=new KLALBRoutingProtocolJsonData(KLALBRoutingProtocolJsonData.OPEN_LINES_RESP,dataobj.getUuid(),controller.getSelflineTable());
routingProtocol.sendJsonPacketToAddress(new JsonDataPacket(json),addr);
case KLALBRoutingProtocolJsonData.NODE_INFO_TINY_REQ:
// 精简查询:仅返回设备名称(设备名称随路由信息广播公开,不受 denyExternalEndpointQuery 限制)
KLALBRoutingProtocolJsonData tinyjson=new KLALBRoutingProtocolJsonData(KLALBRoutingProtocolJsonData.NODE_INFO_TINY_RESP,dataobj.getUuid(),null);
tinyjson.setDeviceName(controller.getIpv6Router().getDeviceName());
routingProtocol.sendJsonPacketToAddress(new JsonDataPacket(tinyjson),addr);
break;
case KLALBRoutingProtocolJsonData.NODE_INFO_FULL_REQ:
// 完整查询:设备名称与描述总是正常响应;denyExternalEndpointQuery 仅隐藏外部端点列表
boolean denyEndpoints=controller.getConfigItem()!=null&&controller.getConfigItem().isDenyExternalEndpointQuery();
KLALBRoutingProtocolJsonData json=new KLALBRoutingProtocolJsonData(KLALBRoutingProtocolJsonData.NODE_INFO_FULL_RESP,dataobj.getUuid(),denyEndpoints?null:controller.getExternalEndpoints());
json.setDeviceName(controller.getIpv6Router().getDeviceName());// 附带本机设备名称
if(controller.getConfigItem()!=null) {
json.setDeviceDescription(controller.getConfigItem().getDeviceDescription());// 附带本机设备描述
}
routingProtocol.sendJsonPacketToAddress(new JsonDataPacket(json),addr);
break;
}
} catch (IOException e) {
@@ -3,11 +3,27 @@ package org.kne.cloud.network.srv6;
import java.util.UUID;
public class KLALBRoutingProtocolJsonData {
public static final String OPEN_LINES_REQ="openlinesreq";
public static final String OPEN_LINES_RESP="openlinesresp";
public static final String NODE_INFO_TINY_REQ="nodeinfotinyreq";// 精简查询:仅设备名称
public static final String NODE_INFO_TINY_RESP="nodeinfotinyresp";
public static final String NODE_INFO_FULL_REQ="nodeinfofullreq";// 完整查询:开放线路+设备名称+设备描述
public static final String NODE_INFO_FULL_RESP="nodeinfofullresp";
private String type;
private UUID uuid;
private Object data;
private String deviceName;// 对端设备名称
private String deviceDescription;// 对端设备描述
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getDeviceDescription() {
return deviceDescription;
}
public void setDeviceDescription(String deviceDescription) {
this.deviceDescription = deviceDescription;
}
public String getType() {
return type;
}
@@ -24,6 +40,8 @@ public class KLALBRoutingProtocolJsonData {
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
result = prime * result + ((deviceName == null) ? 0 : deviceName.hashCode());
result = prime * result + ((deviceDescription == null) ? 0 : deviceDescription.hashCode());
return result;
}
@Override
@@ -50,6 +68,16 @@ public class KLALBRoutingProtocolJsonData {
return false;
} else if (!uuid.equals(other.uuid))
return false;
if (deviceName == null) {
if (other.deviceName != null)
return false;
} else if (!deviceName.equals(other.deviceName))
return false;
if (deviceDescription == null) {
if (other.deviceDescription != null)
return false;
} else if (!deviceDescription.equals(other.deviceDescription))
return false;
return true;
}
public KLALBRoutingProtocolJsonData(String type, UUID uuid, Object data) {
@@ -60,7 +88,8 @@ public class KLALBRoutingProtocolJsonData {
}
@Override
public String toString() {
return "KLALBRoutingProtocolJsonData [type=" + type + ", uuid=" + uuid + ", data=" + data + "]";
return "KLALBRoutingProtocolJsonData [type=" + type + ", uuid=" + uuid + ", data=" + data + ", deviceName="
+ deviceName + ", deviceDescription=" + deviceDescription + "]";
}
}