From 68916c229599cf9e350a8c088ce3e8f13965599a Mon Sep 17 00:00:00 2001 From: zerou Date: Sat, 11 Jul 2026 14:03:47 +0200 Subject: [PATCH 1/4] WASMImpl/Java: introduce nullability annotations + fix some IntelliJ IDEA warnings Signed-off-by: zerou --- WASMImpl/Java/pom.xml | 6 + .../com/gitlab/luxon_project/LuxonServer.java | 959 +++++++++--------- 2 files changed, 484 insertions(+), 481 deletions(-) diff --git a/WASMImpl/Java/pom.xml b/WASMImpl/Java/pom.xml index f1089ab..44167c8 100644 --- a/WASMImpl/Java/pom.xml +++ b/WASMImpl/Java/pom.xml @@ -27,6 +27,12 @@ wasi ${chicory.version} + + org.jetbrains + annotations + 26.1.0 + provided + diff --git a/WASMImpl/Java/src/main/java/com/gitlab/luxon_project/LuxonServer.java b/WASMImpl/Java/src/main/java/com/gitlab/luxon_project/LuxonServer.java index 6a5bf78..a37065f 100644 --- a/WASMImpl/Java/src/main/java/com/gitlab/luxon_project/LuxonServer.java +++ b/WASMImpl/Java/src/main/java/com/gitlab/luxon_project/LuxonServer.java @@ -8,7 +8,10 @@ import com.dylibso.chicory.runtime.Memory; import com.dylibso.chicory.wasi.WasiOptions; import com.dylibso.chicory.wasi.WasiPreview1; +import com.dylibso.chicory.wasm.WasmModule; import com.dylibso.chicory.wasm.types.ValueType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -23,6 +26,7 @@ import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; +import java.nio.channels.UnsupportedAddressTypeException; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.security.SecureRandom; @@ -33,21 +37,20 @@ import java.util.Map; public class LuxonServer { - private static final int O_NONBLOCK = 0x00000800; private static final int F_GETFL = 3; private static final int F_SETFL = 4; - + private static final int AF_UNSPEC = 0; private static final int AF_INET = 2; private static final int AF_INET6 = 10; - + private static final int SOCK_STREAM = 1; private static final int SOCK_DGRAM = 2; - + private static final int IPPROTO_TCP = 6; private static final int IPPROTO_UDP = 17; - + private static final int AI_PASSIVE = 0x0001; private static final int AI_CANONNAME = 0x0002; private static final int AI_NUMERICHOST = 0x0004; @@ -55,7 +58,7 @@ public class LuxonServer { private static final int AI_ALL = 0x0010; private static final int AI_ADDRCONFIG = 0x0020; // accepted, ignored private static final int AI_NUMERICSERV = 0x0400; - + private static final int EAI_BADFLAGS = -1; private static final int EAI_NONAME = -2; private static final int EAI_AGAIN = -3; @@ -64,84 +67,81 @@ public class LuxonServer { private static final int EAI_SOCKTYPE = -7; private static final int EAI_SERVICE = -8; private static final int EAI_MEMORY = -10; - + private static final int SOCKADDR_IN_LEN = 16; private static final int SOCKADDR_IN6_LEN = 28; private static final int ADDRINFO_LEN = 32; - + // Emulated POSIX descriptor map starting at 100 to clear standard WASI descriptors (0-3) private static final Map sockets = new HashMap<>(); private static int nextFd = 100; - + private static class SocketHandle { final int fd; final int family; boolean isServer = false; - boolean isUdp = false; + boolean isUdp; boolean nonBlocking = false; ServerSocketChannel serverChannel; SocketChannel socketChannel; DatagramChannel datagramChannel; - + SocketHandle(int fd, int family, boolean isUdp) { this.fd = fd; this.family = family; this.isUdp = isUdp; } } - - public static void main(String[] args) { + + public static void main(@NotNull String @NotNull [] args) { try { - WasiOptions wasiOptions = WasiOptions.builder() - .withStdout(System.out) - .withStderr(System.err) - .withDirectory(".", Path.of(".")) - .build(); - - WasiPreview1 wasi = WasiPreview1.builder() - .withOptions(wasiOptions) - .build(); - - List functions = new ArrayList<>(Arrays.asList(wasi.toHostFunctions())); - - ImportFunction origPathOpen = null; - ImportFunction origFdRead = null; - ImportFunction origFdClose = null; - - for (ImportFunction f : functions) { - if ("wasi_snapshot_preview1".equals(f.module())) { - if ("path_open".equals(f.name())) origPathOpen = f; - else if ("fd_read".equals(f.name())) origFdRead = f; - else if ("fd_close".equals(f.name())) origFdClose = f; + @NotNull WasiOptions wasiOptions = WasiOptions.builder() + .withStdout(System.out) + .withStderr(System.err) + .withDirectory(".", Path.of(".")) + .build(); + + //noinspection resource + @NotNull List<@NotNull ImportFunction> functions = new ArrayList<>(Arrays.asList(WasiPreview1.builder().withOptions(wasiOptions).build().toHostFunctions())); + + @Nullable ImportFunction origPathOpen = null; + @Nullable ImportFunction origFdRead = null; + @Nullable ImportFunction origFdClose = null; + + for (@NotNull ImportFunction function : functions) { + if ("wasi_snapshot_preview1".equals(function.module())) { + if ("path_open".equals(function.name())) origPathOpen = function; + else if ("fd_read".equals(function.name())) origFdRead = function; + else if ("fd_close".equals(function.name())) origFdClose = function; } } - - final ImportFunction finalPathOpen = origPathOpen; - final ImportFunction finalFdRead = origFdRead; - final ImportFunction finalFdClose = origFdClose; - + + final @Nullable ImportFunction finalPathOpen = origPathOpen; + final @Nullable ImportFunction finalFdRead = origFdRead; + final @Nullable ImportFunction finalFdClose = origFdClose; + // Reserve a high virtual FD number that won't collide with WASI or sockets final int RANDOM_FD = 9999; - final SecureRandom secureRandom = new SecureRandom(); - + final @NotNull SecureRandom secureRandom = new SecureRandom(); + if (finalPathOpen != null) { functions.remove(finalPathOpen); functions.add(new HostFunction(finalPathOpen.module(), finalPathOpen.name(), finalPathOpen.paramTypes(), finalPathOpen.returnTypes(), (instance, wasmArgs) -> { int pathPtr = (int) wasmArgs[2]; int pathLen = (int) wasmArgs[3]; int resultFdPtr = (int) wasmArgs[8]; - - Memory mem = instance.memory(); - String path = new String(mem.readBytes(pathPtr, pathLen), StandardCharsets.UTF_8); - + + @NotNull Memory mem = instance.memory(); + @NotNull String path = new String(mem.readBytes(pathPtr, pathLen), StandardCharsets.UTF_8); + if (path.endsWith("/dev/random") || path.endsWith("/dev/urandom") || path.equals("dev/random") || path.equals("dev/urandom")) { writeIntLE(mem, resultFdPtr, RANDOM_FD); - return new long[] { 0 }; // WASI_ESUCCESS + return new long[]{0}; // WASI_ESUCCESS } return finalPathOpen.handle().apply(instance, wasmArgs); })); } - + if (finalFdRead != null) { functions.remove(finalFdRead); functions.add(new HostFunction(finalFdRead.module(), finalFdRead.name(), finalFdRead.paramTypes(), finalFdRead.returnTypes(), (instance, wasmArgs) -> { @@ -150,91 +150,91 @@ public static void main(String[] args) { int iovsPtr = (int) wasmArgs[1]; int iovsLen = (int) wasmArgs[2]; int resultSizePtr = (int) wasmArgs[3]; - Memory mem = instance.memory(); - + @NotNull Memory mem = instance.memory(); + int totalRead = 0; for (int i = 0; i < iovsLen; i++) { int bufPtr = readIntLE(mem, iovsPtr + (i * 8)); int bufLen = readIntLE(mem, iovsPtr + (i * 8) + 4); - - byte[] randBytes = new byte[bufLen]; + + byte @NotNull [] randBytes = new byte[bufLen]; secureRandom.nextBytes(randBytes); mem.write(bufPtr, randBytes); totalRead += bufLen; } writeIntLE(mem, resultSizePtr, totalRead); - return new long[] { 0 }; // WASI_ESUCCESS + return new long[]{0}; // WASI_ESUCCESS } return finalFdRead.handle().apply(instance, wasmArgs); })); } - + if (finalFdClose != null) { functions.remove(finalFdClose); functions.add(new HostFunction(finalFdClose.module(), finalFdClose.name(), finalFdClose.paramTypes(), finalFdClose.returnTypes(), (instance, wasmArgs) -> { int fd = (int) wasmArgs[0]; if (fd == RANDOM_FD) { - return new long[] { 0 }; // WASI_ESUCCESS + return new long[]{0}; // WASI_ESUCCESS } return finalFdClose.handle().apply(instance, wasmArgs); })); } - + functions.addAll(registerSocketEnvironmentImports()); - - ImportValues imports = ImportValues.builder() - .withFunctions(functions) - .build(); - - var module = LuxonServerModule.load(); - Instance instance = Instance.builder(module) - .withMachineFactory(LuxonServerModule::create) - .withImportValues(imports) - .build(); - - ExportFunction startFn = instance.export("_start"); + + @NotNull ImportValues imports = ImportValues.builder() + .withFunctions(functions) + .build(); + + @NotNull WasmModule module = LuxonServerModule.load(); + @NotNull Instance instance = Instance.builder(module) + .withMachineFactory(LuxonServerModule::create) + .withImportValues(imports) + .build(); + + @Nullable ExportFunction startFn = instance.export("_start"); if (startFn != null) { startFn.apply(); } - - } catch (Exception e) { + + } catch (@NotNull Exception e) { System.err.println("Fatal execution error inside WASM host wrapper: " + e.getMessage()); e.printStackTrace(); System.exit(1); } } - - private static List registerSocketEnvironmentImports() { - List env = new ArrayList<>(); - final String NS = "env"; - + + private static @NotNull List<@NotNull ImportFunction> registerSocketEnvironmentImports() { + @NotNull List<@NotNull ImportFunction> env = new ArrayList<>(); + final @NotNull String namespace = "env"; + // u32 w2c_env_socket_socket(domain, type, protocol) -> 3 params - env.add(new HostFunction(NS, "socket_socket", params(3), returns(1), (instance, args) -> { + env.add(new HostFunction(namespace, "socket_socket", params(3), returns(1), (instance, args) -> { int domain = (int) args[0]; int type = (int) args[1]; boolean isUdp = (type == SOCK_DGRAM); int fd = nextFd++; sockets.put(fd, new SocketHandle(fd, domain, isUdp)); - return new long[] { fd }; + return new long[]{fd}; })); - + // u32 w2c_env_socket_bind(sockfd, addr_ptr, addrlen) -> 3 params - env.add(new HostFunction(NS, "socket_bind", params(3), returns(1), (instance, args) -> { + env.add(new HostFunction(namespace, "socket_bind", params(3), returns(1), (instance, args) -> { int sockfd = (int) args[0]; int addrPtr = (int) args[1]; int addrlen = (int) args[2]; - SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[] { -1L }; - + @Nullable SocketHandle h = sockets.get(sockfd); + if (h == null) return new long[]{-1L}; + try { - Memory mem = instance.memory(); + @NotNull Memory mem = instance.memory(); int family = mem.readBytes(addrPtr, 1)[0] & 0xFF; int port = ((mem.readBytes(addrPtr + 2, 2)[0] & 0xFF) << 8) | (mem.readBytes(addrPtr + 2, 2)[1] & 0xFF); - - InetAddress addr = (family == AF_INET6 || addrlen == 28) ? + + @NotNull InetAddress addr = (family == AF_INET6 || addrlen == 28) ? InetAddress.getByAddress(mem.readBytes(addrPtr + 8, 16)) : InetAddress.getByAddress(mem.readBytes(addrPtr + 4, 4)); - + try { if (h.isUdp) { h.datagramChannel = DatagramChannel.open(); @@ -246,8 +246,8 @@ private static List registerSocketEnvironmentImports() { h.serverChannel.configureBlocking(!h.nonBlocking); h.serverChannel.bind(new InetSocketAddress(addr, port)); } - } catch (java.nio.channels.UnsupportedAddressTypeException e) { - InetAddress fallback = getFallbackAddress(addr); + } catch (UnsupportedAddressTypeException e) { + @Nullable InetAddress fallback = getFallbackAddress(addr); if (fallback != null) { System.err.println("WARNING: Unsupported address type for bind. Falling back from " + addr + " to " + fallback); if (h.isUdp) { @@ -259,165 +259,165 @@ private static List registerSocketEnvironmentImports() { throw e; } } - return new long[] { 0 }; - } catch (Exception e) { - return new long[] { -1L }; + return new long[]{0}; + } catch (@NotNull Exception e) { + return new long[]{-1L}; } })); - + // u32 w2c_env_socket_listen(sockfd, backlog) -> 2 params - env.add(new HostFunction(NS, "socket_listen", params(2), returns(1), (instance, args) -> { - SocketHandle h = sockets.get((int) args[0]); - if (h != null && h.isUdp) return new long[] { 0 }; - return new long[] { (h != null && h.isServer) ? 0 : -1L }; + env.add(new HostFunction(namespace, "socket_listen", params(2), returns(1), (instance, args) -> { + @Nullable SocketHandle h = sockets.get((int) args[0]); + if (h != null && h.isUdp) return new long[]{0}; + return new long[]{(h != null && h.isServer) ? 0 : -1L}; })); - + // u32 w2c_env_socket_accept(sockfd, addr_ptr, addrlen_ptr) -> 3 params - env.add(new HostFunction(NS, "socket_accept", params(3), returns(1), (instance, args) -> { + env.add(new HostFunction(namespace, "socket_accept", params(3), returns(1), (instance, args) -> { int sockfd = (int) args[0]; int addrPtr = (int) args[1]; int addrlenPtr = (int) args[2]; - - SocketHandle h = sockets.get(sockfd); + + @Nullable SocketHandle h = sockets.get(sockfd); if (h == null || h.isUdp || !h.isServer || h.serverChannel == null) { - return new long[] { -1L }; + return new long[]{-1L}; } - + // POSIX ABI: if addr != NULL, addrlen must be a valid value-result pointer. if (addrPtr != 0 && addrlenPtr == 0) { - return new long[] { -1L }; + return new long[]{-1L}; } - + try { - SocketChannel client = h.serverChannel.accept(); + @Nullable SocketChannel client = h.serverChannel.accept(); if (client == null) { - return new long[] { -1L }; + return new long[]{-1L}; } - + client.configureBlocking(true); - + int clientFd = nextFd++; - SocketHandle clientHandle = new SocketHandle(clientFd, h.family, false); + @NotNull SocketHandle clientHandle = new SocketHandle(clientFd, h.family, false); clientHandle.socketChannel = client; sockets.put(clientFd, clientHandle); - + if (addrPtr != 0) { - SocketAddress remote = client.getRemoteAddress(); + @Nullable SocketAddress remote = client.getRemoteAddress(); if (!(remote instanceof InetSocketAddress) || - !writeSockaddrResult(instance.memory(), addrPtr, addrlenPtr, (InetSocketAddress) remote, h.family)) { + writeSockaddrResult(instance.memory(), addrPtr, addrlenPtr, (InetSocketAddress) remote, h.family)) { closeHandle(clientFd); - return new long[] { -1L }; + return new long[]{-1L}; } } - - return new long[] { clientFd }; - } catch (IOException e) { - return new long[] { -1L }; + + return new long[]{clientFd}; + } catch (@NotNull IOException e) { + return new long[]{-1L}; } })); - + // u32 w2c_env_socket_connect(sockfd, addr_ptr, addrlen) -> 3 params - env.add(new HostFunction(NS, "socket_connect", params(3), returns(1), (instance, args) -> { + env.add(new HostFunction(namespace, "socket_connect", params(3), returns(1), (instance, args) -> { int sockfd = (int) args[0]; int addrPtr = (int) args[1]; int addrlen = (int) args[2]; - SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[] { -1L }; - + @Nullable SocketHandle h = sockets.get(sockfd); + if (h == null) return new long[]{-1L}; + try { - Memory mem = instance.memory(); + @NotNull Memory mem = instance.memory(); int family = mem.readBytes(addrPtr, 1)[0] & 0xFF; int port = ((mem.readBytes(addrPtr + 2, 2)[0] & 0xFF) << 8) | (mem.readBytes(addrPtr + 2, 2)[1] & 0xFF); - InetAddress addr = (family == AF_INET6 || addrlen == 28) ? + @NotNull InetAddress addr = (family == AF_INET6 || addrlen == 28) ? InetAddress.getByAddress(mem.readBytes(addrPtr + 8, 16)) : InetAddress.getByAddress(mem.readBytes(addrPtr + 4, 4)); - + try { if (h.isUdp) { h.datagramChannel = DatagramChannel.open(); h.datagramChannel.configureBlocking(!h.nonBlocking); h.datagramChannel.connect(new InetSocketAddress(addr, port)); - return new long[] { 0 }; + return new long[]{0}; } else { h.socketChannel = SocketChannel.open(); h.socketChannel.configureBlocking(!h.nonBlocking); boolean success = h.socketChannel.connect(new InetSocketAddress(addr, port)); - return new long[] { success ? 0 : -1L }; + return new long[]{success ? 0 : -1L}; } - } catch (java.nio.channels.UnsupportedAddressTypeException e) { - InetAddress fallback = getFallbackAddress(addr); + } catch (@NotNull UnsupportedAddressTypeException e) { + @Nullable InetAddress fallback = getFallbackAddress(addr); if (fallback != null) { System.err.println("WARNING: Unsupported address type for connect. Falling back from " + addr + " to " + fallback); if (h.isUdp) { h.datagramChannel.connect(new InetSocketAddress(fallback, port)); - return new long[] { 0 }; + return new long[]{0}; } else { boolean success = h.socketChannel.connect(new InetSocketAddress(fallback, port)); - return new long[] { success ? 0 : -1L }; + return new long[]{success ? 0 : -1L}; } } else { throw e; // Rethrow if we can't formulate a valid fallback } } - } catch (Exception e) { - return new long[] { -1L }; + } catch (@NotNull Exception e) { + return new long[]{-1L}; } })); - - env.add(new HostFunction(NS, "socket_send", params(4), returns(1), (instance, args) -> + + env.add(new HostFunction(namespace, "socket_send", params(4), returns(1), (instance, args) -> doSend(instance, (int) args[0], (int) args[1], (int) args[2], (int) args[3], 0, 0) )); - - env.add(new HostFunction(NS, "socket_recv", params(4), returns(1), (instance, args) -> + + env.add(new HostFunction(namespace, "socket_recv", params(4), returns(1), (instance, args) -> doRecv(instance, (int) args[0], (int) args[1], (int) args[2], (int) args[3], 0, 0) )); - - env.add(new HostFunction(NS, "socket_sendto", params(6), returns(1), (instance, args) -> + + env.add(new HostFunction(namespace, "socket_sendto", params(6), returns(1), (instance, args) -> doSend(instance, (int) args[0], (int) args[1], (int) args[2], (int) args[3], (int) args[4], (int) args[5]) )); - - env.add(new HostFunction(NS, "socket_recvfrom", params(6), returns(1), (instance, args) -> + + env.add(new HostFunction(namespace, "socket_recvfrom", params(6), returns(1), (instance, args) -> doRecv(instance, (int) args[0], (int) args[1], (int) args[2], (int) args[3], (int) args[4], (int) args[5]) )); - - env.add(new HostFunction(NS, "socket_setsockopt", params(5), returns(1), (instance, args) -> new long[] { 0 })); - env.add(new HostFunction(NS, "socket_shutdown", params(2), returns(1), (instance, args) -> closeHandle((int) args[0]))); - env.add(new HostFunction(NS, "socket_close", params(1), returns(1), (instance, args) -> closeHandle((int) args[0]))); - + + env.add(new HostFunction(namespace, "socket_setsockopt", params(5), returns(1), (instance, args) -> new long[]{0})); + env.add(new HostFunction(namespace, "socket_shutdown", params(2), returns(1), (instance, args) -> closeHandle((int) args[0]))); + env.add(new HostFunction(namespace, "socket_close", params(1), returns(1), (instance, args) -> closeHandle((int) args[0]))); + // u32 w2c_env_socket_fcntl(fd, cmd, arg) -> 3 params - env.add(new HostFunction(NS, "socket_fcntl", params(3), returns(1), (instance, args) -> { - SocketHandle h = sockets.get((int) args[0]); - if (h == null) return new long[] { -1L }; + env.add(new HostFunction(namespace, "socket_fcntl", params(3), returns(1), (instance, args) -> { + @Nullable SocketHandle h = sockets.get((int) args[0]); + if (h == null) return new long[]{-1L}; int cmd = (int) args[1]; int arg = (int) args[2]; - + if (cmd == F_GETFL) { - return new long[] { h.nonBlocking ? O_NONBLOCK : 0 }; + return new long[]{h.nonBlocking ? O_NONBLOCK : 0}; } else if (cmd == F_SETFL) { h.nonBlocking = (arg & O_NONBLOCK) != 0; try { if (h.serverChannel != null) h.serverChannel.configureBlocking(!h.nonBlocking); if (h.datagramChannel != null) h.datagramChannel.configureBlocking(!h.nonBlocking); if (h.socketChannel != null) h.socketChannel.configureBlocking(!h.nonBlocking); - return new long[] { 0 }; - } catch (IOException e) { - return new long[] { -1L }; + return new long[]{0}; + } catch (@NotNull IOException e) { + return new long[]{-1L}; } } - return new long[] { -1L }; + return new long[]{-1L}; })); - - env.add(new HostFunction(NS, "socket_ioctl", params(3), returns(1), (instance, args) -> new long[] { 0 })); - - env.add(new HostFunction(NS, "socket_inet_pton", params(3), returns(1), (instance, args) -> { + + env.add(new HostFunction(namespace, "socket_ioctl", params(3), returns(1), (instance, args) -> new long[]{0})); + + env.add(new HostFunction(namespace, "socket_inet_pton", params(3), returns(1), (instance, args) -> { int af = (int) args[0]; int srcPtr = (int) args[1]; int dstPtr = (int) args[2]; - + try { - Memory mem = instance.memory(); - String src = readNullTerminatedString(mem, srcPtr); - + @NotNull Memory mem = instance.memory(); + @NotNull String src = readNullTerminatedString(mem, srcPtr); + byte[] parsed; if (af == AF_INET) { parsed = parseIpv4Literal(src); @@ -425,45 +425,46 @@ private static List registerSocketEnvironmentImports() { parsed = parseIpv6Literal(src); } else { // POSIX: unsupported family => -1 / EAFNOSUPPORT. - return new long[] { -1L }; + return new long[]{-1L}; } - + if (parsed == null) { // Invalid presentation format. - return new long[] { 0 }; + return new long[]{0}; } - + mem.write(dstPtr, parsed); - return new long[] { 1 }; - } catch (Exception e) { - return new long[] { 0 }; + return new long[]{1}; + } catch (@NotNull Exception e) { + return new long[]{0}; } })); - - env.add(new HostFunction(NS, "socket_inet_ntop", params(4), returns(1), (instance, args) -> { + + env.add(new HostFunction(namespace, "socket_inet_ntop", params(4), returns(1), (instance, args) -> { try { - Memory mem = instance.memory(); + @NotNull Memory mem = instance.memory(); int af = (int) args[0]; - byte[] ipBytes = mem.readBytes((int) args[1], af == AF_INET6 ? 16 : 4); - byte[] strBytes = InetAddress.getByAddress(ipBytes).getHostAddress().getBytes(StandardCharsets.UTF_8); + byte @NotNull [] ipBytes = mem.readBytes((int) args[1], af == AF_INET6 ? 16 : 4); + byte @NotNull [] strBytes = InetAddress.getByAddress(ipBytes).getHostAddress().getBytes(StandardCharsets.UTF_8); if (strBytes.length + 1 <= (int) args[3]) { mem.write((int) args[2], strBytes); - mem.write((int) args[2] + strBytes.length, new byte[] { 0 }); - return new long[] { args[2] }; + mem.write((int) args[2] + strBytes.length, new byte[]{0}); + return new long[]{args[2]}; } - } catch (Exception e) {} - return new long[] { 0 }; + } catch (@NotNull Exception ignored) { + } + return new long[]{0}; })); - + // Selector loop evaluating Read/Write states asynchronously - env.add(new HostFunction(NS, "socket_select", params(5), returns(1), (instance, args) -> { + env.add(new HostFunction(namespace, "socket_select", params(5), returns(1), (instance, args) -> { int nfds = (int) args[0]; int readfdsPtr = (int) args[1]; int writefdsPtr = (int) args[2]; int exceptfdsPtr = (int) args[3]; int timeoutPtr = (int) args[4]; - Memory mem = instance.memory(); - + @NotNull Memory mem = instance.memory(); + long timeoutMs = 0; boolean hasTimeout = false; if (timeoutPtr != 0) { @@ -472,25 +473,25 @@ private static List registerSocketEnvironmentImports() { long usec = readLongLE(mem, timeoutPtr + 8); timeoutMs = (sec * 1000) + (usec / 1000); } - + try (Selector selector = Selector.open()) { - Map keyToFd = new HashMap<>(); - + @NotNull Map<@NotNull SelectionKey, @NotNull Integer> keyToFd = new HashMap<>(); + int bytesToClear = (nfds + 7) / 8; - + byte[] rfds = readfdsPtr != 0 && bytesToClear > 0 ? mem.readBytes(readfdsPtr, bytesToClear) : null; byte[] wfds = writefdsPtr != 0 && bytesToClear > 0 ? mem.readBytes(writefdsPtr, bytesToClear) : null; - + if (readfdsPtr != 0 && bytesToClear > 0) mem.write(readfdsPtr, new byte[bytesToClear]); if (writefdsPtr != 0 && bytesToClear > 0) mem.write(writefdsPtr, new byte[bytesToClear]); if (exceptfdsPtr != 0 && bytesToClear > 0) mem.write(exceptfdsPtr, new byte[bytesToClear]); - + for (int fd = 0; fd < nfds; fd++) { boolean wantsRead = rfds != null && (rfds[fd / 8] & (1 << (fd % 8))) != 0; boolean wantsWrite = wfds != null && (wfds[fd / 8] & (1 << (fd % 8))) != 0; - + if (wantsRead || wantsWrite) { - SocketHandle h = sockets.get(fd); + @Nullable SocketHandle h = sockets.get(fd); if (h != null) { int ops = 0; if (wantsRead) { @@ -500,9 +501,9 @@ private static List registerSocketEnvironmentImports() { if (wantsWrite && !h.isServer) { ops |= SelectionKey.OP_WRITE; } - + if (ops != 0) { - SelectionKey key = null; + @Nullable SelectionKey key = null; if (h.isServer && h.serverChannel != null) { if (h.serverChannel.isBlocking()) h.serverChannel.configureBlocking(false); key = h.serverChannel.register(selector, ops); @@ -518,7 +519,7 @@ private static List registerSocketEnvironmentImports() { } } } - + int readyCount = 0; if (!keyToFd.isEmpty()) { if (hasTimeout) { @@ -527,8 +528,8 @@ private static List registerSocketEnvironmentImports() { } else { selector.select(); } - - for (SelectionKey key : selector.selectedKeys()) { + + for (@NotNull SelectionKey key : selector.selectedKeys()) { int fd = keyToFd.get(key); if (readfdsPtr != 0 && (key.isReadable() || key.isAcceptable())) { byte[] b = mem.readBytes(readfdsPtr + (fd / 8), 1); @@ -546,93 +547,94 @@ private static List registerSocketEnvironmentImports() { } else if (hasTimeout && timeoutMs > 0) { Thread.sleep(timeoutMs); } - - for (SelectionKey key : keyToFd.keySet()) key.cancel(); + + for (@NotNull SelectionKey key : keyToFd.keySet()) key.cancel(); selector.selectNow(); - + for (int fd : keyToFd.values()) { - SocketHandle h = sockets.get(fd); + @Nullable SocketHandle h = sockets.get(fd); if (h != null) { if (h.isServer && h.serverChannel != null) h.serverChannel.configureBlocking(!h.nonBlocking); - else if (h.isUdp && h.datagramChannel != null) h.datagramChannel.configureBlocking(!h.nonBlocking); + else if (h.isUdp && h.datagramChannel != null) + h.datagramChannel.configureBlocking(!h.nonBlocking); else if (h.socketChannel != null) h.socketChannel.configureBlocking(!h.nonBlocking); } } - return new long[] { readyCount }; - } catch (Exception e) { - return new long[] { -1L }; + return new long[]{readyCount}; + } catch (@NotNull Exception e) { + return new long[]{-1L}; } })); - - env.add(new HostFunction(NS, "socket_getaddrinfo", params(4), returns(1), (instance, args) -> { - Memory mem = instance.memory(); - + + env.add(new HostFunction(namespace, "socket_getaddrinfo", params(4), returns(1), (instance, args) -> { + @NotNull Memory mem = instance.memory(); + int nodePtr = (int) args[0]; int servicePtr = (int) args[1]; int hintsPtr = (int) args[2]; int resPtr = (int) args[3]; - + if (resPtr == 0) { - return new long[] { EAI_FAIL }; + return new long[]{EAI_FAIL}; } writeIntLE(mem, resPtr, 0); - - String node = nodePtr != 0 ? readNullTerminatedString(mem, nodePtr) : null; - String service = servicePtr != 0 ? readNullTerminatedString(mem, servicePtr) : null; - + + @Nullable String node = nodePtr != 0 ? readNullTerminatedString(mem, nodePtr) : null; + @Nullable String service = servicePtr != 0 ? readNullTerminatedString(mem, servicePtr) : null; + if (node == null && service == null) { - return new long[] { EAI_NONAME }; + return new long[]{EAI_NONAME}; } - + int flags = 0; int family = AF_UNSPEC; int socktype = 0; int protocol = 0; - + if (hintsPtr != 0) { - flags = readIntLE(mem, hintsPtr + 0); + flags = readIntLE(mem, hintsPtr); family = readIntLE(mem, hintsPtr + 4); socktype = readIntLE(mem, hintsPtr + 8); protocol = readIntLE(mem, hintsPtr + 12); } - + int supportedFlags = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | - AI_V4MAPPED | AI_ALL | AI_ADDRCONFIG | AI_NUMERICSERV; - + AI_V4MAPPED | AI_ALL | AI_ADDRCONFIG | AI_NUMERICSERV; + if ((flags & ~supportedFlags) != 0) { - return new long[] { EAI_BADFLAGS }; + return new long[]{EAI_BADFLAGS}; } - + if (family != AF_UNSPEC && family != AF_INET && family != AF_INET6) { - return new long[] { EAI_FAMILY }; + return new long[]{EAI_FAMILY}; } - + if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM) { - return new long[] { EAI_SOCKTYPE }; + return new long[]{EAI_SOCKTYPE}; } - + if (protocol != 0 && protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) { - return new long[] { EAI_SERVICE }; + return new long[]{EAI_SERVICE}; } - + if ((socktype == SOCK_STREAM && protocol == IPPROTO_UDP) || (socktype == SOCK_DGRAM && protocol == IPPROTO_TCP)) { - return new long[] { EAI_SERVICE }; + return new long[]{EAI_SERVICE}; } - + int port = 0; if (service != null) { - Integer parsedPort = parseNumericService(service); + @Nullable Integer parsedPort = parseNumericService(service); if (parsedPort == null) { - return new long[] { EAI_SERVICE }; + return new long[]{EAI_SERVICE}; } port = parsedPort; } - - List addresses; - boolean numericNode = false; - + + @NotNull List<@NotNull InetAddress> addresses; + boolean numericNode; + try { if (node == null) { addresses = defaultAddressesForNullNode(family, (flags & AI_PASSIVE) != 0); @@ -640,43 +642,43 @@ private static List registerSocketEnvironmentImports() { byte[] v4 = parseIpv4Literal(node); byte[] v6 = (v4 == null) ? parseIpv6Literal(node) : null; numericNode = (v4 != null || v6 != null); - + if (numericNode) { - addresses = resolveNumericNode(node, family, flags, v4, v6); + addresses = resolveNumericNode(family, flags, v4, v6); } else { if ((flags & AI_NUMERICHOST) != 0) { - return new long[] { EAI_NONAME }; + return new long[]{EAI_NONAME}; } addresses = resolveDnsNode(node, family, flags); } } - } catch (UnknownHostException e) { - return new long[] { EAI_NONAME }; - } catch (Exception e) { - return new long[] { EAI_FAIL }; + } catch (@NotNull UnknownHostException e) { + return new long[]{EAI_NONAME}; + } catch (@NotNull Exception e) { + return new long[]{EAI_FAIL}; } - + if (addresses.isEmpty()) { - return new long[] { EAI_NONAME }; + return new long[]{EAI_NONAME}; } - - List pairs = buildSockProtoPairs(socktype, protocol); + + @NotNull List<@NotNull SockProtoPair> pairs = buildSockProtoPairs(socktype, protocol); if (pairs.isEmpty()) { - return new long[] { EAI_SERVICE }; + return new long[]{EAI_SERVICE}; } - - String canonName = ((flags & AI_CANONNAME) != 0 && node != null) ? node : null; - - List results = new ArrayList<>(); + + @Nullable String canonName = ((flags & AI_CANONNAME) != 0 && node != null) ? node : null; + + @NotNull List<@NotNull AddrInfoResult> results = new ArrayList<>(); boolean first = true; - - for (InetAddress addr : addresses) { + + for (@NotNull InetAddress addr : addresses) { byte[] raw = addr.getAddress(); int outFamily = raw.length == 16 ? AF_INET6 : AF_INET; int scopeId = (addr instanceof Inet6Address) ? ((Inet6Address) addr).getScopeId() : 0; byte[] sockaddr = encodeSockaddr(outFamily, raw, port, scopeId); - - for (SockProtoPair pair : pairs) { + + for (@NotNull SockProtoPair pair : pairs) { results.add(new AddrInfoResult( outFamily, pair.socktype, @@ -687,25 +689,25 @@ private static List registerSocketEnvironmentImports() { first = false; } } - - ExportFunction malloc = findExport(instance, "malloc", "_malloc"); - ExportFunction free = findExport(instance, "free", "_free"); + + @Nullable ExportFunction malloc = findExport(instance, "malloc", "_malloc"); + @Nullable ExportFunction free = findExport(instance, "free", "_free"); if (malloc == null) { - return new long[] { EAI_MEMORY }; + return new long[]{EAI_MEMORY}; } - - List allocated = new ArrayList<>(); - + + @NotNull List<@NotNull Integer> allocated = new ArrayList<>(); + try { int head = 0; int prev = 0; - - for (AddrInfoResult r : results) { + + for (@NotNull AddrInfoResult r : results) { int saPtr = guestMalloc(malloc, r.sockaddr.length); if (saPtr == 0) throw new OutOfMemoryError(); allocated.add(saPtr); mem.write(saPtr, r.sockaddr); - + int canonPtr = 0; if (r.canonName != null) { byte[] nameBytes = r.canonName.getBytes(StandardCharsets.UTF_8); @@ -713,14 +715,14 @@ private static List registerSocketEnvironmentImports() { if (canonPtr == 0) throw new OutOfMemoryError(); allocated.add(canonPtr); mem.write(canonPtr, nameBytes); - mem.write(canonPtr + nameBytes.length, new byte[] { 0 }); + mem.write(canonPtr + nameBytes.length, new byte[]{0}); } - + int aiPtr = guestMalloc(malloc, ADDRINFO_LEN); if (aiPtr == 0) throw new OutOfMemoryError(); allocated.add(aiPtr); - - writeIntLE(mem, aiPtr + 0, 0); + + writeIntLE(mem, aiPtr, 0); writeIntLE(mem, aiPtr + 4, r.family); writeIntLE(mem, aiPtr + 8, r.socktype); writeIntLE(mem, aiPtr + 12, r.protocol); @@ -728,7 +730,7 @@ private static List registerSocketEnvironmentImports() { writeIntLE(mem, aiPtr + 20, saPtr); writeIntLE(mem, aiPtr + 24, canonPtr); writeIntLE(mem, aiPtr + 28, 0); - + if (head == 0) { head = aiPtr; } else { @@ -736,10 +738,10 @@ private static List registerSocketEnvironmentImports() { } prev = aiPtr; } - + writeIntLE(mem, resPtr, head); - return new long[] { 0 }; - } catch (Throwable t) { + return new long[]{0}; + } catch (@NotNull Throwable t) { if (free != null) { for (int i = allocated.size() - 1; i >= 0; i--) { int ptr = allocated.get(i); @@ -747,22 +749,22 @@ private static List registerSocketEnvironmentImports() { } } writeIntLE(mem, resPtr, 0); - return new long[] { EAI_MEMORY }; + return new long[]{EAI_MEMORY}; } })); - - env.add(new HostFunction(NS, "socket_freeaddrinfo", params(1), returns(0), (instance, args) -> { - ExportFunction free = instance.export("free"); + + env.add(new HostFunction(namespace, "socket_freeaddrinfo", params(1), returns(0), (instance, args) -> { + @Nullable ExportFunction free = instance.export("free"); if (free == null) free = instance.export("_free"); if (free == null) return new long[0]; - - Memory mem = instance.memory(); + + @NotNull Memory mem = instance.memory(); int curr = (int) args[0]; while (curr != 0) { int addr = readIntLE(mem, curr + 20); int canon = readIntLE(mem, curr + 24); int next = readIntLE(mem, curr + 28); - + if (addr != 0) free.apply(addr); if (canon != 0) free.apply(canon); free.apply(curr); @@ -770,23 +772,23 @@ private static List registerSocketEnvironmentImports() { } return new long[0]; })); - + // u32 w2c_env_socket_getsockname(sockfd, addr_ptr, addrlen_ptr) -> 3 params - env.add(new HostFunction(NS, "socket_getsockname", params(3), returns(1), (instance, args) -> { + env.add(new HostFunction(namespace, "socket_getsockname", params(3), returns(1), (instance, args) -> { int sockfd = (int) args[0]; int addrPtr = (int) args[1]; int addrlenPtr = (int) args[2]; - - SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[] { -1L }; - + + @Nullable SocketHandle h = sockets.get(sockfd); + if (h == null) return new long[]{-1L}; + // POSIX ABI: if addr != NULL, addrlen must be a valid value-result pointer. if (addrPtr != 0 && addrlenPtr == 0) { - return new long[] { -1L }; + return new long[]{-1L}; } - + try { - SocketAddress local = null; + @Nullable SocketAddress local = null; if (h.isServer && h.serverChannel != null) { local = h.serverChannel.getLocalAddress(); } else if (h.isUdp && h.datagramChannel != null) { @@ -794,28 +796,28 @@ private static List registerSocketEnvironmentImports() { } else if (h.socketChannel != null) { local = h.socketChannel.getLocalAddress(); } - + if (local == null) { - return new long[] { -1L }; + return new long[]{-1L}; } - + if (addrPtr != 0) { if (!(local instanceof InetSocketAddress) || - !writeSockaddrResult(instance.memory(), addrPtr, addrlenPtr, (InetSocketAddress) local, h.family)) { - return new long[] { -1L }; + writeSockaddrResult(instance.memory(), addrPtr, addrlenPtr, (InetSocketAddress) local, h.family)) { + return new long[]{-1L}; } } - - return new long[] { 0 }; - } catch (IOException e) { - return new long[] { -1L }; + + return new long[]{0}; + } catch (@NotNull IOException e) { + return new long[]{-1L}; } })); - + return env; } - -private static InetAddress getFallbackAddress(InetAddress addr) { + + private static @Nullable InetAddress getFallbackAddress(@NotNull InetAddress addr) { try { byte[] raw = addr.getAddress(); if (raw.length == 16) { @@ -823,7 +825,7 @@ private static InetAddress getFallbackAddress(InetAddress addr) { if (isIpv4MappedIpv6(raw)) { return InetAddress.getByAddress(extractMappedIpv4(raw)); } - + // Check for IPv6 ANY (::) -> Translate to IPv4 ANY (0.0.0.0) boolean isAny = true; for (byte b : raw) { @@ -835,7 +837,7 @@ private static InetAddress getFallbackAddress(InetAddress addr) { if (isAny) { return InetAddress.getByAddress(new byte[]{0, 0, 0, 0}); } - + // Check for IPv6 Loopback (::1) -> Translate to IPv4 Loopback (127.0.0.1) boolean isLoopback = true; for (int i = 0; i < 15; i++) { @@ -847,124 +849,133 @@ private static InetAddress getFallbackAddress(InetAddress addr) { if (isLoopback && raw[15] == 1) { return InetAddress.getByAddress(new byte[]{127, 0, 0, 1}); } - + } else if (raw.length == 4) { // Try promoting IPv4 up to IPv6 as a last resort return InetAddress.getByAddress(ipv4ToMappedIpv6(raw)); } - } catch (UnknownHostException e) { + } catch (@NotNull UnknownHostException ignored) { // Ignore, will return null } return null; } - - private static long[] doSend(Instance instance, int sockfd, int bufPtr, int len, int flags, int destAddrPtr, int addrlen) { - SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[] { -1L }; + + private static long[] doSend(Instance instance, int sockfd, int bufPtr, int len, @SuppressWarnings("unused") int flags, int destAddrPtr, int addrlen) { + @Nullable SocketHandle h = sockets.get(sockfd); + if (h == null) return new long[]{-1L}; try { - Memory mem = instance.memory(); + @NotNull Memory mem = instance.memory(); byte[] data = mem.readBytes(bufPtr, len); - ByteBuffer buf = ByteBuffer.wrap(data); - + @NotNull ByteBuffer buf = ByteBuffer.wrap(data); + if (h.isUdp && h.datagramChannel != null) { if (destAddrPtr != 0) { int family = mem.readBytes(destAddrPtr, 1)[0] & 0xFF; int port = ((mem.readBytes(destAddrPtr + 2, 2)[0] & 0xFF) << 8) | (mem.readBytes(destAddrPtr + 2, 2)[1] & 0xFF); - InetAddress addr = (family == AF_INET6 || addrlen == 28) ? + @NotNull InetAddress addr = (family == AF_INET6 || addrlen == 28) ? InetAddress.getByAddress(mem.readBytes(destAddrPtr + 8, 16)) : InetAddress.getByAddress(mem.readBytes(destAddrPtr + 4, 4)); int sent = h.datagramChannel.send(buf, new InetSocketAddress(addr, port)); - return new long[] { sent }; + return new long[]{sent}; } else { - return new long[] { h.datagramChannel.write(buf) }; + return new long[]{h.datagramChannel.write(buf)}; } } else if (h.socketChannel != null) { - return new long[] { h.socketChannel.write(buf) }; + return new long[]{h.socketChannel.write(buf)}; } - return new long[] { -1L }; - } catch (IOException e) { - return new long[] { -1L }; + return new long[]{-1L}; + } catch (@NotNull IOException e) { + return new long[]{-1L}; } } - + // Dynamic address structure promotion mapped securely to guest memory buffers - private static long[] doRecv(Instance instance, int sockfd, int bufPtr, int len, int flags, int srcAddrPtr, int addrlenPtr) { - SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[] { -1L }; - + private static long[] doRecv(@NotNull Instance instance, int sockfd, int bufPtr, int len, @SuppressWarnings("unused") int flags, int srcAddrPtr, int addrlenPtr) { + @Nullable SocketHandle h = sockets.get(sockfd); + if (h == null) return new long[]{-1L}; + // POSIX ABI: if src_addr != NULL, addrlen must be a valid value-result pointer. if (srcAddrPtr != 0 && addrlenPtr == 0) { - return new long[] { -1L }; + return new long[]{-1L}; } - + try { - Memory mem = instance.memory(); - ByteBuffer buf = ByteBuffer.allocate(len); - + @NotNull Memory mem = instance.memory(); + @NotNull ByteBuffer buf = ByteBuffer.allocate(len); + if (h.isUdp && h.datagramChannel != null) { SocketAddress sender = h.datagramChannel.receive(buf); if (sender == null) { - return new long[] { -1L }; + return new long[]{-1L}; } - + buf.flip(); mem.write(bufPtr, Arrays.copyOf(buf.array(), buf.limit())); - + if (srcAddrPtr != 0) { if (!(sender instanceof InetSocketAddress) || - !writeSockaddrResult(mem, srcAddrPtr, addrlenPtr, (InetSocketAddress) sender, h.family)) { - return new long[] { -1L }; + writeSockaddrResult(mem, srcAddrPtr, addrlenPtr, (InetSocketAddress) sender, h.family)) { + return new long[]{-1L}; } } - - return new long[] { buf.limit() }; + + return new long[]{buf.limit()}; } else if (h.socketChannel != null) { int read = h.socketChannel.read(buf); if (read > 0) { mem.write(bufPtr, Arrays.copyOf(buf.array(), read)); - return new long[] { read }; + return new long[]{read}; } - return new long[] { read == -1 ? 0 : -1L }; + return new long[]{read == -1 ? 0 : -1L}; } - - return new long[] { -1L }; - } catch (IOException e) { - return new long[] { -1L }; + + return new long[]{-1L}; + } catch (@NotNull IOException e) { + return new long[]{-1L}; } } - + private static long[] closeHandle(int fd) { - SocketHandle h = sockets.remove(fd); + @Nullable SocketHandle h = sockets.remove(fd); if (h != null) { - try { if (h.serverChannel != null) h.serverChannel.close(); } catch (IOException e) {} - try { if (h.datagramChannel != null) h.datagramChannel.close(); } catch (IOException e) {} - try { if (h.socketChannel != null) h.socketChannel.close(); } catch (IOException e) {} + try { + if (h.serverChannel != null) h.serverChannel.close(); + } catch (@NotNull IOException ignored) { + } + try { + if (h.datagramChannel != null) h.datagramChannel.close(); + } catch (@NotNull IOException ignored) { + } + try { + if (h.socketChannel != null) h.socketChannel.close(); + } catch (@NotNull IOException ignored) { + } } - return new long[] { 0 }; + return new long[]{0}; } - - private static List params(int count) { - List res = new ArrayList<>(count); + + private static @NotNull List<@NotNull ValueType> params(int count) { + @NotNull List<@NotNull ValueType> res = new ArrayList<>(count); for (int i = 0; i < count; i++) res.add(ValueType.I32); return res; } - - private static List returns(int count) { + + private static @NotNull List<@NotNull ValueType> returns(int count) { return count == 0 ? List.of() : List.of(ValueType.I32); } - - private static void writeIntLE(Memory mem, int offset, int val) { - mem.write(offset, new byte[] { + + private static void writeIntLE(@NotNull Memory mem, int offset, int val) { + mem.write(offset, new byte[]{ (byte) val, (byte) (val >> 8), (byte) (val >> 16), (byte) (val >> 24) }); } - - private static int readIntLE(Memory mem, int offset) { + + private static int readIntLE(@NotNull Memory mem, int offset) { byte[] b = mem.readBytes(offset, 4); return (b[0] & 0xFF) | ((b[1] & 0xFF) << 8) | ((b[2] & 0xFF) << 16) | ((b[3] & 0xFF) << 24); } - - private static long readLongLE(Memory mem, int offset) { + + private static long readLongLE(@NotNull Memory mem, int offset) { byte[] b = mem.readBytes(offset, 8); long res = 0; for (int i = 0; i < 8; i++) { @@ -972,8 +983,8 @@ private static long readLongLE(Memory mem, int offset) { } return res; } - - private static String readNullTerminatedString(Memory mem, int offset) { + + private static @NotNull String readNullTerminatedString(@NotNull Memory mem, int offset) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int curr = offset; while (true) { @@ -983,67 +994,53 @@ private static String readNullTerminatedString(Memory mem, int offset) { } return baos.toString(StandardCharsets.UTF_8); } - - private static final class SockProtoPair { - final int socktype; - final int protocol; - - SockProtoPair(int socktype, int protocol) { - this.socktype = socktype; - this.protocol = protocol; - } + + private record SockProtoPair(int socktype, int protocol) { } - - private static final class AddrInfoResult { - final int family; - final int socktype; - final int protocol; - final byte[] sockaddr; - final String canonName; - - AddrInfoResult(int family, int socktype, int protocol, byte[] sockaddr, String canonName) { - this.family = family; - this.socktype = socktype; - this.protocol = protocol; - this.sockaddr = sockaddr; - this.canonName = canonName; - } + + private record AddrInfoResult( + int family, + int socktype, + int protocol, + byte @NotNull [] sockaddr, + @NotNull String canonName + ) { } - - private static ExportFunction findExport(Instance instance, String primary, String fallback) { - ExportFunction fn = instance.export(primary); + + private static @Nullable ExportFunction findExport(@NotNull Instance instance, @NotNull String primary, @NotNull String fallback) { + @Nullable ExportFunction fn = instance.export(primary); return fn != null ? fn : instance.export(fallback); } - - private static int guestMalloc(ExportFunction malloc, int size) { + + private static int guestMalloc(@NotNull ExportFunction malloc, int size) { return (int) malloc.apply(size)[0]; } - - private static void putU16LE(byte[] out, int off, int v) { + + private static void putU16LE(byte[] out, @SuppressWarnings("SameParameterValue") int off, int v) { out[off] = (byte) (v & 0xFF); out[off + 1] = (byte) ((v >>> 8) & 0xFF); } - - private static void putU16BE(byte[] out, int off, int v) { + + private static void putU16BE(byte[] out, @SuppressWarnings("SameParameterValue") int off, int v) { out[off] = (byte) ((v >>> 8) & 0xFF); out[off + 1] = (byte) (v & 0xFF); } - + private static void putIntLE(byte[] out, int off, int v) { out[off] = (byte) (v & 0xFF); out[off + 1] = (byte) ((v >>> 8) & 0xFF); out[off + 2] = (byte) ((v >>> 16) & 0xFF); out[off + 3] = (byte) ((v >>> 24) & 0xFF); } - - private static byte[] ipv4ToMappedIpv6(byte[] v4) { + + private static byte @NotNull [] ipv4ToMappedIpv6(byte[] v4) { byte[] out = new byte[16]; out[10] = (byte) 0xFF; out[11] = (byte) 0xFF; System.arraycopy(v4, 0, out, 12, 4); return out; } - + private static boolean isIpv4MappedIpv6(byte[] v6) { if (v6 == null || v6.length != 16) return false; for (int i = 0; i < 10; i++) { @@ -1051,24 +1048,24 @@ private static boolean isIpv4MappedIpv6(byte[] v6) { } return v6[10] == (byte) 0xFF && v6[11] == (byte) 0xFF; } - - private static byte[] extractMappedIpv4(byte[] v6) { + + private static byte @NotNull [] extractMappedIpv4(byte @NotNull [] v6) { return Arrays.copyOfRange(v6, 12, 16); } - - private static byte[] encodeSockaddr(int family, byte[] addr, int port, int scopeId) { + + private static byte @NotNull [] encodeSockaddr(int family, byte @NotNull [] addr, int port, int scopeId) { if (family == AF_INET) { if (addr.length != 4) throw new IllegalArgumentException("AF_INET requires 4 bytes"); - byte[] out = new byte[SOCKADDR_IN_LEN]; + byte @NotNull [] out = new byte[SOCKADDR_IN_LEN]; putU16LE(out, 0, AF_INET); putU16BE(out, 2, port); System.arraycopy(addr, 0, out, 4, 4); return out; } - + if (family == AF_INET6) { if (addr.length != 16) throw new IllegalArgumentException("AF_INET6 requires 16 bytes"); - byte[] out = new byte[SOCKADDR_IN6_LEN]; + byte @NotNull [] out = new byte[SOCKADDR_IN6_LEN]; putU16LE(out, 0, AF_INET6); putU16BE(out, 2, port); putIntLE(out, 4, 0); // flowinfo @@ -1076,27 +1073,27 @@ private static byte[] encodeSockaddr(int family, byte[] addr, int port, int scop putIntLE(out, 24, scopeId); return out; } - + throw new IllegalArgumentException("unsupported family: " + family); } - - private static boolean writeSockaddrResult(Memory mem, int addrPtr, int addrlenPtr, InetSocketAddress remote, int socketFamily) { + + private static boolean writeSockaddrResult(@NotNull Memory mem, int addrPtr, int addrlenPtr, @NotNull InetSocketAddress remote, int socketFamily) { if (addrPtr == 0) { - return true; + return false; } if (addrlenPtr == 0) { - return false; + return true; } - - InetAddress inet = remote.getAddress(); + + @NotNull InetAddress inet = remote.getAddress(); if (inet == null) { - return false; + return true; } - + byte[] raw = inet.getAddress(); int family; int scopeId = 0; - + if (socketFamily == AF_INET6) { family = AF_INET6; if (raw.length == 4) { @@ -1109,24 +1106,24 @@ private static boolean writeSockaddrResult(Memory mem, int addrPtr, int addrlenP family = AF_INET; if (raw.length == 16) { if (!isIpv4MappedIpv6(raw)) { - return false; + return true; } raw = extractMappedIpv4(raw); } } - - byte[] sockaddr = encodeSockaddr(family, raw, remote.getPort(), scopeId); + + byte @NotNull [] sockaddr = encodeSockaddr(family, raw, remote.getPort(), scopeId); int callerLen = Math.max(0, readIntLE(mem, addrlenPtr)); int copyLen = Math.min(callerLen, sockaddr.length); - + if (copyLen > 0) { mem.write(addrPtr, Arrays.copyOf(sockaddr, copyLen)); } writeIntLE(mem, addrlenPtr, sockaddr.length); - return true; + return false; } - - private static Integer parseNumericService(String s) { + + private static @Nullable Integer parseNumericService(@Nullable String s) { if (s == null || s.isEmpty()) return null; for (int i = 0; i < s.length(); i++) { if (!Character.isDigit(s.charAt(i))) return null; @@ -1138,22 +1135,22 @@ private static Integer parseNumericService(String s) { return null; } } - + private static int hexValue(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return 10 + (c - 'a'); if (c >= 'A' && c <= 'F') return 10 + (c - 'A'); return -1; } - - private static byte[] parseIpv4Literal(String s) { + + private static byte[] parseIpv4Literal(@Nullable String s) { if (s == null || s.isEmpty()) return null; - String[] parts = s.split("\\.", -1); + @NotNull String @NotNull [] parts = s.split("\\.", -1); if (parts.length != 4) return null; - - byte[] out = new byte[4]; + + byte @NotNull [] out = new byte[4]; for (int i = 0; i < 4; i++) { - String p = parts[i]; + @NotNull String p = parts[i]; if (p.isEmpty() || p.length() > 3) return null; int v = 0; for (int j = 0; j < p.length(); j++) { @@ -1166,19 +1163,19 @@ private static byte[] parseIpv4Literal(String s) { } return out; } - - private static List parseIpv6Section(String part, boolean allowIpv4Tail) { - List words = new ArrayList<>(); + + private static @Nullable List<@NotNull Integer> parseIpv6Section(@NotNull String part, boolean allowIpv4Tail) { + @NotNull List<@NotNull Integer> words = new ArrayList<>(); if (part.isEmpty()) return words; - + String[] tokens = part.split(":", -1); for (int i = 0; i < tokens.length; i++) { - String token = tokens[i]; + @NotNull String token = tokens[i]; if (token.isEmpty()) return null; - + if (token.indexOf('.') >= 0) { if (!allowIpv4Tail || i != tokens.length - 1) return null; - byte[] v4 = parseIpv4Literal(token); + byte @NotNull [] v4 = parseIpv4Literal(token); if (v4 == null) return null; words.add(((v4[0] & 0xFF) << 8) | (v4[1] & 0xFF)); words.add(((v4[2] & 0xFF) << 8) | (v4[3] & 0xFF)); @@ -1193,38 +1190,38 @@ private static List parseIpv6Section(String part, boolean allowIpv4Tail words.add(value); } } - + return words; } - - private static byte[] parseIpv6Literal(String s) { + + private static byte @Nullable [] parseIpv6Literal(@Nullable String s) { if (s == null || s.isEmpty()) return null; if (s.indexOf('%') >= 0) return null; // inet_pton does not accept zone ids - - String[] halves = s.split("::", -1); + + @NotNull String @NotNull [] halves = s.split("::", -1); if (halves.length > 2) return null; - - List words = new ArrayList<>(8); - + + @NotNull List<@NotNull Integer> words = new ArrayList<>(8); + if (halves.length == 1) { - List all = parseIpv6Section(s, true); + @Nullable List<@NotNull Integer> all = parseIpv6Section(s, true); if (all == null || all.size() != 8) return null; words.addAll(all); } else { - List left = parseIpv6Section(halves[0], false); - List right = parseIpv6Section(halves[1], true); + @Nullable List<@NotNull Integer> left = parseIpv6Section(halves[0], false); + @Nullable List<@NotNull Integer> right = parseIpv6Section(halves[1], true); if (left == null || right == null) return null; - + int zeros = 8 - (left.size() + right.size()); if (zeros < 1) return null; - + words.addAll(left); for (int i = 0; i < zeros; i++) words.add(0); words.addAll(right); } - + if (words.size() != 8) return null; - + byte[] out = new byte[16]; for (int i = 0; i < 8; i++) { int w = words.get(i); @@ -1233,28 +1230,28 @@ private static byte[] parseIpv6Literal(String s) { } return out; } - - private static List defaultAddressesForNullNode(int family, boolean passive) throws UnknownHostException { - List out = new ArrayList<>(); - + + private static @NotNull List<@NotNull InetAddress> defaultAddressesForNullNode(int family, boolean passive) throws UnknownHostException { + @NotNull List<@NotNull InetAddress> out = new ArrayList<>(); + if (family == AF_UNSPEC || family == AF_INET6) { byte[] v6 = new byte[16]; if (!passive) v6[15] = 1; // ::1 out.add(InetAddress.getByAddress(v6)); } - + if (family == AF_UNSPEC || family == AF_INET) { - byte[] v4 = passive ? new byte[] {0, 0, 0, 0} : new byte[] {127, 0, 0, 1}; + byte[] v4 = passive ? new byte[]{0, 0, 0, 0} : new byte[]{127, 0, 0, 1}; out.add(InetAddress.getByAddress(v4)); } - + return out; } - - private static List resolveNumericNode(String node, int family, int flags, byte[] v4, byte[] v6) - throws UnknownHostException { + + private static @NotNull List<@NotNull InetAddress> resolveNumericNode(int family, int flags, byte @Nullable [] v4, byte @Nullable [] v6) + throws UnknownHostException { List out = new ArrayList<>(); - + if (v4 != null) { if (family == AF_UNSPEC || family == AF_INET) { out.add(InetAddress.getByAddress(v4)); @@ -1263,51 +1260,51 @@ private static List resolveNumericNode(String node, int family, int } return out; } - + if (v6 != null) { if (family == AF_UNSPEC || family == AF_INET6) { out.add(InetAddress.getByAddress(v6)); } } - + return out; } - - private static List resolveDnsNode(String node, int family, int flags) throws UnknownHostException { + + private static @NotNull List<@NotNull InetAddress> resolveDnsNode(@NotNull String node, int family, int flags) throws UnknownHostException { InetAddress[] resolved = InetAddress.getAllByName(node); - + List v4 = new ArrayList<>(); List v6 = new ArrayList<>(); for (InetAddress addr : resolved) { if (addr.getAddress().length == 16) v6.add(addr); else v4.add(addr); } - + List out = new ArrayList<>(); - + if (family == AF_UNSPEC) { out.addAll(Arrays.asList(resolved)); return out; } - + if (family == AF_INET) { out.addAll(v4); return out; } - + // AF_INET6 out.addAll(v6); if ((flags & AI_V4MAPPED) != 0 && (((flags & AI_ALL) != 0) || v6.isEmpty())) { - for (InetAddress a : v4) { + for (@NotNull InetAddress a : v4) { out.add(InetAddress.getByAddress(ipv4ToMappedIpv6(a.getAddress()))); } } return out; } - - private static List buildSockProtoPairs(int socktype, int protocol) { - List out = new ArrayList<>(); - + + private static @NotNull List<@NotNull SockProtoPair> buildSockProtoPairs(int socktype, int protocol) { + @NotNull List<@NotNull SockProtoPair> out = new ArrayList<>(); + if (socktype == 0) { if (protocol == 0 || protocol == IPPROTO_TCP) { out.add(new SockProtoPair(SOCK_STREAM, IPPROTO_TCP)); @@ -1317,17 +1314,17 @@ private static List buildSockProtoPairs(int socktype, int protoco } return out; } - + if (socktype == SOCK_STREAM) { out.add(new SockProtoPair(SOCK_STREAM, IPPROTO_TCP)); return out; } - + if (socktype == SOCK_DGRAM) { out.add(new SockProtoPair(SOCK_DGRAM, IPPROTO_UDP)); return out; } - + return out; } } From ba94954e3978489fb0547bdb8bae767befcee06b Mon Sep 17 00:00:00 2001 From: zerou Date: Sat, 11 Jul 2026 14:06:43 +0200 Subject: [PATCH 2/4] WASMImpl/Java: remove binary file from repository Signed-off-by: zerou --- WASMImpl/Java/src/main/luxon_server.wasm | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 WASMImpl/Java/src/main/luxon_server.wasm diff --git a/WASMImpl/Java/src/main/luxon_server.wasm b/WASMImpl/Java/src/main/luxon_server.wasm deleted file mode 100644 index e69de29..0000000 From 2ef76bdcbd71098f685bd8154c893565325871bf Mon Sep 17 00:00:00 2001 From: zerou Date: Sat, 11 Jul 2026 14:08:12 +0200 Subject: [PATCH 3/4] WASMImpl/Java: add dedicated .gitignore Signed-off-by: zerou --- WASMImpl/Java/.gitignore | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 WASMImpl/Java/.gitignore diff --git a/WASMImpl/Java/.gitignore b/WASMImpl/Java/.gitignore new file mode 100644 index 0000000..0874e68 --- /dev/null +++ b/WASMImpl/Java/.gitignore @@ -0,0 +1,46 @@ +# Maven +/target/ +/run/ +/dependency-reduced-pom.xml + +# IntelliJ IDEA +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +.idea/* +*.iws +*.iml +*.ipr +out/ +**/src/main/**/out/ +**/src/test/**/out/ + +# Eclipse +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +**/src/main/**/bin/ +**/src/test/**/bin/ + +# NetBeans +/nbproject/private/ +/nbbuild/ +/nbdist/ + +# Visual Studio Code +/.vscode/ + +# macOS +.DS_Store + +# Java +hs_err_pid*.log + +# Luxon +/src/main/luxon_server.wasm From 8483c1ed3ec968f25cd992d9f6b271b60e0313a2 Mon Sep 17 00:00:00 2001 From: zerou Date: Sat, 22 Aug 2026 18:32:40 +0200 Subject: [PATCH 4/4] WASMImpl/Java: rename a lot of variables Signed-off-by: zerou --- .../com/gitlab/luxon_project/LuxonServer.java | 1026 +++++++++-------- 1 file changed, 530 insertions(+), 496 deletions(-) diff --git a/WASMImpl/Java/src/main/java/com/gitlab/luxon_project/LuxonServer.java b/WASMImpl/Java/src/main/java/com/gitlab/luxon_project/LuxonServer.java index a37065f..f785299 100644 --- a/WASMImpl/Java/src/main/java/com/gitlab/luxon_project/LuxonServer.java +++ b/WASMImpl/Java/src/main/java/com/gitlab/luxon_project/LuxonServer.java @@ -74,11 +74,11 @@ public class LuxonServer { // Emulated POSIX descriptor map starting at 100 to clear standard WASI descriptors (0-3) private static final Map sockets = new HashMap<>(); - private static int nextFd = 100; + private static int nextFileDescriptor = 100; private static class SocketHandle { - final int fd; - final int family; + final int fileDescriptor; + final int addressFamily; boolean isServer = false; boolean isUdp; boolean nonBlocking = false; @@ -86,9 +86,9 @@ private static class SocketHandle { SocketChannel socketChannel; DatagramChannel datagramChannel; - SocketHandle(int fd, int family, boolean isUdp) { - this.fd = fd; - this.family = family; + SocketHandle(int fileDescriptor, int addressFamily, boolean isUdp) { + this.fileDescriptor = fileDescriptor; + this.addressFamily = addressFamily; this.isUdp = isUdp; } } @@ -126,10 +126,10 @@ public static void main(@NotNull String @NotNull [] args) { if (finalPathOpen != null) { functions.remove(finalPathOpen); - functions.add(new HostFunction(finalPathOpen.module(), finalPathOpen.name(), finalPathOpen.paramTypes(), finalPathOpen.returnTypes(), (instance, wasmArgs) -> { - int pathPtr = (int) wasmArgs[2]; - int pathLen = (int) wasmArgs[3]; - int resultFdPtr = (int) wasmArgs[8]; + functions.add(new HostFunction(finalPathOpen.module(), finalPathOpen.name(), finalPathOpen.paramTypes(), finalPathOpen.returnTypes(), (instance, wasmArguments) -> { + int pathPtr = (int) wasmArguments[2]; + int pathLen = (int) wasmArguments[3]; + int resultFdPtr = (int) wasmArguments[8]; @NotNull Memory mem = instance.memory(); @NotNull String path = new String(mem.readBytes(pathPtr, pathLen), StandardCharsets.UTF_8); @@ -138,42 +138,42 @@ public static void main(@NotNull String @NotNull [] args) { writeIntLE(mem, resultFdPtr, RANDOM_FD); return new long[]{0}; // WASI_ESUCCESS } - return finalPathOpen.handle().apply(instance, wasmArgs); + return finalPathOpen.handle().apply(instance, wasmArguments); })); } if (finalFdRead != null) { functions.remove(finalFdRead); - functions.add(new HostFunction(finalFdRead.module(), finalFdRead.name(), finalFdRead.paramTypes(), finalFdRead.returnTypes(), (instance, wasmArgs) -> { - int fd = (int) wasmArgs[0]; + functions.add(new HostFunction(finalFdRead.module(), finalFdRead.name(), finalFdRead.paramTypes(), finalFdRead.returnTypes(), (instance, wasmArguments) -> { + int fd = (int) wasmArguments[0]; if (fd == RANDOM_FD) { - int iovsPtr = (int) wasmArgs[1]; - int iovsLen = (int) wasmArgs[2]; - int resultSizePtr = (int) wasmArgs[3]; - @NotNull Memory mem = instance.memory(); + int iovsPtr = (int) wasmArguments[1]; + int iovsLen = (int) wasmArguments[2]; + int resultSizePtr = (int) wasmArguments[3]; + @NotNull Memory memory = instance.memory(); int totalRead = 0; for (int i = 0; i < iovsLen; i++) { - int bufPtr = readIntLE(mem, iovsPtr + (i * 8)); - int bufLen = readIntLE(mem, iovsPtr + (i * 8) + 4); + int bufferPointer = readIntLE(memory, iovsPtr + (i * 8)); + int bufferLength = readIntLE(memory, iovsPtr + (i * 8) + 4); - byte @NotNull [] randBytes = new byte[bufLen]; - secureRandom.nextBytes(randBytes); - mem.write(bufPtr, randBytes); - totalRead += bufLen; + byte @NotNull [] randomBytes = new byte[bufferLength]; + secureRandom.nextBytes(randomBytes); + memory.write(bufferPointer, randomBytes); + totalRead += bufferLength; } - writeIntLE(mem, resultSizePtr, totalRead); + writeIntLE(memory, resultSizePtr, totalRead); return new long[]{0}; // WASI_ESUCCESS } - return finalFdRead.handle().apply(instance, wasmArgs); + return finalFdRead.handle().apply(instance, wasmArguments); })); } if (finalFdClose != null) { functions.remove(finalFdClose); functions.add(new HostFunction(finalFdClose.module(), finalFdClose.name(), finalFdClose.paramTypes(), finalFdClose.returnTypes(), (instance, wasmArgs) -> { - int fd = (int) wasmArgs[0]; - if (fd == RANDOM_FD) { + int fileDescriptor = (int) wasmArgs[0]; + if (fileDescriptor == RANDOM_FD) { return new long[]{0}; // WASI_ESUCCESS } return finalFdClose.handle().apply(instance, wasmArgs); @@ -192,237 +192,237 @@ public static void main(@NotNull String @NotNull [] args) { .withImportValues(imports) .build(); - @Nullable ExportFunction startFn = instance.export("_start"); - if (startFn != null) { - startFn.apply(); + @Nullable ExportFunction startFunction = instance.export("_start"); + if (startFunction != null) { + startFunction.apply(); } - } catch (@NotNull Exception e) { - System.err.println("Fatal execution error inside WASM host wrapper: " + e.getMessage()); - e.printStackTrace(); + } catch (@NotNull Exception exception) { + System.err.println("Fatal execution error inside WASM host wrapper: " + exception.getMessage()); + exception.printStackTrace(); System.exit(1); } } private static @NotNull List<@NotNull ImportFunction> registerSocketEnvironmentImports() { - @NotNull List<@NotNull ImportFunction> env = new ArrayList<>(); + final @NotNull List<@NotNull ImportFunction> environment = new ArrayList<>(); final @NotNull String namespace = "env"; // u32 w2c_env_socket_socket(domain, type, protocol) -> 3 params - env.add(new HostFunction(namespace, "socket_socket", params(3), returns(1), (instance, args) -> { + environment.add(new HostFunction(namespace, "socket_socket", params(3), returns(1), (instance, args) -> { int domain = (int) args[0]; int type = (int) args[1]; - boolean isUdp = (type == SOCK_DGRAM); - int fd = nextFd++; - sockets.put(fd, new SocketHandle(fd, domain, isUdp)); - return new long[]{fd}; + boolean isUdp = type == SOCK_DGRAM; + int fileDescriptor = nextFileDescriptor++; + sockets.put(fileDescriptor, new SocketHandle(fileDescriptor, domain, isUdp)); + return new long[]{fileDescriptor}; })); // u32 w2c_env_socket_bind(sockfd, addr_ptr, addrlen) -> 3 params - env.add(new HostFunction(namespace, "socket_bind", params(3), returns(1), (instance, args) -> { - int sockfd = (int) args[0]; - int addrPtr = (int) args[1]; - int addrlen = (int) args[2]; - @Nullable SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[]{-1L}; + environment.add(new HostFunction(namespace, "socket_bind", params(3), returns(1), (instance, args) -> { + int socketFileDescriptor = (int) args[0]; + int addressPointer = (int) args[1]; + int addressLength = (int) args[2]; + @Nullable SocketHandle handle = sockets.get(socketFileDescriptor); + if (handle == null) return new long[]{-1L}; try { - @NotNull Memory mem = instance.memory(); - int family = mem.readBytes(addrPtr, 1)[0] & 0xFF; - int port = ((mem.readBytes(addrPtr + 2, 2)[0] & 0xFF) << 8) | (mem.readBytes(addrPtr + 2, 2)[1] & 0xFF); + @NotNull Memory memory = instance.memory(); + int addressFamily = memory.readBytes(addressPointer, 1)[0] & 0xFF; + int port = ((memory.readBytes(addressPointer + 2, 2)[0] & 0xFF) << 8) | (memory.readBytes(addressPointer + 2, 2)[1] & 0xFF); - @NotNull InetAddress addr = (family == AF_INET6 || addrlen == 28) ? - InetAddress.getByAddress(mem.readBytes(addrPtr + 8, 16)) : - InetAddress.getByAddress(mem.readBytes(addrPtr + 4, 4)); + @NotNull InetAddress address = (addressFamily == AF_INET6 || addressLength == 28) ? + InetAddress.getByAddress(memory.readBytes(addressPointer + 8, 16)) : + InetAddress.getByAddress(memory.readBytes(addressPointer + 4, 4)); try { - if (h.isUdp) { - h.datagramChannel = DatagramChannel.open(); - h.datagramChannel.configureBlocking(!h.nonBlocking); - h.datagramChannel.bind(new InetSocketAddress(addr, port)); + if (handle.isUdp) { + handle.datagramChannel = DatagramChannel.open(); + handle.datagramChannel.configureBlocking(!handle.nonBlocking); + handle.datagramChannel.bind(new InetSocketAddress(address, port)); } else { - h.isServer = true; - h.serverChannel = ServerSocketChannel.open(); - h.serverChannel.configureBlocking(!h.nonBlocking); - h.serverChannel.bind(new InetSocketAddress(addr, port)); + handle.isServer = true; + handle.serverChannel = ServerSocketChannel.open(); + handle.serverChannel.configureBlocking(!handle.nonBlocking); + handle.serverChannel.bind(new InetSocketAddress(address, port)); } - } catch (UnsupportedAddressTypeException e) { - @Nullable InetAddress fallback = getFallbackAddress(addr); + } catch (UnsupportedAddressTypeException exception) { + @Nullable InetAddress fallback = getFallbackAddress(address); if (fallback != null) { - System.err.println("WARNING: Unsupported address type for bind. Falling back from " + addr + " to " + fallback); - if (h.isUdp) { - h.datagramChannel.bind(new InetSocketAddress(fallback, port)); + System.err.println("WARNING: Unsupported address type for bind. Falling back from " + address + " to " + fallback); + if (handle.isUdp) { + handle.datagramChannel.bind(new InetSocketAddress(fallback, port)); } else { - h.serverChannel.bind(new InetSocketAddress(fallback, port)); + handle.serverChannel.bind(new InetSocketAddress(fallback, port)); } } else { - throw e; + throw exception; } } return new long[]{0}; - } catch (@NotNull Exception e) { + } catch (@NotNull Exception exception) { return new long[]{-1L}; } })); // u32 w2c_env_socket_listen(sockfd, backlog) -> 2 params - env.add(new HostFunction(namespace, "socket_listen", params(2), returns(1), (instance, args) -> { - @Nullable SocketHandle h = sockets.get((int) args[0]); - if (h != null && h.isUdp) return new long[]{0}; - return new long[]{(h != null && h.isServer) ? 0 : -1L}; + environment.add(new HostFunction(namespace, "socket_listen", params(2), returns(1), (instance, args) -> { + @Nullable SocketHandle handle = sockets.get((int) args[0]); + if (handle != null && handle.isUdp) return new long[]{0}; + return new long[]{(handle != null && handle.isServer) ? 0 : -1L}; })); // u32 w2c_env_socket_accept(sockfd, addr_ptr, addrlen_ptr) -> 3 params - env.add(new HostFunction(namespace, "socket_accept", params(3), returns(1), (instance, args) -> { - int sockfd = (int) args[0]; - int addrPtr = (int) args[1]; - int addrlenPtr = (int) args[2]; + environment.add(new HostFunction(namespace, "socket_accept", params(3), returns(1), (instance, args) -> { + int socketFileDescriptor = (int) args[0]; + int addressPointer = (int) args[1]; + int addressLengthPointer = (int) args[2]; - @Nullable SocketHandle h = sockets.get(sockfd); - if (h == null || h.isUdp || !h.isServer || h.serverChannel == null) { + @Nullable SocketHandle handle = sockets.get(socketFileDescriptor); + if (handle == null || handle.isUdp || !handle.isServer || handle.serverChannel == null) { return new long[]{-1L}; } // POSIX ABI: if addr != NULL, addrlen must be a valid value-result pointer. - if (addrPtr != 0 && addrlenPtr == 0) { + if (addressPointer != 0 && addressLengthPointer == 0) { return new long[]{-1L}; } try { - @Nullable SocketChannel client = h.serverChannel.accept(); + @Nullable SocketChannel client = handle.serverChannel.accept(); if (client == null) { return new long[]{-1L}; } client.configureBlocking(true); - int clientFd = nextFd++; - @NotNull SocketHandle clientHandle = new SocketHandle(clientFd, h.family, false); + int clientFileDescriptor = nextFileDescriptor++; + @NotNull SocketHandle clientHandle = new SocketHandle(clientFileDescriptor, handle.addressFamily, false); clientHandle.socketChannel = client; - sockets.put(clientFd, clientHandle); + sockets.put(clientFileDescriptor, clientHandle); - if (addrPtr != 0) { + if (addressPointer != 0) { @Nullable SocketAddress remote = client.getRemoteAddress(); if (!(remote instanceof InetSocketAddress) || - writeSockaddrResult(instance.memory(), addrPtr, addrlenPtr, (InetSocketAddress) remote, h.family)) { - closeHandle(clientFd); + writeSockaddrResult(instance.memory(), addressPointer, addressLengthPointer, (InetSocketAddress) remote, handle.addressFamily)) { + closeHandle(clientFileDescriptor); return new long[]{-1L}; } } - return new long[]{clientFd}; + return new long[]{clientFileDescriptor}; } catch (@NotNull IOException e) { return new long[]{-1L}; } })); // u32 w2c_env_socket_connect(sockfd, addr_ptr, addrlen) -> 3 params - env.add(new HostFunction(namespace, "socket_connect", params(3), returns(1), (instance, args) -> { - int sockfd = (int) args[0]; - int addrPtr = (int) args[1]; - int addrlen = (int) args[2]; - @Nullable SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[]{-1L}; + environment.add(new HostFunction(namespace, "socket_connect", params(3), returns(1), (instance, args) -> { + int socketFileDescriptor = (int) args[0]; + int addressPointer = (int) args[1]; + int addressLength = (int) args[2]; + @Nullable SocketHandle handle = sockets.get(socketFileDescriptor); + if (handle == null) return new long[]{-1L}; try { - @NotNull Memory mem = instance.memory(); - int family = mem.readBytes(addrPtr, 1)[0] & 0xFF; - int port = ((mem.readBytes(addrPtr + 2, 2)[0] & 0xFF) << 8) | (mem.readBytes(addrPtr + 2, 2)[1] & 0xFF); - @NotNull InetAddress addr = (family == AF_INET6 || addrlen == 28) ? - InetAddress.getByAddress(mem.readBytes(addrPtr + 8, 16)) : - InetAddress.getByAddress(mem.readBytes(addrPtr + 4, 4)); + @NotNull Memory memory = instance.memory(); + int addressFamily = memory.readBytes(addressPointer, 1)[0] & 0xFF; + int port = ((memory.readBytes(addressPointer + 2, 2)[0] & 0xFF) << 8) | (memory.readBytes(addressPointer + 2, 2)[1] & 0xFF); + @NotNull InetAddress address = (addressFamily == AF_INET6 || addressLength == 28) ? + InetAddress.getByAddress(memory.readBytes(addressPointer + 8, 16)) : + InetAddress.getByAddress(memory.readBytes(addressPointer + 4, 4)); try { - if (h.isUdp) { - h.datagramChannel = DatagramChannel.open(); - h.datagramChannel.configureBlocking(!h.nonBlocking); - h.datagramChannel.connect(new InetSocketAddress(addr, port)); + if (handle.isUdp) { + handle.datagramChannel = DatagramChannel.open(); + handle.datagramChannel.configureBlocking(!handle.nonBlocking); + handle.datagramChannel.connect(new InetSocketAddress(address, port)); return new long[]{0}; } else { - h.socketChannel = SocketChannel.open(); - h.socketChannel.configureBlocking(!h.nonBlocking); - boolean success = h.socketChannel.connect(new InetSocketAddress(addr, port)); + handle.socketChannel = SocketChannel.open(); + handle.socketChannel.configureBlocking(!handle.nonBlocking); + boolean success = handle.socketChannel.connect(new InetSocketAddress(address, port)); return new long[]{success ? 0 : -1L}; } - } catch (@NotNull UnsupportedAddressTypeException e) { - @Nullable InetAddress fallback = getFallbackAddress(addr); + } catch (@NotNull UnsupportedAddressTypeException exception) { + @Nullable InetAddress fallback = getFallbackAddress(address); if (fallback != null) { - System.err.println("WARNING: Unsupported address type for connect. Falling back from " + addr + " to " + fallback); - if (h.isUdp) { - h.datagramChannel.connect(new InetSocketAddress(fallback, port)); + System.err.println("WARNING: Unsupported address type for connect. Falling back from " + address + " to " + fallback); + if (handle.isUdp) { + handle.datagramChannel.connect(new InetSocketAddress(fallback, port)); return new long[]{0}; } else { - boolean success = h.socketChannel.connect(new InetSocketAddress(fallback, port)); + boolean success = handle.socketChannel.connect(new InetSocketAddress(fallback, port)); return new long[]{success ? 0 : -1L}; } } else { - throw e; // Rethrow if we can't formulate a valid fallback + throw exception; // Rethrow if we can't formulate a valid fallback } } - } catch (@NotNull Exception e) { + } catch (@NotNull Exception exception) { return new long[]{-1L}; } })); - env.add(new HostFunction(namespace, "socket_send", params(4), returns(1), (instance, args) -> - doSend(instance, (int) args[0], (int) args[1], (int) args[2], (int) args[3], 0, 0) + environment.add(new HostFunction(namespace, "socket_send", params(4), returns(1), (instance, wasmArguments) -> + doSend(instance, (int) wasmArguments[0], (int) wasmArguments[1], (int) wasmArguments[2], (int) wasmArguments[3], 0, 0) )); - env.add(new HostFunction(namespace, "socket_recv", params(4), returns(1), (instance, args) -> - doRecv(instance, (int) args[0], (int) args[1], (int) args[2], (int) args[3], 0, 0) + environment.add(new HostFunction(namespace, "socket_recv", params(4), returns(1), (instance, wasmArguments) -> + doRecv(instance, (int) wasmArguments[0], (int) wasmArguments[1], (int) wasmArguments[2], (int) wasmArguments[3], 0, 0) )); - env.add(new HostFunction(namespace, "socket_sendto", params(6), returns(1), (instance, args) -> - doSend(instance, (int) args[0], (int) args[1], (int) args[2], (int) args[3], (int) args[4], (int) args[5]) + environment.add(new HostFunction(namespace, "socket_sendto", params(6), returns(1), (instance, wasmArguments) -> + doSend(instance, (int) wasmArguments[0], (int) wasmArguments[1], (int) wasmArguments[2], (int) wasmArguments[3], (int) wasmArguments[4], (int) wasmArguments[5]) )); - env.add(new HostFunction(namespace, "socket_recvfrom", params(6), returns(1), (instance, args) -> - doRecv(instance, (int) args[0], (int) args[1], (int) args[2], (int) args[3], (int) args[4], (int) args[5]) + environment.add(new HostFunction(namespace, "socket_recvfrom", params(6), returns(1), (instance, wasmArguments) -> + doRecv(instance, (int) wasmArguments[0], (int) wasmArguments[1], (int) wasmArguments[2], (int) wasmArguments[3], (int) wasmArguments[4], (int) wasmArguments[5]) )); - env.add(new HostFunction(namespace, "socket_setsockopt", params(5), returns(1), (instance, args) -> new long[]{0})); - env.add(new HostFunction(namespace, "socket_shutdown", params(2), returns(1), (instance, args) -> closeHandle((int) args[0]))); - env.add(new HostFunction(namespace, "socket_close", params(1), returns(1), (instance, args) -> closeHandle((int) args[0]))); + environment.add(new HostFunction(namespace, "socket_setsockopt", params(5), returns(1), (instance, wasmArguments) -> new long[]{0})); + environment.add(new HostFunction(namespace, "socket_shutdown", params(2), returns(1), (instance, wasmArguments) -> closeHandle((int) wasmArguments[0]))); + environment.add(new HostFunction(namespace, "socket_close", params(1), returns(1), (instance, wasmArguments) -> closeHandle((int) wasmArguments[0]))); // u32 w2c_env_socket_fcntl(fd, cmd, arg) -> 3 params - env.add(new HostFunction(namespace, "socket_fcntl", params(3), returns(1), (instance, args) -> { - @Nullable SocketHandle h = sockets.get((int) args[0]); - if (h == null) return new long[]{-1L}; - int cmd = (int) args[1]; - int arg = (int) args[2]; + environment.add(new HostFunction(namespace, "socket_fcntl", params(3), returns(1), (instance, wasmArguments) -> { + @Nullable SocketHandle handle = sockets.get((int) wasmArguments[0]); + if (handle == null) return new long[]{-1L}; + int cmd = (int) wasmArguments[1]; + int arg = (int) wasmArguments[2]; if (cmd == F_GETFL) { - return new long[]{h.nonBlocking ? O_NONBLOCK : 0}; + return new long[]{handle.nonBlocking ? O_NONBLOCK : 0}; } else if (cmd == F_SETFL) { - h.nonBlocking = (arg & O_NONBLOCK) != 0; + handle.nonBlocking = (arg & O_NONBLOCK) != 0; try { - if (h.serverChannel != null) h.serverChannel.configureBlocking(!h.nonBlocking); - if (h.datagramChannel != null) h.datagramChannel.configureBlocking(!h.nonBlocking); - if (h.socketChannel != null) h.socketChannel.configureBlocking(!h.nonBlocking); + if (handle.serverChannel != null) handle.serverChannel.configureBlocking(!handle.nonBlocking); + if (handle.datagramChannel != null) handle.datagramChannel.configureBlocking(!handle.nonBlocking); + if (handle.socketChannel != null) handle.socketChannel.configureBlocking(!handle.nonBlocking); return new long[]{0}; - } catch (@NotNull IOException e) { + } catch (@NotNull IOException exception) { return new long[]{-1L}; } } return new long[]{-1L}; })); - env.add(new HostFunction(namespace, "socket_ioctl", params(3), returns(1), (instance, args) -> new long[]{0})); + environment.add(new HostFunction(namespace, "socket_ioctl", params(3), returns(1), (instance, wasmArguments) -> new long[]{0})); - env.add(new HostFunction(namespace, "socket_inet_pton", params(3), returns(1), (instance, args) -> { - int af = (int) args[0]; - int srcPtr = (int) args[1]; - int dstPtr = (int) args[2]; + environment.add(new HostFunction(namespace, "socket_inet_pton", params(3), returns(1), (instance, wasmArguments) -> { + int addressFamily = (int) wasmArguments[0]; + int sourcePointer = (int) wasmArguments[1]; + int destinationPointer = (int) wasmArguments[2]; try { - @NotNull Memory mem = instance.memory(); - @NotNull String src = readNullTerminatedString(mem, srcPtr); + @NotNull Memory memory = instance.memory(); + @NotNull String source = readNullTerminatedString(memory, sourcePointer); byte[] parsed; - if (af == AF_INET) { - parsed = parseIpv4Literal(src); - } else if (af == AF_INET6) { - parsed = parseIpv6Literal(src); + if (addressFamily == AF_INET) { + parsed = parseIpv4Literal(source); + } else if (addressFamily == AF_INET6) { + parsed = parseIpv6Literal(source); } else { // POSIX: unsupported family => -1 / EAFNOSUPPORT. return new long[]{-1L}; @@ -433,22 +433,22 @@ public static void main(@NotNull String @NotNull [] args) { return new long[]{0}; } - mem.write(dstPtr, parsed); + memory.write(destinationPointer, parsed); return new long[]{1}; } catch (@NotNull Exception e) { return new long[]{0}; } })); - env.add(new HostFunction(namespace, "socket_inet_ntop", params(4), returns(1), (instance, args) -> { + environment.add(new HostFunction(namespace, "socket_inet_ntop", params(4), returns(1), (instance, args) -> { try { - @NotNull Memory mem = instance.memory(); - int af = (int) args[0]; - byte @NotNull [] ipBytes = mem.readBytes((int) args[1], af == AF_INET6 ? 16 : 4); + @NotNull Memory memory = instance.memory(); + int addressFamily = (int) args[0]; + byte @NotNull [] ipBytes = memory.readBytes((int) args[1], addressFamily == AF_INET6 ? 16 : 4); byte @NotNull [] strBytes = InetAddress.getByAddress(ipBytes).getHostAddress().getBytes(StandardCharsets.UTF_8); if (strBytes.length + 1 <= (int) args[3]) { - mem.write((int) args[2], strBytes); - mem.write((int) args[2] + strBytes.length, new byte[]{0}); + memory.write((int) args[2], strBytes); + memory.write((int) args[2] + strBytes.length, new byte[]{0}); return new long[]{args[2]}; } } catch (@NotNull Exception ignored) { @@ -457,107 +457,113 @@ public static void main(@NotNull String @NotNull [] args) { })); // Selector loop evaluating Read/Write states asynchronously - env.add(new HostFunction(namespace, "socket_select", params(5), returns(1), (instance, args) -> { + environment.add(new HostFunction(namespace, "socket_select", params(5), returns(1), (instance, args) -> { int nfds = (int) args[0]; int readfdsPtr = (int) args[1]; int writefdsPtr = (int) args[2]; int exceptfdsPtr = (int) args[3]; - int timeoutPtr = (int) args[4]; - @NotNull Memory mem = instance.memory(); + int timeoutPointer = (int) args[4]; + @NotNull Memory memory = instance.memory(); - long timeoutMs = 0; + long timeoutMilliseconds = 0; boolean hasTimeout = false; - if (timeoutPtr != 0) { + if (timeoutPointer != 0) { hasTimeout = true; - long sec = readLongLE(mem, timeoutPtr); - long usec = readLongLE(mem, timeoutPtr + 8); - timeoutMs = (sec * 1000) + (usec / 1000); + long seconds = readLongLE(memory, timeoutPointer); + long milliseconds = readLongLE(memory, timeoutPointer + 8); + timeoutMilliseconds = (seconds * 1000) + (milliseconds / 1000); } try (Selector selector = Selector.open()) { - @NotNull Map<@NotNull SelectionKey, @NotNull Integer> keyToFd = new HashMap<>(); + @NotNull Map<@NotNull SelectionKey, @NotNull Integer> keyFileDescriptorMap = new HashMap<>(); int bytesToClear = (nfds + 7) / 8; - byte[] rfds = readfdsPtr != 0 && bytesToClear > 0 ? mem.readBytes(readfdsPtr, bytesToClear) : null; - byte[] wfds = writefdsPtr != 0 && bytesToClear > 0 ? mem.readBytes(writefdsPtr, bytesToClear) : null; + byte[] rfds = readfdsPtr != 0 && bytesToClear > 0 ? memory.readBytes(readfdsPtr, bytesToClear) : null; + byte[] wfds = writefdsPtr != 0 && bytesToClear > 0 ? memory.readBytes(writefdsPtr, bytesToClear) : null; - if (readfdsPtr != 0 && bytesToClear > 0) mem.write(readfdsPtr, new byte[bytesToClear]); - if (writefdsPtr != 0 && bytesToClear > 0) mem.write(writefdsPtr, new byte[bytesToClear]); - if (exceptfdsPtr != 0 && bytesToClear > 0) mem.write(exceptfdsPtr, new byte[bytesToClear]); + if (readfdsPtr != 0 && bytesToClear > 0) memory.write(readfdsPtr, new byte[bytesToClear]); + if (writefdsPtr != 0 && bytesToClear > 0) memory.write(writefdsPtr, new byte[bytesToClear]); + if (exceptfdsPtr != 0 && bytesToClear > 0) memory.write(exceptfdsPtr, new byte[bytesToClear]); for (int fd = 0; fd < nfds; fd++) { boolean wantsRead = rfds != null && (rfds[fd / 8] & (1 << (fd % 8))) != 0; boolean wantsWrite = wfds != null && (wfds[fd / 8] & (1 << (fd % 8))) != 0; if (wantsRead || wantsWrite) { - @Nullable SocketHandle h = sockets.get(fd); - if (h != null) { - int ops = 0; + @Nullable SocketHandle handle = sockets.get(fd); + if (handle != null) { + int operations = 0; if (wantsRead) { - if (h.isServer && h.serverChannel != null) ops |= SelectionKey.OP_ACCEPT; - else ops |= SelectionKey.OP_READ; + if (handle.isServer && handle.serverChannel != null) + operations |= SelectionKey.OP_ACCEPT; + else operations |= SelectionKey.OP_READ; } - if (wantsWrite && !h.isServer) { - ops |= SelectionKey.OP_WRITE; + if (wantsWrite && !handle.isServer) { + operations |= SelectionKey.OP_WRITE; } - if (ops != 0) { + if (operations != 0) { @Nullable SelectionKey key = null; - if (h.isServer && h.serverChannel != null) { - if (h.serverChannel.isBlocking()) h.serverChannel.configureBlocking(false); - key = h.serverChannel.register(selector, ops); - } else if (h.isUdp && h.datagramChannel != null) { - if (h.datagramChannel.isBlocking()) h.datagramChannel.configureBlocking(false); - key = h.datagramChannel.register(selector, ops); - } else if (h.socketChannel != null) { - if (h.socketChannel.isBlocking()) h.socketChannel.configureBlocking(false); - key = h.socketChannel.register(selector, ops); + if (handle.isServer && handle.serverChannel != null) { + if (handle.serverChannel.isBlocking()) + handle.serverChannel.configureBlocking(false); + key = handle.serverChannel.register(selector, operations); + } else if (handle.isUdp && handle.datagramChannel != null) { + if (handle.datagramChannel.isBlocking()) + handle.datagramChannel.configureBlocking(false); + key = handle.datagramChannel.register(selector, operations); + } else if (handle.socketChannel != null) { + if (handle.socketChannel.isBlocking()) + handle.socketChannel.configureBlocking(false); + key = handle.socketChannel.register(selector, operations); } - if (key != null) keyToFd.put(key, fd); + if (key != null) keyFileDescriptorMap.put(key, fd); } } } } int readyCount = 0; - if (!keyToFd.isEmpty()) { + if (!keyFileDescriptorMap.isEmpty()) { if (hasTimeout) { - if (timeoutMs == 0) selector.selectNow(); - else selector.select(timeoutMs); + if (timeoutMilliseconds == 0) selector.selectNow(); + else selector.select(timeoutMilliseconds); } else { selector.select(); } for (@NotNull SelectionKey key : selector.selectedKeys()) { - int fd = keyToFd.get(key); + int fd = keyFileDescriptorMap.get(key); if (readfdsPtr != 0 && (key.isReadable() || key.isAcceptable())) { - byte[] b = mem.readBytes(readfdsPtr + (fd / 8), 1); - b[0] |= (byte) (1 << (fd % 8)); - mem.write(readfdsPtr + (fd / 8), b); + byte @NotNull [] bytes = memory.readBytes(readfdsPtr + (fd / 8), 1); + bytes[0] |= (byte) (1 << (fd % 8)); + memory.write(readfdsPtr + (fd / 8), bytes); readyCount++; } if (writefdsPtr != 0 && key.isWritable()) { - byte[] b = mem.readBytes(writefdsPtr + (fd / 8), 1); - b[0] |= (byte) (1 << (fd % 8)); - mem.write(writefdsPtr + (fd / 8), b); + byte @NotNull [] bytes = memory.readBytes(writefdsPtr + (fd / 8), 1); + bytes[0] |= (byte) (1 << (fd % 8)); + memory.write(writefdsPtr + (fd / 8), bytes); readyCount++; } } - } else if (hasTimeout && timeoutMs > 0) { - Thread.sleep(timeoutMs); + } else if (hasTimeout && timeoutMilliseconds > 0) { + Thread.sleep(timeoutMilliseconds); } - for (@NotNull SelectionKey key : keyToFd.keySet()) key.cancel(); + for (@NotNull SelectionKey key : keyFileDescriptorMap.keySet()) key.cancel(); selector.selectNow(); - for (int fd : keyToFd.values()) { - @Nullable SocketHandle h = sockets.get(fd); - if (h != null) { - if (h.isServer && h.serverChannel != null) h.serverChannel.configureBlocking(!h.nonBlocking); - else if (h.isUdp && h.datagramChannel != null) - h.datagramChannel.configureBlocking(!h.nonBlocking); - else if (h.socketChannel != null) h.socketChannel.configureBlocking(!h.nonBlocking); + for (int fileDescriptor : keyFileDescriptorMap.values()) { + @Nullable SocketHandle handle = sockets.get(fileDescriptor); + if (handle != null) { + if (handle.isServer && handle.serverChannel != null) + handle.serverChannel.configureBlocking(!handle.nonBlocking); + else if (handle.isUdp && handle.datagramChannel != null) + handle.datagramChannel.configureBlocking(!handle.nonBlocking); + else if (handle.socketChannel != null) + handle.socketChannel.configureBlocking(!handle.nonBlocking); } } return new long[]{readyCount}; @@ -566,36 +572,36 @@ else if (h.isUdp && h.datagramChannel != null) } })); - env.add(new HostFunction(namespace, "socket_getaddrinfo", params(4), returns(1), (instance, args) -> { - @NotNull Memory mem = instance.memory(); + environment.add(new HostFunction(namespace, "socket_getaddrinfo", params(4), returns(1), (instance, args) -> { + @NotNull Memory memory = instance.memory(); - int nodePtr = (int) args[0]; - int servicePtr = (int) args[1]; - int hintsPtr = (int) args[2]; - int resPtr = (int) args[3]; + int nodePointer = (int) args[0]; + int servicePointer = (int) args[1]; + int hintsPointer = (int) args[2]; + int resourcePointer = (int) args[3]; - if (resPtr == 0) { + if (resourcePointer == 0) { return new long[]{EAI_FAIL}; } - writeIntLE(mem, resPtr, 0); + writeIntLE(memory, resourcePointer, 0); - @Nullable String node = nodePtr != 0 ? readNullTerminatedString(mem, nodePtr) : null; - @Nullable String service = servicePtr != 0 ? readNullTerminatedString(mem, servicePtr) : null; + @Nullable String node = nodePointer != 0 ? readNullTerminatedString(memory, nodePointer) : null; + @Nullable String service = servicePointer != 0 ? readNullTerminatedString(memory, servicePointer) : null; if (node == null && service == null) { return new long[]{EAI_NONAME}; } int flags = 0; - int family = AF_UNSPEC; + int addressFamily = AF_UNSPEC; int socktype = 0; int protocol = 0; - if (hintsPtr != 0) { - flags = readIntLE(mem, hintsPtr); - family = readIntLE(mem, hintsPtr + 4); - socktype = readIntLE(mem, hintsPtr + 8); - protocol = readIntLE(mem, hintsPtr + 12); + if (hintsPointer != 0) { + flags = readIntLE(memory, hintsPointer); + addressFamily = readIntLE(memory, hintsPointer + 4); + socktype = readIntLE(memory, hintsPointer + 8); + protocol = readIntLE(memory, hintsPointer + 12); } int supportedFlags = @@ -606,7 +612,7 @@ else if (h.isUdp && h.datagramChannel != null) return new long[]{EAI_BADFLAGS}; } - if (family != AF_UNSPEC && family != AF_INET && family != AF_INET6) { + if (addressFamily != AF_UNSPEC && addressFamily != AF_INET && addressFamily != AF_INET6) { return new long[]{EAI_FAMILY}; } @@ -637,19 +643,19 @@ else if (h.isUdp && h.datagramChannel != null) try { if (node == null) { - addresses = defaultAddressesForNullNode(family, (flags & AI_PASSIVE) != 0); + addresses = defaultAddressesForNullNode(addressFamily, (flags & AI_PASSIVE) != 0); } else { byte[] v4 = parseIpv4Literal(node); byte[] v6 = (v4 == null) ? parseIpv6Literal(node) : null; numericNode = (v4 != null || v6 != null); if (numericNode) { - addresses = resolveNumericNode(family, flags, v4, v6); + addresses = resolveNumericNode(addressFamily, flags, v4, v6); } else { if ((flags & AI_NUMERICHOST) != 0) { return new long[]{EAI_NONAME}; } - addresses = resolveDnsNode(node, family, flags); + addresses = resolveDnsNode(node, addressFamily, flags); } } } catch (@NotNull UnknownHostException e) { @@ -667,7 +673,7 @@ else if (h.isUdp && h.datagramChannel != null) return new long[]{EAI_SERVICE}; } - @Nullable String canonName = ((flags & AI_CANONNAME) != 0 && node != null) ? node : null; + @Nullable String canonicalName = ((flags & AI_CANONNAME) != 0 && node != null) ? node : null; @NotNull List<@NotNull AddrInfoResult> results = new ArrayList<>(); boolean first = true; @@ -681,10 +687,10 @@ else if (h.isUdp && h.datagramChannel != null) for (@NotNull SockProtoPair pair : pairs) { results.add(new AddrInfoResult( outFamily, - pair.socktype, + pair.socketType, pair.protocol, sockaddr, - first ? canonName : null + first ? canonicalName : null )); first = false; } @@ -699,255 +705,270 @@ else if (h.isUdp && h.datagramChannel != null) @NotNull List<@NotNull Integer> allocated = new ArrayList<>(); try { - int head = 0; - int prev = 0; + int headPointer = 0; + int previousPointer = 0; for (@NotNull AddrInfoResult r : results) { - int saPtr = guestMalloc(malloc, r.sockaddr.length); + int saPtr = guestMalloc(malloc, r.socketAddress.length); if (saPtr == 0) throw new OutOfMemoryError(); allocated.add(saPtr); - mem.write(saPtr, r.sockaddr); + memory.write(saPtr, r.socketAddress); int canonPtr = 0; - if (r.canonName != null) { - byte[] nameBytes = r.canonName.getBytes(StandardCharsets.UTF_8); + if (r.canonicalName != null) { + byte[] nameBytes = r.canonicalName.getBytes(StandardCharsets.UTF_8); canonPtr = guestMalloc(malloc, nameBytes.length + 1); if (canonPtr == 0) throw new OutOfMemoryError(); allocated.add(canonPtr); - mem.write(canonPtr, nameBytes); - mem.write(canonPtr + nameBytes.length, new byte[]{0}); + memory.write(canonPtr, nameBytes); + memory.write(canonPtr + nameBytes.length, new byte[]{0}); } - int aiPtr = guestMalloc(malloc, ADDRINFO_LEN); - if (aiPtr == 0) throw new OutOfMemoryError(); - allocated.add(aiPtr); + int addressInfoPointer = guestMalloc(malloc, ADDRINFO_LEN); + if (addressInfoPointer == 0) throw new OutOfMemoryError(); + allocated.add(addressInfoPointer); - writeIntLE(mem, aiPtr, 0); - writeIntLE(mem, aiPtr + 4, r.family); - writeIntLE(mem, aiPtr + 8, r.socktype); - writeIntLE(mem, aiPtr + 12, r.protocol); - writeIntLE(mem, aiPtr + 16, r.sockaddr.length); - writeIntLE(mem, aiPtr + 20, saPtr); - writeIntLE(mem, aiPtr + 24, canonPtr); - writeIntLE(mem, aiPtr + 28, 0); + writeIntLE(memory, addressInfoPointer, 0); + writeIntLE(memory, addressInfoPointer + 4, r.addressFamily); + writeIntLE(memory, addressInfoPointer + 8, r.socketType); + writeIntLE(memory, addressInfoPointer + 12, r.protocol); + writeIntLE(memory, addressInfoPointer + 16, r.socketAddress.length); + writeIntLE(memory, addressInfoPointer + 20, saPtr); + writeIntLE(memory, addressInfoPointer + 24, canonPtr); + writeIntLE(memory, addressInfoPointer + 28, 0); - if (head == 0) { - head = aiPtr; + if (headPointer == 0) { + headPointer = addressInfoPointer; } else { - writeIntLE(mem, prev + 28, aiPtr); + writeIntLE(memory, previousPointer + 28, addressInfoPointer); } - prev = aiPtr; + previousPointer = addressInfoPointer; } - writeIntLE(mem, resPtr, head); + writeIntLE(memory, resourcePointer, headPointer); return new long[]{0}; - } catch (@NotNull Throwable t) { + } catch (@NotNull Throwable throwable) { if (free != null) { for (int i = allocated.size() - 1; i >= 0; i--) { int ptr = allocated.get(i); if (ptr != 0) free.apply(ptr); } } - writeIntLE(mem, resPtr, 0); + writeIntLE(memory, resourcePointer, 0); return new long[]{EAI_MEMORY}; } })); - env.add(new HostFunction(namespace, "socket_freeaddrinfo", params(1), returns(0), (instance, args) -> { + environment.add(new HostFunction(namespace, "socket_freeaddrinfo", params(1), returns(0), (instance, args) -> { @Nullable ExportFunction free = instance.export("free"); if (free == null) free = instance.export("_free"); if (free == null) return new long[0]; @NotNull Memory mem = instance.memory(); - int curr = (int) args[0]; - while (curr != 0) { - int addr = readIntLE(mem, curr + 20); - int canon = readIntLE(mem, curr + 24); - int next = readIntLE(mem, curr + 28); + int currentArgument = (int) args[0]; + while (currentArgument != 0) { + int address = readIntLE(mem, currentArgument + 20); + int canon = readIntLE(mem, currentArgument + 24); + int next = readIntLE(mem, currentArgument + 28); - if (addr != 0) free.apply(addr); + if (address != 0) free.apply(address); if (canon != 0) free.apply(canon); - free.apply(curr); - curr = next; + free.apply(currentArgument); + currentArgument = next; } return new long[0]; })); // u32 w2c_env_socket_getsockname(sockfd, addr_ptr, addrlen_ptr) -> 3 params - env.add(new HostFunction(namespace, "socket_getsockname", params(3), returns(1), (instance, args) -> { - int sockfd = (int) args[0]; - int addrPtr = (int) args[1]; - int addrlenPtr = (int) args[2]; + environment.add(new HostFunction(namespace, "socket_getsockname", params(3), returns(1), (instance, args) -> { + int socketFileDescriptor = (int) args[0]; + int addressPointer = (int) args[1]; + int addressLengthPointer = (int) args[2]; - @Nullable SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[]{-1L}; + @Nullable SocketHandle handle = sockets.get(socketFileDescriptor); + if (handle == null) return new long[]{-1L}; // POSIX ABI: if addr != NULL, addrlen must be a valid value-result pointer. - if (addrPtr != 0 && addrlenPtr == 0) { + if (addressPointer != 0 && addressLengthPointer == 0) { return new long[]{-1L}; } try { - @Nullable SocketAddress local = null; - if (h.isServer && h.serverChannel != null) { - local = h.serverChannel.getLocalAddress(); - } else if (h.isUdp && h.datagramChannel != null) { - local = h.datagramChannel.getLocalAddress(); - } else if (h.socketChannel != null) { - local = h.socketChannel.getLocalAddress(); + @Nullable SocketAddress socketAddress = null; + if (handle.isServer && handle.serverChannel != null) { + socketAddress = handle.serverChannel.getLocalAddress(); + } else if (handle.isUdp && handle.datagramChannel != null) { + socketAddress = handle.datagramChannel.getLocalAddress(); + } else if (handle.socketChannel != null) { + socketAddress = handle.socketChannel.getLocalAddress(); } - if (local == null) { + if (socketAddress == null) { return new long[]{-1L}; } - if (addrPtr != 0) { - if (!(local instanceof InetSocketAddress) || - writeSockaddrResult(instance.memory(), addrPtr, addrlenPtr, (InetSocketAddress) local, h.family)) { + if (addressPointer != 0) { + if (!(socketAddress instanceof InetSocketAddress) || + writeSockaddrResult(instance.memory(), addressPointer, addressLengthPointer, (InetSocketAddress) socketAddress, handle.addressFamily)) { return new long[]{-1L}; } } return new long[]{0}; - } catch (@NotNull IOException e) { + } catch (@NotNull IOException exception) { return new long[]{-1L}; } })); - return env; + return environment; } - private static @Nullable InetAddress getFallbackAddress(@NotNull InetAddress addr) { + private static @Nullable InetAddress getFallbackAddress(@NotNull InetAddress address) { try { - byte[] raw = addr.getAddress(); - if (raw.length == 16) { - // Check if it's an IPv4-mapped IPv6 (::ffff:x.x.x.x) - if (isIpv4MappedIpv6(raw)) { - return InetAddress.getByAddress(extractMappedIpv4(raw)); + byte[] rawAddress = address.getAddress(); + if (rawAddress.length == 16) { + // Check for an IPv4-mapped IPv6 address (::ffff:x.x.x.x) + if (isIpv4MappedIpv6(rawAddress)) { + return InetAddress.getByAddress(extractMappedIpv4(rawAddress)); } - // Check for IPv6 ANY (::) -> Translate to IPv4 ANY (0.0.0.0) - boolean isAny = true; - for (byte b : raw) { - if (b != 0) { - isAny = false; + // Check for IPv6 wildcard address (::) and translate to IPv4 wildcard address (0.0.0.0) + boolean isWildcardAddress = true; + for (byte item : rawAddress) { + if (item != 0) { + isWildcardAddress = false; break; } } - if (isAny) { + if (isWildcardAddress) { return InetAddress.getByAddress(new byte[]{0, 0, 0, 0}); } - // Check for IPv6 Loopback (::1) -> Translate to IPv4 Loopback (127.0.0.1) + // Check for IPv6 loopback address (::1) and translate to to IPv4 loopback address (127.0.0.1) boolean isLoopback = true; for (int i = 0; i < 15; i++) { - if (raw[i] != 0) { + if (rawAddress[i] != 0) { isLoopback = false; break; } } - if (isLoopback && raw[15] == 1) { + if (isLoopback && rawAddress[15] == 1) { return InetAddress.getByAddress(new byte[]{127, 0, 0, 1}); } - } else if (raw.length == 4) { + } else if (rawAddress.length == 4) { // Try promoting IPv4 up to IPv6 as a last resort - return InetAddress.getByAddress(ipv4ToMappedIpv6(raw)); + return InetAddress.getByAddress(ipv4ToMappedIpv6(rawAddress)); } } catch (@NotNull UnknownHostException ignored) { - // Ignore, will return null } return null; } - private static long[] doSend(Instance instance, int sockfd, int bufPtr, int len, @SuppressWarnings("unused") int flags, int destAddrPtr, int addrlen) { - @Nullable SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[]{-1L}; + private static long[] doSend( + Instance instance, + int socketFileDescriptor, + int destinationBufferPointer, + int desinationBufferLength, + @SuppressWarnings("unused") int flags, + int destinationAddressPointer, + int destinationAddressLength + ) { + @Nullable SocketHandle handle = sockets.get(socketFileDescriptor); + if (handle == null) return new long[]{-1L}; try { - @NotNull Memory mem = instance.memory(); - byte[] data = mem.readBytes(bufPtr, len); + @NotNull Memory memory = instance.memory(); + byte[] data = memory.readBytes(destinationBufferPointer, desinationBufferLength); @NotNull ByteBuffer buf = ByteBuffer.wrap(data); - if (h.isUdp && h.datagramChannel != null) { - if (destAddrPtr != 0) { - int family = mem.readBytes(destAddrPtr, 1)[0] & 0xFF; - int port = ((mem.readBytes(destAddrPtr + 2, 2)[0] & 0xFF) << 8) | (mem.readBytes(destAddrPtr + 2, 2)[1] & 0xFF); - @NotNull InetAddress addr = (family == AF_INET6 || addrlen == 28) ? - InetAddress.getByAddress(mem.readBytes(destAddrPtr + 8, 16)) : - InetAddress.getByAddress(mem.readBytes(destAddrPtr + 4, 4)); - int sent = h.datagramChannel.send(buf, new InetSocketAddress(addr, port)); + if (handle.isUdp && handle.datagramChannel != null) { + if (destinationAddressPointer != 0) { + int addressFamily = memory.readBytes(destinationAddressPointer, 1)[0] & 0xFF; + int port = ((memory.readBytes(destinationAddressPointer + 2, 2)[0] & 0xFF) << 8) | (memory.readBytes(destinationAddressPointer + 2, 2)[1] & 0xFF); + @NotNull InetAddress addr = (addressFamily == AF_INET6 || destinationAddressLength == 28) ? + InetAddress.getByAddress(memory.readBytes(destinationAddressPointer + 8, 16)) : + InetAddress.getByAddress(memory.readBytes(destinationAddressPointer + 4, 4)); + int sent = handle.datagramChannel.send(buf, new InetSocketAddress(addr, port)); return new long[]{sent}; } else { - return new long[]{h.datagramChannel.write(buf)}; + return new long[]{handle.datagramChannel.write(buf)}; } - } else if (h.socketChannel != null) { - return new long[]{h.socketChannel.write(buf)}; + } else if (handle.socketChannel != null) { + return new long[]{handle.socketChannel.write(buf)}; } return new long[]{-1L}; - } catch (@NotNull IOException e) { + } catch (@NotNull IOException exception) { return new long[]{-1L}; } } // Dynamic address structure promotion mapped securely to guest memory buffers - private static long[] doRecv(@NotNull Instance instance, int sockfd, int bufPtr, int len, @SuppressWarnings("unused") int flags, int srcAddrPtr, int addrlenPtr) { - @Nullable SocketHandle h = sockets.get(sockfd); - if (h == null) return new long[]{-1L}; + private static long[] doRecv( + @NotNull Instance instance, + int socketFileDescriptor, + int destinationBufferPointer, + int desinationBufferLength, + @SuppressWarnings("unused") int flags, + int sourceAddressPointer, + int sourceAddressLength + ) { + @Nullable SocketHandle handle = sockets.get(socketFileDescriptor); + if (handle == null) return new long[]{-1L}; // POSIX ABI: if src_addr != NULL, addrlen must be a valid value-result pointer. - if (srcAddrPtr != 0 && addrlenPtr == 0) { + if (sourceAddressPointer != 0 && sourceAddressLength == 0) { return new long[]{-1L}; } try { - @NotNull Memory mem = instance.memory(); - @NotNull ByteBuffer buf = ByteBuffer.allocate(len); + @NotNull Memory memory = instance.memory(); + @NotNull ByteBuffer buffer = ByteBuffer.allocate(desinationBufferLength); - if (h.isUdp && h.datagramChannel != null) { - SocketAddress sender = h.datagramChannel.receive(buf); + if (handle.isUdp && handle.datagramChannel != null) { + SocketAddress sender = handle.datagramChannel.receive(buffer); if (sender == null) { return new long[]{-1L}; } - buf.flip(); - mem.write(bufPtr, Arrays.copyOf(buf.array(), buf.limit())); + buffer.flip(); + memory.write(destinationBufferPointer, Arrays.copyOf(buffer.array(), buffer.limit())); - if (srcAddrPtr != 0) { + if (sourceAddressPointer != 0) { if (!(sender instanceof InetSocketAddress) || - writeSockaddrResult(mem, srcAddrPtr, addrlenPtr, (InetSocketAddress) sender, h.family)) { + writeSockaddrResult(memory, sourceAddressPointer, sourceAddressLength, (InetSocketAddress) sender, handle.addressFamily)) { return new long[]{-1L}; } } - return new long[]{buf.limit()}; - } else if (h.socketChannel != null) { - int read = h.socketChannel.read(buf); + return new long[]{buffer.limit()}; + } else if (handle.socketChannel != null) { + int read = handle.socketChannel.read(buffer); if (read > 0) { - mem.write(bufPtr, Arrays.copyOf(buf.array(), read)); + memory.write(destinationBufferPointer, Arrays.copyOf(buffer.array(), read)); return new long[]{read}; } return new long[]{read == -1 ? 0 : -1L}; } return new long[]{-1L}; - } catch (@NotNull IOException e) { + } catch (@NotNull IOException exception) { return new long[]{-1L}; } } - private static long[] closeHandle(int fd) { - @Nullable SocketHandle h = sockets.remove(fd); - if (h != null) { + private static long[] closeHandle(int handleID) { + @Nullable SocketHandle handle = sockets.remove(handleID); + if (handle != null) { try { - if (h.serverChannel != null) h.serverChannel.close(); + if (handle.serverChannel != null) handle.serverChannel.close(); } catch (@NotNull IOException ignored) { } try { - if (h.datagramChannel != null) h.datagramChannel.close(); + if (handle.datagramChannel != null) handle.datagramChannel.close(); } catch (@NotNull IOException ignored) { } try { - if (h.socketChannel != null) h.socketChannel.close(); + if (handle.socketChannel != null) handle.socketChannel.close(); } catch (@NotNull IOException ignored) { } } @@ -995,173 +1016,179 @@ private static long readLongLE(@NotNull Memory mem, int offset) { return baos.toString(StandardCharsets.UTF_8); } - private record SockProtoPair(int socktype, int protocol) { + private record SockProtoPair(int socketType, int protocol) { } private record AddrInfoResult( - int family, - int socktype, + int addressFamily, + int socketType, int protocol, - byte @NotNull [] sockaddr, - @NotNull String canonName + byte @NotNull [] socketAddress, + @NotNull String canonicalName ) { } private static @Nullable ExportFunction findExport(@NotNull Instance instance, @NotNull String primary, @NotNull String fallback) { - @Nullable ExportFunction fn = instance.export(primary); - return fn != null ? fn : instance.export(fallback); + @Nullable ExportFunction function = instance.export(primary); + return function != null ? function : instance.export(fallback); } private static int guestMalloc(@NotNull ExportFunction malloc, int size) { return (int) malloc.apply(size)[0]; } - private static void putU16LE(byte[] out, @SuppressWarnings("SameParameterValue") int off, int v) { - out[off] = (byte) (v & 0xFF); - out[off + 1] = (byte) ((v >>> 8) & 0xFF); + private static void putU16LE(byte[] buffer, @SuppressWarnings("SameParameterValue") int offset, int value) { + buffer[offset] = (byte) (value & 0xFF); + buffer[offset + 1] = (byte) ((value >>> 8) & 0xFF); } - private static void putU16BE(byte[] out, @SuppressWarnings("SameParameterValue") int off, int v) { - out[off] = (byte) ((v >>> 8) & 0xFF); - out[off + 1] = (byte) (v & 0xFF); + private static void putU16BE(byte[] buffer, @SuppressWarnings("SameParameterValue") int offset, int value) { + buffer[offset] = (byte) ((value >>> 8) & 0xFF); + buffer[offset + 1] = (byte) (value & 0xFF); } - private static void putIntLE(byte[] out, int off, int v) { - out[off] = (byte) (v & 0xFF); - out[off + 1] = (byte) ((v >>> 8) & 0xFF); - out[off + 2] = (byte) ((v >>> 16) & 0xFF); - out[off + 3] = (byte) ((v >>> 24) & 0xFF); + private static void putIntLE(byte[] buffer, int offset, int value) { + buffer[offset] = (byte) (value & 0xFF); + buffer[offset + 1] = (byte) ((value >>> 8) & 0xFF); + buffer[offset + 2] = (byte) ((value >>> 16) & 0xFF); + buffer[offset + 3] = (byte) ((value >>> 24) & 0xFF); } - private static byte @NotNull [] ipv4ToMappedIpv6(byte[] v4) { - byte[] out = new byte[16]; - out[10] = (byte) 0xFF; - out[11] = (byte) 0xFF; - System.arraycopy(v4, 0, out, 12, 4); - return out; + private static byte @NotNull [] ipv4ToMappedIpv6(byte[] address) { + byte[] returnValue = new byte[16]; + returnValue[10] = (byte) 0xFF; + returnValue[11] = (byte) 0xFF; + System.arraycopy(address, 0, returnValue, 12, 4); + return returnValue; } - private static boolean isIpv4MappedIpv6(byte[] v6) { - if (v6 == null || v6.length != 16) return false; - for (int i = 0; i < 10; i++) { - if (v6[i] != 0) return false; + private static boolean isIpv4MappedIpv6(byte[] address) { + if (address == null || address.length != 16) return false; + for (int index = 0; index < 10; index++) { + if (address[index] != 0) return false; } - return v6[10] == (byte) 0xFF && v6[11] == (byte) 0xFF; + return address[10] == (byte) 0xFF && address[11] == (byte) 0xFF; } - private static byte @NotNull [] extractMappedIpv4(byte @NotNull [] v6) { - return Arrays.copyOfRange(v6, 12, 16); + private static byte @NotNull [] extractMappedIpv4(byte @NotNull [] address) { + return Arrays.copyOfRange(address, 12, 16); } - private static byte @NotNull [] encodeSockaddr(int family, byte @NotNull [] addr, int port, int scopeId) { - if (family == AF_INET) { - if (addr.length != 4) throw new IllegalArgumentException("AF_INET requires 4 bytes"); + private static byte @NotNull [] encodeSockaddr(int addressFamily, byte @NotNull [] address, int port, int scopeId) { + if (addressFamily == AF_INET) { + if (address.length != 4) throw new IllegalArgumentException("AF_INET requires 4 bytes"); byte @NotNull [] out = new byte[SOCKADDR_IN_LEN]; putU16LE(out, 0, AF_INET); putU16BE(out, 2, port); - System.arraycopy(addr, 0, out, 4, 4); + System.arraycopy(address, 0, out, 4, 4); return out; } - if (family == AF_INET6) { - if (addr.length != 16) throw new IllegalArgumentException("AF_INET6 requires 16 bytes"); + if (addressFamily == AF_INET6) { + if (address.length != 16) throw new IllegalArgumentException("AF_INET6 requires 16 bytes"); byte @NotNull [] out = new byte[SOCKADDR_IN6_LEN]; putU16LE(out, 0, AF_INET6); putU16BE(out, 2, port); putIntLE(out, 4, 0); // flowinfo - System.arraycopy(addr, 0, out, 8, 16); + System.arraycopy(address, 0, out, 8, 16); putIntLE(out, 24, scopeId); return out; } - throw new IllegalArgumentException("unsupported family: " + family); + throw new IllegalArgumentException("Unsupported address family '" + addressFamily + "'"); } - private static boolean writeSockaddrResult(@NotNull Memory mem, int addrPtr, int addrlenPtr, @NotNull InetSocketAddress remote, int socketFamily) { - if (addrPtr == 0) { + private static boolean writeSockaddrResult( + @NotNull Memory memory, + int addressPointer, + int addressLength, + @NotNull InetSocketAddress remoteAddress, + int socketFamily + ) { + if (addressPointer == 0) { return false; } - if (addrlenPtr == 0) { + if (addressLength == 0) { return true; } - @NotNull InetAddress inet = remote.getAddress(); + @NotNull InetAddress inet = remoteAddress.getAddress(); if (inet == null) { return true; } - byte[] raw = inet.getAddress(); - int family; + byte[] rawAddress = inet.getAddress(); + int addressFamily; int scopeId = 0; if (socketFamily == AF_INET6) { - family = AF_INET6; - if (raw.length == 4) { - raw = ipv4ToMappedIpv6(raw); + addressFamily = AF_INET6; + if (rawAddress.length == 4) { + rawAddress = ipv4ToMappedIpv6(rawAddress); } if (inet instanceof Inet6Address) { scopeId = ((Inet6Address) inet).getScopeId(); } } else { - family = AF_INET; - if (raw.length == 16) { - if (!isIpv4MappedIpv6(raw)) { + addressFamily = AF_INET; + if (rawAddress.length == 16) { + if (!isIpv4MappedIpv6(rawAddress)) { return true; } - raw = extractMappedIpv4(raw); + rawAddress = extractMappedIpv4(rawAddress); } } - byte @NotNull [] sockaddr = encodeSockaddr(family, raw, remote.getPort(), scopeId); - int callerLen = Math.max(0, readIntLE(mem, addrlenPtr)); - int copyLen = Math.min(callerLen, sockaddr.length); + byte @NotNull [] socketAddress = encodeSockaddr(addressFamily, rawAddress, remoteAddress.getPort(), scopeId); + int callerLength = Math.max(0, readIntLE(memory, addressLength)); + int copyLength = Math.min(callerLength, socketAddress.length); - if (copyLen > 0) { - mem.write(addrPtr, Arrays.copyOf(sockaddr, copyLen)); + if (copyLength > 0) { + memory.write(addressPointer, Arrays.copyOf(socketAddress, copyLength)); } - writeIntLE(mem, addrlenPtr, sockaddr.length); + writeIntLE(memory, addressLength, socketAddress.length); return false; } - private static @Nullable Integer parseNumericService(@Nullable String s) { - if (s == null || s.isEmpty()) return null; - for (int i = 0; i < s.length(); i++) { - if (!Character.isDigit(s.charAt(i))) return null; + private static @Nullable Integer parseNumericService(@Nullable String string) { + if (string == null || string.isEmpty()) return null; + for (int i = 0; i < string.length(); i++) { + if (!Character.isDigit(string.charAt(i))) return null; } try { - int port = Integer.parseInt(s); + int port = Integer.parseInt(string); return (port >= 0 && port <= 65535) ? port : null; } catch (NumberFormatException e) { return null; } } - private static int hexValue(char c) { - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'f') return 10 + (c - 'a'); - if (c >= 'A' && c <= 'F') return 10 + (c - 'A'); + private static int hexValue(char character) { + if (character >= '0' && character <= '9') return character - '0'; + if (character >= 'a' && character <= 'f') return 10 + (character - 'a'); + if (character >= 'A' && character <= 'F') return 10 + (character - 'A'); return -1; } - private static byte[] parseIpv4Literal(@Nullable String s) { - if (s == null || s.isEmpty()) return null; - @NotNull String @NotNull [] parts = s.split("\\.", -1); + private static byte[] parseIpv4Literal(@Nullable String string) { + if (string == null || string.isEmpty()) return null; + @NotNull String @NotNull [] parts = string.split("\\.", -1); if (parts.length != 4) return null; - byte @NotNull [] out = new byte[4]; - for (int i = 0; i < 4; i++) { - @NotNull String p = parts[i]; - if (p.isEmpty() || p.length() > 3) return null; - int v = 0; - for (int j = 0; j < p.length(); j++) { - char c = p.charAt(j); - if (!Character.isDigit(c)) return null; - v = (v * 10) + (c - '0'); + byte @NotNull [] returnValue = new byte[4]; + for (int index = 0; index < 4; index++) { + @NotNull String part = parts[index]; + if (part.isEmpty() || part.length() > 3) return null; + int value = 0; + for (int partIndex = 0; partIndex < part.length(); partIndex++) { + char character = part.charAt(partIndex); + if (!Character.isDigit(character)) return null; + value = (value * 10) + (character - '0'); } - if (v < 0 || v > 255) return null; - out[i] = (byte) v; + if (value < 0 || value > 255) return null; + returnValue[index] = (byte) value; } - return out; + return returnValue; } private static @Nullable List<@NotNull Integer> parseIpv6Section(@NotNull String part, boolean allowIpv4Tail) { @@ -1169,23 +1196,23 @@ private static byte[] parseIpv4Literal(@Nullable String s) { if (part.isEmpty()) return words; String[] tokens = part.split(":", -1); - for (int i = 0; i < tokens.length; i++) { - @NotNull String token = tokens[i]; + for (int index = 0; index < tokens.length; index++) { + @NotNull String token = tokens[index]; if (token.isEmpty()) return null; if (token.indexOf('.') >= 0) { - if (!allowIpv4Tail || i != tokens.length - 1) return null; - byte @NotNull [] v4 = parseIpv4Literal(token); - if (v4 == null) return null; - words.add(((v4[0] & 0xFF) << 8) | (v4[1] & 0xFF)); - words.add(((v4[2] & 0xFF) << 8) | (v4[3] & 0xFF)); + if (!allowIpv4Tail || index != tokens.length - 1) return null; + byte @NotNull [] address = parseIpv4Literal(token); + if (address == null) return null; + words.add(((address[0] & 0xFF) << 8) | (address[1] & 0xFF)); + words.add(((address[2] & 0xFF) << 8) | (address[3] & 0xFF)); } else { if (token.length() > 4) return null; int value = 0; - for (int j = 0; j < token.length(); j++) { - int hv = hexValue(token.charAt(j)); - if (hv < 0) return null; - value = (value << 4) | hv; + for (int tokenIndex = 0; tokenIndex < token.length(); tokenIndex++) { + int hexValue = hexValue(token.charAt(tokenIndex)); + if (hexValue < 0) return null; + value = (value << 4) | hexValue; } words.add(value); } @@ -1194,17 +1221,17 @@ private static byte[] parseIpv4Literal(@Nullable String s) { return words; } - private static byte @Nullable [] parseIpv6Literal(@Nullable String s) { - if (s == null || s.isEmpty()) return null; - if (s.indexOf('%') >= 0) return null; // inet_pton does not accept zone ids + private static byte @Nullable [] parseIpv6Literal(@Nullable String string) { + if (string == null || string.isEmpty()) return null; + if (string.indexOf('%') >= 0) return null; // inet_pton does not accept zone ids - @NotNull String @NotNull [] halves = s.split("::", -1); + @NotNull String @NotNull [] halves = string.split("::", -1); if (halves.length > 2) return null; @NotNull List<@NotNull Integer> words = new ArrayList<>(8); if (halves.length == 1) { - @Nullable List<@NotNull Integer> all = parseIpv6Section(s, true); + @Nullable List<@NotNull Integer> all = parseIpv6Section(string, true); if (all == null || all.size() != 8) return null; words.addAll(all); } else { @@ -1222,109 +1249,116 @@ private static byte[] parseIpv4Literal(@Nullable String s) { if (words.size() != 8) return null; - byte[] out = new byte[16]; - for (int i = 0; i < 8; i++) { - int w = words.get(i); - out[i * 2] = (byte) ((w >>> 8) & 0xFF); - out[i * 2 + 1] = (byte) (w & 0xFF); + byte[] returnValue = new byte[16]; + for (int index = 0; index < 8; index++) { + int word = words.get(index); + returnValue[index * 2] = (byte) ((word >>> 8) & 0xFF); + returnValue[index * 2 + 1] = (byte) (word & 0xFF); } - return out; + return returnValue; } - private static @NotNull List<@NotNull InetAddress> defaultAddressesForNullNode(int family, boolean passive) throws UnknownHostException { - @NotNull List<@NotNull InetAddress> out = new ArrayList<>(); + private static @NotNull List<@NotNull InetAddress> defaultAddressesForNullNode( + int addressFamily, + boolean passive + ) throws UnknownHostException { + @NotNull List<@NotNull InetAddress> returnValue = new ArrayList<>(); - if (family == AF_UNSPEC || family == AF_INET6) { - byte[] v6 = new byte[16]; - if (!passive) v6[15] = 1; // ::1 - out.add(InetAddress.getByAddress(v6)); + if (addressFamily == AF_UNSPEC || addressFamily == AF_INET6) { + byte[] address = new byte[16]; + if (!passive) address[15] = 1; // ::1 + returnValue.add(InetAddress.getByAddress(address)); } - if (family == AF_UNSPEC || family == AF_INET) { - byte[] v4 = passive ? new byte[]{0, 0, 0, 0} : new byte[]{127, 0, 0, 1}; - out.add(InetAddress.getByAddress(v4)); + if (addressFamily == AF_UNSPEC || addressFamily == AF_INET) { + byte[] address = passive ? new byte[]{0, 0, 0, 0} : new byte[]{127, 0, 0, 1}; + returnValue.add(InetAddress.getByAddress(address)); } - return out; + return returnValue; } - private static @NotNull List<@NotNull InetAddress> resolveNumericNode(int family, int flags, byte @Nullable [] v4, byte @Nullable [] v6) - throws UnknownHostException { - List out = new ArrayList<>(); + private static @NotNull List<@NotNull InetAddress> resolveNumericNode( + int addressFamily, + int flags, + byte @Nullable [] v4Address, + byte @Nullable [] v6Address + ) throws UnknownHostException { + List returnValue = new ArrayList<>(); - if (v4 != null) { - if (family == AF_UNSPEC || family == AF_INET) { - out.add(InetAddress.getByAddress(v4)); - } else if (family == AF_INET6 && (flags & AI_V4MAPPED) != 0) { - out.add(InetAddress.getByAddress(ipv4ToMappedIpv6(v4))); + if (v4Address != null) { + if (addressFamily == AF_UNSPEC || addressFamily == AF_INET) { + returnValue.add(InetAddress.getByAddress(v4Address)); + } else if (addressFamily == AF_INET6 && (flags & AI_V4MAPPED) != 0) { + returnValue.add(InetAddress.getByAddress(ipv4ToMappedIpv6(v4Address))); } - return out; + return returnValue; } - if (v6 != null) { - if (family == AF_UNSPEC || family == AF_INET6) { - out.add(InetAddress.getByAddress(v6)); + if (v6Address != null) { + if (addressFamily == AF_UNSPEC || addressFamily == AF_INET6) { + returnValue.add(InetAddress.getByAddress(v6Address)); } } - return out; + return returnValue; } - private static @NotNull List<@NotNull InetAddress> resolveDnsNode(@NotNull String node, int family, int flags) throws UnknownHostException { - InetAddress[] resolved = InetAddress.getAllByName(node); + private static @NotNull List<@NotNull InetAddress> resolveDnsNode(@NotNull String node, int addressFamily, int flags) throws UnknownHostException { + InetAddress[] resolvedAddresses = InetAddress.getAllByName(node); - List v4 = new ArrayList<>(); - List v6 = new ArrayList<>(); - for (InetAddress addr : resolved) { - if (addr.getAddress().length == 16) v6.add(addr); - else v4.add(addr); + List v4Address = new ArrayList<>(); + List v6Address = new ArrayList<>(); + for (InetAddress address : resolvedAddresses) { + if (address.getAddress().length == 16) v6Address.add(address); + else v4Address.add(address); } - List out = new ArrayList<>(); + List returnValue = new ArrayList<>(); - if (family == AF_UNSPEC) { - out.addAll(Arrays.asList(resolved)); - return out; + if (addressFamily == AF_UNSPEC) { + returnValue.addAll(Arrays.asList(resolvedAddresses)); + return returnValue; } - if (family == AF_INET) { - out.addAll(v4); - return out; + if (addressFamily == AF_INET) { + returnValue.addAll(v4Address); + return returnValue; } // AF_INET6 - out.addAll(v6); - if ((flags & AI_V4MAPPED) != 0 && (((flags & AI_ALL) != 0) || v6.isEmpty())) { - for (@NotNull InetAddress a : v4) { - out.add(InetAddress.getByAddress(ipv4ToMappedIpv6(a.getAddress()))); + returnValue.addAll(v6Address); + if ((flags & AI_V4MAPPED) != 0 && (((flags & AI_ALL) != 0) || v6Address.isEmpty())) { + for (@NotNull InetAddress a : v4Address) { + returnValue.add(InetAddress.getByAddress(ipv4ToMappedIpv6(a.getAddress()))); } } - return out; + return returnValue; } private static @NotNull List<@NotNull SockProtoPair> buildSockProtoPairs(int socktype, int protocol) { - @NotNull List<@NotNull SockProtoPair> out = new ArrayList<>(); + @NotNull List<@NotNull SockProtoPair> returnValue = new ArrayList<>(); if (socktype == 0) { if (protocol == 0 || protocol == IPPROTO_TCP) { - out.add(new SockProtoPair(SOCK_STREAM, IPPROTO_TCP)); + returnValue.add(new SockProtoPair(SOCK_STREAM, IPPROTO_TCP)); } if (protocol == 0 || protocol == IPPROTO_UDP) { - out.add(new SockProtoPair(SOCK_DGRAM, IPPROTO_UDP)); + returnValue.add(new SockProtoPair(SOCK_DGRAM, IPPROTO_UDP)); } - return out; + return returnValue; } if (socktype == SOCK_STREAM) { - out.add(new SockProtoPair(SOCK_STREAM, IPPROTO_TCP)); - return out; + returnValue.add(new SockProtoPair(SOCK_STREAM, IPPROTO_TCP)); + return returnValue; } if (socktype == SOCK_DGRAM) { - out.add(new SockProtoPair(SOCK_DGRAM, IPPROTO_UDP)); - return out; + returnValue.add(new SockProtoPair(SOCK_DGRAM, IPPROTO_UDP)); + return returnValue; } - return out; + return returnValue; } }