This commit is contained in:
Administrator
2025-04-24 10:16:38 +08:00
parent 6de65562be
commit 7267aec1fd
108 changed files with 7621 additions and 1890 deletions
@@ -0,0 +1,272 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.BindException;
import java.net.DatagramPacket;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
import org.kne.cloud.network.ByteBufferAllocator;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.RawSocketImpl;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.VirtualRawSocketImpl;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload;
import org.kne.cloud.network.srv6.PacketConsumer;
import org.kne.cloud.network.srv6.SRv6Router;
import org.kne.concurrent.HighPerformanceExecutor;
import org.kne.io.KNEChannels;
public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements PacketConsumer{
private boolean ipHeaderInclude=false;
private SRv6Router router;
protected volatile Inet6Address remoteaddr;
protected volatile Inet6Address localaddr;
private int bindProtocolNumber;
private volatile int inputchachesize = 1024*1024;
protected SRv6Router getRouter() {
return router;
}
public KLALBVirtualRawSocketImpl(SRv6Router router) {
super();
this.router = router;
}
@Override
public void setOption(int optID, Object value) throws SocketException {
// TODO 自动生成的方法存根
}
@Override
public Object getOption(int optID) throws SocketException {
// TODO 自动生成的方法存根
return null;
}
@Override
protected void create() throws IOException {
}
@Override
protected void setIPHeaderInclude(boolean ipHeaderInclude) throws IOException {
this.ipHeaderInclude=ipHeaderInclude;
}
@Override
protected boolean getIPHeaderInclude() throws IOException {
return ipHeaderInclude;
}
@Override
protected void setUseSelectTimeout(boolean useSelect) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected boolean getUseSelectTimeout() throws IOException {
// TODO 自动生成的方法存根
return false;
}
@Override
protected void setSendTimeout(int timeout) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected int getSendTimeout() throws IOException {
// TODO 自动生成的方法存根
return 0;
}
@Override
protected void setReceiveTimeout(int timeout) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected int getReceiveTimeout() throws IOException {
// TODO 自动生成的方法存根
return 0;
}
@Override
protected void close() {
router.getProtocolNumberRegister().remove(bindProtocolNumber);
}
@Override
protected void bind(InetAddress address,int protocolNumber) throws SocketException{
if(protocolNumber<0) {
throw new UnsupportedOperationException("unsupprted bind all protocols");
}
try {
if (address.equals(Inet4Address.getByName("0.0.0.0"))) {
address = Inet6Address.getByName("::0");
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
if (!(address instanceof Inet6Address)) {
throw new IllegalArgumentException("invalid address type, KLALB socket can only use IPV6 address");
}
if ((!address.isAnyLocalAddress()) && (!address.equals(router.getLocator().getAddress()))) {
throw new BindException("must bind to self");
}
localaddr=(Inet6Address) address;
this.bindProtocolNumber=protocolNumber;
if(router.getProtocolNumberRegister().putIfAbsent(protocolNumber, this)!=null) {
throw new BindException("protocol number already bind");
}
}
@Override
protected void join(InetAddress inetaddr) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected void leave(InetAddress inetaddr) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected void joinGroup(InetAddress mcastaddr, NetworkInterface netIf) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected void leaveGroup(InetAddress mcastaddr, NetworkInterface netIf) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected void send(DatagramPacket p) throws IOException {
ByteBuffer buf= ByteBuffer.wrap(p.getData(), p.getOffset(), p.getLength());
if(ipHeaderInclude) {
}else {
HighPerformanceExecutor.defaultExecutor.execute(() -> {
IPv6Packet ipv=new IPv6Packet();
ipv.setVersion(6);
ipv.setTrafficClass(0);
ipv.setFlowLabel(0);
ipv.setHopLimit(255);
ipv.setSourceAddress(router.getLocator().getAddress());
InetAddress address= p.getAddress();
if (!(address instanceof Inet6Address)) {
throw new IllegalArgumentException("invalid address type, KLALB socket can only use IPV6 address");
}
ipv.setDestinationAddress((Inet6Address)address);
ipv.setPriority(3);
//ipv.enableECN();
IPv6Payload pl=new IPv6Payload(bindProtocolNumber);
pl.getData().put(buf);
pl.getData().flip();
ipv.setPayload(pl);
router.insertSRHandRoutePacket(ipv);
});
}
}
@Override
protected InetAddress peek() throws IOException {
return peekNextPacket().getSourceAddress();
}
@Override
protected void peekData(DatagramPacket p) throws IOException {
IPv6Packet pack=peekNextPacket();
copyTo(pack, p);
}
private void copyTo(IPv6Packet pack, DatagramPacket p) throws IOException {
p.setAddress(pack.getSourceAddress());
ByteBuffer buffer= ByteBuffer.wrap(p.getData(),p.getOffset(),p.getLength());
if(ipHeaderInclude) {
}else {
try {
pack.getPayload().writeToChannel(KNEChannels.newWritableChannel(buffer));
}catch(BufferOverflowException e) {
}
}
buffer.flip();
p.setLength(buffer.limit());
}
@Override
protected void receive(DatagramPacket p) throws IOException {
IPv6Packet pack=pollNextPacket();
copyTo(pack, p);
}
private volatile Thread parkThread;
private IPv6Packet peekNextPacket() {
IPv6Packet pol=null;
while(true) {
pol=recvQueue.peek();
if(pol!=null) {
recvQueueUsed.addAndGet((int) -pol.getPayload().getLength());
return pol;
}
parkThread=Thread.currentThread();
LockSupport.parkNanos(1000000L);
}
}
private IPv6Packet pollNextPacket() {
IPv6Packet pol=null;
while(true) {
pol=recvQueue.poll();
if(pol!=null) {
recvQueueUsed.addAndGet((int) -pol.getPayload().getLength());
return pol;
}
parkThread=Thread.currentThread();
LockSupport.parkNanos(1000000L);
}
}
private Queue<IPv6Packet> recvQueue = new ConcurrentLinkedQueue<IPv6Packet>();
private AtomicInteger recvQueueUsed=new AtomicInteger(0);
@Override
public void accept(IPv6Packet packx) throws IOException {
if(recvQueueUsed.get()<=inputchachesize) {
if(recvQueue.offer(packx)) {
recvQueueUsed.addAndGet((int) packx.getPayload().getLength());
LockSupport.unpark(parkThread);
}
}
}
}