diff options
Diffstat (limited to 'src/tcp.c')
-rw-r--r-- | src/tcp.c | 164 |
1 files changed, 82 insertions, 82 deletions
@@ -29,10 +29,10 @@ static int meth_receive(lua_State *L); | |||
29 | static int meth_accept(lua_State *L); | 29 | static int meth_accept(lua_State *L); |
30 | static int meth_close(lua_State *L); | 30 | static int meth_close(lua_State *L); |
31 | static int meth_setoption(lua_State *L); | 31 | static int meth_setoption(lua_State *L); |
32 | static int meth_timeout(lua_State *L); | 32 | static int meth_settimeout(lua_State *L); |
33 | static int meth_fd(lua_State *L); | 33 | static int meth_fd(lua_State *L); |
34 | static int meth_dirty(lua_State *L); | 34 | static int meth_dirty(lua_State *L); |
35 | static int opt_nodelay(lua_State *L); | 35 | static int opt_tcp_nodelay(lua_State *L); |
36 | static int opt_keepalive(lua_State *L); | 36 | static int opt_keepalive(lua_State *L); |
37 | static int opt_linger(lua_State *L); | 37 | static int opt_linger(lua_State *L); |
38 | 38 | ||
@@ -47,7 +47,7 @@ static luaL_reg tcp[] = { | |||
47 | {"setsockname", meth_bind}, | 47 | {"setsockname", meth_bind}, |
48 | {"getpeername", meth_getpeername}, | 48 | {"getpeername", meth_getpeername}, |
49 | {"getsockname", meth_getsockname}, | 49 | {"getsockname", meth_getsockname}, |
50 | {"timeout", meth_timeout}, | 50 | {"settimeout", meth_settimeout}, |
51 | {"close", meth_close}, | 51 | {"close", meth_close}, |
52 | {"setoption", meth_setoption}, | 52 | {"setoption", meth_setoption}, |
53 | {"__gc", meth_close}, | 53 | {"__gc", meth_close}, |
@@ -59,7 +59,7 @@ static luaL_reg tcp[] = { | |||
59 | /* socket option handlers */ | 59 | /* socket option handlers */ |
60 | static luaL_reg opt[] = { | 60 | static luaL_reg opt[] = { |
61 | {"keepalive", opt_keepalive}, | 61 | {"keepalive", opt_keepalive}, |
62 | {"nodelay", opt_nodelay}, | 62 | {"tcp-nodelay", opt_tcp_nodelay}, |
63 | {"linger", opt_linger}, | 63 | {"linger", opt_linger}, |
64 | {NULL, NULL} | 64 | {NULL, NULL} |
65 | }; | 65 | }; |
@@ -83,8 +83,8 @@ void tcp_open(lua_State *L) | |||
83 | aux_add2group(L, "tcp{master}", "tcp{any}"); | 83 | aux_add2group(L, "tcp{master}", "tcp{any}"); |
84 | aux_add2group(L, "tcp{client}", "tcp{any}"); | 84 | aux_add2group(L, "tcp{client}", "tcp{any}"); |
85 | aux_add2group(L, "tcp{server}", "tcp{any}"); | 85 | aux_add2group(L, "tcp{server}", "tcp{any}"); |
86 | aux_add2group(L, "tcp{client}", "tcp{client, server}"); | 86 | aux_add2group(L, "tcp{client}", "tcp{client,server}"); |
87 | aux_add2group(L, "tcp{server}", "tcp{client, server}"); | 87 | aux_add2group(L, "tcp{server}", "tcp{client,server}"); |
88 | /* both server and client objects are selectable */ | 88 | /* both server and client objects are selectable */ |
89 | aux_add2group(L, "tcp{client}", "select{able}"); | 89 | aux_add2group(L, "tcp{client}", "select{able}"); |
90 | aux_add2group(L, "tcp{server}", "select{able}"); | 90 | aux_add2group(L, "tcp{server}", "select{able}"); |
@@ -121,7 +121,7 @@ static int meth_setoption(lua_State *L) | |||
121 | 121 | ||
122 | static int opt_boolean(lua_State *L, int level, int name) | 122 | static int opt_boolean(lua_State *L, int level, int name) |
123 | { | 123 | { |
124 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | 124 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1); |
125 | int val = aux_checkboolean(L, 2); | 125 | int val = aux_checkboolean(L, 2); |
126 | if (setsockopt(tcp->sock, level, name, (char *) &val, sizeof(val)) < 0) { | 126 | if (setsockopt(tcp->sock, level, name, (char *) &val, sizeof(val)) < 0) { |
127 | lua_pushnil(L); | 127 | lua_pushnil(L); |
@@ -132,8 +132,8 @@ static int opt_boolean(lua_State *L, int level, int name) | |||
132 | return 1; | 132 | return 1; |
133 | } | 133 | } |
134 | 134 | ||
135 | /* disables the Nagle algorithm */ | 135 | /* disables the Naggle algorithm */ |
136 | static int opt_nodelay(lua_State *L) | 136 | static int opt_tcp_nodelay(lua_State *L) |
137 | { | 137 | { |
138 | struct protoent *pe = getprotobyname("TCP"); | 138 | struct protoent *pe = getprotobyname("TCP"); |
139 | if (!pe) { | 139 | if (!pe) { |
@@ -155,13 +155,13 @@ int opt_linger(lua_State *L) | |||
155 | struct linger li; | 155 | struct linger li; |
156 | if (!lua_istable(L, 2)) | 156 | if (!lua_istable(L, 2)) |
157 | luaL_typerror(L, 2, lua_typename(L, LUA_TTABLE)); | 157 | luaL_typerror(L, 2, lua_typename(L, LUA_TTABLE)); |
158 | lua_pushstring(L, "onoff"); | 158 | lua_pushstring(L, "on"); |
159 | lua_gettable(L, 2); | 159 | lua_gettable(L, 2); |
160 | if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid onoff field"); | 160 | if (!lua_isboolean(L, -1)) luaL_argerror(L, 2, "invalid 'on' field"); |
161 | li.l_onoff = (int) lua_tonumber(L, -1); | 161 | li.l_onoff = lua_toboolean(L, -1); |
162 | lua_pushstring(L, "linger"); | 162 | lua_pushstring(L, "timeout"); |
163 | lua_gettable(L, 2); | 163 | lua_gettable(L, 2); |
164 | if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid linger field"); | 164 | if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid 'timeout' field"); |
165 | li.l_linger = (int) lua_tonumber(L, -1); | 165 | li.l_linger = (int) lua_tonumber(L, -1); |
166 | if (setsockopt(tcp->sock, SOL_SOCKET, SO_LINGER, | 166 | if (setsockopt(tcp->sock, SOL_SOCKET, SO_LINGER, |
167 | (char *) &li, sizeof(li) < 0)) { | 167 | (char *) &li, sizeof(li) < 0)) { |
@@ -178,122 +178,122 @@ int opt_linger(lua_State *L) | |||
178 | \*-------------------------------------------------------------------------*/ | 178 | \*-------------------------------------------------------------------------*/ |
179 | static int meth_fd(lua_State *L) | 179 | static int meth_fd(lua_State *L) |
180 | { | 180 | { |
181 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1); | 181 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1); |
182 | lua_pushnumber(L, tcp->sock); | 182 | lua_pushnumber(L, tcp->sock); |
183 | return 1; | 183 | return 1; |
184 | } | 184 | } |
185 | 185 | ||
186 | static int meth_dirty(lua_State *L) | 186 | static int meth_dirty(lua_State *L) |
187 | { | 187 | { |
188 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1); | 188 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1); |
189 | lua_pushboolean(L, !buf_isempty(&tcp->buf)); | 189 | lua_pushboolean(L, !buf_isempty(&tcp->buf)); |
190 | return 1; | 190 | return 1; |
191 | } | 191 | } |
192 | 192 | ||
193 | /*-------------------------------------------------------------------------*\ | 193 | /*-------------------------------------------------------------------------*\ |
194 | * Just call inet methods | 194 | * Waits for and returns a client object attempting connection to the |
195 | \*-------------------------------------------------------------------------*/ | 195 | * server object |
196 | static int meth_getpeername(lua_State *L) | ||
197 | { | ||
198 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); | ||
199 | return inet_meth_getpeername(L, &tcp->sock); | ||
200 | } | ||
201 | |||
202 | static int meth_getsockname(lua_State *L) | ||
203 | { | ||
204 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1); | ||
205 | return inet_meth_getsockname(L, &tcp->sock); | ||
206 | } | ||
207 | |||
208 | /*-------------------------------------------------------------------------*\ | ||
209 | * Just call tm methods | ||
210 | \*-------------------------------------------------------------------------*/ | ||
211 | static int meth_timeout(lua_State *L) | ||
212 | { | ||
213 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | ||
214 | return tm_meth_timeout(L, &tcp->tm); | ||
215 | } | ||
216 | |||
217 | /*-------------------------------------------------------------------------*\ | ||
218 | * Closes socket used by object | ||
219 | \*-------------------------------------------------------------------------*/ | 196 | \*-------------------------------------------------------------------------*/ |
220 | static int meth_close(lua_State *L) | 197 | static int meth_accept(lua_State *L) |
221 | { | 198 | { |
222 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | 199 | struct sockaddr_in addr; |
223 | sock_destroy(&tcp->sock); | 200 | socklen_t addr_len = sizeof(addr); |
224 | return 0; | 201 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); |
202 | p_tm tm = &server->tm; | ||
203 | p_tcp client = lua_newuserdata(L, sizeof(t_tcp)); | ||
204 | tm_markstart(tm); | ||
205 | aux_setclass(L, "tcp{client}", -1); | ||
206 | for ( ;; ) { | ||
207 | sock_accept(&server->sock, &client->sock, | ||
208 | (SA *) &addr, &addr_len, tm_get(tm)); | ||
209 | if (client->sock == SOCK_INVALID) { | ||
210 | if (tm_get(tm) == 0) { | ||
211 | lua_pushnil(L); | ||
212 | io_pusherror(L, IO_TIMEOUT); | ||
213 | return 2; | ||
214 | } | ||
215 | } else break; | ||
216 | } | ||
217 | /* initialize remaining structure fields */ | ||
218 | io_init(&client->io, (p_send) sock_send, (p_recv) sock_recv, &client->sock); | ||
219 | tm_init(&client->tm, -1, -1); | ||
220 | buf_init(&client->buf, &client->io, &client->tm); | ||
221 | return 1; | ||
225 | } | 222 | } |
226 | 223 | ||
227 | /*-------------------------------------------------------------------------*\ | 224 | /*-------------------------------------------------------------------------*\ |
228 | * Turns a master tcp object into a client object. | 225 | * Turns a master object into a server object |
229 | \*-------------------------------------------------------------------------*/ | 226 | \*-------------------------------------------------------------------------*/ |
230 | static int meth_connect(lua_State *L) | 227 | static int meth_bind(lua_State *L) |
231 | { | 228 | { |
232 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | 229 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); |
233 | const char *address = luaL_checkstring(L, 2); | 230 | const char *address = luaL_checkstring(L, 2); |
234 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); | 231 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); |
235 | const char *err = inet_tryconnect(&tcp->sock, address, port); | 232 | int backlog = (int) luaL_optnumber(L, 4, 1); |
233 | const char *err = inet_trybind(&tcp->sock, address, port, backlog); | ||
236 | if (err) { | 234 | if (err) { |
237 | lua_pushnil(L); | 235 | lua_pushnil(L); |
238 | lua_pushstring(L, err); | 236 | lua_pushstring(L, err); |
239 | return 2; | 237 | return 2; |
240 | } | 238 | } |
241 | /* turn master object into a client object */ | 239 | /* turn master object into a server object */ |
242 | aux_setclass(L, "tcp{client}", 1); | 240 | aux_setclass(L, "tcp{server}", 1); |
243 | lua_pushnumber(L, 1); | 241 | lua_pushnumber(L, 1); |
244 | return 1; | 242 | return 1; |
245 | } | 243 | } |
246 | 244 | ||
247 | /*-------------------------------------------------------------------------*\ | 245 | /*-------------------------------------------------------------------------*\ |
248 | * Turns a master object into a server object | 246 | * Turns a master tcp object into a client object. |
249 | \*-------------------------------------------------------------------------*/ | 247 | \*-------------------------------------------------------------------------*/ |
250 | static int meth_bind(lua_State *L) | 248 | static int meth_connect(lua_State *L) |
251 | { | 249 | { |
252 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | 250 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); |
253 | const char *address = luaL_checkstring(L, 2); | 251 | const char *address = luaL_checkstring(L, 2); |
254 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); | 252 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); |
255 | int backlog = (int) luaL_optnumber(L, 4, 1); | 253 | const char *err = inet_tryconnect(&tcp->sock, address, port); |
256 | const char *err = inet_trybind(&tcp->sock, address, port, backlog); | ||
257 | if (err) { | 254 | if (err) { |
258 | lua_pushnil(L); | 255 | lua_pushnil(L); |
259 | lua_pushstring(L, err); | 256 | lua_pushstring(L, err); |
260 | return 2; | 257 | return 2; |
261 | } | 258 | } |
262 | /* turn master object into a server object */ | 259 | /* turn master object into a client object */ |
263 | aux_setclass(L, "tcp{server}", 1); | 260 | aux_setclass(L, "tcp{client}", 1); |
264 | lua_pushnumber(L, 1); | 261 | lua_pushnumber(L, 1); |
265 | return 1; | 262 | return 1; |
266 | } | 263 | } |
267 | 264 | ||
268 | /*-------------------------------------------------------------------------*\ | 265 | /*-------------------------------------------------------------------------*\ |
269 | * Waits for and returns a client object attempting connection to the | 266 | * Closes socket used by object |
270 | * server object | ||
271 | \*-------------------------------------------------------------------------*/ | 267 | \*-------------------------------------------------------------------------*/ |
272 | static int meth_accept(lua_State *L) | 268 | static int meth_close(lua_State *L) |
273 | { | 269 | { |
274 | struct sockaddr_in addr; | 270 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); |
275 | socklen_t addr_len = sizeof(addr); | 271 | sock_destroy(&tcp->sock); |
276 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); | 272 | return 0; |
277 | p_tm tm = &server->tm; | 273 | } |
278 | p_tcp client = lua_newuserdata(L, sizeof(t_tcp)); | 274 | |
279 | tm_markstart(tm); | 275 | /*-------------------------------------------------------------------------*\ |
280 | aux_setclass(L, "tcp{client}", -1); | 276 | * Just call inet methods |
281 | for ( ;; ) { | 277 | \*-------------------------------------------------------------------------*/ |
282 | sock_accept(&server->sock, &client->sock, | 278 | static int meth_getpeername(lua_State *L) |
283 | (SA *) &addr, &addr_len, tm_get(tm)); | 279 | { |
284 | if (client->sock == SOCK_INVALID) { | 280 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); |
285 | if (tm_get(tm) == 0) { | 281 | return inet_meth_getpeername(L, &tcp->sock); |
286 | lua_pushnil(L); | 282 | } |
287 | io_pusherror(L, IO_TIMEOUT); | 283 | |
288 | return 2; | 284 | static int meth_getsockname(lua_State *L) |
289 | } | 285 | { |
290 | } else break; | 286 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1); |
291 | } | 287 | return inet_meth_getsockname(L, &tcp->sock); |
292 | /* initialize remaining structure fields */ | 288 | } |
293 | io_init(&client->io, (p_send) sock_send, (p_recv) sock_recv, &client->sock); | 289 | |
294 | tm_init(&client->tm, -1, -1); | 290 | /*-------------------------------------------------------------------------*\ |
295 | buf_init(&client->buf, &client->io, &client->tm); | 291 | * Just call tm methods |
296 | return 1; | 292 | \*-------------------------------------------------------------------------*/ |
293 | static int meth_settimeout(lua_State *L) | ||
294 | { | ||
295 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1); | ||
296 | return tm_meth_settimeout(L, &tcp->tm); | ||
297 | } | 297 | } |
298 | 298 | ||
299 | /*=========================================================================*\ | 299 | /*=========================================================================*\ |