# HG changeset patch # User Florian Zeitz # Date 1308174258 -7200 # Node ID aff627b1ce959f7e56da28577b0b8f28c39b43af # Parent 4dcdba6900f2a18fa60e68f638b16bc78ace0a06 connlistener, server_select, prosody: Add support for binding to multiple addresses diff -r 4dcdba6900f2 -r aff627b1ce95 net/connlisteners.lua --- a/net/connlisteners.lua Sun Jun 12 22:21:10 2011 +0100 +++ b/net/connlisteners.lua Wed Jun 15 23:44:18 2011 +0200 @@ -12,6 +12,8 @@ local server = require "net.server"; local log = require "util.logger".init("connlisteners"); local tostring = tostring; +local type = type +local ipairs = ipairs local dofile, xpcall, error = dofile, xpcall, error @@ -55,7 +57,8 @@ error("No such connection module: "..name.. (err and (" ("..err..")") or ""), 0); end - local interface = (udata and udata.interface) or h.default_interface or "*"; + local interfaces = (udata and udata.interface) or h.default_interface or "*"; + if type(interfaces) == "string" then interfaces = {interfaces}; end local port = (udata and udata.port) or h.default_port or error("Can't start listener "..name.." because no port was specified, and it has no default port", 0); local mode = (udata and udata.mode) or h.default_mode or 1; local ssl = (udata and udata.ssl) or nil; @@ -64,8 +67,15 @@ if autossl and not ssl then return nil, "no ssl context"; end - - return server.addserver(interface, port, h, mode, autossl and ssl or nil); + + ok, err = true, {}; + for _, interface in ipairs(interfaces) do + local handler + handler, err[interface] = server.addserver(interface, port, h, mode, autossl and ssl or nil); + ok = ok and handler; + end + + return ok, err; end return _M; diff -r 4dcdba6900f2 -r aff627b1ce95 net/server_select.lua --- a/net/server_select.lua Sun Jun 12 22:21:10 2011 +0100 +++ b/net/server_select.lua Wed Jun 15 23:44:18 2011 +0200 @@ -701,19 +701,19 @@ end if type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then err = "invalid port" - elseif _server[ port ] then - err = "listeners on port '" .. port .. "' already exist" + elseif _server[ addr..":"..port ] then + err = "listeners on '[" .. addr .. "]:" .. port .. "' already exist" elseif sslctx and not luasec then err = "luasec not found" end if err then - out_error( "server.lua, port ", port, ": ", err ) + out_error( "server.lua, [", addr, "]:", port, ": ", err ) return nil, err end addr = addr or "*" local server, err = socket_bind( addr, port ) if err then - out_error( "server.lua, port ", port, ": ", err ) + out_error( "server.lua, [", addr, "]:", port, ": ", err ) return nil, err end local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx, _maxclientsperserver ) -- wrap new server socket @@ -723,23 +723,23 @@ end server:settimeout( 0 ) _readlistlen = addsocket(_readlist, server, _readlistlen) - _server[ port ] = handler + _server[ addr..":"..port ] = handler _socketlist[ server ] = handler - out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '", addr, ":", port, "'" ) + out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" ) return handler end -getserver = function ( port ) - return _server[ port ]; +getserver = function ( addr, port ) + return _server[ addr..":"..port ]; end -removeserver = function( port ) - local handler = _server[ port ] +removeserver = function( addr, port ) + local handler = _server[ addr..":"..port ] if not handler then - return nil, "no server found on port '" .. tostring( port ) .. "'" + return nil, "no server found on '[" .. addr .. "]:" .. tostring( port ) .. "'" end handler:close( ) - _server[ port ] = nil + _server[ addr..":"..port ] = nil return true end diff -r 4dcdba6900f2 -r aff627b1ce95 prosody --- a/prosody Sun Jun 12 22:21:10 2011 +0100 +++ b/prosody Wed Jun 15 23:44:18 2011 +0200 @@ -270,7 +270,7 @@ if type(port) ~= "number" then log("error", "Non-numeric "..ports_option..": "..tostring(port)); else - local ok, err = cl.start(listener, { + local ok, errors = cl.start(listener, { ssl = conntype == "ssl" and global_ssl_ctx, port = port, interface = (option and config.get("*", "core", option.."_interface")) @@ -279,31 +279,33 @@ type = conntype }); if not ok then - local friendly_message = err; - if err:match(" in use") then - if port == 5222 or port == 5223 or port == 5269 then - friendly_message = "check that Prosody or another XMPP server is " - .."not already running and using this port"; - elseif port == 80 or port == 81 then - friendly_message = "check that a HTTP server is not already using " - .."this port"; - elseif port == 5280 then - friendly_message = "check that Prosody or a BOSH connection manager " - .."is not already running"; - else - friendly_message = "this port is in use by another application"; + for addr, err in pairs(errors) do + local friendly_message = err; + if err:match(" in use") then + if port == 5222 or port == 5223 or port == 5269 then + friendly_message = "check that Prosody or another XMPP server is " + .."not already running and using this port"; + elseif port == 80 or port == 81 then + friendly_message = "check that a HTTP server is not already using " + .."this port"; + elseif port == 5280 then + friendly_message = "check that Prosody or a BOSH connection manager " + .."is not already running"; + else + friendly_message = "this port is in use by another application"; + end + elseif err:match("permission") then + friendly_message = "Prosody does not have sufficient privileges to use this port"; + elseif err == "no ssl context" then + if not config.get("*", "core", "ssl") then + friendly_message = "there is no 'ssl' config under Host \"*\" which is " + .."require for legacy SSL ports"; + else + friendly_message = "initializing SSL support failed, see previous log entries"; + end end - elseif err:match("permission") then - friendly_message = "Prosody does not have sufficient privileges to use this port"; - elseif err == "no ssl context" then - if not config.get("*", "core", "ssl") then - friendly_message = "there is no 'ssl' config under Host \"*\" which is " - .."require for legacy SSL ports"; - else - friendly_message = "initializing SSL support failed, see previous log entries"; - end + log("error", "Failed to open server port %d on %s, %s", port, addr, friendly_message); end - log("error", "Failed to open server port %d, %s", port, friendly_message); end end end