Esempio n. 1
0
/*=========================================================================*/
void SLPDOutgoingAge(time_t seconds)
/*=========================================================================*/
{
    SLPDSocket* del  = 0;
    SLPDSocket* sock = (SLPDSocket*)G_OutgoingSocketList.head;

    while ( sock )
    {
        switch ( sock->state )
        {
        case DATAGRAM_MULTICAST:
        case DATAGRAM_BROADCAST:
        case DATAGRAM_UNICAST:
            if ( sock->age > G_SlpdProperty.unicastMaximumWait / 1000 )
            {
                del = sock;
            }
            sock->age = sock->age + seconds;
            break;

        case STREAM_READ_FIRST:
        case STREAM_WRITE_FIRST:
            sock->age = 0;
            break;
        case STREAM_CONNECT_BLOCK:
        case STREAM_READ:
        case STREAM_WRITE:
            if ( G_OutgoingSocketList.count > SLPD_COMFORT_SOCKETS )
            {
                /* Accellerate ageing cause we are low on sockets */
                if ( sock->age > SLPD_CONFIG_BUSY_CLOSE_CONN )
                {
                    SLPDKnownDARemove(&(sock->peeraddr.sin_addr));
                    del = sock;
                }
            }
            else
            {
                if ( sock->age > SLPD_CONFIG_CLOSE_CONN )
                {
                    SLPDKnownDARemove(&(sock->peeraddr.sin_addr));
                    del = sock;
                }
            }
            sock->age = sock->age + seconds;
            break;

        case STREAM_WRITE_WAIT:
            sock->age = 0;
            sock->state = STREAM_WRITE_FIRST;
            break;

        default:
            /* don't age the other sockets at all */
            break;
        }

        sock = (SLPDSocket*)sock->listitem.next;

        if ( del )
        {
            SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_OutgoingSocketList,(SLPListItem*)del));
            del = 0;
        }
    }                                                 
}
Esempio n. 2
0
/** Resend messages on sockets whose timeout has expired
 *
 * @param[in] seconds - The number of seconds old a socket must be to have
 * its messages resent.
 *
 * @remarks - Ideally, this would be at a resolution lower than one second, 
 * but given the default timeout values, this isn't too far off the mark, and
 * should not add too much of a burden to the main loop.
 */
void SLPDOutgoingRetry(time_t seconds)
{
   SLPDSocket * del = 0;
   SLPDSocket * sock = (SLPDSocket *) G_OutgoingSocketList.head;

   if(seconds <= 0)
      return;

   while (sock)
   {
      switch (sock->state)
      {
       case DATAGRAM_UNICAST:
          if(0 == sock->sendlist.count)  /*Clean up as fast as we can, as all messages were sent*/
             del = sock;
          else
          {
             sock->age += seconds;
             if(sock->age >= G_SlpdProperty.unicastTimeouts[sock->reconns] / 1000)
             {
               ++sock->reconns;
               if(sock->reconns >= MAX_RETRANSMITS)  
               {
                  char addr_str[INET6_ADDRSTRLEN];
                  SLPDLog("SLPD: Didn't receive response from DA at %s, removing it from list.\n",
                  SLPNetSockAddrStorageToString(&sock->peeraddr, addr_str, sizeof(addr_str)));
            
                  SLPDKnownDARemove(&(sock->peeraddr));
                  del = sock;
               }
               else
               {
                  SLPBuffer pbuf;
                  sock->age = 0;
                  for(pbuf = (SLPBuffer) sock->sendlist.head; pbuf; pbuf = (SLPBuffer) pbuf->listitem.next)
                     SLPDOutgoingDatagramWrite(sock, pbuf);
               }
             }
          }
            break;

         case DATAGRAM_MULTICAST:
         case DATAGRAM_BROADCAST:
         case STREAM_READ_FIRST:
         case STREAM_WRITE_FIRST:
         case STREAM_CONNECT_BLOCK:
         case STREAM_READ:
         case STREAM_WRITE:
         case STREAM_CONNECT_IDLE:
         case STREAM_WRITE_WAIT:
         default:
            break;
      }

      sock = (SLPDSocket *) sock->listitem.next;

      if (del)
      {
         SLPDSocketFree((SLPDSocket *)
               SLPListUnlink(&G_OutgoingSocketList, (SLPListItem *) del));
         del = 0;
      }
   }
}
Esempio n. 3
0
/** Reconnect an outbound socket.
 *
 * @param[in] socklist - The list of sockets being monitored.
 * @param[in] sock - The socket to be reconnected.
 */
