forked from KNEMC/KLALB
KLALB3.2
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.kne.cloud.network.klalb.IPSequence;
|
||||
|
||||
public class ACKSEQSSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
|
||||
public ACKSEQSSegmentRoutingTLV(ByteBuffer klalbHeader) {
|
||||
super(klalbHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ACKSEQSSegmentRoutingTLV [getSequence()=" + getSequence() + "]";
|
||||
}
|
||||
|
||||
public ACKSEQSSegmentRoutingTLV(UUID ackid, boolean promise) {
|
||||
super(IPv6SegmentRoutingTLV.ACKSEQS);
|
||||
setUUID(ackid);
|
||||
setPromise(promise);
|
||||
getData().limit(22);
|
||||
}
|
||||
public ACKSEQSSegmentRoutingTLV(IPSequence ackid, boolean promise) {
|
||||
super(IPv6SegmentRoutingTLV.ACKSEQS);
|
||||
setIPSequence(ackid);
|
||||
setPromise(promise);
|
||||
getData().limit(22);
|
||||
}
|
||||
public void setUUID(UUID uuid) {
|
||||
getData().putLong(6,uuid.getMostSignificantBits());
|
||||
getData().putLong(14,uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return new UUID(getData().getLong(6),getData().getLong(14));
|
||||
}
|
||||
public void setIPSequence(IPSequence ackid) {
|
||||
setUUID(ackid.getUuid());
|
||||
}
|
||||
|
||||
public IPSequence getIPSequence() {
|
||||
return new IPSequence(getUUID(),isPromise());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
|
||||
super.writeToChannel(dto);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
super.readFromChannel(din, length);
|
||||
|
||||
}
|
||||
|
||||
public long getSequence() {
|
||||
return getData().getLong(6);
|
||||
}
|
||||
public void setSequence(long sequence) {
|
||||
getData().putLong(6,sequence);
|
||||
}
|
||||
public int getFlowNumber() {
|
||||
return getData().getInt(2);
|
||||
}
|
||||
public void setFlowNumber(int flowsequence) {
|
||||
getData().putInt(2,flowsequence);
|
||||
}
|
||||
public void setACKIP(Inet6Address ip) {
|
||||
getData().put(14, ip.getAddress());
|
||||
}
|
||||
public Inet6Address getACKIP() {
|
||||
byte[]arr=new byte[16];
|
||||
getData().get(14,arr);
|
||||
try {
|
||||
return (Inet6Address) Inet6Address.getByAddress(arr);
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public boolean isPromise() {
|
||||
return getData().get(0)!=0?true:false;
|
||||
}
|
||||
|
||||
public void setPromise(boolean promise) {
|
||||
if(promise) {
|
||||
getData().put(0, (byte) 1);
|
||||
}else {
|
||||
getData().put(0, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
public interface DijkstraAlgorithm extends Runnable{
|
||||
public static final long MAX_WEIGHT=Long.MAX_VALUE/256L;
|
||||
public void setGraph(long[][]pointers,long[][]heap,long startPoint) ;
|
||||
public void run();
|
||||
public long[] getDirection();
|
||||
|
||||
@@ -14,14 +14,21 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
public static final int PADN=4;
|
||||
public static final int HMAC=5;
|
||||
public static final int SEQS=7;
|
||||
public static final int ACKSEQS=8;
|
||||
|
||||
private int headerLength=2;
|
||||
|
||||
public int getHeaderLength() {
|
||||
return headerLength;
|
||||
}
|
||||
|
||||
private boolean isDefault;
|
||||
|
||||
protected volatile ByteBuffer header;
|
||||
|
||||
private ByteBuffer data;
|
||||
|
||||
public IPv6SegmentRoutingTLV(ByteBuffer header ) {
|
||||
public IPv6SegmentRoutingTLV(ByteBuffer header ) {
|
||||
this(header,true);
|
||||
}
|
||||
|
||||
@@ -32,7 +39,10 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
public IPv6SegmentRoutingTLV(ByteBuffer header ,boolean isDefault ) {
|
||||
super();
|
||||
this.header = header;
|
||||
if(isDefault&&(getType()!=PAD1)) {
|
||||
this.isDefault=isDefault;
|
||||
if(getType()==PAD1)
|
||||
headerLength=1;
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
data=ByteBuffer.allocate(512);
|
||||
}
|
||||
}
|
||||
@@ -42,17 +52,19 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
public IPv6SegmentRoutingTLV(int type,boolean isDefault) {
|
||||
super();
|
||||
this.header=ByteBuffer.allocate(2);
|
||||
this.isDefault=isDefault;
|
||||
header.put((byte) type);
|
||||
if(isDefault&&(type!=PAD1)) {
|
||||
if(type==PAD1) {
|
||||
headerLength=1;
|
||||
}
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
data=ByteBuffer.allocate(512);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
if(getType()==PAD1)
|
||||
return 1;
|
||||
return header.limit()+(isDefault?data.limit():0);
|
||||
return headerLength+(isDefault?data.limit():0);
|
||||
}
|
||||
|
||||
public static IPv6SegmentRoutingTLV readIPv6SegmentRoutingTLVFromChannel(ReadableByteChannel din) throws IOException {
|
||||
@@ -74,6 +86,14 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
rtlv=new PADNSegmentRoutingTLV(bbf);
|
||||
rtlv.readFromChannel(din);
|
||||
return rtlv;
|
||||
case SEQS:
|
||||
rtlv=new SEQSSegmentRoutingTLV(bbf);
|
||||
rtlv.readFromChannel(din);
|
||||
return rtlv;
|
||||
case ACKSEQS:
|
||||
rtlv=new ACKSEQSSegmentRoutingTLV(bbf);
|
||||
rtlv.readFromChannel(din);
|
||||
return rtlv;
|
||||
default:
|
||||
rtlv=new IPv6SegmentRoutingTLV(bbf);
|
||||
rtlv.readFromChannel(din);
|
||||
@@ -84,26 +104,26 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
tlv.writeToChannel(dto);
|
||||
}
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(isDefault&&(getType()!=PAD1)) {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
setDataLength(data.limit());
|
||||
}
|
||||
header.limit(headerLength);
|
||||
dto.write(header.slice(0,header.limit()));
|
||||
if(isDefault&&(getType()!=PAD1)) {
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
dto.write(data.slice(0, data.limit()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
header.limit(1);
|
||||
while (header.hasRemaining()) {
|
||||
if (din.read(header) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
int type=getType();
|
||||
if(type!=PAD1) {
|
||||
if(headerLength>1) {
|
||||
header.limit(2);
|
||||
while (header.hasRemaining()) {
|
||||
if (din.read(header) == -1) {
|
||||
@@ -113,7 +133,7 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
}
|
||||
header.flip();
|
||||
|
||||
if(isDefault&&(getType()!=PAD1)) {
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
data.clear();
|
||||
data.limit(getDataLength());
|
||||
while(data.hasRemaining()){
|
||||
|
||||
@@ -32,26 +32,41 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.ipv6.Neighbor;
|
||||
import org.kne.cloud.network.klalb.KLALBVirtualRawSocket;
|
||||
import org.kne.cloud.network.monitor.DelayMonitorData;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorData;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||
import org.kne.cloud.network.scanner.InetAddressRange;
|
||||
import org.kne.cloud.network.te.BandwidthDistributer;
|
||||
|
||||
import com.google.gson.internal.Pair;
|
||||
|
||||
public class KLALBRoutingProtocol extends Thread{
|
||||
|
||||
private static final boolean debug = false;
|
||||
|
||||
|
||||
private RouterInfo selfRouterInfo;
|
||||
private Map<Inet6Address, RouterInfo> netmap=new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
private volatile Map<Inet6Address,Long>addresses;
|
||||
|
||||
private volatile Map<Inet6Address, Set<LinkDirection>> paths;
|
||||
private volatile Map<Inet6Address, List<LinkDirection>> paths;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static final int DEFAULT_PORT=1001;
|
||||
|
||||
public static final int DEFAULT_PROTOCOL_NUMBER=252;
|
||||
|
||||
public static final long HOTSOPT_TIMEOUT = 1000000000;
|
||||
|
||||
public static final int HOTSOPT_REPORT_INTERVAL = 100000000;
|
||||
@@ -63,60 +78,59 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
this.router=router;
|
||||
}
|
||||
|
||||
private ReentrantLock sendlock=new ReentrantLock();
|
||||
//private ReentrantLock sendlock=new ReentrantLock();
|
||||
|
||||
private long floodTimer=System.nanoTime();
|
||||
private long floodTimer2=System.nanoTime();
|
||||
private long requestTimer=System.nanoTime();
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.currentThread().setName("KLALB路由协议接收线程");
|
||||
getSelfRouterInfo();
|
||||
DatagramSocket ds = null;
|
||||
KLALBVirtualRawSocket ds = null;
|
||||
try{
|
||||
ds=new DatagramSocket(new InetSocketAddress(router.getLocator().getAddress(), DEFAULT_PORT) );
|
||||
DatagramSocket ds2=ds;
|
||||
ds=new KLALBVirtualRawSocket(router,router.getLocator().getAddress(), DEFAULT_PROTOCOL_NUMBER);
|
||||
KLALBVirtualRawSocket ds2=ds;
|
||||
new Thread(()->{
|
||||
Thread.currentThread().setName("KLALB路由协议接收线程");
|
||||
|
||||
while(true) {
|
||||
try {
|
||||
/*List<NetworkLink>links=router.getLinkTabel();
|
||||
Object[] nls=links.toArray();
|
||||
byte[]to=createLinkStatePacket(nls);
|
||||
DatagramPacket dgp=new DatagramPacket(to,to.length);
|
||||
|
||||
for(int i=0;i<nls.length;i++) {
|
||||
NetworkLink nl=(NetworkLink) nls[i];
|
||||
if(!nl.isLoopBack()) {
|
||||
Set<Inet6Address>neis=nl.discoverNeighbors();
|
||||
for (Iterator<Inet6Address> iteratorx = neis.iterator(); iteratorx.hasNext();) {
|
||||
Inet6Address addresses = (Inet6Address) iteratorx.next();
|
||||
dgp.setAddress(addresses);
|
||||
dgp.setPort(DEFAULT_PORT);
|
||||
ds2.send(dgp);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
RouterInfo slf= getSelfRouterInfo();
|
||||
RouterInfo oslf=netmap.put(slf.getLocator().getAddress(), slf);
|
||||
selfRouterInfo = getSelfRouterInfo();
|
||||
RouterInfo oslf=netmap.put(selfRouterInfo.getLocator().getAddress(), selfRouterInfo);
|
||||
noticeUpdate();
|
||||
if(oslf==null||(!slf.equals(oslf))) {
|
||||
//System.out.println("change:"+oslf+"\n"+slf);
|
||||
/*if(oslf==null||(!selfRouterInfo.equals(oslf))) {
|
||||
long cur=System.nanoTime();
|
||||
if(cur-floodTimer2>5000000000L) {
|
||||
//System.out.println("update10");
|
||||
floodTimer2=cur;
|
||||
floodPacket(ds2, null, new RouterInfoPacket(slf,true));
|
||||
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true));
|
||||
}
|
||||
}else {
|
||||
long cur=System.nanoTime();
|
||||
if(cur-floodTimer>60000000000L) {
|
||||
//System.out.println("update60");
|
||||
floodTimer=cur;
|
||||
floodPacket(ds2, null, new RouterInfoPacket(slf,true));
|
||||
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true));
|
||||
}
|
||||
}*/
|
||||
|
||||
long cur=System.nanoTime();
|
||||
if(cur-floodTimer>60000000000L) {
|
||||
if(debug)
|
||||
System.out.println("update60");
|
||||
floodTimer=cur;
|
||||
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true,-1));
|
||||
}
|
||||
Set<Inet6Address> requestSet=new HashSet<>();
|
||||
|
||||
if(cur-floodTimer2>1000000000L) {
|
||||
if(debug)
|
||||
System.out.println("update1");
|
||||
floodTimer2=cur;
|
||||
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true,router.getASN()));
|
||||
}
|
||||
|
||||
//Set<Inet6Address> requestSet=new HashSet<>();
|
||||
for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = netmap.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, RouterInfo> type = (Entry<Inet6Address, RouterInfo>) iterator.next();
|
||||
RouterInfo val=type.getValue();
|
||||
@@ -124,7 +138,7 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
iterator.remove();
|
||||
noticeUpdate();
|
||||
}
|
||||
Set<NeighborInfo> ads=val.getNeighborAddresses();
|
||||
/*List<NeighborInfo> ads=val.getNeighborAddresses();
|
||||
for (Iterator<NeighborInfo> iterator2 = ads.iterator(); iterator2.hasNext();) {
|
||||
Inet6Address address=iterator2.next().getLocator().getAddress();
|
||||
//System.out.println(address);
|
||||
@@ -132,35 +146,37 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
requestSet.add(address);
|
||||
}
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
computeShortestPathIfUpdated();
|
||||
|
||||
|
||||
|
||||
/*long cur2=System.nanoTime();
|
||||
if(cur2-requestTimer>1000000000L) {
|
||||
requestTimer=cur2;
|
||||
|
||||
for (Iterator<Inet6Address> iterator = requestSet.iterator(); iterator.hasNext();) {
|
||||
Inet6Address inet6Address = (Inet6Address) iterator.next();
|
||||
byte[]to=new byte[] {0};
|
||||
DatagramPacket dgp=new DatagramPacket(to,to.length);
|
||||
dgp.setAddress(inet6Address);
|
||||
dgp.setPort(DEFAULT_PORT);
|
||||
|
||||
writePacket(ds2, new RouterInfoRequestPacket( ), new InetSocketAddress(inet6Address, DEFAULT_PORT));
|
||||
|
||||
if(debug)
|
||||
System.out.println("Request:"+inet6Address);
|
||||
sendlock.lock();
|
||||
try {
|
||||
ds2.send(dgp);
|
||||
}catch(SocketException e) {
|
||||
System.out.println("Send failed:"+dgp.getAddress());
|
||||
}finally {
|
||||
sendlock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}*/
|
||||
|
||||
for (Iterator<Entry<Inet6Address, HotspotAddressTimer>> iterator = hotspots.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, HotspotAddressTimer> type = (Entry<Inet6Address, HotspotAddressTimer>) iterator.next();
|
||||
if(type.getValue().checkReportTime()) {
|
||||
//System.out.println("hotspot address:"+type.getKey());
|
||||
writePacket(ds2, new RouterInfoPacket( netmap.get(router.getLocator().getAddress()),false), new InetSocketAddress(type.getKey(), DEFAULT_PORT));
|
||||
writePacket(ds2, new RouterInfoPacket( netmap.get(router.getLocator().getAddress()),false,-1), new InetSocketAddress(type.getKey(), DEFAULT_PORT));
|
||||
}
|
||||
if(type.getValue().checkTimeOut()) {
|
||||
iterator.remove();
|
||||
@@ -193,8 +209,16 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
switch(kp.getType()) {
|
||||
case KLALBRoutingProtocolPacket.RINFO_REQ:
|
||||
RouterInfo rifr=netmap.get(router.getLocator().getAddress());
|
||||
if(rifr!=null)
|
||||
writePacket(ds, new RouterInfoPacket( rifr,false), dgp.getSocketAddress());
|
||||
if(debug)
|
||||
System.out.println("get Request from:"+dgp.getSocketAddress());
|
||||
if(rifr!=null) {
|
||||
writePacket(ds, new RouterInfoPacket( rifr,false,-1), dgp.getSocketAddress());
|
||||
if(debug)
|
||||
System.out.println("response router info:"+rifr);
|
||||
}else {
|
||||
if(debug)
|
||||
System.out.println("router info is null!");
|
||||
}
|
||||
break;
|
||||
case KLALBRoutingProtocolPacket.RINFO:
|
||||
|
||||
@@ -237,7 +261,8 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
}
|
||||
}
|
||||
|
||||
private void floodPacket(DatagramSocket ds,SocketAddress except,KLALBRoutingProtocolPacket rifp) throws IOException {
|
||||
private void floodPacket(KLALBVirtualRawSocket ds2,SocketAddress except,RouterInfoPacket rifp) throws IOException {
|
||||
long asn=rifp.getASN();
|
||||
List<IPv6NetworkLink>links=router.getLinkTabel();
|
||||
Object[] nls=links.toArray();
|
||||
for(int i=0;i<nls.length;i++) {
|
||||
@@ -248,27 +273,31 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
InetSocketAddress isa=new InetSocketAddress(addresses.getLocator().getAddress(),DEFAULT_PORT);
|
||||
if(!isa.equals(except)) {
|
||||
writePacket(ds, rifp, isa);
|
||||
if(asn==-1) {
|
||||
writePacket(ds2, rifp, isa);
|
||||
}else{
|
||||
RouterInfo nif= netmap.get(isa.getAddress());
|
||||
if(nif!=null&&nif.getAsn()==asn) {
|
||||
writePacket(ds2, rifp, isa);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writePacket(DatagramSocket ds,KLALBRoutingProtocolPacket pkt,SocketAddress dest) throws IOException {
|
||||
private void writePacket(KLALBVirtualRawSocket ds2,KLALBRoutingProtocolPacket pkt,SocketAddress dest) throws IOException {
|
||||
ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
|
||||
KLALBRoutingProtocolPacket.writeKLALBPacketToChannel(Channels.newChannel(bos),pkt);
|
||||
byte[]to=bos.toByteArray();
|
||||
DatagramPacket dgpx=new DatagramPacket(to,to.length);
|
||||
dgpx.setSocketAddress(dest);
|
||||
sendlock.lock();
|
||||
try {
|
||||
ds.send(dgpx);
|
||||
ds2.send(dgpx);
|
||||
}catch(BindException e) {
|
||||
e.printStackTrace();
|
||||
System.err.println("Cannot assign:"+dest);
|
||||
}finally {
|
||||
sendlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,47 +358,51 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
return;
|
||||
}
|
||||
Set<Entry<Inet6Address, RouterInfo>> s=netmap.entrySet();
|
||||
Map<Inet6Address,Long>airs=new HashMap<>();
|
||||
Map<Inet6Address,Long>airs=new HashMap<>(netmap.size()+1);
|
||||
|
||||
List<Inet6Address>rias=new ArrayList<>();
|
||||
List<Inet6Address>rias=new ArrayList<>(netmap.size()+1);
|
||||
|
||||
Map<Inet6Address,Set< LinkDirection>>paths=new HashMap<>();
|
||||
Map<Inet6Address,List< LinkDirection>>paths=new HashMap<>();
|
||||
long number=0;
|
||||
for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = s.iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, RouterInfo> entry = (Entry<Inet6Address, RouterInfo>) iterator.next();
|
||||
for(Entry<Inet6Address, RouterInfo> entry:s) {
|
||||
if(!airs.containsKey(entry.getKey())) {
|
||||
airs.put(entry.getKey(),number);
|
||||
rias.add( entry.getKey());
|
||||
number++;
|
||||
}
|
||||
Set<NeighborInfo> ni= entry.getValue().getNeighborAddresses();
|
||||
for (Iterator<NeighborInfo> iterator2 = ni.iterator(); iterator2.hasNext();) {
|
||||
NeighborInfo neighborInfo = (NeighborInfo) iterator2.next();
|
||||
List<NeighborInfo> ni= entry.getValue().getNeighborAddresses();
|
||||
for(NeighborInfo neighborInfo :ni) {
|
||||
Inet6Address ias2=neighborInfo.getLocator().getAddress();
|
||||
if(!airs.containsKey(ias2)) {
|
||||
airs.put(ias2,number);
|
||||
rias.add( ias2);
|
||||
number++;
|
||||
}
|
||||
Set<LinkDirection>lp1=paths.get(entry.getKey());
|
||||
List<LinkDirection>lp1=paths.get(entry.getKey());
|
||||
if(lp1==null) {
|
||||
paths.put(entry.getKey(), lp1=new HashSet<>());
|
||||
paths.put(entry.getKey(), lp1=new ArrayList<>());
|
||||
}
|
||||
lp1.add(new LinkDirection(neighborInfo.getLocal(),neighborInfo.getNeighbor(),entry.getKey(), ias2, neighborInfo.getUploadDelay(),neighborInfo.getUploadSpeed(),neighborInfo.getUploadSpeedMax()));
|
||||
lp1.add(new LinkDirection(neighborInfo.getLocal(),neighborInfo.getNeighbor(),entry.getKey(), ias2, neighborInfo.getUploadDelay(),neighborInfo.getUploadDelayMin(),neighborInfo.getUploadSpeed(),neighborInfo.getUploadSpeedMax()));
|
||||
|
||||
Set<LinkDirection>lp2=paths.get(ias2);
|
||||
/*Set<LinkDirection>lp2=paths.get(ias2);
|
||||
if(lp2==null) {
|
||||
paths.put(ias2, lp2=new HashSet<>());
|
||||
}
|
||||
lp2.add( new LinkDirection(neighborInfo.getNeighbor(),neighborInfo.getLocal(),ias2,entry.getKey() , neighborInfo.getDownloadDelay(),neighborInfo.getDownloadSpeed(),neighborInfo.getDownloadSpeedMax()));
|
||||
lp2.add( new LinkDirection(neighborInfo.getNeighbor(),neighborInfo.getLocal(),ias2,entry.getKey() , neighborInfo.getDownloadDelay(),neighborInfo.getDownloadDelayMin(),neighborInfo.getDownloadSpeed(),neighborInfo.getDownloadSpeedMax()));
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
long[][]pointers=new long[(int) airs.size()][2];
|
||||
long heappos=0;
|
||||
long linknumber=0;
|
||||
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = paths.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();
|
||||
for(Entry<Inet6Address, List<LinkDirection>> entry:paths.entrySet()) {
|
||||
/*for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = paths.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();*/
|
||||
linknumber+=entry.getValue().size();
|
||||
}
|
||||
long[][]heap=new long[(int) (linknumber)][2];
|
||||
@@ -377,12 +410,16 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
long heapindex=0;
|
||||
pointers[(int) i][0]=heappos;
|
||||
InetAddress ia=rias.get((int) i);
|
||||
Set<LinkDirection>lks=paths.get(ia);
|
||||
List<LinkDirection>lks=paths.get(ia);
|
||||
if(lks!=null)
|
||||
for(LinkDirection linkPath:lks) {
|
||||
/*
|
||||
for (Iterator<LinkDirection> iterator = lks.iterator(); iterator.hasNext();) {
|
||||
LinkDirection linkPath=iterator.next();
|
||||
LinkDirection linkPath=iterator.next();*/
|
||||
heap[(int)(heappos+ heapindex)][0]=airs.get(linkPath.getToLocator());
|
||||
heap[(int) (heappos+heapindex)][1]=linkPath.getWeight();
|
||||
//heap[(int) (heappos+heapindex)][2]=linkPath.get
|
||||
// heap[(int) (heappos+heapindex)][3]=0;
|
||||
heapindex++;
|
||||
|
||||
}
|
||||
@@ -391,6 +428,8 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
pointers[(int) i][1]=heapindex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
algorithm.setGraph(pointers,heap,airs.get(router.getLocator().getAddress()));
|
||||
algorithm.run();
|
||||
directions=new NetmapDirections(algorithm.getDirection(), rias, airs);
|
||||
@@ -407,12 +446,12 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
private Inet6Address fromLocator;
|
||||
private Inet6Address toLocator;
|
||||
private long delay;
|
||||
private long delayMin;
|
||||
private long speed;
|
||||
public long getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
private long bandwidth;
|
||||
private long usedBandwidth=0;
|
||||
public Inet6AddressGroup getFromAddress() {
|
||||
return fromAddress;
|
||||
}
|
||||
@@ -425,22 +464,28 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
public long getBandwidth() {
|
||||
return bandwidth;
|
||||
}
|
||||
|
||||
public long getDelayMin() {
|
||||
return delayMin;
|
||||
}
|
||||
|
||||
public LinkDirection(Inet6AddressGroup fromAddress, Inet6AddressGroup toAddress, Inet6Address fromLocator,
|
||||
Inet6Address toLocator,long delay,long speed, long bandwidth) {
|
||||
Inet6Address toLocator, long delay, long delayMin, long speed, long bandwidth) {
|
||||
super();
|
||||
this.fromAddress = fromAddress;
|
||||
this.toAddress = toAddress;
|
||||
this.fromLocator = fromLocator;
|
||||
this.toLocator = toLocator;
|
||||
this.delay = delay;
|
||||
this.speed=speed;
|
||||
this.delayMin = delayMin;
|
||||
this.speed = speed;
|
||||
this.bandwidth = bandwidth;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LinkDirection [fromAddress=" + fromAddress + ", toAddress=" + toAddress + ", fromLocator="
|
||||
+ fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", speed=" + speed
|
||||
+ ", bandwidth=" + bandwidth + ", usedBandwidth=" + usedBandwidth + "]";
|
||||
+ fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", delayMin=" + delayMin
|
||||
+ ", speed=" + speed + ", bandwidth=" + bandwidth + "]";
|
||||
}
|
||||
public Inet6Address getFromLocator() {
|
||||
return fromLocator;
|
||||
@@ -470,8 +515,7 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
private RouterInfo getSelfRouterInfo() {
|
||||
List<IPv6NetworkLink>links=router.getLinkTabel();
|
||||
Object[] nls=links.toArray();
|
||||
RouterInfo ri=new RouterInfo(System.currentTimeMillis());
|
||||
ri.setLocator(router.getLocator());
|
||||
RouterInfo ri=new RouterInfo(System.currentTimeMillis(),router.getLocator(),router.getASN());
|
||||
for(int i=0;i<nls.length;i++) {
|
||||
IPv6NetworkLink nl=(IPv6NetworkLink) nls[i];
|
||||
if((!nl.isLoopBack())&&nl.isUp()) {
|
||||
@@ -480,6 +524,8 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
long updelay=10000000000L;
|
||||
long downdelay=10000000000L;
|
||||
long updelayMin=10000000000L;
|
||||
long downdelayMin=10000000000L;
|
||||
long uploadspeed=1024L*1024;
|
||||
long downloadspeed=1024L*1024;
|
||||
long uploadspeedmax=1024L*1024;
|
||||
@@ -489,6 +535,11 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
if(md instanceof DelayMonitorData) {
|
||||
updelay=((DelayMonitorData) md).getOutDelay();
|
||||
downdelay=((DelayMonitorData) md).getInDelay();
|
||||
|
||||
if(md instanceof SpeedAndTrafficAndDelayMonitorDataImpl) {
|
||||
updelayMin=((SpeedAndTrafficAndDelayMonitorDataImpl) md).getOutDelayMin();
|
||||
downdelayMin=((SpeedAndTrafficAndDelayMonitorDataImpl) md).getInDelayMin();
|
||||
}
|
||||
}
|
||||
if(md instanceof SpeedAndTrafficMonitorData) {
|
||||
uploadspeed=((SpeedAndTrafficMonitorData) md).getOutSpeed();
|
||||
@@ -500,7 +551,9 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
}
|
||||
}
|
||||
}
|
||||
ri.getNeighborAddresses().add(new NeighborInfo(nl.getAddressGroup(),addresses.getAddress(),addresses.getLocator(),updelay ,downdelay ,uploadspeed ,downloadspeed,uploadspeedmax ,downloadspeedmax));
|
||||
NeighborInfo ni=new NeighborInfo(nl.getAddressGroup(),addresses.getAddress(),addresses.getLocator(),updelay ,downdelay,updelayMin ,downdelayMin ,uploadspeed ,downloadspeed,uploadspeedmax ,downloadspeedmax);
|
||||
ni.setContext(addresses);
|
||||
ri.getNeighborAddresses().add(ni);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -513,7 +566,7 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
public Map<Inet6Address, Long> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
public Map<Inet6Address, Set<LinkDirection>> getPaths() {
|
||||
public Map<Inet6Address, List<LinkDirection>> getPaths() {
|
||||
return paths;
|
||||
}
|
||||
public List<Inet6Address> createSegmentList(Inet6Address dest) {
|
||||
@@ -564,12 +617,41 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
|
||||
private Map<Inet6Address, HotspotAddressTimer> hotspots=new ConcurrentHashMap<>();
|
||||
public void putHotspotAddress(Inet6Address sourceAddress) {
|
||||
if(true) {
|
||||
HotspotAddressTimer hat=hotspots.get(sourceAddress);
|
||||
if(hat==null) {
|
||||
hotspots.put(sourceAddress, new HotspotAddressTimer());
|
||||
}else {
|
||||
hat.refreshTimeout();
|
||||
}
|
||||
}
|
||||
}
|
||||
private Map<Inet6Address,Long> toIpBandwidth=new ConcurrentHashMap<Inet6Address,Long>();
|
||||
|
||||
public void updateTotalRequestBandwidth(Inet6Address targetaAddress, Long treq) {
|
||||
Objects.requireNonNull(targetaAddress);
|
||||
//System.out.println("到"+targetaAddress.getHostAddress()+"请求带宽更新:"+treq);
|
||||
if(treq<=0) {
|
||||
if(toIpBandwidth.remove(targetaAddress)!=null) {
|
||||
noticeUpdate();
|
||||
}
|
||||
}else {
|
||||
Long old=toIpBandwidth.put(targetaAddress, treq);
|
||||
if(old==null||old.longValue()!=treq.longValue()) {
|
||||
noticeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
public Inet6Address getDijkstraPrevNode(Inet6Address text) {
|
||||
NetmapDirections directionsx=directions;
|
||||
if(directionsx==null)
|
||||
return null;
|
||||
long number= directionsx.getDirection_airs().get(text);
|
||||
long prev= directionsx.getDirection()[(int)number];
|
||||
if(prev==-1) {
|
||||
return null;
|
||||
}
|
||||
return directionsx.getDirection_rias().get((int) prev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
|
||||
public KLALBRoutingProtocolPacket(int type) {
|
||||
super();
|
||||
header=NetworkPacket.databufferpool_40.borrow();
|
||||
header=NetworkPacket.bufferAllocator.allocate(40);
|
||||
header.put((byte) type);
|
||||
}
|
||||
@Override
|
||||
@@ -49,7 +49,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
|
||||
|
||||
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
sndtime=System.nanoTime();
|
||||
dto.write(header.slice(0, (int) getHeaderSize()));
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
rcvtime=System.nanoTime();
|
||||
//System.out.println(this+" "+getHeaderSize());
|
||||
header.limit((int) getHeaderSize());
|
||||
@@ -89,12 +89,6 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
return header;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/* ByteBuffer headerx=header;
|
||||
header=null;
|
||||
KLALBRoutingProtocolPacket.databufferpool_40.back(headerx);*/
|
||||
}
|
||||
|
||||
public static KLALBRoutingProtocolPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
|
||||
return readKLALBPacketFromChannel(Channels.newChannel(in));
|
||||
@@ -102,7 +96,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
|
||||
public static KLALBRoutingProtocolPacket 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) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import java.net.Inet6Address;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.ipv6.Neighbor;
|
||||
|
||||
public class NeighborInfo implements Serializable {
|
||||
@Override
|
||||
@@ -26,13 +27,16 @@ public class NeighborInfo implements Serializable {
|
||||
private Inet6AddressGroup local;
|
||||
private Inet6AddressGroup neighbor;
|
||||
private Inet6AddressGroup locator;
|
||||
public NeighborInfo(Inet6AddressGroup local,Inet6AddressGroup neighbor,Inet6AddressGroup locator, long uploadDelay, long downloadDelay, long uploadSpeed, long downloadSpeed, long uploadspeedmax, long downloadspeedmax) {
|
||||
private transient Neighbor context;
|
||||
public NeighborInfo(Inet6AddressGroup local,Inet6AddressGroup neighbor,Inet6AddressGroup locator, long uploadDelay, long downloadDelay,long uploadDelayMin, long downloadDelayMin, long uploadSpeed, long downloadSpeed, long uploadspeedmax, long downloadspeedmax) {
|
||||
super();
|
||||
this.local=local;
|
||||
this.neighbor = neighbor;
|
||||
this.locator=locator;
|
||||
this.uploadDelay = uploadDelay;
|
||||
this.downloadDelay = downloadDelay;
|
||||
this.uploadDelayMin = uploadDelayMin;
|
||||
this.downloadDelayMin= downloadDelayMin;
|
||||
this.uploadSpeed = uploadSpeed;
|
||||
this.downloadSpeed = downloadSpeed;
|
||||
this.uploadSpeedMax=uploadspeedmax;
|
||||
@@ -40,12 +44,24 @@ public class NeighborInfo implements Serializable {
|
||||
}
|
||||
public NeighborInfo() {
|
||||
}
|
||||
|
||||
private long uploadDelay;
|
||||
private long downloadDelay;
|
||||
private long uploadDelayMin;
|
||||
private long downloadDelayMin;
|
||||
private long uploadSpeed;
|
||||
private long downloadSpeed;
|
||||
private long uploadSpeedMax;
|
||||
private long downloadSpeedMax;
|
||||
|
||||
|
||||
|
||||
public void setContext(Neighbor context) {
|
||||
this.context = context;
|
||||
}
|
||||
public Neighbor getContext() {
|
||||
return context;
|
||||
}
|
||||
public Inet6AddressGroup getNeighbor() {
|
||||
return neighbor;
|
||||
}
|
||||
@@ -100,6 +116,7 @@ public class NeighborInfo implements Serializable {
|
||||
public void setLocator(Inet6AddressGroup locator) {
|
||||
this.locator = locator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(local, locator, neighbor);
|
||||
@@ -122,6 +139,8 @@ public class NeighborInfo implements Serializable {
|
||||
locator.writeToStream(out);
|
||||
out.writeLong(uploadDelay);
|
||||
out.writeLong(downloadDelay);
|
||||
out.writeLong(uploadDelayMin);
|
||||
out.writeLong(downloadDelayMin);
|
||||
out.writeLong(uploadSpeed);
|
||||
out.writeLong(downloadSpeed);
|
||||
out.writeLong(uploadSpeedMax);
|
||||
@@ -134,9 +153,17 @@ public class NeighborInfo implements Serializable {
|
||||
locator=new Inet6AddressGroup(in);
|
||||
uploadDelay=in.readLong();
|
||||
downloadDelay=in.readLong();
|
||||
uploadDelayMin=in.readLong();
|
||||
downloadDelayMin=in.readLong();
|
||||
uploadSpeed=in.readLong();
|
||||
downloadSpeed=in.readLong();
|
||||
uploadSpeedMax=in.readLong();
|
||||
downloadSpeedMax=in.readLong();
|
||||
}
|
||||
public long getUploadDelayMin() {
|
||||
return uploadDelayMin;
|
||||
}
|
||||
public long getDownloadDelayMin() {
|
||||
return downloadDelayMin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import java.nio.ByteBuffer;
|
||||
|
||||
public class PAD1SegmentRoutingTLV extends IPv6SegmentRoutingTLV {
|
||||
|
||||
public PAD1SegmentRoutingTLV(int type) {
|
||||
super(type);
|
||||
public PAD1SegmentRoutingTLV() {
|
||||
super(IPv6SegmentRoutingTLV.PAD1);
|
||||
}
|
||||
|
||||
public PAD1SegmentRoutingTLV(ByteBuffer klalbHeader) {
|
||||
|
||||
@@ -11,19 +11,20 @@ public class PADNSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
|
||||
super(klalbHeader);
|
||||
}
|
||||
|
||||
public PADNSegmentRoutingTLV(int type) {
|
||||
super(type);
|
||||
public PADNSegmentRoutingTLV(int dataLength) {
|
||||
super(IPv6SegmentRoutingTLV.PADN);
|
||||
getData().limit(dataLength);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
|
||||
super.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);
|
||||
|
||||
}
|
||||
|
||||
@@ -30,12 +30,20 @@ public class RouterInfo implements Serializable{
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Inet6AddressGroup locator;
|
||||
private long asn;
|
||||
public Inet6AddressGroup getLocator() {
|
||||
return locator;
|
||||
}
|
||||
public void setLocator(Inet6AddressGroup locator) {
|
||||
this.locator = locator;
|
||||
}
|
||||
|
||||
public long getAsn() {
|
||||
return asn;
|
||||
}
|
||||
public void setAsn(long asn) {
|
||||
this.asn = asn;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(locator, neighborAddresses);
|
||||
@@ -51,7 +59,7 @@ public class RouterInfo implements Serializable{
|
||||
RouterInfo other = (RouterInfo) obj;
|
||||
return Objects.equals(locator, other.locator) && Objects.equals(neighborAddresses, other.neighborAddresses);
|
||||
}
|
||||
private Set<NeighborInfo> neighborAddresses=new HashSet<>();
|
||||
private List<NeighborInfo> neighborAddresses=new ArrayList<>();
|
||||
private long createTime;
|
||||
|
||||
|
||||
@@ -59,7 +67,7 @@ public class RouterInfo implements Serializable{
|
||||
return createTime;
|
||||
}
|
||||
private static final long INFO_UPDATETIME=10000000000L;
|
||||
private static final long INFO_TIMEOUT=20000000000L;
|
||||
private static final long INFO_TIMEOUT=120000000000L;
|
||||
private long putTime=System.nanoTime();
|
||||
public boolean checkUpdateTime() {
|
||||
return System.nanoTime()-putTime>INFO_UPDATETIME;
|
||||
@@ -74,21 +82,24 @@ public class RouterInfo implements Serializable{
|
||||
return "RINFO [locator=" + locator + ", neighborAddresses=" + neighborAddresses + ", putTime=" + putTime
|
||||
+ "]";
|
||||
}
|
||||
public Set<NeighborInfo> getNeighborAddresses() {
|
||||
public List<NeighborInfo> getNeighborAddresses() {
|
||||
return neighborAddresses;
|
||||
}
|
||||
|
||||
public RouterInfo( long createTime) {
|
||||
public RouterInfo( long createTime,Inet6AddressGroup locator,long asn) {
|
||||
this.createTime = createTime;
|
||||
this.locator=locator;
|
||||
this.asn=asn;
|
||||
}
|
||||
|
||||
public RouterInfo() {
|
||||
}
|
||||
public void writeToStream(DataOutputStream out) throws IOException {
|
||||
locator.writeToStream(out);
|
||||
out.writeLong(asn);
|
||||
out.writeLong(createTime);
|
||||
out.writeInt(neighborAddresses.size());
|
||||
for (Iterator iterator = neighborAddresses.iterator(); iterator.hasNext();) {
|
||||
NeighborInfo neighborInfo = (NeighborInfo) iterator.next();
|
||||
for( NeighborInfo neighborInfo :neighborAddresses) {
|
||||
neighborInfo.writeToStream(out);
|
||||
}
|
||||
}
|
||||
@@ -101,9 +112,10 @@ public class RouterInfo implements Serializable{
|
||||
}
|
||||
public void readFromStream(DataInputStream in) throws IOException {
|
||||
locator=new Inet6AddressGroup(in);
|
||||
asn=in.readLong();
|
||||
createTime=in.readLong();
|
||||
int size=in.readInt();
|
||||
neighborAddresses=new HashSet<>(size);
|
||||
neighborAddresses=new ArrayList<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
NeighborInfo nif=new NeighborInfo();
|
||||
nif.readFromStream(in);
|
||||
|
||||
@@ -24,9 +24,10 @@ import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
|
||||
public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Serializable{
|
||||
|
||||
public RouterInfoPacket(RouterInfo routerInfo, boolean flood) {
|
||||
public RouterInfoPacket(RouterInfo routerInfo, boolean flood,long asn) {
|
||||
super(RINFO);
|
||||
getHeader().put(1,(byte) (flood?1:0));
|
||||
getHeader().putLong(2,asn);
|
||||
this.rinfo=routerInfo;
|
||||
}
|
||||
protected RouterInfoPacket(ByteBuffer bb) {
|
||||
@@ -39,12 +40,16 @@ public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Seri
|
||||
return (getHeader().get(1)&1)==1;
|
||||
}
|
||||
|
||||
public long getASN() {
|
||||
return getHeader().getLong(2);
|
||||
}
|
||||
|
||||
public RouterInfo getRinfo() {
|
||||
return rinfo;
|
||||
}
|
||||
@Override
|
||||
protected long getHeaderSize() {
|
||||
return super.getHeaderSize()+1;
|
||||
return super.getHeaderSize()+9;
|
||||
}
|
||||
@Override
|
||||
public long getLength() {
|
||||
@@ -60,12 +65,12 @@ public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Seri
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
super.writeToChannel(dto);
|
||||
rinfo.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);
|
||||
rinfo=new RouterInfo();
|
||||
rinfo.readFromChannel(din, length);
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SEQSSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
|
||||
public SEQSSegmentRoutingTLV(ByteBuffer klalbHeader) {
|
||||
super(klalbHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SEQSSegmentRoutingTLV [getSequence()=" + getSequence() + "]";
|
||||
}
|
||||
|
||||
public SEQSSegmentRoutingTLV(long sequence,UUID uuid, boolean promise,boolean keeporder/*,int flownumber,long flowsequence*/) {
|
||||
super(IPv6SegmentRoutingTLV.SEQS);
|
||||
setSequence(sequence);
|
||||
setUUID(uuid);
|
||||
setPromise(promise);
|
||||
setKeepOrder(keeporder);
|
||||
//setFlowNumber(flownumber);
|
||||
//setFlowSequence(flowsequence);
|
||||
//getData().limit(14);
|
||||
//getData().limit(22);
|
||||
getData().limit(30);
|
||||
}
|
||||
|
||||
public void setUUID(UUID uuid) {
|
||||
getData().putLong(14,uuid.getMostSignificantBits());
|
||||
getData().putLong(22,uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return new UUID(getData().getLong(14),getData().getLong(22));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
|
||||
super.writeToChannel(dto);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
super.readFromChannel(din, length);
|
||||
|
||||
}
|
||||
|
||||
public long getSequence() {
|
||||
return getData().getLong(6);
|
||||
}
|
||||
public void setSequence(long sequence) {
|
||||
getData().putLong(6,sequence);
|
||||
}
|
||||
|
||||
public int getFlowNumber() {
|
||||
return getData().getInt(2);
|
||||
}
|
||||
public void setFlowNumber(int flowsequence) {
|
||||
getData().putInt(2,flowsequence);
|
||||
}
|
||||
|
||||
/*public long getFlowSequence() {
|
||||
return getData().getLong(14);
|
||||
}
|
||||
public void setFlowSequence(long flowsequence) {
|
||||
getData().putLong(14,flowsequence);
|
||||
}*/
|
||||
|
||||
public boolean isPromise() {
|
||||
return getData().get(0)!=0?true:false;
|
||||
}
|
||||
|
||||
public void setPromise(boolean promise) {
|
||||
if(promise) {
|
||||
getData().put(0, (byte) 1);
|
||||
}else {
|
||||
getData().put(0, (byte) 0);
|
||||
}
|
||||
}
|
||||
public boolean isKeepOrder() {
|
||||
return getData().get(1)!=0?true:false;
|
||||
}
|
||||
|
||||
public void setKeepOrder(boolean keeporder) {
|
||||
if(keeporder) {
|
||||
getData().put(1, (byte) 1);
|
||||
}else {
|
||||
getData().put(1, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
|
||||
public class SRv6PacketReorder {
|
||||
|
||||
private PacketConsumer packetConsumer;
|
||||
|
||||
public SRv6PacketReorder(PacketConsumer packetConsumer) {
|
||||
this.packetConsumer=packetConsumer;
|
||||
}
|
||||
|
||||
private long jumpTime=500000000L;
|
||||
|
||||
private Map<Long,IPv6Packet>map=new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
private long orderTime=System.nanoTime();
|
||||
private AtomicLong seqptr=new AtomicLong();
|
||||
|
||||
public void put(IPv6Packet pack, long sequence) throws IOException {
|
||||
//System.out.println(pack.getFlowLabel()+" "+sequence);
|
||||
map.put(sequence,pack);
|
||||
runOrdering();
|
||||
}
|
||||
private ReentrantLock orderLock=new ReentrantLock();
|
||||
public void runOrdering() throws IOException {
|
||||
orderLock.lock();
|
||||
try {
|
||||
boolean whi=false;
|
||||
do {
|
||||
whi=false;
|
||||
|
||||
while(true) {
|
||||
IPv6Packet i6p=map.remove(seqptr.get());
|
||||
if(i6p!=null) {
|
||||
//System.out.println("Ord:"+i6p.getFlowLabel()+" "+seqptr.get());
|
||||
seqptr.getAndIncrement();
|
||||
orderTime=System.nanoTime();
|
||||
if(packetConsumer!=null) {
|
||||
packetConsumer.accept(i6p);
|
||||
}
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
long ct=System.nanoTime();
|
||||
if(ct-orderTime>jumpTime) {
|
||||
orderTime=ct;
|
||||
long l=Long.MAX_VALUE;
|
||||
for(Long ent:map.keySet()) {
|
||||
if(ent<l) {
|
||||
l=ent;
|
||||
}
|
||||
}
|
||||
seqptr.set(l);
|
||||
whi=true;
|
||||
}
|
||||
|
||||
}while(whi);
|
||||
|
||||
}finally {
|
||||
orderLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.ipv6.FlowSession;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
|
||||
public class SRv6PacketSeqMarker {
|
||||
private Map<FlowSession,AtomicLong> flowseqMap=new ConcurrentHashMap<FlowSession,AtomicLong>();
|
||||
public void mark(IPv6Packet ipp) {
|
||||
AtomicLong nal=new AtomicLong();
|
||||
AtomicLong rez=flowseqMap.putIfAbsent(ipp.getFlowSession(), nal);
|
||||
if(rez==null) {
|
||||
rez=nal;
|
||||
}
|
||||
ipp.setFlowSeqMark(rez.getAndIncrement());
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -15,18 +16,19 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.acclerate.FastLib;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.ipv6.FlowSession;
|
||||
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
||||
@@ -74,8 +76,10 @@ import com.google.gson.internal.Pair;
|
||||
public class SRv6Router {
|
||||
private static final boolean debug = false;
|
||||
|
||||
public static final int MTU = 9000;
|
||||
public static final int MTU = 8192;
|
||||
|
||||
public static final int MAX_REROUTE_COUNT=2;//1
|
||||
|
||||
public static final IpV6RoutingType SRH_HEADER = new IpV6RoutingType((byte) 4, "SRH Header");
|
||||
// private List<NetworkLink>links=new ArrayList<>();
|
||||
|
||||
@@ -140,7 +144,7 @@ public class SRv6Router {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCongress(IPv6Packet iPv6Packet) {
|
||||
public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -170,6 +174,40 @@ public class SRv6Router {
|
||||
return loopbackAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RouteItem> getRouteItems() {
|
||||
List<RouteItem> rlist=new ArrayList<>();
|
||||
|
||||
rlist.add(new RouteItem(new Inet6AddressGroup(this.getAddressGroup().getAddress(), 128),
|
||||
this.getAddressGroup().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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
public List<RouteItem> getRouteTabel() {
|
||||
@@ -180,32 +218,44 @@ public class SRv6Router {
|
||||
return routeTabel0;
|
||||
}
|
||||
|
||||
|
||||
private Consumer<IPv6Packet> defaultReroute = new Consumer<IPv6Packet>() {
|
||||
|
||||
@Override
|
||||
public void accept(IPv6Packet t) {
|
||||
//HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||
routePacket(t,true);
|
||||
t.putTimePassport("rerouted");
|
||||
//});
|
||||
}
|
||||
};
|
||||
private Consumer<IPv6Packet> defaultReceive = new Consumer<IPv6Packet>() {
|
||||
|
||||
@Override
|
||||
public void accept(IPv6Packet t) {
|
||||
HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||
//HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||
routePacket(t);
|
||||
t.putTimePassport("routed");
|
||||
});
|
||||
//});
|
||||
}
|
||||
};
|
||||
private Consumer<IPv6Packet> srhReceive = new Consumer<IPv6Packet>() {
|
||||
|
||||
@Override
|
||||
public void accept(IPv6Packet t) {
|
||||
HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||
//HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||
insertSRHandRoutePacket(t);
|
||||
});
|
||||
//});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private volatile UUID suid=UUID.randomUUID();
|
||||
public void updateRouteTabel() {
|
||||
List<RouteItem> routeTabel0x = new ArrayList<>();
|
||||
|
||||
for (Iterator<IPv6NetworkLink> iterator = linkTabel.iterator(); iterator.hasNext();) {
|
||||
IPv6NetworkLink nlink = (IPv6NetworkLink) iterator.next();
|
||||
if (nlink.isLoopBack()) {
|
||||
/*if (nlink.isLoopBack()) {
|
||||
if (nlink instanceof IPv6TUNLoopbackNetworkLink) {
|
||||
routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128),
|
||||
nlink.getAddressGroup().getAddress(), nlink, "Direct", 0, 1, null, "D"));
|
||||
@@ -215,10 +265,7 @@ public class SRv6Router {
|
||||
nlink.getAddressGroup().getAddress(), nlink, "Direct", 0, 0, null, "D"));
|
||||
|
||||
}
|
||||
}/*else {
|
||||
routeTabel0x.add(new RouteItem(new Inet6AddressGroup(nlink.getAddressGroup().getAddress(), 128),
|
||||
nlink.getAddressGroup().getAddress(), inLoopBack, "Direct", 0, 0, null, "D"));
|
||||
}*/
|
||||
}
|
||||
for (Iterator<Neighbor> iteratorx = nlink.getNeighborsInfo()
|
||||
.iterator(); iteratorx.hasNext();) {
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
@@ -230,9 +277,11 @@ public class SRv6Router {
|
||||
nlink, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D");
|
||||
routeTabel0x.add(ris);
|
||||
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
List<RouteItem>routes=nlink.getRouteItems();
|
||||
|
||||
routeTabel0x.addAll(routes);
|
||||
|
||||
if (nlink instanceof IPv6TUNLoopbackNetworkLink) {
|
||||
|
||||
@@ -240,14 +289,28 @@ public class SRv6Router {
|
||||
} else {
|
||||
nlink.setReceiveConsumer(defaultReceive);
|
||||
}
|
||||
nlink.setRerouteConsumer(defaultReroute);
|
||||
}
|
||||
|
||||
/*List<RouteItem> routeTabel1x=new ArrayList<>(routeTabel0x.size());
|
||||
|
||||
routeTabel0x.addAll(routeTabel);
|
||||
for (Iterator<RouteItem> iterator = routeTabel0x.iterator(); iterator.hasNext();) {
|
||||
RouteItem routeItem = (RouteItem) iterator.next();
|
||||
routeTabel1x.add((RouteItem) routeItem.clone());
|
||||
}*/
|
||||
for (Iterator<RouteItem> iterator = routeTabel0x.iterator(); iterator.hasNext();) {
|
||||
RouteItem routeItem = (RouteItem) iterator.next();
|
||||
routeItem.preSort();
|
||||
|
||||
}
|
||||
Collections.sort(routeTabel0x);
|
||||
routeTabel0 = routeTabel0x;
|
||||
suid=UUID.randomUUID();
|
||||
}
|
||||
|
||||
private Inet6AddressGroup locator;
|
||||
private long asn=new SecureRandom().nextLong(1,Long.MAX_VALUE);
|
||||
/*
|
||||
* public List<NetworkLink> getLinks() { return links; }
|
||||
*/
|
||||
@@ -259,42 +322,50 @@ public class SRv6Router {
|
||||
return locator;
|
||||
}
|
||||
|
||||
public long getASN() {
|
||||
return asn;
|
||||
}
|
||||
|
||||
public void setASN(long asn) {
|
||||
this.asn = asn;
|
||||
}
|
||||
|
||||
public void setLocator(Inet6AddressGroup locator) {
|
||||
this.locator = locator;
|
||||
updateRouteTabel();
|
||||
}
|
||||
|
||||
|
||||
private ConcurrentHashMap<FlowSession, TCPTransimitAgent> swist = new ConcurrentHashMap<>();
|
||||
//private ConcurrentHashMap<FlowSession, TCPTransimitAgent> swist = new ConcurrentHashMap<>();
|
||||
|
||||
// private AtomicLong qsn=new AtomicLong();
|
||||
public void insertSRHandRoutePacket(IPv6Packet ipp) {
|
||||
insertSRH(ipp);
|
||||
ipp.putTimePassport("SRH inserted");
|
||||
routePacket(ipp);
|
||||
ipp.putTimePassport("routed");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void insertSRH(IPv6Packet ipp) {
|
||||
if(ipp.getSRHHeader()!=null) {
|
||||
throw new IllegalStateException("packet already has SRH!");
|
||||
}
|
||||
if (klalbRouteProtol != null) {
|
||||
List<Inet6Address> segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress());
|
||||
// System.out.println(segs);
|
||||
if (segs != null && (!segs.isEmpty())) {
|
||||
/*
|
||||
* List<SRv6TLV>tlvs=new ArrayList<>(1); if(ipp.getPayload().getType()==6) {
|
||||
* SRv6StreamSequenceTLV sers= new SRv6StreamSequenceTLV();
|
||||
* sers.setSequence(qsn.getAndIncrement()); tlvs.add(sers); }
|
||||
*/
|
||||
|
||||
//IpV6RoutingSRHData srh = new IpV6RoutingSRHData(segs);
|
||||
|
||||
|
||||
IPv6SegmentRoutingHeader irh = new IPv6SegmentRoutingHeader(segs);
|
||||
|
||||
//System.out.println(ipp.getFlowLabel());
|
||||
ThreadLocalRandom tlr=ThreadLocalRandom.current();
|
||||
//System.out.println(ipp.getFlowSeqMark());
|
||||
irh.getTlvs().add(new SEQSSegmentRoutingTLV(ipp.getFlowSeqMark(),new UUID(suid.getMostSignificantBits()^tlr.nextLong(),suid.getMostSignificantBits()^tlr.nextLong()),ipp.isPromise(),ipp.getFlowSeqMark()!=-1));
|
||||
|
||||
ipp.getHeaders().add(irh);
|
||||
|
||||
|
||||
ipp.setDestinationAddress(segs.get(segs.size() - 1));
|
||||
/*
|
||||
* if(ipp.getPayload().getType()==6) System.out.println(ipp);
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -303,7 +374,14 @@ public class SRv6Router {
|
||||
private volatile List<RouteItem> routeTabel0 = new ArrayList<>();
|
||||
|
||||
// private ReentrantReadWriteLock routelock=new ReentrantReadWriteLock();
|
||||
|
||||
|
||||
//路由数据包
|
||||
public void routePacket(IPv6Packet iPv6Packet) {
|
||||
routePacket(iPv6Packet ,false);
|
||||
}
|
||||
//路由数据包
|
||||
public void routePacket(IPv6Packet iPv6Packet, boolean reroute) {
|
||||
// routelock.readLock().lock();
|
||||
// try {
|
||||
// System.out.println("路由表:"+routeTabel0);
|
||||
@@ -311,96 +389,55 @@ public class SRv6Router {
|
||||
if (debug) {
|
||||
dbg=new StringBuilder();
|
||||
}
|
||||
iPv6Packet.lockAll();
|
||||
try {
|
||||
if(iPv6Packet.isSomeDisposed())
|
||||
return;
|
||||
int hop = iPv6Packet.getHopLimit();
|
||||
int hop = iPv6Packet.getHopLimit();//检查TTL值,只有大于0才会被转发,否则丢弃
|
||||
if (hop > 0) {
|
||||
// List<RouteItem> mached=new ArrayList<>();
|
||||
// RouteItem pri=null;
|
||||
|
||||
Inet6Address ia = iPv6Packet.getDestinationAddress();
|
||||
if (debug) {
|
||||
dbg.append("----------------------------------------\n");
|
||||
dbg.append("packet:" + iPv6Packet.getSourceAddress().getHostAddress() + "->"
|
||||
+ iPv6Packet.getDestinationAddress().getHostAddress()+"\n");
|
||||
}
|
||||
for (int i = 0; i < routeTabel0.size(); i++) {
|
||||
RouteItem tri = routeTabel0.get(i);
|
||||
if (!tri.checkMatch(ia)) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("unmatched.\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!tri.getDestlink().isUp()) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("linkdown.\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (tri.getDestlink().isCongress(iPv6Packet)) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("congress.\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!tri.getDestlink().canSend(iPv6Packet)) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("linkrefused.\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("matched.\n");
|
||||
}
|
||||
processPacket(iPv6Packet, tri);
|
||||
return;
|
||||
/*
|
||||
* if(pri==null||pri.equals(tri)) { mached.add(tri); pri=tri; }else { break; }
|
||||
*/
|
||||
}
|
||||
if (debug) {
|
||||
dbg.append("miss.\n");
|
||||
}
|
||||
if (iPv6Packet.isEnableECN()) {
|
||||
iPv6Packet.markCE();
|
||||
for (int i = 0; i < routeTabel0.size(); i++) {
|
||||
RouteItem tri = routeTabel0.get(i);
|
||||
if (tri.checkMatch(ia)) {
|
||||
if (!tri.getDestlink().isUp()) {
|
||||
continue;
|
||||
}
|
||||
processPacket(iPv6Packet, tri);
|
||||
return;
|
||||
/*
|
||||
* if(pri==null||pri.equals(tri)) { mached.add(tri); pri=tri; }else { break; }
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
//按延迟顺序从小到大匹配路由表
|
||||
if(searchTableAndFoward(iPv6Packet, reroute, dbg)) {
|
||||
//匹配到路由表,返回
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
if (debug)
|
||||
dbg.append("congress\n");
|
||||
// System.out.println(ia.getAddress()+" match "+ri);
|
||||
/*
|
||||
* for (Iterator iterator = mached.iterator(); iterator.hasNext();) { RouteItem
|
||||
* routeItem = (RouteItem) iterator.next();
|
||||
* if(routeItem.getDestlink().isCongress()) {
|
||||
*
|
||||
* }else { processPacket(iPv6Packet,pri); break; } }
|
||||
*/
|
||||
// else
|
||||
// System.out.println("路由失败:"+iPv6Packet);
|
||||
|
||||
dbg.append("noroute\n");
|
||||
//System.out.println("找不到路由表:"+iPv6Packet.getSourceAddress().getHostAddress()+" -> "+iPv6Packet.getDestinationAddress().getHostAddress());
|
||||
|
||||
//未找到合适的路由表或路由表对应的链路down,使用FRR保护创建备用路由表
|
||||
IPv6SegmentRoutingHeader srh=iPv6Packet.getSRHHeader();
|
||||
if(srh!=null) {
|
||||
System.out.println("原SRH:"+srh);
|
||||
int segmentsLeft=srh.getSegmentsLeft();
|
||||
if(segmentsLeft>0) {
|
||||
srh.getAddresses().remove(segmentsLeft);
|
||||
segmentsLeft--;
|
||||
}
|
||||
List<Inet6Address> repairSegments= klalbRouteProtol.createSegmentList(srh.getAddresses().get(segmentsLeft));
|
||||
if(repairSegments ==null) {
|
||||
System.out.println("FRR保护失败");
|
||||
return;
|
||||
}
|
||||
repairSegments.remove(0);
|
||||
srh.getAddresses().addAll(segmentsLeft+1, repairSegments);
|
||||
segmentsLeft+=repairSegments.size();
|
||||
srh.setSegmentsLeft(segmentsLeft);
|
||||
iPv6Packet.setDestinationAddress(srh.getAddresses().get(segmentsLeft));
|
||||
}else {
|
||||
return;
|
||||
}
|
||||
System.out.println("FRR修复SRH:"+srh);
|
||||
if(searchTableAndFoward(iPv6Packet, reroute, dbg)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
IcmpV6TimeExceededPacket.Builder icmpte = new IcmpV6TimeExceededPacket.Builder();
|
||||
ByteBuffer IPv6data = NetworkPacket.databufferpool_65535.borrow();
|
||||
ByteBuffer IPv6data = NetworkPacket.bufferAllocator.allocate(65535);
|
||||
iPv6Packet.writeToChannel(KNEChannels.newWritableChannel(IPv6data));
|
||||
byte[] raw = new byte[IPv6data.remaining()];
|
||||
IPv6data.get(0, raw);
|
||||
@@ -433,34 +470,206 @@ public class SRv6Router {
|
||||
if(debug) {
|
||||
System.out.println(dbg.toString());
|
||||
}
|
||||
iPv6Packet.unlockAll();
|
||||
}
|
||||
// }finally {
|
||||
// routelock.readLock().unlock();
|
||||
// }
|
||||
}
|
||||
|
||||
private void processPacket(IPv6Packet iPv6Packet, RouteItem ri) throws IllegalRawDataException, IOException {
|
||||
int hop = iPv6Packet.getHopLimit();
|
||||
private boolean searchTableAndFoward(IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg)
|
||||
throws IllegalRawDataException, IOException {
|
||||
byte[] ia = new byte[16];
|
||||
iPv6Packet.getRawDestinationAddress(ia);
|
||||
if (debug) {
|
||||
dbg.append("----------------------------------------\n");
|
||||
dbg.append("packet:" + iPv6Packet.getSourceAddress().getHostAddress() + " -> "
|
||||
+ iPv6Packet.getDestinationAddress().getHostAddress()+"\n");
|
||||
}
|
||||
|
||||
boolean routeFound=false;
|
||||
|
||||
RouteItem prevr=null;
|
||||
List<RouteItem> routes=new ArrayList<>();
|
||||
//遍历路由表
|
||||
for (RouteItem tri: routeTabel0) {
|
||||
if(!tri.checkMatch(ia)) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("unmatched.\n");
|
||||
}
|
||||
//跳过前缀与掩码不符合要求的路由表条目
|
||||
continue;
|
||||
}
|
||||
if (!tri.getDestlink().canSend(iPv6Packet)) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("linkrefused.\n");
|
||||
}
|
||||
//跳过不能转发这种数据包的链路
|
||||
continue;
|
||||
}
|
||||
if (!tri.getDestlink().isUp()) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("linkdown.\n");
|
||||
}
|
||||
//跳过断开连接的链路
|
||||
continue;
|
||||
}
|
||||
routeFound=true;
|
||||
if(prevr!=null) {
|
||||
if(!tri.ECMPequals(prevr)) {
|
||||
//执行流量整形负载均衡调度算法
|
||||
if(routingLoadBalance(iPv6Packet, reroute, dbg, routes)) {
|
||||
return routeFound;
|
||||
}
|
||||
routes.clear();
|
||||
}
|
||||
}
|
||||
//将等价路由加入负载均衡列表
|
||||
routes.add(tri);
|
||||
|
||||
prevr=tri;
|
||||
|
||||
|
||||
|
||||
}
|
||||
routingLoadBalance(iPv6Packet, reroute, dbg, routes);
|
||||
return routeFound;
|
||||
}
|
||||
|
||||
private boolean routingLoadBalance(IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg, List<RouteItem> routes)
|
||||
throws IllegalRawDataException, IOException {
|
||||
|
||||
double cscale=1.0;
|
||||
if(iPv6Packet.getPayload().getProtocolNumber()==6) {
|
||||
cscale=15.0;
|
||||
}
|
||||
|
||||
boolean retry=false;
|
||||
long start=System.nanoTime();
|
||||
do {
|
||||
retry=false;
|
||||
//遍历可用于负载均衡调度的路由表
|
||||
for (RouteItem tri: routes) {
|
||||
if (!tri.getDestlink().isUp()) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("linkdown.\n");
|
||||
}
|
||||
//跳过断开的链路
|
||||
continue;
|
||||
}
|
||||
if (tri.getDestlink().isCongress(iPv6Packet,cscale)) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("congress.\n");
|
||||
}
|
||||
//跳过缓冲区拥塞的链路
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tri.getDestlink().isReachSpeedLimit(iPv6Packet)) {
|
||||
retry=true;
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("reachspeedlimit.\n");
|
||||
}
|
||||
//跳过达到流量整形速度限制的链路(若仅超过流量整形速度限制,可多次重试)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("matched.\n");
|
||||
}
|
||||
//链路可用,处理并转发数据包
|
||||
processPacket(iPv6Packet, tri,reroute);
|
||||
return true;
|
||||
|
||||
}
|
||||
if(retry) {
|
||||
if(System.nanoTime()-start>200000000L) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//Thread.yield();
|
||||
//短暂挂起当前线程,待链路速度未超限时重试发送数据包
|
||||
}
|
||||
}while((!routes.isEmpty())&&retry);
|
||||
if (debug) {
|
||||
dbg.append("miss.\n");
|
||||
}
|
||||
//负载均衡未匹配成功,若数据包支持ECN,打上拥塞标记位
|
||||
if(iPv6Packet.isEnableECN()) {
|
||||
iPv6Packet.markCE();
|
||||
if (debug) {
|
||||
dbg.append("ECN enabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (RouteItem tri: routes) {
|
||||
|
||||
if (!tri.getDestlink().isUp()) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("linkdown.\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (tri.getDestlink().isCongress(iPv6Packet,25.0)) {
|
||||
if (debug) {
|
||||
dbg.append(tri+"\n");
|
||||
dbg.append("congress.\n");
|
||||
}
|
||||
//缓冲区留部分余量避免丢包
|
||||
continue;
|
||||
}
|
||||
processPacket(iPv6Packet, tri,reroute);
|
||||
return true;
|
||||
}
|
||||
//仍未成功发送,丢弃数据包
|
||||
return false;
|
||||
}
|
||||
|
||||
private void processPacket(IPv6Packet iPv6Packet, RouteItem ri, boolean reroute) throws IllegalRawDataException, IOException {
|
||||
int hop = iPv6Packet.getHopLimit();
|
||||
|
||||
if (ri.getDestlink().isLoopBack()) {
|
||||
IPv6SegmentRoutingHeader srhh = getSRHHeaderFromPacket(iPv6Packet);
|
||||
IPv6SegmentRoutingHeader srhh =iPv6Packet. getSRHHeader();
|
||||
if (srhh != null) {
|
||||
processSRv6Packet(iPv6Packet, ri, srhh);
|
||||
processSRv6Packet(iPv6Packet, ri, srhh,reroute);
|
||||
} else {
|
||||
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
|
||||
}
|
||||
} else {
|
||||
if(iPv6Packet.getRerouteCounter().getAndIncrement()>=MAX_REROUTE_COUNT) {
|
||||
|
||||
//System.out.println("reroute count >=2");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!reroute) {
|
||||
// if(!iPv6Packet.isTTLdecreased()) {
|
||||
hop--;
|
||||
/* iPv6Packet.setTTLdecreased(true);
|
||||
}else {
|
||||
System.out.print("ttl err");
|
||||
}*/
|
||||
}
|
||||
// System.out.println(ipp.getHeader().getSrcAddr()+"->"+ipp.getHeader().getDstAddr()+"
|
||||
// "+(hop+1)+"->"+hop);
|
||||
if (hop > 0) {
|
||||
|
||||
|
||||
iPv6Packet.setHopLimit(hop);
|
||||
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
|
||||
} else {
|
||||
IcmpV6TimeExceededPacket.Builder icmpte = new IcmpV6TimeExceededPacket.Builder();
|
||||
ByteBuffer IPv6data = NetworkPacket.databufferpool_65535.borrow();
|
||||
ByteBuffer IPv6data = NetworkPacket.bufferAllocator.allocate(65535);
|
||||
iPv6Packet.writeToChannel(KNEChannels.newWritableChannel(IPv6data));
|
||||
byte[] raw = new byte[IPv6data.remaining()];
|
||||
IPv6data.get(0, raw);
|
||||
@@ -491,37 +700,25 @@ public class SRv6Router {
|
||||
|
||||
}
|
||||
|
||||
private void processSRv6Packet(IPv6Packet iPv6Packet, RouteItem ri, IPv6SegmentRoutingHeader srhh)
|
||||
private void processSRv6Packet(IPv6Packet iPv6Packet, RouteItem ri, IPv6SegmentRoutingHeader srhh, boolean reroute)
|
||||
throws IllegalRawDataException, IOException {
|
||||
/*byte[] srd = new byte[(int) (srhh.getLength() - 4)];
|
||||
srhh.getData().get(4, srd);
|
||||
IpV6RoutingSRHData srh = IpV6RoutingSRHData.newInstance(srd, 0, srd.length);*/
|
||||
|
||||
if (srhh.getSegmentsLeft() <= 0) {
|
||||
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
|
||||
} else {
|
||||
|
||||
if(reroute) {
|
||||
|
||||
}else {
|
||||
int newSL = srhh.getSegmentsLeft() - 1;
|
||||
srhh.setSegmentsLeft(newSL);
|
||||
iPv6Packet.setDestinationAddress(srhh.getAddresses().get(newSL));
|
||||
}
|
||||
klalbRouteProtol.putHotspotAddress(iPv6Packet.getSourceAddress());
|
||||
routePacket(iPv6Packet);
|
||||
routePacket(iPv6Packet,reroute);
|
||||
}
|
||||
}
|
||||
|
||||
private IPv6SegmentRoutingHeader getSRHHeaderFromPacket(IPv6Packet iPv6Packet) {
|
||||
IPv6SegmentRoutingHeader srhh = null;
|
||||
List<IPv6ExtHeader> exhs = iPv6Packet.getHeaders();
|
||||
for (int j = 0; j < exhs.size(); j++) {
|
||||
IPv6ExtHeader exh = exhs.get(j);
|
||||
if (exh instanceof IPv6SegmentRoutingHeader) {
|
||||
if (((IPv6SegmentRoutingHeader) exh).getRoutingType() == 4) {
|
||||
srhh = (IPv6SegmentRoutingHeader) exh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return srhh;
|
||||
}
|
||||
|
||||
|
||||
public SRv6Router(Inet6AddressGroup hostAddress) {
|
||||
super();
|
||||
@@ -551,19 +748,20 @@ public class SRv6Router {
|
||||
return klalbRouteProtol;
|
||||
}
|
||||
|
||||
private Map<Integer, PacketConsumer> protocolNumberRegister = new ConcurrentHashMap<>();
|
||||
private Map<Integer, PacketConsumer> protocolNumberRegister = new ConcurrentHashMap<>(256*2);
|
||||
|
||||
public Map<Integer, PacketConsumer> getProtocolNumberRegister() {
|
||||
return protocolNumberRegister;
|
||||
}
|
||||
|
||||
public void putProtocolNumberPacketAndInsertSRH(IPv6Packet pkt) {
|
||||
|
||||
/*public void putProtocolNumberPacketAndInsertSRHAsync(IPv6Packet pkt) {
|
||||
// inLoopBack.getReceiveConsumer().accept(pkt);
|
||||
srhReceive.accept(pkt);
|
||||
}
|
||||
|
||||
public void putProtocolNumberPacket(IPv6Packet pkt) {
|
||||
public void putProtocolNumberPacketAsync(IPv6Packet pkt) {
|
||||
// inLoopBack.getReceiveConsumer().accept(pkt);
|
||||
defaultReceive.accept(pkt);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ public class SingleDijkstraAlgorithm implements DijkstraAlgorithm {
|
||||
private long startPoint;
|
||||
|
||||
|
||||
private static final long MAX_WEIGHT=Long.MAX_VALUE/256L;
|
||||
@Override
|
||||
public void setGraph(long[][] pointers,long[][] heap,long startPoint) {
|
||||
this.heap=heap;
|
||||
|
||||
Reference in New Issue
Block a user