Permalink
Browse files

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
  • Loading branch information...
1 parent 1acf818 commit c2e29537f576a7082247091036c7957479d42b21 @diegonehab diegonehab committed Apr 23, 2012
Showing with 107 additions and 62 deletions.
  1. +5 −1 TODO
  2. +2 −1 doc/index.html
  3. +7 −4 doc/tcp.html
  4. +12 −6 doc/udp.html
  5. +74 −43 src/inet.c
  6. +3 −3 src/inet.h
  7. +2 −2 src/tcp.c
  8. +2 −2 src/udp.c
View
6 TODO
@@ -1,5 +1,4 @@
- document bind and connect behavior.
-- getsockname should also support IPv6, no?
- shouldn't we instead make the code compatible to Lua 5.2
without any compat stuff, and use a compatibility layer to
make it work on 5.1?
@@ -16,6 +15,11 @@
Done:
+- added IPv6 support to getsockname
+- simplified getpeername implementation
+- added family to return of getsockname and getpeername
+ and added modification to the manual to describe
+
- connect and bind try all adresses returned by getaddrinfo
- document headers.lua?
- update copyright date everywhere?
View
@@ -134,7 +134,8 @@ <h2 id=new>What's New</h2>
<li> Added: IPv6 support;
<ul>
<li> <tt>Socket.connect</tt> and <tt>socket.bind</tt> support IPv6 addresses;
-<li> <tt>Getpeername</tt> and <tt>getsockname</tt> support IPv6 addresses;
+<li> <tt>Getpeername</tt> and <tt>getsockname</tt> support
+IPv6 addresses, and return the socket family as a third value;
<li> URL module updated to support IPv6 host names;
<li> New <tt>socket.tcp6</tt> and <tt>socket.udp6</tt> functions;
<li> New <tt>socket.dns.getaddrinfo</tt> function;
View
@@ -225,8 +225,9 @@ <h2 id="tcp">TCP</h2>
</p>
<p class=return>
-Returns a string with the IP address of the peer, followed by the
-port number that peer is using for the connection.
+Returns a string with the IP address of the peer, the
+port number that peer is using for the connection,
+and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>").
In case of error, the method returns <b><tt>nil</tt></b>.
</p>
@@ -247,8 +248,10 @@ <h2 id="tcp">TCP</h2>
</p>
<p class=return>
-The method returns a string with local IP address and a number with
-the port. In case of error, the method returns <b><tt>nil</tt></b>.
+The method returns a string with local IP address, a number with
+the local port,
+and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>").
+In case of error, the method returns <b><tt>nil</tt></b>.
</p>
<!-- getstats +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
View
@@ -140,8 +140,12 @@ <h2 id="udp">UDP</h2>
associated with a connected UDP object.
</p>
-<p class="return">
-Returns the IP address and port number of the peer.
+
+<p class=return>
+Returns a string with the IP address of the peer, the
+port number that peer is using for the connection,
+and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>").
+In case of error, the method returns <b><tt>nil</tt></b>.
</p>
<p class="note">
@@ -159,10 +163,12 @@ <h2 id="udp">UDP</h2>
Returns the local address information associated to the object.
</p>
-<p class="return">
-The method returns a string with local IP
-address and a number with the port. In case of error, the method
-returns <b><tt>nil</tt></b>.
+
+<p class=return>
+The method returns a string with local IP address, a number with
+the local port,
+and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>").
+In case of error, the method returns <b><tt>nil</tt></b>.
</p>
<p class="note">
View
@@ -165,61 +165,92 @@ static int inet_global_gethostname(lua_State *L)
/*-------------------------------------------------------------------------*\
* Retrieves socket peer name
\*-------------------------------------------------------------------------*/
-int inet_meth_getpeername(lua_State *L, p_socket ps)
+int inet_meth_getpeername(lua_State *L, p_socket ps, int family)
{
- union {
- struct sockaddr_storage sas;
- struct sockaddr sa;
- struct sockaddr_in sa4;
- struct sockaddr_in6 sa6;
- } peer;
- socklen_t peer_len = sizeof(peer);
-
- if (getpeername(*ps, &peer.sa, &peer_len) < 0) {
- lua_pushnil(L);
- lua_pushfstring(L, "getpeername failed (%d): %s", errno,
- strerror(errno));
- } else {
- char ipaddr[INET6_ADDRSTRLEN] = "";
- unsigned short port = 0;
-
- switch (peer.sa.sa_family) {
- case AF_INET:
- inet_ntop(AF_INET, &peer.sa4.sin_addr, ipaddr, sizeof(ipaddr));
- port = ntohs(peer.sa4.sin_port);
- break;
- case AF_INET6:
- inet_ntop(AF_INET6, &peer.sa6.sin6_addr, ipaddr, sizeof(ipaddr));
- port = ntohs(peer.sa6.sin6_port);
- break;
+ switch (family) {
+ case PF_INET: {
+ struct sockaddr_in peer;
+ socklen_t peer_len = sizeof(peer);
+ char name[INET_ADDRSTRLEN];
+ if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
+ lua_pushnil(L);
+ lua_pushstring(L, "getpeername failed");
+ return 2;
+ } else {
+ inet_ntop(family, &peer.sin_addr, name, sizeof(name));
+ lua_pushstring(L, name);
+ lua_pushnumber(L, ntohs(peer.sin_port));
+ lua_pushliteral(L, "inet");
+ return 3;
+ }
+ }
+ case PF_INET6: {
+ struct sockaddr_in6 peer;
+ socklen_t peer_len = sizeof(peer);
+ char name[INET6_ADDRSTRLEN];
+ if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
+ lua_pushnil(L);
+ lua_pushstring(L, "getpeername failed");
+ return 2;
+ } else {
+ inet_ntop(family, &peer.sin6_addr, name, sizeof(name));
+ lua_pushstring(L, name);
+ lua_pushnumber(L, ntohs(peer.sin6_port));
+ lua_pushliteral(L, "inet6");
+ return 3;
+ }
+ return 2;
+ }
default:
lua_pushnil(L);
- lua_pushfstring(L, "Unknown address family %d", peer.sa.sa_family);
+ lua_pushstring(L, "unknown family");
return 2;
- break;
- }
-
- lua_pushstring(L, ipaddr);
- lua_pushnumber(L, port);
}
- return 2;
}
/*-------------------------------------------------------------------------*\
* Retrieves socket local name
\*-------------------------------------------------------------------------*/
-int inet_meth_getsockname(lua_State *L, p_socket ps)
+int inet_meth_getsockname(lua_State *L, p_socket ps, int family)
{
- struct sockaddr_in local;
- socklen_t local_len = sizeof(local);
- if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
- lua_pushnil(L);
- lua_pushstring(L, "getsockname failed");
- } else {
- lua_pushstring(L, inet_ntoa(local.sin_addr));
- lua_pushnumber(L, ntohs(local.sin_port));
+ switch (family) {
+ case PF_INET: {
+ struct sockaddr_in local;
+ socklen_t local_len = sizeof(local);
+ char name[INET_ADDRSTRLEN];
+ if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
+ lua_pushnil(L);
+ lua_pushstring(L, "getsockname failed");
+ return 2;
+ } else {
+ inet_ntop(family, &local.sin_addr, name, sizeof(name));
+ lua_pushstring(L, name);
+ lua_pushnumber(L, ntohs(local.sin_port));
+ lua_pushliteral(L, "inet");
+ return 3;
+ }
+ }
+ case PF_INET6: {
+ struct sockaddr_in6 local;
+ socklen_t local_len = sizeof(local);
+ char name[INET6_ADDRSTRLEN];
+ if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
+ lua_pushnil(L);
+ lua_pushstring(L, "getsockname failed");
+ return 2;
+ } else {
+ inet_ntop(family, &local.sin6_addr, name, sizeof(name));
+ lua_pushstring(L, name);
+ lua_pushnumber(L, ntohs(local.sin6_port));
+ lua_pushliteral(L, "inet6");
+ return 3;
+ }
+ }
+ default:
+ lua_pushnil(L);
+ lua_pushstring(L, "unknown family");
+ return 2;
}
- return 2;
}
/*=========================================================================*\
View
@@ -24,14 +24,14 @@
int inet_open(lua_State *L);
-const char *inet_trycreate(p_socket ps, int domain, int type);
+const char *inet_trycreate(p_socket ps, int family, int type);
const char *inet_tryconnect(p_socket ps, const char *address,
const char *serv, p_timeout tm, struct addrinfo *connecthints);
const char *inet_trybind(p_socket ps, const char *address, const char *serv,
struct addrinfo *bindhints);
-int inet_meth_getpeername(lua_State *L, p_socket ps);
-int inet_meth_getsockname(lua_State *L, p_socket ps);
+int inet_meth_getpeername(lua_State *L, p_socket ps, int family);
+int inet_meth_getsockname(lua_State *L, p_socket ps, int family);
#ifdef INET_ATON
int inet_aton(const char *cp, struct in_addr *inp);
View
@@ -337,13 +337,13 @@ static int meth_shutdown(lua_State *L)
static int meth_getpeername(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
- return inet_meth_getpeername(L, &tcp->sock);
+ return inet_meth_getpeername(L, &tcp->sock, tcp->family);
}
static int meth_getsockname(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
- return inet_meth_getsockname(L, &tcp->sock);
+ return inet_meth_getsockname(L, &tcp->sock, tcp->family);
}
/*-------------------------------------------------------------------------*\
View
@@ -269,12 +269,12 @@ static int meth_dirty(lua_State *L) {
\*-------------------------------------------------------------------------*/
static int meth_getpeername(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1);
- return inet_meth_getpeername(L, &udp->sock);
+ return inet_meth_getpeername(L, &udp->sock, udp->family);
}
static int meth_getsockname(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
- return inet_meth_getsockname(L, &udp->sock);
+ return inet_meth_getsockname(L, &udp->sock, udp->family);
}
/*-------------------------------------------------------------------------*\

0 comments on commit c2e2953

Please sign in to comment.