Files
KLALB/src/org/kne/cloud/network/klalb/KLALBController.java
T
2026-07-07 00:22:32 +08:00

1039 lines
33 KiB
Java

package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.BindException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.DatagramChannel;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import org.kne.cloud.clock.HighAccuracyClock;
import org.kne.cloud.network.IPMulticastDiscovery;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.PortPair;
import org.kne.cloud.network.SocketType;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.ipv6.IPv6Address;
import org.kne.cloud.network.ipv6.IPv6AddressGroup;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink;
import org.kne.cloud.network.ipv6.Neighbor;
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.SpeedAndTrafficMonitorDataImpl;
import org.kne.cloud.network.ntp.NTPContext;
import org.kne.cloud.network.ntp.NTPv4Packet;
import org.kne.cloud.network.ntp.NTPv4Protocol;
import org.kne.cloud.network.ntp.NTPv4Protocol.NTPPeer;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
import org.kne.cloud.network.srv6.KLALBRoutingProtocolAPIClient;
import org.kne.cloud.network.srv6.KLALBRoutingProtocolAPIServer;
import org.kne.cloud.network.srv6.SRv6Router;
import org.kne.cloud.network.srv6.SRv6RouterListener;
import org.kne.cloud.network.tcp.UDPPacket;
import org.kne.cloud.network.tcp.UDPProtocolRegister;
import org.kne.cloud.network.te.BandwidthDistributer;
public class KLALBController {
private UUID nodeuuid=UUID.randomUUID();
private HighAccuracyClock clock = new HighAccuracyClock();
public HighAccuracyClock getClock() {
return clock;
}
private final long TIME_WINDOW=5000000000L;
private SpeedAndTrafficMonitorDataImpl linkMonitor = new SpeedAndTrafficMonitorDataImpl(
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "up", 100,TIME_WINDOW ),
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, TIME_WINDOW));
private SpeedAndTrafficMonitorDataImpl datatMonitor = new SpeedAndTrafficMonitorDataImpl(
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "up", 100, TIME_WINDOW),
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, TIME_WINDOW));
private List<MultipurposeSocketAddress> selflineTable = new ArrayList<>();
private static final boolean debug=false;
private static final boolean showpacket = false;
private static final int PREFIX = 128;// 112
private static final int DISCOVERY_PORT = 4569;
private static List<IPMulticastDiscovery> ipmd = new ArrayList<>();
private List<NetworkInterface> networkInterfaceExcept = new ArrayList<>();
public List<NetworkInterface> getNetworkInterfaceExcept() {
return networkInterfaceExcept;
}
private List<InetAddress> dnsAddresses = new ArrayList<>();
public List<InetAddress> getDnsAddresses() {
return dnsAddresses;
}
private ScheduledExecutorService scheduleTimer=Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(),new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return ThreadTool.makeVDaemonThreadIfSupport("计时器线程", r);
}
});
public ScheduledExecutorService getScheduleTimer() {
return scheduleTimer;
}
private Timer twk = new Timer("网卡检测扫描计时器", true);
private List<InetAddress> getAllNetworkInterfaceAddress() throws SocketException {
List<InetAddress> addresses = new ArrayList<InetAddress>();
Enumeration<NetworkInterface> eu = NetworkInterface.getNetworkInterfaces();
while (eu.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
if (networkInterface.getDisplayName()
.startsWith(CONST.KLALB_DECENTRALIZED_S_RV6_NETWORK)) {
continue;
}
if (networkInterfaceExcept.contains(networkInterface)) {
continue;
}
if (networkInterface.isUp()) {
// System.out.println(networkInterface+" "+networkInterface.isUp());
Enumeration<InetAddress> ei = networkInterface.getInetAddresses();
while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement();
if (checkIsSelfLocator(inetAddress)) {
continue;
}
addresses.add(inetAddress);
}
}
}
return addresses;
}
private TimerTask tsk1 = new TimerTask() {
@Override
public void run() {
try {
List<InetAddress> localaddress = getAllNetworkInterfaceAddress();
for (InetAddress inetAddress : localaddress) {
if (!inetAddress.isLoopbackAddress())
for (Iterator<MultipurposeSocketAddress> iterator = listens.iterator(); iterator.hasNext();) {
MultipurposeSocketAddress tcpl = (MultipurposeSocketAddress) iterator.next();
try {
if (tcpl.getInetAddress().isAnyLocalAddress()
|| tcpl.getInetAddress().equals(inetAddress)) {
MultipurposeSocketAddress bind = new MultipurposeSocketAddress(tcpl.getType(),
inetAddress.getHostAddress(), tcpl.getPort());
// System.out.println(bind);
synchronized (selflineTable) {
if (!selflineTable.contains(bind)) {
selflineTable.add(bind);
}
}
}
} catch (UnknownHostException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
lineslock.writeLock().lock();
try {
Set<MultipurposeSocketAddress> st = new HashSet<>();
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link = iterator.next();
if (link instanceof KLALBRemoteLink) {
KLALBRemoteLink multipurposeSocketAddress = (KLALBRemoteLink) link;
if (multipurposeSocketAddress.getSocketAddress() != null)
st.add(multipurposeSocketAddress.getSocketAddress());
}
}
for (Iterator<MultipurposeSocketAddress> iterator = st.iterator(); iterator.hasNext();) {
MultipurposeSocketAddress target = (MultipurposeSocketAddress) iterator.next();
addRemoteLines(target);
}
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link = iterator.next();
if (link instanceof KLALBRemoteLink) {
KLALBRemoteLink reml = (KLALBRemoteLink) link;
if (reml.getSocketAddress() != null) {
if (reml.getBindAddress() != null || reml.getRemoteVaddr() != null)
try {
MultipurposeSocketAddress iadr=reml.getBindAddress();
if(iadr!=null) {
if (!localaddress.contains(iadr.getInetAddress())) {
reml.close();
srv6Router.getLinkTabel().remove(reml);
}
}else {
reml.close();
}
} catch (UnknownHostException e) {
reml.close();
srv6Router.getLinkTabel().remove(reml);
e.printStackTrace();
}
}
}
}
} finally {
lineslock.writeLock().unlock();
}
updateBroadcastNetworkInterface();
} catch (SocketException e) {
}catch (Exception e) {
e.printStackTrace();
}
}
private void updateBroadcastNetworkInterface() throws SocketException {
for (Iterator<IPMulticastDiscovery> iterator = ipmd.iterator(); iterator.hasNext();) {
IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next();
if (ipMulticastDiscovery.isClosed() || (!ipMulticastDiscovery.getNinterface().isUp())
|| (configItem != null && configItem.isDenyLineTableBroadcast())) {
iterator.remove();
try {
ipMulticastDiscovery.close();
} catch (IOException e) {
e.printStackTrace();
}
if(debug)
System.out.println("关闭网卡地址广播:" + ipMulticastDiscovery.getNinterface());
}
}
if (configItem != null && configItem.isDenyLineTableBroadcast()) {
} else {
Enumeration<NetworkInterface> eu2 = NetworkInterface.getNetworkInterfaces();
while (eu2.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) eu2.nextElement();
if (networkInterface.getDisplayName()
.startsWith(CONST.KLALB_DECENTRALIZED_S_RV6_NETWORK)) {
continue;
}
if (networkInterfaceExcept.contains(networkInterface)) {
continue;
}
if (networkInterface.isUp()) {
Enumeration<InetAddress> ei = networkInterface.getInetAddresses();
loop: while (ei.hasMoreElements()) {
InetAddress bidr = (InetAddress) ei.nextElement();
if (checkIsSelfLocator(bidr)) {
continue;
}
for (Iterator<IPMulticastDiscovery> iterator = ipmd.iterator(); iterator.hasNext();) {
IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next();
if (networkInterface.equals(ipMulticastDiscovery.getNinterface())
&& bidr.equals(ipMulticastDiscovery.getBind().getAddress())) {
continue loop;
}
}
try {
// InetAddress bidr=InetAddress.getByName("::0");
if (bidr instanceof Inet6Address) {
IPMulticastDiscovery ipd = new IPMulticastDiscovery(
new InetSocketAddress(bidr, DISCOVERY_PORT),
new InetSocketAddress(InetAddress.getByName("ff02::2486"),
DISCOVERY_PORT),
networkInterface, selflineTable, nodeuuid,10000L);
ipd.setCon((mpa) -> {
// System.out.println("添加本地IPv6链路:"+mpa);
try {
if (!checkIsSelf(mpa))
addRemoteLines(mpa);
} catch (UnknownHostException e) {
}
});
ipd.start();
ipmd.add(ipd);
} else if (bidr instanceof Inet4Address) {
// bidr=InetAddress.getByName("0.0.0.0");
IPMulticastDiscovery ipd2 = new IPMulticastDiscovery(
new InetSocketAddress(bidr, DISCOVERY_PORT),
new InetSocketAddress(InetAddress.getByName("224.0.0.86"),
DISCOVERY_PORT),
networkInterface, selflineTable,nodeuuid, 10000L);
ipd2.setCon((mpa) -> {
// System.out.println("添加本地IPv4链路:"+mpa);
try {
if (!checkIsSelf(mpa))
addRemoteLines(mpa);
} catch (UnknownHostException e) {
}
});
ipd2.start();
ipmd.add(ipd2);
}
if(debug)
System.out.println("开启网卡地址广播:" + networkInterface);
} catch (BindException e) {
// e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// }
}
}
}
}
};
private boolean checkIsSelf(MultipurposeSocketAddress inetAddress) throws UnknownHostException {
return inetAddress.getInetAddress().isAnyLocalAddress() || inetAddress.getInetAddress().isLoopbackAddress()
|| selflineTable.contains(inetAddress);
}
private boolean checkIsSelfLocator(InetAddress inetAddress) {
return srv6Router.getLocator().getAddress().toInet6Address().equals(inetAddress);
}
private TimerTask tsk2 = new TimerTask() {
@Override
public void run() {
List<MultipurposeSocketAddress> nt = ntptable;
// System.out.println("srv6 ip"+nb);
if (nvc2 != null) {
Set<NTPPeer> sp = nvc2.getPeers();
for (MultipurposeSocketAddress server : nt) {
sp.add(new NTPPeer(server, NTPv4Packet.NTP_CLIENT));
}
sp.removeIf((p) -> {
for (MultipurposeSocketAddress server : nt) {
if (server.equals(p.getAddress())) {
return false;
}
}
return true;
});
}
}
};
private TimerTask tsk3 = new TimerTask() {
@Override
public void run() {
if (srv6Router != null && routingProtocol != null) {
Set<IPv6AddressGroup> nb = srv6Router.getLocators();
for (Iterator<IPv6AddressGroup> iterator = nb.iterator(); iterator.hasNext();) {
IPv6AddressGroup neighbor = (IPv6AddressGroup) iterator.next();
try {
InetSocketAddress iaddr = new InetSocketAddress(neighbor.getAddress().toInet6Address(),
KLALBRoutingProtocol.DEFAULT_PORT);
apiClient.requestOpenLines(iaddr, (v) -> {
ThreadTool.makeVDaemonThreadIfSupport("线路添加任务", () -> {
for (MultipurposeSocketAddress msa : v) {
// System.out.print(msa);
addRemoteLines(msa);
}
}).start();
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
public SpeedAndTrafficMonitorDataImpl getLinkMonitor() {
return linkMonitor;
}
public SpeedAndTrafficMonitorDataImpl getDatatMonitor() {
return datatMonitor;
}
private SocketType streamSocketType = new KLALBStreamSocketType();
public class KLALBStreamSocketType extends SocketType {
public KLALBStreamSocketType() {
super(new KLALBVirtualSocketFactory(KLALBController.this),
new KLALBVirtualServerSocketFactory(KLALBController.this),
new KLALBVirtualSocketChannelFactory(KLALBController.this),
new KLALBVirtualServerSocketChannelFactory(KLALBController.this));
}
}
public SocketType getStreamSocketType() {
return streamSocketType;
}
private SocketType datagramSocketType = new KLALBDatagramSocketType();
public class KLALBDatagramSocketType extends SocketType {
public KLALBDatagramSocketType() {
super(new KLALBVirtualDatagramSocketFactory(KLALBController.this),
new KLALBVirtualDatagramServerSocketFactory(KLALBController.this));
// new KLALBVirtualDatagramSocketChannelFactory(KLALBController.this),
// new KLALBVirtualDatagramServerSocketChannelFactory(KLALBController.this));
}
}
public SocketType getDatagramSocketType() {
return datagramSocketType;
}
public List<MultipurposeSocketAddress> getSelflineTable() {
return selflineTable;
}
public IPv6AddressGroup getSelf() {
return srv6Router.getLocator();
}
private ReadWriteLock lineslock = new ReentrantReadWriteLock();
public List<IPv6NetworkLink> getLines() {
return srv6Router.getLinkTabel();
}
public void reconnectImmediately() {
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink val = iterator.next();
if (val instanceof KLALBRemoteLink) {
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) val;
klalbRemoteLine.reconnectImmediately();
}
}
}
private NTPv4Protocol nvc2;
private KLALBRoutingProtocolAPIServer apiServer;
private KLALBRoutingProtocolAPIClient apiClient;
private KLALBControllerConfigItem configItem;
public void addRemoteLines(List<MultipurposeSocketAddress> select) {
for (MultipurposeSocketAddress target : select) {
addRemoteLines(target);
}
}
public List<KLALBRemoteLink> addRemoteLines(MultipurposeSocketAddress target) {
lineslock.writeLock().lock();
try {
List<KLALBRemoteLink> added = new ArrayList<>();
try {
Enumeration<NetworkInterface> eu = NetworkInterface.getNetworkInterfaces();
while (eu.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
if (networkInterface.isUp()) {
// System.out.println(networkInterface+" "+networkInterface.isUp());
Enumeration<InetAddress> ei = networkInterface.getInetAddresses();
while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement();
try {
MultipurposeSocketAddress bind = new MultipurposeSocketAddress(
inetAddress.getHostAddress(), 0);
try {
if (target.getInetAddress().isLoopbackAddress()
&& (!bind.getInetAddress().isLoopbackAddress())) {
continue;
}
if ((!target.getInetAddress().isLoopbackAddress())
&& bind.getInetAddress().isLoopbackAddress()) {
continue;
}
if (target.getInetAddress() instanceof Inet4Address
&& bind.getInetAddress() instanceof Inet6Address) {
continue;
}
if (target.getInetAddress() instanceof Inet6Address
&& bind.getInetAddress() instanceof Inet4Address) {
continue;
}
// System.out.println(target+"->"+bind);
} catch (UnknownHostException e) {
if (e.getMessage().trim().toLowerCase().contains("no scope_id found")) {
throw e;
}
// e.printStackTrace();
}
if (!checkContainsTargetAndBind(target, bind)) {
int count=1;
if(configItem!=null) {
count=configItem.getLinkConnectionsCount();
}
if(count<=0) {
count=1;
}
for(int i=0;i<count;i++) {
KLALBRemoteLink line = new KLALBRemoteLink(this, target, bind);
addRemoteLine(line);
added.add(line);
}
}
} catch (UnknownHostException e) {
}
}
}
}
} catch (SocketException e) {
if (!checkContainsTarget(target)) {
KLALBRemoteLink line = new KLALBRemoteLink(this, target);
addRemoteLine(line);
added.add(line);
}
// throw e;
}
return added;
} finally {
lineslock.writeLock().unlock();
}
}
public List<KLALBRemoteLink> removeRemoteLines(MultipurposeSocketAddress mpsa) {
List<KLALBRemoteLink> rmved = new ArrayList<>();
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link = iterator.next();
if (link instanceof KLALBRemoteLink) {
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
if (mpsa.equals(klalbRemoteLine.getSocketAddress())) {
klalbRemoteLine.close();
rmved.add(klalbRemoteLine);
}
}
}
return rmved;
}
public Inet6Address getRemoteVaddrBySocketAddress(MultipurposeSocketAddress target) throws SocketTimeoutException {
KLALBRemoteLink kr = null;
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link = iterator.next();
if (link instanceof KLALBRemoteLink) {
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
if (target.equals(klalbRemoteLine.getSocketAddress()) && klalbRemoteLine.getBindAddress() == null) {
kr = klalbRemoteLine;
break;
}
}
}
if (kr == null) {
kr = new KLALBRemoteLink(this, target);
addRemoteLine(kr);
kr.waitForRemoteVaddrAvaliable(20000);
} else {
kr.reconnectImmediately();
kr.waitForRemoteVaddrAvaliable(20000);
}
return kr.getRemoteVaddr().getAddress().toInet6Address();
}
private boolean checkContainsTargetAndBind(MultipurposeSocketAddress target, MultipurposeSocketAddress bind) {
boolean b = false;
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link = iterator.next();
if (link instanceof KLALBRemoteLink) {
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
if (bind.equals2(klalbRemoteLine.getBindAddress())
&& target.equals2(klalbRemoteLine.getSocketAddress())) {
b = true;
break;
}
}
}
return b;
}
private boolean checkContainsTarget(MultipurposeSocketAddress target) {
boolean b = false;
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link = iterator.next();
if (link instanceof KLALBRemoteLink) {
KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
if (target.equals(klalbRemoteLine.getSocketAddress())) {
b = true;
break;
}
}
}
return b;
}
public void addRemoteLine(KLALBRemoteLink krs) {
lineslock.writeLock().lock();
try {
krs.startIO();
String selflineTable = generateSelfLineTable();
if (selflineTable != null && !selflineTable.equals(""))
krs.sendPacket(new ADDLINESPacket(selflineTable));
srv6Router.getLinkTabel().add(krs);
} finally {
lineslock.writeLock().unlock();
}
}
private String generateSelfLineTable() {
StringBuilder sbd = new StringBuilder();
for (Iterator<MultipurposeSocketAddress> iterator = selflineTable.iterator(); iterator.hasNext();) {
MultipurposeSocketAddress klalbRemoteLine = (MultipurposeSocketAddress) iterator.next();
sbd.append(klalbRemoteLine.toString());
sbd.append('\n');
}
return sbd.toString();
}
private UDPProtocolRegister udpr;
public UDPProtocolRegister getUDPregister() {
return udpr;
}
private KLTPProtocolRegister kltpr;
public KLTPProtocolRegister getKLTPregister() {
return kltpr;
}
private PortBinder rawPortBinder ;
protected PortBinder getRawPortBinder() {
return rawPortBinder;
}
private void loadSRv6ProtocolStack(IPv6AddressGroup selfx, boolean enableVirtualAdapter) {
srv6Router = new SRv6Router(selfx, clock);
srv6Router.runKLALBRouteProtocol();
routingProtocol = srv6Router.getKlalbRouteProtol();
routingProtocol.addReceiver((addr, packet) -> {
});
rawPortBinder= new PortBinder(this.getSelf().getAddress());
System.out.println(" Loaded: SRv6 Stack");
String name=(configItem!=null)?configItem.getTUNName():CONST.KLALB_S_RV6;
if (enableVirtualAdapter&&(name!=null)) {
Thread t=new Thread(()->{
try {
IPv6TUNLoopbackNetworkLink tunlink = new IPv6TUNLoopbackNetworkLink(name,
new IPv6AddressGroup(srv6Router.getLocator().getAddress(), 32), SRv6Router.MTU, dnsAddresses);
tunlink.setMonitor(datatMonitor);
// srv6Router.getLinkTabel().add(tunlink);
srv6Router.getinLoopback().setFallbackLink(tunlink);
System.out.println(" Mounted: Tun Adapter");
} catch (Exception e) {
System.err.println("挂载虚拟网卡失败,可能是无管理员权限?请尝试使用管理员权限运行软件");
e.printStackTrace();
}
});
t.start();
}else {
System.out.println(" Tun Adapter Disbaled");
}
udpr=new UDPProtocolRegister(this);
srv6Router.getinLoopback().getProtocolNumberRegister()[UDPPacket.UDP_PROTOCOL_NUMBER]=
udpr;
System.out.println(" Loaded: UDP Protocol");
kltpr=new KLTPProtocolRegister(this);
srv6Router.getinLoopback().getProtocolNumberRegister()[KLTPPacket.KLTP_PROTOCOL_NUMBER]=
kltpr;
System.out.println(" Loaded: KLTP Protocol");
String iproxyname = "KLALB_" + UUID.randomUUID();
registerToProxyTypeAs(iproxyname);
System.out.println(" Loaded: KLALB Protocol");
NTPContext context = new NTPContext(clock);
context.syncToSystem();
// System.out.println(context);
try {
NTPv4Protocol nvc = new NTPv4Protocol(context,
new MultipurposeSocketAddress("{" + iproxyname + "_Datagram}0.0.0.0:123"));
srv6Router.addSRv6RouterListener(new SRv6RouterListener() {
@Override
public void onLinkChanged(SRv6Router router, IPv6NetworkLink link) {
List<Neighbor> nb = router.getNeighbors();
Set<NTPPeer> sp = nvc.getPeers();
for (Neighbor neighbor : nb) {
if (neighbor.getLocator() != null)
sp.add(new NTPPeer(
new MultipurposeSocketAddress(iproxyname + "_Datagram",
neighbor.getLocator().getAddress().toString(), 123),
NTPv4Packet.NTP_SYMMETRIC_ACTIVE));
}
sp.removeIf((p) -> {
for (Neighbor neighbor : nb) {
try {
if (neighbor.getLocator() != null)
if (neighbor.getLocator().getAddress().toInet6Address()
.equals(p.getAddress().getInetAddress())) {
return false;
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
return true;
});
}
});
nvc2 = new NTPv4Protocol(context, new MultipurposeSocketAddress("{UDP}0.0.0.0:0"));// 106.55.184.199
System.out.println(" Loaded: NTP Module");
} catch (UnknownHostException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} // 106.55.184.199
}
private void loadController() {
this.apiServer = new KLALBRoutingProtocolAPIServer(routingProtocol, this);
this.apiClient = new KLALBRoutingProtocolAPIClient(routingProtocol);
twk.schedule(tsk1, 5000, 5000);
twk.schedule(tsk2, 5000, 5000);
twk.schedule(tsk3, 5000, 5000);
}
public KLALBController() {
this(true, null);
}
public KLALBController(Inet6Address self) {
this(self, true, null);
}
public KLALBController(Inet6Address self, boolean enableVirtualAdapter, List<InetAddress> dnsaddr) {
this.dnsAddresses = dnsaddr;
IPv6AddressGroup selfg = new IPv6AddressGroup(IPv6Address.valueOf(self), PREFIX);
initKLALB(enableVirtualAdapter, 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);
loadController();
}
public KLALBController(boolean enableVirtualAdapter, List<InetAddress> dnsaddr) {
this.dnsAddresses = dnsaddr;
IPv6AddressGroup selfx = new IPv6AddressGroup(KLALBUtils.randomKLALBIPv6Address(), PREFIX);
initKLALB(enableVirtualAdapter, selfx);
}
public KLALBController(KLALBControllerConfigItem configItem) {
this.configItem = configItem;
String vase = configItem.getVirtualAddress();
this.dnsAddresses = new ArrayList<InetAddress>();
List<InetAddress> vdns = configItem.getDNS();
if (vdns != null) {
dnsAddresses.addAll(vdns);
}
IPv6AddressGroup selfx = null;
if (vase != null) {
try {
selfx = new IPv6AddressGroup(IPv6Address.valueOf(vase), PREFIX);
} catch (UnknownHostException e) {
e.printStackTrace();
}
} else {
selfx = new IPv6AddressGroup(KLALBUtils.randomKLALBIPv6Address(), PREFIX);
}
initKLALB(true, selfx);
Long vasn = configItem.getVirtualASN();
if (vasn != null) {
getIpv6Router().setASN(vasn);
}
List<MultipurposeSocketAddress> linele = configItem.getLineTable();
if (linele != null) {
getSelflineTable().addAll(linele);
}
List<MultipurposeSocketAddress> linetoc = configItem.getConnectLineTable();
if (linetoc != null) {
linetoc.forEach((aline) -> {
addRemoteLines(aline);
});
}
List<MultipurposeSocketAddress> ntps = configItem.getNtpServerTable();
if (ntps != null) {
getNTPTable().addAll(ntps);
}
List<String> strexc = configItem.getNetworkInterfaceExcepts();
getNetworkInterfaceExcept().clear();
if (strexc != null) {
for (String strexci : strexc) {
try {
getNetworkInterfaceExcept().add(NetworkInterface.getByName(strexci));
} catch (SocketException e) {
e.printStackTrace();
}
}
}
}
public KLALBController(List<InetAddress> daddr) {
this(true, daddr);
}
public KLALBController(Inet6Address self, List<InetAddress> daddr) {
this(self, true, daddr);
}
public KLALBController(boolean enableVirtualAdapter) {
this(enableVirtualAdapter, null);
}
protected KLALBVirtualSocketImpl createVirtualSocketImpl() {
return new KLALBVirtualSocketImpl(this);
}
protected KLALBVirtualDatagramSocketImpl createVirtualDatagramSocketImpl() {
return new KLALBVirtualDatagramSocketImpl(this);
}
private SRv6Router srv6Router;
public SRv6Router getIpv6Router() {
return srv6Router;
}
private Timer trtr = new Timer("路由表刷新计时器", true);
{
trtr.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (srv6Router != null) {
srv6Router.getLinkTabel().removeIf((v) -> {
return (v instanceof KLALBRemoteLink) && ((KLALBRemoteLink) v).isClosed();
});
srv6Router.updateRouteTabel();
}
}
}, 100, 100);
trtr.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (srv6Router != null) {
srv6Router.sortRouteTabel();
}
}
}, 10, 10);
}
public IPv6Packet createPacketToAddress(IPv6Address addr, int flowlabel, IPv6Packet.IPv6Payload packet) {
return createPacketToAddress(addr, flowlabel, packet, 1);
}
public IPv6Packet createPacketToAddress(IPv6Address addr, int flowlabel, IPv6Packet.IPv6Payload packet,
int count) {
IPv6Packet ipv = new IPv6Packet();
if (showpacket)
System.out.println("KLALB_TX:" + packet);
ipv.setVersion(6);
ipv.setTrafficClass(0b10);
ipv.setFlowLabel(flowlabel);
ipv.setHopLimit(255);
ipv.setSourceAddress(getSelf().getAddress());
ipv.setDestinationAddress(addr);
ipv.setPayload(packet);
packet.setParent(ipv);
return ipv;
}
private Map<IPv6Address, BandwidthDistributer<PortPair>> bandwidthDistrmap = new ConcurrentHashMap<>();
private Lock bdmLock = new ReentrantLock();
protected Map<IPv6Address, BandwidthDistributer<PortPair>> getBandwidthDistrmap() {
return bandwidthDistrmap;
}
protected void registerDistUpdateConsumer(IPv6Address targetaAddress, PortPair portp,
Consumer<Long> updateConsumer) {
if (updateConsumer == null) {
System.out.println("连接" + targetaAddress + " " + portp + " 释放带宽!");
bdmLock.lock();
try {
BandwidthDistributer<PortPair> bdr = bandwidthDistrmap.get(targetaAddress);
if (bdr != null) {
bdr.setDistrUpdateConsumer(portp, updateConsumer);
bdr.setBandwidthRequest(portp, 0L);
if (bdr.getDistrUpdateConsumerMap().isEmpty()) {
bandwidthDistrmap.remove(targetaAddress);
}
}
} finally {
bdmLock.unlock();
}
} else {
System.out.println("连接" + targetaAddress + " " + portp + " 申请带宽!");
bdmLock.lock();
try {
BandwidthDistributer<PortPair> bdr = bandwidthDistrmap.get(targetaAddress);
if (bdr == null) {
bdr = new BandwidthDistributer<>(1024 * 20000L * 1024);
bdr.setTotalRequestUpdateConsumer((treq) -> {
KLALBRoutingProtocol krp = srv6Router.getKlalbRouteProtol();
krp.updateTotalRequestBandwidth(targetaAddress, treq);
});
bandwidthDistrmap.put(targetaAddress, bdr);
}
bdr.setDistrUpdateConsumer(portp, updateConsumer);
} finally {
bdmLock.unlock();
}
}
}
protected void updateBandwidthRequest(IPv6Address targetaAddress, PortPair portp, long bandwidth) {
if (bandwidth < 0) {
throw new IllegalArgumentException(bandwidth + "<0");
}
// System.out.println("连接"+targetaAddress.getHostAddress()+" "+portp+"
// 调整带宽到"+bandwidth/1024 +"KB/s!");
BandwidthDistributer<PortPair> bdr = bandwidthDistrmap.get(targetaAddress);
if (bdr != null) {
bdr.setBandwidthRequest(portp, bandwidth);
} else {
throw new NullPointerException("连接" + targetaAddress + " " + portp + " 未申请带宽!");
}
}
private List<MultipurposeSocketAddress> listens = new CopyOnWriteArrayList<>();
public void registerToProxyTypeAs(String proxyname) {
MultipurposeSocketAddress.getSocketTypeRegister().put(proxyname + "_Stream", streamSocketType);
MultipurposeSocketAddress.getSocketTypeRegister().put(proxyname + "_Datagram", datagramSocketType);
// ProxyProfileEntry.getRegister().put(proxyname, this);
}
public List<MultipurposeSocketAddress> getListenSocketAddress() {
return listens;
}
private List<MultipurposeSocketAddress> ntptable = new CopyOnWriteArrayList();
private KLALBRoutingProtocol routingProtocol;
public List<MultipurposeSocketAddress> getNTPTable() {
return ntptable;
}
public KLALBControllerConfigItem getConfigItem() {
return configItem;
}
}