diff --git a/nselib/comm.lua b/nselib/comm.lua index 64337fdb6..fe257c15b 100644 --- a/nselib/comm.lua +++ b/nselib/comm.lua @@ -10,7 +10,7 @@ -- * bytes - minimum number of bytes to read. -- * lines - minimum number of lines to read. -- * proto - string, protocol to use. Default "tcp" --- * timeout - socket timeout in milliseconds. Default 8000 +-- * timeout - socket timeout in milliseconds. Default: same as stdnse.get_timeout -- * connect_timeout - override timeout for connection -- * request_timeout - override timeout for requests -- * recv_before - boolean, receive data before sending first payload @@ -169,7 +169,7 @@ end -- request_timeout: specific timeout for requests -- recv_before: receive data before sending first payload -- --- Default timeout is set to 8000. +-- Default timeout is result of stdnse.get_timeout -- -- @param host The destination host IP -- @param port The destination host port @@ -189,7 +189,7 @@ local function opencon(host, port, protocol, data, opts) elseif opts and opts.timeout then sd:set_timeout(opts.timeout) else - sd:set_timeout(8000) + sd:set_timeout(stdnse.get_timeout(host)) end local status = sd:connect(host, port, protocol) @@ -205,7 +205,7 @@ local function opencon(host, port, protocol, data, opts) elseif opts and opts.timeout then sd:set_timeout(opts.timeout) else - sd:set_timeout(8000) + sd:set_timeout(stdnse.get_timeout(host)) end local response, early_resp; diff --git a/nselib/rpc.lua b/nselib/rpc.lua index 5288d664f..7ddcfc032 100644 --- a/nselib/rpc.lua +++ b/nselib/rpc.lua @@ -163,12 +163,7 @@ Comm = { if (not(status)) then return status, err end - timeout = timeout or ( - -- Use host timeout value * 5 if available - (type(host) == "table" and host.times and host.times.timeout * 5) - or 10 -- default 10 seconds - ) * 1000 -- convert to ms - stdnse.debug1("Timeout: %d", timeout) + timeout = timeout or stdnse.get_timeout(host, 10000) local new_socket = function(...) local socket = nmap.new_socket(...) socket:set_timeout(timeout) diff --git a/nselib/stdnse.lua b/nselib/stdnse.lua index 8c7e80b40..bf801b476 100644 --- a/nselib/stdnse.lua +++ b/nselib/stdnse.lua @@ -1363,5 +1363,40 @@ function contains(tab, item) return false, nil end +--- Returns a conservative timeout for a host +-- +-- If the host parameter is a NSE host table with a times.timeout +-- attribute, then the return value is the host timeout scaled according to the +-- max_timeout. The scaling factor is defined by a linear formula such that +-- (max_timeout=8000, scale=2) and (max_timeout=1000, scale=1) +-- +-- @param host The host object to base the timeout on. If this is anything but +-- a host table, the max_timeout is returned. +-- @param max_timeout The maximum timeout in milliseconds. This is the default +-- timeout used if there is no host.times.timeout. Default: 8000 +-- @param min_timeout The minimum timeout in milliseconds that will be +-- returned. Default: 1000 +-- @return The timeout in milliseconds, suitable for passing to set_timeout +-- @usage +-- assert(host.times.timeout == 1.3) +-- assert(get_timeout() == 8000) +-- assert(get_timeout(nil, 5000) == 5000) +-- assert(get_timeout(host) == 2600) +-- assert(get_timeout(host, 10000, 3000) == 3000) +function get_timeout(host, max_timeout, min_timeout) + max_timeout = max_timeout or 8000 + local t = type(host) == "table" and host.times and host.times.timeout + if not t then + return max_timeout + end + t = t * (max_timeout + 6000) / 7 + min_timeout = min_timeout or 1000 + if t < min_timeout then + return min_timeout + elseif t > max_timeout then + return max_timeout + end + return t +end return _ENV;