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 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 ipmd = new ArrayList<>(); private List networkInterfaceExcept = new ArrayList<>(); public List getNetworkInterfaceExcept() { return networkInterfaceExcept; } private List dnsAddresses = new ArrayList<>(); public List getDnsAddresses() { return dnsAddresses; } private Timer twk = new Timer("网卡检测扫描计时器", true); private TimerTask tsk1=new TimerTask() { @Override public void run() { try { Enumeration 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 ei = networkInterface.getInetAddresses(); while (ei.hasMoreElements()) { InetAddress inetAddress = (InetAddress) ei.nextElement(); 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(); } } } } } } catch (SocketException e) { } lineslock.writeLock().lock(); try { List localaddress = new ArrayList<>(); 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(); MultipurposeSocketAddress bind = new MultipurposeSocketAddress( inetAddress.getHostAddress(), 0); localaddress.add(bind); } } } Set st = new HashSet<>(); for (Iterator 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 iterator = st.iterator(); iterator.hasNext();) { MultipurposeSocketAddress target = (MultipurposeSocketAddress) iterator.next(); addRemoteLines(target); /* * for (Iterator 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 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 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 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 ei = networkInterface.getInetAddresses(); loop: while (ei.hasMoreElements()) { InetAddress bidr = (InetAddress) ei.nextElement(); 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, 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 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();) { 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 selflineTableSupplier=()->{return null;}; /* * public Supplier getSelflineTableSupplier() { return * selflineTableSupplier; } * * public void setSelflineTableSupplier(Supplier selflineTableSupplier) * { this.selflineTableSupplier = selflineTableSupplier; } */ public List getSelflineTable() { return selflineTable; } // private Inet6AddressGroup self; public Inet6AddressGroup getSelf() { return srv6Router.getLocator(); } private ReadWriteLock lineslock = new ReentrantReadWriteLock(); public List 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 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 { @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 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)) { 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 removeRemoteLines(MultipurposeSocketAddress mpsa) { List rmved = new ArrayList<>(); for (Iterator 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 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 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 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 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 nb=router.getNeighbors(); //System.out.println("srv6 ip"+nb); Set 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 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 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 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 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> bandwidthDistrmap = new ConcurrentHashMap<>(); private Lock bdmLock = new ReentrantLock(); protected Map> getBandwidthDistrmap() { return bandwidthDistrmap; } protected void registerDistUpdateConsumer(Inet6Address targetaAddress, PortPair portp, Consumer updateConsumer) { if (updateConsumer == null) { System.out.println("连接" + targetaAddress.getHostAddress() + " " + 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.getHostAddress() + " " + 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(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 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 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 getListenSocketAddress() { return listens; } private Listntptable=new CopyOnWriteArrayList(); private KLALBRoutingProtocol routingProtocol; public List 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 * 自动生成的方法存根 * * } */ }