diff options
-rw-r--r-- | src/inet.c | 23 |
1 files changed, 18 insertions, 5 deletions
@@ -169,14 +169,27 @@ static int inet_global_gethostname(lua_State *L) | |||
169 | \*-------------------------------------------------------------------------*/ | 169 | \*-------------------------------------------------------------------------*/ |
170 | int inet_meth_getpeername(lua_State *L, p_socket ps) | 170 | int inet_meth_getpeername(lua_State *L, p_socket ps) |
171 | { | 171 | { |
172 | struct sockaddr_in peer; | 172 | struct sockaddr *peer; |
173 | socklen_t peer_len = sizeof(peer); | 173 | socklen_t peer_len = sizeof(struct sockaddr_storage); |
174 | if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { | 174 | char ipaddr[INET6_ADDRSTRLEN]; |
175 | |||
176 | peer = (struct sockaddr *) malloc(peer_len); | ||
177 | if (!peer || (getpeername(*ps, (SA *) peer, &peer_len) < 0)) { | ||
175 | lua_pushnil(L); | 178 | lua_pushnil(L); |
176 | lua_pushstring(L, "getpeername failed"); | 179 | lua_pushstring(L, "getpeername failed"); |
177 | } else { | 180 | } else { |
178 | lua_pushstring(L, inet_ntoa(peer.sin_addr)); | 181 | if (peer->sa_family == AF_INET) |
179 | lua_pushnumber(L, ntohs(peer.sin_port)); | 182 | inet_ntop(AF_INET, &((struct sockaddr_in *)peer)->sin_addr, |
183 | ipaddr, sizeof(ipaddr)); | ||
184 | else if (peer->sa_family == AF_INET6) | ||
185 | inet_ntop(AF_INET6, &((struct sockaddr_in6 *)peer)->sin6_addr, | ||
186 | ipaddr, sizeof(ipaddr)); | ||
187 | lua_pushstring(L, ipaddr); | ||
188 | if (peer->sa_family == AF_INET) | ||
189 | lua_pushnumber(L, ntohs(((struct sockaddr_in *)peer)->sin_port)); | ||
190 | else if (peer->sa_family == AF_INET6) | ||
191 | lua_pushnumber(L, ntohs(((struct sockaddr_in6 *)peer)->sin6_port)); | ||
192 | free(peer); | ||
180 | } | 193 | } |
181 | return 2; | 194 | return 2; |
182 | } | 195 | } |