Skip to content
This repository has been archived by the owner on Nov 20, 2020. It is now read-only.

Commit

Permalink
Fixed getpeername/getsockname situation
Browse files Browse the repository at this point in the history
- 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
diegonehab committed Apr 23, 2012
1 parent 1acf818 commit c2e2953
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 62 deletions.
6 changes: 5 additions & 1 deletion 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?
Expand All @@ -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?
Expand Down
3 changes: 2 additions & 1 deletion doc/index.html
Expand Up @@ -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;
Expand Down
11 changes: 7 additions & 4 deletions doc/tcp.html
Expand Up @@ -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>

Expand All @@ -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 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
Expand Down
18 changes: 12 additions & 6 deletions doc/udp.html
Expand Up @@ -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">
Expand All @@ -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">
Expand Down
117 changes: 74 additions & 43 deletions src/inet.c
Expand Up @@ -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;
}

/*=========================================================================*\
Expand Down
6 changes: 3 additions & 3 deletions src/inet.h
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/tcp.c
Expand Up @@ -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);
}

/*-------------------------------------------------------------------------*\
Expand Down
4 changes: 2 additions & 2 deletions src/udp.c
Expand Up @@ -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);
}

/*-------------------------------------------------------------------------*\
Expand Down

0 comments on commit c2e2953

Please sign in to comment.