diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2002-07-03 19:06:55 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2002-07-03 19:06:55 +0000 |
commit | 46828c1a7d02f029cf3fa1b3c6d56cf054100c98 (patch) | |
tree | 67e31a70ee2b3100e1bfdb9d8c2b896e14bbcc1f /src | |
parent | 88026bef8a5ca586e354965a79134646fb566c72 (diff) | |
download | luasocket-46828c1a7d02f029cf3fa1b3c6d56cf054100c98.tar.gz luasocket-46828c1a7d02f029cf3fa1b3c6d56cf054100c98.tar.bz2 luasocket-46828c1a7d02f029cf3fa1b3c6d56cf054100c98.zip |
internet class.
Diffstat (limited to 'src')
-rw-r--r-- | src/inet.c | 116 |
1 files changed, 46 insertions, 70 deletions
@@ -1,11 +1,11 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * Internet socket methods implementation | 2 | * Internet domain class |
3 | * Lua methods: | ||
4 | * getpeername: gets socket peer ip address and port | ||
5 | * getsockname: gets local socket ip address and port | ||
3 | * Global Lua fuctions: | 6 | * Global Lua fuctions: |
4 | * toip(hostname) | 7 | * toip: gets resolver info on host name |
5 | * tohostname(dotted-quad) | 8 | * tohostname: gets resolver info on dotted-quad |
6 | * Socket table methods: | ||
7 | * getpeername() | ||
8 | * getsockname() | ||
9 | \*=========================================================================*/ | 9 | \*=========================================================================*/ |
10 | #include <string.h> | 10 | #include <string.h> |
11 | 11 | ||
@@ -46,7 +46,9 @@ void inet_open(lua_State *L) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | /*-------------------------------------------------------------------------*\ | 48 | /*-------------------------------------------------------------------------*\ |
49 | * Hook object methods to methods table. | 49 | * Hook lua methods to methods table. |
50 | * Input | ||
51 | * lsclass: class name | ||
50 | \*-------------------------------------------------------------------------*/ | 52 | \*-------------------------------------------------------------------------*/ |
51 | void inet_inherit(lua_State *L, cchar *lsclass) | 53 | void inet_inherit(lua_State *L, cchar *lsclass) |
52 | { | 54 | { |
@@ -62,6 +64,9 @@ void inet_inherit(lua_State *L, cchar *lsclass) | |||
62 | } | 64 | } |
63 | } | 65 | } |
64 | 66 | ||
67 | /*-------------------------------------------------------------------------*\ | ||
68 | * Constructs the object | ||
69 | \*-------------------------------------------------------------------------*/ | ||
65 | void inet_construct(lua_State *L, p_inet inet) | 70 | void inet_construct(lua_State *L, p_inet inet) |
66 | { | 71 | { |
67 | sock_construct(L, (p_sock) inet); | 72 | sock_construct(L, (p_sock) inet); |
@@ -71,7 +76,8 @@ void inet_construct(lua_State *L, p_inet inet) | |||
71 | * Global Lua functions | 76 | * Global Lua functions |
72 | \*=========================================================================*/ | 77 | \*=========================================================================*/ |
73 | /*-------------------------------------------------------------------------*\ | 78 | /*-------------------------------------------------------------------------*\ |
74 | * Returns the list of ip addresses associated with a host name | 79 | * Returns all information provided by the resolver given a host name |
80 | * or ip address | ||
75 | * Lua Input: address | 81 | * Lua Input: address |
76 | * address: ip address or hostname to dns lookup | 82 | * address: ip address or hostname to dns lookup |
77 | * Lua Returns | 83 | * Lua Returns |
@@ -98,7 +104,8 @@ static int inet_lua_toip(lua_State *L) | |||
98 | } | 104 | } |
99 | 105 | ||
100 | /*-------------------------------------------------------------------------*\ | 106 | /*-------------------------------------------------------------------------*\ |
101 | * Returns the list of host names associated with an ip address | 107 | * Returns all information provided by the resolver given a host name |
108 | * or ip address | ||
102 | * Lua Input: address | 109 | * Lua Input: address |
103 | * address: ip address or host name to reverse dns lookup | 110 | * address: ip address or host name to reverse dns lookup |
104 | * Lua Returns | 111 | * Lua Returns |
@@ -124,7 +131,7 @@ static int inet_lua_tohostname(lua_State *L) | |||
124 | } | 131 | } |
125 | 132 | ||
126 | /*=========================================================================*\ | 133 | /*=========================================================================*\ |
127 | * Socket table methods | 134 | * Lua methods |
128 | \*=========================================================================*/ | 135 | \*=========================================================================*/ |
129 | /*-------------------------------------------------------------------------*\ | 136 | /*-------------------------------------------------------------------------*\ |
130 | * Retrieves socket peer name | 137 | * Retrieves socket peer name |
@@ -220,42 +227,28 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp) | |||
220 | * Returns | 227 | * Returns |
221 | * NULL in case of success, error message otherwise | 228 | * NULL in case of success, error message otherwise |
222 | \*-------------------------------------------------------------------------*/ | 229 | \*-------------------------------------------------------------------------*/ |
223 | cchar *inet_tryconnect(p_inet inet, cchar *address, ushort port, | 230 | cchar *inet_tryconnect(p_inet inet, cchar *address, ushort port) |
224 | int type) | ||
225 | { | 231 | { |
226 | struct sockaddr_in remote; | 232 | struct sockaddr_in remote; |
227 | cchar *err = NULL; | ||
228 | memset(&remote, 0, sizeof(remote)); | 233 | memset(&remote, 0, sizeof(remote)); |
229 | if (strlen(address) && inet_aton(address, &remote.sin_addr)) { | 234 | remote.sin_family = AF_INET; |
230 | remote.sin_family = AF_INET; | 235 | remote.sin_port = htons(port); |
231 | remote.sin_port = htons(port); | 236 | if (!strlen(address) || !inet_aton(address, &remote.sin_addr)) { |
232 | err = inet_trysocket(inet, type); | ||
233 | if (err) return err; | ||
234 | if (compat_connect(inet->fd, (SA *) &remote, sizeof(remote)) < 0) { | ||
235 | compat_close(inet->fd); | ||
236 | inet->fd = COMPAT_INVALIDFD; | ||
237 | return compat_connectstrerror(); | ||
238 | } else return NULL; | ||
239 | /* go ahead and try by hostname resolution */ | ||
240 | } else { | ||
241 | struct hostent *hp = gethostbyname(address); | 237 | struct hostent *hp = gethostbyname(address); |
242 | struct in_addr **addr; | 238 | struct in_addr **addr; |
243 | if (!hp) return compat_hoststrerror(); | 239 | if (!hp) return compat_hoststrerror(); |
244 | addr = (struct in_addr **) hp->h_addr_list; | 240 | addr = (struct in_addr **) hp->h_addr_list; |
245 | for (; *addr != NULL; addr++) { | 241 | memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr)); |
246 | memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr)); | ||
247 | remote.sin_family = AF_INET; | ||
248 | remote.sin_port = htons(port); | ||
249 | err = inet_trysocket(inet, type); | ||
250 | if (err) return err; | ||
251 | if (compat_connect(inet->fd, (SA *)&remote, sizeof(remote)) < 0) { | ||
252 | compat_close(inet->fd); | ||
253 | inet->fd = COMPAT_INVALIDFD; | ||
254 | } else return NULL; | ||
255 | memset(&remote, 0, sizeof(remote)); | ||
256 | } | ||
257 | return compat_connectstrerror(); | ||
258 | } | 242 | } |
243 | compat_setblocking(inet->fd); | ||
244 | if (compat_connect(inet->fd, (SA *) &remote, sizeof(remote)) < 0) { | ||
245 | const char *err = compat_connectstrerror(); | ||
246 | compat_close(inet->fd); | ||
247 | inet->fd = COMPAT_INVALIDFD; | ||
248 | return err; | ||
249 | } | ||
250 | compat_setnonblocking(inet->fd); | ||
251 | return NULL; | ||
259 | } | 252 | } |
260 | 253 | ||
261 | /*-------------------------------------------------------------------------*\ | 254 | /*-------------------------------------------------------------------------*\ |
@@ -263,51 +256,34 @@ cchar *inet_tryconnect(p_inet inet, cchar *address, ushort port, | |||
263 | * Input | 256 | * Input |
264 | * address: host name or ip address | 257 | * address: host name or ip address |
265 | * port: port number to bind to | 258 | * port: port number to bind to |
266 | * backlog: backlog to set | ||
267 | * Returns | 259 | * Returns |
268 | * NULL in case of success, error message otherwise | 260 | * NULL in case of success, error message otherwise |
269 | \*-------------------------------------------------------------------------*/ | 261 | \*-------------------------------------------------------------------------*/ |
270 | cchar *inet_trybind(p_inet inet, cchar *address, ushort port, | 262 | cchar *inet_trybind(p_inet inet, cchar *address, ushort port) |
271 | int type) | ||
272 | { | 263 | { |
273 | struct sockaddr_in local; | 264 | struct sockaddr_in local; |
274 | cchar *err = NULL; | ||
275 | memset(&local, 0, sizeof(local)); | 265 | memset(&local, 0, sizeof(local)); |
276 | /* address is either wildcard or a valid ip address */ | 266 | /* address is either wildcard or a valid ip address */ |
277 | local.sin_addr.s_addr = htonl(INADDR_ANY); | 267 | local.sin_addr.s_addr = htonl(INADDR_ANY); |
278 | if (!strcmp(address, "*") || | 268 | local.sin_port = htons(port); |
279 | (strlen(address) && inet_aton(address, &local.sin_addr))) { | 269 | local.sin_family = AF_INET; |
280 | local.sin_port = htons(port); | 270 | if (strcmp(address, "*") && |
281 | local.sin_family = AF_INET; | 271 | (!strlen(address) || !inet_aton(address, &local.sin_addr))) { |
282 | err = inet_trysocket(inet, type); | ||
283 | if (err) return err; | ||
284 | compat_setreuseaddr(inet->fd); | ||
285 | if (compat_bind(inet->fd, (SA *) &local, sizeof(local)) < 0) { | ||
286 | compat_close(inet->fd); | ||
287 | inet->fd = COMPAT_INVALIDFD; | ||
288 | return compat_bindstrerror(); | ||
289 | } else return NULL; | ||
290 | /* otherwise, proceed with domain name resolution */ | ||
291 | } else { | ||
292 | struct hostent *hp = gethostbyname(address); | 272 | struct hostent *hp = gethostbyname(address); |
293 | struct in_addr **addr; | 273 | struct in_addr **addr; |
294 | if (!hp) return compat_hoststrerror(); | 274 | if (!hp) return compat_hoststrerror(); |
295 | addr = (struct in_addr **) hp->h_addr_list; | 275 | addr = (struct in_addr **) hp->h_addr_list; |
296 | for (; *addr != NULL; addr++) { | 276 | memcpy(&local.sin_addr, *addr, sizeof(struct in_addr)); |
297 | memcpy(&local.sin_addr, *addr, sizeof(struct in_addr)); | 277 | } |
298 | local.sin_port = htons(port); | 278 | compat_setblocking(inet->fd); |
299 | local.sin_family = AF_INET; | 279 | if (compat_bind(inet->fd, (SA *) &local, sizeof(local)) < 0) { |
300 | err = inet_trysocket(inet, type); | 280 | const char *err = compat_bindstrerror(); |
301 | if (err) return err; | 281 | compat_close(inet->fd); |
302 | compat_setreuseaddr(inet->fd); | 282 | inet->fd = COMPAT_INVALIDFD; |
303 | if (compat_bind(inet->fd, (SA *) &local, sizeof(local)) < 0) { | 283 | return err; |
304 | compat_close(inet->fd); | ||
305 | inet->fd = COMPAT_INVALIDFD; | ||
306 | } else return NULL; | ||
307 | memset(&local, 0, sizeof(local)); | ||
308 | } | ||
309 | return compat_bindstrerror(); | ||
310 | } | 284 | } |
285 | compat_setnonblocking(inet->fd); | ||
286 | return NULL; | ||
311 | } | 287 | } |
312 | 288 | ||
313 | /*-------------------------------------------------------------------------*\ | 289 | /*-------------------------------------------------------------------------*\ |