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