forked from KNEMC/KLALB
优化代码,性能暴涨
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Objects;
|
||||
|
||||
public class FlowSession implements Serializable{
|
||||
private Inet6Address srcAddr;
|
||||
private Inet6Address dstAddr;
|
||||
private int flowLabel;
|
||||
public FlowSession(Inet6Address srcAddr, Inet6Address dstAddr, int flowLabel) {
|
||||
super();
|
||||
this.srcAddr = srcAddr;
|
||||
this.dstAddr = dstAddr;
|
||||
this.flowLabel = flowLabel;
|
||||
}
|
||||
public Inet6Address getSrcAddr() {
|
||||
return srcAddr;
|
||||
}
|
||||
public Inet6Address getDstAddr() {
|
||||
return dstAddr;
|
||||
}
|
||||
public int getFlowLabel() {
|
||||
return flowLabel;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FlowSession [srcAddr=" + srcAddr + ", dstAddr=" + dstAddr + ", flowLabel=" + flowLabel + "]";
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(dstAddr, flowLabel, srcAddr);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
FlowSession other = (FlowSession) obj;
|
||||
return Objects.equals(dstAddr, other.dstAddr) && flowLabel == other.flowLabel
|
||||
&& Objects.equals(srcAddr, other.srcAddr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.kne.cloud.network.klalb.KLALBPacket;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||
|
||||
public interface IPv6NetworkLink {
|
||||
public boolean isLoopBack();
|
||||
public Inet6AddressGroup getAddressGroup();
|
||||
public List<Neighbor> getNeighborsInfo();
|
||||
public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException;
|
||||
public boolean isCongress(IPv6Packet iPv6Packet);
|
||||
public String getName();
|
||||
public boolean isUp();
|
||||
public boolean canSend(IPv6Packet iPv6Packet);
|
||||
public void setReceiveConsumer(Consumer<IPv6Packet>con);
|
||||
}
|
||||
@@ -0,0 +1,840 @@
|
||||
package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader;
|
||||
import org.kne.cloud.network.klalb.KLALBPacket;
|
||||
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
|
||||
import org.kne.cloud.network.srv6.IpV6RoutingSRHData;
|
||||
import org.kne.cloud.network.srv6.SRv6Pad1TLV;
|
||||
import org.kne.cloud.network.srv6.SRv6PadNTLV;
|
||||
import org.kne.cloud.network.srv6.SRv6StreamSequenceTLV;
|
||||
import org.kne.cloud.network.srv6.SRv6TLV;
|
||||
import org.pcap4j.packet.namednumber.IpNumber;
|
||||
|
||||
public class IPv6Packet extends NetworkPacket {
|
||||
private volatile ByteBuffer IPv6header ;
|
||||
|
||||
private volatile List<IPv6ExtHeader> headers = new ArrayList<>();
|
||||
|
||||
private IPv6Payload payload;
|
||||
|
||||
public static final int IPv6_HEADER_LENGTH = 40;
|
||||
|
||||
public IPv6Payload getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public void setPayload(IPv6Payload payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
public IPv6Packet() {
|
||||
IPv6header = NetworkPacket.databufferpool_40.borrow();
|
||||
IPv6header.limit(IPv6_HEADER_LENGTH);
|
||||
}
|
||||
|
||||
public static int getIPVersion(byte b) {
|
||||
return b>>>4;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return IPv6header.get(0) >>> 4;
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
IPv6header.put(0, (byte) (IPv6header.get(0) & 0b00001111 | version << 4));
|
||||
}
|
||||
|
||||
public int getTrafficClass() {
|
||||
return (IPv6header.get(0) << 4) & (IPv6header.get(1) >>> 4) & 0xff;
|
||||
}
|
||||
|
||||
public void setTrafficClass(int trafficClass) {
|
||||
IPv6header.put(0, (byte) (IPv6header.get(0) & 0b11110000 | (trafficClass >>> 4)));
|
||||
IPv6header.put(1, (byte) (IPv6header.get(1) & 0b00001111 | ((trafficClass & 0b00001111) << 4)));
|
||||
}
|
||||
|
||||
public boolean isEnableECN() {
|
||||
return (IPv6header.get(1)&0b00110000)!=0;
|
||||
}
|
||||
|
||||
public void enableECN() {
|
||||
IPv6header.put(1, (byte) ((IPv6header.get(1)&0b11101111)|0b00100000));
|
||||
}
|
||||
|
||||
public void markCE() {
|
||||
IPv6header.put(1,(byte) (IPv6header.get(1)|0b00110000));
|
||||
}
|
||||
|
||||
public boolean isCE() {
|
||||
return ((IPv6header.get(1)>>>4)&0b11)==0b11;
|
||||
}
|
||||
|
||||
public int getFlowLabel() {
|
||||
return ((IPv6header.get(1) & 0b00001111) << 16) | (IPv6header.getShort(2) & 0xffff);
|
||||
}
|
||||
|
||||
public void setFlowLabel(int flowLabel) {
|
||||
IPv6header.put(1, (byte) (IPv6header.get(1) & 0b11110000 | (flowLabel >>> 16)));
|
||||
IPv6header.putShort(2, (short) flowLabel);
|
||||
}
|
||||
|
||||
public int getPayloadLength() {
|
||||
return IPv6header.getShort(4) & 0xffff;
|
||||
}
|
||||
|
||||
public void setPayloadLength(int payloadLength) {
|
||||
IPv6header.putShort(4, (short) payloadLength);
|
||||
}
|
||||
|
||||
public int getNextHeader() {
|
||||
return IPv6header.get(6) & 0xff;
|
||||
}
|
||||
|
||||
public void setNextHeader(int nextHeader) {
|
||||
IPv6header.put(6, (byte) nextHeader);
|
||||
}
|
||||
|
||||
public int getHopLimit() {
|
||||
return IPv6header.get(7) & 0xff;
|
||||
}
|
||||
|
||||
public void setHopLimit(int hopLimit) {
|
||||
IPv6header.put(7, (byte) hopLimit);
|
||||
}
|
||||
|
||||
public Inet6Address getSourceAddress() {
|
||||
byte[] b = new byte[16];
|
||||
IPv6header.get(8, b, 0, b.length);
|
||||
try {
|
||||
return (Inet6Address) Inet6Address.getByAddress(b);
|
||||
} catch (UnknownHostException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSourceAddress(Inet6Address sourceAddress) {
|
||||
byte[] b = sourceAddress.getAddress();
|
||||
IPv6header.put(8, b, 0, b.length);
|
||||
}
|
||||
|
||||
public Inet6Address getDestinationAddress() {
|
||||
byte[] b = new byte[16];
|
||||
IPv6header.get(24, b, 0, b.length);
|
||||
try {
|
||||
return (Inet6Address) Inet6Address.getByAddress(b);
|
||||
} catch (UnknownHostException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setDestinationAddress(Inet6Address destinationAddress) {
|
||||
byte[] b = destinationAddress.getAddress();
|
||||
IPv6header.put(24, b, 0, b.length);
|
||||
}
|
||||
|
||||
public FlowSession getFlowSession() {
|
||||
return new FlowSession(getSourceAddress(), getDestinationAddress(), getFlowLabel());
|
||||
}
|
||||
|
||||
private int calcPayloadLength() {
|
||||
int lth=0;
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
lth+= headers.get(i).getLength();
|
||||
}
|
||||
lth+=payload.getLength();
|
||||
return lth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
return calcPayloadLength()+IPv6_HEADER_LENGTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doDisposeAfterSend() {
|
||||
super.doDisposeAfterSend();
|
||||
payload.doDisposeAfterSend();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/*ByteBuffer headerx = IPv6header;
|
||||
IPv6header = null;
|
||||
if(headerx!=null)
|
||||
NetworkPacket.databufferpool_40.back(headerx);*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeAll() {
|
||||
super.disposeAll();
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
headers.get(i).disposeAll();
|
||||
}
|
||||
payload.disposeAll();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(headers.isEmpty()) {
|
||||
setNextHeader(payload.getProtocolNumber());
|
||||
}else {
|
||||
setNextHeader(headers.get(0).getProtocolNumber());
|
||||
}
|
||||
setPayloadLength(calcPayloadLength());
|
||||
dto.write(IPv6header.slice(0, IPv6header.limit()));
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
IPv6ExtHeader exth=headers.get(i);
|
||||
if(i+1<headers.size()) {
|
||||
exth.setNextHeader(headers.get(i+1).getProtocolNumber());
|
||||
}else {
|
||||
exth.setNextHeader(payload.getProtocolNumber());
|
||||
}
|
||||
exth.writeToChannel(dto);
|
||||
}
|
||||
payload.writeToChannel(dto);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
IPv6header.limit(IPv6_HEADER_LENGTH);
|
||||
IPv6header.position(0);
|
||||
while (IPv6header.hasRemaining()) {
|
||||
if (din.read(IPv6header) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
int payloadlength=getPayloadLength();
|
||||
int nextheader=getNextHeader();
|
||||
loop:while(true) {
|
||||
IPv6ExtHeader ext;
|
||||
switch(nextheader) {
|
||||
|
||||
case 0:
|
||||
ext=new IPv6ExtHeader(nextheader);
|
||||
ext.readFromChannel(din, 0);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 60:
|
||||
ext=new IPv6DestinationHeader();
|
||||
ext.readFromChannel(din, 0);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 43:
|
||||
ByteBuffer bbf=NetworkPacket.databufferpool_2048.borrow();
|
||||
bbf.limit(4);
|
||||
while (bbf.hasRemaining()) {
|
||||
if (din.read(bbf) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
|
||||
int routingType= bbf.get(2)&0xff;
|
||||
switch(routingType) {
|
||||
case 4:
|
||||
ext=new IPv6SegmentRoutingHeader(bbf);
|
||||
break;
|
||||
default:
|
||||
ext=new IPv6RoutingHeader(true,bbf);
|
||||
break;
|
||||
}
|
||||
ext.readFromChannel(din, 0);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 44:
|
||||
ext=new IPv6ExtHeader(nextheader);
|
||||
ext.readFromChannel(din, 0);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 50:
|
||||
ext=new IPv6ExtHeader(nextheader);
|
||||
ext.readFromChannel(din, 0);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 51:
|
||||
ext=new IPv6ExtHeader(nextheader);
|
||||
ext.readFromChannel(din, 0);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 59:
|
||||
|
||||
ext=new IPv6ExtHeader(nextheader);
|
||||
ext.readFromChannel(din, 0);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case KLALBPacket.KLALB_PROTOCOL_NUMBER:
|
||||
KLALBPacket kp=KLALBPacket.readKLALBPacketFromChannel(din);
|
||||
this.payload=kp;
|
||||
break loop;
|
||||
|
||||
default:
|
||||
IPv6Payload pld=new IPv6Payload(nextheader);
|
||||
pld.readFromChannel(din, payloadlength);
|
||||
this.payload=pld;
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*public void analyse() {
|
||||
headers.clear();
|
||||
int headerPos=IPv6_HEADER_LENGTH;
|
||||
int nextheader=getNextHeader();
|
||||
int payloadlength=getPayloadLength();
|
||||
loop: while(true) {
|
||||
IPv6ExtHeader ext;
|
||||
switch(nextheader) {
|
||||
|
||||
case 0:
|
||||
ext=new IPv6ExtHeader(headerPos,nextheader);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headerPos+=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 60:
|
||||
ext=new IPv6DestinationHeader(headerPos);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headerPos+=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 43:
|
||||
ext=new IPv6RoutingHeader(headerPos);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headerPos+=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 44:
|
||||
ext=new IPv6ExtHeader(headerPos,nextheader);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headerPos+=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 50:
|
||||
ext=new IPv6ExtHeader(headerPos,nextheader);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headerPos+=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 51:
|
||||
ext=new IPv6ExtHeader(headerPos,nextheader);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headerPos+=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 59:
|
||||
|
||||
ext=new IPv6ExtHeader(headerPos,nextheader);
|
||||
nextheader=ext.getNextHeader();
|
||||
payloadlength-=ext.getLength();
|
||||
headerPos+=ext.getLength();
|
||||
headers.add(ext);
|
||||
break;
|
||||
default:
|
||||
IPv6Payload pld=new IPv6Payload(headerPos,payloadlength,nextheader);
|
||||
this.payload=pld;
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
//System.out.println(headers);
|
||||
//System.out.println(payload);
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void lockAll() {
|
||||
super.lockAll();
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
headers.get(i).lockAll();
|
||||
}
|
||||
payload.lockAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSomeDisposed() {
|
||||
if(super.isSomeDisposed()||payload.isSomeDisposed())
|
||||
return true;
|
||||
for (Iterator<IPv6ExtHeader> iterator = headers.iterator(); iterator.hasNext();) {
|
||||
IPv6ExtHeader iPv6ExtHeader = (IPv6ExtHeader) iterator.next();
|
||||
if(iPv6ExtHeader.isSomeDisposed())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockAll() {
|
||||
payload.unlockAll();
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
headers.get(i).unlockAll();
|
||||
}
|
||||
super.unlockAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IPv6Packet [getVersion()=" + getVersion() + ", getTrafficClass()=" + getTrafficClass()
|
||||
+ ", getFlowLabel()=" + getFlowLabel() + ", getPayloadLength()=" + getPayloadLength()
|
||||
+ ", getNextHeader()=" + getNextHeader() + ", getHopLimit()=" + getHopLimit() + ", getSourceAddress()="
|
||||
+ getSourceAddress() + ", getDestinationAddress()=" + getDestinationAddress() + ", getLength()="
|
||||
+ getLength() + ", headers=" + headers + ", payload=" + payload + "]";
|
||||
}
|
||||
|
||||
public static class IPv6Payload extends NetworkPacket{
|
||||
private ByteBuffer data ;
|
||||
|
||||
private boolean onDefault=true;
|
||||
|
||||
public ByteBuffer getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
private int protocolNumber;
|
||||
|
||||
public IPv6Payload(int protocolNumber) {
|
||||
this(protocolNumber,true);
|
||||
}
|
||||
|
||||
protected IPv6Payload(int protocolNumber,boolean isonDefault) {
|
||||
this.protocolNumber = protocolNumber;
|
||||
this.onDefault=isonDefault;
|
||||
if(onDefault)
|
||||
this.data=NetworkPacket.databufferpool_65535.borrow();
|
||||
}
|
||||
|
||||
public int getProtocolNumber() {
|
||||
return protocolNumber;
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
return data.limit();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(onDefault)
|
||||
dto.write(data.slice(0,data.limit()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
if(onDefault) {
|
||||
data.limit((int) length);
|
||||
while (data.hasRemaining()) {
|
||||
if (din.read(data) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/*if(onDefault) {
|
||||
ByteBuffer datax = data;
|
||||
data = null;
|
||||
NetworkPacket.databufferpool_65535.back(datax);
|
||||
}*/
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needEndPosition() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class IPv6ExtHeader extends NetworkPacket{
|
||||
private ByteBuffer data ;
|
||||
|
||||
private int protocolNumber;
|
||||
|
||||
private boolean onDefault=true;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IPv6ExtHeader [protocolNumber=" + protocolNumber + ", getNextHeader()=" + getNextHeader()
|
||||
+ ", getExtLength()=" + getExtLength() + "]";
|
||||
}
|
||||
|
||||
public ByteBuffer getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public IPv6ExtHeader(int type) {
|
||||
this(type,true);
|
||||
}
|
||||
|
||||
protected IPv6ExtHeader(int protocolNumber,boolean isonDefault) {
|
||||
this.protocolNumber = protocolNumber;
|
||||
this.onDefault=isonDefault;
|
||||
if(onDefault) {
|
||||
this.data=NetworkPacket.databufferpool_2048.borrow();
|
||||
}else {
|
||||
this.data=NetworkPacket.databufferpool_40.borrow();
|
||||
}
|
||||
}
|
||||
|
||||
protected IPv6ExtHeader(int protocolNumber,boolean isonDefault,ByteBuffer data) {
|
||||
this.protocolNumber = protocolNumber;
|
||||
this.onDefault=isonDefault;
|
||||
this.data=data;
|
||||
}
|
||||
|
||||
public int getProtocolNumber() {
|
||||
return protocolNumber;
|
||||
}
|
||||
|
||||
public int getNextHeader() {
|
||||
return data.get(0) & 0xff;
|
||||
}
|
||||
|
||||
public void setNextHeader(int nextHeader) {
|
||||
data.put(0, (byte) nextHeader);
|
||||
}
|
||||
|
||||
public int getExtLength() {
|
||||
return data.get(1) & 0xff;
|
||||
}
|
||||
|
||||
protected void setExtLength(int extLength) {
|
||||
data.put(1, (byte) extLength);
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
return data.limit();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(onDefault) {
|
||||
int ext=(data.limit()-8)/8;
|
||||
setExtLength(ext);
|
||||
dto.write(data.slice(0,data.limit()));
|
||||
}else {
|
||||
dto.write(data.slice(0,8));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
data.limit(8);
|
||||
while (data.hasRemaining()) {
|
||||
if (din.read(data) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
if(onDefault) {
|
||||
int newLimit=getExtLength()*8+data.limit();
|
||||
data.limit(newLimit);
|
||||
while (data.hasRemaining()) {
|
||||
if (din.read(data) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needEndPosition() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/*ByteBuffer bbft=data;
|
||||
data=null;
|
||||
if(bbft!=null) {
|
||||
if(bbft.capacity()==40) {
|
||||
NetworkPacket.databufferpool_40.back(bbft);
|
||||
}else {
|
||||
NetworkPacket.databufferpool_2048.back(bbft);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
public static class IPv6RoutingHeader extends IPv6ExtHeader{
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IPv6RoutingHeader [protocolNumber=" + getProtocolNumber() + ", getNextHeader()=" + getNextHeader()
|
||||
+ ", getExtLength()=" + getExtLength()+ ", getRoutingType()="+getRoutingType() + "]";
|
||||
}
|
||||
public IPv6RoutingHeader() {
|
||||
super(43);
|
||||
}
|
||||
public IPv6RoutingHeader(boolean onDefault) {
|
||||
super(43,onDefault);
|
||||
}
|
||||
|
||||
public IPv6RoutingHeader( boolean isonDefault, ByteBuffer data) {
|
||||
super(43, isonDefault, data);
|
||||
}
|
||||
public int getRoutingType() {
|
||||
return getData().get(2)&0xff;
|
||||
}
|
||||
public void setRoutingType(int routingTypr) {
|
||||
getData().put(2, (byte) routingTypr);
|
||||
}
|
||||
public int getSegmentsLeft() {
|
||||
return getData().get(3);
|
||||
}
|
||||
public void setSegmentsLeft(int segmentsLeft) {
|
||||
getData().put(3,(byte) segmentsLeft);
|
||||
}
|
||||
}
|
||||
|
||||
public static class IPv6SegmentRoutingHeader extends IPv6RoutingHeader{
|
||||
|
||||
private final List<Inet6Address> addresses=new ArrayList<Inet6Address>();
|
||||
private final List<IPv6SegmentRoutingTLV> tlvs=new ArrayList<IPv6SegmentRoutingTLV>();
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IPv6SegmentRoutingHeader [addresses=" + addresses + ", tlvs=" + tlvs + ", getLastEntry()="
|
||||
+ getLastEntry() + ", getFlags()=" + getFlags() + ", getTag()=" + getTag() + ", getAddresses()="
|
||||
+ getAddresses() + ", getRoutingType()=" + getRoutingType() + ", getSegmentsLeft()="
|
||||
+ getSegmentsLeft() + ", getProtocolNumber()=" + getProtocolNumber() + ", getNextHeader()="
|
||||
+ getNextHeader() + ", getExtLength()=" + getExtLength() + "]";
|
||||
}
|
||||
public IPv6SegmentRoutingHeader() {
|
||||
super(false);
|
||||
setRoutingType(4);
|
||||
}
|
||||
|
||||
public IPv6SegmentRoutingHeader(ByteBuffer bbf) {
|
||||
super(false,bbf);
|
||||
}
|
||||
public IPv6SegmentRoutingHeader(List<Inet6Address> segs) {
|
||||
this();
|
||||
this.addresses.addAll( segs);
|
||||
int ln=addresses.size()-1;
|
||||
setLastEntry(ln);
|
||||
setSegmentsLeft(ln);
|
||||
}
|
||||
public int getLastEntry() {
|
||||
return getData().get(4)&0xff;
|
||||
}
|
||||
|
||||
public void setLastEntry(int lastEntry) {
|
||||
getData().put(4, (byte) lastEntry);
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return getData().get(5)&0xff;
|
||||
}
|
||||
|
||||
public void setFlags(int flags) {
|
||||
getData().put(5,(byte) flags);
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return getData().getShort(6)&0xffff;
|
||||
}
|
||||
|
||||
public void setTag(int tag) {
|
||||
getData().putShort(6,(short) tag);
|
||||
}
|
||||
public List<Inet6Address> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
setExtLength(calcExtLength()/8);
|
||||
setLastEntry(addresses.size()-1);
|
||||
super.writeToChannel(dto);
|
||||
for (Iterator<Inet6Address> iterator = addresses.iterator(); iterator.hasNext();) {
|
||||
Inet6Address inet6Address = (Inet6Address) iterator.next();
|
||||
dto.write(ByteBuffer.wrap(inet6Address.getAddress()));
|
||||
}
|
||||
|
||||
}
|
||||
private int calcExtLength() {
|
||||
int tlvsl=0;
|
||||
for (Iterator<IPv6SegmentRoutingTLV> iterator = tlvs.iterator(); iterator.hasNext();) {
|
||||
IPv6SegmentRoutingTLV tlve = (IPv6SegmentRoutingTLV) iterator.next();
|
||||
tlvsl+=tlve.getLength();
|
||||
}
|
||||
return addresses.size()*16+tlvsl;
|
||||
}
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
super.readFromChannel(din, length);
|
||||
int extl=getExtLength();
|
||||
int laste=getLastEntry();
|
||||
|
||||
int rl=extl*8;
|
||||
int usdl=0;
|
||||
|
||||
//System.out.println("SR length:"+(laste+1));
|
||||
addresses.clear();
|
||||
ByteBuffer bfr=ByteBuffer.allocate(16);
|
||||
for (int i = 0; i < (laste+1); i++) {
|
||||
bfr.clear();
|
||||
while (bfr.hasRemaining()) {
|
||||
if (din.read(bfr) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
bfr.flip();
|
||||
usdl+=bfr.limit();
|
||||
Inet6Address addr=(Inet6Address) Inet6Address.getByAddress(bfr.array());
|
||||
//System.out.println("SR:"+addr);
|
||||
addresses.add(addr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public long getLength() {
|
||||
return calcExtLength()+8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class IPv6DestinationHeader extends IPv6ExtHeader{
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IPv6DestinationHeader [protocolNumber=" + getProtocolNumber() + ", getNextHeader()=" + getNextHeader()
|
||||
+ ", getExtLength()=" + getExtLength()+ ", getRoutingType()="+getRoutingType() + "]";
|
||||
}
|
||||
public IPv6DestinationHeader() {
|
||||
super( 60);
|
||||
}
|
||||
public int getRoutingType() {
|
||||
return getData().get(2)&0xff;
|
||||
}
|
||||
public void setRoutingType(int routingTypr) {
|
||||
getData().put(2, (byte) routingTypr);
|
||||
}
|
||||
public int getSegmentsLeft() {
|
||||
return getData().get(3);
|
||||
}
|
||||
public void setSegmentsLeft(int segmentsLeft) {
|
||||
getData().put(3,(byte) segmentsLeft);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<IPv6ExtHeader> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
/*public IPv6DestinationHeader insertDestinationHeader(int index,int extLength) {
|
||||
long ptr;
|
||||
long lth=extLength*8+8;
|
||||
if(index==headers.size()) {
|
||||
ptr=payload.getPointer();
|
||||
}else if(index<headers.size()){
|
||||
IPv6ExtHeader iext=headers.get(index);
|
||||
ptr=iext.getPointer();
|
||||
}else {
|
||||
throw new IndexOutOfBoundsException(index);
|
||||
}
|
||||
byte[]temp=new byte[(int) (IPv6data.limit()-ptr)];
|
||||
IPv6data.get((int) ptr, temp);
|
||||
IPv6data.limit((int) (IPv6data.limit()+lth));
|
||||
setPayloadLength((int) (getPayloadLength()+lth));
|
||||
IPv6data.put((int) (ptr+lth), temp);
|
||||
IPv6DestinationHeader irh=new IPv6DestinationHeader(ptr,extLength);
|
||||
if(index>=headers.size()) {
|
||||
irh.setNextHeader(payload.getType());
|
||||
}else {
|
||||
irh.setNextHeader(headers.get(index).getType());
|
||||
}
|
||||
if(index-1<0) {
|
||||
setNextHeader(irh.getType());
|
||||
}else {
|
||||
headers.get(index-1).setNextHeader(irh.getType());
|
||||
}
|
||||
headers.add(index, irh);
|
||||
analyse();
|
||||
return irh;
|
||||
}
|
||||
public IPv6RoutingHeader insertSRHRoutingHeader(int index,IpV6RoutingSRHData srh) {
|
||||
long ptr;
|
||||
long lth=srh.length()+4;
|
||||
if(index==headers.size()) {
|
||||
ptr=payload.getPointer();
|
||||
}else if(index<headers.size()){
|
||||
IPv6ExtHeader iext=headers.get(index);
|
||||
ptr=iext.getPointer();
|
||||
}else {
|
||||
throw new IndexOutOfBoundsException(index);
|
||||
}
|
||||
byte[]temp=new byte[(int) (IPv6data.limit()-ptr)];
|
||||
IPv6data.get((int) ptr, temp);
|
||||
IPv6data.limit((int) (IPv6data.limit()+lth));
|
||||
setPayloadLength((int) (getPayloadLength()+lth));
|
||||
IPv6data.put((int) (ptr+lth), temp);
|
||||
IPv6RoutingHeader irh=new IPv6RoutingHeader(ptr,(int) ((lth-8)/8));
|
||||
if(index>=headers.size()) {
|
||||
irh.setNextHeader(payload.getType());
|
||||
}else {
|
||||
irh.setNextHeader(headers.get(index).getType());
|
||||
}
|
||||
if(index-1<0) {
|
||||
setNextHeader(irh.getType());
|
||||
}else {
|
||||
headers.get(index-1).setNextHeader(irh.getType());
|
||||
}
|
||||
headers.add(index, irh);
|
||||
irh.setRoutingType(4);
|
||||
irh.setSegmentsLeft(srh.getLastEntry());
|
||||
irh.getData().put(4, srh.getRawData());
|
||||
analyse();
|
||||
return irh;
|
||||
}*/
|
||||
@Override
|
||||
protected boolean needEndPosition() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||
import org.kne.cloud.network.srv6.IpV6RoutingSRHData;
|
||||
import org.kne.cloud.network.srv6.PacketConsumer;
|
||||
import org.kne.cloud.network.srv6.PacketReorder;
|
||||
import org.kne.cloud.network.srv6.SRv6StreamSequenceTLV;
|
||||
import org.kne.cloud.network.srv6.SRv6TLV;
|
||||
import org.kne.cloud.network.tun.TUNNetworkDevice;
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, AutoCloseable {
|
||||
|
||||
public static final String KLALB_DECENTRALIZED_S_RV6_NETWORK = "KLALB Decentralized SRv6 Network";
|
||||
|
||||
public static final String KLALB_S_RV6 = "KLALB SRv6";
|
||||
|
||||
private TUNNetworkDevice tun;
|
||||
|
||||
private Inet6AddressGroup hostAddress;
|
||||
|
||||
private Thread tr;
|
||||
|
||||
private ThreadPoolExecutor exc = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
|
||||
private Lock slok=new SpinLock();
|
||||
|
||||
public IPv6TUNLoopbackNetworkLink(Inet6AddressGroup hostAddress, int mtu) throws IOException {
|
||||
if (tun != null)
|
||||
throw new IllegalStateException("already open!");
|
||||
try {
|
||||
tun = TUNNetworkDevice.createDevice(KLALB_S_RV6, KLALB_DECENTRALIZED_S_RV6_NETWORK);
|
||||
tun.open();
|
||||
tun.setStatus(true);
|
||||
this.hostAddress = hostAddress;
|
||||
if (hostAddress != null)
|
||||
tun.setIPAddress(hostAddress.getAddress(), hostAddress.getPrefixLength());
|
||||
tun.setMTU(mtu);
|
||||
Thread tb = new Thread(() -> {
|
||||
while (true) {
|
||||
ByteBuffer tmp = NetworkPacket.databufferpool_65535.borrow();
|
||||
try {
|
||||
tun.read(tmp);
|
||||
tmp.flip();
|
||||
if (IPv6Packet.getIPVersion(tmp.get(0)) == 6) {
|
||||
while(exc.getQueue().size()>10) {
|
||||
LockSupport.parkNanos(1000000);
|
||||
}
|
||||
exc.execute(() -> {
|
||||
try {
|
||||
IPv6Packet ipp = new IPv6Packet();
|
||||
ipp.readFromChannel(KNEChannels.newReadableChannel(tmp), mtu);
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
if (con != null) {
|
||||
|
||||
monitor.getOutPacketCounterAL().incrementAndGet();
|
||||
monitor.getOutTrafficAL().addAndGet(ipp.getLength());
|
||||
ipp.setDisposeAfterSend(true);
|
||||
ipp.getPayload().setDisposeAfterSend(true);
|
||||
con.accept(ipp);
|
||||
} else {
|
||||
ipp.dispose();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
});
|
||||
}else {
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
tb.setPriority(Thread.MAX_PRIORITY-1);
|
||||
tb.start();
|
||||
tr = new Thread(() -> {
|
||||
while (true) {
|
||||
ByteBuffer tmp = sendQueue.poll();
|
||||
if (tmp != null) {
|
||||
|
||||
slok.lock();
|
||||
try {
|
||||
tun.write(tmp);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
slok.unlock();
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
}
|
||||
} else {
|
||||
LockSupport.parkNanos(1000000L);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
tr.setPriority(Thread.MAX_PRIORITY-1);
|
||||
tr.start();
|
||||
|
||||
}catch(UnsatisfiedLinkError e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private LinkedBlockingQueue<ByteBuffer> sendQueue = new LinkedBlockingQueue<ByteBuffer>();
|
||||
|
||||
private volatile Consumer<IPv6Packet> con;
|
||||
|
||||
private SpeedAndTrafficMonitorDataImpl monitor;
|
||||
|
||||
@Override
|
||||
public void sendPacket(IPv6Packet pack, Inet6Address next) throws IOException {
|
||||
if (tun != null) {/*
|
||||
* AtomicLong seqs=null; try { IPv6RoutingHeader
|
||||
* srhh=getRoutingHeaderFromPacket(pack); if(srhh!=null) { byte[]srd=new
|
||||
* byte[(int) (srhh.getLength()-4)]; srhh.getData().get(4, srd);
|
||||
* IpV6RoutingSRHData srh=IpV6RoutingSRHData.newInstance( srd,0,srd.length);
|
||||
* SRv6StreamSequenceTLV ssqv= getStreamSequenceTLV(srh); if(ssqv!=null)
|
||||
* seqs=new AtomicLong( ssqv.getSequence()); } }catch(IllegalRawDataException
|
||||
* re) {
|
||||
*
|
||||
* }
|
||||
*/
|
||||
|
||||
// System.out.println("add");
|
||||
while(exc.getQueue().size()>10) {
|
||||
LockSupport.parkNanos(1000000);
|
||||
}
|
||||
exc.execute(()->{
|
||||
ByteBuffer tmp = NetworkPacket.databufferpool_65535.borrow();
|
||||
|
||||
try {
|
||||
// System.out.println("rev");
|
||||
pack.writeToChannel(KNEChannels.newWritableChannel(tmp));
|
||||
monitor.getInPacketCounterAL().incrementAndGet();
|
||||
monitor.getInTrafficAL().addAndGet(pack.getLength());
|
||||
tmp.flip();
|
||||
sendQueue.add(tmp);
|
||||
LockSupport.unpark(tr);
|
||||
|
||||
} catch (IOException e) {
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
pack.disposeAll();
|
||||
});
|
||||
} else {
|
||||
pack.disposeAll();
|
||||
}
|
||||
}
|
||||
|
||||
private SRv6StreamSequenceTLV getStreamSequenceTLV(IpV6RoutingSRHData srh) {
|
||||
List<SRv6TLV> stv = srh.getTlvs();
|
||||
for (Iterator iterator = stv.iterator(); iterator.hasNext();) {
|
||||
SRv6TLV sRv6TLV = (SRv6TLV) iterator.next();
|
||||
if (sRv6TLV.getType() == SRv6TLV.SEQS) {
|
||||
return (SRv6StreamSequenceTLV) sRv6TLV;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoopBack() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Neighbor> getNeighborsInfo() {
|
||||
List<Neighbor> hs = new ArrayList<>();
|
||||
//if (hostAddress != null)
|
||||
//hs.put(hostAddress, null);
|
||||
return hs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCongress(IPv6Packet iPv6Packet) {
|
||||
return sendQueue.size() > 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "tunLoopBack";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUp() {
|
||||
return tun.isOpen();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (tun != null) {
|
||||
tun.close();
|
||||
tun = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSend(IPv6Packet iPv6Packet) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReceiveConsumer(Consumer<IPv6Packet> con) {
|
||||
this.con = con;
|
||||
}
|
||||
|
||||
public void setMonitor(SpeedAndTrafficMonitorDataImpl monitor) {
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
public SpeedAndTrafficMonitorDataImpl getMonitor() {
|
||||
return monitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inet6AddressGroup getAddressGroup() {
|
||||
return hostAddress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Inet6AddressGroup implements Comparable<Inet6AddressGroup>{
|
||||
private static final byte[][] maskTransf=new byte[129][16];
|
||||
static {
|
||||
for (int i = 0; i < 129; i++) {
|
||||
for(int j=0;j<i;j++) {
|
||||
maskTransf[i][j/8]=(byte) (((0b10000000)>>>j%8)|maskTransf[i][j/8]);
|
||||
}
|
||||
}
|
||||
/* for (int i = 0; i < maskTransf.length; i++) {
|
||||
try {
|
||||
System.out.println(InetAddress.getByAddress(maskTransf[i]));
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
public Inet6AddressGroup(Inet6Address address) {
|
||||
this(address, 128);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return address.getHostAddress()+"/"+prefixLength;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(address, prefixLength);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Inet6AddressGroup other = (Inet6AddressGroup) obj;
|
||||
return Objects.equals(address, other.address) && prefixLength == other.prefixLength;
|
||||
}
|
||||
public Inet6AddressGroup(Inet6Address address, int prefixLength) {
|
||||
super();
|
||||
this.address = address;
|
||||
this.prefixLength = prefixLength;
|
||||
}
|
||||
public Inet6AddressGroup(DataInputStream in) throws IOException {
|
||||
readFromStream(in);
|
||||
}
|
||||
private Inet6Address address;
|
||||
private int prefixLength=128;
|
||||
public Inet6Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
public int getPrefixLength() {
|
||||
return prefixLength;
|
||||
}
|
||||
public boolean checkMatch(Inet6Address ia) {
|
||||
byte[]mask=maskTransf[prefixLength];
|
||||
byte[]andj=and0(mask,ia.getAddress());
|
||||
byte[]andm=and0(mask ,address.getAddress());
|
||||
return Arrays.equals(andj,andm);
|
||||
}
|
||||
private byte[] and0(byte[] bs, byte[] address2) {
|
||||
byte[]rez=new byte[bs.length];
|
||||
for (int i = 0; i < rez.length; i++) {
|
||||
rez[i]=(byte) (bs[i]&address2[i]);
|
||||
}
|
||||
return rez;
|
||||
}
|
||||
@Override
|
||||
public int compareTo(Inet6AddressGroup o) {
|
||||
return -Integer.compare(prefixLength, o.prefixLength);
|
||||
}
|
||||
public void writeToStream(DataOutputStream out) throws IOException {
|
||||
out.write(address.getAddress());
|
||||
out.write(prefixLength);
|
||||
}
|
||||
public void readFromStream(DataInputStream in) throws IOException {
|
||||
byte[]b=new byte[16];
|
||||
in.readFully(b);
|
||||
address=(Inet6Address) Inet6Address.getByAddress(b);
|
||||
prefixLength=in.read();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
|
||||
public class Neighbor {
|
||||
private Inet6AddressGroup address;
|
||||
private Inet6AddressGroup locator;
|
||||
private MonitorData monitor;
|
||||
public MonitorData getMonitor() {
|
||||
return monitor;
|
||||
}
|
||||
public Inet6AddressGroup getAddress() {
|
||||
return address;
|
||||
}
|
||||
public Inet6AddressGroup getLocator() {
|
||||
return locator;
|
||||
}
|
||||
public Neighbor(Inet6AddressGroup address, Inet6AddressGroup locator, MonitorData monitor) {
|
||||
super();
|
||||
this.address = address;
|
||||
this.locator = locator;
|
||||
this.monitor = monitor;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Neighbor [address=" + address + ", locator=" + locator + ", monitor=" + monitor + "]";
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(address, locator);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Neighbor other = (Neighbor) obj;
|
||||
return Objects.equals(address, other.address) && Objects.equals(locator, other.locator);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.monitor.DelayMonitorData;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
|
||||
|
||||
public class RouteItem implements Comparable<RouteItem>{
|
||||
private Inet6AddressGroup destination;
|
||||
private Inet6Address nexthop;
|
||||
private IPv6NetworkLink destlink;
|
||||
private String proto;
|
||||
private int pre;
|
||||
private long cost;
|
||||
private String flag;
|
||||
private MonitorData monitor;
|
||||
public String getFlag() {
|
||||
return flag;
|
||||
}
|
||||
public MonitorData getMonitor() {
|
||||
return monitor;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(cost, destination, destlink, flag, nexthop, pre, proto);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
RouteItem other = (RouteItem) obj;
|
||||
return cost == other.cost && Objects.equals(destination, other.destination)
|
||||
&& Objects.equals(flag, other.flag)
|
||||
&& pre == other.pre && Objects.equals(proto, other.proto);
|
||||
}
|
||||
public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
|
||||
long cost,String flag) {
|
||||
super();
|
||||
this.destination = destination;
|
||||
this.nexthop = nexthop;
|
||||
this.destlink = destlink;
|
||||
this.proto = proto;
|
||||
this.pre = pre;
|
||||
this.cost = cost;
|
||||
this.flag=flag;
|
||||
}
|
||||
public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
|
||||
long cost,MonitorData monitor,String flag) {
|
||||
super();
|
||||
this.destination = destination;
|
||||
this.nexthop = nexthop;
|
||||
this.destlink = destlink;
|
||||
this.proto = proto;
|
||||
this.pre = pre;
|
||||
this.cost = cost;
|
||||
this.monitor=monitor;
|
||||
this.flag=flag;
|
||||
}
|
||||
public Inet6AddressGroup getDestination() {
|
||||
return destination;
|
||||
}
|
||||
public Inet6Address getNexthop() {
|
||||
return nexthop;
|
||||
}
|
||||
public IPv6NetworkLink getDestlink() {
|
||||
return destlink;
|
||||
}
|
||||
public String getProto() {
|
||||
return proto;
|
||||
}
|
||||
public int getPre() {
|
||||
return pre;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return getDestination()+"\t"+getProto()+"\t"+getPre()+"\t"+getCost()+"\t"+getFlag()+"\t"+getNexthop().getHostAddress()+"\t"+getDestlink().getName();
|
||||
}
|
||||
public long getCost() {
|
||||
return cost;
|
||||
}
|
||||
public boolean checkMatch(Inet6Address ia) {
|
||||
return destination.checkMatch(ia);
|
||||
}
|
||||
@Override
|
||||
public int compareTo(RouteItem o) {
|
||||
int v1=destination.compareTo(o.destination);
|
||||
if(v1!=0)
|
||||
return v1;
|
||||
int v2=Integer.compare(pre, o.pre);
|
||||
if(v2!=0)
|
||||
return v2;
|
||||
int v3=Long.compare(cost, o.cost);
|
||||
if(v3!=0)
|
||||
return v3;
|
||||
if(monitor==null||o.monitor==null||(!(monitor instanceof DelayMonitorData))||(!(o.monitor instanceof DelayMonitorData)))
|
||||
return v3;
|
||||
if(!(monitor instanceof QueueingMonitorDataImpl)||!(o.monitor instanceof QueueingMonitorDataImpl))
|
||||
return Long.compare(((DelayMonitorData)monitor).getOutDelay(), ((DelayMonitorData)o.monitor).getOutDelay());
|
||||
return Long.compare(((DelayMonitorData)monitor).getOutDelay()+((QueueingMonitorDataImpl)monitor).getQueueingDelay(), ((DelayMonitorData)o.monitor).getOutDelay()+((QueueingMonitorDataImpl)o.monitor).getQueueingDelay());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user