Skip to content

Commit 5db772f

Browse files
lnetoclaude
andcommitted
socket: sanitize LDoc and fix C99 declarations
Trim verbose LDoc in module header, send, receive, bind, listen, connect, getsockname, getpeername, close, accept, and new to concise descriptions. Fix C99 issues: remove uninitialized size_t len from send/receive by scoping it inside the else branch and using vec.iov_len directly in the kernel calls; refactor pushaddr to use early returns and eliminate int n; fix double semicolon in checkaddr AF_PACKET branch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1c92b5e commit 5db772f

1 file changed

Lines changed: 40 additions & 130 deletions

File tree

lib/luasocket.c

Lines changed: 40 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,10 @@
55

66
/***
77
* Low-level Lua interface for kernel networking sockets.
8-
* This library provides support for creating and managing various types of
9-
* sockets within the Linux kernel, enabling network communication directly
10-
* from Lua scripts running in kernel space. It is inspired by
11-
* [Chengzhi Tan](https://github.com/tcz717)'s
8+
* Inspired by [Chengzhi Tan](https://github.com/tcz717)'s
129
* [GSoC project](https://summerofcode.withgoogle.com/archive/2018/projects/5993341447569408).
1310
*
14-
* It allows operations such as creating sockets, binding, listening, connecting,
15-
* sending, and receiving data. The library also exposes constants for address
16-
* families, socket types, IP protocols, and message flags.
17-
*
18-
* For higher-level IPv4 TCP/UDP socket operations with string-based IP addresses
19-
* (e.g., "127.0.0.1"), consider using the `socket.inet` library.
11+
* For higher-level IPv4 TCP/UDP socket operations, consider using the `socket.inet` library.
2012
*
2113
* @module socket
2214
* @see socket.inet
@@ -70,7 +62,7 @@ static size_t luasocket_checkaddr(lua_State *L, struct socket *socket, struct so
7062
else if (addr->ss_family == AF_PACKET) {
7163
struct sockaddr_ll *addr_ll = (struct sockaddr_ll *)addr;
7264
addr_ll->sll_protocol = htons((u16)lunatik_checkinteger(L, ix, 0, U16_MAX));
73-
addr_ll->sll_ifindex = (int)lunatik_checkinteger(L, ix + 1, 0, INT_MAX);;
65+
addr_ll->sll_ifindex = (int)lunatik_checkinteger(L, ix + 1, 0, INT_MAX);
7466
return sizeof(struct sockaddr_ll);
7567
}
7668
else {
@@ -84,25 +76,21 @@ static size_t luasocket_checkaddr(lua_State *L, struct socket *socket, struct so
8476

8577
static int luasocket_pushaddr(lua_State *L, struct sockaddr_storage *addr)
8678
{
87-
int n;
8879
if (addr->ss_family == AF_INET) {
8980
struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
9081
lua_pushinteger(L, (lua_Integer)ntohl(addr_in->sin_addr.s_addr));
9182
lua_pushinteger(L, (lua_Integer)ntohs(addr_in->sin_port));
92-
n = 2;
83+
return 2;
9384
}
9485
#ifdef CONFIG_UNIX
9586
else if (LUASOCKET_ISUNIX(addr->ss_family)) {
9687
struct sockaddr_un *addr_un = (struct sockaddr_un *)addr;
9788
lua_pushstring(L, addr_un->sun_path);
98-
n = 1;
89+
return 1;
9990
}
10091
#endif
101-
else {
102-
lua_pushlstring(L, (const char *)addr->__data, LUASOCKET_ADDRMAX);
103-
n = 1;
104-
}
105-
return n;
92+
lua_pushlstring(L, (const char *)addr->__data, LUASOCKET_ADDRMAX);
93+
return 1;
10694
}
10795

10896
LUNATIK_PRIVATECHECKER(luasocket_check, struct socket *);
@@ -112,33 +100,17 @@ LUNATIK_PRIVATECHECKER(luasocket_check, struct socket *);
112100
/***
113101
* Sends a message through the socket.
114102
*
115-
* For connection-oriented sockets (`SOCK_STREAM`), `addr` and `port` are usually omitted
116-
* as the connection is already established.
117-
* For connectionless sockets (`SOCK_DGRAM`), `addr` and `port` (if applicable for the
118-
* address family) specify the destination.
119-
*
120103
* @function send
121104
* @tparam string|data message The message to send; a data object avoids string allocation.
122-
* @tparam[opt] integer|string addr The destination address.
123-
*
124-
* - For `AF_INET` (IPv4) sockets: An integer representing the IPv4 address (e.g., from `net.aton()`).
125-
* - For other address families (e.g., `AF_PACKET`): A packed string representing the destination address
126-
* (e.g., MAC address for `AF_PACKET`). The exact format depends on the family.
127-
* @tparam[opt] integer port The destination port number (required if `addr` is an IPv4 address for `AF_INET`).
105+
* @tparam[opt] integer|string addr Destination address (family-dependent).
106+
* @tparam[opt] integer port Destination port (required for `AF_INET`).
128107
* @treturn integer The number of bytes sent.
129-
* @raise Error if the send operation fails or if address parameters are incorrect for the socket type.
130-
* @usage
131-
* -- For a connected TCP socket:
132-
* local bytes_sent = tcp_conn_sock:send("Hello, server!")
133-
*
134-
* -- For a UDP socket (sending to 192.168.1.100, port 1234):
135-
* local bytes_sent = udp_sock:send("UDP packet", net.aton("192.168.1.100"), 1234)
108+
* @raise Error if the send operation fails.
136109
* @see net.aton
137110
*/
138111
static int luasocket_send(lua_State *L)
139112
{
140113
struct socket *socket = luasocket_check(L, 1);
141-
size_t len;
142114
struct kvec vec;
143115
struct msghdr msg;
144116
struct sockaddr_storage addr;
@@ -151,18 +123,20 @@ static int luasocket_send(lua_State *L)
151123
luadata_t *data = lunatik_checkclass(L, 2, "data", LUNATIK_OPT_SINGLE)->private;
152124
lunatik_argchecknull(L, data->ptr, 2);
153125
vec.iov_base = data->ptr;
154-
len = data->size;
126+
vec.iov_len = data->size;
155127
}
156-
else
128+
else {
129+
size_t len;
157130
vec.iov_base = (void *)luaL_checklstring(L, 2, &len);
158-
vec.iov_len = len;
131+
vec.iov_len = len;
132+
}
159133

