diff options
Diffstat (limited to 'src/udp.c')
-rw-r--r-- | src/udp.c | 75 |
1 files changed, 73 insertions, 2 deletions
@@ -35,6 +35,11 @@ static int meth_fd(lua_State *L); | |||
35 | static int meth_dirty(lua_State *L); | 35 | static int meth_dirty(lua_State *L); |
36 | static int opt_dontroute(lua_State *L); | 36 | static int opt_dontroute(lua_State *L); |
37 | static int opt_broadcast(lua_State *L); | 37 | static int opt_broadcast(lua_State *L); |
38 | static int opt_reuseaddr(lua_State *L); | ||
39 | static int opt_ip_multicast_ttl(lua_State *L); | ||
40 | static int opt_ip_multicast_loop(lua_State *L); | ||
41 | static int opt_ip_add_membership(lua_State *L); | ||
42 | static int opt_ip_drop_membersip(lua_State *L); | ||
38 | 43 | ||
39 | /* udp object methods */ | 44 | /* udp object methods */ |
40 | static luaL_reg udp[] = { | 45 | static luaL_reg udp[] = { |
@@ -57,8 +62,13 @@ static luaL_reg udp[] = { | |||
57 | 62 | ||
58 | /* socket options */ | 63 | /* socket options */ |
59 | static luaL_reg opt[] = { | 64 | static luaL_reg opt[] = { |
60 | {"dontroute", opt_dontroute}, | 65 | {"dontroute", opt_dontroute}, |
61 | {"broadcast", opt_broadcast}, | 66 | {"broadcast", opt_broadcast}, |
67 | {"reuseaddr", opt_reuseaddr}, | ||
68 | {"ip-multicast-ttl", opt_ip_multicast_ttl}, | ||
69 | {"ip-multicast-loop", opt_ip_multicast_loop}, | ||
70 | {"ip-add-membership", opt_ip_add_membership}, | ||
71 | {"ip-drop-membership", opt_ip_drop_membersip}, | ||
62 | {NULL, NULL} | 72 | {NULL, NULL} |
63 | }; | 73 | }; |
64 | 74 | ||
@@ -244,11 +254,72 @@ static int opt_dontroute(lua_State *L) | |||
244 | return opt_boolean(L, SOL_SOCKET, SO_DONTROUTE); | 254 | return opt_boolean(L, SOL_SOCKET, SO_DONTROUTE); |
245 | } | 255 | } |
246 | 256 | ||
257 | static int opt_reuseaddr(lua_State *L) | ||
258 | { | ||
259 | return opt_boolean(L, SOL_SOCKET, SO_REUSEADDR); | ||
260 | } | ||
261 | |||
247 | static int opt_broadcast(lua_State *L) | 262 | static int opt_broadcast(lua_State *L) |
248 | { | 263 | { |
249 | return opt_boolean(L, SOL_SOCKET, SO_BROADCAST); | 264 | return opt_boolean(L, SOL_SOCKET, SO_BROADCAST); |
250 | } | 265 | } |
251 | 266 | ||
267 | static int opt_ip_multicast_loop(lua_State *L) | ||
268 | { | ||
269 | return opt_boolean(L, IPPROTO_IP, IP_MULTICAST_LOOP); | ||
270 | } | ||
271 | |||
272 | static int opt_ip_multicast_ttl(lua_State *L) | ||
273 | { | ||
274 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | ||
275 | int val = (int) luaL_checknumber(L, 2); | ||
276 | if (setsockopt(udp->sock, IPPROTO_IP, IP_MULTICAST_TTL, | ||
277 | (char *) &val, sizeof(val)) < 0) { | ||
278 | lua_pushnil(L); | ||
279 | lua_pushstring(L, "setsockopt failed"); | ||
280 | return 2; | ||
281 | } | ||
282 | lua_pushnumber(L, 1); | ||
283 | return 1; | ||
284 | } | ||
285 | |||
286 | static int opt_membership(lua_State *L, int level, int name) | ||
287 | { | ||
288 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | ||
289 | struct ip_mreq val; | ||
290 | if (!lua_istable(L, 2)) | ||
291 | luaL_typerror(L, 2, lua_typename(L, LUA_TTABLE)); | ||
292 | lua_pushstring(L, "multiaddr"); | ||
293 | lua_gettable(L, 2); | ||
294 | if (!lua_isstring(L, -1)) luaL_argerror(L, 2, "invalid 'group' field"); | ||
295 | if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr)) | ||
296 | luaL_argerror(L, 3, "invalid 'multiaddr' ip address"); | ||
297 | lua_pushstring(L, "interface"); | ||
298 | lua_gettable(L, 2); | ||
299 | if (!lua_isstring(L, -1)) luaL_argerror(L, 2, "invalid 'interface' field"); | ||
300 | val.imr_interface.s_addr = htonl(INADDR_ANY); | ||
301 | if (strcmp(lua_tostring(L, -1), "*") && | ||
302 | !inet_aton(lua_tostring(L, -1), &val.imr_interface)) | ||
303 | luaL_argerror(L, 3, "invalid 'interface' ip address"); | ||
304 | if (setsockopt(udp->sock, level, name, (char *) &val, sizeof(val)) < 0) { | ||
305 | lua_pushnil(L); | ||
306 | lua_pushstring(L, "setsockopt failed"); | ||
307 | return 2; | ||
308 | } | ||
309 | lua_pushnumber(L, 1); | ||
310 | return 1; | ||
311 | } | ||
312 | |||
313 | static int opt_ip_add_membership(lua_State *L) | ||
314 | { | ||
315 | return opt_membership(L, IPPROTO_IP, IP_ADD_MEMBERSHIP); | ||
316 | } | ||
317 | |||
318 | static int opt_ip_drop_membersip(lua_State *L) | ||
319 | { | ||
320 | return opt_membership(L, IPPROTO_IP, IP_DROP_MEMBERSHIP); | ||
321 | } | ||
322 | |||
252 | /*-------------------------------------------------------------------------*\ | 323 | /*-------------------------------------------------------------------------*\ |
253 | * Just call tm methods | 324 | * Just call tm methods |
254 | \*-------------------------------------------------------------------------*/ | 325 | \*-------------------------------------------------------------------------*/ |