Files
KLALB/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java
T

885 lines
25 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.nio.channels.UnresolvedAddressException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.kne.cloud.clock.AdjustedNanoClock;
import org.kne.cloud.clock.ReliabilityBackoffTimeClock;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.SpeedLimiter;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
import org.kne.cloud.network.te.LoadingBalanceEntry;
public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteLine> ,LoadingBalanceEntry<KLALBRemoteLine>{
private static final boolean debug = false;
private static final boolean showpacket = false;
private ReliabilityBackoffTimeClock coll = new ReliabilityBackoffTimeClock();
private volatile boolean closed = false;
private volatile Supplier<Inet6AddressGroup> localVaddrSupplier;
private volatile KLALBController klalbController;
public KLALBController getKlalbController() {
return klalbController;
}
public void setKlalbController(KLALBController klalbController) {
this.klalbController = klalbController;
if (klalbController != null && remoteVaddr != null) {
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress());
}
}
public Supplier<Inet6AddressGroup> getLocalVaddrSupplier() {
return localVaddrSupplier;
}
public void setLocalVaddrSupplier(Supplier<Inet6AddressGroup> localVaddrSupplier) {
this.localVaddrSupplier = localVaddrSupplier;
}
private volatile Inet6AddressGroup remoteVaddr;
public Inet6AddressGroup getRemoteVaddr() {
return remoteVaddr;
}
private volatile AdjustedNanoClock adjnc = new AdjustedNanoClock();
public void waitForRemoteVaddrAvaliable(long timeout) throws SocketTimeoutException {
long s = System.nanoTime();
while (remoteVaddr == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (System.nanoTime() - s > timeout * 1000000)
throw new SocketTimeoutException();
}
}
public QueueingMonitorDataImpl getMonitor() {
return monitor;
}
public String toString() {
return remoteVaddr + "\t" + monitor.toString();
}
private QueueingMonitorDataImpl monitor;
private volatile KLALBPacketLink kplink;
private MultipurposeSocketAddress bindAddress;
private MultipurposeSocketAddress socketAddress;
private Thread lthd;
public void setKplink(KLALBPacketLink kplink) {
this.kplink = kplink;
}
public KLALBPacketLink getKplink() {
return kplink;
}
public MultipurposeSocketAddress getSocketAddress() {
return socketAddress;
}
public MultipurposeSocketAddress getBindAddress() {
return bindAddress;
}
private Inet6AddressGroup addressGroup;
private Inet6AddressGroup peerAddress;
@Override
public Inet6AddressGroup getAddressGroup() {
return addressGroup;
}
public Inet6AddressGroup getPeerAddress() {
return peerAddress;
}
public KLALBRemoteLine(MultipurposeSocketAddress mpa, Inet6AddressGroup address) {
this(mpa,address, new QueueingMonitorDataImpl());
}
public KLALBRemoteLine(MultipurposeSocketAddress mpa, Inet6AddressGroup address, QueueingMonitorDataImpl monitor) {
this(mpa, null,address, monitor);
}
public KLALBRemoteLine(KLALBPacketLink kpl, Inet6AddressGroup address) {
this(kpl,address, new QueueingMonitorDataImpl());
}
public KLALBRemoteLine(KLALBPacketLink kpl, Inet6AddressGroup address,QueueingMonitorDataImpl monitor) {
this.kplink = kpl;
this.addressGroup=address;
this.monitor = monitor;
monitor.setName(kpl.toString());
}
public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr,Inet6AddressGroup address,
QueueingMonitorDataImpl monitor) {
this.socketAddress = mpa;
this.bindAddress = bindaddr;
this.addressGroup=address;
this.monitor = monitor;
if (bindaddr == null) {
monitor.setName("→" + mpa.toString());
} else {
monitor.setName(bindaddr.toString() + "→" + mpa.toString());
}
}
public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr, Inet6AddressGroup address) {
this(mpa, bindaddr,address, new QueueingMonitorDataImpl());
}
public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bind) {
this(mpa, bind, null);
}
public KLALBRemoteLine(MultipurposeSocketAddress mpa) {
this(mpa,(Inet6AddressGroup)null);
}
public KLALBRemoteLine(KLALBPacketLink link) {
this(link, (Inet6AddressGroup)null);
}
PrintStream pw;
private boolean flag=false;
private void startRecord() {
if(flag)
return;
flag=true;
try {
File fl = new File("logs");
if (!fl.exists()) {
fl.mkdirs();
}
File fx = new File(fl, getMonitor().getName().replace(':', '') + ".csv");
pw = new PrintStream(new FileOutputStream(fx, true));
if (fx.length() <= 0)
pw.println("时间,状态,上传速度,下载速度,上传延迟,下载延迟,往返延迟,抖动");
ThreadTool.makeVDaemonThreadIfSupport("BigData Record", () -> {
while (!closed) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
pw.println(System.currentTimeMillis() + "," + monitor.getState() + "," + monitor.getOutSpeed() + ","
+ monitor.getInSpeed() + "," + monitor.getOutDelay() + "," + monitor.getInDelay() + ","
+ monitor.getLatency() + "," + monitor.getTotalJitter());
}
pw.close();
}).start();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private static long MIN_SPEED=256*1024L;
private SpeedLimiter congress = new SpeedLimiter(MIN_SPEED,10000000L);
private long congressSpeed = 0;
private double loadPercent = 1.01;
protected void startIO() {
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
//Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
while (true) {
try {
monitor.setState(MonitorData.CONNECTING);
if (socketAddress == null) {
if (kplink.isClosed()) {
close();
break;
}
if(addressGroup==null) {
byte[]addr=new byte[16];
SecureRandom scr=new SecureRandom();
scr.nextBytes(addr);
addr[0]=(byte)0x24;
addr[1]=(byte) 0x86;
addr[2]=0;
addr[3]=2;
addr[14]=0;
addr[15]=1;
Inet6Address i6a=(Inet6Address) Inet6Address.getByAddress(addr);
addressGroup=new Inet6AddressGroup(i6a, 112);
}
} else {
kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress);
}
//startRecord();
kplink.setSoTimeout(20000);
Thread t = ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> {
tlock = Thread.currentThread();
//tlock.setPriority(Thread.NORM_PRIORITY+1);
try {
writePacketToKPL(new ADDRREQPacket());
writePacketToKPL(new ADDRREQPacket());
if(addressGroup!=null) {
writePacketToKPL(new ADDRPacket(addressGroup));
writePacketToKPL(new ADDRPacket(addressGroup));
}
writePacketToKPL(new VADDRREQPacket());
writePacketToKPL(new VADDRREQPacket());
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
flushKPL();
KLALBPacket kpp = null;
while ((!kplink.isClosed()) && (!closed)) {
// TimeDebugger tdb=new TimeDebugger();
// tdb.putTime("start");
if(checkBandwidthReportTime()) {
sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg2(), monitor.getInSpeedAvg2()));
}
if (checkPingTimeSleep()) {
writePacketToKPL(new PINGPacket(System.nanoTime()));
if (remoteVaddr == null)
writePacketToKPL(new VADDRREQPacket());
if(peerAddress==null)
writePacketToKPL(new ADDRREQPacket());
}else {
KLALBPacket kpip = IsendDequeList.poll();
if (kpip != null) {
writePacketToKPL(kpip);
}else {
// tdb.putTime("Isend");
if (kpp == null) {
do {
kpp = sendDequeList.poll();
} while (kpp != null && kpp.isDisposed());
if(kpp==null) {
monitor.setQueueingDelay(0);
}
}
// System.out.println(sendDequeList.size());
if (kpp != null) {
// TimeDebugger tdb=new TimeDebugger();
//tdb.putTime("start");
KLALBPacket kppt=kpp;
kppt.lockAll();
try {
if (kpp.isSomeDisposed()) {
kpp = null;
} else {
// if (congress.checkTransmit(length)) {
writePacketToKPL(kpp);
if (checkPingTime()) {
writePacketToKPL(new PINGPacket(System.nanoTime()));
}
monitor.setQueueingDelay( System.nanoTime()- kpp.getJoinqueuetime());
/*if (kpp instanceof DATATPacket||kpp instanceof IPv6OverKLALBPacket) {
resetSleepTimer();
}*/
kpp.doDisposeAfterSend();
kpp = null;
}
//}
} finally {
kppt.unlockAll();
}
//tdb.putTime("sendToLink");
//tdb.print();
}else {
LockSupport.parkNanos(1000000);
}
}
}
/*if (flsh) {
flushKPL();
} else {
// tdb.putTime("send");
// tdb.putTime("flush");
if (pressure && pressureSpeed.checkTransmit(testPacket.getLength())) {
writePacketToKPL(testPacket);
flushKPL();
} else {
tlock = Thread.currentThread();
LockSupport.parkNanos(1000000);
}
// tdb.putTime("park");
}*/
// tdb.print();
// System.out.println(sendDequeList.isEmpty());
Thread.yield();
}
} catch (IOException | UnresolvedAddressException e) {
if (debug)
e.printStackTrace();
} finally {
try {
kplink.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
boolean fst = true;
long stime = 5000000000L;
while ((!kplink.isClosed()) && (!closed)) {
long readStart = System.nanoTime();
KLALBPacket kpp = readPacketFromKPL();
/*long readTime = System.nanoTime() - readStart;
readTime *= 10;
if (readTime > stime) {
stime = readTime;
} else {
stime = (stime * 999 + readTime) / 1000;
}
if (stime < 2000000000L) {
stime = 2000000000L;
}*/
// System.out.println(readTime);
kplink.setSoTimeout(3000);
kplink.setSoTimeout((int) (stime / 1000000));
if (kpp == null) {
break;
}
switch (kpp.getType()) {
case KLALBPacket.PING:
sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime()));
break;
case KLALBPacket.PONG:
PONGPacket png = (PONGPacket) kpp;
long ul = png.getRcvtime() - png.getTimepingsnd()-(png.getTimepongsnd()-png.getTimepingrcv());
long DsndDelayFactor0 = png.getTimepingrcv() - png.getTimepingsnd();
long DrcvDelayFactor0 = png.getRcvtime() - png.getTimepongsnd();
long DsndDelayFactor;
long DrcvDelayFactor;
adjnc.getLock().lock();
try {
adjnc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
if (DsndDelayFactor < 0) {
if (DrcvDelayFactor < 0) {
} else {
adjnc.setDelta(adjnc.getDelta() + DsndDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
}
} else {
if (DrcvDelayFactor < 0) {
adjnc.setDelta(adjnc.getDelta() - DrcvDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
}
}
} finally {
adjnc.getLock().unlock();
}
if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) {
monitor.setOutDelay(DsndDelayFactor);
monitor.setInDelay(DrcvDelayFactor);
monitor.setRecentPingNanoTime(png.getTimepingsnd());
//pingInterval = monitor.getLatencyAvg()+2000000L;
//double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay();
loadPercent =Math.max( 1.2,0.4);
}
LockSupport.unpark(tlock);
break;
case KLALBPacket.BWINF:
BWINFPacket bwi = (BWINFPacket) kpp;
if (bwi.getDownSpeed() >= congressSpeed) {
congressSpeed = bwi.getDownSpeed();
} else {
congressSpeed = (congressSpeed * 999 + bwi.getDownSpeed()) / 1000;
}
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) );
// System.out.println(congressSpeed);
break;
case KLALBPacket.ADDRREQ:
if(addressGroup!=null)
sendIPacket(new ADDRPacket(addressGroup));
break;
case KLALBPacket.ADDR:
peerAddress = ((ADDRPacket) kpp).getAddr();
if(addressGroup==null) {
byte[]ab=peerAddress.getAddress().getAddress();
ab[15]=2;
Inet6AddressGroup ardg2=new Inet6AddressGroup((Inet6Address) InetAddress.getByAddress(ab),peerAddress.getPrefixLength());
addressGroup=ardg2;
}
break;
case KLALBPacket.VADDRREQ:
sendIPacket(new VADDRPacket(localVaddrSupplier.get()));
break;
case KLALBPacket.VADDR:
Inet6AddressGroup vdr = ((VADDRPacket) kpp).getVaddr();
remoteVaddr = vdr;
sendIPacket(new VADDRACKPacket());
if (klalbController != null) {
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress());
}
if (fst) {
// coll.resetCoolingTime();
monitor.setState(MonitorData.ONLINE);
fst = false;
}
break;
case KLALBPacket.VADDRACK:
break;
case KLALBPacket.TEST:
break;
case KLALBPacket.IPV6OVERKLALB:
if(ipv6con!=null) {
IPv6OverKLALBPacket ivk=(IPv6OverKLALBPacket) kpp;
IPv6Packet iv6= ivk.getIPv6Packet();
ivk.putTimePassport("unpacked");
ivk.printPassport();
iv6.putTimePassport("unpackFromLink");
ipv6con.accept(iv6);
}
break;
default:
while (rec == null) {
Thread.sleep(1);
}
rec.accept( kpp);
break;
}
Thread.yield();
}
} catch (IOException | UnresolvedAddressException e) {
if (debug)
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
monitor.setState(MonitorData.OFFLINE);
pressure = false;
try {
if (kplink != null)
kplink.close();
} catch (IOException e) {
e.printStackTrace();
}
/*KLALBPacket pack;
while((pack=sendDequeList.poll())!=null) {
try {
if(remoteVaddr!=null) {
klalbController.sendPacketToLinkAddress(remoteVaddr, pack);
if(debug)
System.out.println("RETRY:"+pack);
}
} catch (IOException e) {
}
}*/
}
if (closed) {
break;
}
// Thread.sleep(monitor.getCoolingTime());
lthd = Thread.currentThread();
LockSupport.parkNanos(coll.getCoolingTime(monitor.getReliability()));
// coll.incCoolingTime();
}
}).start();
}
private void flushKPL() throws IOException {
kplink.flush();
}
private KLALBPacket readPacketFromKPL() throws IOException {
KLALBPacket packet = kplink.readPacket();
if (showpacket) {
if (!(packet instanceof PINGPacket))
if (!(packet instanceof PONGPacket))
if (!(packet instanceof BWINFPacket))
System.out.println("RX:" + packet);
}
if (packet != null) {
packet.putTimePassport("received");
long length=packet.getLength();
monitor.getInTrafficAL().addAndGet(length);
monitor.getInPacketCounterAL().incrementAndGet();
if (klalbController != null)
klalbController.getLinkMonitor().getInTrafficAL().addAndGet(length);
klalbController.getLinkMonitor().getInPacketCounterAL().incrementAndGet();
}
return packet;
}
private void writePacketToKPL(KLALBPacket packet) throws IOException {
long length=packet.getLength();
monitor.getOutTrafficAL().addAndGet(length);
monitor.getOutPacketCounterAL().incrementAndGet();
if (klalbController != null)
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
kplink.writePacket(packet);
packet.putTimePassport("sended");
packet.printPassport();
if (showpacket) {
if (!(packet instanceof PINGPacket))
if (!(packet instanceof PONGPacket))
if (!(packet instanceof BWINFPacket))
System.err.println("TX:" + packet);
}
}
private void writePacketToKPL(KLALBPacket packet,long length) throws IOException {
monitor.getOutTrafficAL().addAndGet(length);
monitor.getOutPacketCounterAL().incrementAndGet();
if (klalbController != null)
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
kplink.writePacket(packet);
if (showpacket) {
if (!(packet instanceof PINGPacket))
if (!(packet instanceof PONGPacket))
if (!(packet instanceof BWINFPacket))
System.err.println("TX:" + packet);
}
}
public void close() {
closed = true;
monitor.setState(MonitorData.OFFLINE);
pressure = false;
try {
if (kplink != null)
kplink.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean isClosed() {
return closed;
}
private volatile long time = System.nanoTime();
private volatile long pingInterval = 10000000L;
private volatile long pingIntervalSleep = 200000000L;
private boolean checkPingTime() {
long cu = System.nanoTime();
if (cu - time > pingInterval) {
time = cu;
return true;
} else {
return false;
}
}
private boolean checkPingTimeSleep() {
long cu = System.nanoTime();
if (cu - time > pingIntervalSleep) {
time = cu;
return true;
} else {
return false;
}
}
private volatile long bwtime = System.nanoTime();
private volatile long bwpingInterval = 10000000L;
private volatile long bwpingIntervalSleep = 100000000L;
private boolean checkBandwidthReportTime(){
long cu = System.nanoTime();
if (cu - bwtime > bwpingIntervalSleep) {
bwtime = cu;
return true;
} else {
return false;
}
}
private volatile Consumer<KLALBPacket> rec;
private volatile Thread tlock;
private ConcurrentLinkedQueue<KLALBPacket> IsendDequeList = new ConcurrentLinkedQueue<KLALBPacket>();
private PriorityBlockingQueue<KLALBPacket> sendDequeList = new PriorityBlockingQueue<KLALBPacket>();
public PriorityBlockingQueue<KLALBPacket> getQueue() {
return sendDequeList;
}
protected void sendPacket(KLALBPacket blk) {
blk.markJoinqueuetime();
sendDequeList.add(blk);
LockSupport.unpark(tlock);
}
private void sendIPacket(KLALBPacket blk) {
IsendDequeList.add(blk);
LockSupport.unpark(tlock);
}
public void setPacketReceiver(Consumer< KLALBPacket> rec) {
this.rec = rec;
}
/*public void remoeFromSendQueue(KLALBPacket klalbPacket) {
sendDequeList.remove(klalbPacket);
}*/
public long statLengthBefore(long l) {
AtomicLong al = new AtomicLong();
for (Iterator<KLALBPacket> iterator = sendDequeList.iterator(); iterator.hasNext();) {
KLALBPacket queue = iterator.next();
if (queue.getPriority() <= l) {
al.addAndGet(queue.getLength());
}
}
return al.get();
}
private volatile long predictTime;
public void runPredict() {
//predictTime = monitor.getOutDelayPredicted();
predictTime=monitor.getOutDelay();
/*
* long al=0; al=statLengthBefore(5); long speed=getMonitor().getOutSpeedAvg();
* // spdlmt.setLimitspeed(speed*2+65536); if(speed==0) { if(al>0) {
* predictTime=Long.MAX_VALUE; } }else { predictTime+=al*1000000000L/speed; }
*/
}
@Override
public int compareTo(KLALBRemoteLine o2) {
long t1 = this.predictTime;
long t2 = o2.predictTime;
if (t1 > t2) {
return 1;
} else if (t1 < t2) {
return -1;
} else {
return 0;
}
}
public void reconnectImmediately() {
if (lthd != null) {
LockSupport.unpark(lthd);
}
}
public void dislink() {
if (kplink != null) {
try {
kplink.close();
} catch (IOException e) {
}
}
}
private static final TESTPacket testPacket = new TESTPacket(60000);
private volatile boolean pressure = false;
private SpeedLimiter pressureSpeed = new SpeedLimiter(32768);
public void pressureTest() {
if (pressure)
throw new IllegalStateException("Test already start");
this.pressure = true;
pressureSpeed.setLimitspeed(32768);
ThreadTool.makeVThreadIfSupport("压力测试控制线程", () -> {
while (pressure) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (getMonitor().getOutSpeed() < pressureSpeed.getLimitspeed() * 2 / 3
|| getMonitor().getInDelayMin() * 30 < getMonitor().getInDelay()) {
pressure = false;
break;
}
pressureSpeed.setLimitspeed(pressureSpeed.getLimitspeed() * 400 / 399);
}
}).start();
}
public long getPredictedTime() {
return predictTime;
}
private List<Double>ranks=new ArrayList<Double>();
private Consumer<IPv6Packet> ipv6con;
@Override
public void noticeRank(int rank) {
while(rank>=ranks.size()) {
ranks.add(0.5);
}
for (int i = 0; i < ranks.size(); i++) {
if(i==rank) {
ranks.set(i, (ranks.get(i)*99.0+1.0D)/100.0);
}else {
ranks.set(i, ranks.get(i)*99.0/100.0);
}
}
}
@Override
public double getWeightAtRank(int rank) {
while(rank>=ranks.size()) {
ranks.add(0.5);
}
return ranks.get(rank);
}
public List<Double> getRanks() {
return ranks;
}
@Override
public boolean isLoopBack() {
return false;
}
@Override
public List<Neighbor> getNeighborsInfo() {
List<Neighbor>hs=new ArrayList<>();
if(peerAddress!=null) {
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor));
//System.out.println(peerAddress+" "+addressGroup);
}
return hs;
}
@Override
public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException {
pack.lockAll();
try {
if(pack.isSomeDisposed()) {
return;
}
if(inet6Address.equals(remoteVaddr.getAddress())||inet6Address.equals(peerAddress.getAddress())) {
IPv6OverKLALBPacket kipv6=new IPv6OverKLALBPacket(pack);
kipv6.setPriority(pack.getPriority());
kipv6.setDisposeAfterSend(true);
pack.putTimePassport("packdInLink");
pack.printPassport();
sendPacketToLink(kipv6);
}
}finally {
pack.unlockAll();
}
}
private void sendPacketToLink(KLALBPacket packet) {
packet.genseq();
//packet.getSendRecord().add(this);
sendPacket(packet);
}
@Override
public boolean isCongress(IPv6Packet iPv6Packet) {
int size=getQueue().size();
if(size>30) {
return true;
}else {
return !congress.checkTransmit(iPv6Packet.getLength());
}
}
@Override
public String getName() {
return monitor.getName();
}
@Override
public boolean isUp() {
return (!isClosed())&&getMonitor().getState()==MonitorData.ONLINE;
}
@Override
public boolean canSend(IPv6Packet iPv6Packet) {
return true;
}
@Override
public void setReceiveConsumer(Consumer<IPv6Packet> ipv6con) {
this.ipv6con=ipv6con;
}
}