From 369436fc1f15bda68b0dc0d5f7e1bf6cc2c2d74f Mon Sep 17 00:00:00 2001 From: Tilmann Date: Fri, 21 Jun 2024 12:24:13 +0200 Subject: [PATCH] API clean up #2 (#95) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * RequestPath --------- Co-authored-by: Tilmann Zäschke --- CHANGELOG.md | 8 +- README.md | 25 ++++--- doc/Design.md | 4 +- .../scion/jpan/AbstractDatagramChannel.java | 29 ++++--- src/main/java/org/scion/jpan/Path.java | 2 + .../java/org/scion/jpan/PathMetadata.java | 4 +- src/main/java/org/scion/jpan/PathPolicy.java | 31 ++++---- .../java/org/scion/jpan/ResponsePath.java | 5 ++ .../java/org/scion/jpan/ScionAddress.java | 3 + .../org/scion/jpan/ScionDatagramChannel.java | 21 +++--- .../org/scion/jpan/ScionDatagramSocket.java | 14 ++-- .../java/org/scion/jpan/ScionService.java | 36 ++++++--- src/main/java/org/scion/jpan/ScionUtil.java | 5 +- src/main/java/org/scion/jpan/ScmpChannel.java | 6 +- .../api/DatagramChannelApiServerTest.java | 2 +- .../jpan/api/DatagramChannelApiTest.java | 43 +++-------- .../api/DatagramChannelErrorHandlingTest.java | 6 +- ...ramChannelMultiWriteConnectedPathTest.java | 3 +- .../api/DatagramChannelPathSwitchTest.java | 3 +- .../scion/jpan/api/DatagramSocketApiTest.java | 40 ++-------- .../DatagramSocketConcurrentPingPongTest.java | 5 +- .../jpan/api/DatagramSocketPingPongTest.java | 5 +- .../java/org/scion/jpan/api/SCMPTest.java | 26 +++---- .../org/scion/jpan/api/ScionServiceTest.java | 75 +++++++++++++------ .../java/org/scion/jpan/api/ScionTest.java | 16 ++-- .../org/scion/jpan/api/ScionUtilTest.java | 15 ++-- .../jpan/demo/PingPongChannelClient.java | 4 +- .../org/scion/jpan/demo/ScmpEchoDemo.java | 60 ++++++--------- .../scion/jpan/demo/ScmpTracerouteDemo.java | 8 +- .../org/scion/jpan/demo/ShowpathsDemo.java | 9 ++- .../scion/jpan/testutil/ExamplePacket.java | 4 +- .../jpan/testutil/PingPongChannelHelper.java | 9 +-- .../jpan/testutil/PingPongHelperBase.java | 6 +- .../jpan/testutil/PingPongSocketHelper.java | 7 +- 34 files changed, 277 insertions(+), 262 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f82738081..bd243cde8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,13 +28,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. [#92](https://github.com/scionproto-contrib/jpan/pull/92) - **BREAKING CHANGE**: Path metadata has been moved to `PathMetadata`. [#93](https://github.com/scionproto-contrib/jpan/pull/93) -- **BREAKING CHANGE**: `receive()` returns `ScionSocketAddress`; `RequestAddress` and - `RequestPath` are removed from from public API. +- **BREAKING CHANGE**: `receive()` returns `ScionSocketAddress`; `ResponseAddress` and + `ResponsePath` are removed from from public API. [#94](https://github.com/scionproto-contrib/jpan/pull/94) +- **BREAKING CHANGE**: removed `RequestPath` and `ScionAddress` from public API. + [#95](https://github.com/scionproto-contrib/jpan/pull/95) ### Fixed - Fixed locking and resizing of buffers. [#68](https://github.com/scionproto-contrib/jpan/pull/68) -- Fixed unhelpful error & log message when with topofile has wrong permissions. +- Fixed unhelpful error & log message when with topo file has wrong permissions. [#74](https://github.com/scionproto-contrib/jpan/issues/74) - Topology file parser support for new "local" attribute. [#72](https://github.com/scionproto-contrib/jpan/issues/72) diff --git a/README.md b/README.md index 531c5799d..3ba4d4a47 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,6 @@ The following artifact contains the complete SCION Java implementation: ### Planned features - API: `Selector` for `DatagramChannel` -- API: `Path` extends `InetSocketAddress` - Autodetection of NAT external IP - Path creation with short-cuts, on-path and peering routes - Improve docs, demos and testing @@ -74,11 +73,13 @@ The central classes of the API are: - `DatagramChannel`: This class works like a `java.nio.channel.DatagramChannel`. It implements `Channel` and `ByteChannel`. Scattering, gathering, multicast and selectors are currently not supported. -- `Path`, `RequestPath`, `ResponsePath`: The notion of path is slightly different than in other - parts of SCION. A `Path` contains a route to a destination ("raw path") plus the full - destination, i.e. IP-address and port. - - `RequestPath` is a `Path` with meta information (bandwidth, geo info, etc). - - `ResponsePath` is a `Path` with source IA, IP & port. +- `ScionSocketAddress` is an `InetSocketAddress` with the IP of a Scion enabled endhost. + A `ScionSocketAddress` also has the ISD/AS code of that endhost and a path to the that endhost. +- `Path` objects contain a route to a destination ("raw path") plus the full + destination, i.e. SCION-enabled IP address and port. + - If the path was created by the `ScionService` then it has `PathMetadata` with meta information + (bandwidth, geo info, etc). + - A path returned by `receive()` (as part of a `ScionSocketAddress`) has no meta information. - `PathPolicy` is an interface with several example implementations for: first path returned by daemon (default), max bandwidth, min latency, min hops, ... - `ScionService`: Provides methods to request paths and get ISD/AS information. @@ -213,6 +214,12 @@ use something like: InetSocketAddress serverAddress = new InetSocketAddress("your-domain.org", 80); channel.connect(serverAddress); ``` +or +```java +InetSocketAddress serverAddress = new InetSocketAddress("your-domain.org", 80); +Path path = Scion.getDefaultService().lookupAndGetPath(serverAddress, PathPolicy.DEFAULT); +channel.send(buffer, path); +``` Alternatively, the ISD/AS can be specified explicitly in several ways. @@ -278,7 +285,7 @@ API beyond the standard Java `DatagramScoket`: * `create(ScionService)` and `create(SocketAddress, ScionService)` for creating a `DatagramSocket` with a non-default `ScionService`. -* `connect(RequestPath path)` for connecting to a remote host +* `connect(Path path)` for connecting to a remote host * `getConnectionPath()` gets the connected path if the socket has been connected * `getCachedPath(InetAddress address)` get the cached path for a given IP * `setPathCacheCapacity(int capacity)` and `getPathCacheCapacity()` for managing the cache size @@ -292,11 +299,11 @@ API beyond the standard Java `DatagramScoket`: multiple packets to the same destination, one should use `path = send(buffer, path)` or `connect()` + `write()` in order to avoid frequent path lookups. -- **Using expired path (client).** When using `send(buffer, path)` with an expired `RequestPath`, the channel will +- **Using expired path (client).** When using `send(buffer, path)` with an expired `Path`, the channel will transparently look up a new path. This works but causes a path lookup for every `send()`. Solution: always use the latest path returned by send, e.g. `path = send(buffer, path)`. -- **Using expired path (server).** When using `send(buffer, path)` with an expired `ResponsePath`, the channel will +- **Using expired path (server).** When using `send(buffer, path)` with an expired `Path`, the channel will simple send it anyway. ## Configuration diff --git a/doc/Design.md b/doc/Design.md index fdca73300..5ea4b9a03 100644 --- a/doc/Design.md +++ b/doc/Design.md @@ -19,7 +19,7 @@ at least a topology server + control server. ## Server / Client -Server functionality, such as `open()` and `receive()` -> `send(RequestPath)`, should _not_ require +Server functionality, such as `open()` and `receive()` -> `send(Path)`, should _not_ require any access to a daemon or control service. The main reason is that it ensures efficiency by completely avoiding any type of interaction with daemon/CS. Interaction with daemon/CS should not be denied but it should not occur during default operations. @@ -64,7 +64,7 @@ used or returned by `Scion.defaultService()`. ## Paths -There are two types of paths (both inherit `Path`: +There are two types of paths (both inherit `Path`, both are (will be) package private): - `RequestPath` are used to send initial request. They are retrieved from a path service and contain meta information. diff --git a/src/main/java/org/scion/jpan/AbstractDatagramChannel.java b/src/main/java/org/scion/jpan/AbstractDatagramChannel.java index 26f2c70d3..bb57ad489 100644 --- a/src/main/java/org/scion/jpan/AbstractDatagramChannel.java +++ b/src/main/java/org/scion/jpan/AbstractDatagramChannel.java @@ -104,7 +104,8 @@ public void setPathPolicy(PathPolicy pathPolicy) throws IOException { synchronized (stateLock) { this.pathPolicy = pathPolicy; if (isConnected()) { - connectionPath = pathPolicy.filter(getOrCreateService().getPaths(connectionPath)); + connectionPath = + (RequestPath) pathPolicy.filter(getOrCreateService().getPaths(connectionPath)); updateConnection(connectionPath, true); } } @@ -181,7 +182,7 @@ public InetSocketAddress getLocalAddress() throws IOException { * @return The remote address or 'null' if this channel is not connected. * @see DatagramChannel#getRemoteAddress() * @see #connect(SocketAddress) - * @see #connect(RequestPath) + * @see #connect(Path) * @throws IOException If an I/O error occurs */ public InetSocketAddress getRemoteAddress() throws IOException { @@ -217,7 +218,9 @@ public void close() throws IOException { * Connect to a destination host. * *

