mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 04:28:20 +01:00
Added support to UDP socket options.
This commit is contained in:
parent
561177a1dd
commit
8c6473577d
@ -159,7 +159,7 @@ static int global_tohostname(lua_State *L);
|
||||
static int global_udpsocket(lua_State *L);
|
||||
|
||||
#ifndef LUASOCKET_NOGLOBALS
|
||||
static int global_calltable(lua_State *L);
|
||||
static int global_callfromtable(lua_State *L);
|
||||
#endif
|
||||
|
||||
/* luasocket table method API functions */
|
||||
@ -219,6 +219,7 @@ static const char *udp_setpeername(p_sock sock, const char *address,
|
||||
unsigned short port);
|
||||
static const char *udp_setsockname(p_sock sock, const char *address,
|
||||
unsigned short port);
|
||||
static int set_option(lua_State *L, p_sock sock);
|
||||
static void set_reuseaddr(p_sock sock);
|
||||
static void set_blocking(p_sock sock);
|
||||
static void set_nonblocking(p_sock sock);
|
||||
@ -305,8 +306,6 @@ static int global_tcpconnect(lua_State *L)
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Creates a udp socket object and returns it to the Lua script.
|
||||
* The timeout values are initialized as -1 so that the socket will block
|
||||
* at any IO operation.
|
||||
* Lua Returns
|
||||
* On success: udp socket
|
||||
* On error: nil, followed by an error message
|
||||
@ -314,8 +313,16 @@ static int global_tcpconnect(lua_State *L)
|
||||
static int global_udpsocket(lua_State *L)
|
||||
{
|
||||
p_tags tags = pop_tags(L);
|
||||
int top = lua_gettop(L);
|
||||
p_sock sock = push_udptable(L, tags);
|
||||
if (!sock) return 2;
|
||||
if (top >= 1 && lua_istable(L, 1)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1)) {
|
||||
if (!set_option(L, sock)) lua_error(L, "invalid socket option");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -542,7 +549,7 @@ static int table_udpsendto(lua_State *L)
|
||||
* Global function that calls corresponding table method.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
#ifndef LUASOCKET_NOGLOBALS
|
||||
int global_calltable(lua_State *L)
|
||||
int global_callfromtable(lua_State *L)
|
||||
{
|
||||
p_tags tags = pop_tags(L);
|
||||
if (lua_tag(L, 1) != tags->table) lua_error(L, "invalid socket object");
|
||||
@ -1049,6 +1056,61 @@ void set_reuseaddr(p_sock sock)
|
||||
setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Set socket options from a table on top of Lua stack.
|
||||
* Supports SO_KEEPALIVE, SO_DONTROUTE, SO_BROADCAST, and SO_LINGER options.
|
||||
* Input
|
||||
* L: Lua state to use
|
||||
* sock: socket to set option
|
||||
* Returns
|
||||
* 1 if successful, 0 otherwise
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int set_option(lua_State *L, p_sock sock)
|
||||
{
|
||||
static const char *const optionnames[] = {
|
||||
"SO_KEEPALIVE", "SO_DONTROUTE", "SO_BROADCAST", "SO_LINGER", NULL
|
||||
};
|
||||
const char *option = lua_tostring(L, -2);
|
||||
int err;
|
||||
switch (luaL_findstring(option, optionnames)) {
|
||||
case 0: {
|
||||
int bool = (int) lua_tonumber(L, -1);
|
||||
err = setsockopt(sock->sock, SOL_SOCKET, SO_KEEPALIVE, &bool,
|
||||
sizeof(bool));
|
||||
return err >= 0;
|
||||
}
|
||||
case 1: {
|
||||
int bool = (int) lua_tonumber(L, -1);
|
||||
err = setsockopt(sock->sock, SOL_SOCKET, SO_DONTROUTE, &bool,
|
||||
sizeof(bool));
|
||||
return err >= 0;
|
||||
}
|
||||
case 2: {
|
||||
int bool = (int) lua_tonumber(L, -1);
|
||||
err = setsockopt(sock->sock, SOL_SOCKET, SO_BROADCAST, &bool,
|
||||
sizeof(bool));
|
||||
return err >= 0;
|
||||
}
|
||||
case 3: {
|
||||
struct linger linger;
|
||||
if (!lua_istable(L, -1)) return 0;
|
||||
lua_pushstring(L, "l_onoff");
|
||||
lua_gettable(L, -2);
|
||||
linger.l_onoff = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_pushstring(L, "l_linger");
|
||||
lua_gettable(L, -2);
|
||||
linger.l_linger = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
err = setsockopt(sock->sock, SOL_SOCKET, SO_LINGER, &linger,
|
||||
sizeof(linger));
|
||||
return err >= 0;
|
||||
}
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Tries to create a TCP socket and bind it to (address, port)
|
||||
* Input
|
||||
@ -1630,7 +1692,7 @@ void lua_socketlibopen(lua_State *L)
|
||||
for (i = 0; i < sizeof(global)/sizeof(char *); i++) {
|
||||
lua_pushstring(L, global[i]);
|
||||
lua_pushuserdata(L, tags);
|
||||
lua_pushcclosure(L, global_calltable, 2);
|
||||
lua_pushcclosure(L, global_callfromtable, 2);
|
||||
lua_setglobal(L, global[i]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user