add IPv6 support

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
Ludovic Orban 2021-09-13 14:55:23 +02:00 committed by Simone Bordet
parent 63e4f1a074
commit 29c8256b39
5 changed files with 126 additions and 83 deletions

View File

@ -77,13 +77,13 @@ public class QuicheConnection
if (isLinux())
{
netinet_linux.sockaddr_in to = netinet_linux.to_sock_addr(peer);
netinet_linux.sockaddr to = netinet_linux.to_sock_addr(peer);
LibQuiche.quiche_conn quicheConn = ((LibQuiche_linux)LibQuiche.Holder.instance()).quiche_connect(peer.getHostName(), scid, new size_t(scid.length), to, new size_t(to.size()), libQuicheConfig);
return new QuicheConnection(quicheConn, libQuicheConfig);
}
else if (isMac())
{
netinet_macos.sockaddr_in to = netinet_macos.to_sock_addr(peer);
netinet_macos.sockaddr to = netinet_macos.to_sock_addr(peer);
LibQuiche.quiche_conn quicheConn = ((LibQuiche_macos)LibQuiche.Holder.instance()).quiche_connect(peer.getHostName(), scid, new size_t(scid.length), to, new size_t(to.size()), libQuicheConfig);
return new QuicheConnection(quicheConn, libQuicheConfig);
}
@ -324,12 +324,12 @@ public class QuicheConnection
LibQuiche.quiche_conn quicheConn;
if (isLinux())
{
netinet_linux.sockaddr_in from = netinet_linux.to_sock_addr(peer);
netinet_linux.sockaddr from = netinet_linux.to_sock_addr(peer);
quicheConn = ((LibQuiche_linux)LibQuiche.Holder.instance()).quiche_accept(dcid, dcid_len.getPointee(), odcid, new size_t(odcid.length), from, new size_t(from.size()), libQuicheConfig);
}
else if (isMac())
{
netinet_macos.sockaddr_in from = netinet_macos.to_sock_addr(peer);
netinet_macos.sockaddr from = netinet_macos.to_sock_addr(peer);
quicheConn = ((LibQuiche_macos)LibQuiche.Holder.instance()).quiche_accept(dcid, dcid_len.getPointee(), odcid, new size_t(odcid.length), from, new size_t(from.size()), libQuicheConfig);
}
else
@ -396,8 +396,8 @@ public class QuicheConnection
if (isLinux())
{
LibQuiche_linux.quiche_recv_info info = new LibQuiche_linux.quiche_recv_info();
netinet_linux.sockaddr_in from = netinet_linux.to_sock_addr(peer);
info.from = netinet_linux.sockaddr_in.byReference(from);
netinet_linux.sockaddr from = netinet_linux.to_sock_addr(peer);
info.from = netinet_linux.sockaddr.byReference(from);
info.from_len = new size_t(from.size());
received = ((LibQuiche_linux)libQuiche()).quiche_conn_recv(quicheConn, buffer, new size_t(buffer.remaining()), info).intValue();
@ -405,8 +405,8 @@ public class QuicheConnection
else if (isMac())
{
LibQuiche_macos.quiche_recv_info info = new LibQuiche_macos.quiche_recv_info();
netinet_macos.sockaddr_in from = netinet_macos.to_sock_addr(peer);
info.from = netinet_macos.sockaddr_in.byReference(from);
netinet_macos.sockaddr from = netinet_macos.to_sock_addr(peer);
info.from = netinet_macos.sockaddr.byReference(from);
info.from_len = new size_t(from.size());
received = ((LibQuiche_macos)libQuiche()).quiche_conn_recv(quicheConn, buffer, new size_t(buffer.remaining()), info).intValue();

View File

@ -28,10 +28,10 @@ public interface LibQuiche_linux extends LibQuiche
LibQuiche INSTANCE = Native.load("quiche", LibQuiche_linux.class);
// Creates a new client-side connection.
quiche_conn quiche_connect(String server_name, byte[] scid, size_t scid_len, netinet_linux.sockaddr_in to, size_t to_len, quiche_config config);
quiche_conn quiche_connect(String server_name, byte[] scid, size_t scid_len, netinet_linux.sockaddr to, size_t to_len, quiche_config config);
// Creates a new server-side connection.
quiche_conn quiche_accept(byte[] scid, size_t scid_len, byte[] odcid, size_t odcid_len, netinet_linux.sockaddr_in from, size_t from_len, quiche_config config);
quiche_conn quiche_accept(byte[] scid, size_t scid_len, byte[] odcid, size_t odcid_len, netinet_linux.sockaddr from, size_t from_len, quiche_config config);
@Structure.FieldOrder({"to", "to_len", "at"})
class quiche_send_info extends Structure
@ -47,7 +47,7 @@ public interface LibQuiche_linux extends LibQuiche
@Structure.FieldOrder({"from", "from_len"})
class quiche_recv_info extends Structure
{
public netinet_linux.sockaddr_in.ByReference from;
public netinet_linux.sockaddr.ByReference from;
public size_t from_len;
}

View File

@ -14,11 +14,11 @@
package org.eclipse.jetty.quic.quiche.ffi.linux;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
@ -30,20 +30,34 @@ public interface netinet_linux
uint16_t AF_INET = new uint16_t(2);
uint16_t AF_INET6 = new uint16_t(10);
static sockaddr_in to_sock_addr(SocketAddress socketAddress)
static sockaddr to_sock_addr(SocketAddress socketAddress)
{
if (!(socketAddress instanceof InetSocketAddress))
throw new IllegalArgumentException("Expected InetSocketAddress instance, got: " + socketAddress);
InetSocketAddress inetSocketAddress = (InetSocketAddress)socketAddress;
InetAddress address = inetSocketAddress.getAddress();
if (!(address instanceof Inet4Address))
throw new UnsupportedOperationException("TODO: only ipv4 is supported for now");
sockaddr_in sa = new sockaddr_in();
sa.sin_family = AF_INET;
sa.sin_addr = new uint32_t(ByteBuffer.wrap(address.getAddress()).order(ByteOrder.nativeOrder()).getInt());
sa.sin_port = new uint16_t(inetSocketAddress.getPort());
return sa;
if (address instanceof Inet4Address)
{
sockaddr_in sin = new sockaddr_in();
sin.sin_family = AF_INET;
sin.sin_addr = new uint32_t(ByteBuffer.wrap(address.getAddress()).getInt());
sin.sin_port = new uint16_t(inetSocketAddress.getPort());
return sin.to_sockaddr();
}
else if (address instanceof Inet6Address)
{
sockaddr_in6 sin6 = new sockaddr_in6();
sin6.sin6_family = AF_INET6;
System.arraycopy(address.getAddress(), 0, sin6.sin6_addr, 0, sin6.sin6_addr.length);
sin6.sin6_port = new uint16_t(inetSocketAddress.getPort());
sin6.sin6_flowinfo = new uint32_t(0);
sin6.sin6_scope_id = new uint32_t(0);
return sin6.to_sockaddr();
}
else
{
throw new UnsupportedOperationException("Unsupported InetAddress: " + address);
}
}
@Structure.FieldOrder({"sa_family", "sa_data"})
@ -51,6 +65,25 @@ public interface netinet_linux
{
public uint16_t sa_family;
public byte[] sa_data = new byte[14]; // 14 bytes of protocol address
private sockaddr(Pointer p)
{
super(p);
read();
}
public static sockaddr.ByReference byReference(sockaddr sa)
{
return new sockaddr.ByReference(sa.getPointer());
}
public static class ByReference extends sockaddr implements Structure.ByReference
{
private ByReference(Pointer p)
{
super(p);
}
}
}
@Structure.FieldOrder({"sin_family", "sin_port", "sin_addr", "sin_zero"})
@ -61,39 +94,27 @@ public interface netinet_linux
public uint32_t sin_addr;
public byte[] sin_zero = new byte[8]; // padding to have the same size as sockaddr
public sockaddr_in()
public sockaddr to_sockaddr()
{
}
private sockaddr_in(Pointer p)
{
super(p);
read();
}
public static ByReference byReference(sockaddr_in inet)
{
inet.write();
return new ByReference(inet.getPointer());
}
public static class ByReference extends sockaddr_in implements Structure.ByReference
{
private ByReference(Pointer p)
{
super(p);
}
write();
return new sockaddr(getPointer());
}
}
@Structure.FieldOrder({"sin6_family", "sin6_port", "sin6_flowinfo", "s6_addr", "sin6_scope_id"})
@Structure.FieldOrder({"sin6_family", "sin6_port", "sin6_flowinfo", "sin6_addr", "sin6_scope_id"})
class sockaddr_in6 extends Structure
{
public uint16_t sin6_family;
public uint16_t sin6_port;
public uint32_t sin6_flowinfo;
public byte[] s6_addr = new byte[16];
public byte[] sin6_addr = new byte[16];
public uint32_t sin6_scope_id;
public sockaddr to_sockaddr()
{
write();
return new sockaddr(getPointer());
}
}
@Structure.FieldOrder({"ss_family", "ss_zero"})

View File

@ -28,10 +28,10 @@ public interface LibQuiche_macos extends LibQuiche
LibQuiche INSTANCE = Native.load("quiche", LibQuiche_macos.class);
// Creates a new client-side connection.
quiche_conn quiche_connect(String server_name, byte[] scid, size_t scid_len, netinet_macos.sockaddr_in to, size_t to_len, quiche_config config);
quiche_conn quiche_connect(String server_name, byte[] scid, size_t scid_len, netinet_macos.sockaddr to, size_t to_len, quiche_config config);
// Creates a new server-side connection.
quiche_conn quiche_accept(byte[] scid, size_t scid_len, byte[] odcid, size_t odcid_len, netinet_macos.sockaddr_in from, size_t from_len, quiche_config config);
quiche_conn quiche_accept(byte[] scid, size_t scid_len, byte[] odcid, size_t odcid_len, netinet_macos.sockaddr from, size_t from_len, quiche_config config);
@Structure.FieldOrder({"to", "to_len", "at"})
class quiche_send_info extends Structure
@ -47,7 +47,7 @@ public interface LibQuiche_macos extends LibQuiche
@Structure.FieldOrder({"from", "from_len"})
class quiche_recv_info extends Structure
{
public netinet_macos.sockaddr_in.ByReference from;
public netinet_macos.sockaddr.ByReference from;
public size_t from_len;
}

View File

@ -14,11 +14,11 @@
package org.eclipse.jetty.quic.quiche.ffi.macos;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
@ -31,21 +31,36 @@ public interface netinet_macos
uint8_t AF_INET = new uint8_t((byte)2);
uint8_t AF_INET6 = new uint8_t((byte)30);
static sockaddr_in to_sock_addr(SocketAddress socketAddress)
static sockaddr to_sock_addr(SocketAddress socketAddress)
{
if (!(socketAddress instanceof InetSocketAddress))
throw new IllegalArgumentException("Expected InetSocketAddress instance, got: " + socketAddress);
InetSocketAddress inetSocketAddress = (InetSocketAddress)socketAddress;
InetAddress address = inetSocketAddress.getAddress();
if (!(address instanceof Inet4Address))
throw new UnsupportedOperationException("TODO: only ipv4 is supported for now");
sockaddr_in sa = new sockaddr_in();
sa.sin_len = new uint8_t((byte)sa.size());
sa.sin_family = AF_INET;
sa.sin_addr = new uint32_t(ByteBuffer.wrap(address.getAddress()).order(ByteOrder.nativeOrder()).getInt());
sa.sin_port = new uint16_t(inetSocketAddress.getPort());
return sa;
if (address instanceof Inet4Address)
{
sockaddr_in sin = new sockaddr_in();
sin.sin_len = new uint8_t((byte)sin.size());
sin.sin_family = AF_INET;
sin.sin_addr = new uint32_t(ByteBuffer.wrap(address.getAddress()).getInt());
sin.sin_port = new uint16_t(inetSocketAddress.getPort());
return sin.to_sockaddr();
}
else if (address instanceof Inet6Address)
{
sockaddr_in6 sin6 = new sockaddr_in6();
sin6.sin6_len = new uint8_t((byte)sin6.size());
sin6.sin6_family = AF_INET6;
System.arraycopy(address.getAddress(), 0, sin6.sin6_addr, 0, sin6.sin6_addr.length);
sin6.sin6_port = new uint16_t(inetSocketAddress.getPort());
sin6.sin6_flowinfo = new uint32_t(0);
sin6.sin6_scope_id = new uint32_t(0);
return sin6.to_sockaddr();
}
else
{
throw new UnsupportedOperationException("Unsupported InetAddress: " + address);
}
}
@Structure.FieldOrder({"sa_len", "sa_family", "sa_data"})
@ -54,6 +69,25 @@ public interface netinet_macos
public uint8_t sa_len;
public uint8_t sa_family;
public byte[] sa_data = new byte[14]; // 14 bytes of protocol address
private sockaddr(Pointer p)
{
super(p);
read();
}
public static sockaddr.ByReference byReference(sockaddr sa)
{
return new sockaddr.ByReference(sa.getPointer());
}
public static class ByReference extends sockaddr implements Structure.ByReference
{
private ByReference(Pointer p)
{
super(p);
}
}
}
@Structure.FieldOrder({"sin_len", "sin_family", "sin_port", "sin_addr", "sin_zero"})
@ -65,40 +99,28 @@ public interface netinet_macos
public uint32_t sin_addr;
public byte[] sin_zero = new byte[8]; // padding to have the same size as sockaddr
public sockaddr_in()
public sockaddr to_sockaddr()
{
}
private sockaddr_in(Pointer p)
{
super(p);
read();
}
public static ByReference byReference(sockaddr_in inet)
{
inet.write();
return new ByReference(inet.getPointer());
}
public static class ByReference extends sockaddr_in implements Structure.ByReference
{
private ByReference(Pointer p)
{
super(p);
}
write();
return new sockaddr(getPointer());
}
}
@Structure.FieldOrder({"sin6_len", "sin6_family", "sin6_port", "sin6_flowinfo", "s6_addr", "sin6_scope_id"})
@Structure.FieldOrder({"sin6_len", "sin6_family", "sin6_port", "sin6_flowinfo", "sin6_addr", "sin6_scope_id"})
class sockaddr_in6 extends Structure
{
public uint8_t sin6_len;
public uint8_t sin6_family;
public uint16_t sin6_port;
public uint32_t sin6_flowinfo;
public byte[] s6_addr = new byte[16];
public byte[] sin6_addr = new byte[16];
public uint32_t sin6_scope_id;
public sockaddr to_sockaddr()
{
write();
return new sockaddr(getPointer());
}
}
@Structure.FieldOrder({"ss_len", "ss_family", "ss_zero"})