diff options
| author | Diego Nehab <diego.nehab@gmail.com> | 2012-04-24 00:47:30 +0800 |
|---|---|---|
| committer | Diego Nehab <diego.nehab@gmail.com> | 2012-04-24 00:47:30 +0800 |
| commit | c2e29537f576a7082247091036c7957479d42b21 (patch) | |
| tree | fb6a4da9566e8413d824522ca9a7fb94de049b61 /src | |
| parent | 1acf8188cd732de4fd5fcdc016eeab501c86a773 (diff) | |
| download | luasocket-c2e29537f576a7082247091036c7957479d42b21.tar.gz luasocket-c2e29537f576a7082247091036c7957479d42b21.tar.bz2 luasocket-c2e29537f576a7082247091036c7957479d42b21.zip | |
Fixed getpeername/getsockname situation
- Added IPv6 support to getsockname
- Simplified getpeername implementation
- Added family to return of getsockname and getpeername
and added modification to the manual to describe
Diffstat (limited to 'src')
| -rw-r--r-- | src/inet.c | 117 | ||||
| -rw-r--r-- | src/inet.h | 6 | ||||
| -rw-r--r-- | src/tcp.c | 4 | ||||
| -rw-r--r-- | src/udp.c | 4 |
4 files changed, 81 insertions, 50 deletions
| @@ -165,61 +165,92 @@ static int inet_global_gethostname(lua_State *L) | |||
| 165 | /*-------------------------------------------------------------------------*\ | 165 | /*-------------------------------------------------------------------------*\ |
| 166 | * Retrieves socket peer name | 166 | * Retrieves socket peer name |
| 167 | \*-------------------------------------------------------------------------*/ | 167 | \*-------------------------------------------------------------------------*/ |
| 168 | int inet_meth_getpeername(lua_State *L, p_socket ps) | 168 | int inet_meth_getpeername(lua_State *L, p_socket ps, int family) |
| 169 | { | 169 | { |
| 170 | union { | 170 | switch (family) { |
| 171 | struct sockaddr_storage sas; | 171 | case PF_INET: { |
| 172 | struct sockaddr sa; | 172 | struct sockaddr_in peer; |
| 173 | struct sockaddr_in sa4; | 173 | socklen_t peer_len = sizeof(peer); |
| 174 | struct sockaddr_in6 sa6; | 174 | char name[INET_ADDRSTRLEN]; |
| 175 | } peer; | 175 | if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { |
| 176 | socklen_t peer_len = sizeof(peer); | 176 | lua_pushnil(L); |
| 177 | 177 | lua_pushstring(L, "getpeername failed"); | |
| 178 | if (getpeername(*ps, &peer.sa, &peer_len) < 0) { | 178 | return 2; |
| 179 | lua_pushnil(L); | 179 | } else { |
| 180 | lua_pushfstring(L, "getpeername failed (%d): %s", errno, | 180 | inet_ntop(family, &peer.sin_addr, name, sizeof(name)); |
| 181 | strerror(errno)); | 181 | lua_pushstring(L, name); |
| 182 | } else { | 182 | lua_pushnumber(L, ntohs(peer.sin_port)); |
| 183 | char ipaddr[INET6_ADDRSTRLEN] = ""; | 183 | lua_pushliteral(L, "inet"); |
| 184 | unsigned short port = 0; | 184 | return 3; |
| 185 | 185 | } | |
| 186 | switch (peer.sa.sa_family) { | 186 | } |
| 187 | case AF_INET: | 187 | case PF_INET6: { |
| 188 | inet_ntop(AF_INET, &peer.sa4.sin_addr, ipaddr, sizeof(ipaddr)); | 188 | struct sockaddr_in6 peer; |
| 189 | port = ntohs(peer.sa4.sin_port); | 189 | socklen_t peer_len = sizeof(peer); |
| 190 | break; | 190 | char name[INET6_ADDRSTRLEN]; |
| 191 | case AF_INET6: | 191 | if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { |
| 192 | inet_ntop(AF_INET6, &peer.sa6.sin6_addr, ipaddr, sizeof(ipaddr)); | 192 | lua_pushnil(L); |
| 193 | port = ntohs(peer.sa6.sin6_port); | 193 | lua_pushstring(L, "getpeername failed"); |
| 194 | break; | 194 | return 2; |
| 195 | } else { | ||
| 196 | inet_ntop(family, &peer.sin6_addr, name, sizeof(name)); | ||
| 197 | lua_pushstring(L, name); | ||
| 198 | lua_pushnumber(L, ntohs(peer.sin6_port)); | ||
| 199 | lua_pushliteral(L, "inet6"); | ||
| 200 | return 3; | ||
| 201 | } | ||
| 202 | return 2; | ||
| 203 | } | ||
| 195 | default: | 204 | default: |
| 196 | lua_pushnil(L); | 205 | lua_pushnil(L); |
| 197 | lua_pushfstring(L, "Unknown address family %d", peer.sa.sa_family); | 206 | lua_pushstring(L, "unknown family"); |
| 198 | return 2; | 207 | return 2; |
| 199 | break; | ||
| 200 | } | ||
| 201 | |||
| 202 | lua_pushstring(L, ipaddr); | ||
| 203 | lua_pushnumber(L, port); | ||
| 204 | } | 208 | } |
| 205 | return 2; | ||
| 206 | } | 209 | } |
| 207 | 210 | ||
| 208 | /*-------------------------------------------------------------------------*\ | 211 | /*-------------------------------------------------------------------------*\ |
| 209 | * Retrieves socket local name | 212 | * Retrieves socket local name |
| 210 | \*-------------------------------------------------------------------------*/ | 213 | \*-------------------------------------------------------------------------*/ |
| 211 | int inet_meth_getsockname(lua_State *L, p_socket ps) | 214 | int inet_meth_getsockname(lua_State *L, p_socket ps, int family) |
| 212 | { | 215 | { |
| 213 | struct sockaddr_in local; | 216 | switch (family) { |
| 214 | socklen_t local_len = sizeof(local); | 217 | case PF_INET: { |
| 215 | if (getsockname(*ps, (SA *) &local, &local_len) < 0) { | 218 | struct sockaddr_in local; |
| 216 | lua_pushnil(L); | 219 | socklen_t local_len = sizeof(local); |
| 217 | lua_pushstring(L, "getsockname failed"); | 220 | char name[INET_ADDRSTRLEN]; |
| 218 | } else { | 221 | if (getsockname(*ps, (SA *) &local, &local_len) < 0) { |
| 219 | lua_pushstring(L, inet_ntoa(local.sin_addr)); | 222 | lua_pushnil(L); |
| 220 | lua_pushnumber(L, ntohs(local.sin_port)); | 223 | lua_pushstring(L, "getsockname failed"); |
| 224 | return 2; | ||
| 225 | } else { | ||
| 226 | inet_ntop(family, &local.sin_addr, name, sizeof(name)); | ||
| 227 | lua_pushstring(L, name); | ||
| 228 | lua_pushnumber(L, ntohs(local.sin_port)); | ||
| 229 | lua_pushliteral(L, "inet"); | ||
| 230 | return 3; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | case PF_INET6: { | ||
| 234 | struct sockaddr_in6 local; | ||
| 235 | socklen_t local_len = sizeof(local); | ||
| 236 | char name[INET6_ADDRSTRLEN]; | ||
| 237 | if (getsockname(*ps, (SA *) &local, &local_len) < 0) { | ||
| 238 | lua_pushnil(L); | ||
| 239 | lua_pushstring(L, "getsockname failed"); | ||
| 240 | return 2; | ||
| 241 | } else { | ||
| 242 | inet_ntop(family, &local.sin6_addr, name, sizeof(name)); | ||
| 243 | lua_pushstring(L, name); | ||
| 244 | lua_pushnumber(L, ntohs(local.sin6_port)); | ||
| 245 | lua_pushliteral(L, "inet6"); | ||
| 246 | return 3; | ||
| 247 | } | ||
| 248 | } | ||
| 249 | default: | ||
| 250 | lua_pushnil(L); | ||
| 251 | lua_pushstring(L, "unknown family"); | ||
| 252 | return 2; | ||
| 221 | } | 253 | } |
| 222 | return 2; | ||
| 223 | } | 254 | } |
| 224 | 255 | ||
| 225 | /*=========================================================================*\ | 256 | /*=========================================================================*\ |
| @@ -24,14 +24,14 @@ | |||
| 24 | 24 | ||
| 25 | int inet_open(lua_State *L); | 25 | int inet_open(lua_State *L); |
| 26 | 26 | ||
| 27 | const char *inet_trycreate(p_socket ps, int domain, int type); | 27 | const char *inet_trycreate(p_socket ps, int family, int type); |
| 28 | const char *inet_tryconnect(p_socket ps, const char *address, | 28 | const char *inet_tryconnect(p_socket ps, const char *address, |
| 29 | const char *serv, p_timeout tm, struct addrinfo *connecthints); | 29 | const char *serv, p_timeout tm, struct addrinfo *connecthints); |
| 30 | const char *inet_trybind(p_socket ps, const char *address, const char *serv, | 30 | const char *inet_trybind(p_socket ps, const char *address, const char *serv, |
| 31 | struct addrinfo *bindhints); | 31 | struct addrinfo *bindhints); |
| 32 | 32 | ||
| 33 | int inet_meth_getpeername(lua_State *L, p_socket ps); | 33 | int inet_meth_getpeername(lua_State *L, p_socket ps, int family); |
| 34 | int inet_meth_getsockname(lua_State *L, p_socket ps); | 34 | int inet_meth_getsockname(lua_State *L, p_socket ps, int family); |
| 35 | 35 | ||
| 36 | #ifdef INET_ATON | 36 | #ifdef INET_ATON |
| 37 | int inet_aton(const char *cp, struct in_addr *inp); | 37 | int inet_aton(const char *cp, struct in_addr *inp); |
| @@ -337,13 +337,13 @@ error: | |||
| 337 | static int meth_getpeername(lua_State *L) | 337 | static int meth_getpeername(lua_State *L) |
| 338 | { | 338 | { |
| 339 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | 339 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); |
| 340 | return inet_meth_getpeername(L, &tcp->sock); | 340 | return inet_meth_getpeername(L, &tcp->sock, tcp->family); |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | static int meth_getsockname(lua_State *L) | 343 | static int meth_getsockname(lua_State *L) |
| 344 | { | 344 | { |
| 345 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | 345 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); |
| 346 | return inet_meth_getsockname(L, &tcp->sock); | 346 | return inet_meth_getsockname(L, &tcp->sock, tcp->family); |
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | /*-------------------------------------------------------------------------*\ | 349 | /*-------------------------------------------------------------------------*\ |
| @@ -269,12 +269,12 @@ static int meth_dirty(lua_State *L) { | |||
| 269 | \*-------------------------------------------------------------------------*/ | 269 | \*-------------------------------------------------------------------------*/ |
| 270 | static int meth_getpeername(lua_State *L) { | 270 | static int meth_getpeername(lua_State *L) { |
| 271 | p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1); | 271 | p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1); |
| 272 | return inet_meth_getpeername(L, &udp->sock); | 272 | return inet_meth_getpeername(L, &udp->sock, udp->family); |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | static int meth_getsockname(lua_State *L) { | 275 | static int meth_getsockname(lua_State *L) { |
| 276 | p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | 276 | p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); |
| 277 | return inet_meth_getsockname(L, &udp->sock); | 277 | return inet_meth_getsockname(L, &udp->sock, udp->family); |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | /*-------------------------------------------------------------------------*\ | 280 | /*-------------------------------------------------------------------------*\ |
