From 5a6edd6f458ec2fde77a9ff95ff7d52628284ce3 Mon Sep 17 00:00:00 2001
From: Dave Bakker
Date: Sat, 18 Mar 2023 09:39:03 +0100
Subject: [PATCH 1/2] Merge bind and listen into a single call.
---
wit/tcp-create-socket.wit | 2 +-
wit/tcp.wit | 66 ++++++++++++++++-----------------------
2 files changed, 28 insertions(+), 40 deletions(-)
diff --git a/wit/tcp-create-socket.wit b/wit/tcp-create-socket.wit
index 04e3943..a41ca38 100644
--- a/wit/tcp-create-socket.wit
+++ b/wit/tcp-create-socket.wit
@@ -8,7 +8,7 @@ default interface tcp-create-socket {
/// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX.
///
/// This function does not require a network capability handle. This is considered to be safe because
- /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect`
+ /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `listen`/`connect`
/// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world.
///
/// # Typical errors
diff --git a/wit/tcp.wit b/wit/tcp.wit
index 0f5f180..b47bf6e 100644
--- a/wit/tcp.wit
+++ b/wit/tcp.wit
@@ -20,30 +20,7 @@ default interface tcp {
}
- /// Bind the socket to a specific network on the provided IP address and port.
- ///
- /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which
- /// network interface(s) to bind to.
- /// If the TCP/UDP port is zero, the socket will be bound to a random free port.
- ///
- /// When a socket is not explicitly bound, the first invocation to a listen or connect operation will
- /// implicitly bind the socket.
- ///
- /// # Typical errors
- /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL)
- /// - `already-bound`: The socket is already bound. (EINVAL)
- /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
- /// - `address-in-use`: Address is already in use. (EADDRINUSE)
- /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL)
- /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
- ///
- /// # References
- /// -
- /// -
- /// -
- /// -
- bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code>
-
+
/// Connect to a remote endpoint.
///
/// On success:
@@ -58,11 +35,10 @@ default interface tcp {
/// - `address-family-mismatch`: The `remote-address` has the wrong address family. (EAFNOSUPPORT)
/// - `invalid-remote-address`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows)
/// - `invalid-remote-address`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows)
- /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`.
/// - `already-connected`: The socket is already in the Connection state. (EISCONN)
/// - `already-listening`: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
/// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
- /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
+ /// - `concurrency-conflict`: Another `connect` or `listen` operation is already in progress. (EALREADY)
///
/// # References
/// -
@@ -71,23 +47,35 @@ default interface tcp {
/// -
connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result, error-code>
- /// Start listening for new connections.
+ /// Bind the socket to a specific network on the provided IP address & port and start listening for new connections.
+ ///
+ /// This is the POSIX equivalent of calling `bind` and `listen` consecutively.
+ ///
+ /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which
+ /// network interface(s) to bind to.
+ /// If the TCP/UDP port is zero, the socket will be bound to a random free port.
///
/// Transitions the socket into the Listener state.
///
/// # Typical errors
- /// - `already-attached`: The socket is already attached to a different network. The `network` passed to `listen` must be identical to the one passed to `bind`.
+ /// - `address-family-mismatch`: The `local-address` has the wrong address family. (EINVAL)
/// - `already-connected`: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
/// - `already-listening`: The socket is already in the Listener state.
- /// - `ephemeral-ports-exhausted`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
- /// - `concurrency-conflict`: Another `bind`, `connect` or `listen` operation is already in progress. (EINVAL on BSD)
+ /// - `ephemeral-ports-exhausted`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
+ /// - `address-in-use`: Address is already in use. (EADDRINUSE)
+ /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL)
+ /// - `concurrency-conflict`: Another `connect` or `listen` operation is already in progress. (EALREADY, EINVAL on BSD)
///
/// # References
+ /// -
/// -
+ /// -
/// -
+ /// -
/// -
+ /// -
/// -
- listen: func(this: tcp-socket, network: network) -> result<_, error-code>
+ listen: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code>
/// Accept a new client socket.
///
@@ -120,7 +108,7 @@ default interface tcp {
/// -
local-address: func(this: tcp-socket) -> result
- /// Get the bound remote address.
+ /// Get the connected remote address.
///
/// # Typical errors
/// - `not-connected`: The socket is not connected to a remote address. (ENOTCONN)
@@ -145,7 +133,7 @@ default interface tcp {
/// - `ipv6-only-operation`: (get/set) `this` socket is an IPv4 socket.
/// - `already-bound`: (set) The socket is already bound.
/// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
- /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
+ /// - `concurrency-conflict`: (set) A `connect` or `listen` operation is already in progress. (EALREADY)
ipv6-only: func(this: tcp-socket) -> result
set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error-code>
@@ -153,20 +141,20 @@ default interface tcp {
///
/// # Typical errors
/// - `already-connected`: (set) The socket is already in the Connection state.
- /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
+ /// - `concurrency-conflict`: (set) A `connect` or `listen` operation is already in progress. (EALREADY)
set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error-code>
/// Equivalent to the SO_KEEPALIVE socket option.
///
/// # Typical errors
- /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
+ /// - `concurrency-conflict`: (set) A `connect` or `listen` operation is already in progress. (EALREADY)
keep-alive: func(this: tcp-socket) -> result
set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error-code>
/// Equivalent to the TCP_NODELAY socket option.
///
/// # Typical errors
- /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
+ /// - `concurrency-conflict`: (set) A `connect` or `listen` operation is already in progress. (EALREADY)
no-delay: func(this: tcp-socket) -> result
set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error-code>
@@ -175,7 +163,7 @@ default interface tcp {
/// # Typical errors
/// - `already-connected`: (set) The socket is already in the Connection state.
/// - `already-listening`: (set) The socket is already in the Listener state.
- /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
+ /// - `concurrency-conflict`: (set) A `connect` or `listen` operation is already in progress. (EALREADY)
unicast-hop-limit: func(this: tcp-socket) -> result
set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error-code>
@@ -193,7 +181,7 @@ default interface tcp {
/// # Typical errors
/// - `already-connected`: (set) The socket is already in the Connection state.
/// - `already-listening`: (set) The socket is already in the Listener state.
- /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
+ /// - `concurrency-conflict`: (set) A `connect` or `listen` operation is already in progress. (EALREADY)
receive-buffer-size: func(this: tcp-socket) -> result
set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code>
send-buffer-size: func(this: tcp-socket) -> result
@@ -209,7 +197,7 @@ default interface tcp {
/// They're planned to be removed when `future` is natively supported in Preview3.
///
/// # Typical errors
- /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY)
+ /// - `concurrency-conflict`: (set) A `connect` or `listen` operation is already in progress. (EALREADY)
non-blocking: func(this: tcp-socket) -> result
set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error-code>
From 6119993908a18389c9e3e4f80e5d32f62bab0baa Mon Sep 17 00:00:00 2001
From: Dave Bakker
Date: Sat, 18 Mar 2023 10:09:21 +0100
Subject: [PATCH 2/2] Update example-world.md
---
example-world.md | 73 +++++++++++++++++-------------------------------
1 file changed, 25 insertions(+), 48 deletions(-)
diff --git a/example-world.md b/example-world.md
index b9c020f..5d3f5cf 100644
--- a/example-world.md
+++ b/example-world.md
@@ -992,39 +992,6 @@ be used.
Functions
-
-Bind the socket to a specific network on the provided IP address and port.
-If the IP address is zero (0.0.0.0
in IPv4, ::
in IPv6), it is left to the implementation to decide which
-network interface(s) to bind to.
-If the TCP/UDP port is zero, the socket will be bound to a random free port.
-When a socket is not explicitly bound, the first invocation to a listen or connect operation will
-implicitly bind the socket.
-Typical errors
-
-address-family-mismatch
: The local-address
has the wrong address family. (EINVAL)
-already-bound
: The socket is already bound. (EINVAL)
-ephemeral-ports-exhausted
: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
-address-in-use
: Address is already in use. (EADDRINUSE)
-address-not-bindable
: local-address
is not an address that the network
can bind to. (EADDRNOTAVAIL)
-concurrency-conflict
: Another bind
, connect
or listen
operation is already in progress. (EALREADY)
-
-References
-
-Params
-
-Return values
-
Connect to a remote endpoint.
On success:
@@ -1041,11 +1008,10 @@ implicitly bind the socket.
address-family-mismatch
: The remote-address
has the wrong address family. (EAFNOSUPPORT)
invalid-remote-address
: The IP address in remote-address
is set to INADDR_ANY (0.0.0.0
/ ::
). (EADDRNOTAVAIL on Windows)
invalid-remote-address
: The port in remote-address
is set to 0. (EADDRNOTAVAIL on Windows)
-already-attached
: The socket is already attached to a different network. The network
passed to connect
must be identical to the one passed to bind
.
already-connected
: The socket is already in the Connection state. (EISCONN)
already-listening
: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
ephemeral-ports-exhausted
: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
-concurrency-conflict
: Another bind
, connect
or listen
operation is already in progress. (EALREADY)
+concurrency-conflict
: Another connect
or listen
operation is already in progress. (EALREADY)
References
-Start listening for new connections.
+Bind the socket to a specific network on the provided IP address & port and start listening for new connections.
+This is the POSIX equivalent of calling bind
and listen
consecutively.
+If the IP address is zero (0.0.0.0
in IPv4, ::
in IPv6), it is left to the implementation to decide which
+network interface(s) to bind to.
+If the TCP/UDP port is zero, the socket will be bound to a random free port.
Transitions the socket into the Listener state.
Typical errors
-already-attached
: The socket is already attached to a different network. The network
passed to listen
must be identical to the one passed to bind
.
+address-family-mismatch
: The local-address
has the wrong address family. (EINVAL)
already-connected
: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
already-listening
: The socket is already in the Listener state.
-ephemeral-ports-exhausted
: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
-concurrency-conflict
: Another bind
, connect
or listen
operation is already in progress. (EINVAL on BSD)
+ephemeral-ports-exhausted
: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
+address-in-use
: Address is already in use. (EADDRINUSE)
+address-not-bindable
: local-address
is not an address that the network
can bind to. (EADDRNOTAVAIL)
+concurrency-conflict
: Another connect
or listen
operation is already in progress. (EALREADY, EINVAL on BSD)
References
Params
Return values
-Get the bound remote address.
+Get the connected remote address.
Typical errors
not-connected
: The socket is not connected to a remote address. (ENOTCONN)
@@ -1177,7 +1154,7 @@ a pair of streams that can be used to read & write to the connection.
ipv6-only-operation
: (get/set) this
socket is an IPv4 socket.
already-bound
: (set) The socket is already bound.
not-supported
: (set) Host does not support dual-stack sockets. (Implementations are not required to.)
-concurrency-conflict
: (set) A bind
, connect
or listen
operation is already in progress. (EALREADY)
+concurrency-conflict
: (set) A connect
or listen
operation is already in progress. (EALREADY)
Params