# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 1.0.0 - 2026-10-22

First official release of the WASI library. It supports the Wasm module instances and requires Architecture 9.0.0 or higher.

### Changed

 - Migrate WASI implementation to the Wasm module instances specification (Architecture 9.0.0).
 - Isolate WASI context per `WasmModule` instance (file descriptors, pre-opened directories, environment, and RNG).
 - Declare the `wasi_snapshot_preview1` and `wasi_ssl` host functions public, as required by the stronger import accessibility checks of Architecture 9.0.0.
 - Update the SSL API to 2.3.1, which depends on the Crypto API instead of the Security API.
 - Update the BON API to 1.6.0.

## 0.1.4 - 2026-03-31

### Added

 - Add `fd_renumber` WASI function (atomically replace a file descriptor by renumbering another).
 - Add missing POSIX socket/IP constants: `SO_SNDBUF`, `SO_RCVBUF`, `SO_KEEPALIVE`, `TCP_NODELAY`, `IPPROTO_IPV6`, `IPV6_V6ONLY`, and `NI_*` name-info flags.
 - Add numeric-only `getnameinfo()` implementation (reverse DNS is not available on WASI; `NI_NAMEREQD` returns `EAI_NONAME` as POSIX requires).
 - Add `AI_ADDRCONFIG`, `AI_V4MAPPED`, and `AI_ALL` hint flag defines for DNS resolution.
 - Add `fd_sync`, `path_link`, and `path_symlink` WASI stubs (`fd_sync` returns SUCCESS; `path_link` and `path_symlink` return NOSYS).
 - Add POSIX `getifaddrs()`/`freeifaddrs()` for network interface enumeration, backed by `getifaddrs_count_ext`/`getifaddrs_get_ext` WASI imports using `java.net.NetworkInterface`.
 - Add UDP datagram socket support (`WasiDatagramSocket`) with `sendto_ext`/`recvfrom_ext` taking parsed IP bytes + port.
 - Add `socket()` C wrapper that strips `SOCK_NONBLOCK`/`SOCK_CLOEXEC` flags before forwarding to the Java runtime.
 - Add `Wasi.setEnvironment()` API and implement `environ_sizes_get`/`environ_get` to pass environment variables to WASI modules.
 - Add socket error mapping: translate `NativeIOException` error codes (`J_EADDRINUSE`, `J_EMSGSIZE`, `J_EINVAL`, `J_ECONNREFUSED`) to WASI errno values via `WasiIOException`, propagating specific errors through `bind_ext`, `listen`, and `sendto_ext` instead of generic `ERRNO_IO`.
 - Add `listen()` C wrapper converting WASI errno return values to POSIX convention (0/-1 + `errno`), so that C code calling `listen()` gets standard POSIX error reporting.
 - Add POSIX-compatible listen-without-bind: auto-bind to ephemeral port when `listen()` is called on an unbound socket.
 - Add WASI errno constants: `ERRNO_ADDRINUSE` (3), `ERRNO_ADDRNOTAVAIL` (4), `ERRNO_CONNREFUSED` (14), `ERRNO_MSGSIZE` (35).
 - Add `getsockopt_ext` WASI import for socket option queries (`SO_RCVBUF`/`SO_SNDBUF`).
 - Add socket buffer size support (`setReceiveBufferSize`/`getReceiveBufferSize`/`setSendBufferSize`/`getSendBufferSize`) in `WasiSocketOpt` interface and all socket implementations.
 - Add `SO_BROADCAST` support in `setsockopt`/`getsockopt` — delegates to `DatagramSocket.setBroadcast()`/`getBroadcast()` for UDP sockets; no-op for stream and server sockets.
 - Add `IPPROTO_IP` and `IPPROTO_IPV6` socket option constants (`IP_TTL`, `IP_MULTICAST_*`, `IP_ADD/DROP_MEMBERSHIP`, `IPV6_*_HOPS`, `IPV6_MULTICAST_*`, `IPV6_JOIN/LEAVE_GROUP`).
 - Add IPv4 multicast support via `MulticastSocket`: `IP_MULTICAST_IF` sets outgoing interface, `IP_MULTICAST_TTL` sets hop limit, `IP_MULTICAST_LOOP` controls loopback, `IP_ADD_MEMBERSHIP`/`IP_DROP_MEMBERSHIP` join/leave groups. IPv6 multicast options (`IPPROTO_IPV6`) remain whitelisted no-ops.

