I've created small lib tcp-exists to check if tcp endpoint exists. Just to iterate over a network to find anything on special ports.
But when I am iterating – some of tcp sockets (which creates by lib tcp-exists) take a large amount of time (1-3s instead of 5-20ms) to establish connections on 100% existing endpoints.
import tcpExists from 'tcp-exists'
async function main () {
for (let i = 1; i < 250; ++i) {
let time = performance.now()
const exists = await tcpExists('192.168.1.87', 80, 2000)
time = performance.now() - time
console.log(`time [${i}]:`, time)
if (time > 500) console.log('=====STRANGE=====')
if (!exists) console.log('exists')
}
}
main()
There is no difference between am I checking the same port or different ports on one IP, or am I checking different IPs. Some of that connections will take x100 more time to establish a connection. It can lead to a situation when there is an endpoint that exists, but the function will return false because of a small timeout.
I cannot set a timeout bigger than 25ms for one check. Because if I will want to scan from 192.168.0.0 to 192.168.255.255 (65536 endpoints) — where are most of IP has no endpoint and should be returned false by timeout — and use for example 1s as timeout - then it will take 65536 seconds or ~18hours...
The TCP handshake means that the client sends a SYN to the server, the server ACKs the clients SYN and send its own SYN back (usually both within a single packet, i.e. SYN+ACK) and then the clients reacts to the servers SYN with its own ACK. The speed of the handshakes thus depends on the network latency between client and server and how fast the server reacts to the connection request (SYN). Any packets lost on the way need to be retransmitted after some timeout, which further increases the time for the TCP handshake.
All of this is out of control of the client, i.e. there is no way to speed it up. High performance scanners therefore don't try one connection after the other but try many connections in parallel.