From a7b86fa0fa14b9d936808833123fb4f2744a000b Mon Sep 17 00:00:00 2001 From: dmiller Date: Thu, 18 Sep 2014 03:38:24 +0000 Subject: [PATCH] Change timeouts for comm.lua As reported by nnposter (http://seclists.org/nmap-dev/2014/q3/472) using the rtt-based timeouts for read timeouts is not a good idea, since host processing time can be considerably longer, especially for SSL connections. comm.lua already allowed for different connect_ and request_timeout values to reflect this truth, so this commit switches to using the rtt-based timeout for the connect timeout and adding 6 seconds to get the request timeout. This value is based on the totalwaitms value in nmap-service-probes, and is still well short of the default 30s nsock timeout. --- nselib/comm.lua | 70 +++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/nselib/comm.lua b/nselib/comm.lua index fe257c15b..f5fe42afb 100644 --- a/nselib/comm.lua +++ b/nselib/comm.lua @@ -10,9 +10,9 @@ -- * 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: same as stdnse.get_timeout --- * connect_timeout - override timeout for connection --- * request_timeout - override timeout for requests +-- * timeout - override timeout in milliseconds. This overrides all other timeout defaults, but can be overridden by specific connect and request timeouts (below) +-- * connect_timeout - socket timeout for connection. Default: same as stdnse.get_timeout +-- * request_timeout - additional socket timeout for requests. This is added to the connect_timeout to get a total time for a request to receive a response. Default: 5000ms -- * recv_before - boolean, receive data before sending first payload -- -- If both "bytes" and "lines" are provided, @@ -26,6 +26,36 @@ local shortport = require "shortport" local stdnse = require "stdnse" _ENV = stdnse.module("comm", stdnse.seeall) +-- This timeout value (in ms) is added to the connect timeout and represents +-- the amount of processing time allowed for the host before it sends a packet. +-- For justification of this value, see totalwaitms in nmap-service-probes +local REQUEST_TIMEOUT = 6000 + +-- Function used to get a connect and request timeout based on specified options +local function get_timeouts(host, opts) + local connect_timeout, request_timeout + -- connect_timeout based on options or stdnse.get_timeout() + if opts and opts.connect_timeout then + connect_timeout = opts.connect_timeout + elseif opts and opts.timeout then + connect_timeout = opts.timeout + else + connect_timeout = stdnse.get_timeout(host) + end + + -- request_timeout based on options or READ_TIMEOUT + connect_timeout + if opts and opts.request_timeout then + request_timeout = opts.request_timeout + elseif opts and opts.timeout then + request_timeout = opts.timeout + else + request_timeout = REQUEST_TIMEOUT + end + request_timeout = request_timeout + connect_timeout + + return connect_timeout, request_timeout +end + -- Makes sure that opts exists and the default proto is there local initopts = function(opts) if not opts then @@ -43,9 +73,9 @@ end local setup_connect = function(host, port, opts) local sock = nmap.new_socket() - if opts.timeout then - sock:set_timeout(opts.timeout) - end + local connect_timeout, request_timeout = get_timeouts(host, opts) + + sock:set_timeout(connect_timeout) local status, err = sock:connect(host, port, opts.proto) @@ -53,6 +83,8 @@ local setup_connect = function(host, port, opts) return status, err end + sock:set_timeout(request_timeout) + return true, sock end @@ -164,13 +196,9 @@ end -- protocol used is fine) -- -- Possible options: --- timeout: generic timeout value --- connect_timeout: specific timeout for connection --- request_timeout: specific timeout for requests +-- timeout, connect_timeout, request_timeout: See module documentation -- recv_before: receive data before sending first payload -- --- Default timeout is result of stdnse.get_timeout --- -- @param host The destination host IP -- @param port The destination host port -- @param protocol The protocol for the connection @@ -182,15 +210,9 @@ end local function opencon(host, port, protocol, data, opts) local sd = nmap.new_socket() - -- check for connect_timeout or timeout option + local connect_timeout, request_timeout = get_timeouts(host, opts) - if opts and opts.connect_timeout then - sd:set_timeout(opts.connect_timeout) - elseif opts and opts.timeout then - sd:set_timeout(opts.timeout) - else - sd:set_timeout(stdnse.get_timeout(host)) - end + sd:set_timeout(connect_timeout) local status = sd:connect(host, port, protocol) if not status then @@ -198,15 +220,7 @@ local function opencon(host, port, protocol, data, opts) return nil, nil, nil end - -- check for request_timeout or timeout option - - if opts and opts.request_timeout then - sd:set_timeout(opts.request_timeout) - elseif opts and opts.timeout then - sd:set_timeout(opts.timeout) - else - sd:set_timeout(stdnse.get_timeout(host)) - end + sd:set_timeout(request_timeout) local response, early_resp; if opts and opts.recv_before then status, early_resp = read(sd, opts) end