aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Nehab <diego.nehab@gmail.com>2012-04-24 00:47:30 +0800
committerDiego Nehab <diego.nehab@gmail.com>2012-04-24 00:47:30 +0800
commitc2e29537f576a7082247091036c7957479d42b21 (patch)
treefb6a4da9566e8413d824522ca9a7fb94de049b61
parent1acf8188cd732de4fd5fcdc016eeab501c86a773 (diff)
downloadluasocket-c2e29537f576a7082247091036c7957479d42b21.tar.gz
luasocket-c2e29537f576a7082247091036c7957479d42b21.tar.bz2
luasocket-c2e29537f576a7082247091036c7957479d42b21.zip
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
-rw-r--r--TODO6
-rw-r--r--doc/index.html3
-rw-r--r--doc/tcp.html11
-rw-r--r--doc/udp.html18
-rw-r--r--src/inet.c117
-rw-r--r--src/inet.h6
-rw-r--r--src/tcp.c4
-rw-r--r--src/udp.c4
8 files changed, 107 insertions, 62 deletions
diff --git a/TODO b/TODO
index ae290f2..2c68d67 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,4 @@
1- document bind and connect behavior. 1- document bind and connect behavior.
2- getsockname should also support IPv6, no?
3- shouldn't we instead make the code compatible to Lua 5.2 2- shouldn't we instead make the code compatible to Lua 5.2
4 without any compat stuff, and use a compatibility layer to 3 without any compat stuff, and use a compatibility layer to
5 make it work on 5.1? 4 make it work on 5.1?
@@ -16,6 +15,11 @@
16 15
17Done: 16Done:
18 17
18- added IPv6 support to getsockname
19- simplified getpeername implementation
20- added family to return of getsockname and getpeername
21 and added modification to the manual to describe
22
19- connect and bind try all adresses returned by getaddrinfo 23- connect and bind try all adresses returned by getaddrinfo
20- document headers.lua? 24- document headers.lua?
21- update copyright date everywhere? 25- update copyright date everywhere?
diff --git a/doc/index.html b/doc/index.html
index 833c9a8..56c958f 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -134,7 +134,8 @@ and Lua&nbsp;5.2 compatibility.
134<li> Added: IPv6 support; 134<li> Added: IPv6 support;
135<ul> 135<ul>
136<li> <tt>Socket.connect</tt> and <tt>socket.bind</tt> support IPv6 addresses; 136<li> <tt>Socket.connect</tt> and <tt>socket.bind</tt> support IPv6 addresses;
137<li> <tt>Getpeername</tt> and <tt>getsockname</tt> support IPv6 addresses; 137<li> <tt>Getpeername</tt> and <tt>getsockname</tt> support
138IPv6 addresses, and return the socket family as a third value;
138<li> URL module updated to support IPv6 host names; 139<li> URL module updated to support IPv6 host names;
139<li> New <tt>socket.tcp6</tt> and <tt>socket.udp6</tt> functions; 140<li> New <tt>socket.tcp6</tt> and <tt>socket.udp6</tt> functions;
140<li> New <tt>socket.dns.getaddrinfo</tt> function; 141<li> New <tt>socket.dns.getaddrinfo</tt> function;
diff --git a/doc/tcp.html b/doc/tcp.html
index dc1a0b6..5f39d0e 100644
--- a/doc/tcp.html
+++ b/doc/tcp.html
@@ -225,8 +225,9 @@ Returns information about the remote side of a connected client object.
225</p> 225</p>
226 226
227<p class=return> 227<p class=return>
228Returns a string with the IP address of the peer, followed by the 228Returns a string with the IP address of the peer, the
229port number that peer is using for the connection. 229port number that peer is using for the connection,
230and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>").
230In case of error, the method returns <b><tt>nil</tt></b>. 231In case of error, the method returns <b><tt>nil</tt></b>.
231</p> 232</p>
232 233
@@ -247,8 +248,10 @@ Returns the local address information associated to the object.
247</p> 248</p>
248 249
249<p class=return> 250<p class=return>
250The method returns a string with local IP address and a number with 251The method returns a string with local IP address, a number with
251the port. In case of error, the method returns <b><tt>nil</tt></b>. 252the local port,
253and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>").
254In case of error, the method returns <b><tt>nil</tt></b>.
252</p> 255</p>
253 256
254<!-- getstats +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 257<!-- getstats +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
diff --git a/doc/udp.html b/doc/udp.html
index 4a334b7..554fa31 100644
--- a/doc/udp.html
+++ b/doc/udp.html
@@ -140,8 +140,12 @@ Retrieves information about the peer
140associated with a connected UDP object. 140associated with a connected UDP object.
141</p> 141</p>
142 142
143<p class="return"> 143
144Returns the IP address and port number of the peer. 144<p class=return>
145Returns a string with the IP address of the peer, the
146port number that peer is using for the connection,
147and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>").
148In case of error, the method returns <b><tt>nil</tt></b>.
145</p> 149</p>
146 150
147<p class="note"> 151<p class="note">
@@ -159,10 +163,12 @@ unconnected:<b>getsockname()</b>
159Returns the local address information associated to the object. 163Returns the local address information associated to the object.
160</p> 164</p>
161 165
162<p class="return"> 166
163The method returns a string with local IP 167<p class=return>
164address and a number with the port. In case of error, the method 168The method returns a string with local IP address, a number with
165returns <b><tt>nil</tt></b>. 169the local port,
170and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>").
171In case of error, the method returns <b><tt>nil</tt></b>.
166</p> 172</p>
167 173
168<p class="note"> 174<p class="note">
diff --git a/src/inet.c b/src/inet.c
index fd16506..5823c36 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -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\*-------------------------------------------------------------------------*/
168int inet_meth_getpeername(lua_State *L, p_socket ps) 168int 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\*-------------------------------------------------------------------------*/
211int inet_meth_getsockname(lua_State *L, p_socket ps) 214int 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/*=========================================================================*\
diff --git a/src/inet.h b/src/inet.h
index 0f32ff1..1cbe4f4 100644
--- a/src/inet.h
+++ b/src/inet.h
@@ -24,14 +24,14 @@
24 24
25int inet_open(lua_State *L); 25int inet_open(lua_State *L);
26 26
27const char *inet_trycreate(p_socket ps, int domain, int type); 27const char *inet_trycreate(p_socket ps, int family, int type);
28const char *inet_tryconnect(p_socket ps, const char *address, 28const 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);
30const char *inet_trybind(p_socket ps, const char *address, const char *serv, 30const char *inet_trybind(p_socket ps, const char *address, const char *serv,
31 struct addrinfo *bindhints); 31 struct addrinfo *bindhints);
32 32
33int inet_meth_getpeername(lua_State *L, p_socket ps); 33int inet_meth_getpeername(lua_State *L, p_socket ps, int family);
34int inet_meth_getsockname(lua_State *L, p_socket ps); 34int inet_meth_getsockname(lua_State *L, p_socket ps, int family);
35 35
36#ifdef INET_ATON 36#ifdef INET_ATON
37int inet_aton(const char *cp, struct in_addr *inp); 37int inet_aton(const char *cp, struct in_addr *inp);
diff --git a/src/tcp.c b/src/tcp.c
index 872b1c6..9e1e2bd 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -337,13 +337,13 @@ error:
337static int meth_getpeername(lua_State *L) 337static 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
343static int meth_getsockname(lua_State *L) 343static 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/*-------------------------------------------------------------------------*\
diff --git a/src/udp.c b/src/udp.c
index bfa934f..0241cc5 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -269,12 +269,12 @@ static int meth_dirty(lua_State *L) {
269\*-------------------------------------------------------------------------*/ 269\*-------------------------------------------------------------------------*/
270static int meth_getpeername(lua_State *L) { 270static 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
275static int meth_getsockname(lua_State *L) { 275static 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/*-------------------------------------------------------------------------*\