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 | /*-------------------------------------------------------------------------*\ |
