From 7d0d00809fa49f3870b4994fc99b091d832d0d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilmann=20Z=C3=A4schke?= Date: Mon, 27 May 2024 12:58:49 +0200 Subject: [PATCH 1/4] suqash-7 --- .../scion/jpan/AbstractDatagramChannel.java | 55 ++++---- src/main/java/org/scion/jpan/Path.java | 4 + .../org/scion/jpan/ScionDatagramChannel.java | 38 ++++-- .../org/scion/jpan/ScionDatagramSocket.java | 95 ++++++------- .../java/org/scion/jpan/ScionService.java | 27 +++- .../org/scion/jpan/ScionSocketAddress.java | 125 ++++++++++++++++++ src/main/java/org/scion/jpan/ScmpChannel.java | 5 +- .../scion/jpan/internal/HostsFileParser.java | 8 +- .../jpan/internal/ScionHeaderParser.java | 6 +- .../internal/SelectingDatagramChannel.java | 5 +- .../DatagramChannelApiConcurrencyTest.java | 8 +- .../api/DatagramChannelApiServerTest.java | 7 +- .../jpan/api/DatagramChannelApiTest.java | 9 +- .../DatagramChannelMultiSendInetAddrTest.java | 15 ++- .../api/DatagramChannelMultiSendPathTest.java | 11 +- ...nnelMultiWriteConnectedInetSocketTest.java | 9 +- ...ramChannelMultiWriteConnectedPathTest.java | 11 +- .../api/DatagramChannelPathSwitchTest.java | 9 +- .../jpan/api/DatagramChannelStreamTest.java | 11 +- .../scion/jpan/api/DatagramSocketApiTest.java | 13 +- .../DatagramSocketConcurrentPingPongTest.java | 8 +- .../jpan/api/DatagramSocketPingPongTest.java | 8 +- .../jpan/demo/PingPongChannelServer.java | 11 +- .../jpan/internal/HeaderComposeTest.java | 11 +- .../jpan/testutil/PingPongChannelHelper.java | 25 ++-- .../jpan/testutil/PingPongHelperBase.java | 6 +- .../jpan/testutil/PingPongSocketHelper.java | 19 +-- 27 files changed, 368 insertions(+), 191 deletions(-) create mode 100644 src/main/java/org/scion/jpan/ScionSocketAddress.java diff --git a/src/main/java/org/scion/jpan/AbstractDatagramChannel.java b/src/main/java/org/scion/jpan/AbstractDatagramChannel.java index 3c3147bc2..73313b1d9 100644 --- a/src/main/java/org/scion/jpan/AbstractDatagramChannel.java +++ b/src/main/java/org/scion/jpan/AbstractDatagramChannel.java @@ -22,7 +22,6 @@ import java.nio.channels.ClosedChannelException; import java.nio.channels.DatagramChannel; import java.nio.channels.NotYetConnectedException; -import java.time.Instant; import java.util.Objects; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; @@ -180,13 +179,13 @@ public InetSocketAddress getLocalAddress() throws IOException { * Returns the remote address. * * @see DatagramChannel#getRemoteAddress() - * @return The remote address. + * @return The remote address as ScionSocketAddress. * @throws IOException If an I/O error occurs */ - public InetSocketAddress getRemoteAddress() throws IOException { + public ScionSocketAddress getRemoteAddress() throws IOException { Path path = getConnectionPath(); if (path != null) { - return new InetSocketAddress(path.getRemoteAddress(), path.getRemotePort()); + return ScionSocketAddress.fromPath(path); } return null; } @@ -232,6 +231,10 @@ public C connect(SocketAddress addr) throws IOException { throw new IllegalArgumentException( "connect() requires an InetSocketAddress or a ScionSocketAddress."); } + if (addr instanceof ScionSocketAddress) { + // TODO check if this is a RequestPath? + return connect((RequestPath) ((ScionSocketAddress) addr).getPath()); + } return connect(pathPolicy.filter(getOrCreateService().getPaths((InetSocketAddress) addr))); } } @@ -398,13 +401,14 @@ public void setOverrideSourceAddress(InetSocketAddress address) { this.overrideExternalAddress = address; } - protected int sendRaw(ByteBuffer buffer, InetSocketAddress address, Path path) + protected int sendRaw(ByteBuffer buffer, InetSocketAddress firstHop, Path path) throws IOException { if (cfgRemoteDispatcher && path != null && path.getRawPath().length == 0) { + // TODO remove this once dispatcher is removed return channel.send( - buffer, new InetSocketAddress(address.getAddress(), Constants.DISPATCHER_PORT)); + buffer, new InetSocketAddress(firstHop.getAddress(), Constants.DISPATCHER_PORT)); } - return channel.send(buffer, address); + return channel.send(buffer, firstHop); } protected int sendRaw(ByteBuffer buffer, InetSocketAddress address) throws IOException { @@ -534,20 +538,22 @@ protected final ByteBuffer getBufferReceive(int requiredSize) { } /** - * @param path path + * @param dst Destination address * @param payloadLength payload length * @return argument path or a new path if the argument path was expired * @throws IOException in case of IOException. */ - protected Path checkPathAndBuildHeader( - ByteBuffer buffer, Path path, int payloadLength, InternalConstants.HdrTypes hdrType) + protected void checkPathAndBuildHeader( + ByteBuffer buffer, + ScionSocketAddress dst, + int payloadLength, + InternalConstants.HdrTypes hdrType) throws IOException { synchronized (stateLock) { - if (path instanceof RequestPath) { - path = ensureUpToDate((RequestPath) path); + if (dst.isRequestAddress()) { + ensureUpToDate(dst); } - buildHeader(buffer, path, payloadLength, hdrType); - return path; + buildHeader(buffer, dst.getPath(), payloadLength, hdrType); } } @@ -610,8 +616,7 @@ protected void buildHeader( rawPath.length, srcIA, srcAddress.getAddress(), - path.getRemoteIsdAs(), - path.getRemoteAddress().getAddress(), + path, hdrType, cfgTrafficClass); ScionHeaderParser.writePath(buffer, rawPath); @@ -623,17 +628,13 @@ protected void buildHeader( } } - protected RequestPath ensureUpToDate(RequestPath path) throws IOException { + protected void ensureUpToDate(ScionSocketAddress address) throws IOException { synchronized (stateLock) { - if (Instant.now().getEpochSecond() + cfgExpirationSafetyMargin <= path.getExpiration()) { - return path; - } - // expired, get new path - RequestPath newPath = pathPolicy.filter(getOrCreateService().getPaths(path)); - if (isConnected()) { - updateConnection(newPath, true); + if (address.refreshPath(getOrCreateService(), pathPolicy, cfgExpirationSafetyMargin)) { + if (isConnected()) { + updateConnection(address.getPath().asRequestPath(), true); + } } - return newPath; } } @@ -673,4 +674,8 @@ protected ReentrantLock readLock() { protected ReentrantLock writeLock() { return writeLock; } + + protected int getCfgExpirySafetyMargin() { + return cfgExpirationSafetyMargin; + } } diff --git a/src/main/java/org/scion/jpan/Path.java b/src/main/java/org/scion/jpan/Path.java index 898619cec..17a32079a 100644 --- a/src/main/java/org/scion/jpan/Path.java +++ b/src/main/java/org/scion/jpan/Path.java @@ -53,6 +53,10 @@ public long getRemoteIsdAs() { return dstIsdAs; } + RequestPath asRequestPath() { + return (RequestPath) this; + } + @Override public String toString() { return "Path{" diff --git a/src/main/java/org/scion/jpan/ScionDatagramChannel.java b/src/main/java/org/scion/jpan/ScionDatagramChannel.java index 8156d4c22..b37a45d00 100644 --- a/src/main/java/org/scion/jpan/ScionDatagramChannel.java +++ b/src/main/java/org/scion/jpan/ScionDatagramChannel.java @@ -57,7 +57,7 @@ public boolean isBlocking() { return super.isBlocking(); } - public ResponsePath receive(ByteBuffer userBuffer) throws IOException { + public ScionSocketAddress receive(ByteBuffer userBuffer) throws IOException { readLock().lock(); try { ByteBuffer buffer = getBufferReceive(userBuffer.capacity()); @@ -67,7 +67,7 @@ public ResponsePath receive(ByteBuffer userBuffer) throws IOException { } ScionHeaderParser.extractUserPayload(buffer, userBuffer); buffer.clear(); - return receivePath; + return ScionSocketAddress.fromPath(receivePath); } finally { readLock().unlock(); } @@ -84,20 +84,26 @@ public ResponsePath receive(ByteBuffer userBuffer) throws IOException { * cannot be resolved to an ISD/AS. * @see java.nio.channels.DatagramChannel#send(ByteBuffer, SocketAddress) */ - public void send(ByteBuffer srcBuffer, SocketAddress destination) throws IOException { + public int send(ByteBuffer srcBuffer, SocketAddress destination) throws IOException { if (!(destination instanceof InetSocketAddress)) { throw new IllegalArgumentException("Address must be of type InetSocketAddress."); } + if (destination instanceof ScionSocketAddress) { + ScionSocketAddress ssa = (ScionSocketAddress) destination; + send(srcBuffer, ssa); + return 12345; // TODO + } InetSocketAddress dst = (InetSocketAddress) destination; Path path = getPathPolicy().filter(getOrCreateService().getPaths(dst)); - send(srcBuffer, path); + send(srcBuffer, ScionSocketAddress.fromPath(path)); + return 12345; // TODO } /** * Attempts to send the content of the buffer to the destinationAddress. * * @param srcBuffer Data to send - * @param path Path to destination. If this is a Request path and it is expired then it will + * @param address Path to destination. If this is a Request path and it is expired then it will * automatically be replaced with a new path. Expiration of ResponsePaths is not checked * @return either the path argument or a new path if the path was an expired RequestPath. Note * that ResponsePaths are not checked for expiration. @@ -105,27 +111,35 @@ public void send(ByteBuffer srcBuffer, SocketAddress destination) throws IOExcep * cannot be resolved to an ISD/AS. * @see java.nio.channels.DatagramChannel#send(ByteBuffer, SocketAddress) */ - public Path send(ByteBuffer srcBuffer, Path path) throws IOException { + public void send(ByteBuffer srcBuffer, ScionSocketAddress address) throws IOException { writeLock().lock(); try { ByteBuffer buffer = getBufferSend(srcBuffer.remaining()); // + 8 for UDP overlay header length - Path actualPath = - checkPathAndBuildHeader( - buffer, path, srcBuffer.remaining() + 8, InternalConstants.HdrTypes.UDP); + int len = srcBuffer.remaining() + 8; + checkPathAndBuildHeader(buffer, address, len, InternalConstants.HdrTypes.UDP); try { buffer.put(srcBuffer); } catch (BufferOverflowException e) { throw new IOException("Packet is larger than max send buffer size."); } buffer.flip(); - sendRaw(buffer, actualPath.getFirstHopAddress(), actualPath); - return actualPath; + sendRaw(buffer, address.getPath().getFirstHopAddress(), address.getPath()); + // TODO consider TRICK + // - If read()/write() is used then we have no problem, getCurrentPath() works fine + // - receive() always contains a ResponsePath -> cannot expire + // - send() on server -> we have a ResponsePath -> cannot be refreshed + // - send() on client -> we have a RequestPath -> use with getCurrentPath() ??? } finally { writeLock().unlock(); } } + @Deprecated // Please use another send method instead + public void send(ByteBuffer srcBuffer, Path path) throws IOException { + send(srcBuffer, ScionSocketAddress.fromPath(path)); + } + /** * Read data from the connected stream. * @@ -169,7 +183,7 @@ public int write(ByteBuffer src) throws IOException { ByteBuffer buffer = getBufferSend(src.remaining()); int len = src.remaining(); // + 8 for UDP overlay header length - checkPathAndBuildHeader(buffer, getConnectionPath(), len + 8, InternalConstants.HdrTypes.UDP); + checkPathAndBuildHeader(buffer, getRemoteAddress(), len + 8, InternalConstants.HdrTypes.UDP); buffer.put(src); buffer.flip(); diff --git a/src/main/java/org/scion/jpan/ScionDatagramSocket.java b/src/main/java/org/scion/jpan/ScionDatagramSocket.java index b4ccca3f1..73c4644b8 100644 --- a/src/main/java/org/scion/jpan/ScionDatagramSocket.java +++ b/src/main/java/org/scion/jpan/ScionDatagramSocket.java @@ -22,7 +22,6 @@ import java.nio.channels.AlreadyBoundException; import java.nio.channels.DatagramChannel; import java.nio.channels.IllegalBlockingModeException; -import java.time.Instant; import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -56,7 +55,8 @@ public class ScionDatagramSocket extends java.net.DatagramSocket { private final SelectingDatagramChannel channel; private boolean isBound = false; - private final SimpleCache pathCache = new SimpleCache<>(100); + private final SimpleCache pathCache = + new SimpleCache<>(100); private final Object closeLock = new Object(); public ScionDatagramSocket() throws SocketException { @@ -257,7 +257,7 @@ public int getPort() { } @Override - public SocketAddress getRemoteSocketAddress() { + public ScionSocketAddress getRemoteSocketAddress() { try { return channel.getRemoteAddress(); } catch (IOException e) { @@ -283,34 +283,37 @@ public void send(DatagramPacket packet) throws IOException { // Synchronize on packet because this is what the Java DatagramSocket does. synchronized (packet) { - // TODO synchronize also on writeLock()! - if (isConnected() && !channel.getRemoteAddress().equals(packet.getSocketAddress())) { - throw new IllegalArgumentException("Packet address does not match connected address"); - } + channel.writeLock().lock(); + try { + if (isConnected() && !channel.getRemoteAddress().equals(packet.getSocketAddress())) { + throw new IllegalArgumentException("Packet address does not match connected address"); + } - Path path; - if (channel.isConnected()) { - path = channel.getConnectionPath(); - } else { - InetSocketAddress addr = (InetSocketAddress) packet.getSocketAddress(); - synchronized (pathCache) { - path = pathCache.get(addr); - if (path == null) { - path = channel.getPathPolicy().filter(channel.getOrCreateService2().getPaths(addr)); - } else if (path instanceof RequestPath - && ((RequestPath) path).getExpiration() > Instant.now().getEpochSecond()) { - // check expiration only for RequestPaths - RequestPath request = (RequestPath) path; - path = channel.getPathPolicy().filter(channel.getOrCreateService2().getPaths(request)); - } - if (path == null) { - throw new IOException("Address is not resolvable in SCION: " + packet.getAddress()); + ScionSocketAddress dstAddress; + if (channel.isConnected()) { + dstAddress = channel.getRemoteAddress(); + } else { + InetSocketAddress addr = (InetSocketAddress) packet.getSocketAddress(); + synchronized (pathCache) { + dstAddress = pathCache.get(addr); + if (dstAddress == null) { + dstAddress = + channel + .getOrCreateService2() + .lookupSocketAddress(packet.getAddress().getHostName(), packet.getPort()); + } + dstAddress.refreshPath( + channel.getOrCreateService2(), + channel.getPathPolicy(), + channel.getCfgExpirySafetyMargin()); + pathCache.put(addr, dstAddress); } - pathCache.put(addr, path); } + ByteBuffer buf = ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength()); + channel.send(buf, dstAddress); + } finally { + channel.writeLock().unlock(); } - ByteBuffer buf = ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength()); - channel.send(buf, path); } } @@ -321,25 +324,27 @@ public synchronized void receive(DatagramPacket packet) throws IOException { // We synchronize on the packet because that is what the Java socket does. synchronized (packet) { - ByteBuffer receiveBuffer = - ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength()); - ResponsePath path = channel.receive(receiveBuffer); - if (path == null) { - // timeout occurred - throw new SocketTimeoutException(); - } - // TODO this is not ideal, a client may not be connected. Use getService()==null? - if (!channel.isConnected()) { - synchronized (pathCache) { - InetAddress ip = path.getRemoteAddress(); - InetSocketAddress addr = new InetSocketAddress(ip, path.getRemotePort()); - pathCache.put(addr, path); + channel.readLock().lock(); + try { + ByteBuffer receiveBuffer = + ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength()); + ScionSocketAddress path = channel.receive(receiveBuffer); + if (path == null) { + // timeout occurred + throw new SocketTimeoutException(); + } + // TODO this is not ideal, a client may not be connected. Use getService()==null? + if (!channel.isConnected()) { + synchronized (pathCache) { + pathCache.put(path, path); // TODO use Set i.o. Map + } } + receiveBuffer.flip(); + packet.setLength(receiveBuffer.limit()); + packet.setSocketAddress(path); + } finally { + channel.readLock().unlock(); } - receiveBuffer.flip(); - packet.setLength(receiveBuffer.limit()); - packet.setAddress(path.getRemoteAddress()); - packet.setPort(path.getRemotePort()); } } @@ -545,7 +550,7 @@ public RequestPath getConnectionPath() { * @return the cached Path or `null` if not path is found. * @see #setPathCacheCapacity */ - public synchronized Path getCachedPath(InetSocketAddress address) { + public synchronized ScionSocketAddress getCachedPath(InetSocketAddress address) { synchronized (pathCache) { return pathCache.get(address); } diff --git a/src/main/java/org/scion/jpan/ScionService.java b/src/main/java/org/scion/jpan/ScionService.java index 752c82bc8..5b5afc2a1 100644 --- a/src/main/java/org/scion/jpan/ScionService.java +++ b/src/main/java/org/scion/jpan/ScionService.java @@ -299,6 +299,11 @@ List getPathListDaemon(long srcIsdAs, long dstIsdAs) { * @throws IOException if an errors occurs while querying paths. */ public List getPaths(InetSocketAddress dstAddress) throws IOException { + if (dstAddress instanceof ScionSocketAddress + && ((ScionSocketAddress) dstAddress).isRequestAddress()) { + return getPaths(((ScionSocketAddress) dstAddress).getPath().asRequestPath()); + } + // Use getHostString() to avoid DNS reverse lookup. ScionAddress sa = getScionAddress(dstAddress.getHostString()); return getPaths(sa.getIsdAs(), sa.getInetAddress(), dstAddress.getPort()); @@ -369,7 +374,7 @@ public long getLocalIsdAs() { /** * @param hostName hostName of the host to resolve - * @return A ScionAddress + * @return The ISD/AS code for a hostname * @throws ScionException if the DNS/TXT lookup did not return a (valid) SCION address. */ public long getIsdAs(String hostName) throws ScionException { @@ -408,12 +413,30 @@ public long getIsdAs(String hostName) throws ScionException { throw new ScionException("No DNS TXT entry \"scion\" found for host: " + hostName); } + @Deprecated // Please use lookupScionAddress() instead. + public ScionAddress getScionAddress(String hostName) throws ScionException { + return lookupAddress(hostName); + } + /** + * Uses DNS and hostfiles to look up a SCIOn enabled IP address for a give host string. + * + * @param hostName hostName of the host to resolve + * @return A ScionSocketAddress + * @throws ScionException if the DNS/TXT lookup did not return a (valid) SCION address. + */ + public ScionSocketAddress lookupSocketAddress(String hostName, int port) throws ScionException { + return ScionSocketAddress.fromScionAddress(lookupAddress(hostName), port); + } + + /** + * Uses DNS and hostfiles to look up a SCIOn enabled IP address for a give host string. + * * @param hostName hostName of the host to resolve * @return A ScionAddress * @throws ScionException if the DNS/TXT lookup did not return a (valid) SCION address. */ - public ScionAddress getScionAddress(String hostName) throws ScionException { + public ScionAddress lookupAddress(String hostName) throws ScionException { ScionAddress scionAddress = scionAddressCache.get(hostName); if (scionAddress != null) { return scionAddress; diff --git a/src/main/java/org/scion/jpan/ScionSocketAddress.java b/src/main/java/org/scion/jpan/ScionSocketAddress.java new file mode 100644 index 000000000..45774af15 --- /dev/null +++ b/src/main/java/org/scion/jpan/ScionSocketAddress.java @@ -0,0 +1,125 @@ +// Copyright 2024 ETH Zurich +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package org.scion.jpan; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.time.Instant; + +/** + * A ScionSocketAddress is an InetSocketAddress with an attached path. The address part is immutable + * and paths are immutable, but the address can be assigned a new path. This is necessary to allow + * paths to be refreshed once they expire, if the policy changes or if the interface changes. + * + *

The address represents the destination address of the path. + */ +public class ScionSocketAddress extends InetSocketAddress { + + private final long isdAs; + private transient Path path; + + // TODO enable? + // public ScionSocketAddress(long isdAs, String hostname, int port) { + // super(hostname, port); + // this.isdAs = isdAs; + // } + + public ScionSocketAddress(long isdAs, InetAddress addr, int port) { + super(addr, port); + this.isdAs = isdAs; + } + + public ScionSocketAddress(long isdAs, InetSocketAddress addr) { + super(addr.getAddress(), addr.getPort()); + this.isdAs = isdAs; + } + + public static ScionSocketAddress fromPath(Path path) { + ScionSocketAddress a = + new ScionSocketAddress( + path.getRemoteIsdAs(), path.getRemoteAddress(), path.getRemotePort()); + a.path = path; + return a; + } + + public static ScionSocketAddress fromScionAddress(ScionAddress address, int port) { + return new ScionSocketAddress(address.getIsdAs(), address.getInetAddress(), port); + } + + public static ScionSocketAddress fromNonScionIP(InetAddress address, int port) + throws ScionException { + return fromNonScionIP(Scion.defaultService(), address, port); + } + + public static ScionSocketAddress fromNonScionIP( + ScionService service, InetAddress address, int port) throws ScionException { + ScionAddress sa = service.getScionAddress(address.getHostName()); + return new ScionSocketAddress(sa.getIsdAs(), sa.getInetAddress(), port); + } + + public static ScionSocketAddress fromScionIP(long isdAs, InetAddress address, int port) { + return new ScionSocketAddress(isdAs, address, port); + } + + /** + * @return the path currently associated with this address. May return 'null'. + */ + public Path getPath() { + return this.path; + } + + /** + * @param service Service for obtaining new paths when required + * @param pathPolicy PathPolicy for selecting a new path when required + * @param expiryMargin Expiry margin, i.e. a path is considered "expired" if expiry is less than + * expiryMargin seconds away. + * @return `false` if the path is `null`, it it is a ResponsePath or if it didn't need updating. + * Returns `true` only if the path was updated. + */ + synchronized boolean refreshPath(ScionService service, PathPolicy pathPolicy, int expiryMargin) + throws IOException { + if (path == null) { + path = pathPolicy.filter(service.getPaths(this)); + if (path == null) { + throw new IOException("Address is not resolvable in SCION: " + super.toString()); + } + return true; + } + + if (!(path instanceof RequestPath)) { + return false; + } + + RequestPath requestPath = (RequestPath) path; + if (Instant.now().getEpochSecond() + expiryMargin <= requestPath.getExpiration()) { + return false; + } + // expired, get new path + path = pathPolicy.filter(service.getPaths(requestPath)); + return true; + } + + /** + * @return 'true' iff the path associated with this address is an instance of RequestPath. + */ + public boolean isRequestAddress() { + return path instanceof RequestPath; + } + + public long getIsdAs() { + return isdAs; + } +} diff --git a/src/main/java/org/scion/jpan/ScmpChannel.java b/src/main/java/org/scion/jpan/ScmpChannel.java index 458c63faa..387021e72 100644 --- a/src/main/java/org/scion/jpan/ScmpChannel.java +++ b/src/main/java/org/scion/jpan/ScmpChannel.java @@ -141,7 +141,8 @@ private void sendScmpRequest(IOCallable sender, Scmp.TypeCode } else if (result.isTimedOut()) { result.setNanoSeconds(timeOutMs * 1_000_000L); } else { - throw new IOException("SCMP error: " + result.getTypeCode().getText()); + throw new IOException( + "SCMP error: " + result.getTypeCode() + " " + result.getTypeCode().getText()); } } @@ -407,7 +408,7 @@ public InetSocketAddress getLocalAddress() throws IOException { return channel.getLocalAddress(); } - public InetSocketAddress getRemoteAddress() throws IOException { + public ScionSocketAddress getRemoteAddress() throws IOException { return channel.getRemoteAddress(); } diff --git a/src/main/java/org/scion/jpan/internal/HostsFileParser.java b/src/main/java/org/scion/jpan/internal/HostsFileParser.java index 84d239185..e45e4a2f6 100644 --- a/src/main/java/org/scion/jpan/internal/HostsFileParser.java +++ b/src/main/java/org/scion/jpan/internal/HostsFileParser.java @@ -97,7 +97,7 @@ private void parseLine(String line, Path path) { check(lineParts.length >= 2, "Expected ` `"); String[] addrParts = lineParts[0].split(","); check(addrParts.length == 2, "Expected `,`"); - long isdIa = ScionUtil.parseIA(addrParts[0]); + long isdAs = ScionUtil.parseIA(addrParts[0]); check(addrParts[1].startsWith("["), "Expected `[` before address"); check(addrParts[1].endsWith("]"), "Expected `]` after address"); String addrStr = addrParts[1].substring(1, addrParts[1].length() - 1).trim(); @@ -112,13 +112,13 @@ private void parseLine(String line, Path path) { break; } InetAddress inetAddr = InetAddress.getByAddress(hostName, addrBytes); - entries.put(hostName, new HostEntry(isdIa, inetAddr)); + entries.put(hostName, new HostEntry(isdAs, inetAddr)); } InetAddress inetAddr = InetAddress.getByAddress(addrStr, addrBytes); // Use original address string as key - entries.put(addrStr, new HostEntry(isdIa, inetAddr)); + entries.put(addrStr, new HostEntry(isdAs, inetAddr)); // Use "normalized" address string as key (these may differ fo IPv6) - entries.put(inetAddr.getHostAddress(), new HostEntry(isdIa, inetAddr)); + entries.put(inetAddr.getHostAddress(), new HostEntry(isdAs, inetAddr)); } catch (IndexOutOfBoundsException | IllegalArgumentException | UnknownHostException e) { LOG.info("ERROR parsing file {}: error=\"{}\" line=\"{}\"", path, e.getMessage(), line); } diff --git a/src/main/java/org/scion/jpan/internal/ScionHeaderParser.java b/src/main/java/org/scion/jpan/internal/ScionHeaderParser.java index 2fed33a17..1b1b38bf1 100644 --- a/src/main/java/org/scion/jpan/internal/ScionHeaderParser.java +++ b/src/main/java/org/scion/jpan/internal/ScionHeaderParser.java @@ -17,6 +17,7 @@ import java.net.*; import java.nio.ByteBuffer; import org.scion.jpan.Constants; +import org.scion.jpan.Path; import org.scion.jpan.ResponsePath; import org.scion.jpan.Scmp; @@ -366,10 +367,11 @@ public static void write( int pathHeaderLength, long srcIsdAs, byte[] srcAddress, - long dstIsdAs, - byte[] dstAddress, + Path path, InternalConstants.HdrTypes hdrType, int trafficClass) { + long dstIsdAs = path.getRemoteIsdAs(); + byte[] dstAddress = path.getRemoteAddress().getAddress(); int sl = srcAddress.length / 4 - 1; int dl = dstAddress.length / 4 - 1; diff --git a/src/main/java/org/scion/jpan/internal/SelectingDatagramChannel.java b/src/main/java/org/scion/jpan/internal/SelectingDatagramChannel.java index 264e805f7..02e374da4 100644 --- a/src/main/java/org/scion/jpan/internal/SelectingDatagramChannel.java +++ b/src/main/java/org/scion/jpan/internal/SelectingDatagramChannel.java @@ -24,6 +24,7 @@ import org.scion.jpan.ResponsePath; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; +import org.scion.jpan.ScionSocketAddress; /** * DatagramChannel with support for timeout. @@ -89,7 +90,7 @@ private ResponsePath receiveFromTimeoutChannel( } @Override - public ResponsePath receive(ByteBuffer userBuffer) throws IOException { + public ScionSocketAddress receive(ByteBuffer userBuffer) throws IOException { readLock().lock(); try { ByteBuffer buffer = getBufferReceive(userBuffer.capacity()); @@ -99,7 +100,7 @@ public ResponsePath receive(ByteBuffer userBuffer) throws IOException { } ScionHeaderParser.extractUserPayload(buffer, userBuffer); buffer.clear(); - return receivePath; + return ScionSocketAddress.fromPath(receivePath); } finally { readLock().unlock(); } diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelApiConcurrencyTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelApiConcurrencyTest.java index 9bc616c32..70fbb3c41 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelApiConcurrencyTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelApiConcurrencyTest.java @@ -26,9 +26,9 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.scion.jpan.ResponsePath; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; +import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.MockDNS; import org.scion.jpan.testutil.MockDaemon; @@ -128,8 +128,8 @@ private void concurrentReceive(Reader c1, Reader c2, Writer w1, boolean connect) } // check that receive is responsive - ResponsePath path = server.receive(buffer); - server.send(buffer, path); + ScionSocketAddress remote = server.receive(buffer); + server.send(buffer, remote); // wait synchronized (receiveCount) { receiveCount.wait(1000); @@ -138,7 +138,7 @@ private void concurrentReceive(Reader c1, Reader c2, Writer w1, boolean connect) // send again to trigger 2nd receiver buffer.flip(); - server.send(buffer, path); + server.send(buffer, remote); // wait synchronized (receiveCount) { receiveCount.wait(1000); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java index 50d00e1e4..177d2fc15 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java @@ -85,9 +85,8 @@ void send_withoutService() throws IOException { new byte[4], 1, new InetSocketAddress("127.0.0.1", 1)); - Path p2 = channel.send(ByteBuffer.allocate(0), path); + channel.send(ByteBuffer.allocate(0), path); assertNull(channel.getService()); - assertEquals(path, p2); } } @@ -104,9 +103,9 @@ void receive_withoutService() throws IOException { try (ScionDatagramChannel channel = ScionDatagramChannel.open(null, mock)) { assertNull(channel.getService()); ByteBuffer buffer = ByteBuffer.allocate(100); - Path path = channel.receive(buffer); + ScionSocketAddress remote = channel.receive(buffer); assertNull(channel.getService()); - assertEquals(addr, path.getFirstHopAddress()); + assertEquals(addr, remote.getPath().getFirstHopAddress()); } } } diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java index e174854e1..6ee51786d 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java @@ -472,7 +472,9 @@ void send_disconnected_expiredRequestPath() throws IOException { (channel, expiredPath) -> { ByteBuffer sendBuf = ByteBuffer.wrap(PingPongChannelHelper.MSG.getBytes()); try { - RequestPath newPath = (RequestPath) channel.send(sendBuf, expiredPath); + ScionSocketAddress dst = ScionSocketAddress.fromPath(expiredPath); + channel.send(sendBuf, dst); + RequestPath newPath = (RequestPath) dst.getPath(); assertTrue(newPath.getExpiration() > expiredPath.getExpiration()); assertTrue(Instant.now().getEpochSecond() < newPath.getExpiration()); assertNull(channel.getConnectionPath()); @@ -490,7 +492,8 @@ void send_connected_expiredRequestPath() throws IOException { (channel, expiredPath) -> { ByteBuffer sendBuf = ByteBuffer.wrap(PingPongChannelHelper.MSG.getBytes()); try { - RequestPath newPath = (RequestPath) channel.send(sendBuf, expiredPath); + channel.send(sendBuf, expiredPath); + RequestPath newPath = (RequestPath) channel.getConnectionPath(); assertTrue(newPath.getExpiration() > expiredPath.getExpiration()); assertTrue(Instant.now().getEpochSecond() < newPath.getExpiration()); assertEquals(newPath, channel.getConnectionPath()); @@ -527,7 +530,7 @@ private void testExpired( PingPongChannelHelper.Client clientFn = (channel, basePath, id) -> { // Build a path that is already expired - RequestPath expiredPath = createExpiredPath(basePath); + RequestPath expiredPath = createExpiredPath(basePath.getPath()); sendMethod.accept(channel, expiredPath); ByteBuffer response = ByteBuffer.allocate(100); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendInetAddrTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendInetAddrTest.java index 0122e69d8..313ac8970 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendInetAddrTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendInetAddrTest.java @@ -23,9 +23,9 @@ import java.nio.charset.Charset; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; +import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.PingPongChannelHelper; /** Test receive()/send(InetAddress) operations on DatagramChannel. */ @@ -45,21 +45,22 @@ void test() { pph.runPingPong(serverFn, clientFn); } - private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { + private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) + throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); // Test send() with InetAddress - InetAddress inetServerAddress = serverAddress.getRemoteAddress(); + InetAddress inetServerAddress = serverAddress.getAddress(); InetSocketAddress inetServerSocketAddress = - new InetSocketAddress(inetServerAddress, serverAddress.getRemotePort()); + new InetSocketAddress(inetServerAddress, serverAddress.getPort()); channel.send(sendBuf, inetServerSocketAddress); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); ByteBuffer response = ByteBuffer.allocate(512); - Path address = channel.receive(response); + ScionSocketAddress address = channel.receive(response); assertNotNull(address); - assertEquals(serverAddress.getRemoteAddress(), address.getRemoteAddress()); - assertEquals(serverAddress.getRemotePort(), address.getRemotePort()); + assertEquals(serverAddress.getAddress(), address.getAddress()); + assertEquals(serverAddress.getPort(), address.getPort()); response.flip(); String pong = Charset.defaultCharset().decode(response).toString(); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendPathTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendPathTest.java index bdcc191bb..f78450ed6 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendPathTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendPathTest.java @@ -21,9 +21,9 @@ import java.nio.charset.Charset; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; +import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.PingPongChannelHelper; /** Test receive()/send(Path) operations on DatagramChannel. */ @@ -43,17 +43,18 @@ void test() { pph.runPingPong(serverFn, clientFn); } - private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { + private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) + throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); channel.send(sendBuf, serverAddress); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); ByteBuffer response = ByteBuffer.allocate(512); - Path address = channel.receive(response); + ScionSocketAddress address = channel.receive(response); assertNotNull(address); - assertEquals(serverAddress.getRemoteAddress(), address.getRemoteAddress()); - assertEquals(serverAddress.getRemotePort(), address.getRemotePort()); + assertEquals(serverAddress.getAddress(), address.getAddress()); + assertEquals(serverAddress.getPort(), address.getPort()); response.flip(); String pong = Charset.defaultCharset().decode(response).toString(); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedInetSocketTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedInetSocketTest.java index c950eb29c..34d54227b 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedInetSocketTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedInetSocketTest.java @@ -23,9 +23,9 @@ import java.nio.charset.Charset; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; +import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.PingPongChannelHelper; /** Test read()/write() operations on DatagramChannel connected with an InetSocketAddress. */ @@ -45,14 +45,15 @@ void test() { pph.runPingPong(serverFn, clientFn); } - private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { + private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) + throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); channel.disconnect(); // Test send() with InetAddress - InetAddress inetAddress = serverAddress.getRemoteAddress(); + InetAddress inetAddress = serverAddress.getAddress(); InetSocketAddress inetServerSocketAddress = - new InetSocketAddress(inetAddress, serverAddress.getRemotePort()); + new InetSocketAddress(inetAddress, serverAddress.getPort()); channel.connect(inetServerSocketAddress); assertTrue(channel.isConnected()); channel.write(sendBuf); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java index dccb0c6a1..be1db95cc 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java @@ -21,10 +21,7 @@ import java.nio.charset.Charset; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.Path; -import org.scion.jpan.RequestPath; -import org.scion.jpan.ScionDatagramChannel; -import org.scion.jpan.ScionService; +import org.scion.jpan.*; import org.scion.jpan.testutil.PingPongChannelHelper; /** Test read()/write() operations on DatagramChannel connected with a path. */ @@ -46,7 +43,7 @@ void test() { pph.runPingPong(serverFn, clientFn); } - private void client(ScionDatagramChannel channel, RequestPath serverAddress, int id) + private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) throws IOException { String message = MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); @@ -68,7 +65,7 @@ private void client(ScionDatagramChannel channel, RequestPath serverAddress, int private void server(ScionDatagramChannel channel) throws IOException { ByteBuffer request = ByteBuffer.allocate(512); // System.out.println("SERVER: --- USER - Waiting for packet --------------------- " + i); - Path path = channel.receive(request); + ScionSocketAddress remote = channel.receive(request); request.flip(); String msg = Charset.defaultCharset().decode(request).toString(); @@ -77,6 +74,6 @@ private void server(ScionDatagramChannel channel) throws IOException { // System.out.println("SERVER: --- USER - Sending packet ---------------------- " + i); request.flip(); - channel.send(request, path); + channel.send(request, remote); } } diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java index d80f9a81d..309f54103 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java @@ -22,11 +22,7 @@ import java.util.List; import org.junit.jupiter.api.AfterAll; 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.*; import org.scion.jpan.testutil.MockNetwork; import org.scion.jpan.testutil.PingPongChannelHelper; @@ -60,7 +56,8 @@ void test() { assertEquals(2 * 2 * 10, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { + private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) + throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelStreamTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelStreamTest.java index 71e2376e6..2f9bce7e3 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelStreamTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelStreamTest.java @@ -22,9 +22,9 @@ import java.util.ArrayList; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; +import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.MockNetwork; import org.scion.jpan.testutil.PingPongChannelHelper; @@ -48,7 +48,8 @@ void test() { assertEquals(2 * 2 * 2 * N_BULK, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { + private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) + throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); @@ -71,10 +72,10 @@ private void client(ScionDatagramChannel channel, Path serverAddress, int id) th } private static class Pair { - Path path; + ScionSocketAddress path; String msg; - Pair(Path path, String msg) { + Pair(ScionSocketAddress path, String msg) { this.path = path; this.msg = msg; } @@ -88,7 +89,7 @@ public void server(ScionDatagramChannel channel) throws IOException { ArrayList received = new ArrayList<>(); for (int i = 0; i < N_BULK; i++) { request.clear(); - Path returnAddress = channel.receive(request); + ScionSocketAddress returnAddress = channel.receive(request); request.flip(); String msg = Charset.defaultCharset().decode(request).toString(); received.add(new Pair(returnAddress, msg)); diff --git a/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java b/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java index f43564973..0d5f9da4e 100644 --- a/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java @@ -634,7 +634,7 @@ private void testExpired(BiConsumer sendMethod PingPongSocketHelper.Client clientFn = (channel, basePath, id) -> { // Build a path that is already expired - RequestPath expiredPath = createExpiredPath(basePath); + RequestPath expiredPath = createExpiredPath(basePath.getPath()); sendMethod.accept(channel, expiredPath); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); @@ -668,6 +668,11 @@ private static InetSocketAddress toAddress(Path path) { return new InetSocketAddress(path.getRemoteAddress(), path.getRemotePort()); } + private static InetSocketAddress toAddress(ScionSocketAddress path) { + // TODO do we need this? For Proper equals()? + return new InetSocketAddress(path.getAddress(), path.getPort()); + } + @Test void getConnectionPath() throws IOException { RequestPath path = ExamplePacket.PATH; @@ -776,7 +781,8 @@ void testPathCache() throws IOException { server.receive(packet1); assertEquals(clientAddress1, packet1.getSocketAddress()); - Path path1 = server.getCachedPath((InetSocketAddress) packet1.getSocketAddress()); + ScionSocketAddress path1 = + server.getCachedPath((InetSocketAddress) packet1.getSocketAddress()); assertEquals(clientAddress1, toAddress(path1)); // 2nd client @@ -800,7 +806,8 @@ void testPathCache() throws IOException { path1 = server.getCachedPath((InetSocketAddress) packet1.getSocketAddress()); assertEquals(clientAddress1, toAddress(path1)); // path 2 should also be there - Path path2 = server.getCachedPath((InetSocketAddress) packet2.getSocketAddress()); + ScionSocketAddress path2 = + server.getCachedPath((InetSocketAddress) packet2.getSocketAddress()); assertEquals(clientAddress2, toAddress(path2)); // reduce capacity diff --git a/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java b/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java index 94a19c2dc..cdfa647ae 100644 --- a/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java @@ -23,9 +23,9 @@ 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.ScionDatagramSocket; import org.scion.jpan.ScionService; +import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.MockNetwork; import org.scion.jpan.testutil.PingPongSocketHelper; @@ -59,12 +59,10 @@ void test() throws IOException { assertEquals(2 * 10 * 10, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramSocket socket, RequestPath requestPath, int id) + private void client(ScionDatagramSocket socket, ScionSocketAddress requestPath, int id) throws IOException { byte[] sendBuf = MSG.getBytes(); - InetAddress addr = requestPath.getRemoteAddress(); - int port = requestPath.getRemotePort(); - DatagramPacket request = new DatagramPacket(sendBuf, sendBuf.length, addr, port); + DatagramPacket request = new DatagramPacket(sendBuf, sendBuf.length, requestPath); socket.send(request); // System.out.println("CLIENT: Sent ... (" + request.getSocketAddress() + ")"); diff --git a/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java b/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java index e5680309c..2a1d7ccfa 100644 --- a/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java @@ -21,9 +21,9 @@ import java.net.*; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.RequestPath; import org.scion.jpan.ScionDatagramSocket; import org.scion.jpan.ScionService; +import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.MockNetwork; import org.scion.jpan.testutil.PingPongSocketHelper; @@ -44,12 +44,10 @@ void test() { assertEquals(2 * 10 * 10, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramSocket socket, RequestPath requestPath, int id) + private void client(ScionDatagramSocket socket, ScionSocketAddress requestPath, int id) throws IOException { byte[] sendBuf = MSG.getBytes(); - InetAddress addr = requestPath.getRemoteAddress(); - int port = requestPath.getRemotePort(); - DatagramPacket request = new DatagramPacket(sendBuf, sendBuf.length, addr, port); + DatagramPacket request = new DatagramPacket(sendBuf, sendBuf.length, requestPath); socket.send(request); // System.out.println("CLIENT: Receiving ... (" + socket.getLocalSocketAddress() + ")"); diff --git a/src/test/java/org/scion/jpan/demo/PingPongChannelServer.java b/src/test/java/org/scion/jpan/demo/PingPongChannelServer.java index 57e064a70..f3c72a565 100644 --- a/src/test/java/org/scion/jpan/demo/PingPongChannelServer.java +++ b/src/test/java/org/scion/jpan/demo/PingPongChannelServer.java @@ -17,8 +17,8 @@ import java.io.*; import java.net.*; import java.nio.ByteBuffer; -import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; +import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.ScionUtil; public class PingPongChannelServer { @@ -54,14 +54,13 @@ private static void service() throws IOException { channel.bind(SERVER_ADDRESS); ByteBuffer buffer = ByteBuffer.allocate(100); println("Waiting for packet ... "); - Path path = channel.receive(buffer); + ScionSocketAddress remote = channel.receive(buffer); String msg = extractMessage(buffer); - String remoteAddress = path.getRemoteAddress() + ":" + path.getRemotePort(); - String borderRouterInterfaces = ScionUtil.toStringPath(path.getRawPath()); - println("Received (from " + remoteAddress + ") via " + borderRouterInterfaces + "): " + msg); + String borderRouterInterfaces = ScionUtil.toStringPath(remote.getPath().getRawPath()); + println("Received (from " + remote + ") via " + borderRouterInterfaces + "): " + msg); String msgAnswer = "Re: " + msg; - channel.send(ByteBuffer.wrap(msgAnswer.getBytes()), path); + channel.send(ByteBuffer.wrap(msgAnswer.getBytes()), remote); println("Sent answer: " + msgAnswer); } } diff --git a/src/test/java/org/scion/jpan/internal/HeaderComposeTest.java b/src/test/java/org/scion/jpan/internal/HeaderComposeTest.java index 6671446fd..854fbff85 100644 --- a/src/test/java/org/scion/jpan/internal/HeaderComposeTest.java +++ b/src/test/java/org/scion/jpan/internal/HeaderComposeTest.java @@ -23,6 +23,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.scion.jpan.RequestPath; import org.scion.jpan.Scion; import org.scion.jpan.ScionService; import org.scion.jpan.ScionUtil; @@ -81,20 +82,20 @@ void testCompose() throws IOException { // Socket internal - compose header data pathService = Scion.newServiceWithDaemon(MockDaemon.DEFAULT_ADDRESS_STR); long srcIA = pathService.getLocalIsdAs(); - byte[] path = pathService.getPaths(dstIA, dstSocketAddress).get(0).getRawPath(); + RequestPath path = pathService.getPaths(dstIA, dstSocketAddress).get(0); + byte[] pathRaw = path.getRawPath(); // Socket internal = write header ScionHeaderParser.write( p, userPacket.limit() + 8, - path.length, + pathRaw.length, srcIA, srcAddress, - dstIA, - dstAddress, + path, InternalConstants.HdrTypes.UDP, 0); - ScionHeaderParser.writePath(p, path); + ScionHeaderParser.writePath(p, path.getRawPath()); // Overlay header ScionHeaderParser.writeUdpOverlayHeader(p, userPacket.limit(), 44444, dstPort); diff --git a/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java b/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java index ad2678b03..f1ddafd6a 100644 --- a/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java +++ b/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java @@ -20,9 +20,8 @@ import java.net.*; 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; public class PingPongChannelHelper extends PingPongHelperBase { @@ -60,11 +59,11 @@ public final void run() { private class ClientEndpoint extends AbstractChannelEndpoint { private final Client client; - private final RequestPath path; + private final ScionSocketAddress 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, ScionSocketAddress path, int nRounds, boolean connect) { super(id); this.client = client; this.path = path; @@ -75,9 +74,7 @@ private class ClientEndpoint extends AbstractChannelEndpoint { @Override public final void runImpl(ScionDatagramChannel channel) throws IOException { if (connect) { - InetAddress inetAddress = path.getRemoteAddress(); - InetSocketAddress iSAddress = new InetSocketAddress(inetAddress, path.getRemotePort()); - channel.connect(iSAddress); + channel.connect(path); } registerStartUpClient(); for (int i = 0; i < nRounds; i++) { @@ -110,7 +107,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, ScionSocketAddress path, int id) throws IOException; } public interface Server { @@ -128,18 +125,18 @@ public void runPingPong(Server serverFn, Client clientFn, boolean reset) { reset); } - public static void defaultClient(ScionDatagramChannel channel, Path serverAddress, int id) - throws IOException { + public static void defaultClient( + ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); channel.send(sendBuf, serverAddress); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); ByteBuffer response = ByteBuffer.allocate(512); - Path address = channel.receive(response); + ScionSocketAddress address = channel.receive(response); assertNotNull(address); - assertEquals(serverAddress.getRemoteAddress(), address.getRemoteAddress()); - assertEquals(serverAddress.getRemotePort(), address.getRemotePort()); + assertEquals(serverAddress.getAddress(), address.getAddress()); + assertEquals(serverAddress.getPort(), address.getPort()); response.flip(); String pong = Charset.defaultCharset().decode(response).toString(); @@ -149,7 +146,7 @@ public static void defaultClient(ScionDatagramChannel channel, Path serverAddres public static void defaultServer(ScionDatagramChannel channel) throws IOException { ByteBuffer request = ByteBuffer.allocate(512); // System.out.println("SERVER: Receiving ... (" + channel.getLocalAddress() + ")"); - Path address = channel.receive(request); + ScionSocketAddress address = channel.receive(request); request.flip(); String msg = Charset.defaultCharset().decode(request).toString(); diff --git a/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java b/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java index 73448d320..b94aa2058 100644 --- a/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java +++ b/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java @@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.scion.jpan.RequestPath; import org.scion.jpan.Scion; +import org.scion.jpan.ScionSocketAddress; public class PingPongHelperBase { @@ -84,7 +85,7 @@ public InetSocketAddress getLocalAddress() { } interface ClientFactory { - AbstractEndpoint create(int id, RequestPath requestPath, int nRounds); + AbstractEndpoint create(int id, ScionSocketAddress requestPath, int nRounds); } interface ServerFactory { @@ -107,7 +108,8 @@ void runPingPong(ServerFactory serverFactory, ClientFactory clientFactory, boole } InetSocketAddress serverAddress = servers[0].getLocalAddress(); MockDNS.install(MockNetwork.TINY_SRV_ISD_AS, serverAddress.getAddress()); - RequestPath scionAddress = Scion.defaultService().getPaths(serverAddress).get(0); + RequestPath path = Scion.defaultService().getPaths(serverAddress).get(0); + ScionSocketAddress scionAddress = ScionSocketAddress.fromPath(path); 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..113085231 100644 --- a/src/test/java/org/scion/jpan/testutil/PingPongSocketHelper.java +++ b/src/test/java/org/scion/jpan/testutil/PingPongSocketHelper.java @@ -21,9 +21,8 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.charset.Charset; -import org.scion.jpan.Path; -import org.scion.jpan.RequestPath; import org.scion.jpan.ScionDatagramSocket; +import org.scion.jpan.ScionSocketAddress; 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 ScionSocketAddress remoteAddress; private final int nRounds; - ClientEndpoint(Client client, int id, RequestPath remoteAddress, int nRounds) { + ClientEndpoint(Client client, int id, ScionSocketAddress remoteAddress, int nRounds) { super(id); this.client = client; this.remoteAddress = remoteAddress; @@ -71,10 +70,7 @@ private class ClientEndpoint extends AbstractSocketEndpoint { public final void runImpl() throws IOException { try (ScionDatagramSocket socket = new ScionDatagramSocket()) { registerStartUpClient(); - InetAddress ipAddress = remoteAddress.getRemoteAddress(); - InetSocketAddress iSAddress = - new InetSocketAddress(ipAddress, remoteAddress.getRemotePort()); - socket.connect(iSAddress); + socket.connect(remoteAddress); for (int i = 0; i < nRounds; i++) { client.run(socket, remoteAddress, id); nRoundsClient.incrementAndGet(); @@ -130,7 +126,7 @@ public final void runImpl() throws IOException { } public interface Client { - void run(ScionDatagramSocket socket, RequestPath path, int id) throws IOException; + void run(ScionDatagramSocket socket, ScionSocketAddress path, int id) throws IOException; } public interface Server { @@ -162,12 +158,11 @@ public void runPingPongSharedServerSocket( } } - public static void defaultClient(ScionDatagramSocket socket, Path path, int id) + public static void defaultClient(ScionDatagramSocket socket, ScionSocketAddress path, int id) throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; - InetSocketAddress dst = new InetSocketAddress(path.getRemoteAddress(), path.getRemotePort()); - DatagramPacket packetOut = new DatagramPacket(message.getBytes(), message.length(), dst); + DatagramPacket packetOut = new DatagramPacket(message.getBytes(), message.length(), path); socket.send(packetOut); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); From 4dd3bc2656502d85c66d2700c58dfa8f1e24fb74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilmann=20Z=C3=A4schke?= Date: Wed, 29 May 2024 15:43:52 +0200 Subject: [PATCH 2/4] mvn exec --- CHANGELOG.md | 1 + README.md | 2 ++ pom.xml | 10 ++++++++++ src/test/java/org/scion/jpan/demo/ScmpEchoDemo.java | 1 + .../java/org/scion/jpan/demo/ScmpTracerouteDemo.java | 1 + src/test/java/org/scion/jpan/demo/ShowpathsDemo.java | 1 + 6 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d8c2d0c5..ae723264d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Added - SCMP echo responder [#78](https://github.com/scionproto-contrib/jpan/pull/78) +- Maven Java executor [#79](https://github.com/scionproto-contrib/jpan/pull/79) ### Changed - Some API changes: [#67](https://github.com/scionproto-contrib/jpan/pull/67) diff --git a/README.md b/README.md index a67537f95..5267e934e 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,8 @@ Before running the demos, you may have to execute `mvn compile` once. - [SCMP traceroute](src/test/java/org/scion/jpan/demo/ScmpTracerouteDemo.java) - [show paths](src/test/java/org/scion/jpan/demo/ShowpathsDemo.java) +After compilation, demos can be executed from the IDE (recommended) or from command line. +For example: `mvn exec:java -Dexec.mainClass="org.scion.jpan.demo.ScmpEchoDemo"`. ### General documentation diff --git a/pom.xml b/pom.xml index fdafbb736..bb721c175 100644 --- a/pom.xml +++ b/pom.xml @@ -319,6 +319,16 @@ + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + test + false + + diff --git a/src/test/java/org/scion/jpan/demo/ScmpEchoDemo.java b/src/test/java/org/scion/jpan/demo/ScmpEchoDemo.java index 47feefc97..b85d2dcec 100644 --- a/src/test/java/org/scion/jpan/demo/ScmpEchoDemo.java +++ b/src/test/java/org/scion/jpan/demo/ScmpEchoDemo.java @@ -100,6 +100,7 @@ public static void main(String[] args) throws IOException { break; } } + Scion.closeDefault(); } private void runDemo(long dstIA, InetSocketAddress dstAddress) throws IOException { diff --git a/src/test/java/org/scion/jpan/demo/ScmpTracerouteDemo.java b/src/test/java/org/scion/jpan/demo/ScmpTracerouteDemo.java index f04f03f78..db8d230d9 100644 --- a/src/test/java/org/scion/jpan/demo/ScmpTracerouteDemo.java +++ b/src/test/java/org/scion/jpan/demo/ScmpTracerouteDemo.java @@ -83,6 +83,7 @@ public static void main(String[] args) throws IOException { break; } } + Scion.closeDefault(); } private void runDemo(long destinationIA) throws IOException { diff --git a/src/test/java/org/scion/jpan/demo/ShowpathsDemo.java b/src/test/java/org/scion/jpan/demo/ShowpathsDemo.java index 6aa458d8c..9510b54ca 100644 --- a/src/test/java/org/scion/jpan/demo/ShowpathsDemo.java +++ b/src/test/java/org/scion/jpan/demo/ShowpathsDemo.java @@ -83,6 +83,7 @@ public static void main(String[] args) throws IOException { break; } } + Scion.closeDefault(); } private void runDemo(long destinationIA) throws IOException { From 47c71dcd1999f0d236110e5ece4970d39c2380db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilmann=20Z=C3=A4schke?= Date: Wed, 29 May 2024 15:53:39 +0200 Subject: [PATCH 3/4] cleanup --- .../scion/jpan/AbstractDatagramChannel.java | 55 ++++---- src/main/java/org/scion/jpan/Path.java | 4 - .../org/scion/jpan/ScionDatagramChannel.java | 38 ++---- .../org/scion/jpan/ScionDatagramSocket.java | 95 +++++++------ .../java/org/scion/jpan/ScionService.java | 27 +--- .../org/scion/jpan/ScionSocketAddress.java | 125 ------------------ src/main/java/org/scion/jpan/ScmpChannel.java | 5 +- .../scion/jpan/internal/HostsFileParser.java | 8 +- .../jpan/internal/ScionHeaderParser.java | 6 +- .../internal/SelectingDatagramChannel.java | 5 +- .../DatagramChannelApiConcurrencyTest.java | 8 +- .../api/DatagramChannelApiServerTest.java | 7 +- .../jpan/api/DatagramChannelApiTest.java | 9 +- .../DatagramChannelMultiSendInetAddrTest.java | 15 +-- .../api/DatagramChannelMultiSendPathTest.java | 11 +- ...nnelMultiWriteConnectedInetSocketTest.java | 9 +- ...ramChannelMultiWriteConnectedPathTest.java | 11 +- .../api/DatagramChannelPathSwitchTest.java | 9 +- .../jpan/api/DatagramChannelStreamTest.java | 11 +- .../scion/jpan/api/DatagramSocketApiTest.java | 13 +- .../DatagramSocketConcurrentPingPongTest.java | 8 +- .../jpan/api/DatagramSocketPingPongTest.java | 8 +- .../jpan/demo/PingPongChannelServer.java | 11 +- .../jpan/internal/HeaderComposeTest.java | 11 +- .../jpan/testutil/PingPongChannelHelper.java | 25 ++-- .../jpan/testutil/PingPongHelperBase.java | 6 +- .../jpan/testutil/PingPongSocketHelper.java | 19 ++- 27 files changed, 191 insertions(+), 368 deletions(-) delete mode 100644 src/main/java/org/scion/jpan/ScionSocketAddress.java diff --git a/src/main/java/org/scion/jpan/AbstractDatagramChannel.java b/src/main/java/org/scion/jpan/AbstractDatagramChannel.java index 73313b1d9..3c3147bc2 100644 --- a/src/main/java/org/scion/jpan/AbstractDatagramChannel.java +++ b/src/main/java/org/scion/jpan/AbstractDatagramChannel.java @@ -22,6 +22,7 @@ import java.nio.channels.ClosedChannelException; import java.nio.channels.DatagramChannel; import java.nio.channels.NotYetConnectedException; +import java.time.Instant; import java.util.Objects; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; @@ -179,13 +180,13 @@ public InetSocketAddress getLocalAddress() throws IOException { * Returns the remote address. * * @see DatagramChannel#getRemoteAddress() - * @return The remote address as ScionSocketAddress. + * @return The remote address. * @throws IOException If an I/O error occurs */ - public ScionSocketAddress getRemoteAddress() throws IOException { + public InetSocketAddress getRemoteAddress() throws IOException { Path path = getConnectionPath(); if (path != null) { - return ScionSocketAddress.fromPath(path); + return new InetSocketAddress(path.getRemoteAddress(), path.getRemotePort()); } return null; } @@ -231,10 +232,6 @@ public C connect(SocketAddress addr) throws IOException { throw new IllegalArgumentException( "connect() requires an InetSocketAddress or a ScionSocketAddress."); } - if (addr instanceof ScionSocketAddress) { - // TODO check if this is a RequestPath? - return connect((RequestPath) ((ScionSocketAddress) addr).getPath()); - } return connect(pathPolicy.filter(getOrCreateService().getPaths((InetSocketAddress) addr))); } } @@ -401,14 +398,13 @@ public void setOverrideSourceAddress(InetSocketAddress address) { this.overrideExternalAddress = address; } - protected int sendRaw(ByteBuffer buffer, InetSocketAddress firstHop, Path path) + protected int sendRaw(ByteBuffer buffer, InetSocketAddress address, Path path) throws IOException { if (cfgRemoteDispatcher && path != null && path.getRawPath().length == 0) { - // TODO remove this once dispatcher is removed return channel.send( - buffer, new InetSocketAddress(firstHop.getAddress(), Constants.DISPATCHER_PORT)); + buffer, new InetSocketAddress(address.getAddress(), Constants.DISPATCHER_PORT)); } - return channel.send(buffer, firstHop); + return channel.send(buffer, address); } protected int sendRaw(ByteBuffer buffer, InetSocketAddress address) throws IOException { @@ -538,22 +534,20 @@ protected final ByteBuffer getBufferReceive(int requiredSize) { } /** - * @param dst Destination address + * @param path path * @param payloadLength payload length * @return argument path or a new path if the argument path was expired * @throws IOException in case of IOException. */ - protected void checkPathAndBuildHeader( - ByteBuffer buffer, - ScionSocketAddress dst, - int payloadLength, - InternalConstants.HdrTypes hdrType) + protected Path checkPathAndBuildHeader( + ByteBuffer buffer, Path path, int payloadLength, InternalConstants.HdrTypes hdrType) throws IOException { synchronized (stateLock) { - if (dst.isRequestAddress()) { - ensureUpToDate(dst); + if (path instanceof RequestPath) { + path = ensureUpToDate((RequestPath) path); } - buildHeader(buffer, dst.getPath(), payloadLength, hdrType); + buildHeader(buffer, path, payloadLength, hdrType); + return path; } } @@ -616,7 +610,8 @@ protected void buildHeader( rawPath.length, srcIA, srcAddress.getAddress(), - path, + path.getRemoteIsdAs(), + path.getRemoteAddress().getAddress(), hdrType, cfgTrafficClass); ScionHeaderParser.writePath(buffer, rawPath); @@ -628,13 +623,17 @@ protected void buildHeader( } } - protected void ensureUpToDate(ScionSocketAddress address) throws IOException { + protected RequestPath ensureUpToDate(RequestPath path) throws IOException { synchronized (stateLock) { - if (address.refreshPath(getOrCreateService(), pathPolicy, cfgExpirationSafetyMargin)) { - if (isConnected()) { - updateConnection(address.getPath().asRequestPath(), true); - } + if (Instant.now().getEpochSecond() + cfgExpirationSafetyMargin <= path.getExpiration()) { + return path; } + // expired, get new path + RequestPath newPath = pathPolicy.filter(getOrCreateService().getPaths(path)); + if (isConnected()) { + updateConnection(newPath, true); + } + return newPath; } } @@ -674,8 +673,4 @@ protected ReentrantLock readLock() { protected ReentrantLock writeLock() { return writeLock; } - - protected int getCfgExpirySafetyMargin() { - return cfgExpirationSafetyMargin; - } } diff --git a/src/main/java/org/scion/jpan/Path.java b/src/main/java/org/scion/jpan/Path.java index 17a32079a..898619cec 100644 --- a/src/main/java/org/scion/jpan/Path.java +++ b/src/main/java/org/scion/jpan/Path.java @@ -53,10 +53,6 @@ public long getRemoteIsdAs() { return dstIsdAs; } - RequestPath asRequestPath() { - return (RequestPath) this; - } - @Override public String toString() { return "Path{" diff --git a/src/main/java/org/scion/jpan/ScionDatagramChannel.java b/src/main/java/org/scion/jpan/ScionDatagramChannel.java index b37a45d00..8156d4c22 100644 --- a/src/main/java/org/scion/jpan/ScionDatagramChannel.java +++ b/src/main/java/org/scion/jpan/ScionDatagramChannel.java @@ -57,7 +57,7 @@ public boolean isBlocking() { return super.isBlocking(); } - public ScionSocketAddress receive(ByteBuffer userBuffer) throws IOException { + public ResponsePath receive(ByteBuffer userBuffer) throws IOException { readLock().lock(); try { ByteBuffer buffer = getBufferReceive(userBuffer.capacity()); @@ -67,7 +67,7 @@ public ScionSocketAddress receive(ByteBuffer userBuffer) throws IOException { } ScionHeaderParser.extractUserPayload(buffer, userBuffer); buffer.clear(); - return ScionSocketAddress.fromPath(receivePath); + return receivePath; } finally { readLock().unlock(); } @@ -84,26 +84,20 @@ public ScionSocketAddress receive(ByteBuffer userBuffer) throws IOException { * cannot be resolved to an ISD/AS. * @see java.nio.channels.DatagramChannel#send(ByteBuffer, SocketAddress) */ - public int send(ByteBuffer srcBuffer, SocketAddress destination) throws IOException { + public void send(ByteBuffer srcBuffer, SocketAddress destination) throws IOException { if (!(destination instanceof InetSocketAddress)) { throw new IllegalArgumentException("Address must be of type InetSocketAddress."); } - if (destination instanceof ScionSocketAddress) { - ScionSocketAddress ssa = (ScionSocketAddress) destination; - send(srcBuffer, ssa); - return 12345; // TODO - } InetSocketAddress dst = (InetSocketAddress) destination; Path path = getPathPolicy().filter(getOrCreateService().getPaths(dst)); - send(srcBuffer, ScionSocketAddress.fromPath(path)); - return 12345; // TODO + send(srcBuffer, path); } /** * Attempts to send the content of the buffer to the destinationAddress. * * @param srcBuffer Data to send - * @param address Path to destination. If this is a Request path and it is expired then it will + * @param path Path to destination. If this is a Request path and it is expired then it will * automatically be replaced with a new path. Expiration of ResponsePaths is not checked * @return either the path argument or a new path if the path was an expired RequestPath. Note * that ResponsePaths are not checked for expiration. @@ -111,35 +105,27 @@ public int send(ByteBuffer srcBuffer, SocketAddress destination) throws IOExcept * cannot be resolved to an ISD/AS. * @see java.nio.channels.DatagramChannel#send(ByteBuffer, SocketAddress) */ - public void send(ByteBuffer srcBuffer, ScionSocketAddress address) throws IOException { + public Path send(ByteBuffer srcBuffer, Path path) throws IOException { writeLock().lock(); try { ByteBuffer buffer = getBufferSend(srcBuffer.remaining()); // + 8 for UDP overlay header length - int len = srcBuffer.remaining() + 8; - checkPathAndBuildHeader(buffer, address, len, InternalConstants.HdrTypes.UDP); + Path actualPath = + checkPathAndBuildHeader( + buffer, path, srcBuffer.remaining() + 8, InternalConstants.HdrTypes.UDP); try { buffer.put(srcBuffer); } catch (BufferOverflowException e) { throw new IOException("Packet is larger than max send buffer size."); } buffer.flip(); - sendRaw(buffer, address.getPath().getFirstHopAddress(), address.getPath()); - // TODO consider TRICK - // - If read()/write() is used then we have no problem, getCurrentPath() works fine - // - receive() always contains a ResponsePath -> cannot expire - // - send() on server -> we have a ResponsePath -> cannot be refreshed - // - send() on client -> we have a RequestPath -> use with getCurrentPath() ??? + sendRaw(buffer, actualPath.getFirstHopAddress(), actualPath); + return actualPath; } finally { writeLock().unlock(); } } - @Deprecated // Please use another send method instead - public void send(ByteBuffer srcBuffer, Path path) throws IOException { - send(srcBuffer, ScionSocketAddress.fromPath(path)); - } - /** * Read data from the connected stream. * @@ -183,7 +169,7 @@ public int write(ByteBuffer src) throws IOException { ByteBuffer buffer = getBufferSend(src.remaining()); int len = src.remaining(); // + 8 for UDP overlay header length - checkPathAndBuildHeader(buffer, getRemoteAddress(), len + 8, InternalConstants.HdrTypes.UDP); + checkPathAndBuildHeader(buffer, getConnectionPath(), len + 8, InternalConstants.HdrTypes.UDP); buffer.put(src); buffer.flip(); diff --git a/src/main/java/org/scion/jpan/ScionDatagramSocket.java b/src/main/java/org/scion/jpan/ScionDatagramSocket.java index 73c4644b8..b4ccca3f1 100644 --- a/src/main/java/org/scion/jpan/ScionDatagramSocket.java +++ b/src/main/java/org/scion/jpan/ScionDatagramSocket.java @@ -22,6 +22,7 @@ import java.nio.channels.AlreadyBoundException; import java.nio.channels.DatagramChannel; import java.nio.channels.IllegalBlockingModeException; +import java.time.Instant; import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -55,8 +56,7 @@ public class ScionDatagramSocket extends java.net.DatagramSocket { private final SelectingDatagramChannel channel; private boolean isBound = false; - private final SimpleCache pathCache = - new SimpleCache<>(100); + private final SimpleCache pathCache = new SimpleCache<>(100); private final Object closeLock = new Object(); public ScionDatagramSocket() throws SocketException { @@ -257,7 +257,7 @@ public int getPort() { } @Override - public ScionSocketAddress getRemoteSocketAddress() { + public SocketAddress getRemoteSocketAddress() { try { return channel.getRemoteAddress(); } catch (IOException e) { @@ -283,37 +283,34 @@ public void send(DatagramPacket packet) throws IOException { // Synchronize on packet because this is what the Java DatagramSocket does. synchronized (packet) { - channel.writeLock().lock(); - try { - if (isConnected() && !channel.getRemoteAddress().equals(packet.getSocketAddress())) { - throw new IllegalArgumentException("Packet address does not match connected address"); - } + // TODO synchronize also on writeLock()! + if (isConnected() && !channel.getRemoteAddress().equals(packet.getSocketAddress())) { + throw new IllegalArgumentException("Packet address does not match connected address"); + } - ScionSocketAddress dstAddress; - if (channel.isConnected()) { - dstAddress = channel.getRemoteAddress(); - } else { - InetSocketAddress addr = (InetSocketAddress) packet.getSocketAddress(); - synchronized (pathCache) { - dstAddress = pathCache.get(addr); - if (dstAddress == null) { - dstAddress = - channel - .getOrCreateService2() - .lookupSocketAddress(packet.getAddress().getHostName(), packet.getPort()); - } - dstAddress.refreshPath( - channel.getOrCreateService2(), - channel.getPathPolicy(), - channel.getCfgExpirySafetyMargin()); - pathCache.put(addr, dstAddress); + Path path; + if (channel.isConnected()) { + path = channel.getConnectionPath(); + } else { + InetSocketAddress addr = (InetSocketAddress) packet.getSocketAddress(); + synchronized (pathCache) { + path = pathCache.get(addr); + if (path == null) { + path = channel.getPathPolicy().filter(channel.getOrCreateService2().getPaths(addr)); + } else if (path instanceof RequestPath + && ((RequestPath) path).getExpiration() > Instant.now().getEpochSecond()) { + // check expiration only for RequestPaths + RequestPath request = (RequestPath) path; + path = channel.getPathPolicy().filter(channel.getOrCreateService2().getPaths(request)); + } + if (path == null) { + throw new IOException("Address is not resolvable in SCION: " + packet.getAddress()); } + pathCache.put(addr, path); } - ByteBuffer buf = ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength()); - channel.send(buf, dstAddress); - } finally { - channel.writeLock().unlock(); } + ByteBuffer buf = ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength()); + channel.send(buf, path); } } @@ -324,27 +321,25 @@ public synchronized void receive(DatagramPacket packet) throws IOException { // We synchronize on the packet because that is what the Java socket does. synchronized (packet) { - channel.readLock().lock(); - try { - ByteBuffer receiveBuffer = - ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength()); - ScionSocketAddress path = channel.receive(receiveBuffer); - if (path == null) { - // timeout occurred - throw new SocketTimeoutException(); - } - // TODO this is not ideal, a client may not be connected. Use getService()==null? - if (!channel.isConnected()) { - synchronized (pathCache) { - pathCache.put(path, path); // TODO use Set i.o. Map - } + ByteBuffer receiveBuffer = + ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength()); + ResponsePath path = channel.receive(receiveBuffer); + if (path == null) { + // timeout occurred + throw new SocketTimeoutException(); + } + // TODO this is not ideal, a client may not be connected. Use getService()==null? + if (!channel.isConnected()) { + synchronized (pathCache) { + InetAddress ip = path.getRemoteAddress(); + InetSocketAddress addr = new InetSocketAddress(ip, path.getRemotePort()); + pathCache.put(addr, path); } - receiveBuffer.flip(); - packet.setLength(receiveBuffer.limit()); - packet.setSocketAddress(path); - } finally { - channel.readLock().unlock(); } + receiveBuffer.flip(); + packet.setLength(receiveBuffer.limit()); + packet.setAddress(path.getRemoteAddress()); + packet.setPort(path.getRemotePort()); } } @@ -550,7 +545,7 @@ public RequestPath getConnectionPath() { * @return the cached Path or `null` if not path is found. * @see #setPathCacheCapacity */ - public synchronized ScionSocketAddress getCachedPath(InetSocketAddress address) { + public synchronized Path getCachedPath(InetSocketAddress address) { synchronized (pathCache) { return pathCache.get(address); } diff --git a/src/main/java/org/scion/jpan/ScionService.java b/src/main/java/org/scion/jpan/ScionService.java index 5b5afc2a1..752c82bc8 100644 --- a/src/main/java/org/scion/jpan/ScionService.java +++ b/src/main/java/org/scion/jpan/ScionService.java @@ -299,11 +299,6 @@ List getPathListDaemon(long srcIsdAs, long dstIsdAs) { * @throws IOException if an errors occurs while querying paths. */ public List getPaths(InetSocketAddress dstAddress) throws IOException { - if (dstAddress instanceof ScionSocketAddress - && ((ScionSocketAddress) dstAddress).isRequestAddress()) { - return getPaths(((ScionSocketAddress) dstAddress).getPath().asRequestPath()); - } - // Use getHostString() to avoid DNS reverse lookup. ScionAddress sa = getScionAddress(dstAddress.getHostString()); return getPaths(sa.getIsdAs(), sa.getInetAddress(), dstAddress.getPort()); @@ -374,7 +369,7 @@ public long getLocalIsdAs() { /** * @param hostName hostName of the host to resolve - * @return The ISD/AS code for a hostname + * @return A ScionAddress * @throws ScionException if the DNS/TXT lookup did not return a (valid) SCION address. */ public long getIsdAs(String hostName) throws ScionException { @@ -413,30 +408,12 @@ public long getIsdAs(String hostName) throws ScionException { throw new ScionException("No DNS TXT entry \"scion\" found for host: " + hostName); } - @Deprecated // Please use lookupScionAddress() instead. - public ScionAddress getScionAddress(String hostName) throws ScionException { - return lookupAddress(hostName); - } - /** - * Uses DNS and hostfiles to look up a SCIOn enabled IP address for a give host string. - * - * @param hostName hostName of the host to resolve - * @return A ScionSocketAddress - * @throws ScionException if the DNS/TXT lookup did not return a (valid) SCION address. - */ - public ScionSocketAddress lookupSocketAddress(String hostName, int port) throws ScionException { - return ScionSocketAddress.fromScionAddress(lookupAddress(hostName), port); - } - - /** - * Uses DNS and hostfiles to look up a SCIOn enabled IP address for a give host string. - * * @param hostName hostName of the host to resolve * @return A ScionAddress * @throws ScionException if the DNS/TXT lookup did not return a (valid) SCION address. */ - public ScionAddress lookupAddress(String hostName) throws ScionException { + public ScionAddress getScionAddress(String hostName) throws ScionException { ScionAddress scionAddress = scionAddressCache.get(hostName); if (scionAddress != null) { return scionAddress; diff --git a/src/main/java/org/scion/jpan/ScionSocketAddress.java b/src/main/java/org/scion/jpan/ScionSocketAddress.java deleted file mode 100644 index 45774af15..000000000 --- a/src/main/java/org/scion/jpan/ScionSocketAddress.java +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2024 ETH Zurich -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package org.scion.jpan; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.time.Instant; - -/** - * A ScionSocketAddress is an InetSocketAddress with an attached path. The address part is immutable - * and paths are immutable, but the address can be assigned a new path. This is necessary to allow - * paths to be refreshed once they expire, if the policy changes or if the interface changes. - * - *

The address represents the destination address of the path. - */ -public class ScionSocketAddress extends InetSocketAddress { - - private final long isdAs; - private transient Path path; - - // TODO enable? - // public ScionSocketAddress(long isdAs, String hostname, int port) { - // super(hostname, port); - // this.isdAs = isdAs; - // } - - public ScionSocketAddress(long isdAs, InetAddress addr, int port) { - super(addr, port); - this.isdAs = isdAs; - } - - public ScionSocketAddress(long isdAs, InetSocketAddress addr) { - super(addr.getAddress(), addr.getPort()); - this.isdAs = isdAs; - } - - public static ScionSocketAddress fromPath(Path path) { - ScionSocketAddress a = - new ScionSocketAddress( - path.getRemoteIsdAs(), path.getRemoteAddress(), path.getRemotePort()); - a.path = path; - return a; - } - - public static ScionSocketAddress fromScionAddress(ScionAddress address, int port) { - return new ScionSocketAddress(address.getIsdAs(), address.getInetAddress(), port); - } - - public static ScionSocketAddress fromNonScionIP(InetAddress address, int port) - throws ScionException { - return fromNonScionIP(Scion.defaultService(), address, port); - } - - public static ScionSocketAddress fromNonScionIP( - ScionService service, InetAddress address, int port) throws ScionException { - ScionAddress sa = service.getScionAddress(address.getHostName()); - return new ScionSocketAddress(sa.getIsdAs(), sa.getInetAddress(), port); - } - - public static ScionSocketAddress fromScionIP(long isdAs, InetAddress address, int port) { - return new ScionSocketAddress(isdAs, address, port); - } - - /** - * @return the path currently associated with this address. May return 'null'. - */ - public Path getPath() { - return this.path; - } - - /** - * @param service Service for obtaining new paths when required - * @param pathPolicy PathPolicy for selecting a new path when required - * @param expiryMargin Expiry margin, i.e. a path is considered "expired" if expiry is less than - * expiryMargin seconds away. - * @return `false` if the path is `null`, it it is a ResponsePath or if it didn't need updating. - * Returns `true` only if the path was updated. - */ - synchronized boolean refreshPath(ScionService service, PathPolicy pathPolicy, int expiryMargin) - throws IOException { - if (path == null) { - path = pathPolicy.filter(service.getPaths(this)); - if (path == null) { - throw new IOException("Address is not resolvable in SCION: " + super.toString()); - } - return true; - } - - if (!(path instanceof RequestPath)) { - return false; - } - - RequestPath requestPath = (RequestPath) path; - if (Instant.now().getEpochSecond() + expiryMargin <= requestPath.getExpiration()) { - return false; - } - // expired, get new path - path = pathPolicy.filter(service.getPaths(requestPath)); - return true; - } - - /** - * @return 'true' iff the path associated with this address is an instance of RequestPath. - */ - public boolean isRequestAddress() { - return path instanceof RequestPath; - } - - public long getIsdAs() { - return isdAs; - } -} diff --git a/src/main/java/org/scion/jpan/ScmpChannel.java b/src/main/java/org/scion/jpan/ScmpChannel.java index 387021e72..458c63faa 100644 --- a/src/main/java/org/scion/jpan/ScmpChannel.java +++ b/src/main/java/org/scion/jpan/ScmpChannel.java @@ -141,8 +141,7 @@ private void sendScmpRequest(IOCallable sender, Scmp.TypeCode } else if (result.isTimedOut()) { result.setNanoSeconds(timeOutMs * 1_000_000L); } else { - throw new IOException( - "SCMP error: " + result.getTypeCode() + " " + result.getTypeCode().getText()); + throw new IOException("SCMP error: " + result.getTypeCode().getText()); } } @@ -408,7 +407,7 @@ public InetSocketAddress getLocalAddress() throws IOException { return channel.getLocalAddress(); } - public ScionSocketAddress getRemoteAddress() throws IOException { + public InetSocketAddress getRemoteAddress() throws IOException { return channel.getRemoteAddress(); } diff --git a/src/main/java/org/scion/jpan/internal/HostsFileParser.java b/src/main/java/org/scion/jpan/internal/HostsFileParser.java index e45e4a2f6..84d239185 100644 --- a/src/main/java/org/scion/jpan/internal/HostsFileParser.java +++ b/src/main/java/org/scion/jpan/internal/HostsFileParser.java @@ -97,7 +97,7 @@ private void parseLine(String line, Path path) { check(lineParts.length >= 2, "Expected ` `"); String[] addrParts = lineParts[0].split(","); check(addrParts.length == 2, "Expected `,`"); - long isdAs = ScionUtil.parseIA(addrParts[0]); + long isdIa = ScionUtil.parseIA(addrParts[0]); check(addrParts[1].startsWith("["), "Expected `[` before address"); check(addrParts[1].endsWith("]"), "Expected `]` after address"); String addrStr = addrParts[1].substring(1, addrParts[1].length() - 1).trim(); @@ -112,13 +112,13 @@ private void parseLine(String line, Path path) { break; } InetAddress inetAddr = InetAddress.getByAddress(hostName, addrBytes); - entries.put(hostName, new HostEntry(isdAs, inetAddr)); + entries.put(hostName, new HostEntry(isdIa, inetAddr)); } InetAddress inetAddr = InetAddress.getByAddress(addrStr, addrBytes); // Use original address string as key - entries.put(addrStr, new HostEntry(isdAs, inetAddr)); + entries.put(addrStr, new HostEntry(isdIa, inetAddr)); // Use "normalized" address string as key (these may differ fo IPv6) - entries.put(inetAddr.getHostAddress(), new HostEntry(isdAs, inetAddr)); + entries.put(inetAddr.getHostAddress(), new HostEntry(isdIa, inetAddr)); } catch (IndexOutOfBoundsException | IllegalArgumentException | UnknownHostException e) { LOG.info("ERROR parsing file {}: error=\"{}\" line=\"{}\"", path, e.getMessage(), line); } diff --git a/src/main/java/org/scion/jpan/internal/ScionHeaderParser.java b/src/main/java/org/scion/jpan/internal/ScionHeaderParser.java index 1b1b38bf1..2fed33a17 100644 --- a/src/main/java/org/scion/jpan/internal/ScionHeaderParser.java +++ b/src/main/java/org/scion/jpan/internal/ScionHeaderParser.java @@ -17,7 +17,6 @@ import java.net.*; import java.nio.ByteBuffer; import org.scion.jpan.Constants; -import org.scion.jpan.Path; import org.scion.jpan.ResponsePath; import org.scion.jpan.Scmp; @@ -367,11 +366,10 @@ public static void write( int pathHeaderLength, long srcIsdAs, byte[] srcAddress, - Path path, + long dstIsdAs, + byte[] dstAddress, InternalConstants.HdrTypes hdrType, int trafficClass) { - long dstIsdAs = path.getRemoteIsdAs(); - byte[] dstAddress = path.getRemoteAddress().getAddress(); int sl = srcAddress.length / 4 - 1; int dl = dstAddress.length / 4 - 1; diff --git a/src/main/java/org/scion/jpan/internal/SelectingDatagramChannel.java b/src/main/java/org/scion/jpan/internal/SelectingDatagramChannel.java index 02e374da4..264e805f7 100644 --- a/src/main/java/org/scion/jpan/internal/SelectingDatagramChannel.java +++ b/src/main/java/org/scion/jpan/internal/SelectingDatagramChannel.java @@ -24,7 +24,6 @@ import org.scion.jpan.ResponsePath; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; -import org.scion.jpan.ScionSocketAddress; /** * DatagramChannel with support for timeout. @@ -90,7 +89,7 @@ private ResponsePath receiveFromTimeoutChannel( } @Override - public ScionSocketAddress receive(ByteBuffer userBuffer) throws IOException { + public ResponsePath receive(ByteBuffer userBuffer) throws IOException { readLock().lock(); try { ByteBuffer buffer = getBufferReceive(userBuffer.capacity()); @@ -100,7 +99,7 @@ public ScionSocketAddress receive(ByteBuffer userBuffer) throws IOException { } ScionHeaderParser.extractUserPayload(buffer, userBuffer); buffer.clear(); - return ScionSocketAddress.fromPath(receivePath); + return receivePath; } finally { readLock().unlock(); } diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelApiConcurrencyTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelApiConcurrencyTest.java index 70fbb3c41..9bc616c32 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelApiConcurrencyTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelApiConcurrencyTest.java @@ -26,9 +26,9 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.scion.jpan.ResponsePath; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; -import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.MockDNS; import org.scion.jpan.testutil.MockDaemon; @@ -128,8 +128,8 @@ private void concurrentReceive(Reader c1, Reader c2, Writer w1, boolean connect) } // check that receive is responsive - ScionSocketAddress remote = server.receive(buffer); - server.send(buffer, remote); + ResponsePath path = server.receive(buffer); + server.send(buffer, path); // wait synchronized (receiveCount) { receiveCount.wait(1000); @@ -138,7 +138,7 @@ private void concurrentReceive(Reader c1, Reader c2, Writer w1, boolean connect) // send again to trigger 2nd receiver buffer.flip(); - server.send(buffer, remote); + server.send(buffer, path); // wait synchronized (receiveCount) { receiveCount.wait(1000); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java index 177d2fc15..50d00e1e4 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelApiServerTest.java @@ -85,8 +85,9 @@ void send_withoutService() throws IOException { new byte[4], 1, new InetSocketAddress("127.0.0.1", 1)); - channel.send(ByteBuffer.allocate(0), path); + Path p2 = channel.send(ByteBuffer.allocate(0), path); assertNull(channel.getService()); + assertEquals(path, p2); } } @@ -103,9 +104,9 @@ void receive_withoutService() throws IOException { try (ScionDatagramChannel channel = ScionDatagramChannel.open(null, mock)) { assertNull(channel.getService()); ByteBuffer buffer = ByteBuffer.allocate(100); - ScionSocketAddress remote = channel.receive(buffer); + Path path = channel.receive(buffer); assertNull(channel.getService()); - assertEquals(addr, remote.getPath().getFirstHopAddress()); + assertEquals(addr, path.getFirstHopAddress()); } } } diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java index 6ee51786d..e174854e1 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelApiTest.java @@ -472,9 +472,7 @@ void send_disconnected_expiredRequestPath() throws IOException { (channel, expiredPath) -> { ByteBuffer sendBuf = ByteBuffer.wrap(PingPongChannelHelper.MSG.getBytes()); try { - ScionSocketAddress dst = ScionSocketAddress.fromPath(expiredPath); - channel.send(sendBuf, dst); - RequestPath newPath = (RequestPath) dst.getPath(); + RequestPath newPath = (RequestPath) channel.send(sendBuf, expiredPath); assertTrue(newPath.getExpiration() > expiredPath.getExpiration()); assertTrue(Instant.now().getEpochSecond() < newPath.getExpiration()); assertNull(channel.getConnectionPath()); @@ -492,8 +490,7 @@ void send_connected_expiredRequestPath() throws IOException { (channel, expiredPath) -> { ByteBuffer sendBuf = ByteBuffer.wrap(PingPongChannelHelper.MSG.getBytes()); try { - channel.send(sendBuf, expiredPath); - RequestPath newPath = (RequestPath) channel.getConnectionPath(); + RequestPath newPath = (RequestPath) channel.send(sendBuf, expiredPath); assertTrue(newPath.getExpiration() > expiredPath.getExpiration()); assertTrue(Instant.now().getEpochSecond() < newPath.getExpiration()); assertEquals(newPath, channel.getConnectionPath()); @@ -530,7 +527,7 @@ private void testExpired( PingPongChannelHelper.Client clientFn = (channel, basePath, id) -> { // Build a path that is already expired - RequestPath expiredPath = createExpiredPath(basePath.getPath()); + RequestPath expiredPath = createExpiredPath(basePath); sendMethod.accept(channel, expiredPath); ByteBuffer response = ByteBuffer.allocate(100); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendInetAddrTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendInetAddrTest.java index 313ac8970..0122e69d8 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendInetAddrTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendInetAddrTest.java @@ -23,9 +23,9 @@ import java.nio.charset.Charset; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; +import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; -import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.PingPongChannelHelper; /** Test receive()/send(InetAddress) operations on DatagramChannel. */ @@ -45,22 +45,21 @@ void test() { pph.runPingPong(serverFn, clientFn); } - private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) - throws IOException { + private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); // Test send() with InetAddress - InetAddress inetServerAddress = serverAddress.getAddress(); + InetAddress inetServerAddress = serverAddress.getRemoteAddress(); InetSocketAddress inetServerSocketAddress = - new InetSocketAddress(inetServerAddress, serverAddress.getPort()); + new InetSocketAddress(inetServerAddress, serverAddress.getRemotePort()); channel.send(sendBuf, inetServerSocketAddress); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); ByteBuffer response = ByteBuffer.allocate(512); - ScionSocketAddress address = channel.receive(response); + Path address = channel.receive(response); assertNotNull(address); - assertEquals(serverAddress.getAddress(), address.getAddress()); - assertEquals(serverAddress.getPort(), address.getPort()); + assertEquals(serverAddress.getRemoteAddress(), address.getRemoteAddress()); + assertEquals(serverAddress.getRemotePort(), address.getRemotePort()); response.flip(); String pong = Charset.defaultCharset().decode(response).toString(); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendPathTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendPathTest.java index f78450ed6..bdcc191bb 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendPathTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelMultiSendPathTest.java @@ -21,9 +21,9 @@ import java.nio.charset.Charset; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; +import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; -import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.PingPongChannelHelper; /** Test receive()/send(Path) operations on DatagramChannel. */ @@ -43,18 +43,17 @@ void test() { pph.runPingPong(serverFn, clientFn); } - private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) - throws IOException { + private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); channel.send(sendBuf, serverAddress); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); ByteBuffer response = ByteBuffer.allocate(512); - ScionSocketAddress address = channel.receive(response); + Path address = channel.receive(response); assertNotNull(address); - assertEquals(serverAddress.getAddress(), address.getAddress()); - assertEquals(serverAddress.getPort(), address.getPort()); + assertEquals(serverAddress.getRemoteAddress(), address.getRemoteAddress()); + assertEquals(serverAddress.getRemotePort(), address.getRemotePort()); response.flip(); String pong = Charset.defaultCharset().decode(response).toString(); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedInetSocketTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedInetSocketTest.java index 34d54227b..c950eb29c 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedInetSocketTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedInetSocketTest.java @@ -23,9 +23,9 @@ import java.nio.charset.Charset; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; +import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; -import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.PingPongChannelHelper; /** Test read()/write() operations on DatagramChannel connected with an InetSocketAddress. */ @@ -45,15 +45,14 @@ void test() { pph.runPingPong(serverFn, clientFn); } - private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) - throws IOException { + private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); channel.disconnect(); // Test send() with InetAddress - InetAddress inetAddress = serverAddress.getAddress(); + InetAddress inetAddress = serverAddress.getRemoteAddress(); InetSocketAddress inetServerSocketAddress = - new InetSocketAddress(inetAddress, serverAddress.getPort()); + new InetSocketAddress(inetAddress, serverAddress.getRemotePort()); channel.connect(inetServerSocketAddress); assertTrue(channel.isConnected()); channel.write(sendBuf); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java index be1db95cc..dccb0c6a1 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelMultiWriteConnectedPathTest.java @@ -21,7 +21,10 @@ import java.nio.charset.Charset; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.*; +import org.scion.jpan.Path; +import org.scion.jpan.RequestPath; +import org.scion.jpan.ScionDatagramChannel; +import org.scion.jpan.ScionService; import org.scion.jpan.testutil.PingPongChannelHelper; /** Test read()/write() operations on DatagramChannel connected with a path. */ @@ -43,7 +46,7 @@ void test() { pph.runPingPong(serverFn, clientFn); } - private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) + private void client(ScionDatagramChannel channel, RequestPath serverAddress, int id) throws IOException { String message = MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); @@ -65,7 +68,7 @@ private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddre private void server(ScionDatagramChannel channel) throws IOException { ByteBuffer request = ByteBuffer.allocate(512); // System.out.println("SERVER: --- USER - Waiting for packet --------------------- " + i); - ScionSocketAddress remote = channel.receive(request); + Path path = channel.receive(request); request.flip(); String msg = Charset.defaultCharset().decode(request).toString(); @@ -74,6 +77,6 @@ private void server(ScionDatagramChannel channel) throws IOException { // System.out.println("SERVER: --- USER - Sending packet ---------------------- " + i); request.flip(); - channel.send(request, remote); + channel.send(request, path); } } diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java index 309f54103..d80f9a81d 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelPathSwitchTest.java @@ -22,7 +22,11 @@ import java.util.List; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.*; +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; import org.scion.jpan.testutil.PingPongChannelHelper; @@ -56,8 +60,7 @@ void test() { assertEquals(2 * 2 * 10, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) - throws IOException { + private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); diff --git a/src/test/java/org/scion/jpan/api/DatagramChannelStreamTest.java b/src/test/java/org/scion/jpan/api/DatagramChannelStreamTest.java index 2f9bce7e3..71e2376e6 100644 --- a/src/test/java/org/scion/jpan/api/DatagramChannelStreamTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramChannelStreamTest.java @@ -22,9 +22,9 @@ import java.util.ArrayList; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; +import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; import org.scion.jpan.ScionService; -import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.MockNetwork; import org.scion.jpan.testutil.PingPongChannelHelper; @@ -48,8 +48,7 @@ void test() { assertEquals(2 * 2 * 2 * N_BULK, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) - throws IOException { + private void client(ScionDatagramChannel channel, Path serverAddress, int id) throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); @@ -72,10 +71,10 @@ private void client(ScionDatagramChannel channel, ScionSocketAddress serverAddre } private static class Pair { - ScionSocketAddress path; + Path path; String msg; - Pair(ScionSocketAddress path, String msg) { + Pair(Path path, String msg) { this.path = path; this.msg = msg; } @@ -89,7 +88,7 @@ public void server(ScionDatagramChannel channel) throws IOException { ArrayList received = new ArrayList<>(); for (int i = 0; i < N_BULK; i++) { request.clear(); - ScionSocketAddress returnAddress = channel.receive(request); + Path returnAddress = channel.receive(request); request.flip(); String msg = Charset.defaultCharset().decode(request).toString(); received.add(new Pair(returnAddress, msg)); diff --git a/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java b/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java index 0d5f9da4e..f43564973 100644 --- a/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramSocketApiTest.java @@ -634,7 +634,7 @@ private void testExpired(BiConsumer sendMethod PingPongSocketHelper.Client clientFn = (channel, basePath, id) -> { // Build a path that is already expired - RequestPath expiredPath = createExpiredPath(basePath.getPath()); + RequestPath expiredPath = createExpiredPath(basePath); sendMethod.accept(channel, expiredPath); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); @@ -668,11 +668,6 @@ private static InetSocketAddress toAddress(Path path) { return new InetSocketAddress(path.getRemoteAddress(), path.getRemotePort()); } - private static InetSocketAddress toAddress(ScionSocketAddress path) { - // TODO do we need this? For Proper equals()? - return new InetSocketAddress(path.getAddress(), path.getPort()); - } - @Test void getConnectionPath() throws IOException { RequestPath path = ExamplePacket.PATH; @@ -781,8 +776,7 @@ void testPathCache() throws IOException { server.receive(packet1); assertEquals(clientAddress1, packet1.getSocketAddress()); - ScionSocketAddress path1 = - server.getCachedPath((InetSocketAddress) packet1.getSocketAddress()); + Path path1 = server.getCachedPath((InetSocketAddress) packet1.getSocketAddress()); assertEquals(clientAddress1, toAddress(path1)); // 2nd client @@ -806,8 +800,7 @@ void testPathCache() throws IOException { path1 = server.getCachedPath((InetSocketAddress) packet1.getSocketAddress()); assertEquals(clientAddress1, toAddress(path1)); // path 2 should also be there - ScionSocketAddress path2 = - server.getCachedPath((InetSocketAddress) packet2.getSocketAddress()); + Path path2 = server.getCachedPath((InetSocketAddress) packet2.getSocketAddress()); assertEquals(clientAddress2, toAddress(path2)); // reduce capacity diff --git a/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java b/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java index cdfa647ae..94a19c2dc 100644 --- a/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramSocketConcurrentPingPongTest.java @@ -23,9 +23,9 @@ 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.ScionDatagramSocket; import org.scion.jpan.ScionService; -import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.MockNetwork; import org.scion.jpan.testutil.PingPongSocketHelper; @@ -59,10 +59,12 @@ void test() throws IOException { assertEquals(2 * 10 * 10, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramSocket socket, ScionSocketAddress requestPath, int id) + private void client(ScionDatagramSocket socket, RequestPath requestPath, int id) throws IOException { byte[] sendBuf = MSG.getBytes(); - DatagramPacket request = new DatagramPacket(sendBuf, sendBuf.length, requestPath); + InetAddress addr = requestPath.getRemoteAddress(); + int port = requestPath.getRemotePort(); + DatagramPacket request = new DatagramPacket(sendBuf, sendBuf.length, addr, port); socket.send(request); // System.out.println("CLIENT: Sent ... (" + request.getSocketAddress() + ")"); diff --git a/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java b/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java index 2a1d7ccfa..e5680309c 100644 --- a/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java +++ b/src/test/java/org/scion/jpan/api/DatagramSocketPingPongTest.java @@ -21,9 +21,9 @@ import java.net.*; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; +import org.scion.jpan.RequestPath; import org.scion.jpan.ScionDatagramSocket; import org.scion.jpan.ScionService; -import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.testutil.MockNetwork; import org.scion.jpan.testutil.PingPongSocketHelper; @@ -44,10 +44,12 @@ void test() { assertEquals(2 * 10 * 10, MockNetwork.getAndResetForwardCount()); } - private void client(ScionDatagramSocket socket, ScionSocketAddress requestPath, int id) + private void client(ScionDatagramSocket socket, RequestPath requestPath, int id) throws IOException { byte[] sendBuf = MSG.getBytes(); - DatagramPacket request = new DatagramPacket(sendBuf, sendBuf.length, requestPath); + InetAddress addr = requestPath.getRemoteAddress(); + int port = requestPath.getRemotePort(); + DatagramPacket request = new DatagramPacket(sendBuf, sendBuf.length, addr, port); socket.send(request); // System.out.println("CLIENT: Receiving ... (" + socket.getLocalSocketAddress() + ")"); diff --git a/src/test/java/org/scion/jpan/demo/PingPongChannelServer.java b/src/test/java/org/scion/jpan/demo/PingPongChannelServer.java index f3c72a565..57e064a70 100644 --- a/src/test/java/org/scion/jpan/demo/PingPongChannelServer.java +++ b/src/test/java/org/scion/jpan/demo/PingPongChannelServer.java @@ -17,8 +17,8 @@ import java.io.*; import java.net.*; import java.nio.ByteBuffer; +import org.scion.jpan.Path; import org.scion.jpan.ScionDatagramChannel; -import org.scion.jpan.ScionSocketAddress; import org.scion.jpan.ScionUtil; public class PingPongChannelServer { @@ -54,13 +54,14 @@ private static void service() throws IOException { channel.bind(SERVER_ADDRESS); ByteBuffer buffer = ByteBuffer.allocate(100); println("Waiting for packet ... "); - ScionSocketAddress remote = channel.receive(buffer); + Path path = channel.receive(buffer); String msg = extractMessage(buffer); - String borderRouterInterfaces = ScionUtil.toStringPath(remote.getPath().getRawPath()); - println("Received (from " + remote + ") via " + borderRouterInterfaces + "): " + msg); + String remoteAddress = path.getRemoteAddress() + ":" + path.getRemotePort(); + String borderRouterInterfaces = ScionUtil.toStringPath(path.getRawPath()); + println("Received (from " + remoteAddress + ") via " + borderRouterInterfaces + "): " + msg); String msgAnswer = "Re: " + msg; - channel.send(ByteBuffer.wrap(msgAnswer.getBytes()), remote); + channel.send(ByteBuffer.wrap(msgAnswer.getBytes()), path); println("Sent answer: " + msgAnswer); } } diff --git a/src/test/java/org/scion/jpan/internal/HeaderComposeTest.java b/src/test/java/org/scion/jpan/internal/HeaderComposeTest.java index 854fbff85..6671446fd 100644 --- a/src/test/java/org/scion/jpan/internal/HeaderComposeTest.java +++ b/src/test/java/org/scion/jpan/internal/HeaderComposeTest.java @@ -23,7 +23,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.scion.jpan.RequestPath; import org.scion.jpan.Scion; import org.scion.jpan.ScionService; import org.scion.jpan.ScionUtil; @@ -82,20 +81,20 @@ void testCompose() throws IOException { // Socket internal - compose header data pathService = Scion.newServiceWithDaemon(MockDaemon.DEFAULT_ADDRESS_STR); long srcIA = pathService.getLocalIsdAs(); - RequestPath path = pathService.getPaths(dstIA, dstSocketAddress).get(0); - byte[] pathRaw = path.getRawPath(); + byte[] path = pathService.getPaths(dstIA, dstSocketAddress).get(0).getRawPath(); // Socket internal = write header ScionHeaderParser.write( p, userPacket.limit() + 8, - pathRaw.length, + path.length, srcIA, srcAddress, - path, + dstIA, + dstAddress, InternalConstants.HdrTypes.UDP, 0); - ScionHeaderParser.writePath(p, path.getRawPath()); + ScionHeaderParser.writePath(p, path); // Overlay header ScionHeaderParser.writeUdpOverlayHeader(p, userPacket.limit(), 44444, dstPort); diff --git a/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java b/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java index f1ddafd6a..ad2678b03 100644 --- a/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java +++ b/src/test/java/org/scion/jpan/testutil/PingPongChannelHelper.java @@ -20,8 +20,9 @@ import java.net.*; 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; public class PingPongChannelHelper extends PingPongHelperBase { @@ -59,11 +60,11 @@ public final void run() { private class ClientEndpoint extends AbstractChannelEndpoint { private final Client client; - private final ScionSocketAddress path; + private final RequestPath path; private final int nRounds; private final boolean connect; - ClientEndpoint(Client client, int id, ScionSocketAddress path, int nRounds, boolean connect) { + ClientEndpoint(Client client, int id, RequestPath path, int nRounds, boolean connect) { super(id); this.client = client; this.path = path; @@ -74,7 +75,9 @@ private class ClientEndpoint extends AbstractChannelEndpoint { @Override public final void runImpl(ScionDatagramChannel channel) throws IOException { if (connect) { - channel.connect(path); + InetAddress inetAddress = path.getRemoteAddress(); + InetSocketAddress iSAddress = new InetSocketAddress(inetAddress, path.getRemotePort()); + channel.connect(iSAddress); } registerStartUpClient(); for (int i = 0; i < nRounds; i++) { @@ -107,7 +110,7 @@ public final void runImpl(ScionDatagramChannel channel) throws IOException { } public interface Client { - void run(ScionDatagramChannel channel, ScionSocketAddress path, int id) throws IOException; + void run(ScionDatagramChannel channel, RequestPath path, int id) throws IOException; } public interface Server { @@ -125,18 +128,18 @@ public void runPingPong(Server serverFn, Client clientFn, boolean reset) { reset); } - public static void defaultClient( - ScionDatagramChannel channel, ScionSocketAddress serverAddress, int id) throws IOException { + public static void defaultClient(ScionDatagramChannel channel, Path serverAddress, int id) + throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; ByteBuffer sendBuf = ByteBuffer.wrap(message.getBytes()); channel.send(sendBuf, serverAddress); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); ByteBuffer response = ByteBuffer.allocate(512); - ScionSocketAddress address = channel.receive(response); + Path address = channel.receive(response); assertNotNull(address); - assertEquals(serverAddress.getAddress(), address.getAddress()); - assertEquals(serverAddress.getPort(), address.getPort()); + assertEquals(serverAddress.getRemoteAddress(), address.getRemoteAddress()); + assertEquals(serverAddress.getRemotePort(), address.getRemotePort()); response.flip(); String pong = Charset.defaultCharset().decode(response).toString(); @@ -146,7 +149,7 @@ public static void defaultClient( public static void defaultServer(ScionDatagramChannel channel) throws IOException { ByteBuffer request = ByteBuffer.allocate(512); // System.out.println("SERVER: Receiving ... (" + channel.getLocalAddress() + ")"); - ScionSocketAddress address = channel.receive(request); + Path address = channel.receive(request); request.flip(); String msg = Charset.defaultCharset().decode(request).toString(); diff --git a/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java b/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java index b94aa2058..73448d320 100644 --- a/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java +++ b/src/test/java/org/scion/jpan/testutil/PingPongHelperBase.java @@ -26,7 +26,6 @@ import java.util.concurrent.atomic.AtomicInteger; import org.scion.jpan.RequestPath; import org.scion.jpan.Scion; -import org.scion.jpan.ScionSocketAddress; public class PingPongHelperBase { @@ -85,7 +84,7 @@ public InetSocketAddress getLocalAddress() { } interface ClientFactory { - AbstractEndpoint create(int id, ScionSocketAddress requestPath, int nRounds); + AbstractEndpoint create(int id, RequestPath requestPath, int nRounds); } interface ServerFactory { @@ -108,8 +107,7 @@ void runPingPong(ServerFactory serverFactory, ClientFactory clientFactory, boole } InetSocketAddress serverAddress = servers[0].getLocalAddress(); MockDNS.install(MockNetwork.TINY_SRV_ISD_AS, serverAddress.getAddress()); - RequestPath path = Scion.defaultService().getPaths(serverAddress).get(0); - ScionSocketAddress scionAddress = ScionSocketAddress.fromPath(path); + RequestPath scionAddress = Scion.defaultService().getPaths(serverAddress).get(0); 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 113085231..66cf093df 100644 --- a/src/test/java/org/scion/jpan/testutil/PingPongSocketHelper.java +++ b/src/test/java/org/scion/jpan/testutil/PingPongSocketHelper.java @@ -21,8 +21,9 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import org.scion.jpan.Path; +import org.scion.jpan.RequestPath; import org.scion.jpan.ScionDatagramSocket; -import org.scion.jpan.ScionSocketAddress; public class PingPongSocketHelper extends PingPongHelperBase { @@ -56,10 +57,10 @@ public final void run() { private class ClientEndpoint extends AbstractSocketEndpoint { private final Client client; - private final ScionSocketAddress remoteAddress; + private final RequestPath remoteAddress; private final int nRounds; - ClientEndpoint(Client client, int id, ScionSocketAddress remoteAddress, int nRounds) { + ClientEndpoint(Client client, int id, RequestPath remoteAddress, int nRounds) { super(id); this.client = client; this.remoteAddress = remoteAddress; @@ -70,7 +71,10 @@ private class ClientEndpoint extends AbstractSocketEndpoint { public final void runImpl() throws IOException { try (ScionDatagramSocket socket = new ScionDatagramSocket()) { registerStartUpClient(); - socket.connect(remoteAddress); + InetAddress ipAddress = remoteAddress.getRemoteAddress(); + InetSocketAddress iSAddress = + new InetSocketAddress(ipAddress, remoteAddress.getRemotePort()); + socket.connect(iSAddress); for (int i = 0; i < nRounds; i++) { client.run(socket, remoteAddress, id); nRoundsClient.incrementAndGet(); @@ -126,7 +130,7 @@ public final void runImpl() throws IOException { } public interface Client { - void run(ScionDatagramSocket socket, ScionSocketAddress path, int id) throws IOException; + void run(ScionDatagramSocket socket, RequestPath path, int id) throws IOException; } public interface Server { @@ -158,11 +162,12 @@ public void runPingPongSharedServerSocket( } } - public static void defaultClient(ScionDatagramSocket socket, ScionSocketAddress path, int id) + public static void defaultClient(ScionDatagramSocket socket, Path path, int id) throws IOException { String message = PingPongChannelHelper.MSG + "-" + id; + InetSocketAddress dst = new InetSocketAddress(path.getRemoteAddress(), path.getRemotePort()); - DatagramPacket packetOut = new DatagramPacket(message.getBytes(), message.length(), path); + DatagramPacket packetOut = new DatagramPacket(message.getBytes(), message.length(), dst); socket.send(packetOut); // System.out.println("CLIENT: Receiving ... (" + channel.getLocalAddress() + ")"); From 3c8bfe85b315a9e15bc4a4b94bc157804ef18e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilmann=20Z=C3=A4schke?= Date: Wed, 29 May 2024 15:55:57 +0200 Subject: [PATCH 4/4] cleanup --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae723264d..aab8edb08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Added - SCMP echo responder [#78](https://github.com/scionproto-contrib/jpan/pull/78) -- Maven Java executor [#79](https://github.com/scionproto-contrib/jpan/pull/79) +- Maven Java executor [#80](https://github.com/scionproto-contrib/jpan/pull/80) ### Changed - Some API changes: [#67](https://github.com/scionproto-contrib/jpan/pull/67)