LINUX.ORG.RU

connect return -1 errno = 105 (ENOBUFS)


0

0

простой многопоточный сканер портов. при сканировании своей подсети
(netmask 255.255.240.0)  примерно после 1000 хоста, начинается сабж. При сканировании других подсетей, все нормально работает. Вопрос подкупает своей новизной, "Кто виноват, и что делать?" Прошу помощи!
куски кода:
int isconnected( int s, fd_set *rd, fd_set *wr, fd_set * )
{
   int err;
   int len = sizeof( err );;   
   errno = 0;   
   if ( !FD_ISSET( s, rd ) && !FD_ISSET( s, wr ) ) return 0;
   if ( getsockopt( s, SOL_SOCKET, SO_ERROR, &err, (socklen_t*)&len ) < 0 ) return 0;
   errno = err;
   return err == 0;
}

bool chkport( const char * ipaddress, int connect_timeout, int port_number )
{
   bool pOpen = FALSE;
   int Ms; //SOCKET   
   fd_set rdevents;
   fd_set wrevents;
   fd_set exevents;
   struct sockaddr_in peer;
   struct timeval tv;
   int flags;
   int rc;
   bzero( &peer, sizeof( peer ) );
   peer.sin_family = AF_INET;
   peer.sin_port = htons( port_number );
   peer.sin_addr.s_addr = inet_addr( ipaddress );
   Ms = socket( AF_INET, SOCK_STREAM, 0 );
   if ( !( Ms >= 0 ) ) 
   {
      cout <<"socket call failed";
      return FALSE;
   }
   if( ( flags = fcntl( Ms, F_GETFL, 0 ) ) < 0 )
      cout <<"fcntl (F_GETFL) failed";
   if ( fcntl( Ms, F_SETFL, flags | O_NONBLOCK ) < 0 )
      cout <<"fcntl (F_SETFL) failed";
   rc = connect( Ms, ( struct sockaddr * )&peer, sizeof( peer ) );
   if ( rc == -1 && errno != EINPROGRESS )     
   {            
      cout <<"connect return -1 errno = "<< errno;
      pOpen = FALSE;   
   }
   
   else if ( rc == 0  && errno != EINPROGRESS )	/* already connected? */
   {
      cout <<"connected quickly";
      pOpen = TRUE;
   }
   else
   {   
      FD_ZERO( &rdevents );
      FD_SET( Ms, &rdevents );
      wrevents = rdevents;
      exevents = rdevents;
      tv.tv_sec = 0;
      tv.tv_usec = connect_timeout;
      rc = select( Ms + 1, &rdevents, &wrevents, &exevents, &tv );
      if ( rc < 0 )
      {
         cout <<"select failed";
      }
      else if ( rc == 0 )
      {
         cout <<"connect timed out";
      }
      else if ( isconnected( Ms, &rdevents, &wrevents, &exevents ) )
      { 
         cout <<"connected 2";
         pOpen = TRUE;
      }      
      else  cout <<"connect failed 2";
   }   
   if ( fcntl( Ms, F_SETFL, flags ) < 0 )
      cout <<"fcntl (F_SETFL) failed";   
   shutdown( Ms, SHUT_RDWR);   
   close(Ms);   
   return pOpen;
}
anonymous

уж очень подозрительно число 1000. возможно что программа открыла максимально возможное число сокетов (1024) и пытается получить ещё

anonymous
()
Ответ на: комментарий от anonymous

число 1000, названо на глаз, но при сканировании других диапазонов - количество сокетов то же. были мысли про ARP(mac) cache, но глупые ;)

anonymous
()
Ответ на: комментарий от anonymous

В man connect в секции ERRORS есть замечание
The following are general socket errors only. There may be other domain-specific error codes.
Поскольку среди пречиленных ошибок ENOBUFS нет, то это как раз
domain-specific error. Т.к. домен PF_INET то идем в (для 2.4) /usr/src/linux/net/ipv4 ищем ф-ю tcp_v4_connect и смотрим когда
она может возвращать -ENOBUFS. Не уверен, что это все варианты
но возможно по крайней мере 2
1. в ф-ции tcp_connect при выделении памяти для sockets buffer
2. в ф-ции ip_route_connect при работе с таблицей маршрутизации

З.Ы. Воообче может все это херня и решение лежит на поверхности.

anonymous
()
Ответ на: комментарий от anonymous

мысли про arp cache оказались правильными
echo 8192 > /proc/sys/net/ipv4/neigh/default/gc_thresh1
помогло

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.