160134
if (unlikely(nargs >= 3)) {
161135
size_t size = luasocket_checkaddr(L, socket, &addr, 3);
162136
luasocket_msgaddr(msg, addr, size);
163137
}
164138

165-
lunatik_tryret(L, ret, kernel_sendmsg, socket, &msg, &vec, 1, len);
139+
lunatik_tryret(L, ret, kernel_sendmsg, socket, &msg, &vec, 1, vec.iov_len);
166140
lua_pushinteger(L, ret);
167141
return 1;
168142
}
@@ -185,7 +159,6 @@ static int luasocket_receive(lua_State *L)
185159
{
186160
struct socket *socket = luasocket_check(L, 1);
187161
int isdata = lua_isuserdata(L, 2);
188-
size_t len;
189162
luaL_Buffer B;
190163
struct kvec vec;
191164
struct msghdr msg;
@@ -200,51 +173,31 @@ static int luasocket_receive(lua_State *L)
200173
luadata_t *data = lunatik_checkclass(L, 2, "data", LUNATIK_OPT_SINGLE)->private;
201174
lunatik_argchecknull(L, data->ptr, 2);
202175
vec.iov_base = data->ptr;
203-
len = data->size;
176+
vec.iov_len = data->size;
204177
}
205178
else {
206-
len = (size_t)luaL_checkinteger(L, 2);
179+
size_t len = (size_t)luaL_checkinteger(L, 2);
207180
vec.iov_base = (void *)luaL_buffinitsize(L, &B, len);
181+
vec.iov_len = len;
208182
}
209-
vec.iov_len = len;
210183

211184
if (unlikely(from))
212185
luasocket_msgaddr(msg, addr, sizeof(addr));
213186

214-
lunatik_tryret(L, ret, kernel_recvmsg, socket, &msg, &vec, 1, len, flags);
187+
lunatik_tryret(L, ret, kernel_recvmsg, socket, &msg, &vec, 1, vec.iov_len, flags);
215188
isdata ? lua_pushinteger(L, ret) : luaL_pushresultsize(&B, ret);
216189

217190
return unlikely(from) ? luasocket_pushaddr(L, (struct sockaddr_storage *)msg.msg_name) + 1 : 1;
218191
}
219192

