diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-05-25 01:54:13 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-05-25 01:54:13 +0000 |
commit | 0f6c8d50a99997ac7829864b1c93362b50f1bbf3 (patch) | |
tree | d0cefe3a05484e65b7b7e79d8cae4a1d2e6d19fb /src/udp.c | |
parent | c1ef3e7103cc652d2004ef1ddc9409b946207f33 (diff) | |
download | luasocket-0f6c8d50a99997ac7829864b1c93362b50f1bbf3.tar.gz luasocket-0f6c8d50a99997ac7829864b1c93362b50f1bbf3.tar.bz2 luasocket-0f6c8d50a99997ac7829864b1c93362b50f1bbf3.zip |
Porting to LUA 5.0 final
Diffstat (limited to 'src/udp.c')
-rw-r--r-- | src/udp.c | 404 |
1 files changed, 184 insertions, 220 deletions
@@ -1,299 +1,263 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * UDP class: inherits from Socked and Internet domain classes and provides | 2 | * UDP object |
3 | * all the functionality for UDP objects. | ||
4 | * Lua methods: | ||
5 | * send: using compat module | ||
6 | * sendto: using compat module | ||
7 | * receive: using compat module | ||
8 | * receivefrom: using compat module | ||
9 | * setpeername: using internet module | ||
10 | * setsockname: using internet module | ||
11 | * Global Lua functions: | ||
12 | * udp: creates the udp object | ||
13 | * | 3 | * |
14 | * RCS ID: $Id$ | 4 | * RCS ID: $Id$ |
15 | \*=========================================================================*/ | 5 | \*=========================================================================*/ |
16 | #include <string.h> | 6 | #include <string.h> |
17 | 7 | ||
18 | #include <lua.h> | 8 | #include <lua.h> |
19 | #include <lauxlib.h> | 9 | #include <lauxlib.h> |
20 | 10 | ||
21 | #include "lsinet.h" | 11 | #include "luasocket.h" |
22 | #include "lsudp.h" | 12 | |
23 | #include "lscompat.h" | 13 | #include "aux.h" |
24 | #include "lsselect.h" | 14 | #include "inet.h" |
15 | #include "udp.h" | ||
25 | 16 | ||
26 | /*=========================================================================*\ | 17 | /*=========================================================================*\ |
27 | * Internal function prototypes. | 18 | * Internal function prototypes |
28 | \*=========================================================================*/ | 19 | \*=========================================================================*/ |
29 | static int udp_lua_send(lua_State *L); | 20 | static int udp_global_create(lua_State *L); |
30 | static int udp_lua_sendto(lua_State *L); | 21 | static int udp_meth_send(lua_State *L); |
31 | static int udp_lua_receive(lua_State *L); | 22 | static int udp_meth_sendto(lua_State *L); |
32 | static int udp_lua_receivefrom(lua_State *L); | 23 | static int udp_meth_receive(lua_State *L); |
33 | static int udp_lua_setpeername(lua_State *L); | 24 | static int udp_meth_receivefrom(lua_State *L); |
34 | static int udp_lua_setsockname(lua_State *L); | 25 | static int udp_meth_getsockname(lua_State *L); |
26 | static int udp_meth_getpeername(lua_State *L); | ||
27 | static int udp_meth_setsockname(lua_State *L); | ||
28 | static int udp_meth_setpeername(lua_State *L); | ||
29 | static int udp_meth_close(lua_State *L); | ||
30 | static int udp_meth_timeout(lua_State *L); | ||
35 | 31 | ||
36 | static int udp_global_udp(lua_State *L); | 32 | /* udp object methods */ |
33 | static luaL_reg udp[] = { | ||
34 | {"setpeername", udp_meth_setpeername}, | ||
35 | {"setsockname", udp_meth_setsockname}, | ||
36 | {"getsockname", udp_meth_getsockname}, | ||
37 | {"getpeername", udp_meth_getpeername}, | ||
38 | {"send", udp_meth_send}, | ||
39 | {"sendto", udp_meth_sendto}, | ||
40 | {"receive", udp_meth_receive}, | ||
41 | {"receivefrom", udp_meth_receivefrom}, | ||
42 | {"timeout", udp_meth_timeout}, | ||
43 | {"close", udp_meth_close}, | ||
44 | {NULL, NULL} | ||
45 | }; | ||
37 | 46 | ||
38 | static struct luaL_reg funcs[] = { | 47 | /* functions in library namespace */ |
39 | {"send", udp_lua_send}, | 48 | static luaL_reg func[] = { |
40 | {"sendto", udp_lua_sendto}, | 49 | {"udp", udp_global_create}, |
41 | {"receive", udp_lua_receive}, | 50 | {NULL, NULL} |
42 | {"receivefrom", udp_lua_receivefrom}, | ||
43 | {"setpeername", udp_lua_setpeername}, | ||
44 | {"setsockname", udp_lua_setsockname}, | ||
45 | }; | 51 | }; |
46 | 52 | ||
47 | /*=========================================================================*\ | ||
48 | * Exported functions | ||
49 | \*=========================================================================*/ | ||
50 | /*-------------------------------------------------------------------------*\ | 53 | /*-------------------------------------------------------------------------*\ |
51 | * Initializes module | 54 | * Initializes module |
52 | \*-------------------------------------------------------------------------*/ | 55 | \*-------------------------------------------------------------------------*/ |
53 | void udp_open(lua_State *L) | 56 | void udp_open(lua_State *L) |
54 | { | 57 | { |
55 | unsigned int i; | 58 | /* create classes */ |
56 | priv_newclass(L, UDP_CLASS); | 59 | aux_newclass(L, "udp{connected}", udp); |
57 | udp_inherit(L, UDP_CLASS); | 60 | aux_newclass(L, "udp{unconnected}", udp); |
58 | /* declare global functions */ | 61 | /* create class groups */ |
59 | lua_pushcfunction(L, udp_global_udp); | 62 | aux_add2group(L, "udp{connected}", "udp{any}"); |
60 | priv_newglobal(L, "udp"); | 63 | aux_add2group(L, "udp{unconnected}", "udp{any}"); |
61 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) | 64 | /* define library functions */ |
62 | priv_newglobalmethod(L, funcs[i].name); | 65 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
63 | /* make class selectable */ | 66 | lua_pop(L, 1); |
64 | select_addclass(L, UDP_CLASS); | ||
65 | } | ||
66 | |||
67 | /*-------------------------------------------------------------------------*\ | ||
68 | * Hook object methods to methods table. | ||
69 | \*-------------------------------------------------------------------------*/ | ||
70 | void udp_inherit(lua_State *L, cchar *lsclass) | ||
71 | { | ||
72 | unsigned int i; | ||
73 | inet_inherit(L, lsclass); | ||
74 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { | ||
75 | lua_pushcfunction(L, funcs[i].func); | ||
76 | priv_setmethod(L, lsclass, funcs[i].name); | ||
77 | } | ||
78 | } | 67 | } |
79 | 68 | ||
69 | /*=========================================================================*\ | ||
70 | * Lua methods | ||
71 | \*=========================================================================*/ | ||
80 | /*-------------------------------------------------------------------------*\ | 72 | /*-------------------------------------------------------------------------*\ |
81 | * Initializes socket structure | 73 | * Send data through connected udp socket |
82 | \*-------------------------------------------------------------------------*/ | 74 | \*-------------------------------------------------------------------------*/ |
83 | void udp_construct(lua_State *L, p_udp udp) | 75 | static int udp_meth_send(lua_State *L) |
84 | { | 76 | { |
85 | inet_construct(L, (p_inet) udp); | 77 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); |
86 | udp->udp_connected = 0; | 78 | p_tm tm = &udp->tm; |
79 | size_t count, sent = 0; | ||
80 | int err; | ||
81 | const char *data = luaL_checklstring(L, 2, &count); | ||
82 | tm_markstart(tm); | ||
83 | err = sock_send(&udp->sock, data, count, &sent, tm_get(tm)); | ||
84 | if (err == IO_DONE) lua_pushnumber(L, sent); | ||
85 | else lua_pushnil(L); | ||
86 | error_push(L, err); | ||
87 | return 2; | ||
87 | } | 88 | } |
88 | 89 | ||
89 | /*-------------------------------------------------------------------------*\ | 90 | /*-------------------------------------------------------------------------*\ |
90 | * Creates a socket structure and initializes it. A socket object is | 91 | * Send data through unconnected udp socket |
91 | * left in the Lua stack. | ||
92 | * Returns | ||
93 | * pointer to allocated structure | ||
94 | \*-------------------------------------------------------------------------*/ | 92 | \*-------------------------------------------------------------------------*/ |
95 | p_udp udp_push(lua_State *L) | 93 | static int udp_meth_sendto(lua_State *L) |
96 | { | 94 | { |
97 | p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); | 95 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
98 | priv_setclass(L, UDP_CLASS); | 96 | size_t count, sent = 0; |
99 | udp_construct(L, udp); | 97 | const char *data = luaL_checklstring(L, 2, &count); |
100 | return udp; | 98 | const char *ip = luaL_checkstring(L, 3); |
99 | ushort port = (ushort) luaL_checknumber(L, 4); | ||
100 | p_tm tm = &udp->tm; | ||
101 | struct sockaddr_in addr; | ||
102 | int err; | ||
103 | memset(&addr, 0, sizeof(addr)); | ||
104 | if (!inet_aton(ip, &addr.sin_addr)) | ||
105 | luaL_argerror(L, 3, "invalid ip address"); | ||
106 | addr.sin_family = AF_INET; | ||
107 | addr.sin_port = htons(port); | ||
108 | tm_markstart(tm); | ||
109 | err = sock_sendto(&udp->sock, data, count, &sent, | ||
110 | (SA *) &addr, sizeof(addr), tm_get(tm)); | ||
111 | if (err == IO_DONE) lua_pushnumber(L, sent); | ||
112 | else lua_pushnil(L); | ||
113 | error_push(L, err == IO_CLOSED ? IO_REFUSED : err); | ||
114 | return 2; | ||
101 | } | 115 | } |
102 | 116 | ||
103 | /*=========================================================================*\ | ||
104 | * Socket table constructors | ||
105 | \*=========================================================================*/ | ||
106 | /*-------------------------------------------------------------------------*\ | ||
107 | * Creates a udp socket object and returns it to the Lua script. | ||
108 | * Lua Input: [options] | ||
109 | * options: socket options table | ||
110 | * Lua Returns | ||
111 | * On success: udp socket | ||
112 | * On error: nil, followed by an error message | ||
113 | \*-------------------------------------------------------------------------*/ | ||
114 | static int udp_global_udp(lua_State *L) | ||
115 | { | ||
116 | int oldtop = lua_gettop(L); | ||
117 | p_udp udp = udp_push(L); | ||
118 | cchar *err = inet_trysocket((p_inet) udp, SOCK_DGRAM); | ||
119 | if (err) { | ||
120 | lua_pushnil(L); | ||
121 | lua_pushstring(L, err); | ||
122 | return 2; | ||
123 | } | ||
124 | if (oldtop < 1) return 1; | ||
125 | err = compat_trysetoptions(L, udp->fd); | ||
126 | if (err) { | ||
127 | lua_pushnil(L); | ||
128 | lua_pushstring(L, err); | ||
129 | return 2; | ||
130 | } | ||
131 | return 1; | ||
132 | } | ||
133 | |||
134 | /*=========================================================================*\ | ||
135 | * Socket table methods | ||
136 | \*=========================================================================*/ | ||
137 | /*-------------------------------------------------------------------------*\ | 117 | /*-------------------------------------------------------------------------*\ |
138 | * Receives data from a UDP socket | 118 | * Receives data from a UDP socket |
139 | * Lua Input: sock [, wanted] | ||
140 | * sock: client socket created by the connect function | ||
141 | * wanted: the number of bytes expected (default: LUASOCKET_UDPBUFFERSIZE) | ||
142 | * Lua Returns | ||
143 | * On success: datagram received | ||
144 | * On error: nil, followed by an error message | ||
145 | \*-------------------------------------------------------------------------*/ | 119 | \*-------------------------------------------------------------------------*/ |
146 | static int udp_lua_receive(lua_State *L) | 120 | static int udp_meth_receive(lua_State *L) |
147 | { | 121 | { |
148 | p_udp udp = (p_udp) lua_touserdata(L, 1); | 122 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
149 | char buffer[UDP_DATAGRAMSIZE]; | 123 | char buffer[UDP_DATAGRAMSIZE]; |
150 | size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); | 124 | size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); |
151 | int err; | 125 | int err; |
152 | p_tm tm = &udp->base_tm; | 126 | p_tm tm = &udp->tm; |
153 | wanted = MIN(wanted, sizeof(buffer)); | 127 | count = MIN(count, sizeof(buffer)); |
154 | tm_markstart(tm); | 128 | tm_markstart(tm); |
155 | err = compat_recv(udp->fd, buffer, wanted, &got, tm_getremaining(tm)); | 129 | err = sock_recv(&udp->sock, buffer, count, &got, tm_get(tm)); |
156 | if (err == PRIV_CLOSED) err = PRIV_REFUSED; | 130 | if (err == IO_DONE) lua_pushlstring(L, buffer, got); |
157 | if (err != PRIV_DONE) lua_pushnil(L); | 131 | else lua_pushnil(L); |
158 | else lua_pushlstring(L, buffer, got); | 132 | error_push(L, err); |
159 | priv_pusherror(L, err); | ||
160 | return 2; | 133 | return 2; |
161 | } | 134 | } |
162 | 135 | ||
163 | /*-------------------------------------------------------------------------*\ | 136 | /*-------------------------------------------------------------------------*\ |
164 | * Receives a datagram from a UDP socket | 137 | * Receives data and sender from a UDP socket |
165 | * Lua Input: sock [, wanted] | ||
166 | * sock: client socket created by the connect function | ||
167 | * wanted: the number of bytes expected (default: LUASOCKET_UDPBUFFERSIZE) | ||
168 | * Lua Returns | ||
169 | * On success: datagram received, ip and port of sender | ||
170 | * On error: nil, followed by an error message | ||
171 | \*-------------------------------------------------------------------------*/ | 138 | \*-------------------------------------------------------------------------*/ |
172 | static int udp_lua_receivefrom(lua_State *L) | 139 | static int udp_meth_receivefrom(lua_State *L) |
173 | { | 140 | { |
174 | p_udp udp = (p_udp) lua_touserdata(L, 1); | 141 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
175 | p_tm tm = &udp->base_tm; | 142 | struct sockaddr_in addr; |
176 | struct sockaddr_in peer; | 143 | size_t addr_len = sizeof(addr); |
177 | size_t peer_len = sizeof(peer); | ||
178 | char buffer[UDP_DATAGRAMSIZE]; | 144 | char buffer[UDP_DATAGRAMSIZE]; |
179 | size_t wanted = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); | 145 | size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); |
180 | size_t got; | ||
181 | int err; | 146 | int err; |
182 | if (udp->udp_connected) luaL_error(L, "receivefrom on connected socket"); | 147 | p_tm tm = &udp->tm; |
183 | tm_markstart(tm); | 148 | tm_markstart(tm); |
184 | wanted = MIN(wanted, sizeof(buffer)); | 149 | count = MIN(count, sizeof(buffer)); |
185 | err = compat_recvfrom(udp->fd, buffer, wanted, &got, tm_getremaining(tm), | 150 | err = sock_recvfrom(&udp->sock, buffer, count, &got, |
186 | (SA *) &peer, &peer_len); | 151 | (SA *) &addr, &addr_len, tm_get(tm)); |
187 | if (err == PRIV_CLOSED) err = PRIV_REFUSED; | 152 | if (err == IO_DONE) { |
188 | if (err == PRIV_DONE) { | ||
189 | lua_pushlstring(L, buffer, got); | 153 | lua_pushlstring(L, buffer, got); |
190 | lua_pushstring(L, inet_ntoa(peer.sin_addr)); | 154 | lua_pushstring(L, inet_ntoa(addr.sin_addr)); |
191 | lua_pushnumber(L, ntohs(peer.sin_port)); | 155 | lua_pushnumber(L, ntohs(addr.sin_port)); |
192 | return 3; | 156 | return 3; |
193 | } else { | 157 | } else { |
194 | lua_pushnil(L); | 158 | lua_pushnil(L); |
195 | priv_pusherror(L, err); | 159 | error_push(L, err); |
196 | return 2; | 160 | return 2; |
197 | } | 161 | } |
198 | } | 162 | } |
199 | 163 | ||
200 | /*-------------------------------------------------------------------------*\ | 164 | /*-------------------------------------------------------------------------*\ |
201 | * Send data through a connected UDP socket | 165 | * Just call inet methods |
202 | * Lua Input: sock, data | ||
203 | * sock: udp socket | ||
204 | * data: data to be sent | ||
205 | * Lua Returns | ||
206 | * On success: nil, followed by the total number of bytes sent | ||
207 | * On error: error message | ||
208 | \*-------------------------------------------------------------------------*/ | 166 | \*-------------------------------------------------------------------------*/ |
209 | static int udp_lua_send(lua_State *L) | 167 | static int udp_meth_getpeername(lua_State *L) |
210 | { | 168 | { |
211 | p_udp udp = (p_udp) lua_touserdata(L, 1); | 169 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); |
212 | p_tm tm = &udp->base_tm; | 170 | return inet_meth_getpeername(L, &udp->sock); |
213 | size_t wanted, sent = 0; | 171 | } |
214 | int err; | 172 | |
215 | cchar *data = luaL_checklstring(L, 2, &wanted); | 173 | static int udp_meth_getsockname(lua_State *L) |
216 | if (!udp->udp_connected) luaL_error(L, "send on unconnected socket"); | 174 | { |
217 | tm_markstart(tm); | 175 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
218 | err = compat_send(udp->fd, data, wanted, &sent, tm_getremaining(tm)); | 176 | return inet_meth_getsockname(L, &udp->sock); |
219 | priv_pusherror(L, err == PRIV_CLOSED ? PRIV_REFUSED : err); | ||
220 | lua_pushnumber(L, sent); | ||
221 | return 2; | ||
222 | } | 177 | } |
223 | 178 | ||
224 | /*-------------------------------------------------------------------------*\ | 179 | /*-------------------------------------------------------------------------*\ |
225 | * Send data through a unconnected UDP socket | 180 | * Just call tm methods |
226 | * Lua Input: sock, data, ip, port | ||
227 | * sock: udp socket | ||
228 | * data: data to be sent | ||
229 | * ip: ip address of target | ||
230 | * port: port in target | ||
231 | * Lua Returns | ||
232 | * On success: nil, followed by the total number of bytes sent | ||
233 | * On error: error message | ||
234 | \*-------------------------------------------------------------------------*/ | 181 | \*-------------------------------------------------------------------------*/ |
235 | static int udp_lua_sendto(lua_State *L) | 182 | static int udp_meth_timeout(lua_State *L) |
236 | { | 183 | { |
237 | p_udp udp = (p_udp) lua_touserdata(L, 1); | 184 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
238 | size_t wanted, sent = 0; | 185 | return tm_meth_timeout(L, &udp->tm); |
239 | cchar *data = luaL_checklstring(L, 2, &wanted); | ||
240 | cchar *ip = luaL_checkstring(L, 3); | ||
241 | ushort port = (ushort) luaL_checknumber(L, 4); | ||
242 | p_tm tm = &udp->base_tm; | ||
243 | struct sockaddr_in peer; | ||
244 | int err; | ||
245 | if (udp->udp_connected) luaL_error(L, "sendto on connected socket"); | ||
246 | memset(&peer, 0, sizeof(peer)); | ||
247 | if (!inet_aton(ip, &peer.sin_addr)) luaL_error(L, "invalid ip address"); | ||
248 | peer.sin_family = AF_INET; | ||
249 | peer.sin_port = htons(port); | ||
250 | tm_markstart(tm); | ||
251 | err = compat_sendto(udp->fd, data, wanted, &sent, tm_getremaining(tm), | ||
252 | (SA *) &peer, sizeof(peer)); | ||
253 | priv_pusherror(L, err == PRIV_CLOSED ? PRIV_REFUSED : err); | ||
254 | lua_pushnumber(L, sent); | ||
255 | return 2; | ||
256 | } | 186 | } |
257 | 187 | ||
258 | /*-------------------------------------------------------------------------*\ | 188 | /*-------------------------------------------------------------------------*\ |
259 | * Associates a local address to an UDP socket | 189 | * Turns a master udp object into a client object. |
260 | * Lua Input: address, port | ||
261 | * address: host name or ip address to bind to | ||
262 | * port: port to bind to | ||
263 | * Lua Returns | ||
264 | * On success: nil | ||
265 | * On error: error message | ||
266 | \*-------------------------------------------------------------------------*/ | 190 | \*-------------------------------------------------------------------------*/ |
267 | static int udp_lua_setsockname(lua_State * L) | 191 | static int udp_meth_setpeername(lua_State *L) |
268 | { | 192 | { |
269 | p_udp udp = (p_udp) lua_touserdata(L, 1); | 193 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
270 | cchar *address = luaL_checkstring(L, 2); | 194 | const char *address = luaL_checkstring(L, 2); |
271 | ushort port = (ushort) luaL_checknumber(L, 3); | 195 | int connecting = strcmp(address, "*"); |
272 | cchar *err = inet_trybind((p_inet) udp, address, port); | 196 | unsigned short port = connecting ? |
273 | if (err) lua_pushstring(L, err); | 197 | (ushort) luaL_checknumber(L, 3) : (ushort) luaL_optnumber(L, 3, 0); |
274 | else lua_pushnil(L); | 198 | const char *err = inet_tryconnect(&udp->sock, address, port); |
199 | if (err) { | ||
200 | lua_pushnil(L); | ||
201 | lua_pushstring(L, err); | ||
202 | return 2; | ||
203 | } | ||
204 | /* change class to connected or unconnected depending on address */ | ||
205 | if (connecting) aux_setclass(L, "udp{connected}", 1); | ||
206 | else aux_setclass(L, "udp{unconnected}", 1); | ||
207 | lua_pushnumber(L, 1); | ||
275 | return 1; | 208 | return 1; |
276 | } | 209 | } |
277 | 210 | ||
278 | /*-------------------------------------------------------------------------*\ | 211 | /*-------------------------------------------------------------------------*\ |
279 | * Sets a peer for a UDP socket | 212 | * Closes socket used by object |
280 | * Lua Input: address, port | 213 | \*-------------------------------------------------------------------------*/ |
281 | * address: remote host name | 214 | static int udp_meth_close(lua_State *L) |
282 | * port: remote host port | 215 | { |
283 | * Lua Returns | 216 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
284 | * On success: nil | 217 | sock_destroy(&udp->sock); |
285 | * On error: error message | 218 | return 0; |
219 | } | ||
220 | |||
221 | /*-------------------------------------------------------------------------*\ | ||
222 | * Turns a master object into a server object | ||
286 | \*-------------------------------------------------------------------------*/ | 223 | \*-------------------------------------------------------------------------*/ |
287 | static int udp_lua_setpeername(lua_State *L) | 224 | static int udp_meth_setsockname(lua_State *L) |
288 | { | 225 | { |
289 | p_udp udp = (p_udp) lua_touserdata(L, 1); | 226 | p_udp udp = (p_udp) aux_checkclass(L, "udp{master}", 1); |
290 | cchar *address = luaL_checkstring(L, 2); | 227 | const char *address = luaL_checkstring(L, 2); |
291 | ushort port = (ushort) luaL_checknumber(L, 3); | 228 | unsigned short port = (ushort) luaL_checknumber(L, 3); |
292 | cchar *err = inet_tryconnect((p_inet) udp, address, port); | 229 | const char *err = inet_trybind(&udp->sock, address, port, -1); |
293 | if (!err) { | 230 | if (err) { |
294 | udp->udp_connected = 1; | ||
295 | lua_pushnil(L); | 231 | lua_pushnil(L); |
296 | } else lua_pushstring(L, err); | 232 | lua_pushstring(L, err); |
233 | return 2; | ||
234 | } | ||
235 | lua_pushnumber(L, 1); | ||
297 | return 1; | 236 | return 1; |
298 | } | 237 | } |
299 | 238 | ||
239 | /*=========================================================================*\ | ||
240 | * Library functions | ||
241 | \*=========================================================================*/ | ||
242 | /*-------------------------------------------------------------------------*\ | ||
243 | * Creates a master udp object | ||
244 | \*-------------------------------------------------------------------------*/ | ||
245 | int udp_global_create(lua_State *L) | ||
246 | { | ||
247 | /* allocate udp object */ | ||
248 | p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); | ||
249 | /* set its type as master object */ | ||
250 | aux_setclass(L, "udp{unconnected}", -1); | ||
251 | /* try to allocate a system socket */ | ||
252 | const char *err = inet_trycreate(&udp->sock, SOCK_DGRAM); | ||
253 | if (err) { | ||
254 | /* get rid of object on stack and push error */ | ||
255 | lua_pop(L, 1); | ||
256 | lua_pushnil(L); | ||
257 | lua_pushstring(L, err); | ||
258 | return 2; | ||
259 | } | ||
260 | /* initialize timeout management */ | ||
261 | tm_init(&udp->tm, -1, -1); | ||
262 | return 1; | ||
263 | } | ||