diff options
author | Diego Nehab <diego.nehab@gmail.com> | 2012-04-24 00:47:30 +0800 |
---|---|---|
committer | Diego Nehab <diego.nehab@gmail.com> | 2012-04-24 00:47:30 +0800 |
commit | c2e29537f576a7082247091036c7957479d42b21 (patch) | |
tree | fb6a4da9566e8413d824522ca9a7fb94de049b61 | |
parent | 1acf8188cd732de4fd5fcdc016eeab501c86a773 (diff) | |
download | luasocket-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-- | TODO | 6 | ||||
-rw-r--r-- | doc/index.html | 3 | ||||
-rw-r--r-- | doc/tcp.html | 11 | ||||
-rw-r--r-- | doc/udp.html | 18 | ||||
-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 |
8 files changed, 107 insertions, 62 deletions
@@ -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 | ||
17 | Done: | 16 | Done: |
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 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 |
138 | IPv6 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> |
228 | Returns a string with the IP address of the peer, followed by the | 228 | Returns a string with the IP address of the peer, the |
229 | port number that peer is using for the connection. | 229 | port number that peer is using for the connection, |
230 | and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>"). | ||
230 | In case of error, the method returns <b><tt>nil</tt></b>. | 231 | In 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> |
250 | The method returns a string with local IP address and a number with | 251 | The method returns a string with local IP address, a number with |
251 | the port. In case of error, the method returns <b><tt>nil</tt></b>. | 252 | the local port, |
253 | and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>"). | ||
254 | In 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 | |||
140 | associated with a connected UDP object. | 140 | associated with a connected UDP object. |
141 | </p> | 141 | </p> |
142 | 142 | ||
143 | <p class="return"> | 143 | |
144 | Returns the IP address and port number of the peer. | 144 | <p class=return> |
145 | Returns a string with the IP address of the peer, the | ||
146 | port number that peer is using for the connection, | ||
147 | and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>"). | ||
148 | In 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> | |||
159 | Returns the local address information associated to the object. | 163 | Returns the local address information associated to the object. |
160 | </p> | 164 | </p> |
161 | 165 | ||
162 | <p class="return"> | 166 | |
163 | The method returns a string with local IP | 167 | <p class=return> |
164 | address and a number with the port. In case of error, the method | 168 | The method returns a string with local IP address, a number with |
165 | returns <b><tt>nil</tt></b>. | 169 | the local port, |
170 | and a string with the family ("<tt>inet</tt>" or "<tt>inet6</tt>"). | ||
171 | In 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"> |
@@ -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 | /*-------------------------------------------------------------------------*\ |