forked from KNEMC/KLALB
KLALB 3.6.0开发一半的状态
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
|
||||
public interface IPv6PacketConsumer {
|
||||
public void accept(IPv6Packet packx)throws IOException;
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import static org.pcap4j.util.ByteArrays.*;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.pcap4j.packet.IllegalRawDataException;
|
||||
import org.pcap4j.packet.IpV6ExtRoutingPacket.IpV6RoutingData;
|
||||
import org.pcap4j.util.ByteArrays;
|
||||
|
||||
|
||||
public final class IpV6RoutingSRHData implements IpV6RoutingData {
|
||||
|
||||
/** */
|
||||
private static final long serialVersionUID = -7972526977248222954L;
|
||||
|
||||
private final int lastEntry;
|
||||
private final int flags;
|
||||
private final int tag;
|
||||
private final List<Inet6Address> addresses;
|
||||
private final List<SRv6TLV> tlvs;
|
||||
|
||||
/**
|
||||
* A static factory method. This method validates the arguments by {@link
|
||||
* ByteArrays#validateBounds(byte[], int, int)}, which may throw exceptions undocumented here.
|
||||
*
|
||||
* @param rawData rawData
|
||||
* @param offset offset
|
||||
* @param length length
|
||||
* @return a new IpV6RoutingSourceRouteData object.
|
||||
* @throws IllegalRawDataException if parsing the raw data fails.
|
||||
*/
|
||||
public static IpV6RoutingSRHData newInstance(byte[] rawData, int offset, int length)
|
||||
throws IllegalRawDataException {
|
||||
return new IpV6RoutingSRHData(rawData, offset, length);
|
||||
}
|
||||
|
||||
private IpV6RoutingSRHData(byte[] rawData, int offset, int length)
|
||||
throws IllegalRawDataException {
|
||||
|
||||
this.lastEntry = rawData[ offset]&0xff;
|
||||
this.flags=rawData[offset+1]&0xff;
|
||||
this.tag=ByteArrays.getShort(rawData, offset+2);
|
||||
this.addresses = new ArrayList<Inet6Address>();
|
||||
this.tlvs=new ArrayList<>();
|
||||
|
||||
int endv=INT_SIZE_IN_BYTES+(lastEntry+1)*INET6_ADDRESS_SIZE_IN_BYTES;
|
||||
for (int i = INT_SIZE_IN_BYTES; i < endv; i += INET6_ADDRESS_SIZE_IN_BYTES) {
|
||||
addresses.add(ByteArrays.getInet6Address(rawData, i + offset));
|
||||
}
|
||||
for(int itlv=endv;itlv<length;) {
|
||||
int type=rawData[itlv+offset]&0xff;
|
||||
switch(type) {
|
||||
case SRv6TLV.PAD1:
|
||||
itlv++;
|
||||
tlvs.add(new SRv6Pad1TLV());
|
||||
break;
|
||||
case SRv6TLV.PADN:
|
||||
itlv++;
|
||||
int lengthPN=rawData[itlv+offset]&0xff;
|
||||
tlvs.add(new SRv6PadNTLV(lengthPN));
|
||||
itlv+=1+lengthPN;
|
||||
break;
|
||||
case SRv6TLV.SEQS:
|
||||
itlv++;
|
||||
int lengthQTLV=rawData[itlv+offset]&0xff;
|
||||
byte[]rawQTLV=new byte[lengthQTLV];
|
||||
System.arraycopy(rawData, itlv+offset+1, rawQTLV, 0, lengthQTLV);
|
||||
tlvs.add(new SRv6StreamSequenceTLV( lengthQTLV, rawQTLV));
|
||||
itlv+=1+lengthQTLV;
|
||||
break;
|
||||
default:
|
||||
itlv++;
|
||||
int lengthTLV=rawData[itlv+offset]&0xff;
|
||||
byte[]rawTLV=new byte[lengthTLV];
|
||||
System.arraycopy(rawData, itlv+offset+1, rawTLV, 0, lengthTLV);
|
||||
tlvs.add(new SRv6TLV(type, lengthTLV, rawTLV));
|
||||
itlv+=1+lengthTLV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<SRv6TLV> getTlvs() {
|
||||
return tlvs;
|
||||
}
|
||||
|
||||
public int getLastEntry() {
|
||||
return lastEntry;
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public List<Inet6Address> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public IpV6RoutingSRHData(List<Inet6Address> addresses) {
|
||||
this(0,0,addresses,new ArrayList<>());
|
||||
}
|
||||
public IpV6RoutingSRHData(List<Inet6Address> addresses,List<SRv6TLV>tlvs) {
|
||||
this(0,0,addresses,tlvs);
|
||||
}
|
||||
/**
|
||||
* @param reserved reserved
|
||||
* @param addresses addresses
|
||||
*/
|
||||
public IpV6RoutingSRHData(int flags,int tag, List<Inet6Address> addresses,List<SRv6TLV>tlvs) {
|
||||
if (addresses == null) {
|
||||
throw new NullPointerException("addresses must not be null");
|
||||
}
|
||||
this.lastEntry = addresses.size()-1;
|
||||
this.flags=flags;
|
||||
this.tag=tag;
|
||||
this.addresses = new ArrayList<Inet6Address>(addresses);
|
||||
this.tlvs=tlvs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
int tlvsize=0;
|
||||
for (int i = 0; i < tlvs.size(); i++) {
|
||||
tlvsize+=tlvs.get(i).getTotalLength();
|
||||
}
|
||||
return INT_SIZE_IN_BYTES+addresses.size() * INET6_ADDRESS_SIZE_IN_BYTES + tlvsize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getRawData() {
|
||||
byte[] rawData = new byte[length()];
|
||||
rawData[0]=(byte) lastEntry;
|
||||
rawData[1]=(byte) flags;
|
||||
rawData[2]=(byte) (tag>>8);
|
||||
rawData[3]=(byte) tag;
|
||||
;
|
||||
int i = INT_SIZE_IN_BYTES;
|
||||
for ( Iterator<Inet6Address> iter = addresses.iterator(); iter.hasNext(); i += INET6_ADDRESS_SIZE_IN_BYTES) {
|
||||
System.arraycopy(
|
||||
ByteArrays.toByteArray(iter.next()), 0, rawData, i, INET6_ADDRESS_SIZE_IN_BYTES);
|
||||
}
|
||||
for (int j = 0; j < tlvs.size(); j++) {
|
||||
SRv6TLV srt=tlvs.get(j);
|
||||
switch(srt.getType()) {
|
||||
case SRv6TLV.PAD1:
|
||||
rawData[i++]=(byte) srt.getType();
|
||||
break;
|
||||
case SRv6TLV.PADN:
|
||||
rawData[i++]=(byte) srt.getType();
|
||||
int plth=srt.getLength();
|
||||
rawData[i++]=(byte) plth;
|
||||
i+=plth;
|
||||
break;
|
||||
default:
|
||||
rawData[i++]=(byte) srt.getType();
|
||||
int dlth=srt.getLength();
|
||||
rawData[i++]=(byte) dlth;
|
||||
System.arraycopy(srt.getValue(), 0, rawData, i, dlth);
|
||||
i+=dlth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rawData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[lastentry: ").append(lastEntry).append("][flags: ").append(flags).append("][tag: ").append(tag).append("] [addresses:");
|
||||
for (Inet6Address addr : addresses) {
|
||||
sb.append(" ").append(addr);
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!this.getClass().isInstance(obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IpV6RoutingSRHData other = (IpV6RoutingSRHData) obj;
|
||||
return lastEntry == other.lastEntry&&flags==other.flags&&tag==other.tag && addresses.equals(other.addresses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + lastEntry;
|
||||
result = 31 * result + flags;
|
||||
result = 31 * result + tag;
|
||||
result = 31 * result + addresses.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -2,22 +2,15 @@ package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.BindException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@@ -30,11 +23,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.ByteBufferAllocator;
|
||||
import org.kne.cloud.network.ipv6.IPv6Address;
|
||||
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
|
||||
import org.kne.cloud.network.ipv6.IPv6AddressGroup;
|
||||
import org.kne.cloud.network.ipv6.Neighbor;
|
||||
import org.kne.cloud.network.klalb.KLALBVirtualRawSocket;
|
||||
@@ -43,10 +35,7 @@ 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;
|
||||
import org.kne.membandboost.MembandBoost;
|
||||
|
||||
public class KLALBRoutingProtocol extends Thread{
|
||||
|
||||
@@ -218,7 +207,7 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
while(true) {
|
||||
|
||||
try {
|
||||
byte[]ca=ByteBufferAllocator.allocateUninitializedArray(65535);
|
||||
byte[]ca=MembandBoost.allocateUninitializedArray(65535);
|
||||
DatagramPacket dgp=new DatagramPacket(ca, ca.length);
|
||||
ds.receive(dgp);
|
||||
//System.out.println(Arrays.toString( Arrays.copyOf( dgp.getData(),dgp.getLength())));
|
||||
@@ -609,7 +598,7 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
public Map<IPv6Address, List<LinkDirection>> getPaths() {
|
||||
return paths;
|
||||
}
|
||||
public List<IPv6Address> createSegmentList(IPv6Address dest) {
|
||||
public IPv6SegmentRoutingHeader createSegmentList(IPv6Address dest) {
|
||||
NetmapDirections directionsx=directions;
|
||||
if(directionsx==null) {
|
||||
return null;
|
||||
@@ -618,14 +607,16 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
if(dn==null) {
|
||||
return null;
|
||||
}
|
||||
List<IPv6Address>segments=new ArrayList<>();
|
||||
IPv6SegmentRoutingHeader segs=new IPv6SegmentRoutingHeader();
|
||||
List<IPv6Address>segments=segs.getAddresses();
|
||||
while(true) {
|
||||
long idx=directionsx.getDirection()[(int) dn.longValue()];
|
||||
if(idx==-1) {
|
||||
return null;
|
||||
}
|
||||
if(idx==dn) {
|
||||
return segments;
|
||||
segs. resetSegmentPos();
|
||||
return segs;
|
||||
}
|
||||
segments.add(directionsx.getDirection_rias().get(dn.intValue()));
|
||||
dn=idx;
|
||||
|
||||
@@ -11,16 +11,14 @@ import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.cloud.network.congestion.DCTCPCongestionAlgorithm;
|
||||
import org.kne.cloud.network.congestion.EmptyCongestionAlgorithm;
|
||||
import org.kne.cloud.network.congestion.NOCongestionAlgorithm;
|
||||
import org.kne.cloud.network.congestion.SendPacketSlidingWindow;
|
||||
import org.kne.opencl64.Releaser;
|
||||
|
||||
public class KLALBRoutingProtocolAPIClient {
|
||||
private KLALBRoutingProtocol routingProtocol;
|
||||
private SendPacketSlidingWindow<UUID, JsonDataPacket> window = new SendPacketSlidingWindow<UUID, JsonDataPacket>(
|
||||
new EmptyCongestionAlgorithm(3000000000L), 1024 * 1024);
|
||||
new NOCongestionAlgorithm(3000000000L), 1024 * 1024);
|
||||
|
||||
private static final Cleaner clr = Cleaner.create();
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.pcap4j.packet.IpV6Packet;
|
||||
|
||||
public interface PacketConsumer {
|
||||
public boolean accept(IPv6Packet packx)throws IOException;
|
||||
}
|
||||
@@ -5,11 +5,8 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.pcap4j.packet.IpV6Packet;
|
||||
import org.pcap4j.packet.TcpPacket;
|
||||
|
||||
public class PacketReorder {
|
||||
public PacketReorder(long sequenceNumber) {
|
||||
@@ -48,7 +45,7 @@ public class PacketReorder {
|
||||
}
|
||||
|
||||
}
|
||||
public void sortPackets(IPv6Packet pack,long seq, PacketConsumer packconsumer) throws IOException {
|
||||
public void sortPackets(IPv6Packet pack,long seq, IPv6PacketConsumer packconsumer) throws IOException {
|
||||
rlock.lock();
|
||||
try {
|
||||
//System.out.println("包序号:"+seq);
|
||||
|
||||
@@ -12,9 +12,9 @@ import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
|
||||
public class SRv6PacketReorder {
|
||||
|
||||
private PacketConsumer packetConsumer;
|
||||
private IPv6PacketConsumer packetConsumer;
|
||||
|
||||
public SRv6PacketReorder(PacketConsumer packetConsumer) {
|
||||
public SRv6PacketReorder(IPv6PacketConsumer packetConsumer) {
|
||||
this.packetConsumer=packetConsumer;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,32 +11,22 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.swing.plaf.synth.SynthOptionPaneUI;
|
||||
|
||||
import org.jctools.counters.FixedSizeStripedLongCounter;
|
||||
import org.kne.cloud.clock.HighAccuracyClock;
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.cloud.network.congestion.ArrayListMessageBatcher;
|
||||
import org.kne.cloud.network.congestion.MessageBatcher;
|
||||
import org.kne.cloud.network.ipv6.ControlledIPv6NetworkLink;
|
||||
import org.kne.cloud.network.ipv6.FlowSession;
|
||||
import org.kne.cloud.network.ipv6.ICMPv6Packet;
|
||||
import org.kne.cloud.network.ipv6.ICMPv6PostcardPacket;
|
||||
import org.kne.cloud.network.ipv6.ICMPv6TimeExceededPacket;
|
||||
import org.kne.cloud.network.ipv6.IPv6Address;
|
||||
@@ -46,24 +36,20 @@ import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6HopByHopHeader;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
|
||||
import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink;
|
||||
import org.kne.cloud.network.ipv6.IPv6AddressGroup;
|
||||
import org.kne.cloud.network.ipv6.KLALBOAMHopByHopTLV;
|
||||
import org.kne.cloud.network.ipv6.KLALBPassportHopByHopTLV;
|
||||
import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink;
|
||||
import org.kne.cloud.network.ipv6.Neighbor;
|
||||
import org.kne.cloud.network.ipv6.PacketID;
|
||||
import org.kne.cloud.network.ipv6.PacketIDGenerator;
|
||||
import org.kne.cloud.network.ipv6.PadNHopByHopTLV;
|
||||
import org.kne.cloud.network.ipv6.PostcardEntry;
|
||||
import org.kne.cloud.network.ipv6.RouteItem;
|
||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
||||
import org.kne.cloud.network.klalb.KLALBRemoteLink;
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
import org.kne.concurrent.HighPerformanceExecutor;
|
||||
import org.kne.concurrent.HighPerformanceExecutor2;
|
||||
import org.kne.concurrent.TimeoutConcurrentHashMap;
|
||||
import org.pcap4j.packet.IllegalRawDataException;
|
||||
|
||||
import com.github.f4b6a3.uuid.UuidCreator;
|
||||
import com.google.gson.internal.Pair;
|
||||
|
||||
// SRv6路由器主类,实现IPv6段路由功能
|
||||
@@ -132,7 +118,6 @@ public class SRv6Router {
|
||||
public void accept(IPv6Packet t) {
|
||||
// HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||
routePacket(null, t, true); // 执行重路由
|
||||
t.putTimePassport("rerouted"); // 标记重路由时间点
|
||||
// });
|
||||
}
|
||||
};
|
||||
@@ -268,7 +253,7 @@ public class SRv6Router {
|
||||
// 预处理和排序路由项
|
||||
for (Iterator<RouteItem> iterator = routeTabel0x.iterator(); iterator.hasNext();) {
|
||||
RouteItem routeItem = (RouteItem) iterator.next();
|
||||
routeItem.preSort(); // 预排序
|
||||
routeItem.updateCost(); // 预排序
|
||||
}
|
||||
Collections.sort(routeTabel0x); // 排序路由表
|
||||
|
||||
@@ -319,15 +304,11 @@ public class SRv6Router {
|
||||
// 插入SRH并路由数据包
|
||||
public void insertSRHandRoutePacket(IPv6NetworkLink link, IPv6Packet ipp) {
|
||||
insertHopByHopHeader(ipp);
|
||||
ipp.putTimePassport("Hop inserted");
|
||||
insertSRHeader(ipp); // 插入段路由头
|
||||
ipp.putTimePassport("SRH inserted"); // 标记SRH插入时间点
|
||||
routePacket(link, ipp); // 路由数据包
|
||||
ipp.putTimePassport("routed"); // 标记路由时间点
|
||||
}
|
||||
|
||||
|
||||
private PacketIDGenerator defaultGen = new PacketIDGenerator();
|
||||
private static final PadNHopByHopTLV pad4 = new PadNHopByHopTLV(4);
|
||||
|
||||
// 插入逐跳路由头
|
||||
@@ -353,16 +334,15 @@ public class SRv6Router {
|
||||
}
|
||||
// 如果KLALB路由协议可用,创建段列表
|
||||
if (klalbRouteProtol != null) {
|
||||
List<IPv6Address> segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress());
|
||||
IPv6SegmentRoutingHeader segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress());
|
||||
// System.out.println(segs);
|
||||
if (segs != null && (!segs.isEmpty())) {
|
||||
if (segs != null && (!segs.getAddresses().isEmpty())) {
|
||||
|
||||
// 创建SRH头
|
||||
IPv6SegmentRoutingHeader irh = new IPv6SegmentRoutingHeader(segs);
|
||||
|
||||
ipp.getHeaders().add(irh); // 添加SRH头
|
||||
ipp.setRoutingHeader(irh);
|
||||
ipp.setDestinationAddress(segs.get(segs.size() - 1)); // 更新目的地址为最后一个段
|
||||
ipp.getHeaders().add(segs); // 添加SRH头
|
||||
ipp.setRoutingHeader(segs);
|
||||
ipp.setDestinationAddress(segs.getAddresses().get(segs.getAddresses().size() - 1)); // 更新目的地址为最后一个段
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -401,8 +381,9 @@ public class SRv6Router {
|
||||
int hop = iPv6Packet.getHopLimit(); // 获取跳数限制
|
||||
if (hop > 0) { // 检查TTL值,只有大于0才会被转发
|
||||
// 搜索匹配的路由表项
|
||||
List<RouteItem> searchResult = searchTable(iPv6Packet, reroute, dbg);
|
||||
if (!searchResult.isEmpty()) {
|
||||
IPv6Address dest=iPv6Packet.getDestinationAddress();
|
||||
List<RouteItem> searchResult = getTabelByAddress(dest);
|
||||
if (searchResult!=null&&(!searchResult.isEmpty())) {
|
||||
// 匹配到路由表,执行负载均衡路由
|
||||
routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult);
|
||||
return;
|
||||
@@ -421,15 +402,15 @@ public class SRv6Router {
|
||||
segmentsLeft--;
|
||||
}
|
||||
// 创建修复段列表
|
||||
List<IPv6Address> repairSegments = klalbRouteProtol
|
||||
IPv6SegmentRoutingHeader repairSegments = klalbRouteProtol
|
||||
.createSegmentList(srh.getAddresses().get(segmentsLeft));
|
||||
if (repairSegments == null || repairSegments.isEmpty()) {
|
||||
if (repairSegments == null ||repairSegments.getAddresses().isEmpty()) {
|
||||
System.out.println("FRR保护失败");
|
||||
return;
|
||||
}
|
||||
repairSegments.remove(0); // 移除第一个段(当前节点)
|
||||
srh.getAddresses().addAll(segmentsLeft + 1, repairSegments); // 添加修复段
|
||||
segmentsLeft += repairSegments.size(); // 更新剩余段数
|
||||
repairSegments.getAddresses().remove(0); // 移除第一个段(当前节点)
|
||||
srh.getAddresses().addAll(segmentsLeft + 1, repairSegments.getAddresses()); // 添加修复段
|
||||
segmentsLeft += repairSegments.getAddresses().size(); // 更新剩余段数
|
||||
srh.setSegmentsLeft(segmentsLeft);
|
||||
iPv6Packet.setDestinationAddress(srh.getAddresses().get(segmentsLeft)); // 更新目的地址
|
||||
} else {
|
||||
@@ -437,8 +418,8 @@ public class SRv6Router {
|
||||
}
|
||||
System.out.println("FRR修复SRH:" + srh);
|
||||
// 重新搜索路由表
|
||||
List<RouteItem> searchResult2 = searchTable(iPv6Packet, reroute, dbg);
|
||||
if (!searchResult2.isEmpty()) {
|
||||
List<RouteItem> searchResult2 = getTabelByAddress(dest);
|
||||
if (searchResult2!=null&&(!searchResult2.isEmpty())) {
|
||||
routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult2);
|
||||
return;
|
||||
}
|
||||
@@ -457,7 +438,7 @@ public class SRv6Router {
|
||||
}
|
||||
|
||||
// 搜索路由表找到匹配的路由项
|
||||
private List<RouteItem> searchTable(IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg)
|
||||
/*private List<RouteItem> searchTable(IPv6Packet iPv6Packet, StringBuilder dbg)
|
||||
throws IllegalRawDataException, IOException {
|
||||
if (debug) {
|
||||
dbg.append("----------------------------------------\n");
|
||||
@@ -476,17 +457,7 @@ public class SRv6Router {
|
||||
|
||||
// 遍历路由表,筛选可用路由
|
||||
for (RouteItem tri : table) {
|
||||
if (!tri.getDestlink().isUp()) { // 检查链路状态
|
||||
if (debug) {
|
||||
dbg.append(tri + "\n");
|
||||
dbg.append("linkdown.\n");
|
||||
}
|
||||
continue; // 跳过断开连接的链路
|
||||
}
|
||||
if (debug) {
|
||||
dbg.append(tri + "\n");
|
||||
dbg.append("matched.\n");
|
||||
}
|
||||
|
||||
// 检查ECMP(等价多路径)条件
|
||||
if (prevr != null) {
|
||||
if (!tri.ECMPequals(prevr)) {
|
||||
@@ -497,7 +468,7 @@ public class SRv6Router {
|
||||
prevr = tri;
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
}*/
|
||||
|
||||
private List<RouteItem> getTabelByAddress(IPv6Address rk6) {
|
||||
List<RouteItem> table = null;
|
||||
@@ -519,35 +490,25 @@ public class SRv6Router {
|
||||
private boolean routingLoadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute,
|
||||
StringBuilder dbg, List<RouteItem> routes) throws IllegalRawDataException, IOException {
|
||||
|
||||
double cscale = 1.0; // 拥塞检测比例因子
|
||||
if (iPv6Packet.getPayload().getProtocolNumber() == 6) { // TCP协议
|
||||
cscale = 15.0; // TCP使用更高的拥塞检测阈值
|
||||
if(routes==null||routes.isEmpty()) {
|
||||
//System.out.println("Route not found:" + iPv6Packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iPv6Packet.getPreviousLink() != null) {
|
||||
List<RouteItem> prev = new ArrayList<>();
|
||||
for (Iterator<RouteItem> iterator = routes.iterator(); iterator.hasNext();) {
|
||||
RouteItem routeItem = (RouteItem) iterator.next();
|
||||
if (routeItem.getDestlink().equals(iPv6Packet.getPreviousLink())) {
|
||||
prev.add(routeItem);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
routes.addAll(prev);
|
||||
}
|
||||
for (double i = 1; i < 10; i += 0.1) {
|
||||
if (loadBalance(linkfrom, iPv6Packet, reroute, dbg, routes, cscale * i)) {
|
||||
|
||||
for (double i = 1; i < 100; i += 0.1) {
|
||||
if (loadBalance(linkfrom, iPv6Packet, reroute, dbg, routes, i)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (iPv6Packet.isEnableECN()) { // 启用ECN
|
||||
iPv6Packet.markCE(); // 标记拥塞
|
||||
if (debug) {
|
||||
dbg.append("ECN enabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("Send failed:" + iPv6Packet);
|
||||
//System.out.println("Send failed:" + iPv6Packet);
|
||||
LosscountAdder.inc(1);
|
||||
|
||||
if (debug) {
|
||||
dbg.append("miss.\n"); // 路由失败
|
||||
}
|
||||
@@ -568,7 +529,7 @@ public class SRv6Router {
|
||||
continue; // 跳过断开链路
|
||||
}
|
||||
if (link instanceof ControlledIPv6NetworkLink) {
|
||||
if (((ControlledIPv6NetworkLink) link).isCongress(iPv6Packet, cscale)) { // 检查拥塞
|
||||
if (((ControlledIPv6NetworkLink) link).isCongestion(iPv6Packet, cscale)) { // 检查拥塞
|
||||
if (debug) {
|
||||
dbg.append(tri + "\n");
|
||||
dbg.append("congress.\n");
|
||||
@@ -623,12 +584,6 @@ public class SRv6Router {
|
||||
if (iPv6Packet.getPayload() instanceof ICMPv6PostcardPacket && ri.getDestlink().isLoopBack()) {
|
||||
onPostcardReceive(iPv6Packet);
|
||||
} else {
|
||||
IPv6NetworkLink oldLink = iPv6Packet.getPreviousLink();
|
||||
/*
|
||||
* if(oldLink!=null) {
|
||||
* System.out.println("重传:"+!oldLink.equals(ri.getDestlink())); }
|
||||
*/
|
||||
iPv6Packet.setPreviousLink(ri.getDestlink());
|
||||
ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
|
||||
}
|
||||
}
|
||||
@@ -642,8 +597,8 @@ public class SRv6Router {
|
||||
if (ris != null) {
|
||||
for (RouteItem ri : ris) {
|
||||
if (ri.getNexthop().equals(sid)) {
|
||||
if (ri.getDestlink() instanceof KLALBRemoteLine) {
|
||||
KLALBRemoteLine rem = (KLALBRemoteLine) ri.getDestlink();
|
||||
if (ri.getDestlink() instanceof KLALBRemoteLink) {
|
||||
KLALBRemoteLink rem = (KLALBRemoteLink) ri.getDestlink();
|
||||
rem.onPostcardReceive(postcard);
|
||||
}
|
||||
}
|
||||
@@ -683,9 +638,9 @@ public class SRv6Router {
|
||||
int sl = srhh.getSegmentsLeft();
|
||||
// IPv6Address prevSID
|
||||
// =sl+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(sl+1);
|
||||
if (linkfrom instanceof KLALBRemoteLine) {
|
||||
if (linkfrom instanceof KLALBRemoteLink) {
|
||||
processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(),
|
||||
((KLALBRemoteLine) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
|
||||
((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
|
||||
}
|
||||
}
|
||||
// System.out.println(iPv6HopByHopHeader);
|
||||
@@ -698,9 +653,9 @@ public class SRv6Router {
|
||||
if (iPv6HopByHopHeader != null) {
|
||||
// IPv6Address prevSID
|
||||
// =oldSL+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(oldSL+1);
|
||||
if (linkfrom instanceof KLALBRemoteLine) {
|
||||
if (linkfrom instanceof KLALBRemoteLink) {
|
||||
processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(),
|
||||
((KLALBRemoteLine) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
|
||||
((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
|
||||
}
|
||||
}
|
||||
// 正常SRv6处理:移动到下一个段
|
||||
@@ -762,8 +717,9 @@ public class SRv6Router {
|
||||
|
||||
private void putPostcard(IPv6Address src, IPv6Address dst, IPv6Address srcSID, UUID uuid, long timeStamp,
|
||||
long delta, int packetLength) {
|
||||
|
||||
PostcardEntry pn = new PostcardEntry(srcSID, uuid, timeStamp, (int) (delta >> 4), packetLength);
|
||||
Pair<IPv6Address, IPv6Address> addressPair = new Pair<IPv6Address, IPv6Address>(src, dst);
|
||||
/*Pair<IPv6Address, IPv6Address> addressPair = new Pair<IPv6Address, IPv6Address>(src, dst);
|
||||
MessageBatcher<PostcardEntry> batch = postcardBatch.computeIfAbsent(addressPair, (k) -> {
|
||||
MessageBatcher<PostcardEntry> mb = new ArrayListMessageBatcher<PostcardEntry>(30, 2000000L);
|
||||
mb.setConsumer((list) -> {
|
||||
@@ -786,13 +742,30 @@ public class SRv6Router {
|
||||
return mb;
|
||||
});
|
||||
postcardBatch.refresh(addressPair);
|
||||
batch.putMessage(pn);
|
||||
batch.putMessage(pn);*/
|
||||
enqueuePacketSendTask(() -> {
|
||||
IPv6Packet icmpv = new IPv6Packet();
|
||||
icmpv.setSourceAddress(src);
|
||||
icmpv.setDestinationAddress(dst);
|
||||
icmpv.setTrafficClass(0);
|
||||
icmpv.setVersion(6);
|
||||
icmpv.setFlowLabel(0);
|
||||
icmpv.setHopLimit(255); // ICMP消息TTL设为最大值
|
||||
ICMPv6PostcardPacket ipl = new ICMPv6PostcardPacket();
|
||||
ipl.getPostcards().addAll(List.of(pn));
|
||||
ipl.setParent(icmpv);
|
||||
ipl.updateChecksum();
|
||||
icmpv.setPayload(ipl);
|
||||
return icmpv;
|
||||
});
|
||||
}
|
||||
|
||||
private static HighPerformanceExecutor defaultExecutor = new HighPerformanceExecutor(
|
||||
Runtime.getRuntime().availableProcessors() + 1, Thread.ofPlatform().name("SRv6 Routing").factory());//Runtime.getRuntime().availableProcessors() + 1
|
||||
private static HighPerformanceExecutor2 defaultExecutor = new HighPerformanceExecutor2(
|
||||
(int) (Runtime.getRuntime().availableProcessors()), Thread.ofVirtual().name("SRv6 Routing").factory());
|
||||
|
||||
//private static HighPerformanceExecutor2 defaultExecutor = new HighPerformanceExecutor2(4, Thread.ofVirtual().name("SRv6 Routing").factory());
|
||||
|
||||
public static HighPerformanceExecutor getDefaultExecutor() {
|
||||
public static HighPerformanceExecutor2 getDefaultExecutor() {
|
||||
return defaultExecutor;
|
||||
}
|
||||
|
||||
@@ -802,38 +775,52 @@ public class SRv6Router {
|
||||
// packetQueue.add(object);
|
||||
defaultExecutor.executeWithCongestionReport((state) -> {
|
||||
try {
|
||||
long start=System.nanoTime();
|
||||
IPv6Packet packet=sendTask.get();
|
||||
if(state) {
|
||||
if(packet.isEnableECN()) {
|
||||
packet.markCE();
|
||||
//System.out.println("mce");
|
||||
}
|
||||
}
|
||||
insertSRHandRoutePacket(null, packet); // 插入SRH并路由
|
||||
long time=System.nanoTime()-start;
|
||||
backplaneCount(time,state);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
},20);
|
||||
}
|
||||
public void runPacketSendTask(Supplier<IPv6Packet> sendTask) {
|
||||
try {
|
||||
boolean state=false;
|
||||
long start=System.nanoTime();
|
||||
IPv6Packet packet=sendTask.get();
|
||||
if(state) {
|
||||
packet.markCE();
|
||||
}
|
||||
insertSRHandRoutePacket(null, packet); // 插入SRH并路由
|
||||
long time=System.nanoTime()-start;
|
||||
backplaneCount(time,state);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void onReceive(IPv6NetworkLink link,IPv6Packet t){
|
||||
if (unduplicate(t)) {
|
||||
insertSRHandRoutePacket(link, t); // 插入SRH并路由数据包
|
||||
t.putTimePassport("routed"); // 标记路由时间点
|
||||
}
|
||||
}
|
||||
|
||||
public void enqueuePacketReceiveTask(IPv6NetworkLink link, Supplier<IPv6Packet> pack) {
|
||||
defaultExecutor.executeWithCongestionReport((state) -> {
|
||||
try {
|
||||
long start=System.nanoTime();
|
||||
IPv6Packet packet = pack.get();
|
||||
if(state) {
|
||||
if(packet.isEnableECN()) {
|
||||
packet.markCE();
|
||||
//System.out.println("mce");
|
||||
}
|
||||
}
|
||||
onReceive(link ,packet);
|
||||
long time=System.nanoTime()-start;
|
||||
backplaneCount(time,state);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -845,6 +832,67 @@ public class SRv6Router {
|
||||
return packet;
|
||||
});
|
||||
}
|
||||
|
||||
//private BandwidthSampler sampler=new BandwidthSampler();
|
||||
private FixedSizeStripedLongCounter timeAdder=KLALBUtils.createCounter();
|
||||
private FixedSizeStripedLongCounter countAdder=KLALBUtils.createCounter();
|
||||
private FixedSizeStripedLongCounter ECNcountAdder=KLALBUtils.createCounter();
|
||||
private FixedSizeStripedLongCounter LosscountAdder=KLALBUtils.createCounter();
|
||||
private void backplaneCount(long time,boolean ECN) {
|
||||
timeAdder.inc(time);
|
||||
countAdder.inc(1);
|
||||
if(ECN) {
|
||||
ECNcountAdder.inc(1);
|
||||
}
|
||||
}
|
||||
private volatile long backplaneTime=0;
|
||||
private volatile double ECNRate=0;
|
||||
private volatile double LossRate=0;
|
||||
private volatile long backplanePPS=0;
|
||||
private volatile long backplanePPSMax=0;
|
||||
private volatile long prevTime=System.nanoTime();
|
||||
|
||||
private Timer backplaneTimer=new Timer();
|
||||
private void updateBackplaneCounter() {
|
||||
long curr=System.nanoTime();
|
||||
long totalTime=timeAdder.getAndReset();
|
||||
long totalCount=countAdder.getAndReset();
|
||||
long ECNCount=ECNcountAdder.getAndReset();
|
||||
long LossCount=LosscountAdder.getAndReset();
|
||||
if(totalCount!=0) {
|
||||
backplaneTime=totalTime/totalCount;
|
||||
ECNRate=((double)ECNCount)/totalCount;
|
||||
LossRate=((double)LossCount)/totalCount;
|
||||
}
|
||||
backplanePPS=totalCount*1000000000L/(curr-prevTime);
|
||||
if(backplanePPSMax<backplanePPS) {
|
||||
backplanePPSMax=backplanePPS;
|
||||
}else {
|
||||
backplanePPSMax=(backplanePPSMax*999+backplanePPS)/1000;
|
||||
}
|
||||
prevTime=curr;
|
||||
}
|
||||
|
||||
|
||||
public long getBackplaneTime() {
|
||||
return backplaneTime;
|
||||
}
|
||||
|
||||
public long getBackplanePPS() {
|
||||
return backplanePPS;
|
||||
}
|
||||
|
||||
public long getBackplanePPSMax() {
|
||||
return backplanePPSMax;
|
||||
}
|
||||
|
||||
public double getECNRate() {
|
||||
return ECNRate;
|
||||
}
|
||||
|
||||
public double getLossRate() {
|
||||
return LossRate;
|
||||
}
|
||||
|
||||
// 构造函数
|
||||
public SRv6Router(IPv6AddressGroup hostAddress, HighAccuracyClock clock) {
|
||||
@@ -856,6 +904,13 @@ public class SRv6Router {
|
||||
this.inLoopBack = new LoopbackIPv6NetworkLink(
|
||||
List.of(new IPv6AddressGroup(IPv6Address.LOOPBACK, 128), hostAddress), this);
|
||||
linkTabel.add(inLoopBack); // 添加到链路表
|
||||
backplaneTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
updateBackplaneCounter();
|
||||
}
|
||||
}, 100, 100);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -892,7 +947,7 @@ public class SRv6Router {
|
||||
Object[] nls = links.toArray();
|
||||
for (int i = 0; i < nls.length; i++) {
|
||||
IPv6NetworkLink nl = (IPv6NetworkLink) nls[i];
|
||||
if (!nl.isLoopBack()) { // 排除环回接口
|
||||
if ((!nl.isLoopBack())&&nl.isUp()) { // 排除环回接口
|
||||
List<Neighbor> neis = nl.getNeighborsInfo();
|
||||
for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
@@ -903,7 +958,7 @@ public class SRv6Router {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 获取所有定位器
|
||||
// 获取所有SID
|
||||
public Set<IPv6AddressGroup> getLocators() {
|
||||
Set<IPv6AddressGroup> result = new HashSet<>();
|
||||
List<IPv6NetworkLink> links = getLinkTabel();
|
||||
@@ -915,10 +970,14 @@ public class SRv6Router {
|
||||
for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
if (addresses.getLocator() != null)
|
||||
result.add(addresses.getLocator()); // 添加邻居定位器
|
||||
result.add(addresses.getLocator()); // 添加邻居SID
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -5,11 +5,8 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.pcap4j.packet.IpV6Packet;
|
||||
import org.pcap4j.packet.TcpPacket;
|
||||
|
||||
public class SlidingWindowInformation {
|
||||
public SlidingWindowInformation(long sequenceNumber) {
|
||||
@@ -57,7 +54,7 @@ public class SlidingWindowInformation {
|
||||
+ ", addtime=" + addtime + "]";
|
||||
}
|
||||
}
|
||||
public void sortPackets(IPv6Packet pack,long seq,int length, PacketConsumer packconsumer) throws IOException {
|
||||
public void sortPackets(IPv6Packet pack,long seq,int length, IPv6PacketConsumer packconsumer) throws IOException {
|
||||
rlock.lock();
|
||||
try {
|
||||
//System.out.println("包序号:"+seq+" 长度:"+length);
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.pcap4j.packet.IpV6Packet;
|
||||
import org.pcap4j.packet.TcpPacket;
|
||||
|
||||
public class TCPTransimitAgent {
|
||||
public TCPTransimitAgent() {
|
||||
@@ -57,7 +51,7 @@ public class TCPTransimitAgent {
|
||||
+ ", addtime=" + addtime + "]";
|
||||
}
|
||||
}
|
||||
public boolean sortPackets(IPv6Packet pack,long seq,int length, PacketConsumer packconsumer) throws IOException {
|
||||
public boolean sortPackets(IPv6Packet pack,long seq,int length, IPv6PacketConsumer packconsumer) throws IOException {
|
||||
if(length<=0) {
|
||||
packconsumer.accept(pack);
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user