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.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(HighAccuracyClock.SYSTEM_CLOCK, "up", 100,TIME_WINDOW ), new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, TIME_WINDOW)); private SpeedAndTrafficMonitorDataImpl datatMonitor = new SpeedAndTrafficMonitorDataImpl( new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "up", 100, TIME_WINDOW), new HashMapTimestampMonitor(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, TIME_WINDOW)); private List 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 ipmd = new ArrayList<>(); private List networkInterfaceExcept = new ArrayList<>(); public List getNetworkInterfaceExcept() { return networkInterfaceExcept; } private List dnsAddresses = new ArrayList<>(); public List 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 getAllNetworkInterfaceAddress() throws SocketException { List addresses = new ArrayList(); Enumeration 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 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 localaddress = getAllNetworkInterfaceAddress(); for (InetAddress inetAddress : localaddress) { if (!inetAddress.isLoopbackAddress()) for (Iterator 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 st = new HashSet<>(); for (Iterator 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 iterator = st.iterator(); iterator.hasNext();) { MultipurposeSocketAddress target = (MultipurposeSocketAddress) iterator.next(); addRemoteLines(target); } for (Iterator 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 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 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 ei = networkInterface.getInetAddresses(); loop: while (ei.hasMoreElements()) { InetAddress bidr = (InetAddress) ei.nextElement(); if (checkIsSelfLocator(bidr)) { continue; } for (Iterator 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 nt = ntptable; // System.out.println("srv6 ip"+nb); if (nvc2 != null) { Set 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 nb = srv6Router.getLocators(); for (Iterator 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 getSelflineTable() { return selflineTable; } public IPv6AddressGroup getSelf() { return srv6Router.getLocator(); } private ReadWriteLock lineslock = new ReentrantReadWriteLock(); public List getLines() { return srv6Router.getLinkTabel(); } public void reconnectImmediately() { for (Iterator 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 select) { for (MultipurposeSocketAddress target : select) { addRemoteLines(target); } } public List addRemoteLines(MultipurposeSocketAddress target) { lineslock.writeLock().lock(); try { List added = new ArrayList<>(); try { Enumeration eu = NetworkInterface.getNetworkInterfaces(); while (eu.hasMoreElements()) { NetworkInterface networkInterface = (NetworkInterface) eu.nextElement(); if (networkInterface.isUp()) { // System.out.println(networkInterface+" "+networkInterface.isUp()); Enumeration 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 removeRemoteLines(MultipurposeSocketAddress mpsa) { List rmved = new ArrayList<>(); for (Iterator 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 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 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 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 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 nb = router.getNeighbors(); Set 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 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 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(); List 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 linele = configItem.getLineTable(); if (linele != null) { getSelflineTable().addAll(linele); } List linetoc = configItem.getConnectLineTable(); if (linetoc != null) { linetoc.forEach((aline) -> { addRemoteLines(aline); }); } List ntps = configItem.getNtpServerTable(); if (ntps != null) { getNTPTable().addAll(ntps); } List 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 daddr) { this(true, daddr); } public KLALBController(Inet6Address self, List 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> bandwidthDistrmap = new ConcurrentHashMap<>(); private Lock bdmLock = new ReentrantLock(); protected Map> getBandwidthDistrmap() { return bandwidthDistrmap; } protected void registerDistUpdateConsumer(IPv6Address targetaAddress, PortPair portp, Consumer updateConsumer) { if (updateConsumer == null) { System.out.println("连接" + targetaAddress + " " + portp + " 释放带宽!"); bdmLock.lock(); try { BandwidthDistributer 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 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 bdr = bandwidthDistrmap.get(targetaAddress); if (bdr != null) { bdr.setBandwidthRequest(portp, bandwidth); } else { throw new NullPointerException("连接" + targetaAddress + " " + portp + " 未申请带宽!"); } } private List 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 getListenSocketAddress() { return listens; } private List ntptable = new CopyOnWriteArrayList(); private KLALBRoutingProtocol routingProtocol; public List getNTPTable() { return ntptable; } public KLALBControllerConfigItem getConfigItem() { return configItem; } }