diff --git a/scan_engine.cc b/scan_engine.cc index 67b1f30..1d4b704 100644 --- a/scan_engine.cc +++ b/scan_engine.cc @@ -4109,6 +4109,10 @@ static bool do_one_select_round(UltraScanInfo *USI, struct timeval *stime) { int numGoodSD = 0; int err = 0; reason_t current_reason = ER_NORESPONSE; + struct sockaddr_storage local; + socklen_t local_len = sizeof(struct sockaddr_storage); + struct sockaddr_storage remote; + size_t remote_len; do { timeleft = TIMEVAL_MSEC_SUBTRACT(*stime, USI->now); @@ -4182,9 +4186,29 @@ static bool do_one_select_round(UltraScanInfo *USI, struct timeval *stime) { optval = socket_errno(); /* Stupid Solaris ... */ switch (optval) { case 0: - newhoststate = HOST_UP; - newportstate = PORT_OPEN; - current_reason = ER_CONACCEPT; + /* Check for self-connected probe */ + if (getsockname(sd, (struct sockaddr*)&local, &local_len) == 0 + && host->target->TargetSockAddr(&remote, &remote_len) == 0) { + if (sockaddr_storage_cmp(&local, &remote) == 0 && ( + (local.ss_family == AF_INET && ((struct sockaddr_in*)&local)->sin_port == htons(probe->dport())) +#if HAVE_IPV6 + || (local.ss_family == AF_INET6 && ((struct sockaddr_in6*)&local)->sin6_port == htons(probe->dport())) +#endif + )) { + if (o.debugging) { + log_write(LOG_STDOUT, "Detected likely self-connect on port %d\n", probe->dport()); + } + host->markProbeTimedout(probeI); + } + else { + newportstate = PORT_OPEN; + } + newhoststate = HOST_UP; + current_reason = ER_CONACCEPT; + } + else { + gh_perror("getsockname or TargetSockAddr failed"); + } break; case EACCES: /* Apparently this can be caused by dest unreachable admin