socketModule
Low-level Lua interface for kernel networking sockets.
This library provides support for creating and managing various types of sockets within the Linux kernel, enabling network communication directly from Lua scripts running in kernel space. It is inspired by Chengzhi Tan’s GSoC project. It allows operations such as creating sockets, binding, listening, connecting,
sending, and receiving data. The constants for address families, socket types,
protocols, message flags and option levels and names are in linux.socket
(af, sock, ipproto, msg, sol, so, ip).
An integer argument is bounded to the kernel type that takes it, an int unless a method
says otherwise: one past it raises “out of bounds” instead of reaching the kernel truncated.
Sockets sleep: a script creates and uses them in a process runtime, the default, or in a
spawned thread. In a softirq or hardirq runtime, socket.new and accept raise
'socket': process-context class in interrupt-context runtime.
For higher-level IPv4 TCP/UDP socket operations with string-based IP addresses (e.g., “127.0.0.1”), consider using the socket.inet library.
See also
Class socket
| socket:accept ([flags=0]) | Accepts a connection on a listening socket. |
| socket:bind (addr[, port]) | Binds the socket to a local address. |
| socket:close () | Closes the socket. |
| socket:connect (addr[, port[, flags=0]]) | Initiates a connection on a socket. |
| socket:getpeername () | Gets the address of the peer to which the socket is connected. |
| socket:getsockname () | Gets the local address to which the socket is bound. |
| socket:listen ([backlog]) | Puts a connection-oriented socket into the listening state. |
| socket:receive (length[, flags=0]) | Receives a message from the socket. |
| socket:receivefrom (length[, flags=0]) | Receives a message from the socket, and the address of its sender. |
| socket:send (message[, addr[, port]]) | Sends a message through the socket. |
| socket:setsockopt (level, optname, value) | Sets a socket option. |
socket
| new (family, type, protocol[, pid]) | Creates a new socket object. |
Class socket in detail
socket.new().
A method that takes an address reads it the way the family the socket was created with spells it:
AF_INET: two integers, the IPv4 address (e.g. fromnet.aton()), within 32 bits, and the port, within 16.AF_INET6: a packed string ofstruct sockaddr_in6past the family: the port and the flow information in network byte order, the address, and the scope id.AF_PACKET: two integers, the ethertype in host byte order, within 16 bits, and the interface index, from 0.AF_NETLINK: two optional integers, the port id and the multicast groups, both 0 by default and within 32 bits.AF_UNIX: a string, a filesystem path or, with a leading NUL, an abstract name.- Other families: a packed string of the address bytes past the family.
A method that returns an address returns it the same way. An AF_PACKET one carries three more
values after the interface index: the packet type (a linux.packet.type value), the hardware type (a
linux.arphrd value) and the hardware address, a string of the length the kernel reports: the
interface’s own for getsockname, the sender’s for receivefrom.
- socket:accept ([flags=0])
-
Accepts a connection on a listening socket.
This function is used with connection-oriented sockets (e.g.,
SOCK_STREAM) that have been put into the listening state bysock:listen(). The call blocks until a connection arrives, with no timeout of its own, unlessflagscarriesO_NONBLOCKor setsockopt set a receive timeout; either makes a wait with no connection to accept answernil, and receive says how a stop ends the wait.Parameters
- flags
integer
file status flags:
O_NONBLOCKmakes the call answer at once when no connection is pending instead of waiting for one.linux.socket.sock.NONBLOCKcarriesO_NONBLOCKon every architecture but alpha and parisc. (default 0)
Returns
-
socket
A new socket object representing the accepted connection;
niland"EAGAIN"when the wait ended with no connection to accept.Raises
Error if the accept operation fails. - flags
integer
file status flags:
- socket:bind (addr[, port])
-
Binds the socket to a local address.
This is typically used on the server side before calling
listen()or on connectionless sockets to specify a local port/interface for receiving.Parameters
- addr
integer or string
local address to bind to. Interpretation depends on the family the socket was created with:
-
AF_INET(IPv4): An integer representing the IPv4 address (e.g., fromnet.aton()). Use0(ornet.aton("0.0.0.0")) to bind to all available interfaces. Theportargument is also required. -
AF_PACKET: An integer representing the ethernet protocol in host byte order (e.g.,0x0003forETH_P_ALL,0x88CCforETH_P_LLDP) Theportargument is also required. -
AF_NETLINK: The port id, 0 to let the kernel pick one;portcarries the multicast groups. -
AF_UNIX: A filesystem path, or, when its first byte is NUL (e.g."\0name"), a name in the abstract namespace, which is registered as the exact bytes given, so a peer of any kind reaches it by the same string. The empty string asks the kernel to pick a name (autobind). - Other families: A packed string directly representing parts of the family-specific address structure.
-
- port
integer
local port or interface index.
-
AF_INET: TCP/UDP port number. -AF_PACKET: Network interface index (e.g., fromlinux.ifindex("eth0")). -AF_NETLINK: Multicast groups to join. (optional)
Returns
-
nil
Raises
Error if the bind operation fails (e.g., address already in use, invalid address).See also
Usage
-- Bind TCP/IPv4 socket to localhost, port 8080 tcp_server_sock:bind(net.aton("127.0.0.1"), 8080) -- Bind AF_PACKET socket to protocol
ETH_P_LLDPon a specific interface af_packet_sock:bind(0x88CC, linux.ifindex("eth0")) - addr
integer or string
- socket:close ()
-
Closes the socket.
This shuts down the socket for both reading and writing and releases
associated kernel resources. A to-be-closed variable holding the socket closes it the
same way, and dropping its last reference does too.
Returns
-
nil
- socket:connect (addr[, port[, flags=0]])
-
Initiates a connection on a socket.
This is typically used by client sockets to establish a connection to a server.
For datagram sockets, this sets the default destination address for send and
the only address from which datagrams are received.
A TCP connect waits for the connection, with no timeout of its own, unless
flagscarriesO_NONBLOCKor setsockopt set a send timeout; either makes a wait that ends with the connection still in progress answernil, whether this connect or an earlier one started it, and send says how a stop ends the wait. AnAF_UNIXconnect waits the same way for room in the backlog of the listener it reaches, and a wait that ends with none answersfalse.Parameters
- addr
integer or string
destination address to connect to. Interpretation depends on the family the socket was created with:
- port
integer
the address’s second integer, for
AF_INET,AF_PACKETandAF_NETLINK; for any other family,flagstakes this place. (optional) - flags
integer
file status flags:
O_NONBLOCKmakes a connect that cannot complete at once not wait for it.linux.socket.sock.NONBLOCKcarriesO_NONBLOCKon every architecture but alpha and parisc. (default 0)
Returns
-
boolean
trueonce connected;niland"EINPROGRESS"when the wait ended with the connection it started still in progress, or"EALREADY"with one an earlier connect started;falsewhen it ended with no room in anAF_UNIXlistener’s backlog.Raises
Error if the connect operation fails (e.g., connection refused, host unreachable).Usage
tcp_client_sock:connect(net.aton("192.168.1.100"), 80)
- addr
integer or string
- socket:getpeername ()
-
Gets the address of the peer to which the socket is connected.
This is typically used with connection-oriented sockets after a connection
has been established, or with connectionless sockets after
connect()has been called to set a default peer.Returns
-
integer or string
addr peer’s address.
- For
AF_INET: An integer representing the IPv4 address (can be converted withnet.ntoa()). - For
AF_UNIX: The peer’s name, carrying its leading NUL when the name is an abstract one, and the empty string when the peer is unbound. - For
AF_NETLINK: The peer’s port id. - For other families: A packed string of the address bytes past the family, of the length the kernel reports.
- For
-
integer
port The peer’s port number for
AF_INET, and its multicast groups forAF_NETLINK.
Raises
Error if the operation fails (e.g., socket not connected);EOPNOTSUPPon anAF_PACKETsocket, which names no peer.Usage
-- a connected AF_INET socket local peer_ip_int, peer_port = connected_socket:getpeername() print("Connected to " .. net.ntoa(peer_ip_int) .. ":" .. peer_port)
-
integer or string
- socket:getsockname ()
-
Gets the local address to which the socket is bound.
Returns
-
integer or string
addr local address.
- For
AF_INET: An integer representing the IPv4 address (can be converted withnet.ntoa()). - For
AF_PACKET: The ethertype the socket was created or bound with, in host byte order. - For
AF_UNIX: The bound name, carrying its leading NUL when the name is an abstract one, and the empty string when the socket is unbound. - For
AF_NETLINK: The port id. - For other families: A packed string of the address bytes past the family, of the length the kernel reports.
- For
-
integer
port The local port number for
AF_INET, the interface index forAF_PACKET, 0 when unbound, and the multicast groups forAF_NETLINK. -
integer
pkttype For
AF_PACKET, 0. -
integer
hatype For
AF_PACKET, the interface’s hardware type, 0 when unbound. -
string
hwaddr For
AF_PACKET, the interface’s hardware address, empty when unbound.
Raises
Error if the operation fails.Usage
-- an AF_INET socket local local_ip_int, local_port = my_socket:getsockname() print("Bound to " .. net.ntoa(local_ip_int) .. ":" .. local_port)
-
integer or string
- socket:listen ([backlog])
-
Puts a connection-oriented socket into the listening state.
This is required for server sockets (e.g.,
SOCK_STREAM) to be able to accept incoming connections.Parameters
- backlog
integer
maximum length of the queue for pending connections.
If omitted, a system-dependent default (e.g.,
SOMAXCONN) is used. (optional)
Returns
-
nil
Raises
Error if the listen operation fails (e.g., socket not bound, invalid state).Usage
tcp_server_sock:listen(10)
- backlog
integer
maximum length of the queue for pending connections.
If omitted, a system-dependent default (e.g.,
- socket:receive (length[, flags=0])
-
Receives a message from the socket.
The call blocks until a message arrives, with no timeout of its own, unless
flagscarrieslinux.socket.msg.DONTWAITor setsockopt set a receive timeout (linux.socket.so.RCVTIMEO_NEW); either makes a wait with nothing to read answernil. A stop of the thread that waits ends its wait, which raisesERESTARTSYS, orEINTRunder a receive timeout.Parameters
- length
integer
maximum number of bytes to receive, from 0 to
INT_MAX. - flags
integer
Optional message flags (e.g.,
linux.socket.msg.PEEK). See the linux.socket.msg table for available flags. These can be OR’d together. (default 0)
Returns
-
string
received message (as a string of bytes); on a stream socket, the empty string is
the end of file, once the peer has shut down its side;
niland"EAGAIN"when the wait ended with nothing to read.Raises
Error if the receive operation fails.See also
Usage
-- For a connected TCP socket: local data = tcp_conn_sock:receive(1024) print("Received:", data)
- length
integer
maximum number of bytes to receive, from 0 to
- socket:receivefrom (length[, flags=0])
-
Receives a message from the socket, and the address of its sender.
It waits as receive does. A connectionless socket (
SOCK_DGRAM) names the sender of each message; TCP names none, and neither does anAF_UNIXpeer that never bound, and nothing follows the message then.Parameters
- length integer maximum number of bytes to receive, as receive takes it.
- flags integer message flags, as receive takes them. (default 0)
Returns
-
string
received message, as receive returns it;
niland"EAGAIN", in place of the message and the address, when the wait ended with nothing to read. -
integer or string
addr the sender’s address (two values for
AF_INETandAF_NETLINK, five forAF_PACKET). - ForAF_INET: An integer representing the IPv4 address (can be converted withnet.ntoa()). - ForAF_PACKET: The frame’s ethertype, in host byte order. - ForAF_UNIX: The sender’s name, carrying its leading NUL when the name is an abstract one. - ForAF_NETLINK: The sender’s port id. - For other families: A packed string of the sender’s address past the family, of the length the protocol reports. -
integer
port the sender’s port number for
AF_INET, the index of the interface the frame arrived on forAF_PACKET, and its multicast groups forAF_NETLINK. -
integer
pkttype For
AF_PACKET, the frame’s packet type. -
integer
hatype For
AF_PACKET, the interface’s hardware type. -
string
hwaddr For
AF_PACKET, the sender’s hardware address.
Raises
Error if the receive operation fails.See also
Usage
-- For a UDP socket, getting sender info: local data, sender_ip_int, sender_port = udp_sock:receivefrom(1500) print("Received from " .. net.ntoa(sender_ip_int) .. ":" .. sender_port .. ": " .. data)
- socket:send (message[, addr[, port]])
-
Sends a message through the socket.
For connection-oriented sockets (
SOCK_STREAM),addrandportare usually omitted as the connection is already established. For connectionless sockets (SOCK_DGRAM),addrandport(if applicable for the address family) specify the destination. A netlink socket always sends to an address, the kernel’s (port id 0) when none is given. The call waits for room in the send buffer, with no timeout of its own, unless setsockopt set a send timeout (linux.socket.so.SNDTIMEO_NEW), which makes a wait it ends with nothing queued answerfalse. Alunatik stopof the spawned thread that waits ends its wait, which raisesERESTARTSYS, orEINTRunder a send timeout, when nothing was queued.Parameters
- message string message to send.
- addr
integer or string
destination address, as the socket type describes it.
- For
AF_INET(IPv4) sockets: An integer representing the IPv4 address (e.g., fromnet.aton()). - For
AF_PACKET: the ethertype, in host byte order. - For
AF_NETLINK: the destination port id.
- For
- port
integer
the address’s second integer: the destination port number for
AF_INET, the interface index forAF_PACKET, the multicast groups forAF_NETLINK. (optional)
Returns
-
integer or boolean
number of bytes sent, short of the message’s length on a stream socket
whose wait ended with part of it queued;
falsewhen a send timeout ended the wait with nothing queued.Raises
Error if the send operation fails or if address parameters are incorrect for the socket type;EAGAINwhen the kernel finds no free port to bind an unboundAF_INETorAF_INET6socket to before it sends.See also
Usage
-- For a connected TCP socket: local bytes_sent = tcp_conn_sock:send("Hello, server!") -- For a UDP socket (sending to 192.168.1.100, port 1234): local bytes_sent = udp_sock:send("UDP packet", net.aton("192.168.1.100"), 1234)
- socket:setsockopt (level, optname, value)
-
Sets a socket option.
SOL_SOCKEToptions are handled by the network core; any other level is passed to the socket’s protocol handler, mirroring thesetsockopt(2)routing.Parameters
- level
integer
option level (e.g.,
linux.socket.sol.SOCKET). - optname
integer
option name (e.g.,
linux.socket.so.RCVTIMEO_NEW). - value
integer or string
option value: an integer for the common
intpayload, fromINT_MINtoUINT_MAX, since an unsigned option such asSO_MARKreads those 32 bits as au32, or a string carrying the option’s packed binary payload.
Raises
Error if the operation fails;unsupported option levelon a kernel before 6.7, at a level the socket’s protocol has no setsockopt for.Usage
local struct = require("struct") local sk = require("linux.socket") -- bound blocking receives to 500 ms (a
struct __kernel_sock_timeval) local timeval = struct(sk.layout.timeval) sock:setsockopt(sk.sol.SOCKET, sk.so.RCVTIMEO_NEW, timeval:pack(0, 500000)) - level
integer
option level (e.g.,
socket in detail
- new (family, type, protocol[, pid])
-
Creates a new socket object.
This function is the primary way to create a socket.
Parameters
- family
integer
address family (e.g.,
linux.socket.af.INET). - type
integer
socket type (e.g.,
linux.socket.sock.STREAM).linux.socket.sock.PACKETis refused;SOCK_RAWandSOCK_DGRAMreplace it onAF_PACKET. - protocol
integer
protocol (e.g.,
linux.socket.ipproto.TCP). ForAF_PACKETsockets,protocolis an ethertype in host byte order, as bind takes it (e.g.,linux.eth.proto.ALLfor every frame). - pid
integer
a task whose network namespace the socket is created in, instead of the
initial one. The pid is read in the initial pid namespace: the number
task:pid()returns, whichever task makes the call. The socket holds its network namespace until the kernel frees the socket, which for a TCP connection still shutting down comes after its close, so the namespace outlives the task. The rest of Lunatik (linux.ifindex, netfilter) keeps to the initial network namespace. (optional)
Returns
-
socket
A new socket object;
niland"ESRCH"if no task has that pid, or the task has exited.Raises
Error if socket creation fails, “unsupported socket type” forlinux.socket.sock.PACKET, “out of bounds” for an argument past anint, anAF_PACKETprotocol past 16 bits or a pid outside 1 toPID_MAX_LIMIT,EOPNOTSUPPon a kernel whose sockets cannot hold a namespace of their own, or'socket': process-context class in interrupt-context runtimein a softirq or hardirq runtime.See also
Usage
local socket = require("socket") local sk = require("linux.socket") local nl = require("linux.netlink") -- TCP/IPv4 socket local tcp_sock = socket.new(sk.af.INET, sk.sock.STREAM, sk.ipproto.TCP) -- rtnetlink socket in the network namespace of the task 1234 local rtnl = socket.new(sk.af.NETLINK, sk.sock.RAW, nl.proto.ROUTE, 1234)
- family
integer
address family (e.g.,