diff options
Diffstat (limited to 'src/options.c')
-rw-r--r-- | src/options.c | 100 |
1 files changed, 73 insertions, 27 deletions
diff --git a/src/options.c b/src/options.c index 2085fdc..ab9e621 100644 --- a/src/options.c +++ b/src/options.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Common option interface | 2 | * Common option interface |
3 | * LuaSocket toolkit | 3 | * LuaSocket toolkit |
4 | * | 4 | * |
5 | * RCS ID: $Id$ | 5 | * RCS ID: $Id: options.c,v 1.7 2009/05/27 09:31:35 diego Exp $ |
6 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
7 | #include <string.h> | 7 | #include <string.h> |
8 | 8 | ||
@@ -11,7 +11,7 @@ | |||
11 | #include "auxiliar.h" | 11 | #include "auxiliar.h" |
12 | #include "options.h" | 12 | #include "options.h" |
13 | #include "inet.h" | 13 | #include "inet.h" |
14 | 14 | #include "lua_typeerror.h" | |
15 | 15 | ||
16 | /*=========================================================================*\ | 16 | /*=========================================================================*\ |
17 | * Internal functions prototypes | 17 | * Internal functions prototypes |
@@ -57,7 +57,7 @@ int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps) | |||
57 | } | 57 | } |
58 | 58 | ||
59 | /* enables reuse of local address */ | 59 | /* enables reuse of local address */ |
60 | int opt_reuseaddr(lua_State *L, p_socket ps) | 60 | int opt_set_reuseaddr(lua_State *L, p_socket ps) |
61 | { | 61 | { |
62 | return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); | 62 | return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); |
63 | } | 63 | } |
@@ -67,8 +67,19 @@ int opt_get_reuseaddr(lua_State *L, p_socket ps) | |||
67 | return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); | 67 | return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); |
68 | } | 68 | } |
69 | 69 | ||
70 | /* enables reuse of local port */ | ||
71 | int opt_set_reuseport(lua_State *L, p_socket ps) | ||
72 | { | ||
73 | return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEPORT); | ||
74 | } | ||
75 | |||
76 | int opt_get_reuseport(lua_State *L, p_socket ps) | ||
77 | { | ||
78 | return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEPORT); | ||
79 | } | ||
80 | |||
70 | /* disables the Naggle algorithm */ | 81 | /* disables the Naggle algorithm */ |
71 | int opt_tcp_nodelay(lua_State *L, p_socket ps) | 82 | int opt_set_tcp_nodelay(lua_State *L, p_socket ps) |
72 | { | 83 | { |
73 | return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); | 84 | return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); |
74 | } | 85 | } |
@@ -78,7 +89,7 @@ int opt_get_tcp_nodelay(lua_State *L, p_socket ps) | |||
78 | return opt_getboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); | 89 | return opt_getboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); |
79 | } | 90 | } |
80 | 91 | ||
81 | int opt_keepalive(lua_State *L, p_socket ps) | 92 | int opt_set_keepalive(lua_State *L, p_socket ps) |
82 | { | 93 | { |
83 | return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); | 94 | return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); |
84 | } | 95 | } |
@@ -88,25 +99,30 @@ int opt_get_keepalive(lua_State *L, p_socket ps) | |||
88 | return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); | 99 | return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); |
89 | } | 100 | } |
90 | 101 | ||
91 | int opt_dontroute(lua_State *L, p_socket ps) | 102 | int opt_set_dontroute(lua_State *L, p_socket ps) |
92 | { | 103 | { |
93 | return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); | 104 | return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); |
94 | } | 105 | } |
95 | 106 | ||
96 | int opt_broadcast(lua_State *L, p_socket ps) | 107 | int opt_set_broadcast(lua_State *L, p_socket ps) |
97 | { | 108 | { |
98 | return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); | 109 | return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); |
99 | } | 110 | } |
100 | 111 | ||
101 | int opt_ip_multicast_loop(lua_State *L, p_socket ps) | 112 | int opt_set_ip_multicast_loop(lua_State *L, p_socket ps) |
102 | { | 113 | { |
103 | return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); | 114 | return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); |
104 | } | 115 | } |
105 | 116 | ||
106 | int opt_linger(lua_State *L, p_socket ps) | 117 | int opt_get_ip_multicast_loop(lua_State *L, p_socket ps) |
118 | { | ||
119 | return opt_getboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); | ||
120 | } | ||
121 | |||
122 | int opt_set_linger(lua_State *L, p_socket ps) | ||
107 | { | 123 | { |
108 | struct linger li; /* obj, name, table */ | 124 | struct linger li; /* obj, name, table */ |
109 | if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); | 125 | if (!lua_istable(L, 3)) luaL_typeerror(L, 3, lua_typename(L, LUA_TTABLE)); |
110 | lua_pushstring(L, "on"); | 126 | lua_pushstring(L, "on"); |
111 | lua_gettable(L, 3); | 127 | lua_gettable(L, 3); |
112 | if (!lua_isboolean(L, -1)) | 128 | if (!lua_isboolean(L, -1)) |
@@ -120,22 +136,6 @@ int opt_linger(lua_State *L, p_socket ps) | |||
120 | return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li)); | 136 | return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li)); |
121 | } | 137 | } |
122 | 138 | ||
123 | int opt_ip_multicast_ttl(lua_State *L, p_socket ps) | ||
124 | { | ||
125 | int val = (int) luaL_checknumber(L, 3); /* obj, name, int */ | ||
126 | return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &val, sizeof(val)); | ||
127 | } | ||
128 | |||
129 | int opt_ip_add_membership(lua_State *L, p_socket ps) | ||
130 | { | ||
131 | return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); | ||
132 | } | ||
133 | |||
134 | int opt_ip_drop_membersip(lua_State *L, p_socket ps) | ||
135 | { | ||
136 | return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); | ||
137 | } | ||
138 | |||
139 | int opt_get_linger(lua_State *L, p_socket ps) | 139 | int opt_get_linger(lua_State *L, p_socket ps) |
140 | { | 140 | { |
141 | struct linger li; /* obj, name */ | 141 | struct linger li; /* obj, name */ |
@@ -151,13 +151,59 @@ int opt_get_linger(lua_State *L, p_socket ps) | |||
151 | return 1; | 151 | return 1; |
152 | } | 152 | } |
153 | 153 | ||
154 | int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps) | ||
155 | { | ||
156 | int val = (int) luaL_checknumber(L, 3); /* obj, name, int */ | ||
157 | return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_TTL, | ||
158 | (char *) &val, sizeof(val)); | ||
159 | } | ||
160 | |||
161 | int opt_set_ip_multicast_if(lua_State *L, p_socket ps) | ||
162 | { | ||
163 | const char *address = luaL_checkstring(L, 3); /* obj, name, ip */ | ||
164 | struct in_addr val; | ||
165 | val.s_addr = htonl(INADDR_ANY); | ||
166 | if (strcmp(address, "*") && !inet_aton(address, &val)) | ||
167 | luaL_argerror(L, 3, "ip expected"); | ||
168 | return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_IF, | ||
169 | (char *) &val, sizeof(val)); | ||
170 | } | ||
171 | |||
172 | int opt_get_ip_multicast_if(lua_State *L, p_socket ps) | ||
173 | { | ||
174 | struct in_addr val; | ||
175 | socklen_t len = sizeof(val); | ||
176 | if (getsockopt(*ps, IPPROTO_IP, IP_MULTICAST_IF, (char *) &val, &len) < 0) { | ||
177 | lua_pushnil(L); | ||
178 | lua_pushstring(L, "getsockopt failed"); | ||
179 | return 2; | ||
180 | } | ||
181 | lua_pushstring(L, inet_ntoa(val)); | ||
182 | return 1; | ||
183 | } | ||
184 | |||
185 | int opt_set_ip_add_membership(lua_State *L, p_socket ps) | ||
186 | { | ||
187 | return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); | ||
188 | } | ||
189 | |||
190 | int opt_set_ip_drop_membersip(lua_State *L, p_socket ps) | ||
191 | { | ||
192 | return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); | ||
193 | } | ||
194 | |||
195 | int opt_set_ip6_v6only(lua_State *L, p_socket ps) | ||
196 | { | ||
197 | return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY); | ||
198 | } | ||
199 | |||
154 | /*=========================================================================*\ | 200 | /*=========================================================================*\ |
155 | * Auxiliar functions | 201 | * Auxiliar functions |
156 | \*=========================================================================*/ | 202 | \*=========================================================================*/ |
157 | static int opt_setmembership(lua_State *L, p_socket ps, int level, int name) | 203 | static int opt_setmembership(lua_State *L, p_socket ps, int level, int name) |
158 | { | 204 | { |
159 | struct ip_mreq val; /* obj, name, table */ | 205 | struct ip_mreq val; /* obj, name, table */ |
160 | if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); | 206 | if (!lua_istable(L, 3)) luaL_typeerror(L, 3, lua_typename(L, LUA_TTABLE)); |
161 | lua_pushstring(L, "multiaddr"); | 207 | lua_pushstring(L, "multiaddr"); |
162 | lua_gettable(L, 3); | 208 | lua_gettable(L, 3); |
163 | if (!lua_isstring(L, -1)) | 209 | if (!lua_isstring(L, -1)) |