pub struct Socket<'n, 'a: 'n> { /* private fields */ }Expand description
A UDP socket, held as a capability.
Minted by net-stack and validated by the kernel on every use, exactly as a file capability is
(7.10). Holding one is the authority to send through it and nothing else: it names one source
port, it cannot be widened, and it stops working the moment net-stack revokes it or dies.
§Why it borrows the Net handle
The same reason File borrows its Fs: both speak to one service over one
endpoint and must share ONE correlation-tag counter. Two counters can mint the same tag for two
exchanges in flight, and the result is not a loud rejection but a stale reply silently accepted
as the current answer. The borrow makes that unspellable.
Implementations§
Source§impl<'n, 'a: 'n> Socket<'n, 'a>
impl<'n, 'a: 'n> Socket<'n, 'a>
Sourcepub fn send_to(
&mut self,
ip: Ipv4,
port: u16,
data: &[u8],
buf: &mut [u8],
) -> Result<usize, Error>
pub fn send_to( &mut self, ip: Ipv4, port: u16, data: &[u8], buf: &mut [u8], ) -> Result<usize, Error>
Send a datagram and return what came back, in buf.
Returns how many bytes of response landed in buf. Zero means nothing answered - which
is an ordinary outcome for UDP, not an error, and is why this is Ok(0) rather than an
Err. Nothing is retried on your behalf.
Blocks up to SOCKET_SECS, because the round trip happens inside net-stack - it
sends, retries, and waits for the response before replying to us at all.
Authority: this capability’s WRITE right, checked by the KERNEL before net-stack is
reached.
§The ambiguity, stated
net-stack answers “nothing came back” - and also “not sent at all”, when it has no gateway
yet - with a single zero byte, which is byte-identical to a
genuine one-byte response of 0x00. This reports both as Ok(0). The protocol makes them the
same bytes, so no reading of it can tell them apart; recording that is better than choosing
one and being quietly wrong for the other. (services/shell reports the sentinel as one byte
of DATA, which is how sock says “received 1 bytes back” about a query nobody answered.)
§Errors
Error::PermissionDenied- this capability does not carryWRITE.Error::Revoked-net-stackrevoked it, or died and was replaced. Open a new one.Error::BufferTooSmall- the response does not fit. Nothing is retried; the datagram was already sent, so call again only if the peer tolerates a repeat.- A send MUTATES the world. On
Error::OutcomeUnknownthe datagram may have left; seeError::retry_is_safe, which says no.
Sourcepub fn take_held(&mut self) -> Option<Message>
pub fn take_held(&mut self) -> Option<Message>
Take one message that arrived during an operation and was NOT the reply.
Drain this in a loop after every operation if your task serves clients - they are real
requests, held rather than dropped, and only you can answer them. A program that serves
nobody always gets None.
Trait Implementations§
Source§impl<'n, 'a: 'n> Drop for Socket<'n, 'a>
impl<'n, 'a: 'n> Drop for Socket<'n, 'a>
Source§fn drop(&mut self)
fn drop(&mut self)
Drops our handle to the capability.
There is no close operation for a UDP socket - net-stack exposes send and nothing else
on this capability - so this releases the local cap-table slot and cannot tell the service
anything. The socket is reclaimed when net-stack revokes it or restarts. Recorded rather
than hidden: a reader comparing this with File, which does close, would
otherwise assume an omission.