Files
KLALB/src/org/kne/cloud/network/klalb/KLALBController.java
T
2025-11-15 11:08:16 +08:00

1087 lines
36 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.NoRouteToHostException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.kne.cloud.clock.AdjustedNanoClock;
import org.kne.cloud.clock.HighAccuracyClock;
import org.kne.cloud.network.IPMulticastDiscovery;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.PortPair;
import org.kne.cloud.network.SocketType;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload;
import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink;
import org.kne.cloud.network.ipv6.Neighbor;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
import org.kne.cloud.network.monitor.TimestampMonitor;
import org.kne.cloud.network.ntp.NTPContext;
import org.kne.cloud.network.ntp.NTPv4Packet;
import org.kne.cloud.network.ntp.NTPv4Protocol;
import org.kne.cloud.network.ntp.NTPv4Protocol.NTPPeer;
import org.kne.cloud.network.srv6.JsonDataPacket;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
import org.kne.cloud.network.srv6.KLALBRoutingProtocolAPIClient;
import org.kne.cloud.network.srv6.KLALBRoutingProtocolAPIServer;
import org.kne.cloud.network.srv6.KLALBRoutingProtocolJsonData;
import org.kne.cloud.network.srv6.PacketConsumer;
import org.kne.cloud.network.srv6.SRv6Router;
import org.kne.cloud.network.srv6.SRv6RouterListener;
import org.kne.cloud.network.tcp.UDPPacket;
import org.kne.cloud.network.te.BandwidthDistributer;
import org.kne.cloud.network.te.DWRRLoadingBalanceAlgorithm;
import org.kne.concurrent.DisruptorExecutor;
import org.kne.concurrent.HighPerformanceExecutor;
import org.kne.io.KNEChannels;
import org.pcap4j.packet.IpV6Packet.IpV6Header;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
public class KLALBController {
//TimestampMonitor<>
private SpeedAndTrafficMonitorDataImpl linkMonitor = new SpeedAndTrafficMonitorDataImpl();
private SpeedAndTrafficMonitorDataImpl datatMonitor = new SpeedAndTrafficMonitorDataImpl();
private List<MultipurposeSocketAddress> selflineTable = new ArrayList<>();
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 Timer twk = new Timer("网卡检测扫描计时器", true);
private TimerTask tsk1=new TimerTask() {
@Override
public void run() {
try {
Enumeration<NetworkInterface> eu = NetworkInterface.getNetworkInterfaces();
while (eu.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
if (networkInterface.getDisplayName()
.startsWith(IPv6TUNLoopbackNetworkLink.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 (!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();
}
}
}
}
}
} catch (SocketException e) {
}
lineslock.writeLock().lock();
try {
List<MultipurposeSocketAddress> localaddress = new ArrayList<>();
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();
MultipurposeSocketAddress bind = new MultipurposeSocketAddress(
inetAddress.getHostAddress(), 0);
localaddress.add(bind);
}
}
}
Set<MultipurposeSocketAddress> st = new HashSet<>();
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link=iterator.next();
if(link instanceof KLALBRemoteLine) {
KLALBRemoteLine multipurposeSocketAddress = (KLALBRemoteLine) 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<MultipurposeSocketAddress> iterator2 = localaddress.iterator();
* iterator2.hasNext();) { MultipurposeSocketAddress bind =
* (MultipurposeSocketAddress) iterator2 .next(); 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; } }
* catch (UnknownHostException e) {
* if(e.getMessage().toLowerCase().contains("no scope_id found")) }
* if(!checkContainsTargetAndBind(target,bind)) {
* //System.out.println(target+" "+bind); addRemoteLine( new
* KLALBRemoteLine(target,bind)); } }
*/
}
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link=iterator.next();
if(link instanceof KLALBRemoteLine) {
KLALBRemoteLine reml = (KLALBRemoteLine) link;
if (reml.getSocketAddress() != null) {
if (reml.getBindAddress() != null || reml.getRemoteVaddr() != null)
if (!localaddress.contains(reml.getBindAddress())) {
reml.close();
srv6Router.getLinkTabel().remove(reml);
}
}
}
}
for (Iterator<IPMulticastDiscovery> iterator = ipmd.iterator(); iterator.hasNext();) {
IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next();
if (ipMulticastDiscovery.isClosed() || (!ipMulticastDiscovery.getNinterface().isUp())) {
iterator.remove();
try {
ipMulticastDiscovery.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("移除网卡:" + ipMulticastDiscovery.getNinterface());
}
}
Enumeration<NetworkInterface> eu2 = NetworkInterface.getNetworkInterfaces();
while (eu2.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) eu2.nextElement();
if (networkInterface.getDisplayName()
.startsWith(IPv6TUNLoopbackNetworkLink.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();
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, 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, 10000L);
ipd2.setCon((mpa) -> {
// System.out.println("添加本地IPv4链路:"+mpa);
try {
if (!checkIsSelf(mpa))
addRemoteLines(mpa);
} catch (UnknownHostException e) {
}
});
ipd2.start();
ipmd.add(ipd2);
}
System.out.println("添加网卡:" + networkInterface);
} catch (BindException e) {
// e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// }
}
}
} catch (SocketException e) {
} finally {
lineslock.writeLock().unlock();
}
}
private boolean checkIsSelf(MultipurposeSocketAddress inetAddress) throws UnknownHostException {
return inetAddress.getInetAddress().isAnyLocalAddress()
|| inetAddress.getInetAddress().isLoopbackAddress() || selflineTable.contains(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<Inet6AddressGroup> nb=srv6Router.getLocators();
for (Iterator<Inet6AddressGroup> iterator = nb.iterator(); iterator.hasNext();) {
Inet6AddressGroup neighbor = (Inet6AddressGroup) iterator.next();
try {
InetSocketAddress iaddr= new InetSocketAddress( neighbor.getAddress(),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 HighAccuracyClock clock;
public HighAccuracyClock getClock() {
return clock;
}
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;
}
// private Supplier<String> selflineTableSupplier=()->{return null;};
/*
* public Supplier<String> getSelflineTableSupplier() { return
* selflineTableSupplier; }
*
* public void setSelflineTableSupplier(Supplier<String> selflineTableSupplier)
* { this.selflineTableSupplier = selflineTableSupplier; }
*/
public List<MultipurposeSocketAddress> getSelflineTable() {
return selflineTable;
}
// private Inet6AddressGroup self;
public Inet6AddressGroup getSelf() {
return srv6Router.getLocator();
}
private ReadWriteLock lineslock = new ReentrantReadWriteLock();
public List<IPv6NetworkLink> getLines() {
return srv6Router.getLinkTabel();
}
private PortBinder streamPortBinder = new PortBinder(this);
private PortBinder datagramPortBinder = new PortBinder(this);
private PortBinder rawPortBinder = new PortBinder(this);
protected PortBinder getStreamPortBinder() {
return streamPortBinder;
}
protected PortBinder getDatagramPortBinder() {
return datagramPortBinder;
}
protected PortBinder getRawPortBinder() {
return rawPortBinder;
}
public void reconnectImmediately() {
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink val=iterator.next();
if(val instanceof KLALBRemoteLine) {
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) val;
klalbRemoteLine.reconnectImmediately();
}
}
}
private NTPv4Protocol nvc2;
private KLALBRoutingProtocolAPIServer apiServer;
private KLALBRoutingProtocolAPIClient apiClient;
/*private PacketReceiver prc = new PacketReceiver();
private class PacketReceiver implements Consumer<KLALBPacket> {
@Override
public void accept(KLALBPacket rec) {
switch (rec.getType()) {
case KLALBPacket.ADDLINES:
ADDLINESPacket lpt = (ADDLINESPacket) rec;
String s = lpt.getLines();
ThreadTool.makeVDaemonThreadIfSupport("线路添加任务", () -> {
Scanner scn = new Scanner(s);
while (scn.hasNext()) {
String sn = scn.nextLine();
MultipurposeSocketAddress msa = new MultipurposeSocketAddress(sn);
addRemoteLines(msa);
}
}).start();
break;
default:
break;
}
}
}*/
public void addRemoteLines(List<MultipurposeSocketAddress> select) {
for(MultipurposeSocketAddress target:select) {
addRemoteLines(target);
}
}
public List<KLALBRemoteLine> addRemoteLines(MultipurposeSocketAddress target) {
lineslock.writeLock().lock();
try {
List<KLALBRemoteLine> 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)) {
KLALBRemoteLine line = new KLALBRemoteLine(target, bind);
addRemoteLine(line);
added.add(line);
}
} catch (UnknownHostException e) {
}
}
}
}
} catch (SocketException e) {
if (!checkContainsTarget(target)) {
KLALBRemoteLine line = new KLALBRemoteLine(target);
addRemoteLine(line);
added.add(line);
}
// throw e;
}
return added;
} finally {
lineslock.writeLock().unlock();
}
}
public List<KLALBRemoteLine> removeRemoteLines(MultipurposeSocketAddress mpsa) {
List<KLALBRemoteLine> rmved = new ArrayList<>();
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link= iterator.next();
if(link instanceof KLALBRemoteLine) {
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine)link;
if (mpsa.equals(klalbRemoteLine.getSocketAddress())) {
klalbRemoteLine.close();
rmved.add(klalbRemoteLine);
}
}
}
return rmved;
}
public Inet6Address getRemoteVaddrBySocketAddress(MultipurposeSocketAddress target) throws SocketTimeoutException {
KLALBRemoteLine kr = null;
for (Iterator<IPv6NetworkLink> iterator = srv6Router.getLinkTabel().iterator(); iterator.hasNext();) {
IPv6NetworkLink link= iterator.next();
if(link instanceof KLALBRemoteLine) {
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link;
if (target.equals(klalbRemoteLine.getSocketAddress()) && klalbRemoteLine.getBindAddress() == null) {
kr = klalbRemoteLine;
break;
}
}
}
if (kr == null) {
kr = new KLALBRemoteLine(target);
addRemoteLine(kr);
kr.waitForRemoteVaddrAvaliable(20000);
} else {
kr.reconnectImmediately();
kr.waitForRemoteVaddrAvaliable(20000);
}
return kr.getRemoteVaddr().getAddress();
}
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 KLALBRemoteLine) {
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link;
if (bind.equals(klalbRemoteLine.getBindAddress()) && target.equals(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 KLALBRemoteLine) {
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) link;
if (target.equals(klalbRemoteLine.getSocketAddress())) {
b = true;
break;
}
}
}
return b;
}
public void addRemoteLine(KLALBRemoteLine krs) {
lineslock.writeLock().lock();
try {
//krs.setPacketReceiver(prc);
krs.setKlalbController(this);
krs.setLocalVaddrSupplier(() -> {
return getSelf();
});
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 class UDPProtocolPacketConsumer implements PacketConsumer {
@Override
public boolean accept(IPv6Packet packx) throws IOException {
IPv6Payload pl = packx.getPayload();
packx.putTimePassport("unpacked");
packx.printPassport();
if (pl instanceof UDPPacket) {
UDPPacket rec = (UDPPacket) pl;
if (showpacket)
System.out.println("UDP_RX:" + rec);
Inet6Address srcA = packx.getSourceAddress();
PortPacket pt = (PortPacket) rec;
if(datagramPortBinder.distributePacketToConsumer(srcA, pt)) {
return true;
}
}
return false;
// packx.dispose();
// });
}
}
private class KLALBProtocolPacketConsumer implements PacketConsumer {
@Override
public boolean accept(IPv6Packet packx) throws IOException {
IPv6Payload pl = packx.getPayload();
packx.putTimePassport("unpacked");
packx.printPassport();
if (pl instanceof KLALBPacket) {
KLALBPacket rec = (KLALBPacket) pl;
if (showpacket)
System.out.println("KLALB_RX:" + rec);
if (rec instanceof PortPacket) {
rec.setCE(packx.isCE());
Inet6Address srcA = packx.getSourceAddress();
PortPacket pt = (PortPacket) rec;
if (streamPortBinder.distributePacketToConsumer(srcA, pt)) {
}else {
if (!(pt instanceof RSTPacket))
HighPerformanceExecutor.defaultExecutor.execute(() -> {
sendPacketToAddress(srcA, 0, new RSTPacket(pt.getDstPort(), pt.getSrcPort()), 2);
});
}
}
}
return true;
// packx.dispose();
}
}
private void loadSRv6ProtocolStack(Inet6AddressGroup selfx, boolean enableVirtualAdapter) {
srv6Router = new SRv6Router(selfx);
srv6Router.runKLALBRouteProtocol();
routingProtocol = srv6Router.getKlalbRouteProtol();
routingProtocol.addReceiver((addr,packet)->{
});
System.out.println("SRv6协议栈已加载");
if (enableVirtualAdapter)
try {
IPv6TUNLoopbackNetworkLink tunlink = new IPv6TUNLoopbackNetworkLink(
new Inet6AddressGroup(srv6Router.getLocator().getAddress(), 32), SRv6Router.MTU, dnsAddresses);
tunlink.setMonitor(datatMonitor);
//srv6Router.getLinkTabel().add(tunlink);
srv6Router.getinLoopback().setFallbackLink(tunlink);
System.out.println("虚拟网卡已挂载");
} catch (Exception e) {
System.err.println("挂载虚拟网卡失败,可能是无管理员权限?请尝试使用管理员权限运行软件");
e.printStackTrace();
}
srv6Router.getinLoopback(). getProtocolNumberRegister().put(UDPPacket.UDP_PROTOCOL_NUMBER, new UDPProtocolPacketConsumer());
System.out.println("UDP协议已加载");
srv6Router.getinLoopback().getProtocolNumberRegister().put(KLALBPacket.KLALB_PROTOCOL_NUMBER,
new KLALBProtocolPacketConsumer());
System.out.println("KLALB协议已加载");
String iproxyname="KLALB_"+UUID.randomUUID();
registerToProxyTypeAs(iproxyname);
clock = new HighAccuracyClock();
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();
//System.out.println("srv6 ip"+nb);
Set<NTPPeer> sp=nvc.getPeers();
for (Neighbor neighbor : nb) {
if(neighbor.getLocator()!=null)
sp.add(new NTPPeer(new MultipurposeSocketAddress(iproxyname+"_Datagram",neighbor.getLocator().getAddress().getHostAddress(),123), NTPv4Packet.NTP_SYMMETRIC_ACTIVE));
}
sp.removeIf((p)->{
for (Neighbor neighbor : nb) {
try {
if(neighbor.getLocator()!=null)
if(neighbor.getLocator().getAddress().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("NTP时钟同步协议已加载");
} 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, 2000, 2000);
twk.schedule(tsk2, 2000, 2000);
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;
Inet6AddressGroup selfg = new Inet6AddressGroup(self, PREFIX);
initKLALB(enableVirtualAdapter, selfg);
}
protected void initKLALB(boolean enableVirtualAdapter, Inet6AddressGroup selfg) {
loadSRv6ProtocolStack(selfg, enableVirtualAdapter);
loadController();
}
public KLALBController(boolean enableVirtualAdapter, List<InetAddress> dnsaddr) {
this.dnsAddresses = dnsaddr;
SecureRandom sc = new SecureRandom();
byte[] v = new byte[16];
sc.nextBytes(v);
v[0] = (byte) 0x24;
v[1] = (byte) 0x86;
v[2] = 0;
v[3] = 1;
v[14] = 0;
v[15] = 1;
Inet6AddressGroup selfx = null;
try {
selfx = new Inet6AddressGroup((Inet6Address) InetAddress.getByAddress(v), PREFIX);
} catch (UnknownHostException e) {
e.printStackTrace();
}
initKLALB(enableVirtualAdapter, selfx);
}
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 KLALBRemoteLine) && ((KLALBRemoteLine) v).isClosed();
});
srv6Router.updateRouteTabel();
}
}
}, 100, 100);
}
protected void sendPacketToAddress(Inet6Address addr, int flowlabel, IPv6Packet.IPv6Payload packet) {
sendPacketToAddress(addr, flowlabel, packet, 1);
}
protected void sendPacketToAddress(Inet6Address addr, int flowlabel, IPv6Packet.IPv6Payload packet, int count)
{
//HighPerformanceExecutor.defaultExecutor.execute(() -> {
IPv6Packet ipv = new IPv6Packet();
if (showpacket)
System.out.println("KLALB_TX:" + packet);
ipv.setVersion(6);
ipv.setTrafficClass(0);
ipv.setFlowLabel(flowlabel);
ipv.setHopLimit(255);
ipv.setSourceAddress(getSelf().getAddress());
ipv.setDestinationAddress(addr);
ipv.setPriority(packet.getPriority());
// if(packet instanceof DATATPacket) {
ipv.setPromise(true);
// }
ipv.enableECN();
/*
* if(b) ipv.markCE();
*/
ipv.setPayload(packet);
packet.setParent(ipv);
// System.out.println(ipv.getPayload().getProtocolNumber());
/*
* System.out.println("SND:"+ipv.getPayload().getData()); byte[]b=new
* byte[ipv.getPayload().getData().limit()]; ipv.getPayload().getData().get(0,
* b); System.out.println(Arrays.toString(b));
*/
// packet.getSendRecord().add(null);
if(packet instanceof KLALBPacket)
((KLALBPacket) packet).incSendCounter();
packet.putTimePassport("packedInIPv6");
packet.printPassport();
ipv.putTimePassport("packed");
srv6Router.insertSRHandRoutePacket(ipv);
// srv6Router.putProtocolNumberPacketAndInsertSRHAsync(ipv);
//});
}
private Map<Inet6Address, BandwidthDistributer<PortPair>> bandwidthDistrmap = new ConcurrentHashMap<>();
private Lock bdmLock = new ReentrantLock();
protected Map<Inet6Address, BandwidthDistributer<PortPair>> getBandwidthDistrmap() {
return bandwidthDistrmap;
}
protected void registerDistUpdateConsumer(Inet6Address targetaAddress, PortPair portp,
Consumer<Long> updateConsumer) {
if (updateConsumer == null) {
System.out.println("连接" + targetaAddress.getHostAddress() + " " + 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.getHostAddress() + " " + 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(Inet6Address 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.getHostAddress() + " " + portp + " 未申请带宽!");
}
}
private Timer t = new Timer("数据包重传计时器", true);
protected Timer getResendTimer() {
return t;
}
private Timer t2 = new Timer("数据包粘包计时器", true);
private List<MultipurposeSocketAddress> listens = new CopyOnWriteArrayList<>();
public Timer getNagleTimer() {
return t2;
}
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;//nvc2.getPeers().add(new NTPPeer("{UDP}106.55.184.199:123", NTPv4Packet.NTP_CLIENT));
}
/*
* @Override public void listen(MultipurposeSocketAddress msa) { // TODO
* 自动生成的方法存根
*
* }
*
* @Override public void unlisten(MultipurposeSocketAddress msc) { // TODO
* 自动生成的方法存根
*
* }
*
* @Override public void connect(MultipurposeSocketAddress msa) { // TODO
* 自动生成的方法存根
*
* }
*
* @Override public void unconnect(MultipurposeSocketAddress msc) { // TODO
* 自动生成的方法存根
*
* }
*/
}