From 36c0f79a9433322be1b10222be79ec273061abaa Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 17 Mar 2021 14:22:50 +0100 Subject: [PATCH] factor out address decoding and encoding Signed-off-by: Ludovic Orban --- .../jetty/http3/server/AddressCodec.java | 81 +++++++++++++++++++ .../jetty/http3/server/QuicConnection.java | 16 +--- .../jetty/http3/server/QuicSession.java | 4 +- .../http3/server/ServerDatagramEndPoint.java | 45 +---------- 4 files changed, 90 insertions(+), 56 deletions(-) create mode 100644 jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/AddressCodec.java diff --git a/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/AddressCodec.java b/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/AddressCodec.java new file mode 100644 index 00000000000..a9cb46827a6 --- /dev/null +++ b/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/AddressCodec.java @@ -0,0 +1,81 @@ +// +// ======================================================================== +// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.http3.server; + +import java.io.IOException; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.util.BufferUtil; + +public class AddressCodec +{ + public static final int ENCODED_ADDRESS_LENGTH = 19; + + public static ByteBuffer encodeInetSocketAddress(ByteBufferPool byteBufferPool, InetSocketAddress remoteAddress) throws IOException + { + ByteBuffer addressBuffer = byteBufferPool.acquire(ENCODED_ADDRESS_LENGTH, true); + try + { + int pos = BufferUtil.flipToFill(addressBuffer); + encodeInetSocketAddress(addressBuffer, remoteAddress); + BufferUtil.flipToFlush(addressBuffer, pos); + return addressBuffer; + } + catch (Throwable x) + { + byteBufferPool.release(addressBuffer); + throw x; + } + } + + public static InetSocketAddress decodeInetSocketAddress(ByteBuffer buffer) throws IOException + { + int headerPosition = buffer.position(); + byte ipVersion = buffer.get(); + byte[] address; + if (ipVersion == 4) + address = new byte[4]; + else if (ipVersion == 6) + address = new byte[16]; + else + throw new IOException("Unsupported IP version: " + ipVersion); + buffer.get(address); + int port = buffer.getChar(); + buffer.position(headerPosition + ENCODED_ADDRESS_LENGTH); + return new InetSocketAddress(InetAddress.getByAddress(address), port); + } + + public static void encodeInetSocketAddress(ByteBuffer buffer, InetSocketAddress peer) throws IOException + { + int headerPosition = buffer.position(); + byte[] addressBytes = peer.getAddress().getAddress(); + int port = peer.getPort(); + byte ipVersion; + if (peer.getAddress() instanceof Inet4Address) + ipVersion = 4; + else if (peer.getAddress() instanceof Inet6Address) + ipVersion = 6; + else + throw new IOException("Unsupported address type: " + peer.getAddress().getClass()); + buffer.put(ipVersion); + buffer.put(addressBytes); + buffer.putChar((char)port); + buffer.position(headerPosition + ENCODED_ADDRESS_LENGTH); + } +} diff --git a/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/QuicConnection.java b/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/QuicConnection.java index 3a9cda56fdf..2cd7297217a 100644 --- a/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/QuicConnection.java +++ b/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/QuicConnection.java @@ -14,7 +14,6 @@ package org.eclipse.jetty.http3.server; import java.io.File; -import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.util.ArrayDeque; @@ -104,7 +103,7 @@ public class QuicConnection extends AbstractConnection { try { - ByteBuffer cipherBuffer = byteBufferPool.acquire(LibQuiche.QUICHE_MIN_CLIENT_INITIAL_LEN + ServerDatagramEndPoint.ENCODED_ADDRESS_LENGTH, true); + ByteBuffer cipherBuffer = byteBufferPool.acquire(LibQuiche.QUICHE_MIN_CLIENT_INITIAL_LEN + AddressCodec.ENCODED_ADDRESS_LENGTH, true); while (true) { int fill = getEndPoint().fill(cipherBuffer); @@ -118,7 +117,7 @@ public class QuicConnection extends AbstractConnection if (LOG.isDebugEnabled()) LOG.debug("received buffer(address+ciphertext) of size {}", cipherBuffer.remaining()); - InetSocketAddress remoteAddress = ServerDatagramEndPoint.decodeInetSocketAddress(cipherBuffer); + InetSocketAddress remoteAddress = AddressCodec.decodeInetSocketAddress(cipherBuffer); if (LOG.isDebugEnabled()) LOG.debug("decoded peer IP address: {}, ciphertext packet size: {}", remoteAddress, cipherBuffer.remaining()); @@ -141,7 +140,7 @@ public class QuicConnection extends AbstractConnection QuicheConnection quicheConnection = QuicheConnection.tryAccept(quicheConfig, remoteAddress, cipherBuffer); if (quicheConnection == null) { - ByteBuffer addressBuffer = encodeInetSocketAddress(byteBufferPool, remoteAddress); + ByteBuffer addressBuffer = AddressCodec.encodeInetSocketAddress(byteBufferPool, remoteAddress); ByteBuffer negotiationBuffer = byteBufferPool.acquire(LibQuiche.QUICHE_MIN_CLIENT_INITIAL_LEN, true); int pos = BufferUtil.flipToFill(negotiationBuffer); @@ -191,15 +190,6 @@ public class QuicConnection extends AbstractConnection flusher.iterate(); } - static ByteBuffer encodeInetSocketAddress(ByteBufferPool byteBufferPool, InetSocketAddress remoteAddress) throws IOException - { - ByteBuffer addressBuffer = byteBufferPool.acquire(ServerDatagramEndPoint.ENCODED_ADDRESS_LENGTH, true); - int pos = BufferUtil.flipToFill(addressBuffer); - ServerDatagramEndPoint.encodeInetSocketAddress(addressBuffer, remoteAddress); - BufferUtil.flipToFlush(addressBuffer, pos); - return addressBuffer; - } - private class Flusher extends IteratingCallback { private final AutoLock lock = new AutoLock(); diff --git a/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/QuicSession.java b/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/QuicSession.java index 56142fead39..e9b12e0c85b 100644 --- a/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/QuicSession.java +++ b/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/QuicSession.java @@ -239,8 +239,8 @@ public class QuicSession protected Action process() throws IOException { ByteBufferPool byteBufferPool = connector.getByteBufferPool(); - addressBuffer = QuicConnection.encodeInetSocketAddress(byteBufferPool, remoteAddress); - cipherBuffer = byteBufferPool.acquire(LibQuiche.QUICHE_MIN_CLIENT_INITIAL_LEN + ServerDatagramEndPoint.ENCODED_ADDRESS_LENGTH, true); + addressBuffer = AddressCodec.encodeInetSocketAddress(byteBufferPool, remoteAddress); + cipherBuffer = byteBufferPool.acquire(LibQuiche.QUICHE_MIN_CLIENT_INITIAL_LEN + AddressCodec.ENCODED_ADDRESS_LENGTH, true); int pos = BufferUtil.flipToFill(cipherBuffer); int drained = quicheConnection.drainCipherText(cipherBuffer); long nextTimeoutInMs = quicheConnection.nextTimeout(); diff --git a/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/ServerDatagramEndPoint.java b/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/ServerDatagramEndPoint.java index 0e35a3c6e3c..333d4d755c9 100644 --- a/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/ServerDatagramEndPoint.java +++ b/jetty-http3/http3-server/src/main/java/org/eclipse/jetty/http3/server/ServerDatagramEndPoint.java @@ -41,8 +41,6 @@ import org.slf4j.LoggerFactory; public class ServerDatagramEndPoint extends IdleTimeout implements EndPoint, ManagedSelector.Selectable { private static final Logger LOG = LoggerFactory.getLogger(ServerDatagramEndPoint.class); - // TODO: javadocs - static final int ENCODED_ADDRESS_LENGTH = 19; private final long createdTimeStamp = System.currentTimeMillis(); private final AtomicBoolean fillable = new AtomicBoolean(); @@ -138,7 +136,7 @@ public class ServerDatagramEndPoint extends IdleTimeout implements EndPoint, Man { int pos = BufferUtil.flipToFill(buffer); - buffer.position(pos + ENCODED_ADDRESS_LENGTH); + buffer.position(pos + AddressCodec.ENCODED_ADDRESS_LENGTH); InetSocketAddress peer = (InetSocketAddress)channel.receive(buffer); if (peer == null) { @@ -149,18 +147,18 @@ public class ServerDatagramEndPoint extends IdleTimeout implements EndPoint, Man int finalPosition = buffer.position(); buffer.position(pos); - encodeInetSocketAddress(buffer, peer); + AddressCodec.encodeInetSocketAddress(buffer, peer); buffer.position(finalPosition); BufferUtil.flipToFlush(buffer, pos); - return finalPosition - ENCODED_ADDRESS_LENGTH; + return finalPosition - AddressCodec.ENCODED_ADDRESS_LENGTH; } @Override public boolean flush(ByteBuffer... buffers) throws IOException { - InetSocketAddress peer = decodeInetSocketAddress(buffers[0]); + InetSocketAddress peer = AddressCodec.decodeInetSocketAddress(buffers[0]); for (int i = 1; i < buffers.length; i++) { ByteBuffer buffer = buffers[i]; @@ -276,39 +274,4 @@ public class ServerDatagramEndPoint extends IdleTimeout implements EndPoint, Man { throw new UnsupportedOperationException(); } - - static InetSocketAddress decodeInetSocketAddress(ByteBuffer buffer) throws IOException - { - int headerPosition = buffer.position(); - byte ipVersion = buffer.get(); - byte[] address; - if (ipVersion == 4) - address = new byte[4]; - else if (ipVersion == 6) - address = new byte[16]; - else - throw new IOException("Unsupported IP version: " + ipVersion); - buffer.get(address); - int port = buffer.getChar(); - buffer.position(headerPosition + ENCODED_ADDRESS_LENGTH); - return new InetSocketAddress(InetAddress.getByAddress(address), port); - } - - static void encodeInetSocketAddress(ByteBuffer buffer, InetSocketAddress peer) throws IOException - { - int headerPosition = buffer.position(); - byte[] addressBytes = peer.getAddress().getAddress(); - int port = peer.getPort(); - byte ipVersion; - if (peer.getAddress() instanceof Inet4Address) - ipVersion = 4; - else if (peer.getAddress() instanceof Inet6Address) - ipVersion = 6; - else - throw new IOException("Unsupported address type: " + peer.getAddress().getClass()); - buffer.put(ipVersion); - buffer.put(addressBytes); - buffer.putChar((char)port); - buffer.position(headerPosition + ENCODED_ADDRESS_LENGTH); - } }