Skip to content

Commit

Permalink
DatagramSocket works! (#32)
Browse files Browse the repository at this point in the history
Co-authored-by: Tilmann Zäschke <tilmann.zaeschke@inf.ethz.ch>
  • Loading branch information
tzaeschke and Tilmann Zäschke authored Mar 12, 2024
1 parent 23f7135 commit 50dcb8f
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 72 deletions.
37 changes: 19 additions & 18 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,44 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Changed
- BREAKING CHANGE: Changed maven artifactId to "client"
[#9](https://github.com/tzaeschke/phtree-cpp/pull/9)
[#9](https://github.com/netsec-ethz/scion-java-client/pull/9)
- BREAKING CHANGE: SCMP refactoring, renamed several SCMP related classes.
[#14](https://github.com/tzaeschke/phtree-cpp/pull/14),
[#15](https://github.com/tzaeschke/phtree-cpp/pull/15),
[#17](https://github.com/tzaeschke/phtree-cpp/pull/17),
[#19](https://github.com/tzaeschke/phtree-cpp/pull/19),
[#20](https://github.com/tzaeschke/phtree-cpp/pull/21)
[#14](https://github.com/netsec-ethz/scion-java-client/pull/14),
[#15](https://github.com/netsec-ethz/scion-java-client/pull/15),
[#17](https://github.com/netsec-ethz/scion-java-client/pull/17),
[#19](https://github.com/netsec-ethz/scion-java-client/pull/19),
[#20](https://github.com/netsec-ethz/scion-java-client/pull/21)
- BREAKING CHANGE:`ScionService` instances created via `Scion.newXYZ`
will not be considered by `Scion.defaultService()`. Also, `DatagramChannel.getService()`
does not create a service if none exists.
[#18](https://github.com/tzaeschke/phtree-cpp/pull/18)
[#18](https://github.com/netsec-ethz/scion-java-client/pull/18)
- Doc cleanup
[#22](https://github.com/tzaeschke/phtree-cpp/pull/22)
[#22](https://github.com/netsec-ethz/scion-java-client/pull/22)
- BREAKING CHANGE: `getCurrentPath()` renamed to `getConnectionPath()`
[#31](https://github.com/tzaeschke/phtree-cpp/pull/31)
[#30](https://github.com/netsec-ethz/scion-java-client/pull/30)

### Fixed
- Fixed: SCMP problem when pinging local AS.
[#16](https://github.com/tzaeschke/phtree-cpp/pull/16),
[#16](https://github.com/netsec-ethz/scion-java-client/pull/16),
- Fixed SCMP timeout and error handling (IOExceptions + SCMP errors).
[#13](https://github.com/tzaeschke/phtree-cpp/pull/13)
- CI (only) failures on JDK 8. [#10](https://github.com/tzaeschke/phtree-cpp/pull/10)
- Sporadic CI (only) failures. [#12](https://github.com/tzaeschke/phtree-cpp/pull/12)
[#13](https://github.com/netsec-ethz/scion-java-client/pull/13)
- CI (only) failures on JDK 8. [#10](https://github.com/netsec-ethz/scion-java-client/pull/10)
- Sporadic CI (only) failures. [#12](https://github.com/netsec-ethz/scion-java-client/pull/12)
- Small fixes for 0.1.0 release. [#32](https://github.com/netsec-ethz/scion-java-client/pull/32)

### Removed

- Removed all code related to DatagramSockets
[#21](https://github.com/tzaeschke/phtree-cpp/pull/21)
[#21](https://github.com/netsec-ethz/scion-java-client/pull/21)


## [0.1.0-ALPHA] - 2024-02-01

### Added
- `DatagramSocket` [#7](https://github.com/tzaeschke/phtree-cpp/pull/7)
- `Path`, `RequestPath`, `ResponsePath` [#7](https://github.com/tzaeschke/phtree-cpp/pull/7)
- `Scion`, `ScionService` [#7](https://github.com/tzaeschke/phtree-cpp/pull/7)
- `ScmpChannel` for SCMP [#7](https://github.com/tzaeschke/phtree-cpp/pull/7)
- `DatagramSocket` [#7](https://github.com/netsec-ethz/scion-java-client/pull/7)
- `Path`, `RequestPath`, `ResponsePath` [#7](https://github.com/netsec-ethz/scion-java-client/pull/7)
- `Scion`, `ScionService` [#7](https://github.com/netsec-ethz/scion-java-client/pull/7)
- `ScmpChannel` for SCMP [#7](https://github.com/netsec-ethz/scion-java-client/pull/7)

### Changed
- Nothing
Expand Down
3 changes: 3 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
- Review + clean up

### 0.2.0
- Allow disabling local address resolution in DNS to local-IA. Resolving 127.0.0.x to
localIA is fine for many purposes, but it can be confusing when testing a local
mock-network (tiny, minimal, ...)
- SCMP errors handling (above)
- Especially for type ¨5: External Interface Down" and "6: Internal Connectivity Down"
Problem: we need to receive() or read() to actually receive SCMP errors.
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/org/scion/AbstractDatagramChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public synchronized void setPathPolicy(PathPolicy pathPolicy) throws IOException
}
}

protected synchronized ScionService getOrCreateService() {
public synchronized ScionService getOrCreateService() {
if (service == null) {
service = ScionService.defaultService();
}
Expand All @@ -111,6 +111,15 @@ public synchronized InetSocketAddress getLocalAddress() throws IOException {
return (InetSocketAddress) channel.getLocalAddress();
}

public SocketAddress getRemoteAddress() throws UnknownHostException {
Path path = getConnectionPath();
if (path != null) {
InetAddress ip = InetAddress.getByAddress(path.getDestinationAddress());
return new InetSocketAddress(ip, path.getDestinationPort());
}
return null;
}

public synchronized void disconnect() throws IOException {
channel.disconnect();
connection = null;
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/org/scion/DatagramChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.io.Closeable;
import java.io.IOException;
import java.net.*;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.channels.NotYetConnectedException;
Expand Down Expand Up @@ -118,7 +119,11 @@ public synchronized Path send(ByteBuffer srcBuffer, Path path) throws IOExceptio
// + 8 for UDP overlay header length
Path actualPath =
buildHeader(bufferSend, path, srcBuffer.remaining() + 8, InternalConstants.HdrTypes.UDP);
bufferSend.put(srcBuffer);
try {
bufferSend.put(srcBuffer);
} catch (BufferOverflowException e) {
throw new IOException("Packet is larger than max send buffer size.");
}
bufferSend.flip();
sendRaw(bufferSend, actualPath.getFirstHopAddress());
return actualPath;
Expand Down
62 changes: 13 additions & 49 deletions src/test/java/org/scion/api/DatagramChannelApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,10 @@ void isConnected_InetSocket() throws IOException {
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 12345);
try (DatagramChannel channel = DatagramChannel.open()) {
assertFalse(channel.isConnected());
assertNull(channel.getRemoteAddress());
channel.connect(address);
assertTrue(channel.isConnected());
assertEquals(address, channel.getRemoteAddress());

// try connecting again
// Should be AlreadyConnectedException but Temurin throws IllegalStateException
Expand All @@ -236,12 +238,14 @@ void isConnected_InetSocket() throws IOException {
// disconnect
channel.disconnect();
assertFalse(channel.isConnected());
assertNull(channel.getRemoteAddress());
channel.disconnect();
assertFalse(channel.isConnected());

// Connect again
channel.connect(address);
assertTrue(channel.isConnected());
assertEquals(address, channel.getRemoteAddress());
channel.close();
assertFalse(channel.isConnected());
}
Expand All @@ -250,10 +254,14 @@ void isConnected_InetSocket() throws IOException {
@Test
void isConnected_Path() throws IOException {
RequestPath path = PackageVisibilityHelper.createDummyPath();
InetAddress ip = InetAddress.getByAddress(path.getDestinationAddress());
InetSocketAddress address = new InetSocketAddress(ip, path.getDestinationPort());
try (DatagramChannel channel = DatagramChannel.open()) {
assertFalse(channel.isConnected());
assertNull(channel.getRemoteAddress());
channel.connect(path);
assertTrue(channel.isConnected());
assertEquals(address, channel.getRemoteAddress());

// try connecting again
// Should be AlreadyConnectedException, but Temurin throws IllegalStateException
Expand All @@ -263,6 +271,7 @@ void isConnected_Path() throws IOException {
// disconnect
channel.disconnect();
assertFalse(channel.isConnected());
assertNull(channel.getRemoteAddress());
channel.disconnect();
assertFalse(channel.isConnected());

Expand All @@ -279,6 +288,8 @@ void getService_default() throws IOException {
ScionService service1 = Scion.defaultService();
ScionService service2 = Scion.newServiceWithDaemon(MockDaemon.DEFAULT_ADDRESS_STR);
try (DatagramChannel channel = DatagramChannel.open()) {
// The initial channel should NOT have a service.
// A server side channel may never need a service so we shouldn't create it.
assertNull(channel.getService());

// trigger service initialization in channel
Expand Down Expand Up @@ -312,53 +323,6 @@ void getPathPolicy() throws IOException {
}
}

@Test
void receive_bufferTooSmall() throws IOException {
MockDaemon.closeDefault(); // We don't need the daemon here
PingPongHelper.Server serverFn = PingPongHelper::defaultServer;
PingPongHelper.Client clientFn =
(channel, serverAddress, id) -> {
String message = PingPongHelper.MSG + "-" + id;
ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes());
channel.send(sendBuf, serverAddress);

// System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")");
ByteBuffer response = ByteBuffer.allocate(5);
channel.receive(response);

response.flip();
assertEquals(5, response.limit());
String pong = Charset.defaultCharset().decode(response).toString();
assertEquals(message.substring(0, 5), pong);
};
PingPongHelper pph = new PingPongHelper(1, 1, 1);
pph.runPingPong(serverFn, clientFn);
}

@Test
void read_bufferTooSmall() throws IOException {
MockDaemon.closeDefault(); // We don't need the daemon here
PingPongHelper.Server serverFn = PingPongHelper::defaultServer;
PingPongHelper.Client clientFn =
(channel, serverAddress, id) -> {
String message = PingPongHelper.MSG + "-" + id;
ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes());
// System.out.println("CLIENT: Writing ... (" + channel.getLocalAddress() + ")");
channel.write(sendBuf);

// System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")");
ByteBuffer response = ByteBuffer.allocate(5);
int len = channel.read(response);
assertEquals(5, len);

response.flip();
String pong = Charset.defaultCharset().decode(response).toString();
assertEquals(message.substring(0, 5), pong);
};
PingPongHelper pph = new PingPongHelper(1, 1, 1);
pph.runPingPong(serverFn, clientFn);
}

@Test
void send_bufferTooLarge() {
RequestPath addr = ExamplePacket.PATH;
Expand All @@ -375,7 +339,7 @@ void send_bufferTooLarge() {
}

@Test
void write_bufferToLarge() {
void write_bufferTooLarge() {
RequestPath addr = ExamplePacket.PATH;
ByteBuffer buffer = ByteBuffer.allocate(65440);
buffer.limit(buffer.capacity());
Expand Down Expand Up @@ -513,7 +477,7 @@ private RequestPath createExpiredPath(Path basePath) throws UnknownHostException
}

@Test
void getCurrentPath() {
void getConnectionPath() {
RequestPath addr = ExamplePacket.PATH;
ByteBuffer buffer = ByteBuffer.allocate(50);
try (DatagramChannel channel = DatagramChannel.open()) {
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/scion/testutil/DNSUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static void installNAPTR(String asHost, byte[] topoAddr, int topoPort) {
Name name = Name.fromString(asHost + "."); // "iinf.ethz.ch.";
Name replacement = new Name("topohost.x.y."); // "netsec-w37w3w.inf.ethz.ch."

Cache c = new Cache(DClass.IN);
Cache c = Lookup.getDefaultCache(DClass.IN);
TXTRecord txt = new TXTRecord(name, DClass.IN, 5000, "x-sciondiscovery=" + topoPort);
c.addRecord(txt, 10);

Expand Down
7 changes: 5 additions & 2 deletions src/test/java/org/scion/testutil/MockNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.scion.testutil;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
Expand Down Expand Up @@ -48,6 +49,7 @@ public class MockNetwork {

public static final String BORDER_ROUTER_HOST = "127.0.0.1";
public static final String TINY_SRV_ADDR_1 = "127.0.0.112";
public static final byte[] TINY_SRV_ADDR_BYTES_1 = {127, 0, 0, 112};
public static final int TINY_SRV_PORT_1 = 22233;
public static final String TINY_SRV_ISD_AS = "1-ff00:0:112";
public static final String TINY_SRV_NAME_1 = "server.as112.test";
Expand Down Expand Up @@ -154,8 +156,9 @@ public static synchronized void stopTiny() {
scmpErrorOnNextPacket.set(null);
}

public static InetSocketAddress getTinyServerAddress() {
return new InetSocketAddress(TINY_SRV_ADDR_1, TINY_SRV_PORT_1);
public static InetSocketAddress getTinyServerAddress() throws IOException {
return new InetSocketAddress(
InetAddress.getByAddress(TINY_SRV_NAME_1, TINY_SRV_ADDR_BYTES_1), TINY_SRV_PORT_1);
}

public static int getAndResetForwardCount() {
Expand Down

0 comments on commit 50dcb8f

Please sign in to comment.