Mercurial > luasocket
comparison src/options.c @ 0:4b915342e2a8
LuaSocket 2.0.2 + CMake build description.
author | Eric Wing <ewing . public |-at-| gmail . com> |
---|---|
date | Tue, 26 Aug 2008 18:40:01 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4b915342e2a8 |
---|---|
1 /*=========================================================================*\ | |
2 * Common option interface | |
3 * LuaSocket toolkit | |
4 * | |
5 * RCS ID: $Id: options.c,v 1.6 2005/11/20 07:20:23 diego Exp $ | |
6 \*=========================================================================*/ | |
7 #include <string.h> | |
8 | |
9 #include "lauxlib.h" | |
10 | |
11 #include "auxiliar.h" | |
12 #include "options.h" | |
13 #include "inet.h" | |
14 | |
15 | |
16 /*=========================================================================*\ | |
17 * Internal functions prototypes | |
18 \*=========================================================================*/ | |
19 static int opt_setmembership(lua_State *L, p_socket ps, int level, int name); | |
20 static int opt_setboolean(lua_State *L, p_socket ps, int level, int name); | |
21 static int opt_set(lua_State *L, p_socket ps, int level, int name, | |
22 void *val, int len); | |
23 | |
24 /*=========================================================================*\ | |
25 * Exported functions | |
26 \*=========================================================================*/ | |
27 /*-------------------------------------------------------------------------*\ | |
28 * Calls appropriate option handler | |
29 \*-------------------------------------------------------------------------*/ | |
30 int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps) | |
31 { | |
32 const char *name = luaL_checkstring(L, 2); /* obj, name, ... */ | |
33 while (opt->name && strcmp(name, opt->name)) | |
34 opt++; | |
35 if (!opt->func) { | |
36 char msg[45]; | |
37 sprintf(msg, "unsupported option `%.35s'", name); | |
38 luaL_argerror(L, 2, msg); | |
39 } | |
40 return opt->func(L, ps); | |
41 } | |
42 | |
43 /* enables reuse of local address */ | |
44 int opt_reuseaddr(lua_State *L, p_socket ps) | |
45 { | |
46 return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); | |
47 } | |
48 | |
49 /* disables the Naggle algorithm */ | |
50 int opt_tcp_nodelay(lua_State *L, p_socket ps) | |
51 { | |
52 return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); | |
53 } | |
54 | |
55 int opt_keepalive(lua_State *L, p_socket ps) | |
56 { | |
57 return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); | |
58 } | |
59 | |
60 int opt_dontroute(lua_State *L, p_socket ps) | |
61 { | |
62 return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); | |
63 } | |
64 | |
65 int opt_broadcast(lua_State *L, p_socket ps) | |
66 { | |
67 return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); | |
68 } | |
69 | |
70 int opt_ip_multicast_loop(lua_State *L, p_socket ps) | |
71 { | |
72 return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); | |
73 } | |
74 | |
75 int opt_linger(lua_State *L, p_socket ps) | |
76 { | |
77 struct linger li; /* obj, name, table */ | |
78 if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); | |
79 lua_pushstring(L, "on"); | |
80 lua_gettable(L, 3); | |
81 if (!lua_isboolean(L, -1)) | |
82 luaL_argerror(L, 3, "boolean 'on' field expected"); | |
83 li.l_onoff = (u_short) lua_toboolean(L, -1); | |
84 lua_pushstring(L, "timeout"); | |
85 lua_gettable(L, 3); | |
86 if (!lua_isnumber(L, -1)) | |
87 luaL_argerror(L, 3, "number 'timeout' field expected"); | |
88 li.l_linger = (u_short) lua_tonumber(L, -1); | |
89 return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li)); | |
90 } | |
91 | |
92 int opt_ip_multicast_ttl(lua_State *L, p_socket ps) | |
93 { | |
94 int val = (int) luaL_checknumber(L, 3); /* obj, name, int */ | |
95 return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &val, sizeof(val)); | |
96 } | |
97 | |
98 int opt_ip_add_membership(lua_State *L, p_socket ps) | |
99 { | |
100 return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); | |
101 } | |
102 | |
103 int opt_ip_drop_membersip(lua_State *L, p_socket ps) | |
104 { | |
105 return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); | |
106 } | |
107 | |
108 /*=========================================================================*\ | |
109 * Auxiliar functions | |
110 \*=========================================================================*/ | |
111 static int opt_setmembership(lua_State *L, p_socket ps, int level, int name) | |
112 { | |
113 struct ip_mreq val; /* obj, name, table */ | |
114 if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); | |
115 lua_pushstring(L, "multiaddr"); | |
116 lua_gettable(L, 3); | |
117 if (!lua_isstring(L, -1)) | |
118 luaL_argerror(L, 3, "string 'multiaddr' field expected"); | |
119 if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr)) | |
120 luaL_argerror(L, 3, "invalid 'multiaddr' ip address"); | |
121 lua_pushstring(L, "interface"); | |
122 lua_gettable(L, 3); | |
123 if (!lua_isstring(L, -1)) | |
124 luaL_argerror(L, 3, "string 'interface' field expected"); | |
125 val.imr_interface.s_addr = htonl(INADDR_ANY); | |
126 if (strcmp(lua_tostring(L, -1), "*") && | |
127 !inet_aton(lua_tostring(L, -1), &val.imr_interface)) | |
128 luaL_argerror(L, 3, "invalid 'interface' ip address"); | |
129 return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); | |
130 } | |
131 | |
132 static | |
133 int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len) | |
134 { | |
135 if (setsockopt(*ps, level, name, (char *) val, len) < 0) { | |
136 lua_pushnil(L); | |
137 lua_pushstring(L, "setsockopt failed"); | |
138 return 2; | |
139 } | |
140 lua_pushnumber(L, 1); | |
141 return 1; | |
142 } | |
143 | |
144 static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) | |
145 { | |
146 int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ | |
147 return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); | |
148 } | |
149 |