Skip to content

Commit

Permalink
TODOs
Browse files Browse the repository at this point in the history
  • Loading branch information
Tilmann Zäschke committed Feb 28, 2024
1 parent 5b11f83 commit 0c091ab
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 74 deletions.
35 changes: 17 additions & 18 deletions src/main/java/org/scion/ScionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,10 @@ public class ScionService {

private static final String DNS_TXT_KEY = "scion";
private static final Object LOCK = new Object();
private static ScionService DEFAULT = null;
private static final String ERR_INVALID_TXT = "Invalid TXT entry: ";
private static ScionService defaultService = null;

private final ScionBootstrapper bootstrapper;
// TODO create subclasses for these two? We can only have either one of them, not both.
private final DaemonServiceGrpc.DaemonServiceBlockingStub daemonStub;
private final SegmentLookupServiceGrpc.SegmentLookupServiceBlockingStub segmentStub;

Expand Down Expand Up @@ -133,28 +132,28 @@ static ScionService defaultService() {
synchronized (LOCK) {
// This is not 100% thread safe, but the worst that can happen is that
// we call close() on a Service that has already been closed.
if (DEFAULT != null) {
return DEFAULT;
if (defaultService != null) {
return defaultService;
}
// try bootstrap service IP
String fileName =
ScionUtil.getPropertyOrEnv(PROPERTY_BOOTSTRAP_TOPO_FILE, ENV_BOOTSTRAP_TOPO_FILE);
if (fileName != null) {
DEFAULT = new ScionService(fileName, Mode.BOOTSTRAP_TOPO_FILE);
return DEFAULT;
defaultService = new ScionService(fileName, Mode.BOOTSTRAP_TOPO_FILE);
return defaultService;
}

String server = ScionUtil.getPropertyOrEnv(PROPERTY_BOOTSTRAP_HOST, ENV_BOOTSTRAP_HOST);
if (server != null) {
DEFAULT = new ScionService(server, Mode.BOOTSTRAP_SERVER_IP);
return DEFAULT;
defaultService = new ScionService(server, Mode.BOOTSTRAP_SERVER_IP);
return defaultService;
}

String naptrName =
ScionUtil.getPropertyOrEnv(PROPERTY_BOOTSTRAP_NAPTR_NAME, ENV_BOOTSTRAP_NAPTR_NAME);
if (naptrName != null) {
DEFAULT = new ScionService(naptrName, Mode.BOOTSTRAP_VIA_DNS);
return DEFAULT;
defaultService = new ScionService(naptrName, Mode.BOOTSTRAP_VIA_DNS);
return defaultService;
}

// try daemon
Expand All @@ -163,8 +162,8 @@ static ScionService defaultService() {
String daemonPort =
ScionUtil.getPropertyOrEnv(PROPERTY_DAEMON_PORT, ENV_DAEMON_PORT, DEFAULT_DAEMON_PORT);
try {
DEFAULT = new ScionService(daemonHost + ":" + daemonPort, Mode.DAEMON);
return DEFAULT;
defaultService = new ScionService(daemonHost + ":" + daemonPort, Mode.DAEMON);
return defaultService;
} catch (ScionRuntimeException e) {
throw new ScionRuntimeException(
"Could not connect to daemon, DNS or bootstrap resource.", e);
Expand All @@ -174,13 +173,13 @@ static ScionService defaultService() {

public static void closeDefault() {
synchronized (LOCK) {
if (DEFAULT != null) {
if (defaultService != null) {
try {
DEFAULT.close();
defaultService.close();
} catch (IOException e) {
throw new ScionRuntimeException(e);
} finally {
DEFAULT = null;
defaultService = null;
}
}
}
Expand All @@ -191,9 +190,9 @@ private Thread addShutdownHook() {
new Thread(
() -> {
try {
if (DEFAULT != null) {
DEFAULT.shutdownHook = null;
DEFAULT.close();
if (defaultService != null) {
defaultService.shutdownHook = null;
defaultService.close();

Check warning on line 195 in src/main/java/org/scion/ScionService.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/scion/ScionService.java#L194-L195

Added lines #L194 - L195 were not covered by tests
}
} catch (IOException e) {
// Ignore, we just want to get out.
Expand Down
25 changes: 6 additions & 19 deletions src/main/java/org/scion/ScionSocketOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.net.SocketOption;

public final class ScionSocketOptions {
// TODO options for Daemon ports/IPs?

/**
* If set to 'true', the Scion header parser will throw errors when encountering problems while
Expand All @@ -28,29 +27,17 @@ public final class ScionSocketOptions {
new SciSocketOption<>("SN_API_THROW_PARSER_FAILURE", Boolean.class);

/**
* TODO not yet implemented. If set to 'true', the receive() and read() operations will read new
* packets directly into the ByteBuffer provided by the user. The ByteBuffer will contain the
* header and the position of will be set to the first byte of the payload. This has two
* advantages: the payload does not need to be copied (saving one copy operation) and the Scion
* packet header is directly available to the user. If set to 'false', the receive() and read()
* operations will copy the payload to the ByteBuffer provided by the user. Default is 'false'
* If set to 'true', the receive() and read() operations will read new packets directly into the
* ByteBuffer provided by the user. The ByteBuffer will contain the header and the position of
* will be set to the first byte of the payload. This has two advantages: the payload does not
* need to be copied (saving one copy operation) and the Scion packet header is directly available
* to the user. If set to 'false', the receive() and read() operations will copy the payload to
* the ByteBuffer provided by the user. Default is 'false'
*/
@Deprecated // TODO implement
public static final SocketOption<Boolean> SN_API_WRITE_TO_USER_BUFFER =
new SciSocketOption<>("SN_API_WRITE_TO_USER_BUFFER", Boolean.class);

// TODO can we use this size for the ByteBuffer in the channel? In the original socket
// they probably refer to a different type of byffer, i.e. if packets are generated
// faster than they can be sent.
// -> The Channel only has *one* buffer....
// /** The size of the socket send buffer. Default is 2000. */
// public static final SocketOption<Integer> SSO_SNDBUF = new SciSocketOption<>("SSO_SNDBUF",
// Integer.class);;
//
// /** The size of the socket receive buffer. Default is 2000. */
// public static final SocketOption<Integer> SSO_RCVBUF = new SciSocketOption<>("SSO_RCVBUF",
// Integer.class);;

/**
* Before sending a packet, a new path will be requested if now() + pathExpirationMargin >
* pathExpirationDate.
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/scion/internal/ScionBootstrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private static String bootstrapViaDNS(String hostName) {
if (STR_X_SCION_TCP.equals(naptrService)) {
String host = nr.getReplacement().toString();
String naptrFlag = nr.getFlags();
LOG.info("Found DNS entry: " + naptrService);
LOG.info("Found DNS entry: {}", naptrService);
int port = queryTXT(hostName);
if ("A".equals(naptrFlag)) {
InetAddress addr = DNSHelper.queryA(host);
Expand Down Expand Up @@ -240,14 +240,14 @@ public int getLocalMtu() {
}

public void refreshTopology() {
// TODO check timeout from dig netsec-w37w3w.inf.ethz.ch?
// TODO check timeout from NAPTR record
// TODO verify local DNS?? How?
// init();
throw new UnsupportedOperationException();
}

private String getTopologyFile() throws IOException {
LOG.info("Getting topology from bootstrap server: " + topologyResource);
LOG.info("Getting topology from bootstrap server: {}", topologyResource);
controlServices.clear();
discoveryServices.clear();
// TODO https????
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/org/scion/internal/ScionHeaderParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public static void extractUserPayload(ByteBuffer data, ByteBuffer userBuffer) {
* @param data The datagram to read from.
* @return A new ScionSocketAddress including raw path.
*/
// TODO this is a bit weird to have the firstHopAddress here....
public static ResponsePath extractResponsePath(
ByteBuffer data, InetSocketAddress firstHopAddress) {
int pos = data.position();
Expand Down Expand Up @@ -337,7 +336,7 @@ public static void write(
i0 = writeInt(i0, 12, 20, 1); // FlowID = 1
data.putInt(i0);
i1 = writeInt(i1, 0, 8, hdrType.code); // NextHdr = 17 is for UDP OverlayHeader
int newHdrLen = (calcLen(pathHeaderLength, dl, sl) - 1) / 4 + 1;
int newHdrLen = (calcLen(pathHeaderLength, sl, dl) - 1) / 4 + 1;
i1 = writeInt(i1, 8, 8, newHdrLen); // HdrLen = bytes/4
i1 = writeInt(i1, 16, 16, userPacketLength); // PayloadLen (+ overlay!)
data.putInt(i1);
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/scion/ProtobufPathDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ public class ProtobufPathDemo {

public static void main(String[] args) {
try (Scion.CloseableService daemon =
Scion.newServiceWithDaemon(DemoConstants.daemon121_minimal)) {
Scion.newServiceWithDaemon(DemoConstants.daemon110_minimal)) {
ProtobufPathDemo demo = new ProtobufPathDemo(daemon);
demo.testAsInfo();
demo.testInterfaces();
demo.testServices();
demo.testPathsDaemon(DemoConstants.ia121, DemoConstants.ia210);
demo.testPathsDaemon(DemoConstants.ia110, DemoConstants.ia211);
// demo.testPathsControlService(srcIA, dstIA);
} catch (IOException e) {
throw new RuntimeException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ protected static void checkInterface(Daemon.Path path, int i, int id, String isd
assertEquals(ScionUtil.parseIA(isdAs), path.getInterfaces(i).getIsdAs());
}

/**
* @param exp byte[] of a raw path returned by a SCION daemon
* @param act byte[] of raw path generated by Java client from segments from SCION control service
*/
protected static void checkRaw(byte[] exp, byte[] act) {
// Path meta header
for (int i = 0; i < 4; i++) {
Expand All @@ -123,24 +127,24 @@ protected static void checkRaw(byte[] exp, byte[] act) {
// info fields
assertEquals(exp[ofs], act[ofs++]); // flags
assertEquals(exp[ofs], act[ofs++]); // RSV
ofs += 6;
ofs += 6; // skip segmentID & timestamp
if (s1 > 0) {
assertEquals(exp[ofs], act[ofs++]);
assertEquals(exp[ofs], act[ofs++]);
ofs += 6;
ofs += 6; // skip segmentID & timestamp
}
if (s2 > 0) {
assertEquals(exp[ofs], act[ofs++]);
assertEquals(exp[ofs], act[ofs++]);
ofs += 6;
ofs += 6; // skip segmentID & timestamp
}

// hop fields
for (int h = 0; h < s; h++) {
for (int i = 0; i < 6; i++) {
assertEquals(exp[ofs], act[ofs++]);
}
ofs += 6;
ofs += 6; // skip MAC
}

assertEquals(ofs, exp.length);
Expand Down
80 changes: 54 additions & 26 deletions src/test/java/org/scion/internal/SegmentsMinimal110Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,36 +96,21 @@ void caseC_SameIsd_Down() throws IOException {
assertFalse(paths.isEmpty());
// Available paths to 1-ff00:0:111
// 2 Hops:
// [0] Hops: [1-ff00:0:110 2>111 1-ff00:0:111] MTU: 1472 NextHop: 127.0.0.18:31004
// Status: alive LocalIP: 127.0.0.1

// ASInfo found: 561850441793808 1-ff00:0:110 core=true mtu=1472
// Interfaces found: 3
// Interface: 3 -> address: "127.0.0.19:31006"
// Interface: 1 -> address: "127.0.0.17:31002"
// Interface: 2 -> address: "127.0.0.18:31004"
// Services found: 1
// ListService: control
// Service: 127.0.0.20:31000
// Paths found: 1
// Path: exp=seconds: 1704747225
// mtu=1472
// [0] Hops: [1-ff00:0:110 2>111 1-ff00:0:111]
// MTU: 1472 NextHop: 127.0.0.18:31004 Status: alive LocalIP: 127.0.0.1

// Path: interfaces = 127.0.0.18:31004
// Path: first hop = 127.0.0.18:31004
// pathIf: 0: 2 561850441793808 1-ff00:0:110
// pathIf: 1: 111 561850441793809 1-ff00:0:111
// linkType: 0 LINK_TYPE_UNSPECIFIED
// raw: [
// 0x0, 0x0, 0x20, 0x0, 0x1, 0x0, 0xea, 0x3c,
// 0x65, 0x9c, 0xc, 0x99, 0x0, 0x3f, 0x0, 0x0,
// 0x0, 0x2, 0x73, 0x52, 0x68, 0x90, 0xb0, 0x35,
// 0x0, 0x3f, 0x0, 0x6f, 0x0, 0x0, 0x6a, 0xde,
// 0xc, 0xa3, 0x38, 0x61]

byte[] raw = {
0, 0, 32, 0, 1, 0, -22, 60, 101, -100, 12, -103, 0, 63, 0, 0, 0, 2, 115, 82, 104, -112, -80,
53, 0, 63, 0, 111, 0, 0, 106, -34, 12, -93, 56, 97
};
Daemon.Path path = paths.get(0);
// compare with recorded byte[]
checkRaw(raw, path.getRaw().toByteArray());
}
assertEquals(1, topoServer.getAndResetCallCount());
assertEquals(1, controlServer.getAndResetCallCount());
Expand All @@ -140,9 +125,20 @@ void caseD_SameIsd_Core() throws IOException {
assertFalse(paths.isEmpty());
// Available paths to 1-ff00:0:120
// 2 Hops:
// [0] Hops: [1-ff00:0:110 1>10 1-ff00:0:120] MTU: 1472 NextHop: 127.0.0.17:31002
// Status: alive LocalIP: 127.0.0.1
// [0] Hops: [1-ff00:0:110 1>10 1-ff00:0:120]
// MTU: 1472 NextHop: 127.0.0.17:31002 Status: alive LocalIP: 127.0.0.1

// Path: exp=1709133356 / 2024-02-28T15:15:56Z mtu=1472
// Path: first hop = 127.0.0.25:31002
// pathIf: 0: 1 561850441793808 1-ff00:0:110
// pathIf: 1: 10 561850441793824 1-ff00:0:120
byte[] raw = {
0, 0, 32, 0, 0, 0, 120, -69, 101, -34, -7, -20, 0, 63, 0, 1, 0, 0, 108, -99, 77, -58, -17,
-27, 0, 63, 0, 0, 0, 10, -57, 0, 47, 115, -27, 19
};
Daemon.Path path = paths.get(0);
// compare with recorded byte[]
checkRaw(raw, path.getRaw().toByteArray());
}
assertEquals(1, topoServer.getAndResetCallCount());
assertEquals(1, controlServer.getAndResetCallCount());
Expand All @@ -166,9 +162,6 @@ void caseF0_SameIsd_CoreDown() throws IOException {
// pathIf: 1: 10 561850441793824 1-ff00:0:120
// pathIf: 2: 21 561850441793824 1-ff00:0:120
// pathIf: 3: 104 561850441793825 1-ff00:0:121
// hop: 0: 0
// linkType: 0 LINK_TYPE_UNSPECIFIED
// linkType: 0 LINK_TYPE_UNSPECIFIED
byte[] raw = {
0, 0, 32, -128, 0, 0, -2, 50, 101, -34, 14, -48, 1, 0, -88, -116, 101, -34, 14, -48, 0, 63,
0, 1, 0, 0, -32, 11, -116, 98, 40, 59, 0, 63, 0, 0, 0, 10, 69, 7, 15, -100, -60, -113, 0,
Expand Down Expand Up @@ -216,6 +209,25 @@ void caseG_DifferentIsd_CoreDown_2_Hop() throws IOException {
// 4 Hops:
// [0] Hops: [1-ff00:0:110 1>10 1-ff00:0:120 1>105 2-ff00:0:210 450>503 2-ff00:0:211]
// MTU: 1280 NextHop: 127.0.0.17:31002 Status: alive LocalIP: 127.0.0.1

// Path: exp=1709133655 / 2024-02-28T15:20:55Z mtu=1280
// Path: first hop = 127.0.0.25:31002
// pathIf: 0: 1 561850441793808 1-ff00:0:110
// pathIf: 1: 10 561850441793824 1-ff00:0:120
// pathIf: 2: 210 561850441793824 1-ff00:0:120
// pathIf: 3: 105 843325418504720 2-ff00:0:210
// pathIf: 4: 450 843325418504720 2-ff00:0:210
// pathIf: 5: 503 843325418504721 2-ff00:0:211
byte[] raw = {
0, 0, 48, -128, 0, 0, -67, -51, 101, -34, -5, 23, 1, 0, 82, -120, 101, -34, -5, 34, 0, 63,
0, 1, 0, 0, 48, -24, 88, -54, -62, 116, 0, 63, 0, -46, 0, 10, 9, 70, -53, -49, 111, 48, 0,
63, 0, 0, 0, 105, 85, 20, 63, -118, -11, 40, 0, 63, 0, 0, 1, -62, 28, -47, -60, 92, 29, 18,
0, 63, 1, -9, 0, 0, -95, -82, 79, 25, 23, -85
};

Daemon.Path path = paths.get(0);
// compare with recorded byte[]
checkRaw(raw, path.getRaw().toByteArray());
}
assertEquals(1, topoServer.getAndResetCallCount());
assertEquals(2, controlServer.getAndResetCallCount());
Expand All @@ -232,6 +244,22 @@ void caseI_DifferentIsd_Core_2_Hop() throws IOException {
// 3 Hops:
// [0] Hops: [1-ff00:0:110 1>10 1-ff00:0:120 1>105 2-ff00:0:210] MTU: 1280
// NextHop: 127.0.0.17:31002 Status: alive LocalIP: 127.0.0.1

// Paths found: 1
// Path: exp=1709132908 / 2024-02-28T15:08:28Z mtu=1280
// Path: first hop = 127.0.0.25:31002
// pathIf: 0: 1 561850441793808 1-ff00:0:110
// pathIf: 1: 10 561850441793824 1-ff00:0:120
// pathIf: 2: 210 561850441793824 1-ff00:0:120
// pathIf: 3: 105 843325418504720 2-ff00:0:210
byte[] raw = {
0, 0, 48, 0, 0, 0, -101, 35, 101, -34, -8, 44, 0, 63, 0, 1, 0, 0, -16, -42, -110, 6, -74,
25, 0, 63, 0, -46, 0, 10, 28, 63, -128, -4, 58, 66, 0, 63, 0, 0, 0, 105, 53, -90, -75, -124,
-62, 70
};
Daemon.Path path = paths.get(0);
// compare with recorded byte[]
checkRaw(raw, path.getRaw().toByteArray());
}
assertEquals(1, topoServer.getAndResetCallCount());
assertEquals(1, controlServer.getAndResetCallCount());
Expand Down

0 comments on commit 0c091ab

Please sign in to comment.