NB: A SCION channel will internally connect to the next border router (first hop) instead of - * the remote host. + * the remote host.
+ * If the address is an instance of {@link ScionSocketAddress} then connect will use the path + * associated with the address, see {@link #connect(Path)}. * *

NB: This method does internally not call {@link * java.nio.channels.DatagramChannel}.connect(), instead it calls bind(). That means this method @@ -235,7 +238,11 @@ public C connect(SocketAddress addr) throws IOException { throw new IllegalArgumentException( "connect() requires an InetSocketAddress or a ScionSocketAddress."); } - return connect(getOrCreateService().lookupAndGetPath((InetSocketAddress) addr, pathPolicy)); + if (addr instanceof ScionSocketAddress) { + return connect(((ScionSocketAddress) addr).getPath()); + } + Path path = getOrCreateService().lookupAndGetPath((InetSocketAddress) addr, pathPolicy); + return connect(path); } } @@ -261,7 +268,11 @@ public C connect(SocketAddress addr) throws IOException { * @throws IOException for example when the first hop (border router) cannot be connected. */ @SuppressWarnings("unchecked") - public C connect(RequestPath path) throws IOException { + public C connect(Path path) throws IOException { + if (!(path instanceof RequestPath)) { + // Technically we could probably allow this, but it feels like an abuse of the API, + throw new IllegalStateException("The path must be a request path."); + } // For reference: Java DatagramChannel behavior: // - fresh channel has getLocalAddress() == null // - connect() and send() cause internal bind() @@ -293,18 +304,18 @@ public C connect(RequestPath path) throws IOException { synchronized (stateLock) { checkConnected(false); ensureBound(); - updateConnection(path, false); + updateConnection((RequestPath) path, false); return (C) this; } } /** - * Get the currently connected path. The connected path is set during {@link - * #connect(RequestPath)} and may be refreshed when expired. + * Get the currently connected path. The connected path is set during {@link #connect(Path)} and + * may be refreshed when expired. * * @return the current Path or `null` if not path is connected. */ - public RequestPath getConnectionPath() { + public Path getConnectionPath() { synchronized (stateLock) { return connectionPath; } diff --git a/src/main/java/org/scion/jpan/Path.java b/src/main/java/org/scion/jpan/Path.java index 78dfcdd70..0cac9cde0 100644 --- a/src/main/java/org/scion/jpan/Path.java +++ b/src/main/java/org/scion/jpan/Path.java @@ -53,6 +53,8 @@ public ScionSocketAddress getRemoteSocketAddress() { return dstAddress; } + public abstract PathMetadata getMetadata(); + @Override public String toString() { try { diff --git a/src/main/java/org/scion/jpan/PathMetadata.java b/src/main/java/org/scion/jpan/PathMetadata.java index c872ed919..30646a715 100644 --- a/src/main/java/org/scion/jpan/PathMetadata.java +++ b/src/main/java/org/scion/jpan/PathMetadata.java @@ -26,8 +26,8 @@ /** * PathMetadata contains the raw path and meta information such as bandwidth, latency or geo - * coordinates. PathMetadata is available from RequestPaths that are created/returned by the - * ScionService when requesting a new path from the control service. + * coordinates. PathMetadata is available from Paths that are created/returned by the ScionService + * when requesting a new path from the control service. */ public class PathMetadata { diff --git a/src/main/java/org/scion/jpan/PathPolicy.java b/src/main/java/org/scion/jpan/PathPolicy.java index bd27a593e..2c852d77e 100644 --- a/src/main/java/org/scion/jpan/PathPolicy.java +++ b/src/main/java/org/scion/jpan/PathPolicy.java @@ -17,6 +17,7 @@ import java.util.*; public interface PathPolicy { + String NO_PATH = "No path found to destination."; PathPolicy FIRST = new First(); PathPolicy MAX_BANDWIDTH = new MaxBandwith(); PathPolicy MIN_LATENCY = new MinLatency(); @@ -24,21 +25,21 @@ public interface PathPolicy { PathPolicy DEFAULT = MIN_HOPS; class First implements PathPolicy { - public RequestPath filter(List paths) { - return paths.stream().findFirst().orElseThrow(NoSuchElementException::new); + public Path filter(List paths) { + return paths.stream().findFirst().orElseThrow(() -> new NoSuchElementException(NO_PATH)); } } class MaxBandwith implements PathPolicy { - public RequestPath filter(List paths) { + public Path filter(List paths) { return paths.stream() .max(Comparator.comparing(path -> Collections.min(path.getMetadata().getBandwidthList()))) - .orElseThrow(NoSuchElementException::new); + .orElseThrow(() -> new NoSuchElementException(NO_PATH)); } } class MinLatency implements PathPolicy { - public RequestPath filter(List paths) { + public Path filter(List paths) { // A 0-value indicates that the AS did not announce a latency for this hop. // We use Integer.MAX_VALUE for comparison of these ASes. return paths.stream() @@ -48,15 +49,15 @@ public RequestPath filter(List paths) { path.getMetadata().getLatencyList().stream() .mapToLong(l -> l > 0 ? l : Integer.MAX_VALUE) .reduce(0, Long::sum))) - .orElseThrow(NoSuchElementException::new); + .orElseThrow(() -> new NoSuchElementException(NO_PATH)); } } class MinHopCount implements PathPolicy { - public RequestPath filter(List paths) { + public Path filter(List paths) { return paths.stream() .min(Comparator.comparing(path -> path.getMetadata().getInternalHopsList().size())) - .orElseThrow(NoSuchElementException::new); + .orElseThrow(() -> new NoSuchElementException(NO_PATH)); } } @@ -68,14 +69,14 @@ public IsdAllow(Set allowedIsds) { } @Override - public RequestPath filter(List paths) { + public Path filter(List paths) { return paths.stream() .filter(this::checkPath) .findAny() - .orElseThrow(NoSuchElementException::new); + .orElseThrow(() -> new NoSuchElementException(NO_PATH)); } - private boolean checkPath(RequestPath path) { + private boolean checkPath(Path path) { for (PathMetadata.PathInterface pif : path.getMetadata().getInterfacesList()) { int isd = (int) (pif.getIsdAs() >>> 48); if (!allowedIsds.contains(isd)) { @@ -94,14 +95,14 @@ public IsdDisallow(Set disallowedIsds) { } @Override - public RequestPath filter(List paths) { + public Path filter(List paths) { return paths.stream() .filter(this::checkPath) .findAny() - .orElseThrow(NoSuchElementException::new); + .orElseThrow(() -> new NoSuchElementException(NO_PATH)); } - private boolean checkPath(RequestPath path) { + private boolean checkPath(Path path) { for (PathMetadata.PathInterface pif : path.getMetadata().getInterfacesList()) { int isd = (int) (pif.getIsdAs() >>> 48); if (disallowedIsds.contains(isd)) { @@ -117,5 +118,5 @@ private boolean checkPath(RequestPath path) { * @return The "best" path according to the filter's policy. * @throws NoSuchElementException if no matching path could be found. */ - RequestPath filter(List paths); + Path filter(List paths); } diff --git a/src/main/java/org/scion/jpan/ResponsePath.java b/src/main/java/org/scion/jpan/ResponsePath.java index 623a91e44..73863e8d6 100644 --- a/src/main/java/org/scion/jpan/ResponsePath.java +++ b/src/main/java/org/scion/jpan/ResponsePath.java @@ -67,6 +67,11 @@ public InetSocketAddress getFirstHopAddress() { return firstHopAddress; } + @Override + public PathMetadata getMetadata() { + return null; + } + public long getLocalIsdAs() { return srcIsdAs; } diff --git a/src/main/java/org/scion/jpan/ScionAddress.java b/src/main/java/org/scion/jpan/ScionAddress.java index 88b6212e8..724a25b26 100644 --- a/src/main/java/org/scion/jpan/ScionAddress.java +++ b/src/main/java/org/scion/jpan/ScionAddress.java @@ -21,7 +21,10 @@ * ScionAddress is an InetAddress + ISD/AS information. * *

This class is threadsafe. + * + * @deprecated This will be made package private in 0.3.0 */ +@Deprecated // This will be made package private in 0.3.0 public class ScionAddress { private final long isdAs; private final String hostName; diff --git a/src/main/java/org/scion/jpan/ScionDatagramChannel.java b/src/main/java/org/scion/jpan/ScionDatagramChannel.java index e2b622132..385b8df4a 100644 --- a/src/main/java/org/scion/jpan/ScionDatagramChannel.java +++ b/src/main/java/org/scion/jpan/ScionDatagramChannel.java @@ -117,7 +117,7 @@ public int send(ByteBuffer srcBuffer, SocketAddress destination) throws IOExcept synchronized (stateLock()) { path = resolvedDestinations.get(dst); if (path == null) { - path = getOrCreateService().lookupAndGetPath(dst, getPathPolicy()); + path = (RequestPath) getOrCreateService().lookupAndGetPath(dst, getPathPolicy()); resolvedDestinations.put(dst, path); } } @@ -251,7 +251,7 @@ private RequestPath refreshPath(RequestPath path, RefreshPolicy refreshPolicy) { return null; } // expired, get new path - List paths = getOrCreateService().getPaths(path); + List paths = getOrCreateService().getPaths(path); switch (refreshPolicy) { case OFF: // let this pass until it is ACTUALLY expired @@ -260,7 +260,7 @@ private RequestPath refreshPath(RequestPath path, RefreshPolicy refreshPolicy) { } throw new ScionRuntimeException("Path is expired"); case POLICY: - return getPathPolicy().filter(getOrCreateService().getPaths(path)); + return (RequestPath) getPathPolicy().filter(getOrCreateService().getPaths(path)); case SAME_LINKS: return findPathSameLinks(paths, path); default: @@ -268,9 +268,9 @@ private RequestPath refreshPath(RequestPath path, RefreshPolicy refreshPolicy) { } } - private RequestPath findPathSameLinks(List paths, RequestPath path) { + private RequestPath findPathSameLinks(List paths, RequestPath path) { List reference = path.getMetadata().getInterfacesList(); - for (RequestPath newPath : paths) { + for (Path newPath : paths) { List ifs = newPath.getMetadata().getInterfacesList(); if (ifs.size() != reference.size()) { continue; @@ -286,7 +286,7 @@ private RequestPath findPathSameLinks(List paths, RequestPath path) } } if (isSame) { - return newPath; + return (RequestPath) newPath; } } return null; @@ -300,7 +300,7 @@ private RequestPath findPathSameLinks(List paths, RequestPath path) * @param address A destination address * @return The mapped path or the path itself if no mapping is available. */ - public RequestPath getMappedPath(InetSocketAddress address) { + public Path getMappedPath(InetSocketAddress address) { synchronized (stateLock()) { return resolvedDestinations.get(address); } @@ -315,9 +315,12 @@ public RequestPath getMappedPath(InetSocketAddress address) { * @param path A Path * @return The mapped path or the path itself if no mapping is available. */ - public RequestPath getMappedPath(RequestPath path) { + public Path getMappedPath(Path path) { + if (!(path instanceof RequestPath)) { + return null; + } synchronized (stateLock()) { - return refreshedPaths.getOrDefault(path, path); + return refreshedPaths.getOrDefault(path, (RequestPath) path); } } } diff --git a/src/main/java/org/scion/jpan/ScionDatagramSocket.java b/src/main/java/org/scion/jpan/ScionDatagramSocket.java index ffeff452f..1f85cbc9b 100644 --- a/src/main/java/org/scion/jpan/ScionDatagramSocket.java +++ b/src/main/java/org/scion/jpan/ScionDatagramSocket.java @@ -165,13 +165,13 @@ public synchronized void bind(SocketAddress address) throws SocketException { } /** - * Connect to a destination using a specific path. See {@link - * ScionDatagramChannel#connect(RequestPath)} for details. + * Connect to a destination using a specific path. See {@link ScionDatagramChannel#connect(Path)} + * for details. * * @param path path to destination - * @see ScionDatagramChannel#connect(RequestPath) + * @see ScionDatagramChannel#connect(Path) */ - public synchronized void connect(RequestPath path) { + public synchronized void connect(Path path) { try { channel.connect(path); } catch (IOException e) { @@ -528,13 +528,13 @@ public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) { } /** - * Get the currently connected path. The connected path is set during {@link - * #connect(RequestPath)} and may be refreshed when expired. + * Get the currently connected path. The connected path is set during {@link #connect(Path)} and + * may be refreshed when expired. * * @return the current Path or `null` if not path is connected. * @see ScionDatagramChannel#getConnectionPath() */ - public RequestPath getConnectionPath() { + public Path getConnectionPath() { return channel.getConnectionPath(); } diff --git a/src/main/java/org/scion/jpan/ScionService.java b/src/main/java/org/scion/jpan/ScionService.java index 169bdd8ce..5b7ca4274 100644 --- a/src/main/java/org/scion/jpan/ScionService.java +++ b/src/main/java/org/scion/jpan/ScionService.java @@ -307,7 +307,7 @@ List getPathListDaemon(long srcIsdAs, long dstIsdAs) { * @throws IOException if an errors occurs while querying paths. */ @Deprecated // Please use lookup() instead - public List getPaths(InetSocketAddress dstAddress) throws IOException { + public List getPaths(InetSocketAddress dstAddress) throws IOException { // Use getHostString() to avoid DNS reverse lookup. ScionAddress sa = getScionAddress(dstAddress.getHostString()); return getPaths(sa.getIsdAs(), sa.getInetAddress(), dstAddress.getPort()); @@ -320,7 +320,10 @@ public List getPaths(InetSocketAddress dstAddress) throws IOExcepti * @param dstScionAddress Destination IP address. Must belong to a SCION enabled end host. * @return All paths returned by the path service. */ - public List getPaths(long dstIsdAs, InetSocketAddress dstScionAddress) { + public List getPaths(long dstIsdAs, InetSocketAddress dstScionAddress) { + if (dstScionAddress instanceof ScionSocketAddress) { + return getPaths(((ScionSocketAddress) dstScionAddress).getPath()); + } return getPaths(dstIsdAs, dstScionAddress.getAddress(), dstScionAddress.getPort()); } @@ -330,7 +333,7 @@ public List getPaths(long dstIsdAs, InetSocketAddress dstScionAddre * @param path A path * @return All paths returned by the path service. */ - public List getPaths(RequestPath path) { + public List getPaths(Path path) { return getPaths(path.getRemoteIsdAs(), path.getRemoteAddress(), path.getRemotePort()); } @@ -342,20 +345,35 @@ public List getPaths(RequestPath path) { * @param dstPort Destination port * @return All paths returned by the path service. Returns an empty list if no paths are found. */ - public List getPaths(long dstIsdAs, InetAddress dstAddress, int dstPort) { + public List getPaths(long dstIsdAs, InetAddress dstAddress, int dstPort) { return getPaths(ScionAddress.create(dstIsdAs, dstAddress), dstPort); } + /** + * Resolves the address to a SCION address, request paths, and selects a path using the policy. + * + * @param hostName Destination host name + * @param port Destination port + * @param policy Path policy. 'null' means PathPolicy.DEFAULT. + * @return All paths returned by the path service. + * @throws ScionException if the DNS/TXT lookup did not return a (valid) SCION address. + */ + public Path lookupAndGetPath(String hostName, int port, PathPolicy policy) throws ScionException { + if (policy == null) { + policy = PathPolicy.DEFAULT; + } + return policy.filter(getPaths(lookupAddress(hostName), port)); + } + /** * Resolves the address to a SCION address, request paths, and selects a path using the policy. * * @param dstAddr Destination address - * @param policy path policy + * @param policy Path policy. 'null' means PathPolicy.DEFAULT. * @return All paths returned by the path service. * @throws ScionException if the DNS/TXT lookup did not return a (valid) SCION address. */ - public RequestPath lookupAndGetPath(InetSocketAddress dstAddr, PathPolicy policy) - throws ScionException { + public Path lookupAndGetPath(InetSocketAddress dstAddr, PathPolicy policy) throws ScionException { if (policy == null) { policy = PathPolicy.DEFAULT; } @@ -368,10 +386,10 @@ public RequestPath lookupAndGetPath(InetSocketAddress dstAddr, PathPolicy policy * @param dstAddress Destination SCION address * @return All paths returned by the path service. */ - public List getPaths(ScionAddress dstAddress, int dstPort) { + public List getPaths(ScionAddress dstAddress, int dstPort) { long srcIsdAs = getLocalIsdAs(); List paths = getPathList(srcIsdAs, dstAddress.getIsdAs()); - List scionPaths = new ArrayList<>(paths.size()); + List scionPaths = new ArrayList<>(paths.size()); for (int i = 0; i < paths.size(); i++) { scionPaths.add( RequestPath.create( diff --git a/src/main/java/org/scion/jpan/ScionUtil.java b/src/main/java/org/scion/jpan/ScionUtil.java index f2efe66e8..cccf190ba 100644 --- a/src/main/java/org/scion/jpan/ScionUtil.java +++ b/src/main/java/org/scion/jpan/ScionUtil.java @@ -128,11 +128,10 @@ public static String toStringPath(byte[] raw) { } /** - * @param path A RequestPath + * @param meta PathMetadata * @return ISD/AS codes and border outer interface IDs along the path. */ - public static String toStringPath(RequestPath path) { - PathMetadata meta = path.getMetadata(); + public static String toStringPath(PathMetadata meta) { if (meta.getInterfacesList().isEmpty()) { return "[]"; } diff --git a/src/main/java/org/scion/jpan/ScmpChannel.java b/src/main/java/org/scion/jpan/ScmpChannel.java index de214930c..337dedf01 100644 --- a/src/main/java/org/scion/jpan/ScmpChannel.java +++ b/src/main/java/org/scion/jpan/ScmpChannel.java @@ -85,7 +85,7 @@ public Scmp.EchoMessage sendEchoRequest(int sequenceNumber, ByteBuffer data) thr * and the time is equal to the time-out duration. * @throws IOException if an IO error occurs or if an SCMP error is received. */ - public Scmp.EchoMessage sendEchoRequest(RequestPath path, int sequenceNumber, ByteBuffer data) + public Scmp.EchoMessage sendEchoRequest(Path path, int sequenceNumber, ByteBuffer data) throws IOException { Scmp.EchoMessage request = Scmp.EchoMessage.createRequest(sequenceNumber, path, data); sendScmpRequest(() -> channel.sendEchoRequest(request), Scmp.TypeCode.TYPE_129); @@ -116,7 +116,7 @@ public List sendTracerouteRequest() throws IOException { * If a request times out, the traceroute is aborted. * @throws IOException if an IO error occurs or if an SCMP error is received. */ - public List sendTracerouteRequest(RequestPath path) throws IOException { + public List sendTracerouteRequest(Path path) throws IOException { List requests = new ArrayList<>(); List nodes = PathHeaderParser.getTraceNodes(path.getRawPath()); for (int i = 0; i < nodes.size(); i++) { @@ -399,7 +399,7 @@ public void close() throws IOException { * @return the current Path * @see ScionDatagramChannel#getConnectionPath() */ - public RequestPath getConnectionPath() { + public Path getConnectionPath() { return channel.getConnectionPath(); } diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java index d97cb3739..462bbcddc 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java @@ -72,7 +72,7 @@ void bind_withoutService() throws IOException { @Test void send_withoutService() throws IOException { - // check that send(ResponsePath) does not internally require a ScionService. + // check that send(Path) does not internally require a ScionService. try (ScionDatagramChannel channel = ScionDatagramChannel.open()) { assertNull(channel.getService()); ResponsePath path = diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java index 39ceb6776..2d580db7c 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java @@ -116,7 +116,7 @@ void getLocalAddress_withSendAddress() throws IOException { @Test void getLocalAddress_withSendRequestPath() throws IOException { - RequestPath path = PackageVisibilityHelper.createDummyPath(); + Path path = PackageVisibilityHelper.createDummyPath(); try (ScionDatagramChannel channel = ScionDatagramChannel.open()) { channel.send(ByteBuffer.allocate(100), path); InetSocketAddress local = channel.getLocalAddress(); @@ -147,26 +147,6 @@ void getLocalAddress_withReceive() throws IOException { } } - @Test - void getLocalAddress_notLocalhost() throws IOException { - ScionService pathService = Scion.defaultService(); - // TXT entry: "scion=64-2:0:9,129.x.x.x" - ScionAddress sAddr = pathService.getScionAddress("ethz.ch"); - InetSocketAddress firstHop = new InetSocketAddress("1.1.1.1", dummyPort); - - RequestPath path = - PackageVisibilityHelper.createDummyPath( - sAddr.getIsdAs(), sAddr.getInetAddress(), dummyPort, new byte[100], firstHop); - - try (ScionDatagramChannel channel = ScionDatagramChannel.open()) { - channel.connect(path); - // Assert that this resolves to a non-local address! - assertFalse(channel.getLocalAddress().toString().contains("127.0.0.")); - assertFalse(channel.getLocalAddress().toString().contains("0:0:0:0:0:0:0:0")); - assertFalse(channel.getLocalAddress().toString().contains("0:0:0:0:0:0:0:1")); - } - } - @Test void send_RequiresInetSocketAddress() throws IOException { ByteBuffer bb = ByteBuffer.allocate(100); @@ -322,7 +302,7 @@ void isConnected_InetSocket() throws IOException { @Test void isConnected_Path() throws IOException { - RequestPath path = PackageVisibilityHelper.createDummyPath(); + Path path = PackageVisibilityHelper.createDummyPath(); InetAddress ip = path.getRemoteAddress(); InetSocketAddress address = new InetSocketAddress(ip, path.getRemotePort()); try (ScionDatagramChannel channel = ScionDatagramChannel.open()) { @@ -372,7 +352,7 @@ void getService_default() throws IOException { assertNull(channel.getService()); // trigger service initialization in channel - RequestPath path = PackageVisibilityHelper.createDummyPath(); + Path path = PackageVisibilityHelper.createDummyPath(); channel.send(ByteBuffer.allocate(0), path); assertNotEquals(service2, channel.getService()); assertEquals(service1, channel.getService()); @@ -415,7 +395,7 @@ void send_bufferSize() throws IOException { @Test void send_bufferTooLarge() { - RequestPath addr = ExamplePacket.PATH; + Path addr = ExamplePacket.PATH; ByteBuffer buffer = ByteBuffer.allocate(65440); buffer.limit(buffer.capacity()); try (ScionDatagramChannel channel = ScionDatagramChannel.open()) { @@ -430,7 +410,7 @@ void send_bufferTooLarge() { @Test void write_bufferTooLarge() throws IOException { - RequestPath addr = ExamplePacket.PATH; + Path addr = ExamplePacket.PATH; ByteBuffer buffer = ByteBuffer.allocate(100_000); buffer.limit(buffer.capacity()); try (ScionDatagramChannel channel = ScionDatagramChannel.open()) { @@ -528,7 +508,7 @@ void write_expiredRequestPath() throws IOException { ByteBuffer sendBuf = ByteBuffer.wrap(PingPongChannelHelper.MSG.getBytes()); try { channel.write(sendBuf); - RequestPath newPath = channel.getConnectionPath(); + Path newPath = channel.getConnectionPath(); assertTrue( newPath.getMetadata().getExpiration() > expiredPath.getMetadata().getExpiration()); assertTrue(Instant.now().getEpochSecond() < newPath.getMetadata().getExpiration()); @@ -539,15 +519,14 @@ void write_expiredRequestPath() throws IOException { true); } - private void testExpired( - BiConsumer sendMethod, boolean connect) + private void testExpired(BiConsumer sendMethod, boolean connect) throws IOException { MockDaemon.closeDefault(); // We don't need the daemon here PingPongChannelHelper.Server serverFn = PingPongChannelHelper::defaultServer; PingPongChannelHelper.Client clientFn = (channel, basePath, id) -> { // Build a path that is already expired - RequestPath expiredPath = createExpiredPath(basePath); + Path expiredPath = createExpiredPath(basePath); sendMethod.accept(channel, expiredPath); ByteBuffer response = ByteBuffer.allocate(100); @@ -561,11 +540,11 @@ private void testExpired( pph.runPingPong(serverFn, clientFn); } - private RequestPath createExpiredPath(Path basePath) throws UnknownHostException { + private Path createExpiredPath(Path basePath) throws UnknownHostException { long now = Instant.now().getEpochSecond(); Daemon.Path.Builder builder = Daemon.Path.newBuilder().setExpiration(Timestamp.newBuilder().setSeconds(now - 10).build()); - RequestPath expiredPath = + Path expiredPath = PackageVisibilityHelper.createRequestPath110_112( builder, basePath.getRemoteIsdAs(), @@ -578,7 +557,7 @@ private RequestPath createExpiredPath(Path basePath) throws UnknownHostException @Test void getConnectionPath() throws IOException { - RequestPath addr = ExamplePacket.PATH; + Path addr = ExamplePacket.PATH; ByteBuffer buffer = ByteBuffer.allocate(50); try (ScionDatagramChannel channel = ScionDatagramChannel.open()) { assertNull(channel.getConnectionPath()); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelErrorHandlingTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelErrorHandlingTest.java index 3e2f85054..d3accbcfc 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelErrorHandlingTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelErrorHandlingTest.java @@ -52,10 +52,10 @@ void testErrorHandling() throws IOException { System.out.println("msg: " + message.getTypeCode()); throw new IllegalArgumentException(); }); - List paths = Scion.defaultService().getPaths(ExamplePacket.DST_IA, dstAddr); + List paths = Scion.defaultService().getPaths(ExamplePacket.DST_IA, dstAddr); assertEquals(2, paths.size()); - RequestPath path0 = paths.get(0); - RequestPath path1 = paths.get(0); + Path path0 = paths.get(0); + Path path1 = paths.get(0); channel.connect(path0); channel.write(ByteBuffer.allocate(0)); assertEquals(path0, channel.getConnectionPath()); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java index a2727b377..5ec933225 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java @@ -43,8 +43,7 @@ void test() { pph.runPingPong(serverFn, clientFn); } - private void client(ScionDatagramChannel channel, RequestPath serverAddress, int id) - throws IOException { + private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { String message = MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); channel.disconnect(); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java index d80f9a81d..ebb0b4be3 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java @@ -24,7 +24,6 @@ import org.junit.jupiter.api.Test; import org.scion.jpan.Path; import org.scion.jpan.PathPolicy; -import org.scion.jpan.RequestPath; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; import org.scion.jpan.testutil.MockNetwork; @@ -38,7 +37,7 @@ class DatagramChannelPathSwitchTest { private int count = 0; @Override - public RequestPath filter(List paths) { + public Path filter(List paths) { return paths.get(count++ % 2); } }; diff --git a/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java b/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java index 04646f26a..815e544e9 100644 --- a/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java @@ -144,31 +144,6 @@ void getLocalAddress_withoutBind() throws IOException { } } - @Test - void getLocalAddress_notLocalhost() throws IOException { - ScionService pathService = Scion.defaultService(); - // TXT entry: "scion=64-2:0:9,129.132.230.98" - // TODO remove ethz.ch?!?! - ScionAddress sAddr = pathService.getScionAddress("ethz.ch"); - InetSocketAddress firstHop = new InetSocketAddress("1.1.1.1", dummyPort); - - RequestPath path = - PackageVisibilityHelper.createDummyPath( - sAddr.getIsdAs(), - sAddr.getInetAddress().getAddress(), - dummyPort, - new byte[100], - firstHop); - - try (ScionDatagramSocket socket = new ScionDatagramSocket()) { - // This constructor binds() to the local ANY address. - assertTrue(socket.getLocalAddress().isAnyLocalAddress()); - socket.connect(path); - // Assert that this doesn't change - assertTrue(socket.getLocalAddress().isAnyLocalAddress()); - } - } - @Test void send_requiresAddressWithScionTxt() { InetSocketAddress addr = new InetSocketAddress("1.1.1.1", 30255); @@ -307,7 +282,7 @@ void isConnected_InetSocket() throws IOException { @Test void isConnected_Path() throws IOException { - RequestPath path = PackageVisibilityHelper.createDummyPath(); + Path path = PackageVisibilityHelper.createDummyPath(); InetAddress ip = path.getRemoteAddress(); InetSocketAddress address = new InetSocketAddress(ip, path.getRemotePort()); try (ScionDatagramSocket socket = new ScionDatagramSocket()) { @@ -617,7 +592,7 @@ void send_connected_expiredRequestPath() throws IOException { new DatagramPacket(msg.getBytes(), msg.length(), toAddress(expiredPath)); try { socket.send(packet); - RequestPath newPath = socket.getConnectionPath(); + Path newPath = socket.getConnectionPath(); assertTrue( newPath.getMetadata().getExpiration() > expiredPath.getMetadata().getExpiration()); assertTrue(Instant.now().getEpochSecond() < newPath.getMetadata().getExpiration()); @@ -627,14 +602,13 @@ void send_connected_expiredRequestPath() throws IOException { }); } - private void testExpired(BiConsumer sendMethod) - throws IOException { + private void testExpired(BiConsumer sendMethod) throws IOException { MockDaemon.closeDefault(); // We don't need the daemon here PingPongSocketHelper.Server serverFn = PingPongSocketHelper::defaultServer; PingPongSocketHelper.Client clientFn = (channel, basePath, id) -> { // Build a path that is already expired - RequestPath expiredPath = createExpiredPath(basePath); + Path expiredPath = createExpiredPath(basePath); sendMethod.accept(channel, expiredPath); DatagramPacket packet = new DatagramPacket(new byte[100], 100); @@ -648,11 +622,11 @@ private void testExpired(BiConsumer sendMethod pph.runPingPong(serverFn, clientFn); } - private RequestPath createExpiredPath(Path basePath) throws UnknownHostException { + private Path createExpiredPath(Path basePath) throws UnknownHostException { long now = Instant.now().getEpochSecond(); Timestamp timestamp = Timestamp.newBuilder().setSeconds(now - 10).build(); Daemon.Path.Builder builder = Daemon.Path.newBuilder().setExpiration(timestamp); - RequestPath expiredPath = + Path expiredPath = PackageVisibilityHelper.createRequestPath110_112( builder, basePath.getRemoteIsdAs(), @@ -669,7 +643,7 @@ private static InetSocketAddress toAddress(Path path) { @Test void getConnectionPath() throws IOException { - RequestPath path = ExamplePacket.PATH; + Path path = ExamplePacket.PATH; DatagramPacket packet = new DatagramPacket(new byte[50], 50, toAddress(path)); try (ScionDatagramSocket channel = new ScionDatagramSocket()) { assertNull(channel.getConnectionPath()); diff --git a/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java b/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java index 94a19c2dc..3df29228d 100644 --- a/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java @@ -23,7 +23,7 @@ import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.RequestPath; +import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramSocket; import org.scion.jpan.ScionService; import org.scion.jpan.testutil.MockNetwork; @@ -59,8 +59,7 @@ void test() throws IOException { assertEquals(2 * 10 * 10, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramSocket socket, RequestPath requestPath, int id) - throws IOException { + private void client(ScionDatagramSocket socket, Path requestPath, int id) throws IOException { byte[] sendBuf = MSG.getBytes(); InetAddress addr = requestPath.getRemoteAddress(); int port = requestPath.getRemotePort(); diff --git a/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java b/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java index e5680309c..41d5dab3e 100644 --- a/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java @@ -21,7 +21,7 @@ import java.net.*; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.RequestPath; +import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramSocket; import org.scion.jpan.ScionService; import org.scion.jpan.testutil.MockNetwork; @@ -44,8 +44,7 @@ void test() { assertEquals(2 * 10 * 10, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramSocket socket, RequestPath requestPath, int id) - throws IOException { + private void client(ScionDatagramSocket socket, Path requestPath, int id) throws IOException { byte[] sendBuf = MSG.getBytes(); InetAddress addr = requestPath.getRemoteAddress(); int port = requestPath.getRemotePort(); diff --git a/src/test/java/org/scion/jpan/api/SCMPTest.java b/src/test/java/org/scion/jpan/api/SCMPTest.java index 634877e29..2ddc0cd98 100644 --- a/src/test/java/org/scion/jpan/api/SCMPTest.java +++ b/src/test/java/org/scion/jpan/api/SCMPTest.java @@ -106,7 +106,7 @@ void echo_localAS() throws IOException { testEcho(this::getPathToLocalAS); } - private void testEcho(Supplier path) throws IOException { + private void testEcho(Supplier path) throws IOException { MockNetwork.startTiny(); MockNetwork.answerNextScmpEchos(1); try (ScmpChannel channel = Scmp.createChannel()) { @@ -128,7 +128,7 @@ private void testEcho(Supplier path) throws IOException { @Test void echo_timeout() throws IOException { MockNetwork.startTiny(); - RequestPath path = getPathTo112(); + Path path = getPathTo112(); try (ScmpChannel channel = Scmp.createChannel()) { channel.setScmpErrorListener(scmpMessage -> fail(scmpMessage.getTypeCode().getText())); channel.setOption(ScionSocketOptions.SCION_API_THROW_PARSER_FAILURE, true); @@ -155,7 +155,7 @@ void echo_timeout() throws IOException { @Test void echo_IOException() throws IOException { MockNetwork.startTiny(); - RequestPath path = getPathTo112(); + Path path = getPathTo112(); try (ScmpChannel channel = Scmp.createChannel()) { channel.setScmpErrorListener(scmpMessage -> fail(scmpMessage.getTypeCode().getText())); channel.setOption(ScionSocketOptions.SCION_API_THROW_PARSER_FAILURE, true); @@ -198,7 +198,7 @@ void traceroute_localAS() throws IOException { testTraceroute(this::getPathToLocalAS, 0); } - private void testTraceroute(Supplier path, int nHops) throws IOException { + private void testTraceroute(Supplier path, int nHops) throws IOException { MockNetwork.startTiny(); try (ScmpChannel channel = Scmp.createChannel()) { channel.setScmpErrorListener(scmpMessage -> fail(scmpMessage.getTypeCode().getText())); @@ -231,7 +231,7 @@ private void testTraceroute(Supplier path, int nHops) throws IOExce @Test void traceroute_timeout() throws IOException { MockNetwork.startTiny(); - RequestPath path = getPathTo112(); + Path path = getPathTo112(); try (ScmpChannel channel = Scmp.createChannel()) { channel.setScmpErrorListener(scmpMessage -> fail(scmpMessage.getTypeCode().getText())); channel.setOption(ScionSocketOptions.SCION_API_THROW_PARSER_FAILURE, true); @@ -262,7 +262,7 @@ void traceroute_timeout() throws IOException { @Test void traceroute_IOException() throws IOException { MockNetwork.startTiny(); - RequestPath path = getPathTo112(); + Path path = getPathTo112(); try (ScmpChannel channel = Scmp.createChannel()) { channel.setScmpErrorListener(scmpMessage -> fail(scmpMessage.getTypeCode().getText())); channel.setOption(ScionSocketOptions.SCION_API_THROW_PARSER_FAILURE, true); @@ -277,7 +277,7 @@ void traceroute_IOException() throws IOException { @Test void traceroute_SCMP_error() throws IOException { MockNetwork.startTiny(); - RequestPath path = getPathTo112(); + Path path = getPathTo112(); try (ScmpChannel channel = Scmp.createChannel()) { AtomicBoolean listenerWasTriggered = new AtomicBoolean(false); channel.setScmpErrorListener(scmpMessage -> listenerWasTriggered.set(true)); @@ -292,7 +292,7 @@ void traceroute_SCMP_error() throws IOException { } } - private RequestPath getPathTo112() { + private Path getPathTo112() { try { InetAddress zero = InetAddress.getByAddress(new byte[] {0, 0, 0, 0}); return getPathTo112(zero); @@ -301,19 +301,19 @@ private RequestPath getPathTo112() { } } - private RequestPath getPathTo112(InetAddress dstAddress) { + private Path getPathTo112(InetAddress dstAddress) { ScionService service = Scion.defaultService(); long dstIA = ScionUtil.parseIA("1-ff00:0:112"); return service.getPaths(dstIA, dstAddress, Constants.SCMP_PORT).get(0); } - private RequestPath getPathToLocalAS() { + private Path getPathToLocalAS() { ScionService service = Scion.defaultService(); long dstIA = service.getLocalIsdAs(); try { InetAddress addr = InetAddress.getByName(MockNetwork.BORDER_ROUTER_HOST); int port = MockNetwork.BORDER_ROUTER_PORT1; - List paths = service.getPaths(dstIA, new InetSocketAddress(addr, port)); + List paths = service.getPaths(dstIA, new InetSocketAddress(addr, port)); return paths.get(0); } catch (UnknownHostException e) { throw new RuntimeException(e); @@ -323,7 +323,7 @@ private RequestPath getPathToLocalAS() { @Test void setUpScmpResponder_echo() throws IOException, InterruptedException { MockNetwork.startTiny(); - RequestPath path = getPathTo112(InetAddress.getLoopbackAddress()); + Path path = getPathTo112(InetAddress.getLoopbackAddress()); // sender is in 110; responder is in 112 try (ScmpChannel sender = Scmp.createChannel()) { sender.setScmpErrorListener(scmpMessage -> fail(scmpMessage.getTypeCode().getText())); @@ -355,7 +355,7 @@ void setUpScmpResponder_echo() throws IOException, InterruptedException { @Test void setUpScmpResponder_echo_blocked() throws IOException, InterruptedException { MockNetwork.startTiny(); - RequestPath path = getPathTo112(InetAddress.getLoopbackAddress()); + Path path = getPathTo112(InetAddress.getLoopbackAddress()); // sender is in 110; responder is in 112 try (ScmpChannel sender = Scmp.createChannel()) { sender.setScmpErrorListener(scmpMessage -> fail(scmpMessage.getTypeCode().getText())); diff --git a/src/test/java/org/scion/jpan/api/ScionServiceTest.java b/src/test/java/org/scion/jpan/api/ScionServiceTest.java index f952067dd..e81799bac 100644 --- a/src/test/java/org/scion/jpan/api/ScionServiceTest.java +++ b/src/test/java/org/scion/jpan/api/ScionServiceTest.java @@ -19,10 +19,7 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.URISyntaxException; -import java.net.URL; +import java.net.*; import java.nio.file.Paths; import java.util.Collections; import java.util.List; @@ -44,6 +41,7 @@ public class ScionServiceTest { private static final String SCION_HOST = "as110.test"; private static final String SCION_TXT = "\"scion=1-ff00:0:110,127.0.0.1\""; private static final String SCION_TXT_IPV6 = "\"scion=1-ff00:0:110,[::1]\""; + private static final int SCION_HOST_PORT = 12345; private static final int DEFAULT_PORT = MockDaemon.DEFAULT_PORT; @AfterAll @@ -75,7 +73,7 @@ void testDaemonCreationIPv6() throws IOException { long dstIA = ScionUtil.parseIA("1-ff00:0:112"); InetSocketAddress dstAddress = new InetSocketAddress("::1", 12345); try (Scion.CloseableService client = Scion.newServiceWithDaemon(daemonAddr)) { - RequestPath path = client.getPaths(dstIA, dstAddress).get(0); + Path path = client.getPaths(dstIA, dstAddress).get(0); assertNotNull(path); // local AS + path assertEquals(2, MockDaemon.getAndResetCallCount()); @@ -91,7 +89,7 @@ void testDaemonCreationIPv4() throws IOException { long dstIA = ScionUtil.parseIA("1-ff00:0:112"); InetSocketAddress dstAddress = new InetSocketAddress("::1", 12345); try (Scion.CloseableService client = Scion.newServiceWithDaemon(daemonAddr)) { - RequestPath path = client.getPaths(dstIA, dstAddress).get(0); + Path path = client.getPaths(dstIA, dstAddress).get(0); assertNotNull(path); // local AS + path assertEquals(2, MockDaemon.getAndResetCallCount()); @@ -106,7 +104,7 @@ void getPath() throws IOException { MockDaemon.createAndStartDefault(); try { // String daemonAddr = "127.0.0.12:30255"; // from 110-topo - RequestPath path; + Path path; long dstIA = ScionUtil.parseIA("1-ff00:0:112"); try (Scion.CloseableService client = Scion.newServiceWithDaemon(MockDaemon.DEFAULT_ADDRESS_STR)) { @@ -144,7 +142,7 @@ void getPaths() throws IOException { MockDaemon.createAndStartDefault(); try { // String daemonAddr = "127.0.0.12:30255"; // from 110-topo - List paths; + List paths; long dstIA = ScionUtil.parseIA("1-ff00:0:112"); try (Scion.CloseableService client = Scion.newServiceWithDaemon(MockDaemon.DEFAULT_ADDRESS_STR)) { @@ -159,7 +157,7 @@ void getPaths() throws IOException { // 0: 2 561850441793808 // 0: 1 561850441793810 assertEquals(1, paths.size()); - for (RequestPath path : paths) { + for (Path path : paths) { assertEquals("/127.0.0.10:31004", path.getFirstHopAddress().toString()); // assertEquals(srcIA, path.getSourceIsdAs()); assertEquals(dstIA, path.getRemoteIsdAs()); @@ -178,7 +176,7 @@ void getPaths_localAS() throws IOException { MockDaemon.createAndStartDefault(); try { // String daemonAddr = "127.0.0.12:30255"; // from 110-topo - List paths; + List paths; long dstIA = ScionUtil.parseIA("1-ff00:0:110"); try (Scion.CloseableService client = Scion.newServiceWithDaemon(MockDaemon.DEFAULT_ADDRESS_STR)) { @@ -193,7 +191,7 @@ void getPaths_localAS() throws IOException { // raw: [] // raw: {} assertEquals(1, paths.size()); - RequestPath path = paths.get(0); + Path path = paths.get(0); InetAddress addr = path.getRemoteAddress(); InetSocketAddress sAddr = new InetSocketAddress(addr, path.getRemotePort()); assertEquals(sAddr, path.getFirstHopAddress()); @@ -211,7 +209,7 @@ void getPaths_noPathFound_fromCore() { InetSocketAddress dstAddress = new InetSocketAddress(InetAddress.getLoopbackAddress(), 12345); try (MockNetwork2 nw = MockNetwork2.start("topologies/minimal/ASff00_0_110/topology.json")) { ScionService service = Scion.defaultService(); - List paths; + List paths; nw.getControlServer().getAndResetCallCount(); // Non-existing AS @@ -236,7 +234,7 @@ void getPaths_noPathFound_fromLeaf() { InetSocketAddress dstAddress = new InetSocketAddress(InetAddress.getLoopbackAddress(), 12345); try (MockNetwork2 nw = MockNetwork2.start("topologies/minimal/ASff00_0_1111/topology.json")) { ScionService service = Scion.defaultService(); - List paths; + List paths; nw.getControlServer().getAndResetCallCount(); // Non-existing AS @@ -257,7 +255,7 @@ void getPaths_noPathFound_fromLeaf() { } @Test - void getScionAddress_IPv4() throws IOException { + void getScionAddress_IPv4_byHostName() throws IOException { // Test that DNS injection via properties works System.setProperty( PackageVisibilityHelper.DEBUG_PROPERTY_DNS_MOCK, SCION_HOST + "=" + SCION_TXT); @@ -265,11 +263,39 @@ void getScionAddress_IPv4() throws IOException { try { ScionService pathService = Scion.defaultService(); // TXT entry: "scion=64-2:0:9,129.x.x.x" - ScionAddress sAddr = pathService.getScionAddress(SCION_HOST); + Path path = pathService.lookupAndGetPath(SCION_HOST, SCION_HOST_PORT, null); + assertNotNull(path); + ScionSocketAddress sAddr = path.getRemoteSocketAddress(); assertNotNull(sAddr); - assertEquals(1, sAddr.getIsd()); assertEquals("1-ff00:0:110", ScionUtil.toStringIA(sAddr.getIsdAs())); - assertEquals(SCION_HOST + "/127.0.0.1", sAddr.getInetAddress().toString()); + assertEquals(SCION_HOST + "/127.0.0.1", sAddr.getAddress().toString()); + assertEquals(SCION_HOST_PORT, sAddr.getPort()); + assertEquals(SCION_HOST, sAddr.getHostName()); + } finally { + System.clearProperty(PackageVisibilityHelper.DEBUG_PROPERTY_DNS_MOCK); + ScionService.closeDefault(); + MockNetwork.stopTiny(); + } + } + + @Test + void getScionAddress_IPv4_byAddress() throws IOException { + // Test that DNS injection via properties works + System.setProperty( + PackageVisibilityHelper.DEBUG_PROPERTY_DNS_MOCK, SCION_HOST + "=" + SCION_TXT); + MockNetwork.startTiny(MockNetwork.Mode.NAPTR); + try { + ScionService pathService = Scion.defaultService(); + // TXT entry: "scion=64-2:0:9,129.x.x.x" + InetAddress ia = Inet4Address.getByAddress(SCION_HOST, new byte[] {127, 0, 0, 1}); + InetSocketAddress isa = new InetSocketAddress(ia, SCION_HOST_PORT); + Path path = pathService.lookupAndGetPath(isa, null); + assertNotNull(path); + ScionSocketAddress sAddr = path.getRemoteSocketAddress(); + assertNotNull(sAddr); + assertEquals("1-ff00:0:110", ScionUtil.toStringIA(sAddr.getIsdAs())); + assertEquals(SCION_HOST + "/127.0.0.1", sAddr.getAddress().toString()); + assertEquals(SCION_HOST_PORT, sAddr.getPort()); assertEquals(SCION_HOST, sAddr.getHostName()); } finally { System.clearProperty(PackageVisibilityHelper.DEBUG_PROPERTY_DNS_MOCK); @@ -287,11 +313,13 @@ void getScionAddress_IPv6() throws IOException { try { ScionService pathService = Scion.defaultService(); // TXT entry: "scion=64-2:0:9,129.x.x.x" - ScionAddress sAddr = pathService.getScionAddress(SCION_HOST); + Path path = pathService.lookupAndGetPath(SCION_HOST, SCION_HOST_PORT, null); + assertNotNull(path); + ScionSocketAddress sAddr = path.getRemoteSocketAddress(); assertNotNull(sAddr); - assertEquals(1, sAddr.getIsd()); assertEquals("1-ff00:0:110", ScionUtil.toStringIA(sAddr.getIsdAs())); - assertEquals(SCION_HOST + "/0:0:0:0:0:0:0:1", sAddr.getInetAddress().toString()); + assertEquals(SCION_HOST + "/0:0:0:0:0:0:0:1", sAddr.getAddress().toString()); + assertEquals(SCION_HOST_PORT, sAddr.getPort()); assertEquals(SCION_HOST, sAddr.getHostName()); } finally { System.clearProperty(PackageVisibilityHelper.DEBUG_PROPERTY_DNS_MOCK); @@ -301,7 +329,7 @@ void getScionAddress_IPv6() throws IOException { } @Test - void getScionAddress_Failure_BadTxtRecord() throws IOException { + void getScionAddress_Failure_BadTxtRecord() { // Test that DNS injection via properties works System.setProperty( PackageVisibilityHelper.DEBUG_PROPERTY_DNS_MOCK, SCION_HOST + "=" + SCION_TXT); @@ -377,8 +405,9 @@ private void testInvalidTxtEntry(String txtEntry) { // Use any topo file MockTopologyServer topo = MockTopologyServer.start(MockTopologyServer.TOPOFILE_TINY_110, true); try { - ScionService pathService = Scion.defaultService(); - Exception ex = assertThrows(ScionException.class, () -> pathService.getScionAddress(host)); + ScionService service = Scion.defaultService(); + Exception ex = + assertThrows(ScionException.class, () -> service.lookupAndGetPath(host, 123, null)); assertTrue(ex.getMessage().startsWith("Invalid TXT entry"), ex.getMessage()); } finally { System.clearProperty(PackageVisibilityHelper.DEBUG_PROPERTY_DNS_MOCK); diff --git a/src/test/java/org/scion/jpan/api/ScionTest.java b/src/test/java/org/scion/jpan/api/ScionTest.java index e2ea85ed2..4ac531aa6 100644 --- a/src/test/java/org/scion/jpan/api/ScionTest.java +++ b/src/test/java/org/scion/jpan/api/ScionTest.java @@ -90,7 +90,7 @@ void defaultService_daemon() throws IOException { System.setProperty(Constants.PROPERTY_DAEMON, "[::1]:" + DEFAULT_PORT); try { ScionService service = Scion.defaultService(); - RequestPath path = service.getPaths(dstIA, dstAddress).get(0); + Path path = service.getPaths(dstIA, dstAddress).get(0); assertNotNull(path); // local AS + path assertEquals(2, MockDaemon.getAndResetCallCount()); @@ -109,7 +109,7 @@ void defaultService_topoFile() { try { System.setProperty(Constants.PROPERTY_BOOTSTRAP_TOPO_FILE, TOPO_FILE); ScionService service = Scion.defaultService(); - RequestPath path = service.getPaths(dstIA, dstAddress).get(0); + Path path = service.getPaths(dstIA, dstAddress).get(0); assertNotNull(path); assertEquals(0, MockDaemon.getAndResetCallCount()); // Daemon is not used! } finally { @@ -135,7 +135,7 @@ void defaultService_bootstrapAddress() { System.setProperty(Constants.PROPERTY_BOOTSTRAP_HOST, host); ScionService service = Scion.defaultService(); - RequestPath path = service.getPaths(dstIA, dstAddress).get(0); + Path path = service.getPaths(dstIA, dstAddress).get(0); assertNotNull(path); assertEquals(0, MockDaemon.getAndResetCallCount()); // Daemon is not used! } finally { @@ -150,7 +150,7 @@ void defaultService_bootstrapNaptrRecord() { MockNetwork.startTiny(MockNetwork.Mode.NAPTR); try { ScionService service = Scion.defaultService(); - RequestPath path = service.getPaths(dstIA, dstAddress).get(0); + Path path = service.getPaths(dstIA, dstAddress).get(0); assertNotNull(path); assertEquals(0, MockDaemon.getAndResetCallCount()); // Daemon is not used! } finally { @@ -166,7 +166,7 @@ void defaultService_bootstrapTopoFile() { try { System.setProperty(Constants.PROPERTY_BOOTSTRAP_TOPO_FILE, TOPO_FILE); ScionService service = Scion.defaultService(); - RequestPath path = service.getPaths(dstIA, dstAddress).get(0); + Path path = service.getPaths(dstIA, dstAddress).get(0); assertNotNull(path); assertEquals(0, MockDaemon.getAndResetCallCount()); // Daemon is not used! } finally { @@ -295,7 +295,7 @@ void newServiceWithDNS() throws IOException { try (Scion.CloseableService ss = Scion.newServiceWithDNS(MockTopologyServer.TOPO_HOST)) { // destination address = 123.123.123.123 because we don´t care for getting a path InetAddress ip123 = InetAddress.getByAddress(new byte[] {123, 123, 123, 123}); - List paths = ss.getPaths(iaDst, ip123, 12345); + List paths = ss.getPaths(iaDst, ip123, 12345); assertNotNull(paths); assertFalse(paths.isEmpty()); assertEquals(1, MockNetwork.getTopoServer().getAndResetCallCount()); @@ -315,7 +315,7 @@ void newServiceWithBootstrapServer() throws IOException { Scion.newServiceWithBootstrapServer(ToStringUtil.toAddressPort(topoAddr))) { // destination address = 123.123.123.123 because we don´t care for getting a path InetAddress ip123 = InetAddress.getByAddress(new byte[] {123, 123, 123, 123}); - List paths = ss.getPaths(iaDst, ip123, 12345); + List paths = ss.getPaths(iaDst, ip123, 12345); assertNotNull(paths); assertFalse(paths.isEmpty()); assertEquals(1, MockNetwork.getTopoServer().getAndResetCallCount()); @@ -336,7 +336,7 @@ void defaultService_bootstrapTopoFile_ScionProto_11() { System.setProperty( Constants.PROPERTY_BOOTSTRAP_TOPO_FILE, "topologies/topology-scionproto-0.11.json"); ScionService service = Scion.defaultService(); - RequestPath path = service.getPaths(dstIA, dstAddress).get(0); + Path path = service.getPaths(dstIA, dstAddress).get(0); assertNotNull(path); assertEquals(0, MockDaemon.getAndResetCallCount()); // Daemon is not used! } finally { diff --git a/src/test/java/org/scion/jpan/api/ScionUtilTest.java b/src/test/java/org/scion/jpan/api/ScionUtilTest.java index 1d05e30a5..ae366f1c3 100644 --- a/src/test/java/org/scion/jpan/api/ScionUtilTest.java +++ b/src/test/java/org/scion/jpan/api/ScionUtilTest.java @@ -20,7 +20,7 @@ import java.net.UnknownHostException; import org.junit.jupiter.api.Test; import org.scion.jpan.PackageVisibilityHelper; -import org.scion.jpan.RequestPath; +import org.scion.jpan.Path; import org.scion.jpan.ScionUtil; import org.scion.jpan.proto.daemon.Daemon; import org.scion.jpan.testutil.ExamplePacket; @@ -102,13 +102,14 @@ void extractIsd() { @Test void toStringPath_requestPath() throws UnknownHostException { - RequestPath pathLocal = createRequestPathLocal(); - assertEquals("[]", ScionUtil.toStringPath(pathLocal)); - RequestPath pathRemote = createRequestPathRemote(); - assertEquals("[1-ff00:0:110 2>1 1-ff00:0:112]", ScionUtil.toStringPath(pathRemote)); + Path pathLocal = createRequestPathLocal(); + assertEquals("[]", ScionUtil.toStringPath(pathLocal.getMetadata())); + Path pathRemote = createRequestPathRemote(); + assertEquals( + "[1-ff00:0:110 2>1 1-ff00:0:112]", ScionUtil.toStringPath(pathRemote.getMetadata())); } - private RequestPath createRequestPathLocal() throws UnknownHostException { + private Path createRequestPathLocal() throws UnknownHostException { return PackageVisibilityHelper.createRequestPath110_110( Daemon.Path.newBuilder(), ExamplePacket.SRC_IA, @@ -116,7 +117,7 @@ private RequestPath createRequestPathLocal() throws UnknownHostException { 12345); } - private RequestPath createRequestPathRemote() throws UnknownHostException { + private Path createRequestPathRemote() throws UnknownHostException { return PackageVisibilityHelper.createRequestPath110_112( Daemon.Path.newBuilder(), ExamplePacket.DST_IA, diff --git a/src/test/java/org/scion/jpan/demo/PingPongChannelClient.java b/src/test/java/org/scion/jpan/demo/PingPongChannelClient.java index 8f14aec13..5c9d2715c 100644 --- a/src/test/java/org/scion/jpan/demo/PingPongChannelClient.java +++ b/src/test/java/org/scion/jpan/demo/PingPongChannelClient.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.net.*; import java.nio.ByteBuffer; +import org.scion.jpan.PathMetadata; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionUtil; import org.scion.jpan.testutil.MockDNS; @@ -50,7 +51,8 @@ private static void run() throws IOException { String msg = "Hello there!"; ByteBuffer sendBuf = ByteBuffer.wrap(msg.getBytes()); channel.write(sendBuf); - println("Sent via " + ScionUtil.toStringPath(channel.getConnectionPath()) + ": " + msg); + PathMetadata meta = channel.getConnectionPath().getMetadata(); + println("Sent via " + ScionUtil.toStringPath(meta) + ": " + msg); println("Receiving ... (" + channel.getLocalAddress() + ")"); ByteBuffer buffer = ByteBuffer.allocate(512); diff --git a/src/test/java/org/scion/jpan/demo/ScmpEchoDemo.java b/src/test/java/org/scion/jpan/demo/ScmpEchoDemo.java index 2f85bebe8..c781e76a9 100644 --- a/src/test/java/org/scion/jpan/demo/ScmpEchoDemo.java +++ b/src/test/java/org/scion/jpan/demo/ScmpEchoDemo.java @@ -17,7 +17,6 @@ import java.io.*; import java.net.*; import java.nio.ByteBuffer; -import java.util.List; import org.scion.jpan.*; import org.scion.jpan.testutil.MockDNS; @@ -65,13 +64,14 @@ public ScmpEchoDemo(int localPort) { private static final Network network = Network.PRODUCTION; public static void main(String[] args) throws IOException { + ScionService service = Scion.defaultService(); switch (network) { case JUNIT_MOCK: { DemoTopology.configureMock(); MockDNS.install("1-ff00:0:112", "ip6-localhost", "::1"); ScmpEchoDemo demo = new ScmpEchoDemo(); - demo.runDemo(DemoConstants.ia112, serviceIP); + demo.runDemo(service.getPaths(DemoConstants.ia112, serviceIP).get(0)); DemoTopology.shutDown(); break; } @@ -79,33 +79,32 @@ public static void main(String[] args) throws IOException { // Same as: // scion ping 2-ff00:0:211,127.0.0.10 --sciond 127.0.0.43:30255 { + // Bootstrap from topo file System.setProperty( Constants.PROPERTY_BOOTSTRAP_TOPO_FILE, "topologies/minimal/ASff00_0_1111/topology.json"); + // Bootstrap from SCION daemon // System.setProperty(Constants.PROPERTY_DAEMON, DemoConstants.daemon1111_minimal); + ScmpEchoDemo demo = new ScmpEchoDemo(); - demo.runDemo(DemoConstants.ia211, serviceIP); - // demo.runDemo(DemoConstants.ia111, toAddr(DemoConstants.daemon111_minimal)); - // demo.runDemo(DemoConstants.ia1111, toAddr(DemoConstants.daemon1111_minimal)); + demo.runDemo(service.getPaths(DemoConstants.ia211, serviceIP).get(0)); + // demo.runDemo(service.getPaths(DemoConstants.ia111, serviceIP).get(0)); + // demo.runDemo(service.getPaths(DemoConstants.ia1111, serviceIP).get(0)); break; } case PRODUCTION: { // Local port must be 30041 for networks that expect a dispatcher ScmpEchoDemo demo = new ScmpEchoDemo(Constants.SCMP_PORT); - // demo.runDemo(DemoConstants.iaOVGU, serviceIP); - InetAddress ethzIP = Scion.defaultService().getScionAddress("ethz.ch").getInetAddress(); - demo.runDemo(DemoConstants.iaETH, new InetSocketAddress(ethzIP, Constants.SCMP_PORT)); - // demo.runDemo(DemoConstants.iaGEANT, serviceIP); + demo.runDemo(service.lookupAndGetPath("ethz.ch", Constants.SCMP_PORT, null)); + demo.runDemo(service.getPaths(DemoConstants.iaOVGU, serviceIP).get(0)); break; } } Scion.closeDefault(); } - private void runDemo(long dstIA, InetSocketAddress dstAddress) throws IOException { - List paths = Scion.defaultService().getPaths(dstIA, dstAddress); - RequestPath path = paths.get(0); + private void runDemo(Path path) throws IOException { ByteBuffer data = ByteBuffer.allocate(0); println("Listening on port " + localPort + " ..."); @@ -120,12 +119,12 @@ private void runDemo(long dstIA, InetSocketAddress dstAddress) throws IOExceptio for (int i = 0; i < 10; i++) { Scmp.EchoMessage msg = scmpChannel.sendEchoRequest(path, i, data); if (i == 0) { - printHeader(dstIA, dstAddress, data, msg); + printHeader(path.getRemoteSocketAddress(), data, msg); } String millis = String.format("%.3f", msg.getNanoSeconds() / (double) 1_000_000); String echoMsgStr = msg.getSizeReceived() + " bytes from "; InetAddress addr = msg.getPath().getRemoteAddress(); - echoMsgStr += ScionUtil.toStringIA(dstIA) + "," + addr.getHostAddress(); + echoMsgStr += ScionUtil.toStringIA(path.getRemoteIsdAs()) + "," + addr.getHostAddress(); echoMsgStr += ": scmp_seq=" + msg.getSequenceNumber(); if (msg.isTimedOut()) { echoMsgStr += " Timed out after"; @@ -141,33 +140,18 @@ private void runDemo(long dstIA, InetSocketAddress dstAddress) throws IOExceptio } } - private void printPath(RequestPath path) { + private void printPath(Path path) { String nl = System.lineSeparator(); - StringBuilder sb = new StringBuilder(); - // sb.append("Actual local address:").append(nl); - // sb.append(" - // ").append(channel.getLocalAddress().getAddress().getHostAddress()).append(nl); - sb.append("Using path:").append(nl); - sb.append(" Hops: ").append(ScionUtil.toStringPath(path)); - sb.append(" MTU: ").append(path.getMetadata().getMtu()); - sb.append(" NextHop: ").append(path.getMetadata().getInterface().getAddress()).append(nl); - println(sb.toString()); + String sb = "Using path:" + nl + " Hops: " + ScionUtil.toStringPath(path.getMetadata()); + sb += " MTU: " + path.getMetadata().getMtu(); + sb += " NextHop: " + path.getMetadata().getInterface().getAddress() + nl; + println(sb); } - private void printHeader( - long dstIA, InetSocketAddress dstAddress, ByteBuffer data, Scmp.EchoMessage msg) { - String sb = - "PING " - + ScionUtil.toStringIA(dstIA) - + "," - + dstAddress.getHostString() - + ":" - + dstAddress.getPort() - + " pld=" - + data.remaining() - + "B scion_pkt=" - + msg.getSizeSent() - + "B"; + private void printHeader(ScionSocketAddress dstAddress, ByteBuffer data, Scmp.EchoMessage msg) { + String sb = "PING " + ScionUtil.toStringIA(dstAddress.getIsdAs()) + ","; + sb += dstAddress.getHostString() + ":" + dstAddress.getPort() + " pld=" + data.remaining(); + sb += "B scion_pkt=" + msg.getSizeSent() + "B"; println(sb); } diff --git a/src/test/java/org/scion/jpan/demo/ScmpTracerouteDemo.java b/src/test/java/org/scion/jpan/demo/ScmpTracerouteDemo.java index 19bb11d0a..b1b3ce13a 100644 --- a/src/test/java/org/scion/jpan/demo/ScmpTracerouteDemo.java +++ b/src/test/java/org/scion/jpan/demo/ScmpTracerouteDemo.java @@ -91,13 +91,13 @@ private void runDemo(long destinationIA) throws IOException { // Dummy address. The traceroute will contact the control service IP instead. InetSocketAddress destinationAddress = new InetSocketAddress(Inet4Address.getByAddress(new byte[] {1, 2, 3, 4}), 12345); - List paths = service.getPaths(destinationIA, destinationAddress); + List paths = service.getPaths(destinationIA, destinationAddress); if (paths.isEmpty()) { String src = ScionUtil.toStringIA(service.getLocalIsdAs()); String dst = ScionUtil.toStringIA(destinationIA); throw new IOException("No path found from " + src + " to " + dst); } - RequestPath path = paths.get(0); + Path path = paths.get(0); println("Listening on port " + localPort + " ..."); try (ScionDatagramChannel channel = ScionDatagramChannel.open()) { @@ -122,13 +122,13 @@ private void runDemo(long destinationIA) throws IOException { } } - private void printPath(RequestPath path) { + private void printPath(Path path) { String nl = System.lineSeparator(); StringBuilder sb = new StringBuilder(); // sb.append("Actual local address:").append(nl); // sb.append(" ").append(channel.getLocalAddress().getAddress().getHostAddress()).append(nl); sb.append("Using path:").append(nl); - sb.append(" Hops: ").append(ScionUtil.toStringPath(path)); + sb.append(" Hops: ").append(ScionUtil.toStringPath(path.getMetadata())); sb.append(" MTU: ").append(path.getMetadata().getMtu()); sb.append(" NextHop: ").append(path.getMetadata().getInterface().getAddress()).append(nl); println(sb.toString()); diff --git a/src/test/java/org/scion/jpan/demo/ShowpathsDemo.java b/src/test/java/org/scion/jpan/demo/ShowpathsDemo.java index 6aebb5da4..f1a776cfd 100644 --- a/src/test/java/org/scion/jpan/demo/ShowpathsDemo.java +++ b/src/test/java/org/scion/jpan/demo/ShowpathsDemo.java @@ -91,7 +91,7 @@ private void runDemo(long destinationIA) throws IOException { // dummy address InetSocketAddress destinationAddress = new InetSocketAddress(Inet4Address.getByAddress(new byte[] {0, 0, 0, 0}), 12345); - List paths = service.getPaths(destinationIA, destinationAddress); + List paths = service.getPaths(destinationIA, destinationAddress); if (paths.isEmpty()) { String src = ScionUtil.toStringIA(service.getLocalIsdAs()); String dst = ScionUtil.toStringIA(destinationIA); @@ -102,19 +102,20 @@ private void runDemo(long destinationIA) throws IOException { println("Available paths to " + ScionUtil.toStringIA(destinationIA)); int id = 0; - for (RequestPath path : paths) { + for (Path path : paths) { String localIP; try (ScionDatagramChannel channel = ScionDatagramChannel.open()) { channel.connect(path); localIP = channel.getLocalAddress().getAddress().getHostAddress(); } + PathMetadata meta = path.getMetadata(); String sb = "[" + id++ + "] Hops: " - + ScionUtil.toStringPath(path) + + ScionUtil.toStringPath(meta) + " MTU: " - + path.getMetadata().getMtu() + + meta.getMtu() + " NextHop: " + path.getFirstHopAddress().getAddress() + " LocalIP: " diff --git a/src/test/java/org/scion/jpan/testutil/ExamplePacket.java b/src/test/java/org/scion/jpan/testutil/ExamplePacket.java index 1522a076f..5e029542b 100644 --- a/src/test/java/org/scion/jpan/testutil/ExamplePacket.java +++ b/src/test/java/org/scion/jpan/testutil/ExamplePacket.java @@ -16,7 +16,7 @@ import java.net.InetSocketAddress; import org.scion.jpan.PackageVisibilityHelper; -import org.scion.jpan.RequestPath; +import org.scion.jpan.Path; import org.scion.jpan.ScionUtil; public class ExamplePacket { @@ -39,7 +39,7 @@ public class ExamplePacket { 0, 63, 0, 1, 0, 0, -8, 2, -114, 25, 76, -122, }; - public static final RequestPath PATH = + public static final Path PATH = PackageVisibilityHelper.createDummyPath( DST_IA, DST_HOST, 8080, PATH_RAW_TINY_110_112, FIRST_HOP); diff --git a/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java b/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java index 794a3ec8c..fc5305abf 100644 --- a/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java +++ b/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; import org.scion.jpan.Path; -import org.scion.jpan.RequestPath; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionSocketAddress; @@ -61,14 +60,14 @@ public final void run() { private class ClientEndpoint extends AbstractChannelEndpoint { private final Client client; - private final RequestPath path; + private final Path path; private final int nRounds; private final boolean connect; - ClientEndpoint(Client client, int id, RequestPath path, int nRounds, boolean connect) { + ClientEndpoint(Client client, int id, Path requestPath, int nRounds, boolean connect) { super(id); this.client = client; - this.path = path; + this.path = requestPath; this.nRounds = nRounds; this.connect = connect; } @@ -111,7 +110,7 @@ public final void runImpl(ScionDatagramChannel channel) throws IOException { } public interface Client { - void run(ScionDatagramChannel channel, RequestPath path, int id) throws IOException; + void run(ScionDatagramChannel channel, Path path, int id) throws IOException; } public interface Server { diff --git a/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java b/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java index 1b7b62556..01d6e521a 100644 --- a/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java +++ b/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java @@ -24,7 +24,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import org.scion.jpan.RequestPath; +import org.scion.jpan.Path; import org.scion.jpan.Scion; public class PingPongHelperBase { @@ -84,7 +84,7 @@ public InetSocketAddress getLocalAddress() { } interface ClientFactory { - AbstractEndpoint create(int id, RequestPath requestPath, int nRounds); + AbstractEndpoint create(int id, Path requestPath, int nRounds); } interface ServerFactory { @@ -107,7 +107,7 @@ void runPingPong(ServerFactory serverFactory, ClientFactory clientFactory, boole } InetSocketAddress serverAddress = servers[0].getLocalAddress(); MockDNS.install(MockNetwork.TINY_SRV_ISD_AS, serverAddress.getAddress()); - RequestPath requestPath = Scion.defaultService().lookupAndGetPath(serverAddress, null); + Path requestPath = Scion.defaultService().lookupAndGetPath(serverAddress, null); Thread[] clients = new Thread[nClients]; for (int i = 0; i < clients.length; i++) { diff --git a/src/test/java/org/scion/jpan/testutil/PingPongSocketHelper.java b/src/test/java/org/scion/jpan/testutil/PingPongSocketHelper.java index 66cf093df..56539adf8 100644 --- a/src/test/java/org/scion/jpan/testutil/PingPongSocketHelper.java +++ b/src/test/java/org/scion/jpan/testutil/PingPongSocketHelper.java @@ -22,7 +22,6 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; import org.scion.jpan.Path; -import org.scion.jpan.RequestPath; import org.scion.jpan.ScionDatagramSocket; public class PingPongSocketHelper extends PingPongHelperBase { @@ -57,10 +56,10 @@ public final void run() { private class ClientEndpoint extends AbstractSocketEndpoint { private final Client client; - private final RequestPath remoteAddress; + private final Path remoteAddress; private final int nRounds; - ClientEndpoint(Client client, int id, RequestPath remoteAddress, int nRounds) { + ClientEndpoint(Client client, int id, Path remoteAddress, int nRounds) { super(id); this.client = client; this.remoteAddress = remoteAddress; @@ -130,7 +129,7 @@ public final void runImpl() throws IOException { } public interface Client { - void run(ScionDatagramSocket socket, RequestPath path, int id) throws IOException; + void run(ScionDatagramSocket socket, Path requestPath, int id) throws IOException; } public interface Server {