powpow/net/common

Search:
Group by:

Common networking utilities for powpow. This module provides platform-agnostic socket types, error handling, and helper functions for setting socket options and resolving addresses. It abstracts away differences between Windows and POSIX APIs, allowing powpow to use a consistent interface for network operations across platforms.

Types

NetError = object of CatchableError

Consts

DefaultBufSize = 4096
Default read buffer size per connection.
O_BINARY = 0'i32
O_RDONLY = 0
SEEK_CUR = 1
SEEK_END = 2
SEEK_SET = 0

Procs

proc closeFile(fd: int) {.inline, ...raises: [], tags: [], forbids: [].}
Close a file descriptor.
proc getFileSize(fd: int): int64 {....raises: [], tags: [], forbids: [].}
Get file size from an open fd. Returns -1 on error.
proc getSockLen(addrBuf: ptr Sockaddr_storage): SockLen {.inline, ...raises: [],
    tags: [], forbids: [].}
Return the correct socklen for the address family.
proc initNet() {....raises: [], tags: [], forbids: [].}
Initialize networking. Safe to call multiple times.
proc isIpAddress(address: string): bool {....raises: [], tags: [], forbids: [].}
True when address is a numeric IPv4 or IPv6 literal (no DNS needed).
proc lastSocketError(): cint {.inline, ...raises: [], tags: [], forbids: [].}
Get the last socket error (platform-agnostic).
proc openFileRead(path: string): int {....raises: [], tags: [], forbids: [].}
Open a file for reading. Returns fd or -1 on error. On Windows, force binary mode to prevent _read from treating 0x1A (Ctrl-Z) as EOF in binary files like videos/images.
proc readFile(fd: int; buf: ptr UncheckedArray[byte]; len: int): int64 {.
    ...raises: [], tags: [], forbids: [].}
Read up to len bytes from a file. Returns bytes read, 0 on EOF, -1 on error.
proc resolveAddr(address: string; port: int; sockType = SOCK_STREAM;
                 protocol = 0): Sockaddr_storage {....raises: [NetError], tags: [],
    forbids: [].}
Resolve address:port into the FIRST socket address ready for bind/connect. Works for both IPv4 and IPv6. For multi-address fallback use resolveAddrAll.
proc resolveAddrAll(address: string; port: int; sockType = SOCK_STREAM;
                    protocol = 0): seq[Sockaddr_storage] {....raises: [NetError],
    tags: [], forbids: [].}
Resolve address:port into ALL returned socket addresses (walks the addrinfo chain, so hosts with multiple A/AAAA records yield multiple candidates). The caller may try them in order for connect fallback.
proc seekFile(fd: int; offset: int64): int64 {....raises: [], tags: [], forbids: [].}
Seek to an absolute position in a file. Returns new position or -1 on error.
proc sendFileChunk(sockFd: SocketHandle; fileFd: int; fileOff: var int64;
                   remaining: var int64): int64 {....raises: [], tags: [],
    forbids: [].}
Send file data to a socket using zero-copy when available. Updates fileOff and remaining. Returns bytes sent, 0 on EAGAIN (caller should retry when socket is writable),
-1 on hard error.
proc setIpv6Only(fd: SocketHandle) {....raises: [], tags: [], forbids: [].}
Set IPV6_V6ONLY so an IPv6 wildcard socket does not also claim IPv4 (required to bind 0.0.0.0 and :: on the same port). No-op on Windows.
proc setNonBlocking(fd: SocketHandle) {....raises: [NetError], tags: [],
                                        forbids: [].}
Put a socket into non-blocking mode using a single ioctl syscall.
proc setReuseAddr(fd: SocketHandle) {....raises: [NetError], tags: [], forbids: [].}
Enable SO_REUSEADDR on a socket.
proc setReusePort(fd: SocketHandle) {....raises: [NetError], tags: [], forbids: [].}
Enable SO_REUSEPORT on a socket (macOS/Linux). No-op on Windows.
proc setTcpCork(fd: SocketHandle; enable: bool) {....raises: [], tags: [],
    forbids: [].}
Enable or disable TCP corking (TCP_CORK on Linux, TCP_NOPUSH on macOS/BSD). No-op on Windows and other unsupported platforms.
proc setTcpNoDelay(fd: SocketHandle) {....raises: [], tags: [], forbids: [].}
Disable Nagle's algorithm for lower latency. Silently ignores errors (e.g. on AF_UNIX sockets where TCP_NODELAY is not applicable).
proc sockaddrFromIp(ip: string; port: int): Sockaddr_storage {.
    ...raises: [NetError], tags: [], forbids: [].}
Build a socket address from a numeric IPv4/IPv6 literal without calling getaddrinfo (which blocks on the resolver). Raises NetError otherwise.
proc sockClose(fd: SocketHandle) {.inline, ...raises: [], tags: [], forbids: [].}
Close a socket.
proc sockInProgress(): bool {.inline, ...raises: [], tags: [], forbids: [].}
proc sockInterrupted(): bool {.inline, ...raises: [], tags: [], forbids: [].}
proc sockRecv(fd: SocketHandle; buf: pointer; bufLen: int): int {.inline,
    ...raises: [], tags: [], forbids: [].}
Read from a socket. Returns bytes read, 0 on EOF, negative on error.
proc sockSend(fd: SocketHandle; buf: pointer; len: int): int {.inline,
    ...raises: [], tags: [], forbids: [].}
Write to a socket. Returns bytes written, negative on error.
proc sockShutdown(fd: SocketHandle; how: cint) {.inline, ...raises: [], tags: [],
    forbids: [].}
Shut down part of a full-duplex connection.
proc sockWouldBlock(): bool {.inline, ...raises: [], tags: [], forbids: [].}
proc sockWritev(fd: SocketHandle; iov: ptr IOVec; iovcnt: int): int {.inline,
    ...raises: [], tags: [], forbids: [].}
Scatter-gather write. On Windows there is no synchronous writev, so a loop of send() calls (one per iovec) would cost N syscalls vs 1 on POSIX — the HTTP response path routinely builds ~7 iovecs. Coalesce small writes into a single send() call instead.