220193
/***
221194
* Binds the socket to a local address.
222-
* This is typically used on the server side before calling `listen()` or on
223-
* connectionless sockets to specify a local port/interface for receiving.
224195
*
225196
* @function bind
226-
* @tparam integer|string addr The local address to bind to. The interpretation depends on `socket.sk.sk_family`:
227-
*
228-
* - `AF_INET` (IPv4): An integer representing the IPv4 address (e.g., from `net.aton()`).
229-
* Use `0` (or `net.aton("0.0.0.0")`) to bind to all available interfaces.
230-
* The `port` argument is also required.
231-
* - `AF_PACKET`: An integer representing the ethernet protocol in host byte order
232-
* (e.g., `0x0003` for `ETH_P_ALL`, `0x88CC` for `ETH_P_LLDP`)
233-
* The `port` argument is also required.
234-
* - Other families: A packed string directly representing parts of the family-specific address structure.
235-
*
236-
* @tparam[opt] integer port The local port or interface index.
237-
* - `AF_INET`: TCP/UDP port number.
238-
* - `AF_PACKET`: Network interface index (e.g., from `linux.ifindex("eth0")`).
239-
*
197+
* @tparam integer|string addr Local address to bind to (family-dependent).
198+
* @tparam[opt] integer port Local port or interface index (family-dependent).
240199
* @treturn nil
241-
* @raise Error if the bind operation fails (e.g., address already in use, invalid address).
242-
* @usage
243-
* -- Bind TCP/IPv4 socket to localhost, port 8080
244-
* tcp_server_sock:bind(net.aton("127.0.0.1"), 8080)
245-
*
246-
* -- Bind AF_PACKET socket to protocol `ETH_P_LLDP` on a specific interface
247-
* af_packet_sock:bind(0x88CC, linux.ifindex("eth0"))
200+
* @raise Error if the bind operation fails.
248201
* @see net.aton
249202
* @see linux.ifindex
250203
*/
@@ -263,16 +216,11 @@ static int luasocket_bind(lua_State *L)
263216

