socket.bind also tries all addresses returned by getaddrinfo.

This commit is contained in:
Diego Nehab 2012-04-23 01:40:31 +08:00
parent 966642f76a
commit 1acf8188cd
2 changed files with 25 additions and 14 deletions

3
TODO
View File

@ -1,3 +1,4 @@
- document bind and connect behavior.
- getsockname should also support IPv6, no? - getsockname should also support IPv6, no?
- shouldn't we instead make the code compatible to Lua 5.2 - shouldn't we instead make the code compatible to Lua 5.2
without any compat stuff, and use a compatibility layer to without any compat stuff, and use a compatibility layer to
@ -5,7 +6,6 @@
- add what's new to manual - add what's new to manual
- should there be an equivalent to tohostname for IPv6? - should there be an equivalent to tohostname for IPv6?
- should we add service name resolution as well to getaddrinfo? - should we add service name resolution as well to getaddrinfo?
- document bind and connect behavior based on address?
- add http POST sample to manual - add http POST sample to manual
people keep asking stupid questions people keep asking stupid questions
@ -16,6 +16,7 @@
Done: Done:
- connect and bind try all adresses returned by getaddrinfo
- document headers.lua? - document headers.lua?
- update copyright date everywhere? - update copyright date everywhere?
- remove RCSID from files? - remove RCSID from files?

View File

@ -19,8 +19,8 @@ function connect(address, port, laddress, lport)
if address == "*" then address = "0.0.0.0" end if address == "*" then address = "0.0.0.0" end
local addrinfo, err = socket.dns.getaddrinfo(address); local addrinfo, err = socket.dns.getaddrinfo(address);
if not addrinfo then return nil, err end if not addrinfo then return nil, err end
local err = "no info on address"
local sock, res local sock, res
err = "no info on address"
for i, alt in base.ipairs(addrinfo) do for i, alt in base.ipairs(addrinfo) do
if alt.family == "inet" then if alt.family == "inet" then
sock, err = socket.tcp() sock, err = socket.tcp()
@ -49,19 +49,29 @@ function bind(host, port, backlog)
if host == "*" then host = "0.0.0.0" end if host == "*" then host = "0.0.0.0" end
local addrinfo, err = socket.dns.getaddrinfo(host); local addrinfo, err = socket.dns.getaddrinfo(host);
if not addrinfo then return nil, err end if not addrinfo then return nil, err end
local sock, err; local sock, res
if addrinfo[1].family == "inet" then err = "no info on address"
for i, alt in base.ipairs(addrinfo) do
if alt.family == "inet" then
sock, err = socket.tcp() sock, err = socket.tcp()
else else
sock, err = socket.tcp6() sock, err = socket.tcp6()
end end
if not sock then return nil, err end if not sock then return nil, err end
sock:setoption("reuseaddr", true) sock:setoption("reuseaddr", true)
local res, err = sock:bind(host, port) res, err = sock:bind(alt.addr, port)
if not res then return nil, err end if not res then
sock:close()
else
res, err = sock:listen(backlog) res, err = sock:listen(backlog)
if not res then return nil, err end if not res then
sock:close()
else
return sock return sock
end
end
end
return nil, err
end end
try = newtry() try = newtry()