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;