This should work

This commit is contained in:
gruetzkopf
2022-01-30 21:10:14 +01:00
committed by Kilobyte22
parent 9f68c9c320
commit 4c3ef28236
3 changed files with 81 additions and 29 deletions

View File

@@ -2,6 +2,7 @@ package li.cil.oc2.common.block;
import li.cil.oc2.common.blockentity.BlockEntities;
import li.cil.oc2.common.blockentity.NetworkHubBlockEntity;
import li.cil.oc2.common.blockentity.TickableBlockEntity;
import li.cil.oc2.common.blockentity.VxlanBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -12,6 +13,8 @@ import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.material.Material;
@@ -52,6 +55,12 @@ public final class VxlanBlock extends HorizontalDirectionalBlock implements Enti
return BlockEntities.VXLAN_HUB.get().create(pos, state);
}
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(final Level level, final BlockState state, final BlockEntityType<T> type) {
return TickableBlockEntity.createServerTicker(level, type, BlockEntities.VXLAN_HUB.get());
}
///////////////////////////////////////////////////////////////////
@Override

View File

@@ -16,13 +16,19 @@ import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.stream.Stream;
public final class VxlanBlockEntity extends ModBlockEntity implements NetworkInterface {
public final class VxlanBlockEntity extends ModBlockEntity implements NetworkInterface, TickableBlockEntity {
private static final int TTL_COST = 1;
private int vti = ((int) (Math.random() * Integer.MAX_VALUE)) & 0x00ff_ffff;
//private int vti = ((int) (Math.random() * Integer.MAX_VALUE)) & 0x00ff_ffff;
private int vti = 4037973;
private boolean initialized = false;
private BlockingQueue<byte[]> packetQueue = new ArrayBlockingQueue<byte[]>(32);
///////////////////////////////////////////////////////////////////
// Each face and the default TunnelInterface connecting to the outernet
@@ -32,9 +38,10 @@ public final class VxlanBlockEntity extends ModBlockEntity implements NetworkInt
///////////////////////////////////////////////////////////////////
public VxlanBlockEntity(final BlockPos pos, final BlockState state) {
super(BlockEntities.NETWORK_HUB.get(), pos, state);
super(BlockEntities.VXLAN_HUB.get(), pos, state);
}
///////////////////////////////////////////////////////////////////
public void handleNeighborChanged() {
@@ -55,24 +62,47 @@ public final class VxlanBlockEntity extends ModBlockEntity implements NetworkInt
});
}
@Override
public void serverTick() {
if (level == null) {
return;
}
if (adjacentBlockInterfaces[0] != null) {
packetQueue.forEach(packet -> {
writeEthernetFrame(adjacentBlockInterfaces[0], packet, 255);
});
packetQueue.clear();
} else {
System.out.printf("VXLAN block is unregistered upstream: VTI=%d\n", vti);
}
}
///////////////////////////////////////////////////////////////////
@Override
public void load(CompoundTag tag) {
super.load(tag);
vti = tag.getInt("vti");
if (!level.isClientSide()) {
// vti = tag.getInt("vti");
adjacentBlockInterfaces[0] = TunnelManager.instance().registerVti(vti, packetQueue);
}
}
@Override
public void saveAdditional(CompoundTag tag) {
super.saveAdditional(tag);
tag.putInt("vti", vti);
if (!level.isClientSide()) {
tag.putInt("vti", vti);
}
}
@Override
protected void onUnload(final boolean isRemove) {
adjacentBlockInterfaces[0] = null;
TunnelManager.instance().unregisterVti(vti);
if (!level.isClientSide()) {
adjacentBlockInterfaces[0] = null;
TunnelManager.instance().unregisterVti(vti);
}
super.onUnload(isRemove);
}
@@ -83,12 +113,14 @@ public final class VxlanBlockEntity extends ModBlockEntity implements NetworkInt
if (!level.isClientSide()) {
System.out.println("Tunnel VTI: " + vti);
adjacentBlockInterfaces[0] = TunnelManager.instance().registerVti(vti, this.packetQueue);
}
adjacentBlockInterfaces[0] = TunnelManager.instance().registerVti(vti, this);
}
///////////////////////////////////////////////////////////////////
@Override
protected void collectCapabilities(final CapabilityCollector collector, @Nullable final Direction direction) {
collector.offer(Capabilities.NETWORK_INTERFACE, this);

View File

@@ -2,11 +2,11 @@ package li.cil.oc2.common.vxlan;
import li.cil.oc2.api.capabilities.NetworkInterface;
import li.cil.oc2.common.Config;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.*;
import java.util.HashMap;
import java.util.concurrent.BlockingQueue;
public class TunnelManager {
@@ -28,8 +28,8 @@ public class TunnelManager {
public static void initialize() {
try {
INSTANCE = new TunnelManager(
InetAddress.getByName("2001:16b8:4908:5700:d22e:ecd:e75b:f5a8"), (short) Config.bindPort,
InetAddress.getByName("2001:470:7398::a"), (short) Config.remotePort
InetAddress.getByName("2001:470:7398::a"), (short) Config.bindPort,
InetAddress.getByName("2001:470:7398::10"), (short) Config.remotePort
);
} catch (SocketException | UnknownHostException e) {
System.out.println("Failed to bind host: " + e.getMessage());
@@ -37,13 +37,15 @@ public class TunnelManager {
}
//if (Config.enable) {
new Thread(() -> {
Thread bgThread = new Thread(() -> {
try {
INSTANCE.listen();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
});
bgThread.setName("VXLAN Background Thread");
bgThread.start();
//}
}
@@ -52,7 +54,7 @@ public class TunnelManager {
//if (Config.enable) {
socket = new DatagramSocket(bindPort/*, bindHost*/);
socket.connect(remoteHost, remotePort);
//socket.connect(remoteHost, remotePort);
//} else {
// socket = null;
//}
@@ -62,28 +64,33 @@ public class TunnelManager {
while (true) {
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
System.out.println("Received message");
if (packet.getData().length < 8) {
if (packet.getLength() < 8) {
continue;
}
byte flags = packet.getData()[0];
int vni = packet.getData()[6]
+ packet.getData()[5] << 8
+ packet.getData()[4] << 16;
int vni = (packet.getData()[6] & 0xFF )
| ( ( packet.getData()[5] & 0xFF ) << 8 )
| ( ( packet.getData()[4] & 0xFF ) << 16 );
if ((flags & 0x08) != 0x08) {
continue;
}
System.out.println(vni);
TunnelInterface iface = tunnels.get(vni);
if (iface != null) {
byte[] inner = new byte[packet.getData().length - 8];
System.arraycopy(packet.getData(), 8, inner, 0, packet.getData().length - 8);
byte[] inner = new byte[packet.getLength() - 8];
System.arraycopy(packet.getData(), 8, inner, 0, packet.getLength() - 8);
iface.target.writeEthernetFrame(iface, inner, 255);
try {
iface.packetQueue.add(inner);
} catch (IllegalStateException ignored) {
System.err.println("Queue full");
}
}
}
}
@@ -92,8 +99,9 @@ public class TunnelManager {
return INSTANCE;
}
public void sendToVti(int vti, byte[] payload) {
public void sendToOuternet(int vti, byte[] payload) {
if (socket != null) {
byte[] buffer = new byte[payload.length + 8];
System.arraycopy(payload, 0, buffer, 8, payload.length);
@@ -110,11 +118,13 @@ public class TunnelManager {
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.printf("No socket in TunnelManager\n");
}
}
public NetworkInterface registerVti(int vti, NetworkInterface iface) {
TunnelInterface tuniface = new TunnelInterface(vti, iface);
public NetworkInterface registerVti(int vti, BlockingQueue<byte[]> packetQueue) {
TunnelInterface tuniface = new TunnelInterface(vti, packetQueue);
tunnels.put(vti, tuniface);
return tuniface;
}
@@ -124,14 +134,15 @@ public class TunnelManager {
}
public class TunnelInterface implements NetworkInterface {
final NetworkInterface target;
final BlockingQueue<byte[]> packetQueue;
private final int vti;
public TunnelInterface(int vti, NetworkInterface iface) {
public TunnelInterface(int vti, BlockingQueue<byte[]> packetQueue) {
this.vti = vti;
this.target = iface;
this.packetQueue = packetQueue;
}
@Override
public byte[] readEthernetFrame() {
return new byte[0];
@@ -139,7 +150,7 @@ public class TunnelManager {
@Override
public void writeEthernetFrame(final NetworkInterface source, final byte[] frame, final int timeToLive) {
TunnelManager.this.sendToVti(vti, frame);
TunnelManager.this.sendToOuternet(vti, frame);
}
}
}