### Changed

 - Optimize `Selector.select()` to check `available()` before the expensive `isConnectionReset()` — skips mark/read/reset + SO_TIMEOUT toggle when data is already buffered.
 - Add `available()` fast-path to `WasiSocketInputStream.read()` non-blocking branch — reads buffered data without touching SO_TIMEOUT; only falls back to a timed probe when the buffer is empty.
 - Make `parse_sockaddr` a `static` function in `wasi-ext.c` and remove it from `wasi-ext.h` to avoid symbol collisions with third-party libraries.
 - Java `listen()` now returns WASI errno values (0/positive) instead of 0/-1; a new C wrapper translates back to POSIX convention.
 - Update README with complete function inventory: add missing WASI API groups (environment, scheduling, random, threads, unsupported stubs), expand POSIX and extended POSIX tables (UDP, DNS, SSL/TLS, threading, filesystem), and add Notes section documenting caveats.
 - `WasiServerSocket.bind()` validates address against local interfaces — returns `EADDRNOTAVAIL` early for non-local addresses.
 - `extractWasiErrno()` detects `BindException` as fallback when no `NativeIOException` found in cause chain.
 - `setsockopt` handles `SO_RCVBUF`/`SO_SNDBUF` (was silently ignored).
 - `setsockopt` now returns `ERRNO_NOSYS` for unknown options/levels instead of silently succeeding — only whitelisted options are accepted.
 - `WasiDatagramSocket` now uses `MulticastSocket` instead of `DatagramSocket` to enable multicast operations (join/leave group, TTL, loopback, outgoing interface).
 - Rename configurable constant `MAX_DGRAM_SIZE` to `UDP_PEEK_BUFFER_MAX_SIZE` (property key: `ej.wasi.select.udp.peek.buffer.max.size`) to reflect its actual usage: capping the Selector's UDP peek buffer allocation.
 - `accept()` now returns `ERRNO_INVAL` on server sockets that have not called `listen()`, matching POSIX semantics.

### Fixed

 - Fix `WasiPipe` connection loop where `socketWriteEnd.isConnected()` evaluated to false causing an infinite loop; check `socketReadEnd == null` instead, which becomes false when the connection is completed.
 - Fix `path_open` discarding `fdflags` parameter — `O_APPEND` opens lost append semantics because only `oflags` were forwarded; now delegates to `fd_fdstat_set_flags` after opening.
 - Fix `path_open` failing with I/O error when opening a directory without `O_DIRECTORY` flag — POSIX allows `open("dir", O_RDONLY)` on directories; now returns a directory fd.
 - Fix `fd_fdstat_get` returning zero rights for all file descriptors, causing wasi-libc's `faccessat` W_OK check to fail with EACCES; now returns `RIGHTS_ALL` for regular files and `RIGHTS_DIR` (excluding seek, tell, write, etc.) for directories, matching wasmtime/wasmer behavior.
 - Fix `SO_ERROR` value in `wasi-ext.h` — was defined as `10`; change to `4` (matching Linux ABI).
 - Fix `getsockname_ext` WASM import routing to `"getpeername_ext"` instead of `"getsockname_ext"` — `getsockname()` was returning the peer address instead of the local address.
 - Fix `poll_oneoff` returning `ERRNO_IO` for FD_READ readiness checks on UDP sockets — `Selector.pendingInputDataCount()` did not handle `WasiDatagramSocket`, causing any `uv_udp_recv_start()` with the event loop to fail.
 - Fix `getSocketAddress()` rejecting UDP and server sockets with `ERRNO_NOTSOCK` — only `WasiSocket` (TCP client) was handled; now supports `WasiDatagramSocket` and `WasiServerSocket` as well.
 - Fix `canAccept()` clobbering server socket non-blocking mode — the readiness peek restored the constructor-time `SoTimeout` (0 = infinite blocking) instead of the live value, causing subsequent `accept()` calls to block indefinitely when the accept queue was empty.
 - Fix `canAccept()` returning `true` on generic `IOException` — the catch-all left `canAccept` at its initial `true` value, which could falsely report the server socket as readable.
 - Fix `listen()` failing when called multiple times — POSIX allows repeated `listen()` (e.g. to update the backlog); Java `ServerSocket.bind()` throws on a second call, so now skip it if already listening.
 - Fix `getSocketAddress()` returning IPv6 family for IPv4-bound sockets on dual-stack systems — Java reports `::` (IPv6) even when bound to `0.0.0.0`; now detects IPv4-mapped/compatible IPv6 addresses and converts them back to IPv4.
 - Fix signed port overflow in `parse_sockaddr` and callers (`bind`, `connect`, `sendto`) — `short port` truncated ephemeral ports above 32767 to negative values, causing Java's `InetSocketAddress` to reject them with "port out of range"; now uses `uint16_t`.
 - Remove duplicate `EAI_FAIL` define (value `42`, dead code — already defined as `-4` earlier in the header).
 - Fix `bind_ext` swallowing bind errors for TCP sockets — the inner `catch (IOException)` block closed the server socket but did not re-throw, causing `bind_ext` to return `ERRNO_SUCCESS` even when `WasiServerSocket.bind()` failed (e.g. with `ERRNO_ADDRNOTAVAIL`).
 - Fix TCP `getsockname` returning `ENOTCONN` between `bind()` and `listen()` — `WasiServerSocket.bind()` deferred the OS-level bind to `listen()`, so `getLocalSocketAddress()` returned null; now eagerly binds at the OS level so `getsockname()` works immediately (POSIX semantics).