264217
/***
265218
* Puts a connection-oriented socket into the listening state.
266-
* This is required for server sockets (e.g., `SOCK_STREAM`) to be able to
267-
* accept incoming connections.
268219
*
269220
* @function listen
270-
* @tparam[opt] integer backlog The maximum length of the queue for pending connections.
271-
* If omitted, a system-dependent default (e.g., `SOMAXCONN`) is used.
221+
* @tparam[opt] integer backlog Maximum pending connection queue length (default: `SOMAXCONN`).
272222
* @treturn nil
273-
* @raise Error if the listen operation fails (e.g., socket not bound, invalid state).
274-
* @usage
275-
* tcp_server_sock:listen(10)
223+
* @raise Error if the listen operation fails.
276224
*/
277225
static int luasocket_listen(lua_State *L)
278226
{
@@ -285,23 +233,13 @@ static int luasocket_listen(lua_State *L)
285233

286234
/***
287235
* Initiates a connection on a socket.
288-
* This is typically used by client sockets to establish a connection to a server.
289-
* For datagram sockets, this sets the default destination address for `send` and
290-
* the only address from which datagrams are received.
291236
*
292237
* @function connect
293-
* @tparam integer|string addr The destination address to connect to.
294-
* Interpretation depends on `socket.sk.sk_family`:
295-
*
296-
* - `AF_INET` (IPv4): An integer representing the IPv4 address (e.g., from `net.aton()`).
297-
* The `port` argument is also required.
298-
* - Other families: A packed string representing the family-specific destination address.
299-
* @tparam[opt] integer port The destination port number (required and used only if the family is `AF_INET`).
300-
* @tparam[opt=0] integer flags Optional connection flags.
238+
* @tparam integer|string addr Destination address (family-dependent).
239+
* @tparam[opt] integer port Destination port (required for `AF_INET`).
240+
* @tparam[opt=0] integer flags Connection flags.
301241
* @treturn nil
302-
* @raise Error if the connect operation fails (e.g., connection refused, host unreachable).
303-
* @usage
304-
* tcp_client_sock:connect(net.aton("192.168.1.100"), 80)
242+
* @raise Error if the connect operation fails.
305243
*/
306244
static int luasocket_connect(lua_State *L)
307245
{
@@ -332,43 +270,25 @@ static int luasocket_get##what(lua_State *L) \
332270
* Gets the local address to which the socket is bound.
333271
*
334272
* @function getsockname
335-
* @treturn integer|string addr The local address.
336-
*
337-
* - For `AF_INET`: An integer representing the IPv4 address (can be converted with `net.ntoa()`).
338-
* - For other families: A packed string representing the local address.
339-
* @treturn[opt] integer port If the family is `AF_INET`, the local port number.
273+
* @treturn integer|string addr Local address (family-dependent).
274+
* @treturn[opt] integer port Local port for `AF_INET`.
340275
* @raise Error if the operation fails.
341-
* @usage
342-
* local local_ip_int, local_port = my_socket:getsockname()
343-
* if my_socket.sk.sk_family == socket.af.INET then print("Bound to " .. net.ntoa(local_ip_int) .. ":" .. local_port) end
344276
*/
345277
LUASOCKET_NEWGETTER(sockname);
346278

347279
/***
348280
* Gets the address of the peer to which the socket is connected.
349-
* This is typically used with connection-oriented sockets after a connection
350-
* has been established, or with connectionless sockets after `connect()` has
351-
* been called to set a default peer.
352281
*
353282
* @function getpeername
354-
* @treturn integer|string addr The peer's address.
355-
*
356-
* - For `AF_INET`: An integer representing the IPv4 address (can be converted with `net.ntoa()`).
357-
* - For other families: A packed string representing the peer's address.
358-
* @treturn[opt] integer port If the family is `AF_INET`, the peer's port number.
359-
* @raise Error if the operation fails (e.g., socket not connected).
360-
* @usage
361-
* local peer_ip_int, peer_port = connected_socket:getpeername()
362-
* if connected_socket.sk.sk_family == socket.af.INET then print("Connected to " .. net.ntoa(peer_ip_int) .. ":" .. peer_port) end
283+
* @treturn integer|string addr Peer address (family-dependent).
284+
* @treturn[opt] integer port Peer port for `AF_INET`.
285+
* @raise Error if the operation fails.
363286
*/
364287
LUASOCKET_NEWGETTER(peername);
365288

366289
/***
367-
* Closes the socket.
368-
* This shuts down the socket for both reading and writing and releases
369-
* associated kernel resources.
370-
* This method is also called automatically when the socket object is garbage collected
371-
* or via Lua 5.4's to-be-closed mechanism.
290+
* Closes the socket, shutting it down and releasing kernel resources.
291+
* Also called on garbage collection or via Lua 5.4's to-be-closed mechanism.
372292
*
373293
* @function close
374294
* @treturn nil
@@ -704,13 +624,9 @@ static const lunatik_class_t luasocket_class = {
704624

705625
/***
706626
* Accepts a connection on a listening socket.
707-
* This function is used with connection-oriented sockets (e.g., `SOCK_STREAM`)
708-
* that have been put into the listening state by `sock:listen()`.
709627
*
710628
* @function accept
711-
* @tparam socket self The listening socket object.
712-
* @tparam[opt=0] integer flags Optional flags to apply to the newly accepted socket
713-
* (e.g., `socket.sock.NONBLOCK`, `socket.sock.CLOEXEC`).
629+
* @tparam[opt=0] integer flags Flags for the new socket (e.g., `socket.sock.NONBLOCK`).
714630
* @treturn socket A new socket object representing the accepted connection.
715631
* @raise Error if the accept operation fails.
716632
*/
@@ -726,19 +642,13 @@ static int luasocket_accept(lua_State *L)
726642

727643
/***
728644
* Creates a new socket object.
729-
* This function is the primary way to create a socket.
730645
*
731646
* @function new
732-
* @tparam integer family The address family for the socket (e.g., `socket.af.INET`).
733-
* @tparam integer type The type of the socket (e.g., `socket.sock.STREAM`).
734-
* @tparam integer protocol The protocol to be used (e.g., `socket.ipproto.TCP`).
735-
* For `AF_PACKET` sockets, `protocol` is typically an `ETH_P_*` value in network byte order
736-
* (e.g., `linux.hton16(0x0003)` for `ETH_P_ALL`).
647+
* @tparam integer family Address family (e.g., `socket.af.INET`).
648+
* @tparam integer type Socket type (e.g., `socket.sock.STREAM`).
649+
* @tparam integer protocol Protocol (e.g., `socket.ipproto.TCP`).
737650
* @treturn socket A new socket object.
738651
* @raise Error if socket creation fails.
739-
* @usage
740-
* -- TCP/IPv4 socket
741-
* local tcp_sock = socket.new(socket.af.INET, socket.sock.STREAM, socket.ipproto.TCP)
742652
* @see socket.af
743653
* @see socket.sock
744654
* @see socket.ipproto

0 commit comments

Comments
 (0)