Suggest to use net.DialTimeout
sergii4 opened this issue · 4 comments
Even big timeout 10*time.Second
can increase performance:
conn, err := net.DialTimeout("tcp", address, 10*time.Second)
bhg/ch-2/tcp-scanner-final/main.go
Line 12 in f86cc72
old:
go run main.go scanme.nmap.org 1,28s user 1,26s system 1% cpu 2:12,38 total
new:
go run main.go scanme.nmap.org 1,01s user 0,63s system 12% cpu 13,153 total
This, I think, is the only thing that will make the port scanner work when it encounters filtered ports. If I run with net.Dial
, it hangs after 1017 ports (i.e., 7 results still pending). Compare that with nmap's output:
$ nmap scanme.nmap.org -p 1-1024
Starting Nmap 7.60 ( https://nmap.org ) at 2020-03-14 18:04 EDT
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up (0.089s latency).
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f
Not shown: 1013 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
25/tcp filtered smtp
80/tcp open http
135/tcp filtered msrpc
136/tcp filtered profile
137/tcp filtered netbios-ns
138/tcp filtered netbios-dgm
139/tcp filtered netbios-ssn
445/tcp filtered microsoft-ds
554/tcp open rtsp
We have 7 filtered ports.
I'm not sure if net.Dial
would time out eventually, but if it doesn't, I don't think the current implementation would ever complete.
Thanks for the input! You are indeed correct, you will want to use DialTimeout
, 500 MS is probably good actually. If you are interested to know, the default is actually up to the OS.
// It is safe to call Dialer's methods concurrently.
type Dialer struct {
// Timeout is the maximum amount of time a dial will wait for
// a connect to complete. If Deadline is also set, it may fail
// earlier.
//
// The default is no timeout.
//
// When using TCP and dialing a host name with multiple IP
// addresses, the timeout may be divided between them.
//
// With or without a timeout, the operating system may impose
// its own earlier timeout. For instance, TCP timeouts are
// often around 3 minutes.
Timeout time.Duration
Did you check out the scanner here https://github.com/blackhat-go/bhg/blob/56620f7153a25b0ca5317d67be4c3364a9561ad4/ch-8/syn-flood/main.go
For the earlier one, we're building on concepts. It maybe useful to bring in DialTimeout
if we do a second edition, for now, I think we should keep this as it simplifies the exercise for the reader. Additionally, DialTimeout
is discussed in later scanners as well :)
FWIW: I've picked up a copy of the book direct from No Starch Press (really enjoying it thus far), but ended up on this GH issue via a Google Search. The discussion here led me in the right direction.
In case it is helpful to someone else landing here from Google, here are the other relevant references that I used to set a timeout for tls.Dial()
(actually tls.DialWithDialer
):
- https://golang.org/pkg/crypto/tls/#DialWithDialer
- https://golang.org/pkg/net/#Dialer
- https://golang.org/pkg/net/#DialTimeout
- https://golang.org/src/crypto/tls/tls_test.go
Example code snippet (outer indentation and surrounding code body removed):
dialer := &net.Dialer{
Timeout: time.Duration(config.Timeout) * time.Second,
}
conn, err := tls.DialWithDialer(dialer, "tcp", server, &cfg)
time.Second
was used here because it matched the application use case.