factor out address decoding and encoding
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
parent
44eb359d57
commit
36c0f79a94
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue