forked from KNEMC/KLALB
KLALB3.2
This commit is contained in:
@@ -14,15 +14,15 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
|
||||
private static final int HEADER_LENGTH=28;
|
||||
private static final int HEADER_LENGTH=35;
|
||||
|
||||
public ACKTPacket(int sport,int dport,long number,boolean avaliable,boolean congress,long rcvSpeed,int sendcount) {
|
||||
public ACKTPacket(int sport,int dport,long number,long avaliableRcvWindow,boolean congress,long rcvSpeed,int sendcount) {
|
||||
super(ACKT,HEADER_LENGTH);
|
||||
klalbHeader.putInt(sport);
|
||||
klalbHeader.putInt(dport);
|
||||
klalbHeader.putLong(number);
|
||||
klalbHeader.put((byte) sendcount);
|
||||
klalbHeader.put((byte) (avaliable?1:0));
|
||||
klalbHeader.putLong(avaliableRcvWindow);
|
||||
klalbHeader.put((byte) (congress?1:0));
|
||||
klalbHeader.putLong(rcvSpeed);
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] "+isAvaliable();
|
||||
return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] avaliable:"+getAvaliableRcvWindow();
|
||||
}
|
||||
|
||||
public int getSport() {
|
||||
@@ -41,7 +41,7 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
}
|
||||
|
||||
public boolean isCongress() {
|
||||
return klalbHeader.get(19)!=0;
|
||||
return klalbHeader.get(26)!=0;
|
||||
}
|
||||
|
||||
public int getDport() {
|
||||
@@ -52,8 +52,8 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
return klalbHeader.getLong(9);
|
||||
}
|
||||
|
||||
public boolean isAvaliable() {
|
||||
return klalbHeader.get(18)!=0;
|
||||
public long getAvaliableRcvWindow() {
|
||||
return klalbHeader.getLong(18);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,6 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
return klalbHeader.getInt(17);
|
||||
}
|
||||
public long getRcvSpeed() {
|
||||
return klalbHeader.getLong(20);
|
||||
return klalbHeader.getLong(27);
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public class ADDLINESPacket extends KLALBPacket {
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
byte[]bta=lines.getBytes(Charset.forName("UTF-8"));
|
||||
klalbHeader.putChar(1,(char) bta.length);
|
||||
super.writeToChannel(dto);
|
||||
@@ -49,7 +49,7 @@ public class ADDLINESPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
super.readFromChannel(din);
|
||||
int lth=klalbHeader.getChar(1);
|
||||
byte[]b=new byte[lth];
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public abstract class AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
|
||||
private AtomicLong[] inputTrafficCounters;
|
||||
private AtomicLong[] outputTrafficCounters;
|
||||
private AtomicLong[] inputPacketsCounters;
|
||||
private AtomicLong[] outputPacketsCounters;
|
||||
@Override
|
||||
public void setOutputPacketsCounters(AtomicLong[] outCounter) {
|
||||
outputPacketsCounters=outCounter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputPacketsCounters(AtomicLong[] inCounter) {
|
||||
inputPacketsCounters=inCounter;
|
||||
|
||||
}
|
||||
@Override
|
||||
public void setOutputTrafficCounters(AtomicLong[] outCounter) {
|
||||
this.outputTrafficCounters=outCounter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputTrafficCounters(AtomicLong[] inCounter) {
|
||||
this.inputTrafficCounters=inCounter;
|
||||
}
|
||||
|
||||
public AtomicLong[] getInputTrafficCounters() {
|
||||
return inputTrafficCounters;
|
||||
}
|
||||
|
||||
public AtomicLong[] getOutputTrafficCounters() {
|
||||
return outputTrafficCounters;
|
||||
}
|
||||
|
||||
public AtomicLong[] getInputPacketsCounters() {
|
||||
return inputPacketsCounters;
|
||||
}
|
||||
|
||||
public AtomicLong[] getOutputPacketsCounters() {
|
||||
return outputPacketsCounters;
|
||||
}
|
||||
|
||||
protected void incOutput(int packetLength) {
|
||||
if(outputTrafficCounters!=null) {
|
||||
for(AtomicLong al:outputTrafficCounters) {
|
||||
al.addAndGet(packetLength);
|
||||
}
|
||||
}
|
||||
if(outputPacketsCounters!=null) {
|
||||
for(AtomicLong al:outputPacketsCounters) {
|
||||
al.incrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void incInput(int packetLength) {
|
||||
if(inputTrafficCounters!=null) {
|
||||
for(AtomicLong al:inputTrafficCounters) {
|
||||
al.addAndGet(packetLength);
|
||||
}
|
||||
}
|
||||
if(inputPacketsCounters!=null) {
|
||||
for(AtomicLong al:inputPacketsCounters) {
|
||||
al.incrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
ByteBuffer dataWrite=NetworkPacket.bufferAllocator.allocate((int) kp.getLength());
|
||||
//dataWrite.clear();
|
||||
KLALBPacket.writeKLALBPacketToChannel(KNEChannels.newWritableChannel( dataWrite), kp);
|
||||
dataWrite.flip();
|
||||
writePacket(dataWrite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
ByteBuffer buffer=readPacket();
|
||||
if(buffer==null) {
|
||||
return null;
|
||||
}
|
||||
return KLALBPacket.readKLALBPacketFromChannel(KNEChannels.newReadableChannel(buffer));
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class ByteArrayPool {
|
||||
private Queue<byte[]> rec;
|
||||
private int maxcount;
|
||||
private int length;
|
||||
public ByteArrayPool(int maxcount, int length) {
|
||||
super();
|
||||
this.maxcount = maxcount;
|
||||
this.length = length;
|
||||
rec=new ConcurrentLinkedQueue<byte[]>();
|
||||
}
|
||||
public void back(byte[]b) {
|
||||
if(b.length!=length)
|
||||
throw new IllegalArgumentException("wrong length");
|
||||
rec.offer(b);
|
||||
}
|
||||
public byte[] borrow() {
|
||||
byte[]b=rec.poll();
|
||||
if(b==null) {
|
||||
b=new byte[length];
|
||||
}
|
||||
return b;
|
||||
}
|
||||
public int getMaxCount() {
|
||||
return maxcount;
|
||||
}
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.debug.TimeDebugger;
|
||||
/*
|
||||
public class ByteBufferPool {
|
||||
private Queue<ByteBuffer> rec;
|
||||
private int maxcount;
|
||||
private int length;
|
||||
private boolean direct;
|
||||
public ByteBufferPool(int maxcount, int length,boolean direct) {
|
||||
super();
|
||||
this.maxcount = maxcount;
|
||||
this.length = length;
|
||||
this.direct=direct;
|
||||
rec=new ConcurrentLinkedQueue<ByteBuffer>();
|
||||
}
|
||||
public ByteBufferPool(int maxcount, int length) {
|
||||
this(maxcount, length, true);
|
||||
}
|
||||
public void back(ByteBuffer b) {
|
||||
if(b.capacity()!=length)
|
||||
throw new IllegalArgumentException("wrong length");
|
||||
b.clear();
|
||||
rec.offer(b);
|
||||
}
|
||||
public ByteBuffer borrow() {
|
||||
ByteBuffer b=rec.poll();
|
||||
if(b==null) {
|
||||
if(direct)
|
||||
b=ByteBuffer.allocateDirect(length);
|
||||
else
|
||||
b=ByteBuffer.allocate(length);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
public int getMaxCount() {
|
||||
return maxcount;
|
||||
}
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
public class ByteBufferPool {
|
||||
private ByteBuffer[]rec;
|
||||
private volatile int pos=0;
|
||||
private Lock lock=new SpinLock();
|
||||
|
||||
private int maxcount;
|
||||
private int length;
|
||||
private int mcj;
|
||||
private boolean direct;
|
||||
public ByteBufferPool(int maxcount, int length,boolean direct) {
|
||||
super();
|
||||
this.maxcount = maxcount;
|
||||
this.length = length;
|
||||
this.direct=direct;
|
||||
rec=new ByteBuffer[maxcount];
|
||||
mcj=rec.length-1;
|
||||
}
|
||||
public ByteBufferPool(int maxcount, int length) {
|
||||
this(maxcount, length, true);
|
||||
}
|
||||
public void back(ByteBuffer b) {
|
||||
if(b.capacity()!=length)
|
||||
throw new IllegalArgumentException("wrong length");
|
||||
b.clear();
|
||||
lock.lock();
|
||||
try {
|
||||
if(pos<mcj)
|
||||
rec[++pos]= b;
|
||||
}finally{
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
public ByteBuffer borrow() {
|
||||
ByteBuffer b=null;
|
||||
lock.lock();
|
||||
try {
|
||||
if(pos>0) {
|
||||
b=rec[pos--];
|
||||
//rec[pos--]=null;
|
||||
}
|
||||
}finally{
|
||||
lock.unlock();
|
||||
}
|
||||
if(b==null) {
|
||||
if(direct)
|
||||
b=ByteBuffer.allocateDirect(length);
|
||||
else
|
||||
b=ByteBuffer.allocate(length);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
public int getMaxCount() {
|
||||
return maxcount;
|
||||
}
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,11 @@ package org.kne.cloud.network.klalb;
|
||||
|
||||
public class CONST {
|
||||
public static final String klalb="KLALB";
|
||||
public static final String klalbver="3.0";
|
||||
public static final String klalbver="3.2";
|
||||
public static final int bversion=3;
|
||||
public static final int sversion=0;
|
||||
public static final int sversion=1;
|
||||
public static final int itemwidth = 720;
|
||||
public static final int linepanelheight = 45;
|
||||
public static final int settingheight = 30;
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
||||
klalbHeader.putChar((char) 0);
|
||||
|
||||
//dataBuffer.limit(mtulimit);
|
||||
dataBuffer=ByteBuffer.allocate(mtulimit);
|
||||
dataBuffer=NetworkPacket.bufferAllocator.allocate(mtulimit);
|
||||
}
|
||||
|
||||
public int getSendcount() {
|
||||
@@ -100,7 +100,7 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
klalbHeader.put(17, (byte) getSendCounter());
|
||||
klalbHeader.putChar(18, (char) dataBuffer.limit());
|
||||
super.writeToChannel(dto);
|
||||
@@ -109,13 +109,13 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
super.readFromChannel(din);
|
||||
numberc=Long.MIN_VALUE;
|
||||
int limit=klalbHeader.getChar(18);
|
||||
//dataBuffer.clear();
|
||||
//dataBuffer.limit();
|
||||
dataBuffer=ByteBuffer.allocate(limit);
|
||||
dataBuffer=NetworkPacket.bufferAllocator.allocate(limit);
|
||||
while(dataBuffer.hasRemaining()){
|
||||
if(din.read(dataBuffer)==-1) {
|
||||
throw new EOFException();
|
||||
@@ -124,12 +124,5 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
||||
dataBuffer.flip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/*ByteBuffer datan=dataBuffer;
|
||||
dataBuffer=null;
|
||||
NetworkPacket.databufferpool_65535.back(datan);*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -125,12 +125,14 @@ import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.kne.cloud.network.DatagramServerSocket;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.SpeedLimiter;
|
||||
|
||||
public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
public class DatagramKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@@ -145,17 +147,20 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
private ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
|
||||
private DataOutputStream dos=new DataOutputStream(bos);
|
||||
@Override
|
||||
public void writePacket(KLALBPacket kp) throws IOException {
|
||||
/*@Override
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
//System.out.println(" TX:"+kp);
|
||||
KLALBPacket.writeKLALBPacketToStream(dos, kp);
|
||||
|
||||
byte[]bt=bos.toByteArray();
|
||||
DatagramPacket dp=new DatagramPacket(bt,bt.length);
|
||||
ds.send(dp);
|
||||
bos.reset();
|
||||
}
|
||||
|
||||
private byte[]bc=new byte[65535];
|
||||
DataInputStream dis;
|
||||
@Override
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
KLALBPacket kp=null;
|
||||
do {
|
||||
if(dis==null) {
|
||||
@@ -176,8 +181,37 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
//System.out.println(" RX:"+kp);
|
||||
}while(true);
|
||||
return kp;
|
||||
}*/
|
||||
|
||||
|
||||
byte[]b=new byte[65536];
|
||||
@Override
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
int length=kp.remaining();
|
||||
incOutput(length);
|
||||
kp.get(b,0,length);
|
||||
DatagramPacket dp=new DatagramPacket(b,length);
|
||||
ds.send(dp);
|
||||
}
|
||||
|
||||
byte[]c=new byte[65536];
|
||||
@Override
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
DatagramPacket dp;
|
||||
if(ds instanceof DatagramServerSocket.SubDatagramSocket) {
|
||||
dp=((DatagramServerSocket.SubDatagramSocket) ds).receive();
|
||||
}else {
|
||||
dp=new DatagramPacket(c, c.length);
|
||||
ds.receive(dp);
|
||||
}
|
||||
incInput(dp.getLength());
|
||||
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(dp.getLength());
|
||||
bbf.put(dp.getData(),0,dp.getLength());
|
||||
bbf.flip();
|
||||
return bbf;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
ds.close();
|
||||
@@ -200,10 +234,7 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
byte[]bt=bos.toByteArray();
|
||||
DatagramPacket dp=new DatagramPacket(bt,bt.length);
|
||||
ds.send(dp);
|
||||
bos.reset();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -211,4 +242,6 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
public boolean isStream() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class IPSequence {
|
||||
private UUID uuid;
|
||||
private boolean isPromise;
|
||||
|
||||
|
||||
public IPSequence(UUID uuid, boolean isPromise) {
|
||||
super();
|
||||
this.uuid = uuid;
|
||||
this.isPromise = isPromise;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public boolean isPromise() {
|
||||
return isPromise;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IPSequence [uuid=" + uuid + ", isPromise=" + isPromise + "]";
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(uuid);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
IPSequence other = (IPSequence) obj;
|
||||
return Objects.equals(uuid, other.uuid);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,26 +10,6 @@ import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
|
||||
public class IPv6OverKLALBPacket extends KLALBPacket {
|
||||
private static final int HEADER_LENGTH=9;
|
||||
@Override
|
||||
public boolean isSomeDisposed() {
|
||||
return super.isDisposed()||ipv6Packet.isSomeDisposed();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void lockAll() {
|
||||
super.lockAll();
|
||||
ipv6Packet.lockAll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void unlockAll() {
|
||||
ipv6Packet.unlockAll();
|
||||
super.unlockAll();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@@ -56,12 +36,6 @@ public class IPv6OverKLALBPacket extends KLALBPacket {
|
||||
super(bb,HEADER_LENGTH);
|
||||
this.ipv6Packet=new IPv6Packet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeAll() {
|
||||
super.disposeAll();
|
||||
ipv6Packet.disposeAll();
|
||||
}
|
||||
|
||||
public IPv6Packet getIPv6Packet() {
|
||||
return ipv6Packet;
|
||||
@@ -78,24 +52,16 @@ public class IPv6OverKLALBPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
klalbHeader.putLong(1, ipv6Packet.getLength());
|
||||
super.writeToChannel(dto);
|
||||
ipv6Packet.writeToChannel(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
super.readFromChannel(din,length);
|
||||
ipv6Packet.readFromChannel(din, klalbHeader.getLong(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void doDisposeAfterSend() {
|
||||
super.doDisposeAfterSend();
|
||||
ipv6Packet.doDisposeAfterSend();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,14 +56,18 @@ import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink;
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
|
||||
import org.kne.cloud.network.srv6.PacketConsumer;
|
||||
import org.kne.cloud.network.srv6.SRv6Router;
|
||||
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.JsonElement;
|
||||
|
||||
public class KLALBController {
|
||||
|
||||
|
||||
@@ -80,6 +84,12 @@ public class KLALBController {
|
||||
|
||||
private static List<IPMulticastDiscovery> ipmd=new ArrayList<>();
|
||||
|
||||
private List<InetAddress>dnsAddresses=new ArrayList<>();
|
||||
|
||||
public List<InetAddress> getDnsAddresses() {
|
||||
return dnsAddresses;
|
||||
}
|
||||
|
||||
private Timer twk=new Timer("网卡检测扫描计时器", true);
|
||||
{
|
||||
|
||||
@@ -210,48 +220,49 @@ public class KLALBController {
|
||||
continue;
|
||||
}
|
||||
if(networkInterface.isUp()) {
|
||||
boolean b=true;
|
||||
|
||||
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())) {
|
||||
b=false;
|
||||
break;
|
||||
if(networkInterface.equals(ipMulticastDiscovery.getNinterface())&&bidr.equals(ipMulticastDiscovery.getBind().getAddress())) {
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
if(b) {
|
||||
/*InetAddress bidr=null;
|
||||
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
|
||||
while (ei.hasMoreElements()) {
|
||||
InetAddress inetAddress = (InetAddress) ei.nextElement();
|
||||
if(inetAddress instanceof Inet6Address) {
|
||||
Inet6Address i6=(Inet6Address) inetAddress;
|
||||
if(i6.getHostAddress().startsWith("fe80")) {
|
||||
bidr=i6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(bidr!=null)*/
|
||||
|
||||
|
||||
|
||||
try {
|
||||
InetAddress bidr=InetAddress.getByName("::0");
|
||||
IPMulticastDiscovery ipd=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("ff02::2486"),DISCOVERY_PORT), networkInterface,selflineTable);
|
||||
//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);
|
||||
addRemoteLines(mpa);
|
||||
try {
|
||||
if(!checkIsSelf(mpa))
|
||||
addRemoteLines(mpa);
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
});
|
||||
ipd.start();
|
||||
ipmd.add(ipd);
|
||||
|
||||
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);
|
||||
}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);
|
||||
addRemoteLines(mpa);
|
||||
try {
|
||||
if(!checkIsSelf(mpa))
|
||||
addRemoteLines(mpa);
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
});
|
||||
ipd2.start();
|
||||
ipmd.add(ipd2);
|
||||
|
||||
}
|
||||
System.out.println("添加网卡:"+networkInterface);
|
||||
}catch(BindException e) {
|
||||
//e.printStackTrace();
|
||||
@@ -259,8 +270,11 @@ public class KLALBController {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +284,11 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean checkIsSelf(MultipurposeSocketAddress inetAddress) throws UnknownHostException {
|
||||
|
||||
return inetAddress.getInetAddress().isAnyLocalAddress()||inetAddress.getInetAddress().isLoopbackAddress()||selflineTable.contains(inetAddress);
|
||||
}
|
||||
}, 2000, 2000);
|
||||
}
|
||||
public SpeedAndTrafficMonitorDataImpl getLinkMonitor() {
|
||||
@@ -326,10 +345,10 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
|
||||
private Inet6AddressGroup self;
|
||||
//private Inet6AddressGroup self;
|
||||
|
||||
public Inet6Address getSelf() {
|
||||
return self.getAddress();
|
||||
public Inet6AddressGroup getSelf() {
|
||||
return srv6Router.getLocator();
|
||||
}
|
||||
private List<KLALBRemoteLine> lines=new CopyOnWriteArrayList<>();
|
||||
private ReadWriteLock lineslock=new ReentrantReadWriteLock();
|
||||
@@ -339,11 +358,16 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
private PortBinder streamPortBinder=new PortBinder(this);
|
||||
|
||||
private PortBinder rawPortBinder=new PortBinder(this);
|
||||
|
||||
protected PortBinder getStreamPortBinder() {
|
||||
return streamPortBinder;
|
||||
}
|
||||
|
||||
|
||||
public PortBinder getRawPortBinder() {
|
||||
return rawPortBinder;
|
||||
}
|
||||
|
||||
public void reconnectImmediately() {
|
||||
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
||||
@@ -380,7 +404,8 @@ public class KLALBController {
|
||||
|
||||
}
|
||||
|
||||
public List<KLALBRemoteLine> addRemoteLines(MultipurposeSocketAddress target) {
|
||||
public List<KLALBRemoteLine> addRemoteLines(MultipurposeSocketAddress target) {lineslock.writeLock().lock();
|
||||
try {
|
||||
List<KLALBRemoteLine>added=new ArrayList<>();
|
||||
try {
|
||||
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
|
||||
@@ -419,6 +444,9 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
return added;
|
||||
}finally {
|
||||
lineslock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
public List<KLALBRemoteLine> removeRemoteLines(MultipurposeSocketAddress mpsa) {
|
||||
|
||||
@@ -477,15 +505,15 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
public void addRemoteLine(KLALBRemoteLine krs) {
|
||||
lineslock.writeLock().lock();
|
||||
try {
|
||||
krs.setPacketReceiver(prc);
|
||||
krs.setKlalbController(this);
|
||||
krs.setLocalVaddrSupplier(()->{return self;});
|
||||
krs.setLocalVaddrSupplier(()->{return getSelf();});
|
||||
krs.startIO();
|
||||
String selflineTable=generateSelfLineTable();
|
||||
if(selflineTable!=null&&!selflineTable.equals(""))
|
||||
krs.sendPacket(new ADDLINESPacket(selflineTable));
|
||||
lineslock.writeLock().lock();
|
||||
try {
|
||||
lines.add(krs);
|
||||
}finally {
|
||||
lineslock.writeLock().unlock();
|
||||
@@ -502,16 +530,12 @@ public class KLALBController {
|
||||
}
|
||||
return sbd.toString();
|
||||
}
|
||||
|
||||
public KLALBController(Inet6Address self) {
|
||||
this.self =new Inet6AddressGroup(self, PREFIX);
|
||||
loadSRv6ProtocolStack();
|
||||
}
|
||||
|
||||
private class KLALBProtocolPacketConsumer implements PacketConsumer{
|
||||
|
||||
@Override
|
||||
public void accept(IPv6Packet packx) throws IOException {
|
||||
HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
//HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
|
||||
/*System.out.println("RCV:"+packx.getPayload().getData());
|
||||
byte[]b=new byte[packx.getPayload().getData().limit()];
|
||||
@@ -539,18 +563,18 @@ public class KLALBController {
|
||||
}
|
||||
}
|
||||
}
|
||||
packx.dispose();
|
||||
});
|
||||
//packx.dispose();
|
||||
//});
|
||||
}
|
||||
|
||||
}
|
||||
private void loadSRv6ProtocolStack() {
|
||||
srv6Router=new SRv6Router(self);
|
||||
private void loadSRv6ProtocolStack(Inet6AddressGroup selfx,boolean enableVirtualAdapter) {
|
||||
srv6Router=new SRv6Router(selfx);
|
||||
if(enableVirtualAdapter)
|
||||
try {
|
||||
IPv6TUNLoopbackNetworkLink tunlink=new IPv6TUNLoopbackNetworkLink(new Inet6AddressGroup( srv6Router.getLocator().getAddress(),32),SRv6Router.MTU);
|
||||
IPv6TUNLoopbackNetworkLink tunlink=new IPv6TUNLoopbackNetworkLink(new Inet6AddressGroup( srv6Router.getLocator().getAddress(),32),SRv6Router.MTU, dnsAddresses);
|
||||
tunlink.setMonitor(datatMonitor);
|
||||
srv6Router.getLinkTabel().add(tunlink);
|
||||
Thread.sleep(100);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -558,8 +582,19 @@ public class KLALBController {
|
||||
srv6Router.getProtocolNumberRegister().put(KLALBPacket.KLALB_PROTOCOL_NUMBER,new KLALBProtocolPacketConsumer());
|
||||
System.out.println("SRv6协议栈已加载");
|
||||
}
|
||||
|
||||
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);
|
||||
loadSRv6ProtocolStack(selfg,enableVirtualAdapter);
|
||||
}
|
||||
public KLALBController(boolean enableVirtualAdapter,List<InetAddress> dnsaddr) {
|
||||
this.dnsAddresses=dnsaddr;
|
||||
SecureRandom sc=new SecureRandom();
|
||||
byte[]v=new byte[16];
|
||||
sc.nextBytes(v);
|
||||
@@ -569,27 +604,31 @@ public class KLALBController {
|
||||
v[3]=1;
|
||||
v[14]=0;
|
||||
v[15]=1;
|
||||
Inet6AddressGroup selfx=null;
|
||||
try {
|
||||
this.self=new Inet6AddressGroup( (Inet6Address) InetAddress.getByAddress(v),PREFIX);
|
||||
selfx=new Inet6AddressGroup( (Inet6Address) InetAddress.getByAddress(v),PREFIX);
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
loadSRv6ProtocolStack();
|
||||
loadSRv6ProtocolStack(selfx,enableVirtualAdapter);
|
||||
}
|
||||
|
||||
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 createVirtualImpl() {
|
||||
return new KLALBVirtualSocketImpl(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected void sendPacketToLinkAddress(Inet6Address addr, KLALBPacket packet)
|
||||
throws IOException {
|
||||
sendPacketToLinkAddress(addr, packet, 1);
|
||||
}
|
||||
|
||||
private SRv6Router srv6Router;
|
||||
|
||||
|
||||
@@ -603,7 +642,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Map<Inet6Address,DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 =new ConcurrentHashMap<>();
|
||||
//Map<Inet6Address,DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 =new ConcurrentHashMap<>();
|
||||
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
||||
if(klalbRemoteLine.isClosed()) {
|
||||
@@ -615,20 +654,20 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
}
|
||||
}else {
|
||||
if(klalbRemoteLine.getRemoteVaddr()!=null&&klalbRemoteLine.getMonitor().getState()==MonitorData.ONLINE) {
|
||||
if(lines2.containsKey(klalbRemoteLine.getRemoteVaddr())) {
|
||||
/* if(lines2.containsKey(klalbRemoteLine.getRemoteVaddr())) {
|
||||
lines2.get(klalbRemoteLine.getRemoteVaddr()).getEntries().add(klalbRemoteLine);
|
||||
}else {
|
||||
ArrayList<KLALBRemoteLine>al1=new ArrayList<>();
|
||||
al1.add(klalbRemoteLine);
|
||||
lines2.put(klalbRemoteLine.getRemoteVaddr().getAddress(), new DWRRLoadingBalanceAlgorithm<>(al1));
|
||||
}
|
||||
}*/
|
||||
if(!srv6Router.getLinkTabel().contains(klalbRemoteLine)) {
|
||||
srv6Router.getLinkTabel().add(klalbRemoteLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Iterator<Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
|
||||
/*for (Iterator<Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> klalbRemoteLine = (Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>) iterator.next();
|
||||
List<KLALBRemoteLine> lineList=klalbRemoteLine.getValue().getEntries();
|
||||
lineList.forEach((r)->{
|
||||
@@ -641,7 +680,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
}
|
||||
|
||||
}
|
||||
KLALBController.this.lines2=lines2;
|
||||
KLALBController.this.lines2=lines2;*/
|
||||
if(srv6Router!=null) {
|
||||
srv6Router.getLinkTabel().removeIf((v)->{
|
||||
return (v instanceof KLALBRemoteLine)&&(!v.isUp());
|
||||
@@ -649,7 +688,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
srv6Router.updateRouteTabel();
|
||||
}
|
||||
}
|
||||
}, 1, 1);
|
||||
}, 2, 2);
|
||||
}
|
||||
/*private void updateLines2(Inet6Address addr) throws SocketTimeoutException {
|
||||
List<KLALBRemoteLine> l=new ArrayList();
|
||||
@@ -675,122 +714,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
lines2.put(addr, l);
|
||||
}
|
||||
}*/
|
||||
private Map<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
protected void sendPacketToLinkAddress(Inet6Address addr, KLALBPacket packet, int count)
|
||||
throws IOException {
|
||||
if(packet==null)
|
||||
throw new NullPointerException("packet is null!");
|
||||
//TimeDebugger tdb=new TimeDebugger();
|
||||
|
||||
|
||||
//tdb.putTime("start");
|
||||
packet.genseq();
|
||||
/*loop:while(true) {
|
||||
if(packet.isDisposed())
|
||||
return;
|
||||
List<KLALBRemoteLine> lines2x;
|
||||
|
||||
lines2x=lines2.get(addr);
|
||||
|
||||
if (lines2x == null || lines2x.isEmpty()) {
|
||||
throw new NoRouteToHostException("address unreachable: " + addr);
|
||||
}
|
||||
|
||||
int count0 = Math.min(count, lines2x.size());
|
||||
|
||||
for (int i = 0; i < lines2x.size(); i++) {
|
||||
KLALBRemoteLine krst =lines2x.get(i);
|
||||
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||
if(!packet.getSendRecord().contains(krst)) {
|
||||
if(krst.getQueue().size()<10) {
|
||||
packet.getSendRecord().add(krst);
|
||||
//System.out.println(krst);
|
||||
krst.sendPacket(packet);
|
||||
count0--;
|
||||
if (count0 <= 0)
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < lines2x.size(); i++) {
|
||||
KLALBRemoteLine krst =lines2x.get(i);
|
||||
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||
if(packet.getSendRecord().contains(krst)) {
|
||||
if(krst.getQueue().size()<10) {
|
||||
packet.getSendRecord().add(krst);
|
||||
//System.out.println(krst);
|
||||
krst.sendPacket(packet);
|
||||
count0--;
|
||||
if (count0 <= 0)
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
LockSupport.parkNanos(50000);
|
||||
//tdb.putTime("sendfailed");
|
||||
}*/
|
||||
//tdb.putTime("sendsuccess");
|
||||
//tdb.print();
|
||||
|
||||
/* List<KLALBRemoteLine> lines2x;
|
||||
lines2x=lines2.get(addr);
|
||||
|
||||
if (lines2x == null || lines2x.isEmpty()) {
|
||||
throw new NoRouteToHostException("address unreachable: " + addr);
|
||||
}
|
||||
KLALBRemoteLine kr= lines2x.get(0);
|
||||
kr.sendPacket(packet);
|
||||
packet.getSendRecord().add(kr);*/
|
||||
|
||||
/*loop:while(true) {
|
||||
if(packet.isDisposed())
|
||||
return;
|
||||
DWRRLoadingBalanceAlgorithm<KLALBRemoteLine> dwrlines2x;
|
||||
|
||||
dwrlines2x=lines2.get(addr);
|
||||
|
||||
if (dwrlines2x == null || dwrlines2x.getEntries().isEmpty()) {
|
||||
throw new NoRouteToHostException("address unreachable: " + addr);
|
||||
}
|
||||
|
||||
List<KLALBRemoteLine>lines2x=dwrlines2x.roundEntriesList();
|
||||
|
||||
int count0 = Math.min(count, lines2x.size());
|
||||
|
||||
for (int i = 0; i < lines2x.size(); i++) {
|
||||
KLALBRemoteLine krst =lines2x.get(i);
|
||||
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||
if(!packet.getSendRecord().contains(krst)) {
|
||||
if(krst.getQueue().size()<5) {
|
||||
packet.getSendRecord().add(krst);
|
||||
//System.out.println(krst);
|
||||
krst.sendPacket(packet);
|
||||
count0--;
|
||||
if (count0 <= 0)
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < lines2x.size(); i++) {
|
||||
KLALBRemoteLine krst =lines2x.get(i);
|
||||
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||
if(packet.getSendRecord().contains(krst)) {
|
||||
if(krst.getQueue().size()<5) {
|
||||
packet.getSendRecord().add(krst);
|
||||
//System.out.println(krst);
|
||||
krst.sendPacket(packet);
|
||||
count0--;
|
||||
if (count0 <= 0)
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
LockSupport.parkNanos(50000);
|
||||
//tdb.putTime("sendfailed");
|
||||
}*/
|
||||
}
|
||||
//private Map<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
|
||||
@@ -804,11 +728,8 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
|
||||
IPv6Packet ipv=new IPv6Packet();
|
||||
packet.getDisposeLock().lock();
|
||||
try {
|
||||
if(packet.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(showpacket)
|
||||
System.out.println("KLALB_TX:"+packet);
|
||||
|
||||
@@ -816,10 +737,15 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
ipv.setTrafficClass(0);
|
||||
ipv.setFlowLabel(flowlabel);
|
||||
ipv.setHopLimit(255);
|
||||
ipv.setSourceAddress(self.getAddress());
|
||||
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);
|
||||
//System.out.println(ipv.getPayload().getProtocolNumber());
|
||||
/*System.out.println("SND:"+ipv.getPayload().getData());
|
||||
@@ -828,13 +754,12 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
System.out.println(Arrays.toString(b));*/
|
||||
//packet.getSendRecord().add(null);
|
||||
packet.incSendCounter();
|
||||
}finally {
|
||||
packet.getDisposeLock().unlock();
|
||||
}
|
||||
|
||||
packet.putTimePassport("packedInIPv6");
|
||||
packet.printPassport();
|
||||
ipv.putTimePassport("packed");
|
||||
srv6Router.putProtocolNumberPacketAndInsertSRH(ipv);
|
||||
srv6Router.insertSRHandRoutePacket(ipv);
|
||||
//srv6Router.putProtocolNumberPacketAndInsertSRHAsync(ipv);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -869,7 +794,11 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
try {
|
||||
BandwidthDistributer<PortPair> bdr= bandwidthDistrmap.get(targetaAddress);
|
||||
if(bdr==null) {
|
||||
bandwidthDistrmap.put(targetaAddress, bdr=new BandwidthDistributer<>(1024*20000L*1024));
|
||||
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);
|
||||
@@ -920,7 +849,6 @@ private List<MultipurposeSocketAddress> listens=new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*@Override
|
||||
public void listen(MultipurposeSocketAddress msa) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
@@ -8,10 +8,18 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StreamCorruptedException;
|
||||
import java.net.Inet6Address;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class KLALBInputStream extends DataInputStream {
|
||||
private ReadableByteChannel channel;
|
||||
public KLALBInputStream(InputStream in) throws IOException {
|
||||
super(in);
|
||||
channel=Channels.newChannel(in);
|
||||
byte[]b=new byte[5];
|
||||
readFully(b);
|
||||
String s=new String(b,"ascii");
|
||||
@@ -23,8 +31,16 @@ public class KLALBInputStream extends DataInputStream {
|
||||
if(bv!=CONST.bversion)
|
||||
throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V"+CONST.klalbver);
|
||||
}
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
int len=readInt();
|
||||
return KLALBPacket.readKLALBPacketFromStream(this);
|
||||
}
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
int len=readInt();
|
||||
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(len);
|
||||
bbf.limit(len);
|
||||
KNEChannels.readFully(channel, bbf);
|
||||
return bbf;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.kne.cloud.network.ipv6.RouteItem;
|
||||
import org.kne.cloud.network.klalb.ui.KLALBStateGUI2;
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
import org.kne.cloud.network.perf.Kperf;
|
||||
import org.kne.cloud.network.perf.MemcpyBenchmark;
|
||||
import org.kne.cloud.network.perf.NodeBenchmark;
|
||||
import org.kne.debug.Debuger;
|
||||
|
||||
public class KLALBMain {
|
||||
@@ -37,7 +39,7 @@ public class KLALBMain {
|
||||
|
||||
KLALBProxySystem kpcje=new KLALBProxySystem();
|
||||
kpcje.loadConfigJson(configJson);
|
||||
System.out.println("SRv6地址:"+kpcje.getKlalbController().getSelf().getHostAddress());
|
||||
System.out.println("SRv6地址:"+kpcje.getKlalbController().getSelf().getAddress().getHostAddress());
|
||||
try {
|
||||
openGUI(kpcje);
|
||||
}catch(RuntimeException e) {
|
||||
@@ -152,10 +154,40 @@ public class KLALBMain {
|
||||
System.out.println("请输入测速服务端地址:端口!");
|
||||
}
|
||||
|
||||
break;
|
||||
case "memcpy":
|
||||
System.out.println("数组拷贝测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark. testArrayCopySpeed(256*1024*1024);
|
||||
}
|
||||
System.out.println("Bytebuffer拷贝测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark.testByteBufferCopySpeed(256*1024*1024);
|
||||
}
|
||||
System.out.println("Directbytebuffer分配测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark.testDirectByteBufferAllocateSpeed(65536);
|
||||
}
|
||||
System.out.println("Bytebuffer分配测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark.testByteBufferAllocateSpeed(65536);
|
||||
}
|
||||
System.out.println("BytebufferAllocator分配测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark.testByteBufferAllocatorSpeed(65536);
|
||||
}
|
||||
break;
|
||||
//case "$$SYSTEM:":
|
||||
//System.out.println();
|
||||
//break;
|
||||
case "nodebenchmark":
|
||||
int nodenumber=100;
|
||||
if(sc.length>=2) {
|
||||
nodenumber=Integer.parseInt(sc[1]);
|
||||
}
|
||||
NodeBenchmark nbc=new NodeBenchmark(kpcje.getKlalbController(),nodenumber);
|
||||
nbc.startPerfing();
|
||||
break;
|
||||
default:
|
||||
System.out.println("未知命令,请输入help以查询命令说明");
|
||||
}
|
||||
|
||||
@@ -4,19 +4,29 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Inet6Address;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
public class KLALBOutputStream extends DataOutputStream {
|
||||
|
||||
private WritableByteChannel channel;
|
||||
public KLALBOutputStream(OutputStream out) throws IOException {
|
||||
super(out);
|
||||
this.channel=Channels.newChannel(out);
|
||||
byte[]b=new byte[] {'K','L','A','L','B'};
|
||||
write(b);
|
||||
writeInt(CONST.bversion);
|
||||
writeInt(CONST.sversion);
|
||||
flush();
|
||||
}
|
||||
public void writePacket(KLALBPacket klb) throws IOException {
|
||||
public void writeKLALBPacket(KLALBPacket klb) throws IOException {
|
||||
writeInt((int) klb.getLength());
|
||||
KLALBPacket.writeKLALBPacketToStream(this, klb);
|
||||
}
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
writeInt( kp.limit());
|
||||
channel.write(kp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.StreamCorruptedException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
@@ -15,6 +16,8 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.kne.cloud.network.perf.TEST1Packet;
|
||||
import org.kne.cloud.network.perf.TESTNPacket;
|
||||
|
||||
public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
public static final int KLALB_PROTOCOL_NUMBER=254;
|
||||
@@ -32,12 +35,13 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
public static final int VADDR=8;
|
||||
public static final int ADDLINES=9;
|
||||
public static final int NACKT=10;
|
||||
public static final int TEST=11;
|
||||
public static final int TESTN=11;
|
||||
public static final int VADDRACK=12;
|
||||
public static final int VADDRREQ=13;
|
||||
public static final int IPV6OVERKLALB=14;
|
||||
public static final int ADDR=15;
|
||||
public static final int ADDRREQ=16;
|
||||
public static final int TEST1=17;
|
||||
|
||||
//private static final int HEADER_CAPACITY = 32;
|
||||
|
||||
@@ -45,7 +49,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
|
||||
//public static final ByteArrayPool dataarraypool=new ByteArrayPool(5000, 8192);
|
||||
|
||||
protected volatile ByteBuffer klalbHeader;
|
||||
protected ByteBuffer klalbHeader;
|
||||
|
||||
protected KLALBPacket(ByteBuffer klalbHeader,int headerLength) {
|
||||
super(KLALB_PROTOCOL_NUMBER,false);
|
||||
@@ -55,7 +59,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
|
||||
public KLALBPacket(int type,int headerLength) {
|
||||
super(KLALB_PROTOCOL_NUMBER,false);
|
||||
klalbHeader=ByteBuffer.allocate(headerLength);
|
||||
klalbHeader=NetworkPacket.bufferAllocator.allocate(headerLength);
|
||||
klalbHeader.put((byte) type);
|
||||
this.headerLength=headerLength;
|
||||
}
|
||||
@@ -83,7 +87,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
return joinqueuetime;
|
||||
}
|
||||
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
sndtime=System.nanoTime();
|
||||
dto.write(klalbHeader.slice(0, headerLength));
|
||||
}
|
||||
@@ -93,7 +97,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
klalbHeader.limit(headerLength);
|
||||
while(klalbHeader.hasRemaining()){
|
||||
if(din.read(klalbHeader)==-1) {
|
||||
@@ -135,13 +139,6 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
return klalbHeader;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/* ByteBuffer datax=klalbHeader;
|
||||
klalbHeader=null;
|
||||
if(datax!=null)
|
||||
KLALBPacket.databufferpool_40.back(datax);*/
|
||||
}
|
||||
|
||||
public static KLALBPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
|
||||
return readKLALBPacketFromChannel(Channels.newChannel(in));
|
||||
@@ -149,14 +146,14 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
|
||||
public static KLALBPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException {
|
||||
while(true) {
|
||||
ByteBuffer bb=databufferpool_40.borrow();
|
||||
ByteBuffer bb=NetworkPacket.bufferAllocator.allocate(40);
|
||||
bb.limit(1);
|
||||
while(bb.hasRemaining()){
|
||||
if(in.read(bb)==-1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
int type=bb.get(0);
|
||||
int type=bb.get(0)&0xff;
|
||||
bb.limit(bb.capacity());
|
||||
|
||||
KLALBPacket klp;
|
||||
@@ -196,8 +193,8 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
klp=new NACKTPacket(bb);
|
||||
klp.readFromChannel(in);
|
||||
return klp;
|
||||
case TEST:
|
||||
klp=new TESTPacket(bb);
|
||||
case TESTN:
|
||||
klp=new TESTNPacket(bb);
|
||||
klp.readFromChannel(in);
|
||||
return klp;
|
||||
case VADDRACK:
|
||||
@@ -220,9 +217,13 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
klp=new ADDRREQPacket(bb);
|
||||
klp.readFromChannel(in);
|
||||
return klp;
|
||||
case TEST1:
|
||||
klp=new TEST1Packet(bb);
|
||||
klp.readFromChannel(in);
|
||||
return klp;
|
||||
}
|
||||
//throw new StreamCorruptedException("unknown package type:"+type);
|
||||
System.err.println("ignore unknown KLALBPacket type:"+type);
|
||||
throw new StreamCorruptedException("unknown package type:"+type);
|
||||
//System.err.println("ignore unknown KLALBPacket type:"+type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,10 +238,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void doDisposeAfterSend() {
|
||||
if(isDisposeAfterSend())
|
||||
dispose();
|
||||
}
|
||||
|
||||
private boolean ce=false;
|
||||
public void setCE(boolean ce) {
|
||||
this.ce=ce;
|
||||
|
||||
@@ -2,13 +2,26 @@ package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
|
||||
public interface KLALBPacketLink {
|
||||
public void writePacket(KLALBPacket kp) throws IOException;
|
||||
public void setOutputTrafficCounters(AtomicLong[] al);
|
||||
public void setOutputPacketsCounters(AtomicLong[] al);
|
||||
public void setInputTrafficCounters(AtomicLong[] al);
|
||||
public void setInputPacketsCounters(AtomicLong[] al);
|
||||
public void writePacket(ByteBuffer kp) throws IOException;
|
||||
public default void writePackets(ByteBuffer[] kpp,int off,int len) throws IOException {
|
||||
for (int i = 0; i < len; i++) {
|
||||
writePacket(kpp[off+i]);
|
||||
}
|
||||
}
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException;
|
||||
public void flush() throws IOException;
|
||||
public KLALBPacket readPacket()throws IOException;
|
||||
public KLALBPacket readKLALBPacket()throws IOException;
|
||||
public ByteBuffer readPacket()throws IOException;
|
||||
public void close() throws IOException;
|
||||
public boolean isClosed();
|
||||
public void setSoTimeout(int val) throws SocketException;
|
||||
|
||||
@@ -11,11 +11,13 @@ import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@@ -112,15 +114,43 @@ public class KLALBProxySystem {
|
||||
case "KLALBController":
|
||||
JsonElement vase= entry.get("VirtualAddress");
|
||||
//System.out.println(vase);
|
||||
List<InetAddress>daddr=new ArrayList<InetAddress>();
|
||||
JsonElement vdns= entry.get("DNS");
|
||||
if(vdns!=null) {
|
||||
if(vdns instanceof JsonArray) {
|
||||
JsonArray arr=(JsonArray) vdns;
|
||||
for(JsonElement str:arr) {
|
||||
try {
|
||||
daddr.add((Inet6Address) InetAddress.getByName(str.getAsString()));
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}else {
|
||||
try {
|
||||
daddr.add((Inet6Address) InetAddress.getByName(vdns.getAsString()));
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(vase!=null) {
|
||||
try {
|
||||
klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString()));
|
||||
klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString()),daddr);
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}else {
|
||||
klalbController=new KLALBController();
|
||||
klalbController=new KLALBController(daddr);
|
||||
}
|
||||
|
||||
|
||||
JsonElement vasn= entry.get("VirtualASN");
|
||||
if(vasn!=null) {
|
||||
klalbController.getIpv6Router().setASN (Long.parseLong( vasn.getAsString()));
|
||||
}
|
||||
|
||||
|
||||
JsonElement vsne=entry.get("VirtualSocketName");
|
||||
//if(vsne!=null) {
|
||||
MultipurposeSocketAddress.getSocketTypeRegister().put(vsne.getAsString(), klalbController.getSocketType());
|
||||
@@ -280,7 +310,7 @@ public class KLALBProxySystem {
|
||||
if(string.startsWith("SocketBridge")) {
|
||||
return new DefaultSocketBridgeFactory();
|
||||
}else if(string.startsWith("MinecraftSocketBridge")) {
|
||||
return new DefaultMinecraftSocketBridgeFactory(klalbController.getSelf(), Integer.parseInt(string.substring(21)));
|
||||
return new DefaultMinecraftSocketBridgeFactory(klalbController.getSelf().getAddress(), Integer.parseInt(string.substring(21)));
|
||||
}
|
||||
throw new IllegalArgumentException("unknown SocketBridge type:"+string);
|
||||
}
|
||||
|
||||
@@ -5,42 +5,69 @@ import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.StreamCorruptedException;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.UnresolvedAddressException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.kne.cloud.clock.AdjustedNanoClock;
|
||||
import org.kne.cloud.clock.ReliabilityBackoffTimeClock;
|
||||
import org.kne.cloud.network.ByteBufferAllocator;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.SpeedLimiter;
|
||||
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.IPv6EmptyPayload;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.ipv6.Neighbor;
|
||||
import org.kne.cloud.network.ipv6.RouteItem;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.NanoTimeSeries;
|
||||
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||
import org.kne.cloud.network.perf.TESTNPacket;
|
||||
import org.kne.cloud.network.srv6.ACKSEQSSegmentRoutingTLV;
|
||||
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
|
||||
import org.kne.cloud.network.srv6.SEQSSegmentRoutingTLV;
|
||||
import org.kne.cloud.network.te.BandwidthDistributer;
|
||||
import org.kne.cloud.network.te.LoadingBalanceEntry;
|
||||
import org.kne.concurrent.DisruptorExecutor;
|
||||
import org.kne.concurrent.HighPerformanceExecutor;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteLine> ,LoadingBalanceEntry<KLALBRemoteLine>{
|
||||
|
||||
public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteLine> {
|
||||
|
||||
private static final int HEADER_CALIBRATE = 40;
|
||||
|
||||
private static final boolean debug = false;
|
||||
|
||||
private static final boolean showpacket = false;
|
||||
@@ -221,10 +248,19 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}
|
||||
|
||||
private static long MIN_SPEED=256*1024L;
|
||||
private SpeedLimiter congress = new SpeedLimiter(MIN_SPEED,10000000L);
|
||||
private SpeedLimiter congress = new SpeedLimiter(MIN_SPEED,20*1000000L);//50*1000000L
|
||||
private long congressSpeed = 0;
|
||||
private double loadPercent = 1.01;
|
||||
private double burstPercent = 1.3;//10.0
|
||||
private double windowPercent = 2;
|
||||
|
||||
private long MIN_RTTVAR=25000000L;
|
||||
|
||||
|
||||
private AtomicBoolean firstUpdate=new AtomicBoolean(true);
|
||||
private volatile long RTTMin=1000000000L;
|
||||
private volatile long RTTVar=1000000000L;
|
||||
private volatile long RTTAvg=1000000000L;
|
||||
private volatile long RTO=1000000000L;
|
||||
protected void startIO() {
|
||||
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
|
||||
//Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
|
||||
@@ -251,87 +287,153 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
addressGroup=new Inet6AddressGroup(i6a, 112);
|
||||
}
|
||||
} else {
|
||||
kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress);
|
||||
kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress,false);
|
||||
}
|
||||
//startRecord();
|
||||
|
||||
if (klalbController != null) {
|
||||
|
||||
kplink.setInputTrafficCounters(new AtomicLong[] {monitor.getInTrafficAL(),klalbController.getLinkMonitor().getInTrafficAL()});
|
||||
kplink.setOutputTrafficCounters(new AtomicLong[] {monitor.getOutTrafficAL(),klalbController.getLinkMonitor().getOutTrafficAL()});
|
||||
kplink.setInputPacketsCounters(new AtomicLong[] {monitor.getInPacketCounterAL(),klalbController.getLinkMonitor().getInPacketCounterAL()});
|
||||
kplink.setOutputPacketsCounters(new AtomicLong[] {monitor.getOutPacketCounterAL(),klalbController.getLinkMonitor().getOutPacketCounterAL()});
|
||||
} else {
|
||||
kplink.setInputTrafficCounters(new AtomicLong[] {monitor.getInTrafficAL()});
|
||||
kplink.setOutputTrafficCounters(new AtomicLong[] {monitor.getOutTrafficAL()});
|
||||
kplink.setInputPacketsCounters(new AtomicLong[] {monitor.getInPacketCounterAL()});
|
||||
kplink.setOutputPacketsCounters(new AtomicLong[] {monitor.getOutPacketCounterAL()});
|
||||
}
|
||||
kplink.setSoTimeout(20000);
|
||||
if(kplink.isStream()) {
|
||||
windowPercent=1.4;
|
||||
MIN_RTTVAR=50000000;
|
||||
burstPercent=2.0;//1.5
|
||||
//ackInterval=10000000L;
|
||||
}else {
|
||||
windowPercent=1.2;
|
||||
MIN_RTTVAR=20000000;
|
||||
burstPercent=2.0;
|
||||
//ackInterval=1000000L;
|
||||
}
|
||||
Thread timer = ThreadTool.makeVDaemonThread("重路由计时器线程", () -> {
|
||||
Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
|
||||
while((!kplink.isClosed()) && (!closed)) {
|
||||
|
||||
Collection<SendItem>vals= sendMap.values();
|
||||
for (Iterator<SendItem> iterator = vals.iterator(); iterator.hasNext();) {
|
||||
SendItem sitm = (SendItem) iterator.next();
|
||||
if(System.nanoTime() -sitm.getSendtime()>RTO) {
|
||||
iterator.remove();
|
||||
sendmapWindowUsed.addAndGet((int) -(sitm.getPacket().getPayload().getLength()+HEADER_CALIBRATE));
|
||||
//if(!kplink.isStream())
|
||||
if(sitm.getPacket().isPromise()) {
|
||||
IPv6Packet pktr=sitm.getPacket();
|
||||
pktr.setPriority(pktr.getPriority()-1);
|
||||
rerouteConsumer.accept(pktr);
|
||||
}
|
||||
//System.out.println("reroute");
|
||||
}
|
||||
}
|
||||
for (Iterator<Entry<UUID, Long>> iterator = recvedUIDMap.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<UUID, Long> sendItem = (Entry<UUID, Long>) iterator.next();
|
||||
if(System.nanoTime()-sendItem.getValue()>10000000000L) {
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
}
|
||||
if(checkACKTime()) {
|
||||
sendALLIPv6ACK();
|
||||
//System.out.println("ACK发送");
|
||||
}
|
||||
try {
|
||||
Thread.sleep(4);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
timer.start();
|
||||
|
||||
Thread t = ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> {
|
||||
tlock = Thread.currentThread();
|
||||
//tlock.setPriority(Thread.NORM_PRIORITY+1);
|
||||
try {
|
||||
writePacketToKPL(new ADDRREQPacket());
|
||||
writePacketToKPL(new ADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new ADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new ADDRREQPacket());
|
||||
if(addressGroup!=null) {
|
||||
writePacketToKPL(new ADDRPacket(addressGroup));
|
||||
writePacketToKPL(new ADDRPacket(addressGroup));
|
||||
writeKLALBPacketToKPL(new ADDRPacket(addressGroup));
|
||||
writeKLALBPacketToKPL(new ADDRPacket(addressGroup));
|
||||
}
|
||||
writePacketToKPL(new VADDRREQPacket());
|
||||
writePacketToKPL(new VADDRREQPacket());
|
||||
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||
writeKLALBPacketToKPL(new VADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new VADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||
writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||
flushKPL();
|
||||
KLALBPacket kpp = null;
|
||||
ByteBuffer[] kpp = null;
|
||||
int kppslen=0;
|
||||
while ((!kplink.isClosed()) && (!closed)) {
|
||||
// TimeDebugger tdb=new TimeDebugger();
|
||||
// tdb.putTime("start");
|
||||
if(checkBandwidthReportTime()) {
|
||||
sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg2(), monitor.getInSpeedAvg2()));
|
||||
sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg(), monitor.getInSpeedAvg()));
|
||||
}
|
||||
if (checkPingTimeSleep()) {
|
||||
writePacketToKPL(new PINGPacket(System.nanoTime()));
|
||||
writeKLALBPacketToKPL(new PINGPacket(System.nanoTime()));
|
||||
if (remoteVaddr == null)
|
||||
writePacketToKPL(new VADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new VADDRREQPacket());
|
||||
if(peerAddress==null)
|
||||
writePacketToKPL(new ADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new ADDRREQPacket());
|
||||
|
||||
}else {
|
||||
KLALBPacket kpip = IsendDequeList.poll();
|
||||
if (kpip != null) {
|
||||
writePacketToKPL(kpip);
|
||||
writeKLALBPacketToKPL(kpip);
|
||||
|
||||
}else {
|
||||
|
||||
// tdb.putTime("Isend");
|
||||
|
||||
if (kpp == null) {
|
||||
do {
|
||||
kpp = sendDequeList.poll();
|
||||
} while (kpp != null && kpp.isDisposed());
|
||||
if(kpp==null) {
|
||||
ByteBuffer tkpp = sendDequeList.poll();
|
||||
if(tkpp==null) {
|
||||
monitor.setQueueingDelay(0);
|
||||
}else {
|
||||
kpp=new ByteBuffer[10];
|
||||
kpp[0]=tkpp;
|
||||
int i=1;
|
||||
for(;i<kpp.length;i++) {
|
||||
ByteBuffer xkpp=sendDequeList.poll();
|
||||
if(xkpp==null)
|
||||
break;
|
||||
kpp[i]=xkpp;
|
||||
}
|
||||
kppslen=i;
|
||||
}
|
||||
}
|
||||
// System.out.println(sendDequeList.size());
|
||||
if (kpp != null) {
|
||||
// TimeDebugger tdb=new TimeDebugger();
|
||||
//tdb.putTime("start");
|
||||
KLALBPacket kppt=kpp;
|
||||
kppt.lockAll();
|
||||
try {
|
||||
if (kpp.isSomeDisposed()) {
|
||||
kpp = null;
|
||||
} else {
|
||||
|
||||
|
||||
// if (congress.checkTransmit(length)) {
|
||||
|
||||
writePacketToKPL(kpp);
|
||||
kplink.writePackets(kpp,0,kppslen);
|
||||
if (checkPingTime()) {
|
||||
writePacketToKPL(new PINGPacket(System.nanoTime()));
|
||||
writeKLALBPacketToKPL(new PINGPacket(System.nanoTime()));
|
||||
}
|
||||
monitor.setQueueingDelay( System.nanoTime()- kpp.getJoinqueuetime());
|
||||
//monitor.setQueueingDelay( System.nanoTime()- kpp.getJoinqueuetime());
|
||||
/*if (kpp instanceof DATATPacket||kpp instanceof IPv6OverKLALBPacket) {
|
||||
resetSleepTimer();
|
||||
}*/
|
||||
kpp.doDisposeAfterSend();
|
||||
kpp = null;
|
||||
}
|
||||
|
||||
//}
|
||||
} finally {
|
||||
kppt.unlockAll();
|
||||
}
|
||||
|
||||
//tdb.putTime("sendToLink");
|
||||
//tdb.print();
|
||||
}else {
|
||||
LockSupport.parkNanos(1000000);
|
||||
LockSupport.parkNanos(10000000L);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,6 +460,8 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
// System.out.println(sendDequeList.isEmpty());
|
||||
Thread.yield();
|
||||
}
|
||||
}catch(StreamCorruptedException sce) {
|
||||
sce.printStackTrace();
|
||||
} catch (IOException | UnresolvedAddressException e) {
|
||||
if (debug)
|
||||
e.printStackTrace();
|
||||
@@ -370,28 +474,26 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
boolean fst = true;
|
||||
AtomicBoolean fst = new AtomicBoolean(true);
|
||||
long stime = 5000000000L;
|
||||
while ((!kplink.isClosed()) && (!closed)) {
|
||||
long readStart = System.nanoTime();
|
||||
KLALBPacket kpp = readPacketFromKPL();
|
||||
/*long readTime = System.nanoTime() - readStart;
|
||||
readTime *= 10;
|
||||
if (readTime > stime) {
|
||||
stime = readTime;
|
||||
} else {
|
||||
stime = (stime * 999 + readTime) / 1000;
|
||||
}
|
||||
if (stime < 2000000000L) {
|
||||
stime = 2000000000L;
|
||||
}*/
|
||||
|
||||
// System.out.println(readTime);
|
||||
ByteBuffer kppb = kplink.readPacket();
|
||||
|
||||
kplink.setSoTimeout(3000);
|
||||
kplink.setSoTimeout((int) (stime / 1000000));
|
||||
if (kpp == null) {
|
||||
if (kppb == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
KLALBPacket kpp=null;
|
||||
try {
|
||||
kpp = KLALBPacket.readKLALBPacketFromChannel(KNEChannels.newReadableChannel(kppb));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(kpp==null)
|
||||
return;
|
||||
debugShowPacket("RX",kpp);
|
||||
switch (kpp.getType()) {
|
||||
case KLALBPacket.PING:
|
||||
sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime()));
|
||||
@@ -404,29 +506,30 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
long DrcvDelayFactor0 = png.getRcvtime() - png.getTimepongsnd();
|
||||
long DsndDelayFactor;
|
||||
long DrcvDelayFactor;
|
||||
|
||||
adjnc.getLock().lock();
|
||||
|
||||
AdjustedNanoClock adjc=adjnc;
|
||||
adjc.getLock().lock();
|
||||
try {
|
||||
adjnc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||
adjc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
|
||||
if (DsndDelayFactor < 0) {
|
||||
if (DrcvDelayFactor < 0) {
|
||||
|
||||
} else {
|
||||
adjnc.setDelta(adjnc.getDelta() + DsndDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||
adjc.setDelta(adjc.getDelta() + DsndDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
|
||||
}
|
||||
} else {
|
||||
if (DrcvDelayFactor < 0) {
|
||||
adjnc.setDelta(adjnc.getDelta() - DrcvDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||
adjc.setDelta(adjc.getDelta() - DrcvDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
adjnc.getLock().unlock();
|
||||
adjc.getLock().unlock();
|
||||
}
|
||||
|
||||
if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) {
|
||||
@@ -436,7 +539,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
//pingInterval = monitor.getLatencyAvg()+2000000L;
|
||||
|
||||
//double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay();
|
||||
loadPercent =Math.max( 1.2,0.4);
|
||||
//loadPercent =Math.max( 1.3,0.4);
|
||||
}
|
||||
|
||||
LockSupport.unpark(tlock);
|
||||
@@ -446,9 +549,12 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
if (bwi.getDownSpeed() >= congressSpeed) {
|
||||
congressSpeed = bwi.getDownSpeed();
|
||||
} else {
|
||||
congressSpeed = (congressSpeed * 999 + bwi.getDownSpeed()) / 1000;
|
||||
congressSpeed = (congressSpeed * 199 + bwi.getDownSpeed()) / 200;
|
||||
}
|
||||
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) );
|
||||
bandwidthDistributer.setTotalBandwidth (congressSpeed );
|
||||
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * burstPercent)) );
|
||||
//reallimit=(int) (congress.getLimitspeed()*monitor.getLatencyMin()/1000000000L);
|
||||
reallimit=(int) (Math.max(MIN_SPEED,(long) (congressSpeed*windowPercent ))*Math.max(2000000L,RTTMin)/1000000000L);
|
||||
// System.out.println(congressSpeed);
|
||||
break;
|
||||
case KLALBPacket.ADDRREQ:
|
||||
@@ -460,7 +566,13 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
if(addressGroup==null) {
|
||||
byte[]ab=peerAddress.getAddress().getAddress();
|
||||
ab[15]=2;
|
||||
Inet6AddressGroup ardg2=new Inet6AddressGroup((Inet6Address) InetAddress.getByAddress(ab),peerAddress.getPrefixLength());
|
||||
Inet6AddressGroup ardg2=null;
|
||||
try {
|
||||
ardg2 = new Inet6AddressGroup((Inet6Address) InetAddress.getByAddress(ab),peerAddress.getPrefixLength());
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(ardg2!=null)
|
||||
addressGroup=ardg2;
|
||||
}
|
||||
break;
|
||||
@@ -475,39 +587,124 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
if (klalbController != null) {
|
||||
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress());
|
||||
}
|
||||
if (fst) {
|
||||
if (fst.compareAndSet(true, false)) {
|
||||
// coll.resetCoolingTime();
|
||||
monitor.setState(MonitorData.ONLINE);
|
||||
fst = false;
|
||||
}
|
||||
break;
|
||||
case KLALBPacket.VADDRACK:
|
||||
break;
|
||||
case KLALBPacket.TEST:
|
||||
case KLALBPacket.TESTN:
|
||||
break;
|
||||
case KLALBPacket.IPV6OVERKLALB:
|
||||
if(ipv6con!=null) {
|
||||
|
||||
IPv6OverKLALBPacket ivk=(IPv6OverKLALBPacket) kpp;
|
||||
IPv6Packet iv6= ivk.getIPv6Packet();
|
||||
ivk.putTimePassport("unpacked");
|
||||
ivk.printPassport();
|
||||
iv6.putTimePassport("unpackFromLink");
|
||||
|
||||
IPSequence val=null;
|
||||
IPv6SegmentRoutingHeader srh= iv6.getSRHHeader();
|
||||
if(srh!=null) {
|
||||
List<IPv6SegmentRoutingTLV> l=srh.getTlvs();
|
||||
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
IPv6SegmentRoutingTLV tlv=l.get(i);
|
||||
if(tlv instanceof SEQSSegmentRoutingTLV) {
|
||||
SEQSSegmentRoutingTLV seqs=(SEQSSegmentRoutingTLV) tlv;
|
||||
// if(seqs.isPromise()) {
|
||||
val=new IPSequence(seqs.getUUID(),seqs.isPromise());
|
||||
//}
|
||||
|
||||
}else if(tlv instanceof ACKSEQSSegmentRoutingTLV) {
|
||||
ACKSEQSSegmentRoutingTLV aseq=(ACKSEQSSegmentRoutingTLV) tlv;
|
||||
l.remove(i);
|
||||
i--;
|
||||
|
||||
SendItem ipv6;
|
||||
if((ipv6=sendMap.remove(aseq.getIPSequence()))!=null) {
|
||||
sendmapWindowUsed.addAndGet((int) -(ipv6.getPacket().getPayload().getLength()+HEADER_CALIBRATE));
|
||||
long RTTC=System.nanoTime()-ipv6.getSendtime();
|
||||
if(RTTC<=RTTMin) {
|
||||
RTTMin=RTTC;
|
||||
}else {
|
||||
RTTMin= (RTTMin*99999+RTTC)/100000;
|
||||
}
|
||||
if(firstUpdate.compareAndSet(true, false)) {
|
||||
RTTAvg=RTTC;
|
||||
RTTVar=RTTC/2;
|
||||
|
||||
}else {
|
||||
RTTVar=(RTTVar*3+Math.abs(RTTAvg-RTTC))/4;
|
||||
RTTAvg= (RTTAvg*7+RTTC)/8;
|
||||
}
|
||||
RTO=RTTAvg+Math.max(MIN_RTTVAR, RTTVar*4);//RTTVar*4
|
||||
//System.out.println("remove:"+aseq.getSequence()+" "+sendMap.size());
|
||||
}else {
|
||||
// System.out.println("miss:"+aseq.getSequence()+" "+sendMap.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(val!=null)
|
||||
ackIDs.add(val);
|
||||
/*if(val!=null&&peerAddress!=null) {
|
||||
UUID val2=val;
|
||||
HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
IPv6Packet ipv=new IPv6Packet();
|
||||
ipv.setVersion(6);
|
||||
ipv.setTrafficClass(0);
|
||||
ipv.setFlowLabel(0);
|
||||
ipv.setHopLimit(255);
|
||||
ipv.setSourceAddress(addressGroup.getAddress());
|
||||
ipv.setDestinationAddress(peerAddress.getAddress());
|
||||
ipv.setPriority(0);
|
||||
ipv.enableECN();
|
||||
IPv6SegmentRoutingHeader srh2=new IPv6SegmentRoutingHeader();
|
||||
srh2.getAddresses().add(peerAddress.getAddress());
|
||||
|
||||
srh2.getTlvs().add(new ACKSEQSSegmentRoutingTLV(val2,true));
|
||||
|
||||
ipv.getHeaders().add(srh2);
|
||||
ipv.setPayload(new IPv6EmptyPayload());
|
||||
|
||||
sendIPacket(new IPv6OverKLALBPacket( ipv));
|
||||
//System.out.println("ack:"+val);
|
||||
});
|
||||
}*/
|
||||
|
||||
if(ipv6con!=null) {
|
||||
if(iv6.getPayload()instanceof IPv6EmptyPayload) {
|
||||
//iv6.dispose();
|
||||
}else {
|
||||
if(val!=null) {
|
||||
Long l=recvedUIDMap.putIfAbsent(val.getUuid(), System.nanoTime());
|
||||
if(l==null) {
|
||||
ipv6con.accept(iv6);
|
||||
}else {
|
||||
//System.out.println("虚假重传:"+val.getUuid());
|
||||
}
|
||||
}else {
|
||||
ipv6con.accept(iv6);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
while (rec == null) {
|
||||
Thread.sleep(1);
|
||||
}
|
||||
if(rec!=null)
|
||||
rec.accept( kpp);
|
||||
break;
|
||||
}
|
||||
});
|
||||
Thread.yield();
|
||||
}
|
||||
}catch(StreamCorruptedException sce) {
|
||||
sce.printStackTrace();
|
||||
} catch (IOException | UnresolvedAddressException e) {
|
||||
if (debug)
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
}catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
monitor.setState(MonitorData.OFFLINE);
|
||||
@@ -518,17 +715,14 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
/*KLALBPacket pack;
|
||||
while((pack=sendDequeList.poll())!=null) {
|
||||
try {
|
||||
if(remoteVaddr!=null) {
|
||||
klalbController.sendPacketToLinkAddress(remoteVaddr, pack);
|
||||
if(debug)
|
||||
System.out.println("RETRY:"+pack);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Collection<SendItem>vals= sendMap.values();
|
||||
SendItem[]packs= vals.toArray(new SendItem[0]);
|
||||
for (SendItem iPv6Packet : packs) {
|
||||
rerouteConsumer.accept(iPv6Packet.getPacket());
|
||||
//System.out.println("重路由:"+iPv6Packet);
|
||||
}
|
||||
}*/
|
||||
sendMap.clear();
|
||||
sendmapWindowUsed.set(0);
|
||||
}
|
||||
|
||||
if (closed) {
|
||||
@@ -544,63 +738,98 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}).start();
|
||||
|
||||
}
|
||||
private ConcurrentLinkedQueue<IPSequence> ackIDs=new ConcurrentLinkedQueue<>();
|
||||
private volatile long prevAckTime=System.nanoTime();
|
||||
private volatile long ackInterval=1000000L;
|
||||
private boolean checkACKTime() {
|
||||
long cu = System.nanoTime();
|
||||
if (cu - prevAckTime > ackInterval) {
|
||||
prevAckTime = cu;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private void sendALLIPv6ACK() {
|
||||
if(peerAddress!=null) {
|
||||
while(true) {
|
||||
int rez=sendIPv6ACK();
|
||||
if(rez<=0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private int sendIPv6ACK() {
|
||||
IPv6SegmentRoutingHeader srh2=new IPv6SegmentRoutingHeader();
|
||||
int adds=addACKSEQToSRH(srh2,40);
|
||||
if(adds<=0)
|
||||
return adds;
|
||||
|
||||
//System.out.println(adds+"ACKS");
|
||||
|
||||
IPv6Packet ipv=new IPv6Packet();
|
||||
ipv.setVersion(6);
|
||||
ipv.setTrafficClass(0);
|
||||
ipv.setFlowLabel(0);
|
||||
ipv.setHopLimit(255);
|
||||
ipv.setSourceAddress(addressGroup.getAddress());
|
||||
ipv.setDestinationAddress(peerAddress.getAddress());
|
||||
ipv.setPriority(0);
|
||||
ipv.enableECN();
|
||||
srh2.getAddresses().add(peerAddress.getAddress());
|
||||
|
||||
|
||||
ipv.getHeaders().add(srh2);
|
||||
ipv.setPayload(new IPv6EmptyPayload());
|
||||
|
||||
sendIPacket(new IPv6OverKLALBPacket( ipv));
|
||||
//System.out.println("ack:"+val);
|
||||
return adds;
|
||||
}
|
||||
|
||||
private int addACKSEQToSRH(IPv6SegmentRoutingHeader srh,int maxAckCount){
|
||||
int i = 0;
|
||||
for (; i < maxAckCount; i++) {
|
||||
|
||||
IPSequence ackid= ackIDs.poll();
|
||||
if(ackid!=null) {
|
||||
srh.getTlvs().add(new ACKSEQSSegmentRoutingTLV(ackid, ackid.isPromise()));
|
||||
}else {
|
||||
prevAckTime=System.nanoTime();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
private void flushKPL() throws IOException {
|
||||
kplink.flush();
|
||||
}
|
||||
|
||||
private KLALBPacket readPacketFromKPL() throws IOException {
|
||||
KLALBPacket packet = kplink.readPacket();
|
||||
if (showpacket) {
|
||||
if (!(packet instanceof PINGPacket))
|
||||
if (!(packet instanceof PONGPacket))
|
||||
if (!(packet instanceof BWINFPacket))
|
||||
System.out.println("RX:" + packet);
|
||||
}
|
||||
private KLALBPacket readKLALBPacketFromKPL() throws IOException {
|
||||
KLALBPacket packet = kplink.readKLALBPacket();
|
||||
debugShowPacket("RX",packet);
|
||||
if (packet != null) {
|
||||
packet.putTimePassport("received");
|
||||
long length=packet.getLength();
|
||||
monitor.getInTrafficAL().addAndGet(length);
|
||||
monitor.getInPacketCounterAL().incrementAndGet();
|
||||
if (klalbController != null)
|
||||
klalbController.getLinkMonitor().getInTrafficAL().addAndGet(length);
|
||||
klalbController.getLinkMonitor().getInPacketCounterAL().incrementAndGet();
|
||||
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
private void writePacketToKPL(KLALBPacket packet) throws IOException {
|
||||
long length=packet.getLength();
|
||||
monitor.getOutTrafficAL().addAndGet(length);
|
||||
monitor.getOutPacketCounterAL().incrementAndGet();
|
||||
if (klalbController != null)
|
||||
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
|
||||
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
|
||||
kplink.writePacket(packet);
|
||||
private void writeKLALBPacketToKPL(KLALBPacket packet) throws IOException {
|
||||
kplink.writeKLALBPacket(packet);
|
||||
packet.putTimePassport("sended");
|
||||
packet.printPassport();
|
||||
|
||||
if (showpacket) {
|
||||
if (!(packet instanceof PINGPacket))
|
||||
if (!(packet instanceof PONGPacket))
|
||||
if (!(packet instanceof BWINFPacket))
|
||||
System.err.println("TX:" + packet);
|
||||
}
|
||||
debugShowPacket("TX",packet);
|
||||
}
|
||||
|
||||
private void writePacketToKPL(KLALBPacket packet,long length) throws IOException {
|
||||
monitor.getOutTrafficAL().addAndGet(length);
|
||||
monitor.getOutPacketCounterAL().incrementAndGet();
|
||||
if (klalbController != null)
|
||||
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
|
||||
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
|
||||
kplink.writePacket(packet);
|
||||
|
||||
private void debugShowPacket(String label, KLALBPacket packet) {
|
||||
if (showpacket) {
|
||||
if (!(packet instanceof PINGPacket))
|
||||
if (!(packet instanceof PONGPacket))
|
||||
if (!(packet instanceof BWINFPacket))
|
||||
System.err.println("TX:" + packet);
|
||||
System.err.println(label+":" + packet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,7 +851,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
|
||||
private volatile long time = System.nanoTime();
|
||||
private volatile long pingInterval = 10000000L;
|
||||
private volatile long pingIntervalSleep = 200000000L;
|
||||
private volatile long pingIntervalSleep = 500000000L;
|
||||
|
||||
private boolean checkPingTime() {
|
||||
long cu = System.nanoTime();
|
||||
@@ -649,7 +878,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
|
||||
private volatile long bwtime = System.nanoTime();
|
||||
private volatile long bwpingInterval = 10000000L;
|
||||
private volatile long bwpingIntervalSleep = 100000000L;
|
||||
private volatile long bwpingIntervalSleep = 200000000L;
|
||||
private boolean checkBandwidthReportTime(){
|
||||
long cu = System.nanoTime();
|
||||
if (cu - bwtime > bwpingIntervalSleep) {
|
||||
@@ -667,16 +896,25 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
|
||||
private ConcurrentLinkedQueue<KLALBPacket> IsendDequeList = new ConcurrentLinkedQueue<KLALBPacket>();
|
||||
|
||||
private PriorityBlockingQueue<KLALBPacket> sendDequeList = new PriorityBlockingQueue<KLALBPacket>();
|
||||
private PriorityBlockingQueue<ByteBuffer> sendDequeList = new PriorityBlockingQueue<ByteBuffer>();
|
||||
|
||||
public PriorityBlockingQueue<KLALBPacket> getQueue() {
|
||||
public PriorityBlockingQueue<ByteBuffer> getQueue() {
|
||||
return sendDequeList;
|
||||
}
|
||||
|
||||
protected void sendPacket(KLALBPacket blk) {
|
||||
debugShowPacket("TX",blk);
|
||||
blk.markJoinqueuetime();
|
||||
sendDequeList.add(blk);
|
||||
ByteBuffer buf=NetworkPacket.bufferAllocator.allocate((int) blk.getLength());
|
||||
try {
|
||||
KLALBPacket.writeKLALBPacketToChannel(KNEChannels.newWritableChannel(buf), blk);
|
||||
buf.flip();
|
||||
sendDequeList.add(buf);
|
||||
LockSupport.unpark(tlock);
|
||||
} catch (IOException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendIPacket(KLALBPacket blk) {
|
||||
@@ -688,21 +926,8 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
this.rec = rec;
|
||||
}
|
||||
|
||||
/*public void remoeFromSendQueue(KLALBPacket klalbPacket) {
|
||||
sendDequeList.remove(klalbPacket);
|
||||
}*/
|
||||
|
||||
public long statLengthBefore(long l) {
|
||||
AtomicLong al = new AtomicLong();
|
||||
for (Iterator<KLALBPacket> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
||||
KLALBPacket queue = iterator.next();
|
||||
if (queue.getPriority() <= l) {
|
||||
al.addAndGet(queue.getLength());
|
||||
}
|
||||
|
||||
}
|
||||
return al.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private volatile long predictTime;
|
||||
|
||||
@@ -744,7 +969,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}
|
||||
}
|
||||
|
||||
private static final TESTPacket testPacket = new TESTPacket(60000);
|
||||
private static final TESTNPacket testPacket = new TESTNPacket(60000);
|
||||
private volatile boolean pressure = false;
|
||||
private SpeedLimiter pressureSpeed = new SpeedLimiter(32768);
|
||||
|
||||
@@ -774,46 +999,21 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
return predictTime;
|
||||
}
|
||||
|
||||
private List<Double>ranks=new ArrayList<Double>();
|
||||
|
||||
private Consumer<IPv6Packet> ipv6con;
|
||||
@Override
|
||||
public void noticeRank(int rank) {
|
||||
while(rank>=ranks.size()) {
|
||||
ranks.add(0.5);
|
||||
}
|
||||
for (int i = 0; i < ranks.size(); i++) {
|
||||
if(i==rank) {
|
||||
ranks.set(i, (ranks.get(i)*99.0+1.0D)/100.0);
|
||||
}else {
|
||||
ranks.set(i, ranks.get(i)*99.0/100.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWeightAtRank(int rank) {
|
||||
while(rank>=ranks.size()) {
|
||||
ranks.add(0.5);
|
||||
}
|
||||
return ranks.get(rank);
|
||||
}
|
||||
|
||||
public List<Double> getRanks() {
|
||||
|
||||
return ranks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoopBack() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private BandwidthDistributer<Inet6Address> bandwidthDistributer=new BandwidthDistributer<Inet6Address>();
|
||||
|
||||
@Override
|
||||
public List<Neighbor> getNeighborsInfo() {
|
||||
List<Neighbor>hs=new ArrayList<>();
|
||||
if(peerAddress!=null) {
|
||||
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor));
|
||||
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor,bandwidthDistributer));
|
||||
//System.out.println(peerAddress+" "+addressGroup);
|
||||
}
|
||||
return hs;
|
||||
@@ -821,26 +1021,77 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
|
||||
|
||||
|
||||
private Map<IPSequence,SendItem> sendMap= new ConcurrentHashMap<>();
|
||||
private AtomicInteger sendmapWindowUsed=new AtomicInteger(0);
|
||||
private Map<UUID,Long>recvedUIDMap=new ConcurrentHashMap<UUID, Long>();
|
||||
|
||||
private volatile int inputchachesize = 8192 * 4000;
|
||||
private volatile int outputchachesize = 8192 * 240;//500
|
||||
private volatile int reallimit = 65536 ;
|
||||
|
||||
private Consumer<IPv6Packet> rerouteConsumer;
|
||||
|
||||
@Override
|
||||
public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException {
|
||||
pack.lockAll();
|
||||
try {
|
||||
if(pack.isSomeDisposed()) {
|
||||
return;
|
||||
//只有已连接的链路才能传输数据
|
||||
if(monitor.getState()==MonitorData.ONLINE) {
|
||||
|
||||
//if(inet6Address.equals(remoteVaddr.getAddress())||inet6Address.equals(peerAddress.getAddress())) {
|
||||
|
||||
//获得数据包的SRv6扩展头部
|
||||
IPv6SegmentRoutingHeader srh= pack.getSRHHeader();
|
||||
|
||||
IPSequence val=null;
|
||||
if(srh!=null) {
|
||||
List<IPv6SegmentRoutingTLV> l=srh.getTlvs();
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
IPv6SegmentRoutingTLV tlv=l.get(i);
|
||||
if(tlv instanceof SEQSSegmentRoutingTLV) {
|
||||
SEQSSegmentRoutingTLV seqs=(SEQSSegmentRoutingTLV) tlv;
|
||||
//if(seqs.isPromise())
|
||||
//获得数据包的序号
|
||||
val=new IPSequence(seqs.getUUID(),seqs.isPromise());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(val!=null) {
|
||||
//放入滑动窗口中并记录缓冲区大小占用
|
||||
SendItem old= sendMap.put(val,new SendItem( pack));
|
||||
if(old!=null) {
|
||||
sendmapWindowUsed.addAndGet((int) -(old.getPacket().getPayload().getLength()+HEADER_CALIBRATE));
|
||||
}
|
||||
sendmapWindowUsed.addAndGet((int) (pack.getPayload().getLength()+HEADER_CALIBRATE));
|
||||
//System.out.println("add: "+ val+" "+sendMap.size());
|
||||
}
|
||||
}
|
||||
//捎带发送反方向的ACK给对方发送过来的数据包,减小设备性能开销
|
||||
if(srh!=null) {
|
||||
addACKSEQToSRH(srh,10);
|
||||
}
|
||||
//发送数据包
|
||||
sendIPv6PacketToLink(pack);
|
||||
//}
|
||||
|
||||
}else {
|
||||
if(rerouteConsumer!=null) {
|
||||
rerouteConsumer.accept(pack);
|
||||
}
|
||||
}
|
||||
if(inet6Address.equals(remoteVaddr.getAddress())||inet6Address.equals(peerAddress.getAddress())) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer) {
|
||||
this.rerouteConsumer=rerouteConsumer;
|
||||
}
|
||||
|
||||
private void sendIPv6PacketToLink(IPv6Packet pack) {
|
||||
IPv6OverKLALBPacket kipv6=new IPv6OverKLALBPacket(pack);
|
||||
kipv6.setPriority(pack.getPriority());
|
||||
kipv6.setDisposeAfterSend(true);
|
||||
pack.putTimePassport("packdInLink");
|
||||
pack.printPassport();
|
||||
sendPacketToLink(kipv6);
|
||||
}
|
||||
}finally {
|
||||
pack.unlockAll();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPacketToLink(KLALBPacket packet) {
|
||||
@@ -850,13 +1101,18 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCongress(IPv6Packet iPv6Packet) {
|
||||
int size=getQueue().size();
|
||||
if(size>30) {
|
||||
public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
|
||||
if(monitor.getInDelay()>3000000000L||monitor.getOutDelay()>3000000000L||monitor.getInSpeedAvg()<=0||monitor.getOutSpeedAvg()<=0)
|
||||
return true;
|
||||
}else {
|
||||
return !congress.checkTransmit(iPv6Packet.getLength());
|
||||
}
|
||||
boolean congress=sendmapWindowUsed.get()>reallimit*scale;
|
||||
return congress;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) {
|
||||
boolean xcongress=!congress.checkTransmit(iPv6Packet.getLength());
|
||||
return xcongress;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -879,6 +1135,30 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
this.ipv6con=ipv6con;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RouteItem> getRouteItems() {
|
||||
List<RouteItem> rlist=new ArrayList<>();
|
||||
|
||||
Inet6AddressGroup adg=addressGroup;
|
||||
if(adg!=null)
|
||||
rlist.add(new RouteItem(new Inet6AddressGroup(adg.getAddress(), 128),
|
||||
adg.getAddress(), this, "Direct", 0, 0, null, "D",true));
|
||||
|
||||
for (Iterator<Neighbor> iteratorx = getNeighborsInfo()
|
||||
.iterator(); iteratorx.hasNext();) {
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
RouteItem ri = new RouteItem(new Inet6AddressGroup(addresses.getAddress().getAddress(), 128), addresses.getAddress().getAddress(),
|
||||
this, "Direct", 0, 128, addresses.getMonitor(), "D",false);
|
||||
rlist.add(ri);
|
||||
|
||||
RouteItem ris = new RouteItem(addresses.getLocator(), (Inet6Address) addresses.getLocator().getAddress(),
|
||||
this, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D",false);
|
||||
rlist.add(ris);
|
||||
|
||||
}
|
||||
return rlist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
|
||||
@@ -135,8 +137,28 @@ public class KLALBUtils {
|
||||
Color col=new Color( r,g,0);
|
||||
return col;
|
||||
}
|
||||
public static Color getColorByLoadPercentagex(float f) {
|
||||
int r=0;
|
||||
int g=200;
|
||||
if(f<50f) {
|
||||
r+=f/50f*200f;
|
||||
}else {
|
||||
r=200;
|
||||
g-=(f-50f)/50f*200f;
|
||||
}
|
||||
if(r>200)
|
||||
r=200;
|
||||
if(r<0)
|
||||
r=0;
|
||||
if(g>200)
|
||||
g=200;
|
||||
if(g<0)
|
||||
g=0;
|
||||
Color col=new Color( r,g,0);
|
||||
return col;
|
||||
}
|
||||
|
||||
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress targetAddress)
|
||||
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress targetAddress,boolean buffered)
|
||||
throws IOException {
|
||||
if (targetAddress.isStream()) {
|
||||
if (targetAddress.supportNIO()) {
|
||||
@@ -164,14 +186,23 @@ public class KLALBUtils {
|
||||
}
|
||||
}
|
||||
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress,
|
||||
MultipurposeSocketAddress targetAddress, int timeout) throws UnknownHostException, IOException {
|
||||
MultipurposeSocketAddress targetAddress,boolean buffered, int timeout) throws UnknownHostException, IOException {
|
||||
if (targetAddress.isStream()) {
|
||||
if (targetAddress.supportNIO()) {
|
||||
if (bindAddress != null) {
|
||||
if(buffered) {
|
||||
return new StreamChannelKLALBPacketLink(targetAddress
|
||||
.connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout));
|
||||
}else {
|
||||
return new StreamChannelKLALBPacketLink(targetAddress
|
||||
.connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout));
|
||||
}
|
||||
} else {
|
||||
if(buffered) {
|
||||
return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout));
|
||||
}else {
|
||||
return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bindAddress != null) {
|
||||
@@ -190,7 +221,116 @@ public class KLALBUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final String IPv6Reg = "([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}$"
|
||||
+ "|^:((:[\\da-fA-F]{1,4}){1,6}|:)$"
|
||||
+ "|^[\\da-fA-F]{1,4}:((:[\\da-fA-F]{1,4}){1,5}|:)$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){2}((:[\\da-fA-F]{1,4}){1,4}|:)$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){3}((:[\\da-fA-F]{1,4}){1,3}|:)$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){4}((:[\\da-fA-F]{1,4}){1,2}|:)$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){5}:([\\da-fA-F]{1,4})?$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){6}:"; // IPv6地址的格式
|
||||
|
||||
/**
|
||||
* 将一个IPv6地址转为全写格式,全写中的前导0省略
|
||||
* 例:将1ade:03da:0::转为1ade:3da:0:0:0:0:0:0
|
||||
*
|
||||
* @param IPv6Str
|
||||
* @return fullIPv6
|
||||
*/
|
||||
public static String parseFullIPv6(String IPv6Str) {
|
||||
// 判断IPv6地址的格式是否正确
|
||||
if (!IPv6Str.matches(IPv6Reg)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String[] arr = new String[]{"0", "0", "0", "0", "0", "0", "0", "0"};
|
||||
|
||||
// 将IPv6地址用::分开
|
||||
// 如果IPv6地址为::,tempArr.length==0
|
||||
// 如果不包含::或以::结尾,tempArr.length==1
|
||||
// 如果以::开头或::在中间,tempArr.length==2
|
||||
String[] tempArr = IPv6Str.split("::");
|
||||
|
||||
// tempArr[0]用:分开,填充到arr前半部分
|
||||
if (tempArr.length > 0) {
|
||||
// new String[0]为空数组,因为"".split(":")为{""},如果tempArr[0]=="",此时数组包含一个元素
|
||||
String[] tempArr0 = tempArr[0].isEmpty() ? new String[0] : tempArr[0].split(":");
|
||||
for (int i = 0; i < tempArr0.length; i++) {
|
||||
// 如果是纯数字,用parseInt去除前导0,如果包含字母,用正则去除前导0
|
||||
arr[i] = tempArr0[i].matches("\\d+")
|
||||
? (Integer.parseInt(tempArr0[i]) + "")
|
||||
: tempArr0[i].replaceAll("^(0+)", "");
|
||||
}
|
||||
}
|
||||
|
||||
// tempArr[1]用:分开,填充到arr后半部分
|
||||
if (tempArr.length > 1) {
|
||||
String[] tempArr1 = tempArr[1].isEmpty() ? new String[0] : tempArr[1].split(":");
|
||||
for (int i = 0; i < tempArr1.length; i++) {
|
||||
arr[i + arr.length - tempArr1.length] = tempArr1[i].matches("\\d+")
|
||||
? (Integer.parseInt(tempArr1[i]) + "")
|
||||
: tempArr1[i].replaceAll("^(0+)", "");
|
||||
}
|
||||
}
|
||||
|
||||
return join(arr, ":");
|
||||
}
|
||||
|
||||
private static String join(String[] arr, String string) {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
sb.append(arr[i]);
|
||||
if(i+1<arr.length) {
|
||||
sb.append(string);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
/**
|
||||
* 将一个IPv6地址转为简写格式
|
||||
* 例:将1ade:03da:0::转为1ade:3da::
|
||||
*
|
||||
* @param IPv6Str
|
||||
* @return AbbrIPv6
|
||||
*/
|
||||
public static String parseAbbrIPv6(String IPv6Str) {
|
||||
// 将一个IPv6地址转为全写格式,全写中的前导0省略
|
||||
String fullIPv6 = parseFullIPv6(IPv6Str);
|
||||
if (fullIPv6.isEmpty()) { // 如果IPv6地址的格式不正确
|
||||
return "";
|
||||
}
|
||||
|
||||
// 将1ade:3da:0:0:0:0:0:99转为{"-","-","0","0","0","0","0","-"}
|
||||
String[] arr = fullIPv6.split(":");
|
||||
for (int i = 0, len = arr.length; i < len; i++) {
|
||||
if (!"0".equals(arr[i])) {
|
||||
arr[i] = "-";
|
||||
}
|
||||
}
|
||||
|
||||
// 找到最长的连续的0
|
||||
Pattern pattern = Pattern.compile("0{2,}");
|
||||
Matcher matcher = pattern.matcher(join(arr, ""));
|
||||
String maxStr = "";
|
||||
int start = -1;
|
||||
int end = -1;
|
||||
while (matcher.find()) {
|
||||
if (maxStr.length() < matcher.group().length()) {
|
||||
maxStr = matcher.group();
|
||||
start = matcher.start();
|
||||
end = matcher.end();
|
||||
}
|
||||
}
|
||||
|
||||
// 合并
|
||||
arr = fullIPv6.split(":");
|
||||
if (maxStr.length() > 0) {
|
||||
for (int i = start; i < end; i++) {
|
||||
arr[i] = ":";
|
||||
}
|
||||
}
|
||||
return join(arr, ":").replaceAll(":{2,}", "::");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.SocketException;
|
||||
|
||||
import org.kne.cloud.network.RawSocket;
|
||||
import org.kne.cloud.network.RawSocketImpl;
|
||||
import org.kne.cloud.network.VirtualRawSocket;
|
||||
import org.kne.cloud.network.srv6.SRv6Router;
|
||||
|
||||
public class KLALBVirtualRawSocket extends VirtualRawSocket {
|
||||
|
||||
public KLALBVirtualRawSocket(SRv6Router controller) {
|
||||
super(new KLALBVirtualRawSocketImpl(controller));
|
||||
}
|
||||
|
||||
public KLALBVirtualRawSocket(SRv6Router controller,Inet6Address bindAddress) throws SocketException {
|
||||
super(new KLALBVirtualRawSocketImpl(controller),bindAddress);
|
||||
}
|
||||
public KLALBVirtualRawSocket(SRv6Router controller,Inet6Address bindAddress,int bindProtocol) throws SocketException {
|
||||
super(new KLALBVirtualRawSocketImpl(controller),bindAddress,bindProtocol);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.BindException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import org.kne.cloud.network.ByteBufferAllocator;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.RawSocketImpl;
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.cloud.network.VirtualRawSocketImpl;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload;
|
||||
import org.kne.cloud.network.srv6.PacketConsumer;
|
||||
import org.kne.cloud.network.srv6.SRv6Router;
|
||||
import org.kne.concurrent.HighPerformanceExecutor;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements PacketConsumer{
|
||||
|
||||
private boolean ipHeaderInclude=false;
|
||||
|
||||
private SRv6Router router;
|
||||
|
||||
|
||||
protected volatile Inet6Address remoteaddr;
|
||||
protected volatile Inet6Address localaddr;
|
||||
|
||||
private int bindProtocolNumber;
|
||||
|
||||
private volatile int inputchachesize = 1024*1024;
|
||||
|
||||
protected SRv6Router getRouter() {
|
||||
return router;
|
||||
}
|
||||
|
||||
public KLALBVirtualRawSocketImpl(SRv6Router router) {
|
||||
super();
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOption(int optID, Object value) throws SocketException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOption(int optID) throws SocketException {
|
||||
// TODO 自动生成的方法存根
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setIPHeaderInclude(boolean ipHeaderInclude) throws IOException {
|
||||
this.ipHeaderInclude=ipHeaderInclude;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getIPHeaderInclude() throws IOException {
|
||||
return ipHeaderInclude;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUseSelectTimeout(boolean useSelect) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getUseSelectTimeout() throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSendTimeout(int timeout) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSendTimeout() throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setReceiveTimeout(int timeout) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getReceiveTimeout() throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close() {
|
||||
router.getProtocolNumberRegister().remove(bindProtocolNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bind(InetAddress address,int protocolNumber) throws SocketException{
|
||||
if(protocolNumber<0) {
|
||||
throw new UnsupportedOperationException("unsupprted bind all protocols");
|
||||
}
|
||||
try {
|
||||
if (address.equals(Inet4Address.getByName("0.0.0.0"))) {
|
||||
address = Inet6Address.getByName("::0");
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!(address instanceof Inet6Address)) {
|
||||
throw new IllegalArgumentException("invalid address type, KLALB socket can only use IPV6 address");
|
||||
}
|
||||
if ((!address.isAnyLocalAddress()) && (!address.equals(router.getLocator().getAddress()))) {
|
||||
throw new BindException("must bind to self");
|
||||
}
|
||||
|
||||
localaddr=(Inet6Address) address;
|
||||
this.bindProtocolNumber=protocolNumber;
|
||||
if(router.getProtocolNumberRegister().putIfAbsent(protocolNumber, this)!=null) {
|
||||
throw new BindException("protocol number already bind");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void join(InetAddress inetaddr) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void leave(InetAddress inetaddr) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void joinGroup(InetAddress mcastaddr, NetworkInterface netIf) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void leaveGroup(InetAddress mcastaddr, NetworkInterface netIf) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void send(DatagramPacket p) throws IOException {
|
||||
ByteBuffer buf= ByteBuffer.wrap(p.getData(), p.getOffset(), p.getLength());
|
||||
if(ipHeaderInclude) {
|
||||
|
||||
}else {
|
||||
HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||
IPv6Packet ipv=new IPv6Packet();
|
||||
ipv.setVersion(6);
|
||||
ipv.setTrafficClass(0);
|
||||
ipv.setFlowLabel(0);
|
||||
ipv.setHopLimit(255);
|
||||
ipv.setSourceAddress(router.getLocator().getAddress());
|
||||
InetAddress address= p.getAddress();
|
||||
if (!(address instanceof Inet6Address)) {
|
||||
throw new IllegalArgumentException("invalid address type, KLALB socket can only use IPV6 address");
|
||||
}
|
||||
ipv.setDestinationAddress((Inet6Address)address);
|
||||
ipv.setPriority(3);
|
||||
//ipv.enableECN();
|
||||
IPv6Payload pl=new IPv6Payload(bindProtocolNumber);
|
||||
pl.getData().put(buf);
|
||||
pl.getData().flip();
|
||||
ipv.setPayload(pl);
|
||||
router.insertSRHandRoutePacket(ipv);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InetAddress peek() throws IOException {
|
||||
return peekNextPacket().getSourceAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void peekData(DatagramPacket p) throws IOException {
|
||||
IPv6Packet pack=peekNextPacket();
|
||||
copyTo(pack, p);
|
||||
}
|
||||
|
||||
private void copyTo(IPv6Packet pack, DatagramPacket p) throws IOException {
|
||||
p.setAddress(pack.getSourceAddress());
|
||||
ByteBuffer buffer= ByteBuffer.wrap(p.getData(),p.getOffset(),p.getLength());
|
||||
if(ipHeaderInclude) {
|
||||
|
||||
}else {
|
||||
try {
|
||||
pack.getPayload().writeToChannel(KNEChannels.newWritableChannel(buffer));
|
||||
}catch(BufferOverflowException e) {
|
||||
|
||||
}
|
||||
}
|
||||
buffer.flip();
|
||||
p.setLength(buffer.limit());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void receive(DatagramPacket p) throws IOException {
|
||||
IPv6Packet pack=pollNextPacket();
|
||||
copyTo(pack, p);
|
||||
}
|
||||
private volatile Thread parkThread;
|
||||
private IPv6Packet peekNextPacket() {
|
||||
IPv6Packet pol=null;
|
||||
while(true) {
|
||||
pol=recvQueue.peek();
|
||||
if(pol!=null) {
|
||||
recvQueueUsed.addAndGet((int) -pol.getPayload().getLength());
|
||||
return pol;
|
||||
}
|
||||
parkThread=Thread.currentThread();
|
||||
LockSupport.parkNanos(1000000L);
|
||||
}
|
||||
}
|
||||
private IPv6Packet pollNextPacket() {
|
||||
IPv6Packet pol=null;
|
||||
while(true) {
|
||||
pol=recvQueue.poll();
|
||||
if(pol!=null) {
|
||||
recvQueueUsed.addAndGet((int) -pol.getPayload().getLength());
|
||||
return pol;
|
||||
}
|
||||
parkThread=Thread.currentThread();
|
||||
LockSupport.parkNanos(1000000L);
|
||||
}
|
||||
}
|
||||
private Queue<IPv6Packet> recvQueue = new ConcurrentLinkedQueue<IPv6Packet>();
|
||||
private AtomicInteger recvQueueUsed=new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public void accept(IPv6Packet packx) throws IOException {
|
||||
if(recvQueueUsed.get()<=inputchachesize) {
|
||||
if(recvQueue.offer(packx)) {
|
||||
recvQueueUsed.addAndGet((int) packx.getPayload().getLength());
|
||||
LockSupport.unpark(parkThread);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,16 +14,16 @@ public class KLALBVirtualSocket extends VirtualSocket {
|
||||
return (KLALBVirtualSocketImpl) super.getVirtualImpl();
|
||||
}
|
||||
|
||||
private KLALBController controler;
|
||||
private KLALBController controller;
|
||||
protected SocketChannel channel;
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler) throws SocketException {
|
||||
super(controler.createVirtualImpl());
|
||||
this.controler = controler;
|
||||
this.controller = controler;
|
||||
}
|
||||
|
||||
protected KLALBController getControler() {
|
||||
return controler;
|
||||
protected KLALBController getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler,String host, int port) throws UnknownHostException, IOException {
|
||||
|
||||
@@ -115,8 +115,7 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
|
||||
|
||||
@Override
|
||||
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return 0;
|
||||
return ((KVSIInputStream)socket.getInputStream()).read(dsts,offset,length);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,8 +125,7 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
|
||||
|
||||
@Override
|
||||
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return 0;
|
||||
return ((KVSIOutputStream)socket.getOutputStream()).write(srcs,offset,length);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,4 +149,10 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
|
||||
socket.associateSocketChannel(b);
|
||||
}
|
||||
|
||||
public boolean isAutoFlush() throws IOException {
|
||||
return ((KVSIOutputStream)socket.getOutputStream()).isAutoFlush();
|
||||
}
|
||||
public void setAutoFlush(boolean b) throws IOException {
|
||||
((KVSIOutputStream)socket.getOutputStream()).setAutoFlush(b);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,11 +34,11 @@ public class PortBinder {
|
||||
this.controller = controller;
|
||||
}
|
||||
private ReentrantReadWriteLock bindMaplock=new ReentrantReadWriteLock();
|
||||
private Map<InetSocketAddress,BindableKLALBPacketConsumer>bindMap=new ConcurrentHashMap<>();
|
||||
private Map<InetSocketAddress,BindableKLALBPacketConsumer>bindMap=new ConcurrentHashMap<>(65536*16);
|
||||
private ReentrantReadWriteLock listenMaplock=new ReentrantReadWriteLock();
|
||||
private Map<InetSocketAddress,BindableKLALBPacketConsumer>listenMap=new ConcurrentHashMap<>();
|
||||
private Map<InetSocketAddress,BindableKLALBPacketConsumer>listenMap=new ConcurrentHashMap<>(65536*16);
|
||||
private ReentrantReadWriteLock connectMaplock=new ReentrantReadWriteLock();
|
||||
private Map<Pair<InetSocketAddress,InetSocketAddress>,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>();
|
||||
private Map<Pair<InetSocketAddress,InetSocketAddress>,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>(65536*16);
|
||||
private volatile int portn=65535;
|
||||
public void bind(BindableKLALBPacketConsumer ks) throws BindException {
|
||||
bindMaplock.writeLock().lock();
|
||||
@@ -205,7 +205,7 @@ public class PortBinder {
|
||||
return b;
|
||||
}*/
|
||||
public boolean distributePacketToConsumer(Inet6Address srcAddr,PortPacket packet) {
|
||||
InetSocketAddress local=new InetSocketAddress(controller.getSelf(), packet.getDport());
|
||||
InetSocketAddress local=new InetSocketAddress(controller.getSelf().getAddress(), packet.getDport());
|
||||
InetSocketAddress remote=new InetSocketAddress(srcAddr, packet.getSport());
|
||||
BindableKLALBPacketConsumer bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(local, remote));
|
||||
if(bkc!=null) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
|
||||
public class SendItem {
|
||||
|
||||
private IPv6Packet packet;
|
||||
private long sendtime=System.nanoTime();
|
||||
|
||||
public SendItem(IPv6Packet packet) {
|
||||
this.packet=packet;
|
||||
}
|
||||
|
||||
public IPv6Packet getPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
public long getSendtime() {
|
||||
return sendtime;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -129,18 +129,20 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.DatagramServerSocket;
|
||||
import org.kne.cloud.network.DatagramServerSocket.SubDatagramSocket;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.PacketRebuilder;
|
||||
import org.kne.cloud.network.PacketSpliter;
|
||||
import org.kne.cloud.network.SpeedLimiter;
|
||||
import org.kne.debug.TimeDebugger;
|
||||
|
||||
public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
private PacketSpliter pslr=new PacketSpliter(65535);
|
||||
private PacketRebuilder pbdr=new PacketRebuilder(1000000000);
|
||||
public class SplitedDatagramKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
private PacketSpliter pslr;
|
||||
private PacketRebuilder pbdr;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@@ -151,13 +153,60 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
public SplitedDatagramKLALBPacketLink(DatagramSocket connectDatagramSocket) throws IOException {
|
||||
this.ds=connectDatagramSocket;
|
||||
bibf.limit(0);
|
||||
pslr=new PacketSpliter(new WritableByteChannel() {
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return !ds.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
int rem=src.remaining();
|
||||
byte[]bt=src.array();
|
||||
DatagramPacket dp=new DatagramPacket(bt,src.position(),src.limit());
|
||||
//System.out.println("SendDatagram:"+src.remaining());
|
||||
ds.send(dp);
|
||||
return rem;
|
||||
}
|
||||
},1350);
|
||||
pbdr=new PacketRebuilder(new ReadableByteChannel() {
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return !ds.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(ByteBuffer dst) throws IOException {DatagramPacket dp;
|
||||
if(ds instanceof SubDatagramSocket) {
|
||||
dp=((SubDatagramSocket) ds).receive();
|
||||
dst.put(dp.getData(), 0, dp.getLength());
|
||||
|
||||
}else {
|
||||
dp=new DatagramPacket(bc, bc.length);
|
||||
ds.receive(dp);
|
||||
dst.put(dp.getData(), 0, dp.getLength());
|
||||
}
|
||||
//System.out.println("RecvDatagram:"+dp.getLength());
|
||||
return dp.getLength();
|
||||
}
|
||||
},1000000000);
|
||||
|
||||
}
|
||||
|
||||
private ByteBuffer bbf=ByteBuffer.allocate(65535);
|
||||
//private ByteBuffer bbf=ByteBuffer.allocate(65535);
|
||||
|
||||
@Override
|
||||
public void writePacket(KLALBPacket kp) throws IOException {
|
||||
/*@Override
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
//System.out.println(" TX:"+kp);
|
||||
//KLALBPacket.writeKLALBPacketToStream(dos, kp);
|
||||
KLALBPacket.writeKLALBPacketToChannel(new WritableByteChannel() {
|
||||
@@ -184,47 +233,21 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
}
|
||||
|
||||
}, kp);
|
||||
}
|
||||
}*/
|
||||
|
||||
private byte[]bc=new byte[65535];
|
||||
|
||||
private ByteBuffer bibf=ByteBuffer.allocate(65535);
|
||||
//private ByteBuffer bibf=ByteBuffer.allocate(65535);
|
||||
|
||||
@Override
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
/*@Override
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
KLALBPacket kp=null;
|
||||
do {
|
||||
if(bibf.remaining()<=0) {
|
||||
bibf.clear();
|
||||
|
||||
/*DatagramPacket dp=new DatagramPacket(bc, bc.length);
|
||||
ds.receive(dp);
|
||||
bibf.put(dp.getData(), 0, dp.getLength());*/
|
||||
pbdr.read(bibf,new ReadableByteChannel() {
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(ByteBuffer dst) throws IOException {DatagramPacket dp;
|
||||
if(ds instanceof SubDatagramSocket) {
|
||||
dp=((SubDatagramSocket) ds).receive();
|
||||
dst.put(dp.getData(), 0, dp.getLength());
|
||||
|
||||
}else {
|
||||
dp=new DatagramPacket(bc, bc.length);
|
||||
ds.receive(dp);
|
||||
dst.put(dp.getData(), 0, dp.getLength());
|
||||
}
|
||||
return dp.getLength();
|
||||
}
|
||||
} );
|
||||
|
||||
pbdr.read(bibf );
|
||||
|
||||
bibf.flip();
|
||||
}
|
||||
@@ -259,7 +282,7 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
}while(true);
|
||||
return kp;
|
||||
}
|
||||
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
ds.close();
|
||||
@@ -280,7 +303,7 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
return ds.getSoTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
/*@Override
|
||||
public void flush() throws IOException {
|
||||
bbf.flip();
|
||||
//TimeDebugger tdb=new TimeDebugger();
|
||||
@@ -307,16 +330,34 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
});
|
||||
//tdb.putTime("flushEnd");
|
||||
//tdb.print();
|
||||
/*byte[]bt=bbf.array();
|
||||
DatagramPacket dp=new DatagramPacket(bt,bbf.limit());
|
||||
ds.send(dp);*/
|
||||
|
||||
bbf.clear();
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public boolean isStream() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
incOutput(kp.remaining());
|
||||
pslr.write(kp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(65535);
|
||||
pbdr.read(bbf );
|
||||
bbf.flip();
|
||||
incInput(bbf.remaining());
|
||||
return bbf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
@@ -19,14 +20,19 @@ import java.nio.channels.Channels;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.ByteBufferAllocator;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.cloud.network.TimeoutTimer;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
|
||||
public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
private volatile long timeoutTimer;
|
||||
private volatile boolean timerenabled=false;
|
||||
private Thread timeouter=new Thread() {
|
||||
private Runnable timeouter=new Runnable() {
|
||||
public void run() {
|
||||
timeoutTimer=System.nanoTime();
|
||||
while(connectSocket.isOpen()) {
|
||||
@@ -38,7 +44,7 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
Thread.sleep(5);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -59,29 +65,13 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
|
||||
public StreamChannelKLALBPacketLink(SocketChannel connectSocket) throws IOException {
|
||||
this.connectSocket=connectSocket;
|
||||
connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
|
||||
timeouter.start();
|
||||
ThreadTool.makeVDaemonThread("连接超时计时线程", timeouter);
|
||||
new KLALBOutputStream(Channels.newOutputStream(connectSocket));
|
||||
new KLALBInputStream(Channels.newInputStream(connectSocket));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writePacket(KLALBPacket kp) throws IOException {
|
||||
KLALBPacket.writeKLALBPacketToChannel(connectSocket, kp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
timeoutTimer=System.nanoTime();
|
||||
timerenabled=true;
|
||||
KLALBPacket res;
|
||||
try {
|
||||
res=KLALBPacket.readKLALBPacketFromChannel(connectSocket);
|
||||
}finally {
|
||||
timerenabled=false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
@@ -113,5 +103,136 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
|
||||
public boolean isStream() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeWrite.limit(4);
|
||||
//szeWrite.clear();
|
||||
incOutput(kp.limit());
|
||||
szeWrite.putInt(kp.limit());
|
||||
szeWrite.flip();
|
||||
KLALBVirtualSocketChannel obj = null;
|
||||
connectSocket.write(new ByteBuffer[] {szeWrite,kp});
|
||||
/*
|
||||
if(connectSocket instanceof KLALBVirtualSocketChannel) {
|
||||
obj=(KLALBVirtualSocketChannel) connectSocket;
|
||||
}
|
||||
boolean isaflush=false;
|
||||
if(obj!=null) {
|
||||
isaflush=obj.isAutoFlush();
|
||||
obj.setAutoFlush(false);
|
||||
}
|
||||
|
||||
//connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,false);
|
||||
connectSocket.write(szeWrite);
|
||||
|
||||
//connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
|
||||
if(obj!=null) {
|
||||
obj.setAutoFlush(true);
|
||||
}
|
||||
connectSocket.write(kp);
|
||||
if(obj!=null) {
|
||||
obj.setAutoFlush(isaflush);
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void writePackets(ByteBuffer[] kpp,int off,int len) throws IOException {
|
||||
ByteBuffer[] bbfw=new ByteBuffer[len<<1];
|
||||
for(int i=0;i<len;i++) {
|
||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeWrite.limit(4);
|
||||
//szeWrite.clear();
|
||||
incOutput(kpp[off+i].limit());
|
||||
szeWrite.putInt(kpp[off+i].limit());
|
||||
szeWrite.flip();
|
||||
KLALBVirtualSocketChannel obj = null;
|
||||
bbfw[i*2]=szeWrite;
|
||||
bbfw[i*2+1]=kpp[i];
|
||||
}
|
||||
connectSocket.write(bbfw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
timeoutTimer=System.nanoTime();
|
||||
timerenabled=true;
|
||||
ByteBuffer kp;
|
||||
|
||||
ByteBuffer szeRead=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeRead.limit(4);
|
||||
//szeRead.clear();
|
||||
try {
|
||||
KNEChannels.readFully(connectSocket,szeRead);
|
||||
szeRead.flip();
|
||||
int size=szeRead.getInt(0);
|
||||
kp=NetworkPacket.bufferAllocator.allocate(size);
|
||||
incInput(size);
|
||||
kp.limit(size);
|
||||
KNEChannels.readFully(connectSocket, kp);
|
||||
kp.flip();
|
||||
return kp;
|
||||
}finally {
|
||||
timerenabled=false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* @Override
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeWrite.limit(4);
|
||||
//szeWrite.clear();
|
||||
int length=(int) kp.getLength();
|
||||
incOutput(length);
|
||||
szeWrite.putInt(length);
|
||||
szeWrite.flip();
|
||||
KLALBVirtualSocketChannel obj = null;
|
||||
if(connectSocket instanceof KLALBVirtualSocketChannel) {
|
||||
obj=(KLALBVirtualSocketChannel) connectSocket;
|
||||
}
|
||||
boolean isaflush=false;
|
||||
if(obj!=null) {
|
||||
isaflush=obj.isAutoFlush();
|
||||
obj.setAutoFlush(false);
|
||||
}
|
||||
|
||||
connectSocket.write(szeWrite);
|
||||
|
||||
if(obj!=null) {
|
||||
obj.setAutoFlush(true);
|
||||
}
|
||||
KLALBPacket.writeKLALBPacketToChannel(connectSocket, kp);
|
||||
if(obj!=null) {
|
||||
obj.setAutoFlush(isaflush);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeWrite.limit(4);
|
||||
KNEChannels.readFully(connectSocket, szeWrite);
|
||||
szeWrite.flip();
|
||||
int readSize=szeWrite.getInt();
|
||||
incInput(readSize);
|
||||
return KLALBPacket.readKLALBPacketFromChannel(connectSocket);
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,10 +7,11 @@ import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
|
||||
public class StreamKLALBPacketLink implements KLALBPacketLink {
|
||||
public class StreamKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@@ -30,13 +31,13 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(KLALBPacket kp) throws IOException {
|
||||
out.writePacket(kp);
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
out.writeKLALBPacket(kp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
return in.readPacket();
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
return in.readKLALBPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,5 +69,15 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
|
||||
public boolean isStream() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
out.writePacket(kp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
return in.readPacket();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
|
||||
public class TESTPacket extends KLALBPacket {
|
||||
|
||||
private static final int HEADER_LENGTH=3;
|
||||
|
||||
private ByteBuffer dataBuffer;//=NetworkPacket.databufferpool_65535.borrow();
|
||||
@Override
|
||||
public long getLength() {
|
||||
return HEADER_LENGTH+dataBuffer.limit();
|
||||
}
|
||||
|
||||
|
||||
public TESTPacket(int limit) {
|
||||
super(TEST,HEADER_LENGTH);
|
||||
//dataBuffer.limit(limit);
|
||||
dataBuffer=ByteBuffer.allocate(limit);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ByteBuffer getDataBuffer() {
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
klalbHeader.putChar(1, (char) dataBuffer.limit());
|
||||
super.writeToChannel(dto);
|
||||
//System.out.println(dataBuffer);
|
||||
dto.write(dataBuffer.slice(0, dataBuffer.limit()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
super.readFromChannel(din);
|
||||
int limit=klalbHeader.getChar(1);
|
||||
//dataBuffer.clear();
|
||||
//dataBuffer.limit(limit);
|
||||
dataBuffer=ByteBuffer.allocate(limit);
|
||||
while(dataBuffer.hasRemaining()){
|
||||
if(din.read(dataBuffer)==-1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
dataBuffer.flip();
|
||||
}
|
||||
|
||||
public TESTPacket(ByteBuffer bb) {
|
||||
super(bb,HEADER_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TEST["+dataBuffer.limit()+"]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,512 @@
|
||||
package org.kne.cloud.network.klalb.ui;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.net.Inet6Address;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection;
|
||||
|
||||
public class GraphPanel extends JPanel {
|
||||
private Map<Inet6Address,GraphNode> nodes=new ConcurrentHashMap<Inet6Address,GraphNode>();
|
||||
private List<GraphEdgeGroup> edgeGroups=new ArrayList<GraphEdgeGroup>();
|
||||
|
||||
public Map<Inet6Address, GraphNode> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public List<GraphEdgeGroup> getEdgeGroups() {
|
||||
return edgeGroups;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private double borderGap=250;
|
||||
|
||||
private double translateX,translateY;
|
||||
|
||||
private double scale=1;
|
||||
|
||||
public double getTranslateX() {
|
||||
return translateX;
|
||||
}
|
||||
|
||||
public double getTranslateY() {
|
||||
return translateY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public double getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
public void setScale(double scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
|
||||
Graphics2D g2d=(Graphics2D)g;
|
||||
|
||||
recalcTranslate();
|
||||
g2d.scale(scale, scale);
|
||||
g2d.translate(translateX,translateY);
|
||||
double w=xmax-xmin;
|
||||
double h=ymax-ymin;
|
||||
if(w>=0&&h>=0) {
|
||||
g2d.drawRect((int)(xmin-borderGap), (int)(ymin-borderGap), (int)(w+borderGap*2), (int)(h+borderGap*2));
|
||||
}
|
||||
synchronized (edgeGroups) {
|
||||
|
||||
for( GraphEdgeGroup graphNode :edgeGroups) {
|
||||
graphNode.paint(g2d);
|
||||
}
|
||||
|
||||
}
|
||||
for(GraphNode graphNode :nodes.values()) {
|
||||
graphNode.paint(g2d);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public class GraphNode{
|
||||
private String text;
|
||||
private Color color;
|
||||
private double nodesize=40;
|
||||
private double x;
|
||||
private double y;
|
||||
private boolean ismarked;
|
||||
private Vector2 delta=new Vector2(0, 0);
|
||||
public GraphNode(String text, Color color, double x, double y,boolean ismarked) {
|
||||
super();
|
||||
this.text = text;
|
||||
this.color = color;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.ismarked=ismarked;
|
||||
}
|
||||
|
||||
public double getNodesize() {
|
||||
return nodesize;
|
||||
}
|
||||
|
||||
public void setNodesize(double nodesize) {
|
||||
this.nodesize = nodesize;
|
||||
}
|
||||
|
||||
public boolean isIsmarked() {
|
||||
return ismarked;
|
||||
}
|
||||
|
||||
public void setIsmarked(boolean ismarked) {
|
||||
this.ismarked = ismarked;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public GraphNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g) {
|
||||
g.setColor(Color.BLACK);
|
||||
g.setStroke(new BasicStroke(2.0f));
|
||||
g.drawOval((int)(x-nodesize/2), (int)(y-nodesize/2), (int)(nodesize), (int)(nodesize));
|
||||
g.setFont(UIEnv.getFont().deriveFont(10.0f));
|
||||
|
||||
g.drawString(text, (int)(x+nodesize/2), (int)(y-nodesize/3));
|
||||
if(ismarked) {
|
||||
Vector2 pos=new Vector2(x, y);
|
||||
Vector2 v2a=new Vector2(0, -1).multi(nodesize/4);
|
||||
Vector2 v2b=new Vector2(Math.sqrt(3)/2.0, 0.5).multi(nodesize/4);
|
||||
Vector2 v2c=new Vector2(-Math.sqrt(3)/2.0, 0.5).multi(nodesize/4);
|
||||
v2a=v2a.add(pos);
|
||||
v2b=v2b.add(pos);
|
||||
v2c=v2c.add(pos);
|
||||
g.drawPolygon(new int[] {(int) v2a.x,(int) v2b.x,(int) v2c.x}, new int[] {(int) v2a.y,(int) v2b.y,(int) v2c.y}, 3);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 getPositionVec2() {
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
public void commitDelta() {
|
||||
x+=delta.x;
|
||||
y+=delta.y;
|
||||
delta=new Vector2(0, 0);
|
||||
}
|
||||
|
||||
public void clearDelta() {
|
||||
delta=new Vector2(0, 0);
|
||||
|
||||
}
|
||||
}
|
||||
public class GraphEdge{
|
||||
private GraphNode from;
|
||||
private GraphNode to;
|
||||
LinkDirection linkPath;
|
||||
|
||||
public GraphEdge(GraphNode nfrom, GraphNode nto,LinkDirection lp) {
|
||||
this.from=nfrom;
|
||||
this.to=nto;
|
||||
this.linkPath=lp;
|
||||
}
|
||||
|
||||
}
|
||||
public class GraphEdgeGroup{
|
||||
private double length=100;
|
||||
private double gap=12;
|
||||
private boolean isShortest=false;
|
||||
private GraphNode nodeA,nodeB;
|
||||
private List<GraphEdge> edges=new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
public double getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(double length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public double getGap() {
|
||||
return gap;
|
||||
}
|
||||
|
||||
public void setGap(double gap) {
|
||||
this.gap = gap;
|
||||
}
|
||||
|
||||
public boolean match(GraphNode a,GraphNode b) {
|
||||
if(a.equals( nodeA)&&b.equals( nodeB))
|
||||
return true;
|
||||
if(b.equals( nodeA)&&a.equals( nodeB))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public GraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
|
||||
super();
|
||||
this.nodeA = nodeA;
|
||||
this.nodeB = nodeB;
|
||||
}
|
||||
|
||||
public boolean isShortest() {
|
||||
return isShortest;
|
||||
}
|
||||
|
||||
public void setShortest(boolean isShortest) {
|
||||
this.isShortest = isShortest;
|
||||
}
|
||||
|
||||
public List<GraphEdge> getPaths() {
|
||||
return getEdges();
|
||||
}
|
||||
public void paint(Graphics2D g) {
|
||||
|
||||
Vector2 nodeAv=new Vector2(nodeA.getX(), nodeA.getY());
|
||||
Vector2 nodeBv=new Vector2(nodeB.getX(), nodeB.getY());
|
||||
Vector2 vecDir=nodeBv.subtract(nodeAv);
|
||||
Vector2 vecDirnor=vecDir.normalize();
|
||||
Vector2 vecRA=vecDirnor.multi(nodeA.getNodesize()/2);
|
||||
Vector2 vecRB=vecDirnor.multi(nodeB.getNodesize()/2);
|
||||
|
||||
Vector2 vec90nor=new Vector2( -vecDir.y, vecDir.x).normalize();
|
||||
|
||||
//所有线路完整显示
|
||||
/*
|
||||
double width=gap*(edges.size()-1);
|
||||
//System.out.println(width);
|
||||
|
||||
Vector2 startPoint=nodeAv.add(vecR).add(vec90nor.multi(width/2));
|
||||
Vector2 endPoint=nodeBv.subtract(vecR).add(vec90nor.multi(width/2));
|
||||
|
||||
for (Iterator<GraphEdge> iterator = edges.iterator(); iterator.hasNext();) {
|
||||
GraphEdge graphEdge = (GraphEdge) iterator.next();
|
||||
|
||||
//System.out.println(vec90nor);
|
||||
|
||||
g.setColor(KLALBUtils.getColorByLoadPercentage(graphEdge.linkPath.getSpeed()*100f/graphEdge.linkPath.getBandwidth()));
|
||||
|
||||
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) )
|
||||
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
|
||||
|
||||
|
||||
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) )
|
||||
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
|
||||
|
||||
startPoint=startPoint.subtract(vec90nor.multi(gap));
|
||||
endPoint=endPoint.subtract(vec90nor.multi(gap));
|
||||
}
|
||||
*/
|
||||
long totalupspeed=0;
|
||||
long usedupspeed=0;
|
||||
long totaldownspeed=0;
|
||||
long useddownspeed=0;
|
||||
for(GraphEdge graphEdge :getEdges()) {
|
||||
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) ) {
|
||||
totalupspeed+=graphEdge.linkPath.getBandwidth();
|
||||
usedupspeed+=graphEdge.linkPath.getSpeed();
|
||||
}
|
||||
|
||||
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) ) {
|
||||
totaldownspeed+=graphEdge.linkPath.getBandwidth();
|
||||
useddownspeed+=graphEdge.linkPath.getSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
g.setStroke(new BasicStroke((float) Math.max(2.0, Math.log10(totalupspeed/10.0/1024.0))));
|
||||
|
||||
double width=gap*1;
|
||||
Vector2 startPoint=nodeAv.add(vecRA).add(vec90nor.multi(width/2));
|
||||
Vector2 endPoint=nodeBv.subtract(vecRB).add(vec90nor.multi(width/2));
|
||||
|
||||
g.setColor(KLALBUtils.getColorByLoadPercentagex(usedupspeed*100f/totalupspeed));
|
||||
|
||||
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
|
||||
|
||||
|
||||
|
||||
startPoint=startPoint.subtract(vec90nor.multi(gap));
|
||||
endPoint=endPoint.subtract(vec90nor.multi(gap));
|
||||
|
||||
|
||||
|
||||
g.setStroke(new BasicStroke((float) Math.max(2.0, Math.log10(totaldownspeed/10.0/1024.0))));
|
||||
|
||||
g.setColor(KLALBUtils.getColorByLoadPercentagex(useddownspeed*100f/totaldownspeed));
|
||||
|
||||
|
||||
|
||||
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
|
||||
|
||||
startPoint=startPoint.subtract(vec90nor.multi(gap));
|
||||
endPoint=endPoint.subtract(vec90nor.multi(gap));
|
||||
|
||||
if(isShortest) {
|
||||
BasicStroke dotted = new BasicStroke(2, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 0, new float[]{0,3,0,3}, 0);
|
||||
g.setStroke(dotted);
|
||||
g.setColor(Color.BLUE);
|
||||
g.drawLine((int)nodeA.getX(), (int)nodeA.getY(), (int)nodeB.getX(), (int)nodeB.getY());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public List<GraphEdge> getEdges() {
|
||||
return edges;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// 计算
|
||||
public static double[] rotateVec(int px, int py, double ang,
|
||||
boolean isChLen, double newLen) {
|
||||
|
||||
double mathstr[] = new double[2];
|
||||
// 矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
|
||||
double vx = px * Math.cos(ang) - py * Math.sin(ang);
|
||||
double vy = px * Math.sin(ang) + py * Math.cos(ang);
|
||||
if (isChLen) {
|
||||
double d = Math.sqrt(vx * vx + vy * vy);
|
||||
vx = vx / d * newLen;
|
||||
vy = vy / d * newLen;
|
||||
mathstr[0] = vx;
|
||||
mathstr[1] = vy;
|
||||
}
|
||||
return mathstr;
|
||||
}
|
||||
public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2)
|
||||
{
|
||||
|
||||
double H = 13; // 箭头高度
|
||||
double L = 8; // 底边的一半
|
||||
int x3 = 0;
|
||||
int y3 = 0;
|
||||
int x4 = 0;
|
||||
int y4 = 0;
|
||||
double awrad = Math.atan(L / H); // 箭头角度
|
||||
double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
|
||||
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
|
||||
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
|
||||
double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
|
||||
double y_3 = ey - arrXY_1[1];
|
||||
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
|
||||
double y_4 = ey - arrXY_2[1];
|
||||
|
||||
Double X3 = new Double(x_3);
|
||||
x3 = X3.intValue();
|
||||
Double Y3 = new Double(y_3);
|
||||
y3 = Y3.intValue();
|
||||
Double X4 = new Double(x_4);
|
||||
x4 = X4.intValue();
|
||||
Double Y4 = new Double(y_4);
|
||||
y4 = Y4.intValue();
|
||||
// 画线
|
||||
g2.drawLine(sx, sy, ex, ey);
|
||||
//
|
||||
GeneralPath triangle = new GeneralPath();
|
||||
triangle.moveTo(ex, ey);
|
||||
triangle.lineTo(x3, y3);
|
||||
triangle.lineTo(x4, y4);
|
||||
triangle.closePath();
|
||||
//实心箭头
|
||||
g2.fill(triangle);
|
||||
//非实心箭头
|
||||
//g2.draw(triangle);
|
||||
|
||||
}
|
||||
|
||||
protected void loadNodes() {
|
||||
updateBounds();
|
||||
}
|
||||
|
||||
private void recalcTranslate() {
|
||||
double xmin=Double.MAX_VALUE,xmax=Double.MIN_VALUE;
|
||||
double ymin=Double.MAX_VALUE,ymax=Double.MIN_VALUE;
|
||||
for(GraphNode graphNode:nodes.values()) {
|
||||
xmin=Math.min(xmin, graphNode.x);
|
||||
xmax=Math.max(xmax, graphNode.x);
|
||||
ymin=Math.min(ymin, graphNode.y);
|
||||
ymax=Math.max(ymax, graphNode.y);
|
||||
}
|
||||
this.xmin=xmin;
|
||||
this.xmax=xmax;
|
||||
this.ymin=ymin;
|
||||
this.ymax=ymax;
|
||||
if(xmin!=Double.MAX_VALUE) {
|
||||
translateX=-xmin+borderGap;
|
||||
translateY= -ymin+borderGap;
|
||||
}
|
||||
}
|
||||
|
||||
private double xmin=Double.MAX_VALUE,xmax=Double.MIN_VALUE;
|
||||
private double ymin=Double.MAX_VALUE,ymax=Double.MIN_VALUE;
|
||||
public void updateBounds() {
|
||||
recalcTranslate();
|
||||
|
||||
if(xmin!=Double.MAX_VALUE) {
|
||||
Dimension d=new Dimension((int)(((xmax-xmin)+borderGap*2)*scale),(int)(((ymax-ymin)+borderGap*2)*scale) );
|
||||
setPreferredSize(d);
|
||||
setSize(d);
|
||||
}
|
||||
}
|
||||
|
||||
public void runPhy() {
|
||||
for( GraphNode graphEdgeGroup :nodes.values()) {
|
||||
Vector2 vecpos=graphEdgeGroup.getPositionVec2();
|
||||
Vector2 vec=new Vector2(0, 0);
|
||||
for (Iterator<GraphNode> iteratorx =nodes.values().iterator(); iteratorx.hasNext();) {
|
||||
GraphNode graphEdgeGroup2 = (GraphNode) iteratorx.next();
|
||||
if(graphEdgeGroup2!=graphEdgeGroup) {
|
||||
Vector2 vecpos2=graphEdgeGroup2.getPositionVec2();
|
||||
Vector2 sub=vecpos.subtract(vecpos2);
|
||||
double distance=sub.Length();
|
||||
Vector2 dic=sub.normalize();
|
||||
vec=vec.add(dic.multi(Math.min(10.0/distance,10.0)));
|
||||
}
|
||||
}
|
||||
graphEdgeGroup.delta=graphEdgeGroup.delta.add(vec);
|
||||
}
|
||||
synchronized (edgeGroups) {
|
||||
|
||||
for(GraphEdgeGroup graphEdgeGroup :edgeGroups) {
|
||||
GraphNode na=graphEdgeGroup.nodeA;
|
||||
GraphNode nb=graphEdgeGroup.nodeB;
|
||||
Vector2 veca=na.getPositionVec2();
|
||||
Vector2 vecb=nb.getPositionVec2();
|
||||
Vector2 sub=veca.subtract(vecb);
|
||||
double distance=sub.Length();
|
||||
double length=graphEdgeGroup.getLength()+na.getNodesize()/2+nb.getNodesize()/2;
|
||||
|
||||
//System.out.println(length);
|
||||
if(distance>length) {
|
||||
Vector2 dicb=sub.normalize().multi((distance-length)/3);
|
||||
Vector2 dica=dicb.opposite();
|
||||
na.delta=na.delta.add(dica);
|
||||
nb.delta=nb.delta.add(dicb);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for( GraphNode graphEdgeGroup:nodes.values()) {
|
||||
|
||||
graphEdgeGroup.commitDelta();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Random r=new Random();
|
||||
public Vector2 getRandomPos() {
|
||||
double x,y;
|
||||
if(xmin>=xmax) {
|
||||
x=r.nextDouble();
|
||||
}else {
|
||||
x=r.nextDouble(xmin, xmax);
|
||||
}
|
||||
if(ymin>=ymax) {
|
||||
y=r.nextDouble();
|
||||
}else {
|
||||
y=r.nextDouble(ymin, ymax);
|
||||
}
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,12 @@ import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.Point;
|
||||
import java.awt.PopupMenu;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.SystemTray;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.TrayIcon;
|
||||
@@ -18,7 +21,14 @@ import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
@@ -32,7 +42,9 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import org.jfree.chart.ChartPanel;
|
||||
@@ -45,11 +57,14 @@ import org.jfree.chart.plot.dial.StandardDialRange;
|
||||
import org.jfree.chart.plot.dial.StandardDialScale;
|
||||
import org.jfree.chart.ui.RectangleEdge;
|
||||
import org.jfree.data.general.DefaultValueDataset;
|
||||
import org.kne.cloud.klalb.uitool.SettingItem;
|
||||
import org.kne.cloud.klalb.uitool.TextSettingItem;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.klalb.CONST;
|
||||
import org.kne.cloud.network.klalb.KLALBController;
|
||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
import org.kne.cloud.network.klalb.ui.GraphPanel.GraphNode;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.ui.XFrame;
|
||||
import org.kne.ui.YScrollPane;
|
||||
@@ -63,8 +78,6 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
|
||||
private TrayIcon ti;
|
||||
|
||||
private long rate=200;
|
||||
|
||||
private Timer t,t2,t3;
|
||||
|
||||
private JCheckBoxMenuItem showoffline;
|
||||
@@ -103,13 +116,16 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
|
||||
private DefaultValueDataset downEfficiency;*/
|
||||
|
||||
private YScrollPane ysp;
|
||||
private YScrollPane ysp,yspc;
|
||||
|
||||
private JTextField devicesOnline;
|
||||
private JTextField textField;
|
||||
private JTextField addressField;
|
||||
private JTextField addressField2;
|
||||
private JTextField asnField;
|
||||
|
||||
private NetworkGraphPanel graph;
|
||||
private JTextField textFieldLocate;
|
||||
|
||||
|
||||
/**
|
||||
@@ -771,11 +787,135 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
|
||||
JPanel panel_4 = new JPanel();
|
||||
panel_3.add(panel_4, BorderLayout.NORTH);
|
||||
panel_4.setLayout(new BorderLayout(0, 0));
|
||||
|
||||
|
||||
|
||||
textFieldLocate = new JTextField();
|
||||
panel_4.add(textFieldLocate, BorderLayout.CENTER);
|
||||
textFieldLocate.setColumns(10);
|
||||
|
||||
graph = new NetworkGraphPanel(kc.getIpv6Router().getKlalbRouteProtol());
|
||||
graph.setOpaque(false);
|
||||
JScrollPane jsp=new JScrollPane(graph);
|
||||
JScrollPane jsp=new JScrollPane();jsp.setWheelScrollingEnabled(false);
|
||||
jsp.setViewportView(graph);
|
||||
MouseAdapter ma = new MouseAdapter() {
|
||||
|
||||
private Point origin;
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
origin = new Point(e.getPoint());
|
||||
//System.out.println(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if (origin != null) {
|
||||
//System.out.println(e);
|
||||
//JViewport viewPort = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, jsp);
|
||||
//if (viewPort != null) {
|
||||
int deltaX = origin.x - e.getX();
|
||||
int deltaY = origin.y - e.getY();
|
||||
|
||||
Rectangle view = jsp.getViewport().getVisibleRect();
|
||||
view.x += deltaX;
|
||||
view.y += deltaY;
|
||||
|
||||
jsp.getViewport().scrollRectToVisible(view);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
graph.addMouseWheelListener(new MouseWheelListener() {
|
||||
private double scaleidx=1;
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
int val= e.getWheelRotation();
|
||||
double scaleidxold=scaleidx;
|
||||
scaleidx*=Math.pow(1.1, val);
|
||||
if(scaleidx>5) {
|
||||
scaleidx=5;
|
||||
}
|
||||
if(scaleidx<0.1) {
|
||||
scaleidx=0.1;
|
||||
}
|
||||
double pow=scaleidx/scaleidxold;
|
||||
Point pos = jsp.getViewport().getViewPosition();
|
||||
double canvasX=e.getX();
|
||||
double canvasY=e.getY();
|
||||
double w=graph.getWidth();
|
||||
double h=graph.getHeight();
|
||||
double percentX=canvasX/w;
|
||||
double percentY=canvasY/h;
|
||||
graph.setScale(scaleidx);
|
||||
graph.updateBounds();
|
||||
double newcanvasX=percentX*w*pow;
|
||||
double newcanvasY=percentY*h*pow;
|
||||
double dx= newcanvasX-canvasX;
|
||||
double dy=newcanvasY-canvasY;
|
||||
//System.out.println(dx+" "+dy);
|
||||
pos.x+=dx;
|
||||
pos.y+=dy ;
|
||||
jsp.getViewport().setViewPosition(pos);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
JButton btnLocate = new JButton("Locate");
|
||||
btnLocate.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String text= textFieldLocate.getText();
|
||||
try {
|
||||
Inet6Address addr=(Inet6Address) Inet6Address.getByName(text);
|
||||
GraphNode node= graph.getNodes().get(addr);
|
||||
if(node==null) {
|
||||
JOptionPane.showMessageDialog(KLALBStateGUI2.this, "Address not found", "Warning", JOptionPane.WARNING_MESSAGE);
|
||||
}else {
|
||||
Point pos = new Point();
|
||||
graph.updateBounds();
|
||||
Dimension dim= jsp.getViewport().getExtentSize();
|
||||
// System.out.println(dim);
|
||||
pos.x =(int) ((node.getX()+graph.getTranslateX())*graph.getScale()-dim.width/2);
|
||||
pos.y =(int) ((node.getY()+graph.getTranslateY())*graph.getScale()-dim.height/2);
|
||||
jsp.getViewport().setViewPosition(pos);
|
||||
}
|
||||
} catch (UnknownHostException e1) {
|
||||
JOptionPane.showMessageDialog(KLALBStateGUI2.this, "Input format error", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
panel_4.add(btnLocate, BorderLayout.EAST);
|
||||
|
||||
JButton btnHome = new JButton("Home");
|
||||
btnHome.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
textFieldLocate.setText(addressField.getText());
|
||||
btnLocate.doClick();
|
||||
}
|
||||
});
|
||||
panel_4.add(btnHome, BorderLayout.WEST);
|
||||
graph.addMouseListener(ma);
|
||||
graph.addMouseMotionListener(ma);
|
||||
panel_3.add(jsp, BorderLayout.CENTER);
|
||||
yspc = new YScrollPane(730);
|
||||
yspc.setOpaque(false);
|
||||
JPanel configsPanel = new JPanel();
|
||||
configsPanel.setLayout(new BorderLayout(0, 0));
|
||||
configsPanel.add(yspc);
|
||||
addSettingItems(yspc);
|
||||
JButton btnSave = new JButton("Save settings");
|
||||
yspc.add(btnSave, BorderLayout.NORTH);
|
||||
tabbedPane.addTab("Settings", null, configsPanel, null);
|
||||
configsPanel.setOpaque(false);
|
||||
textField.addKeyListener(new KeyListener() {
|
||||
|
||||
@Override
|
||||
@@ -795,7 +935,43 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
}
|
||||
}
|
||||
});
|
||||
textFieldLocate.addKeyListener(new KeyListener() {
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
if(e.getKeyCode()==KeyEvent.VK_ENTER) {
|
||||
btnLocate.doClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
private void addSettingItems(YScrollPane settings) {
|
||||
SettingItem si=new SettingItem("Basic settings",UIEnv.getFont().deriveFont(20.0f).deriveFont(Font.BOLD),CONST.itemwidth,CONST.settingheight);
|
||||
settings.getView().add(si);
|
||||
|
||||
TextSettingItem addr6=new TextSettingItem("IPv6 address",CONST.itemwidth,CONST.settingheight);
|
||||
addressField2=addr6.getTextField();
|
||||
settings.getView().add(addr6);
|
||||
|
||||
TextSettingItem asn=new TextSettingItem("AS number",CONST.itemwidth,CONST.settingheight);
|
||||
asnField=asn.getTextField();
|
||||
settings.getView().add(asn);
|
||||
|
||||
settings.updateScrool();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void createRefreshTask(KLALBController kc, YScrollPane ysp) {
|
||||
if(tsk!=null) {
|
||||
tsk.cancel();
|
||||
@@ -920,13 +1096,22 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
if(!contt.equals(devicesOnline.getText())) {
|
||||
devicesOnline.setText(contt);
|
||||
}
|
||||
String address=kc.getSelf().getHostAddress();
|
||||
String address=kc.getSelf().getAddress().getHostAddress();
|
||||
if(!address.equals(addressField.getText())) {
|
||||
addressField.setText(address);
|
||||
}
|
||||
if(!address.equals(addressField2.getText())) {
|
||||
addressField2.setText(address);
|
||||
}
|
||||
|
||||
String asnstr=Long.toString( kc.getIpv6Router().getASN());
|
||||
if(!asnstr.equals(asnField.getText())) {
|
||||
asnField.setText(asnstr);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
t2.scheduleAtFixedRate(tsk2, 200, 50);
|
||||
t2.scheduleAtFixedRate(tsk2, 200, 100);
|
||||
|
||||
if(tsk3!=null) {
|
||||
tsk3.cancel();
|
||||
@@ -970,7 +1155,7 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
}
|
||||
}
|
||||
};
|
||||
t3.scheduleAtFixedRate(tsk4, 200, 10);
|
||||
t3.scheduleAtFixedRate(tsk4, 200, 20);
|
||||
if(tsk5!=null) {
|
||||
tsk5.cancel();
|
||||
}
|
||||
@@ -978,11 +1163,15 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if(graph.isVisible())
|
||||
graph.loadNodes();
|
||||
graph.runPhy();
|
||||
if(graph.isVisible()) {
|
||||
graph.repaint();
|
||||
graph.revalidate();
|
||||
}
|
||||
}
|
||||
};
|
||||
t.scheduleAtFixedRate(tsk5, 200, 2000);
|
||||
t.scheduleAtFixedRate(tsk5, 200, 100);
|
||||
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.kne.cloud.network.klalb.ui;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
@@ -14,6 +15,7 @@ import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -26,240 +28,80 @@ import java.util.Set;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
|
||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection;
|
||||
|
||||
public class NetworkGraphPanel extends JPanel {
|
||||
public class NetworkGraphPanel extends GraphPanel {
|
||||
private KLALBRoutingProtocol routingProtocol;
|
||||
private Map<Inet6Address,GraphNode> nodes=new HashMap<Inet6Address,GraphNode>();
|
||||
private List<GraphEdgeGroup> edgeGroups=new ArrayList<GraphEdgeGroup>();
|
||||
private static final int nodesize=80;
|
||||
private class GraphNode{
|
||||
private String text;
|
||||
private Color color;
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
public GraphNode(String text, Color color, int x, int y) {
|
||||
super();
|
||||
this.text = text;
|
||||
this.color = color;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public GraphNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g) {
|
||||
g.setColor(Color.BLACK);
|
||||
g.setStroke(new BasicStroke(2.0f));
|
||||
g.drawOval(x-nodesize/2, y-nodesize/2, nodesize, nodesize);
|
||||
g.setFont(UIEnv.getFont().deriveFont(10.0f));
|
||||
g.drawString(text, x+nodesize/2, y-nodesize/3);
|
||||
}
|
||||
}
|
||||
private class GraphEdge{
|
||||
private GraphNode from;
|
||||
private GraphNode to;
|
||||
private LinkDirection linkPath;
|
||||
|
||||
public GraphEdge(GraphNode nfrom, GraphNode nto,LinkDirection lp) {
|
||||
this.from=nfrom;
|
||||
this.to=nto;
|
||||
this.linkPath=lp;
|
||||
}
|
||||
|
||||
}
|
||||
private class GraphEdgeGroup{
|
||||
private static final double gap=3;
|
||||
private GraphNode nodeA,nodeB;
|
||||
private List<GraphEdge> edges=new ArrayList<>();
|
||||
|
||||
private boolean match(GraphNode a,GraphNode b) {
|
||||
if(a.equals( nodeA)&&b.equals( nodeB))
|
||||
return true;
|
||||
if(b.equals( nodeA)&&a.equals( nodeB))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public GraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
|
||||
super();
|
||||
this.nodeA = nodeA;
|
||||
this.nodeB = nodeB;
|
||||
}
|
||||
public List<GraphEdge> getPaths() {
|
||||
return edges;
|
||||
}
|
||||
public void paint(Graphics2D g) {
|
||||
g.setStroke(new BasicStroke(1.0f));
|
||||
|
||||
Vector2 nodeAv=new Vector2(nodeA.getX(), nodeA.getY());
|
||||
Vector2 nodeBv=new Vector2(nodeB.getX(), nodeB.getY());
|
||||
Vector2 vecDir=nodeBv.subtract(nodeAv);
|
||||
Vector2 vecDirnor=vecDir.normalize();
|
||||
Vector2 vecR=vecDirnor.multi(nodesize/2);
|
||||
|
||||
Vector2 vec90nor=new Vector2( -vecDir.y, vecDir.x).normalize();
|
||||
|
||||
double width=gap*(edges.size()-1);
|
||||
|
||||
Vector2 startPoint=nodeAv.add(vecR).add(vec90nor.multi(width/2));
|
||||
Vector2 endPoint=nodeBv.subtract(vecR).add(vec90nor.multi(width/2));
|
||||
//System.out.println(width);
|
||||
for (Iterator<GraphEdge> iterator = edges.iterator(); iterator.hasNext();) {
|
||||
GraphEdge graphEdge = (GraphEdge) iterator.next();
|
||||
|
||||
//System.out.println(vec90nor);
|
||||
|
||||
g.setColor(KLALBUtils.getColorByLoadPercentage(graphEdge.linkPath.getSpeed()*100f/graphEdge.linkPath.getBandwidth()));
|
||||
|
||||
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) )
|
||||
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
|
||||
|
||||
|
||||
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) )
|
||||
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
|
||||
|
||||
startPoint=startPoint.subtract(vec90nor.multi(gap));
|
||||
endPoint=endPoint.subtract(vec90nor.multi(gap));
|
||||
}
|
||||
|
||||
//g.drawLine(nodeA.getX(), nodeA.getY(), nodeB.getX(), nodeB.getY());
|
||||
|
||||
}
|
||||
|
||||
public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2)
|
||||
{
|
||||
|
||||
double H = 5; // 箭头高度
|
||||
double L = 2; // 底边的一半
|
||||
int x3 = 0;
|
||||
int y3 = 0;
|
||||
int x4 = 0;
|
||||
int y4 = 0;
|
||||
double awrad = Math.atan(L / H); // 箭头角度
|
||||
double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
|
||||
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
|
||||
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
|
||||
double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
|
||||
double y_3 = ey - arrXY_1[1];
|
||||
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
|
||||
double y_4 = ey - arrXY_2[1];
|
||||
|
||||
Double X3 = new Double(x_3);
|
||||
x3 = X3.intValue();
|
||||
Double Y3 = new Double(y_3);
|
||||
y3 = Y3.intValue();
|
||||
Double X4 = new Double(x_4);
|
||||
x4 = X4.intValue();
|
||||
Double Y4 = new Double(y_4);
|
||||
y4 = Y4.intValue();
|
||||
// 画线
|
||||
g2.drawLine(sx, sy, ex, ey);
|
||||
//
|
||||
GeneralPath triangle = new GeneralPath();
|
||||
triangle.moveTo(ex, ey);
|
||||
triangle.lineTo(x3, y3);
|
||||
triangle.lineTo(x4, y4);
|
||||
triangle.closePath();
|
||||
//实心箭头
|
||||
g2.fill(triangle);
|
||||
//非实心箭头
|
||||
//g2.draw(triangle);
|
||||
|
||||
}
|
||||
|
||||
// 计算
|
||||
public static double[] rotateVec(int px, int py, double ang,
|
||||
boolean isChLen, double newLen) {
|
||||
|
||||
double mathstr[] = new double[2];
|
||||
// 矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
|
||||
double vx = px * Math.cos(ang) - py * Math.sin(ang);
|
||||
double vy = px * Math.sin(ang) + py * Math.cos(ang);
|
||||
if (isChLen) {
|
||||
double d = Math.sqrt(vx * vx + vy * vy);
|
||||
vx = vx / d * newLen;
|
||||
vy = vy / d * newLen;
|
||||
mathstr[0] = vx;
|
||||
mathstr[1] = vy;
|
||||
}
|
||||
return mathstr;
|
||||
}
|
||||
|
||||
}
|
||||
public NetworkGraphPanel(KLALBRoutingProtocol routingProtocol) {
|
||||
super();
|
||||
this.routingProtocol = routingProtocol;
|
||||
//setSize(10000, 10000);
|
||||
//setPreferredSize(getSize());
|
||||
}
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
loadNodes();
|
||||
|
||||
Graphics2D g2d=(Graphics2D)g;
|
||||
|
||||
for (Iterator<GraphEdgeGroup> iterator = edgeGroups.iterator(); iterator.hasNext();) {
|
||||
GraphEdgeGroup graphNode = (GraphEdgeGroup) iterator.next();
|
||||
graphNode.paint(g2d);
|
||||
|
||||
private class InetGraphNode extends GraphNode{
|
||||
|
||||
private InetAddress address;
|
||||
|
||||
public InetGraphNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InetGraphNode(InetAddress address, Color color, double x, double y, boolean ismarked) {
|
||||
super(getText(address), color, x, y, ismarked);
|
||||
this.address=address;
|
||||
}
|
||||
|
||||
private static String getText(InetAddress address2) {
|
||||
String text;
|
||||
if(address2 instanceof Inet6Address) {
|
||||
text=KLALBUtils.parseAbbrIPv6(address2.getHostAddress());
|
||||
}else {
|
||||
text=address2.getHostAddress();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public InetAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(InetAddress address) {
|
||||
this.address = address;
|
||||
super.setText(getText(address));
|
||||
}
|
||||
|
||||
for (Iterator<GraphNode> iterator = nodes.values().iterator(); iterator.hasNext();) {
|
||||
GraphNode graphNode = (GraphNode) iterator.next();
|
||||
graphNode.paint(g2d);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Random r=new Random();
|
||||
private void loadNodes() {
|
||||
|
||||
private double nsPerPixel=1000L;
|
||||
private class InetGraphEdgeGroup extends GraphEdgeGroup{
|
||||
public InetGraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
|
||||
super(nodeA, nodeB);
|
||||
}
|
||||
|
||||
public void updateLength() {
|
||||
long mindelay=Long.MAX_VALUE>>2;
|
||||
for (Iterator<GraphEdge> iterator = getEdges().iterator(); iterator.hasNext();) {
|
||||
GraphEdge graphEdge = (GraphEdge) iterator.next();
|
||||
mindelay=Math.min(mindelay, graphEdge.linkPath.getDelay());
|
||||
}
|
||||
setLength(mindelay/nsPerPixel);
|
||||
}
|
||||
}
|
||||
protected void loadNodes() {
|
||||
Map<Inet6Address, Long> addr= routingProtocol.getAddresses();
|
||||
Set<Inet6Address> ks=addr.keySet();
|
||||
for (Iterator<Inet6Address> iterator = ks.iterator(); iterator.hasNext();) {
|
||||
Inet6Address inet6Address = (Inet6Address) iterator.next();
|
||||
if(!nodes.containsKey(inet6Address))
|
||||
nodes.put(inet6Address,new GraphNode(inet6Address.getHostAddress(),Color.BLACK,r.nextInt(50,getWidth()-100),r.nextInt(50,getHeight()-50)));
|
||||
}
|
||||
Set<Inet6Address> kns=nodes.keySet();
|
||||
if(!getNodes().containsKey(inet6Address)) {
|
||||
Vector2 v2pos=super.getRandomPos();
|
||||
getNodes().put(inet6Address,new InetGraphNode(inet6Address,Color.BLACK,v2pos.x,v2pos.y,inet6Address.equals(routingProtocol.getRouter().getLocator().getAddress())));
|
||||
}
|
||||
}
|
||||
Set<Inet6Address> kns=getNodes().keySet();
|
||||
for (Iterator<Inet6Address> iterator = kns.iterator(); iterator.hasNext();) {
|
||||
Inet6Address inet6Address = (Inet6Address) iterator.next();
|
||||
if(!addr.containsKey(inet6Address)) {
|
||||
@@ -267,32 +109,53 @@ public class NetworkGraphPanel extends JPanel {
|
||||
}
|
||||
}
|
||||
//System.out.println("------------------------------------");
|
||||
edgeGroups.clear();
|
||||
Map<Inet6Address, Set<LinkDirection>> addr1= routingProtocol.getPaths();
|
||||
Set<Entry<Inet6Address, Set<LinkDirection>>> salink=addr1.entrySet();
|
||||
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = salink.iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();
|
||||
Set<LinkDirection>lps=entry.getValue();
|
||||
synchronized (getEdgeGroups()) {
|
||||
|
||||
getEdgeGroups().clear();
|
||||
Map<Inet6Address, List<LinkDirection>> addr1= routingProtocol.getPaths();
|
||||
Set<Entry<Inet6Address, List<LinkDirection>>> salink=addr1.entrySet();
|
||||
for (Iterator<Entry<Inet6Address, List<LinkDirection>>> iterator = salink.iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, List<LinkDirection>> entry = (Entry<Inet6Address, List<LinkDirection>>) iterator.next();
|
||||
List<LinkDirection>lps=entry.getValue();
|
||||
for (Iterator<LinkDirection> iterator2 = lps.iterator(); iterator2.hasNext();) {
|
||||
LinkDirection linkPath = (LinkDirection) iterator2.next();
|
||||
//System.out.println(linkPath);
|
||||
GraphNode nfrom=nodes.get(linkPath.getFromLocator());
|
||||
GraphNode nto=nodes.get(linkPath.getToLocator());
|
||||
InetGraphNode nfrom=(InetGraphNode) getNodes().get(linkPath.getFromLocator());
|
||||
InetGraphNode nto=(InetGraphNode) getNodes().get(linkPath.getToLocator());
|
||||
if(nfrom!=null&&nto!=null) {
|
||||
GraphEdgeGroup group=getGroup(nfrom, nto);
|
||||
group.getPaths().add(new GraphEdge(nfrom,nto,linkPath));
|
||||
|
||||
|
||||
GraphEdge ge=new GraphEdge(nfrom,nto,linkPath);
|
||||
group.getPaths().add(ge);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Iterator iterator = getEdgeGroups().iterator(); iterator.hasNext();) {
|
||||
GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
|
||||
((InetGraphEdgeGroup) graphEdgeGroup).updateLength();
|
||||
}
|
||||
}
|
||||
super.loadNodes();
|
||||
}
|
||||
|
||||
private GraphEdgeGroup getGroup(GraphNode a,GraphNode b) {
|
||||
for (Iterator iterator = edgeGroups.iterator(); iterator.hasNext();) {
|
||||
private GraphEdgeGroup getGroup(InetGraphNode a,InetGraphNode b) {
|
||||
for (Iterator iterator = getEdgeGroups().iterator(); iterator.hasNext();) {
|
||||
GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
|
||||
if(graphEdgeGroup.match(a,b)) {
|
||||
return graphEdgeGroup;
|
||||
}
|
||||
}
|
||||
GraphEdgeGroup ng=new GraphEdgeGroup(a, b);
|
||||
edgeGroups.add(ng);
|
||||
GraphEdgeGroup ng=new InetGraphEdgeGroup(a, b);
|
||||
Inet6Address aprev= routingProtocol.getDijkstraPrevNode((Inet6Address) a.getAddress());
|
||||
Inet6Address bprev= routingProtocol.getDijkstraPrevNode((Inet6Address) b.getAddress());
|
||||
|
||||
if( b.getAddress().equals(aprev)||a.getAddress().equals(bprev)) {
|
||||
ng.setShortest(true);
|
||||
}
|
||||
getEdgeGroups().add(ng);
|
||||
return ng;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import javax.swing.SwingConstants;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.klalb.CONST;
|
||||
import org.kne.cloud.network.klalb.KLALBController;
|
||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
@@ -93,7 +94,7 @@ public class TPanel2 extends JPanel {
|
||||
targup.setHorizontalTextPosition(SwingConstants.LEFT);
|
||||
|
||||
setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||
setSize(720, 45);
|
||||
setSize(CONST.itemwidth, CONST.linepanelheight);
|
||||
setPreferredSize(getSize());
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
|
||||
Reference in New Issue
Block a user