diff options
Diffstat (limited to 'src/tcp.c')
-rw-r--r-- | src/tcp.c | 82 |
1 files changed, 11 insertions, 71 deletions
@@ -14,6 +14,7 @@ | |||
14 | #include "auxiliar.h" | 14 | #include "auxiliar.h" |
15 | #include "socket.h" | 15 | #include "socket.h" |
16 | #include "inet.h" | 16 | #include "inet.h" |
17 | #include "options.h" | ||
17 | #include "tcp.h" | 18 | #include "tcp.h" |
18 | 19 | ||
19 | /*=========================================================================*\ | 20 | /*=========================================================================*\ |
@@ -33,10 +34,6 @@ static int meth_setoption(lua_State *L); | |||
33 | static int meth_settimeout(lua_State *L); | 34 | static int meth_settimeout(lua_State *L); |
34 | static int meth_fd(lua_State *L); | 35 | static int meth_fd(lua_State *L); |
35 | static int meth_dirty(lua_State *L); | 36 | static int meth_dirty(lua_State *L); |
36 | static int opt_tcp_nodelay(lua_State *L); | ||
37 | static int opt_keepalive(lua_State *L); | ||
38 | static int opt_linger(lua_State *L); | ||
39 | static int opt_reuseaddr(lua_State *L); | ||
40 | 37 | ||
41 | /* tcp object methods */ | 38 | /* tcp object methods */ |
42 | static luaL_reg tcp[] = { | 39 | static luaL_reg tcp[] = { |
@@ -60,7 +57,7 @@ static luaL_reg tcp[] = { | |||
60 | }; | 57 | }; |
61 | 58 | ||
62 | /* socket option handlers */ | 59 | /* socket option handlers */ |
63 | static luaL_reg opt[] = { | 60 | static t_opt opt[] = { |
64 | {"keepalive", opt_keepalive}, | 61 | {"keepalive", opt_keepalive}, |
65 | {"reuseaddr", opt_reuseaddr}, | 62 | {"reuseaddr", opt_reuseaddr}, |
66 | {"tcp-nodelay", opt_tcp_nodelay}, | 63 | {"tcp-nodelay", opt_tcp_nodelay}, |
@@ -116,65 +113,12 @@ static int meth_receive(lua_State *L) | |||
116 | } | 113 | } |
117 | 114 | ||
118 | /*-------------------------------------------------------------------------*\ | 115 | /*-------------------------------------------------------------------------*\ |
119 | * Option handlers | 116 | * Just call option handler |
120 | \*-------------------------------------------------------------------------*/ | 117 | \*-------------------------------------------------------------------------*/ |
121 | static int meth_setoption(lua_State *L) | 118 | static int meth_setoption(lua_State *L) |
122 | { | 119 | { |
123 | return aux_meth_setoption(L, opt); | 120 | p_tcp tcp = aux_checkgroup(L, "tcp{any}", 1); |
124 | } | 121 | return opt_meth_setoption(L, opt, &tcp->sock); |
125 | |||
126 | static int opt_boolean(lua_State *L, int level, int name) | ||
127 | { | ||
128 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | ||
129 | int val = aux_checkboolean(L, 2); | ||
130 | if (setsockopt(tcp->sock, level, name, (char *) &val, sizeof(val)) < 0) { | ||
131 | lua_pushnil(L); | ||
132 | lua_pushstring(L, "setsockopt failed"); | ||
133 | return 2; | ||
134 | } | ||
135 | lua_pushnumber(L, 1); | ||
136 | return 1; | ||
137 | } | ||
138 | |||
139 | /* enables reuse of local address */ | ||
140 | static int opt_reuseaddr(lua_State *L) | ||
141 | { | ||
142 | return opt_boolean(L, SOL_SOCKET, SO_REUSEADDR); | ||
143 | } | ||
144 | |||
145 | /* disables the Naggle algorithm */ | ||
146 | static int opt_tcp_nodelay(lua_State *L) | ||
147 | { | ||
148 | return opt_boolean(L, IPPROTO_TCP, TCP_NODELAY); | ||
149 | } | ||
150 | |||
151 | static int opt_keepalive(lua_State *L) | ||
152 | { | ||
153 | return opt_boolean(L, SOL_SOCKET, SO_KEEPALIVE); | ||
154 | } | ||
155 | |||
156 | static int opt_linger(lua_State *L) | ||
157 | { | ||
158 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); | ||
159 | struct linger li; | ||
160 | if (!lua_istable(L, 2)) | ||
161 | luaL_typerror(L, 2, lua_typename(L, LUA_TTABLE)); | ||
162 | lua_pushstring(L, "on"); | ||
163 | lua_gettable(L, 2); | ||
164 | if (!lua_isboolean(L, -1)) luaL_argerror(L, 2, "invalid 'on' field"); | ||
165 | li.l_onoff = lua_toboolean(L, -1); | ||
166 | lua_pushstring(L, "timeout"); | ||
167 | lua_gettable(L, 2); | ||
168 | if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid 'timeout' field"); | ||
169 | li.l_linger = (int) lua_tonumber(L, -1); | ||
170 | if (setsockopt(tcp->sock, SOL_SOCKET, SO_LINGER, | ||
171 | (char *) &li, sizeof(li) < 0)) { | ||
172 | lua_pushnil(L); | ||
173 | lua_pushstring(L, "setsockopt failed"); | ||
174 | return 2; | ||
175 | } | ||
176 | lua_pushnumber(L, 1); | ||
177 | return 1; | ||
178 | } | 122 | } |
179 | 123 | ||
180 | /*-------------------------------------------------------------------------*\ | 124 | /*-------------------------------------------------------------------------*\ |
@@ -201,13 +145,11 @@ static int meth_dirty(lua_State *L) | |||
201 | static int meth_accept(lua_State *L) | 145 | static int meth_accept(lua_State *L) |
202 | { | 146 | { |
203 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); | 147 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); |
204 | p_tm tm = &server->tm; | 148 | p_tm tm = tm_markstart(&server->tm); |
205 | t_sock sock; | 149 | t_sock sock; |
206 | const char *err; | 150 | int err = sock_accept(&server->sock, &sock, NULL, NULL, tm); |
207 | tm_markstart(tm); | ||
208 | err = inet_tryaccept(&server->sock, tm, &sock); | ||
209 | /* if successful, push client socket */ | 151 | /* if successful, push client socket */ |
210 | if (!err) { | 152 | if (err == IO_DONE) { |
211 | p_tcp clnt = lua_newuserdata(L, sizeof(t_tcp)); | 153 | p_tcp clnt = lua_newuserdata(L, sizeof(t_tcp)); |
212 | aux_setclass(L, "tcp{client}", -1); | 154 | aux_setclass(L, "tcp{client}", -1); |
213 | /* initialize structure fields */ | 155 | /* initialize structure fields */ |
@@ -218,7 +160,7 @@ static int meth_accept(lua_State *L) | |||
218 | return 1; | 160 | return 1; |
219 | } else { | 161 | } else { |
220 | lua_pushnil(L); | 162 | lua_pushnil(L); |
221 | lua_pushstring(L, err); | 163 | io_pusherror(L, err); |
222 | return 2; | 164 | return 2; |
223 | } | 165 | } |
224 | } | 166 | } |
@@ -252,10 +194,8 @@ static int meth_connect(lua_State *L) | |||
252 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | 194 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); |
253 | const char *address = luaL_checkstring(L, 2); | 195 | const char *address = luaL_checkstring(L, 2); |
254 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); | 196 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); |
255 | p_tm tm = &tcp->tm; | 197 | p_tm tm = tm_markstart(&tcp->tm); |
256 | const char *err; | 198 | const char *err = inet_tryconnect(&tcp->sock, address, port, tm); |
257 | tm_markstart(tm); | ||
258 | err = inet_tryconnect(&tcp->sock, tm, address, port); | ||
259 | if (err) { | 199 | if (err) { |
260 | lua_pushnil(L); | 200 | lua_pushnil(L); |
261 | lua_pushstring(L, err); | 201 | lua_pushstring(L, err); |