Support getoption method for tcp objects.
This commit is contained in:
parent
0716cb868e
commit
8bb542baaf
6 changed files with 170 additions and 1 deletions
|
@ -18,8 +18,11 @@
|
|||
\*=========================================================================*/
|
||||
static int opt_setmembership(lua_State *L, p_socket ps, int level, int name);
|
||||
static int opt_setboolean(lua_State *L, p_socket ps, int level, int name);
|
||||
static int opt_getboolean(lua_State *L, p_socket ps, int level, int name);
|
||||
static int opt_set(lua_State *L, p_socket ps, int level, int name,
|
||||
void *val, int len);
|
||||
static int opt_get(lua_State *L, p_socket ps, int level, int name,
|
||||
void *val, int* len);
|
||||
|
||||
/*=========================================================================*\
|
||||
* Exported functions
|
||||
|
@ -40,23 +43,51 @@ int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps)
|
|||
return opt->func(L, ps);
|
||||
}
|
||||
|
||||
int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 2); /* obj, name, ... */
|
||||
while (opt->name && strcmp(name, opt->name))
|
||||
opt++;
|
||||
if (!opt->func) {
|
||||
char msg[45];
|
||||
sprintf(msg, "unsupported option `%.35s'", name);
|
||||
luaL_argerror(L, 2, msg);
|
||||
}
|
||||
return opt->func(L, ps);
|
||||
}
|
||||
|
||||
/* enables reuse of local address */
|
||||
int opt_reuseaddr(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
|
||||
}
|
||||
|
||||
int opt_get_reuseaddr(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
|
||||
}
|
||||
|
||||
/* disables the Naggle algorithm */
|
||||
int opt_tcp_nodelay(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY);
|
||||
}
|
||||
|
||||
int opt_get_tcp_nodelay(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_getboolean(L, ps, IPPROTO_TCP, TCP_NODELAY);
|
||||
}
|
||||
|
||||
int opt_keepalive(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);
|
||||
}
|
||||
|
||||
int opt_get_keepalive(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);
|
||||
}
|
||||
|
||||
int opt_dontroute(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE);
|
||||
|
@ -105,6 +136,21 @@ int opt_ip_drop_membersip(lua_State *L, p_socket ps)
|
|||
return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP);
|
||||
}
|
||||
|
||||
int opt_get_linger(lua_State *L, p_socket ps)
|
||||
{
|
||||
struct linger li; /* obj, name */
|
||||
int len = sizeof(li);
|
||||
int err = opt_get(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, &len);
|
||||
if (err)
|
||||
return err;
|
||||
lua_newtable(L);
|
||||
lua_pushboolean(L, li.l_onoff);
|
||||
lua_setfield(L, -2, "on");
|
||||
lua_pushinteger(L, li.l_linger);
|
||||
lua_setfield(L, -2, "timeout");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
* Auxiliar functions
|
||||
\*=========================================================================*/
|
||||
|
@ -129,6 +175,19 @@ static int opt_setmembership(lua_State *L, p_socket ps, int level, int name)
|
|||
return opt_set(L, ps, level, name, (char *) &val, sizeof(val));
|
||||
}
|
||||
|
||||
static
|
||||
int opt_get(lua_State *L, p_socket ps, int level, int name, void *val, int* len)
|
||||
{
|
||||
socklen_t socklen = *len;
|
||||
if (getsockopt(*ps, level, name, (char *) val, &socklen) < 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "getsockopt failed");
|
||||
return 2;
|
||||
}
|
||||
*len = socklen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len)
|
||||
{
|
||||
|
@ -141,6 +200,17 @@ int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int opt_getboolean(lua_State *L, p_socket ps, int level, int name)
|
||||
{
|
||||
int val = 0;
|
||||
int len = sizeof(val);
|
||||
int err = opt_get(L, ps, level, name, (char *) &val, &len);
|
||||
if (err)
|
||||
return err;
|
||||
lua_pushboolean(L, val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int opt_setboolean(lua_State *L, p_socket ps, int level, int name)
|
||||
{
|
||||
int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */
|
||||
|
|
|
@ -17,10 +17,17 @@
|
|||
typedef struct t_opt {
|
||||
const char *name;
|
||||
int (*func)(lua_State *L, p_socket ps);
|
||||
int (*get)(lua_State *L, p_socket ps);
|
||||
} t_opt;
|
||||
typedef t_opt *p_opt;
|
||||
|
||||
/* supported options */
|
||||
int opt_get_reuseaddr(lua_State *L, p_socket ps);
|
||||
int opt_get_tcp_nodelay(lua_State *L, p_socket ps);
|
||||
int opt_get_keepalive(lua_State *L, p_socket ps);
|
||||
int opt_get_linger(lua_State *L, p_socket ps);
|
||||
int opt_get_reuseaddr(lua_State *L, p_socket ps);
|
||||
|
||||
int opt_dontroute(lua_State *L, p_socket ps);
|
||||
int opt_broadcast(lua_State *L, p_socket ps);
|
||||
int opt_reuseaddr(lua_State *L, p_socket ps);
|
||||
|
@ -35,5 +42,6 @@ int opt_ip_drop_membersip(lua_State *L, p_socket ps);
|
|||
|
||||
/* invokes the appropriate option handler */
|
||||
int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps);
|
||||
int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps);
|
||||
|
||||
#endif
|
||||
|
|
16
src/tcp.c
16
src/tcp.c
|
@ -31,6 +31,7 @@ static int meth_shutdown(lua_State *L);
|
|||
static int meth_receive(lua_State *L);
|
||||
static int meth_accept(lua_State *L);
|
||||
static int meth_close(lua_State *L);
|
||||
static int meth_getoption(lua_State *L);
|
||||
static int meth_setoption(lua_State *L);
|
||||
static int meth_settimeout(lua_State *L);
|
||||
static int meth_getfd(lua_State *L);
|
||||
|
@ -47,6 +48,7 @@ static luaL_reg tcp[] = {
|
|||
{"connect", meth_connect},
|
||||
{"dirty", meth_dirty},
|
||||
{"getfd", meth_getfd},
|
||||
{"getoption", meth_getoption},
|
||||
{"getpeername", meth_getpeername},
|
||||
{"getsockname", meth_getsockname},
|
||||
{"getstats", meth_getstats},
|
||||
|
@ -64,6 +66,14 @@ static luaL_reg tcp[] = {
|
|||
};
|
||||
|
||||
/* socket option handlers */
|
||||
static t_opt optget[] = {
|
||||
{"keepalive", opt_get_keepalive},
|
||||
{"reuseaddr", opt_get_reuseaddr},
|
||||
{"tcp-nodelay", opt_get_tcp_nodelay},
|
||||
{"linger", opt_get_linger},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static t_opt opt[] = {
|
||||
{"keepalive", opt_keepalive},
|
||||
{"reuseaddr", opt_reuseaddr},
|
||||
|
@ -125,6 +135,12 @@ static int meth_setstats(lua_State *L) {
|
|||
/*-------------------------------------------------------------------------*\
|
||||
* Just call option handler
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int meth_getoption(lua_State *L)
|
||||
{
|
||||
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
|
||||
return opt_meth_getoption(L, optget, &tcp->sock);
|
||||
}
|
||||
|
||||
static int meth_setoption(lua_State *L)
|
||||
{
|
||||
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue