Example #1
0
/** Connect for outbound traffic to a specified remote address.
 *
 * @param[in] is_TCP - if non-0, this is a tcp connection to the remote device
 * @param[in] addr - The address to be connected to.
 *
 * @remarks Get a pointer to a connected socket that is associated with
 * the outgoing socket list. If a connected socket already exists on the
 * outgoing list, a pointer to it is returned, otherwise a new connection
 * is made and added to the outgoing list
 *
 * @return A pointer to socket, or null on error.
 */
SLPDSocket * SLPDOutgoingConnect(int is_TCP, struct sockaddr_storage * addr)
{
   SLPDSocket * sock = 0;
   
   if(is_TCP)
   {
      sock = (SLPDSocket *) G_OutgoingSocketList.head;
      while (sock)
      {
        if (sock->state == STREAM_CONNECT_IDLE
            || sock->state > STREAM_CONNECT_CLOSE)
        {
           if (SLPNetCompareAddrs(&(sock->peeraddr), addr) == 0)
              break;
        }
        sock = (SLPDSocket *) sock->listitem.next;
      }

      if (sock == 0)
      {
         sock = SLPDSocketCreateConnected(addr);
         if (sock)
            SLPListLinkTail(&(G_OutgoingSocketList), (SLPListItem *) sock);
      }
   }
   else
   {
      sock = SLPDSocketCreateDatagram(addr, DATAGRAM_UNICAST);
      if (sock)
      {
         SLPListLinkTail(&(G_OutgoingSocketList), (SLPListItem *) sock);
         sock->reconns = 0;
         sock->age = 0;
      }
   }

   return sock;
}
Example #2
0
/*=========================================================================*/
void SLPDKnownDAActiveDiscovery()
/* Set outgoing socket list to send an active DA discovery SrvRqst         */
/*									                                       */
/* Returns:  none                                                          */
/*=========================================================================*/
{
    size_t          bufsize;
    SLPDAEntry*     daentry;
    SLPDSocket*     sock;
    char*           prlist;
    size_t          prlistlen;
    struct in_addr  peeraddr;
    
    if(G_SlpdProperty.isDA)
    {
        /* do not perform active DA discovery if we are a DA */
        return;
    }
    if(G_SlpdProperty.activeDiscoveryAttempts <= 0)
    {
        return;
    }
    G_SlpdProperty.activeDiscoveryAttempts --;


    /*--------------------------------------------------*/
    /* Create new DATAGRAM socket with appropriate peer */
    /*--------------------------------------------------*/
    if(G_SlpdProperty.isBroadcastOnly == 0)
    {
        peeraddr.s_addr = htonl(SLP_MCAST_ADDRESS);
        sock = SLPDSocketCreateDatagram(&peeraddr,DATAGRAM_BROADCAST);
    }
    else
    {   
        peeraddr.s_addr = htonl(SLP_BCAST_ADDRESS);
        sock = SLPDSocketCreateDatagram(&peeraddr,DATAGRAM_BROADCAST);
    }

    /*-------------------------------------------------*/
    /* Generate a DA service request buffer to be sent */
    /*-------------------------------------------------*/

    /* determine the size of the fixed portion of the SRVRQST         */
    bufsize  = 47;  /* 14 bytes for the header                        */
                    /*  2 bytes for the prlistlen                     */
                    /*  2 bytes for the srvtype length                */ 
                    /* 23 bytes for "service:directory-agent" srvtype */
                    /*  2 bytes for scopelistlen                      */
                    /*  2 bytes for predicatelen                      */
                    /*  2 bytes for sprstrlen                         */
    
    /* figure out what our Prlist will be by going through our list of  */
    /* known DAs                                                        */
    prlistlen = 0;
    prlist = malloc(SLP_MAX_DATAGRAM_SIZE);
    if(prlist == 0)
    {
        goto FINISHED;
    }
    
    *prlist = 0;
    daentry = (SLPDAEntry*)G_KnownDAList.head;
    while(daentry && prlistlen < SLP_MAX_DATAGRAM_SIZE)
    {
        strcat(prlist,inet_ntoa(daentry->daaddr));
        daentry = (SLPDAEntry*)daentry->listitem.next;
        if(daentry)
        {
            strcat(prlist,",");
        }
        prlistlen = strlen(prlist);
    }                                  

    /* Allocate the send buffer */
    bufsize += G_SlpdProperty.localeLen + prlistlen;
    sock->sendbuf = SLPBufferRealloc(sock->sendbuf,bufsize);
    if(sock->sendbuf == 0)
    {
        return;
    }                            

    /*------------------------------------------------------------*/
    /* Build a buffer containing the fixed portion of the SRVRQST */
    /*------------------------------------------------------------*/
    /*version*/
    *(sock->sendbuf->start)       = 2;
    /*function id*/
    *(sock->sendbuf->start + 1)   = SLP_FUNCT_SRVRQST;
    /*length*/
    ToUINT24(sock->sendbuf->start + 2, bufsize);
    /*flags*/
    ToUINT16(sock->sendbuf->start + 5,  SLP_FLAG_MCAST);
    /*ext offset*/
    ToUINT24(sock->sendbuf->start + 7,0);
    /*xid*/
    ToUINT16(sock->sendbuf->start + 10, 0);  /* TODO: generat a real XID */
    /*lang tag len*/
    ToUINT16(sock->sendbuf->start + 12, G_SlpdProperty.localeLen);
    /*lang tag*/
    memcpy(sock->sendbuf->start + 14,
           G_SlpdProperty.locale,
           G_SlpdProperty.localeLen);
    sock->sendbuf->curpos = sock->sendbuf->start + G_SlpdProperty.localeLen + 14;
    /* Prlist */
    ToUINT16(sock->sendbuf->curpos,prlistlen);
    sock->sendbuf->curpos = sock->sendbuf->curpos + 2;
    memcpy(sock->sendbuf->curpos,prlist,prlistlen);
    sock->sendbuf->curpos = sock->sendbuf->curpos + prlistlen;
    /* service type */
    ToUINT16(sock->sendbuf->curpos,23);                                         
    sock->sendbuf->curpos = sock->sendbuf->curpos + 2;
    memcpy(sock->sendbuf->curpos,"service:directory-agent",23);
    sock->sendbuf->curpos = sock->sendbuf->curpos + 23;
    /* scope list zero length */
    ToUINT16(sock->sendbuf->curpos,0);
    sock->sendbuf->curpos = sock->sendbuf->curpos + 2;
    /* predicate zero length */
    ToUINT16(sock->sendbuf->curpos,0);
    sock->sendbuf->curpos = sock->sendbuf->curpos + 2;
    /* spi list zero length */
    ToUINT16(sock->sendbuf->curpos,0);
    sock->sendbuf->curpos = sock->sendbuf->curpos + 2;
    
    /*------------------------------------*/
    /* Send the active DA service request */
    /*------------------------------------*/
    if(sock)
    {
        sendto(sock->fd,
               sock->sendbuf->start,
               sock->sendbuf->end - sock->sendbuf->start,
               0,
               &(sock->peerinfo.peeraddr),
               sock->peerinfo.peeraddrlen);
    }

FINISHED:
    SLPDSocketFree(sock);
}