Speedup Windows C Port Scanner -


so developed port scanner c on windows have noticed on ip's runs slowly. here's code it:

dword winapi connectportw(lpvoid lpparam) {     handle hstdout;     pmydata pdataarray;      wsadata firstsock;     socket s;     struct sockaddr_in sa;     int err;      char * openports = (char *)malloc(sizeof(char)*256);     memset(&openports[0], 0, strlen(openports));      hstdout = getstdhandle(std_output_handle);     if(hstdout == invalid_handle_value )     {         return 1;     }      pdataarray = (pmydata)lpparam;      strncpy((char *)&sa,"",sizeof sa);       sa.sin_family = af_inet;      if (wsastartup(makeword(2,0),&firstsock) != 0)     {         fprintf(stderr,"wsastartup() failed");          exit(1);     }      sa.sin_addr.s_addr = inet_addr(pdataarray->ip);       s = socket(af_inet, sock_stream, 0); //make net valid socket handle     if(s < 0)     {         perror("\nsocket creation failed");  // perror function prints error message stderr         exit(1);     }      sa.sin_port = htons(pdataarray->port);     err = connect(s, (struct sockaddr *)&sa, sizeof sa);      //connection not accepted     if(err == socket_error)     {         printf("%s %-5d winsock error code : %d\n", pdataarray->ip, pdataarray->port, wsagetlasterror());         strcpy("null", openports);         fflush(stdout);     }     //connection accepted     else     {         printf("%s %-5d accepted            \n", pdataarray->ip, pdataarray->port);         sprintf(openports, "%i,", pdataarray->port);         if(shutdown(s, sd_both ) == socket_error )         {             perror("\nshutdown");             exit(1);            }    }     closesocket(s);      fflush(stdout);     strcpy(pdataarray->openports, openports);     free(openports);     return 0; } 

keep in mind use threads , each thread calls function different port (0 - 1024) on same ip.

so how can speed up? keep seeing people talking non-blocking, speed , if how can implement that. thanks!

edit: taking 614 seconds (10 minutes) scan 0 - 1024 on 1 of aforementioned 'slow' ip's

edit 2: started trying use non-blocking... doing right?

ioctlsocket(s, fionbio, &on); connect(s, (struct sockaddr *)&sa, sizeof sa); fd_zero(&fds); fd_set(s, &fds);  err = select(s, &fds, &fds, &fds, &tv);  if (err != socket_error && err != 0) {     sprintf(openports + strlen(openports),"%i,", pdataarray->port); } closesocket(s); 

edit 3: seems new method giving me inaccurate results much faster. seem getting more open ports compared results of running nmap on same ip.

i see lot of problems thread code:

  • it leaking memory if failure happens.

  • you misusing strlen() when calling memset() on openports variable. remove memset() altogether , use calloc() or localalloc(lmem_zeroinit) instead when allocating openports. or, use call stack instead, since variable small: char openports[256] = {0}; or better, don't use local openports variable @ all, write pdataarray->openports directly when have result available.

  • you should not using exit() @ all. use return instead.

  • it not technically illegal call wsastartup()/wsacleanup() multiple times, since winsock reference counted, best call them once @ program startup/exit, not per thread. but, since calling wsastartup(), must call wsacleanup() keep winsock reference count balanced.

  • what trying strcpy("null", openports);? writing read-only memory. think mean strcpy(openports, "null"); instead.

  • writing pdataarray->openports not thread-safe if multiple threads sharing single buffer (your use of , in sprintf() string implies may case). need synchronize access buffer when writing across multiple threads. can use critical section or mutex purpose.

that being said, using blocking socket, connect() block thread until winsock times out internally, may take awhile on slow networks. speed up, switch socket non-blocking mode using ioctrlsocket(fionbio), , use select() implement own timeout connect(), eg:

dword winapi connectportw(lpvoid lpparam) {     pmydata pdataarray = (pmydata) lpparam;      handle hstdout = getstdhandle(std_output_handle);     if (hstdout == invalid_handle_value)         return 1;      wsadata wsa;     int err = wsastartup(makeword(2,0), &wsa);     if (err != 0)     {         fprintf(stderr, "%s %d wsastartup() failed, error code : %d\n", pdataarray->ip, pdataarray->port, err);         return 1;     }      socket s = socket(af_inet, sock_stream, 0); //make net valid socket handle     if (s == invalid_socket)     {         fprintf(stderr, "%s %d socket creation failed, error code : %d\n", pdataarray->ip, pdataarray->port, wsagetlasterror());         wsacleanup();         return 1;     }      u_long enabled = 1;     if (ioctlsocket(s, fionbio, &enabled) == socket_error)     {         fprintf(stderr, "%s %d socket non-blocking mode failed, error code : %d\n", pdataarray->ip, pdataarray->port, wsagetlasterror());         closesocket(s);         wsacleanup();         return 1;     }      struct sockaddr_in sa = {0};     sa.sin_family = af_inet;     sa.sin_addr.s_addr = inet_addr(pdataarray->ip);      sa.sin_port = htons(pdataarray->port);      if (connect(s, (struct sockaddr *)&sa, sizeof sa) == socket_error)     {         err = wsagetlasterror();         if (err != wsaewouldblock)         {             fprintf(stderr, "%s %d socket connect failed, error code : %d\n", pdataarray->ip, pdataarray->port, err);             closesocket(s);             wsacleanup();             return 1;         }          fd_set wfd, efd;          fd_zero(s, &wfd);         fd_set(s, &wfd);          fd_zero(s, &efd);         fd_set(s, &efd)'          timeval timeout;         timeout.tv_sec = 5;         timeout.tv_usec = 0;          err = select(0, null, &wfd, &efd, &timeout);         if (err == socket_error)         {             fprintf(stderr, "%s %d socket select failed, error code : %d\n", pdataarray->ip, pdataarray->port, wsagetlasterror());             closesocket(s);             wsacleanup();             return 1;         }          if (err == 0)         {             // connect timeout             closesocket(s);             wsacleanup();             return 0;         }          if (fd_isset(s, &efd))         {             err = 0;             getsockopt(s, sol_socket, so_error, (char*)&err, sizeof err);             closesocket(s);             wsacleanup();              switch (err)             {                 case wsaetimedout: // connect timeout                 case wsaeconnrefused: // port closed                     return 0;             }              fprintf(stderr, "%s %d socket connect failed, error code : %d\n", pdataarray->ip, pdataarray->port, err);             return 1;         }     }      // connected!     printf("%s %d accepted\n", pdataarray->ip, pdataarray->port);      // note, not thread-safe! need sync access openports...     sprintf(pdataarray->openports + strlen(pdataarray->openports), "%d,", pdataarray->port);      closesocket(s);      wsacleanup();     return 0; } 

Comments

Popular posts from this blog

PHP and MySQL WP -

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

go - golang pprof for c library code -