mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-25 12:08:21 +01:00
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
This commit is contained in:
parent
1acf8188cd
commit
c2e29537f5
6
TODO
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?
|
||||
|
@ -134,7 +134,8 @@ and Lua 5.2 compatibility.
|
||||
<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;
|
||||
|
11
doc/tcp.html
11
doc/tcp.html
@ -225,8 +225,9 @@ Returns information about the remote side of a connected client object.
|
||||
</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 @@ 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>.
|
||||
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 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||
|
18
doc/udp.html
18
doc/udp.html
@ -140,8 +140,12 @@ Retrieves information about the peer
|
||||
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 @@ unconnected:<b>getsockname()</b>
|
||||
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">
|
||||
|
117
src/inet.c
117
src/inet.c
@ -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;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
|
@ -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);
|
||||
|
@ -337,13 +337,13 @@ error:
|
||||
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);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
|
Loading…
Reference in New Issue
Block a user