## 0.1.3 - 2025-08-04

### Changed

 - Use the B-ON constant `ej.wasi.socket.buffered.input.stream.size` to define the size of the buffered input stream used for sockets.
 - Set the B-ON constant `ej.wasi.socket.nonblocking.timeout` to 1 ms instead of 1000 ms.
 - Use WasiSocketInputStream (based on a BufferedInputStream) to handle blocking/non-blocking modes for WasiSocket and WasiSSL.

### Fixed

 - Handle connection reset case in Selector to allow `select` to return when the connection has been reset by the peer.
 - Fix issue in `wasi-ext.c` with  `getaddrinfo` returning invalid error code when an `UnknownHostException` is catched.

## 0.1.2 - 2025-07-09

### Changed

 - Use the B-ON constants `ej.wasi.socket.connect.timeout` and `ej.wasi.socket.nonblocking.timeout` to define timeouts used to emulate non-blocking socket operations.
 - Use the B-ON constant `ej.wasi.select.polling.timeout` to define the select polling timeout.
 
### Fixed

 - Use the appropriate stream types based on the blocking mode in The WasiSocket#setNonBlocking method.

## 0.1.1 - 2025-06-04

### Changed

 - Change the configuration mapping of the `edc-internal-1.2-api`, `net-errors`, and `ssl-errors` dependencies to a private visibility configuration in the generated ivy.xml file.
 - Set `transitive=false` on SSL API dependency to prevent pulling in unused Security API as a transitive dependency.

## 0.1.0 - 2025-05-28

### Added

 - Implement Wasi API functions:
	- poll_oneoff
	- clock_time_get/clock_res_get
	- fd_close/fd_read/fd_write/fd_seek/fd_pread/fd_pwrite/fd_readdir/fd_tell
	- fd_fdstat_get/fd_prestat_get/fd_filestat_get/fd_prestat_dir_name/fd_filestat_set_size 
	- proc_exit
	- sock_accept/sock_shutdown
	- path_open/path_unlink_file/path_remove_directory/path_filestat_get/path_create_directory 
	- random_get
	- path_rename
	- path_filestat_set_times : last modified implemented, last accessed is stubbed and doesn't do anything.
	- path_readlink: Unsupported
	 
 - Implement Extended WASI API functions:
	- pipe
	- socket
	- setsockopt
	- bind
	- listen
	- connect
	- dup/dup2
	- getpeername
	- fchdir
	- gethostname
	- getsockname
	- getaddrinfo
	- recvfrom
	- sendto
	- SSL_new
	- SSL_set_fd
	- SSL_accept
	- SSL_pending
	- SSL_set_tlsext_host_name
	- SSL_connect
	- SSL_write
	- SSL_read
	- SSL_want_read
	- SSL_want_write: always return false (non blocking write not supported)
	- SSL_shutdown
	- SSL_free
	- SSL_CTX_free

 - Stubbed functions:
	- args_sizes_get/args_get
	- environ_sizes_get/environ_get
	- fd_datasync (we assume flush is automatically done on write)
 	 
 - Wasi thread support
 - Customizable standard output, standard error, and standard input
 - IPv4 and IPv6 support for socket bind/connect
 - Update wasi-ext.h and wasi-ext.c to be clang++ compliance
 
---

_Copyright 2024-2026 MicroEJ Corp. All rights reserved._
_Use of this source code is governed by a BSD-style license that can be found with this software._
_Build: 7E4D1F7C_