void OutgoingStreamReconnect(SLPList * socklist, SLPDSocket * sock)
{
   char addr_str[INET6_ADDRSTRLEN];

   (void)socklist;

   /*-----------------------------------------------------------------*/
   /* If socket is already being reconnected but is reconnect blocked */
   /* just return.  Blocking connect sockets will eventually time out */
   /*-----------------------------------------------------------------*/
   if (sock->state == STREAM_CONNECT_BLOCK)
      return;

#ifdef DEBUG
   /* Log that reconnect warning */
   SLPDLog("WARNING: Reconnect to agent at %s.  "
           "Agent may not be making efficient \n"
           "         use of TCP.\n",
         SLPNetSockAddrStorageToString(&sock->peeraddr,
               addr_str, sizeof(addr_str)));
#endif

   /*----------------------------------------------------------------*/
   /* Make sure we have not reconnected too many times               */
   /* We only allow SLPD_CONFIG_MAX_RECONN reconnection retries      */
   /* before we stop                                                 */
   /*----------------------------------------------------------------*/
   sock->reconns += 1;
   if (sock->reconns > SLPD_CONFIG_MAX_RECONN)
   {
      SLPDLog("WARNING: Reconnect tries to agent at %s "
              "exceeded maximum. It\n         is possible that "
              "the agent is malicious. Check it out!\n",
            SLPNetSockAddrStorageToString(&sock->peeraddr, 
                  addr_str, sizeof(addr_str)));

      /*Since we can't connect, remove it as a DA*/
      SLPDKnownDARemove(&(sock->peeraddr));
      sock->state = SOCKET_CLOSE;
      return;
   }

   /*----------------------------------------------------------------*/
   /* Close the existing socket to clean the stream  and open an new */
   /* socket                                                         */
   /*----------------------------------------------------------------*/
   closesocket(sock->fd);

   if (sock->peeraddr.ss_family == AF_INET)
      sock->fd = socket(PF_INET, SOCK_STREAM, 0);
   else if (sock->peeraddr.ss_family == AF_INET6)
      sock->fd = socket(PF_INET6, SOCK_STREAM, 0);

   if (sock->fd == SLP_INVALID_SOCKET)
   {
      sock->state = SOCKET_CLOSE;
      return;
   }

   /*---------------------------------------------*/
   /* Set the new socket to enable nonblocking IO */
   /*---------------------------------------------*/
#ifdef _WIN32
   {
      u_long fdflags = 1;
      ioctlsocket(sock->fd, FIONBIO, &fdflags);
   }
#else
   {
      int fdflags = fcntl(sock->fd, F_GETFL, 0);
      fcntl(sock->fd, F_SETFL, fdflags | O_NONBLOCK);
   }
#endif

   /*--------------------------*/
   /* Connect a the new socket */
   /*--------------------------*/
   if (connect(sock->fd, (struct sockaddr *)&sock->peeraddr,
         sizeof(struct sockaddr_storage)))
   {
#ifdef _WIN32
      if (WSAEWOULDBLOCK == WSAGetLastError())
#else
      if (errno == EINPROGRESS)
#endif
      {
         /* Connect blocked */
         sock->state = STREAM_CONNECT_BLOCK;
         return;
      }
   }

   /* Connection occured immediately. Set to WRITE_FIRST so whole */
   /* packet will be written                                      */
   sock->state = STREAM_WRITE_FIRST;
}
Esempio n. 4
0
/*=========================================================================*/
void SLPDKnownDARegister(SLPDDatabaseEntry* dbhead, SLPDSocketList* sockets)
/*                                                                         */
/* Modify the specified socket list to register all entries of the         */
/* specified database list with all known DAs                              */
/*                                                                         */
/* Returns:  Zero on success, non-zero on error                            */
/*=========================================================================*/
{
    SLPDDatabaseEntry*  dbentry;
    SLPDSocket*         sockentry;
    SLPDAEntry*         daentry;

    
    if(dbhead)
    {
        daentry = G_KnownDAListHead;
        while(daentry)
        {
            /* check to see if a socket is already connected to this DA */
            sockentry = sockets->head;
            while(sockentry)
            {
                if(sockentry->peerinfo.peertype == SLPD_PEER_CONNECTED)
                {
                    if (memcmp(&sockentry->peerinfo.peeraddr.sin_addr,
                               &daentry->daaddr,
                               sizeof(daentry->daaddr)) == 0)
                    {
                        break;
                    }
                }
                sockentry = (SLPDSocket*)sockentry->listitem.next;                                                            
            }

            if(sockentry == 0)
            {
                /* Could not find a connected socket */
                /* Create a connected socket         */
                sockentry = SLPDSocketCreateConnected(&daentry->daaddr);
                if(sockentry == 0)
                {
                    /* Could not create connected socket */
                    
                    /* TODO: should we log here?         */

                    /* Remove the  known DA entry we could not connect to */
                    daentry = SLPDKnownDARemove(daentry);
                }
                else
                {
                    SLPDSocketListAdd(sockets, sockentry);   
                }
                                                             
            }

            if(sockentry != 0)
            {
                /* Load the send buffer with reg stuff */
                dbentry = dbhead;
                while(dbentry)
                {
                    
                    /* TODO: put a whole bunch of registration stuff here */

                    dbentry = (SLPDDatabaseEntry*)dbentry->listitem.next;
                }
            }
            
            daentry = (SLPDAEntry*)daentry->listitem.next;
        } 
    }
}