diff options
Diffstat (limited to 'src/udp.c')
-rw-r--r-- | src/udp.c | 61 |
1 files changed, 54 insertions, 7 deletions
@@ -1,5 +1,6 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * UDP object | 2 | * UDP object |
3 | * LuaSocket toolkit | ||
3 | * | 4 | * |
4 | * RCS ID: $Id$ | 5 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
@@ -13,7 +14,6 @@ | |||
13 | #include "auxiliar.h" | 14 | #include "auxiliar.h" |
14 | #include "socket.h" | 15 | #include "socket.h" |
15 | #include "inet.h" | 16 | #include "inet.h" |
16 | #include "error.h" | ||
17 | #include "udp.h" | 17 | #include "udp.h" |
18 | 18 | ||
19 | /*=========================================================================*\ | 19 | /*=========================================================================*\ |
@@ -29,9 +29,12 @@ static int meth_getpeername(lua_State *L); | |||
29 | static int meth_setsockname(lua_State *L); | 29 | static int meth_setsockname(lua_State *L); |
30 | static int meth_setpeername(lua_State *L); | 30 | static int meth_setpeername(lua_State *L); |
31 | static int meth_close(lua_State *L); | 31 | static int meth_close(lua_State *L); |
32 | static int meth_setoption(lua_State *L); | ||
32 | static int meth_timeout(lua_State *L); | 33 | static int meth_timeout(lua_State *L); |
33 | static int meth_fd(lua_State *L); | 34 | static int meth_fd(lua_State *L); |
34 | static int meth_dirty(lua_State *L); | 35 | static int meth_dirty(lua_State *L); |
36 | static int opt_dontroute(lua_State *L); | ||
37 | static int opt_broadcast(lua_State *L); | ||
35 | 38 | ||
36 | /* udp object methods */ | 39 | /* udp object methods */ |
37 | static luaL_reg udp[] = { | 40 | static luaL_reg udp[] = { |
@@ -45,11 +48,20 @@ static luaL_reg udp[] = { | |||
45 | {"receivefrom", meth_receivefrom}, | 48 | {"receivefrom", meth_receivefrom}, |
46 | {"timeout", meth_timeout}, | 49 | {"timeout", meth_timeout}, |
47 | {"close", meth_close}, | 50 | {"close", meth_close}, |
51 | {"setoption", meth_setoption}, | ||
52 | {"__gc", meth_close}, | ||
48 | {"fd", meth_fd}, | 53 | {"fd", meth_fd}, |
49 | {"dirty", meth_dirty}, | 54 | {"dirty", meth_dirty}, |
50 | {NULL, NULL} | 55 | {NULL, NULL} |
51 | }; | 56 | }; |
52 | 57 | ||
58 | /* socket options */ | ||
59 | static luaL_reg opt[] = { | ||
60 | {"dontroute", opt_dontroute}, | ||
61 | {"broadcast", opt_broadcast}, | ||
62 | {NULL, NULL} | ||
63 | }; | ||
64 | |||
53 | /* functions in library namespace */ | 65 | /* functions in library namespace */ |
54 | static luaL_reg func[] = { | 66 | static luaL_reg func[] = { |
55 | {"udp", global_create}, | 67 | {"udp", global_create}, |
@@ -91,7 +103,9 @@ static int meth_send(lua_State *L) | |||
91 | err = sock_send(&udp->sock, data, count, &sent, tm_get(tm)); | 103 | err = sock_send(&udp->sock, data, count, &sent, tm_get(tm)); |
92 | if (err == IO_DONE) lua_pushnumber(L, sent); | 104 | if (err == IO_DONE) lua_pushnumber(L, sent); |
93 | else lua_pushnil(L); | 105 | else lua_pushnil(L); |
94 | error_push(L, err); | 106 | /* a 'closed' error on an unconnected means the target address was not |
107 | * accepted by the transport layer */ | ||
108 | io_pusherror(L, err == IO_CLOSED ? IO_REFUSED : err); | ||
95 | return 2; | 109 | return 2; |
96 | } | 110 | } |
97 | 111 | ||
@@ -118,7 +132,9 @@ static int meth_sendto(lua_State *L) | |||
118 | (SA *) &addr, sizeof(addr), tm_get(tm)); | 132 | (SA *) &addr, sizeof(addr), tm_get(tm)); |
119 | if (err == IO_DONE) lua_pushnumber(L, sent); | 133 | if (err == IO_DONE) lua_pushnumber(L, sent); |
120 | else lua_pushnil(L); | 134 | else lua_pushnil(L); |
121 | error_push(L, err == IO_CLOSED ? IO_REFUSED : err); | 135 | /* a 'closed' error on an unconnected means the target address was not |
136 | * accepted by the transport layer */ | ||
137 | io_pusherror(L, err == IO_CLOSED ? IO_REFUSED : err); | ||
122 | return 2; | 138 | return 2; |
123 | } | 139 | } |
124 | 140 | ||
@@ -137,7 +153,7 @@ static int meth_receive(lua_State *L) | |||
137 | err = sock_recv(&udp->sock, buffer, count, &got, tm_get(tm)); | 153 | err = sock_recv(&udp->sock, buffer, count, &got, tm_get(tm)); |
138 | if (err == IO_DONE) lua_pushlstring(L, buffer, got); | 154 | if (err == IO_DONE) lua_pushlstring(L, buffer, got); |
139 | else lua_pushnil(L); | 155 | else lua_pushnil(L); |
140 | error_push(L, err); | 156 | io_pusherror(L, err); |
141 | return 2; | 157 | return 2; |
142 | } | 158 | } |
143 | 159 | ||
@@ -164,7 +180,7 @@ static int meth_receivefrom(lua_State *L) | |||
164 | return 3; | 180 | return 3; |
165 | } else { | 181 | } else { |
166 | lua_pushnil(L); | 182 | lua_pushnil(L); |
167 | error_push(L, err); | 183 | io_pusherror(L, err); |
168 | return 2; | 184 | return 2; |
169 | } | 185 | } |
170 | } | 186 | } |
@@ -174,14 +190,14 @@ static int meth_receivefrom(lua_State *L) | |||
174 | \*-------------------------------------------------------------------------*/ | 190 | \*-------------------------------------------------------------------------*/ |
175 | static int meth_fd(lua_State *L) | 191 | static int meth_fd(lua_State *L) |
176 | { | 192 | { |
177 | p_udp udp = (p_udp) aux_checkclass(L, "udp{any}", 1); | 193 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
178 | lua_pushnumber(L, udp->sock); | 194 | lua_pushnumber(L, udp->sock); |
179 | return 1; | 195 | return 1; |
180 | } | 196 | } |
181 | 197 | ||
182 | static int meth_dirty(lua_State *L) | 198 | static int meth_dirty(lua_State *L) |
183 | { | 199 | { |
184 | p_udp udp = (p_udp) aux_checkclass(L, "udp{any}", 1); | 200 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
185 | (void) udp; | 201 | (void) udp; |
186 | lua_pushboolean(L, 0); | 202 | lua_pushboolean(L, 0); |
187 | return 1; | 203 | return 1; |
@@ -203,6 +219,37 @@ static int meth_getsockname(lua_State *L) | |||
203 | } | 219 | } |
204 | 220 | ||
205 | /*-------------------------------------------------------------------------*\ | 221 | /*-------------------------------------------------------------------------*\ |
222 | * Option handlers | ||
223 | \*-------------------------------------------------------------------------*/ | ||
224 | static int meth_setoption(lua_State *L) | ||
225 | { | ||
226 | return aux_meth_setoption(L, opt); | ||
227 | } | ||
228 | |||
229 | static int opt_boolean(lua_State *L, int level, int name) | ||
230 | { | ||
231 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | ||
232 | int val = aux_checkboolean(L, 2); | ||
233 | if (setsockopt(udp->sock, level, name, (char *) &val, sizeof(val)) < 0) { | ||
234 | lua_pushnil(L); | ||
235 | lua_pushstring(L, "setsockopt failed"); | ||
236 | return 2; | ||
237 | } | ||
238 | lua_pushnumber(L, 1); | ||
239 | return 1; | ||
240 | } | ||
241 | |||
242 | static int opt_dontroute(lua_State *L) | ||
243 | { | ||
244 | return opt_boolean(L, SOL_SOCKET, SO_DONTROUTE); | ||
245 | } | ||
246 | |||
247 | static int opt_broadcast(lua_State *L) | ||
248 | { | ||
249 | return opt_boolean(L, SOL_SOCKET, SO_BROADCAST); | ||
250 | } | ||
251 | |||
252 | /*-------------------------------------------------------------------------*\ | ||
206 | * Just call tm methods | 253 | * Just call tm methods |
207 | \*-------------------------------------------------------------------------*/ | 254 | \*-------------------------------------------------------------------------*/ |
208 | static int meth_timeout(lua_State *L) | 255 | static int meth_timeout(lua_State *L) |