Esempio n. 1
0
/*=========================================================================*/
void SLPDKnownDARegister(SLPDPeerInfo* peerinfo,
                         SLPMessage msg,
                         SLPBuffer buf)
/* Echo a message to a known DA                                            */
/*									   */
/* peerinfo (IN) the peer that the registration came from                   */    
/*                                                                         */ 
/* msg (IN) the translated message to echo                                 */
/*                                                                         */
/* buf (IN) the message buffer to echo                                     */
/*                                                                         */
/* Returns:  Zero on success, non-zero on error                            */
/*=========================================================================*/
{
    SLPDAEntry* daentry;
    SLPDSocket* sock;
    SLPBuffer   dup;

    daentry = (SLPDAEntry*)G_KnownDAList.head;
    while (daentry)
    {
        sock = (SLPDSocket*)G_OutgoingSocketList.head;
        while (sock)
        {
            if (sock->peerinfo.peeraddr.sin_addr.s_addr == daentry->daaddr.s_addr)
            {
                break;
            }
            sock = (SLPDSocket*)sock->listitem.next;
        }

        if (sock == 0)
        {
            /* Create a new socket to the known DA */
            sock = SLPDSocketCreateConnected(&(daentry->daaddr));
            if (sock)
            {
                sock->daentry = daentry;
                SLPListLinkTail(&G_OutgoingSocketList,(SLPListItem*)sock);
            }
        }

        /* Load the socket with the message to send */
        dup = SLPBufferDup(buf);
        if (dup)
        {
            if (sock->state == STREAM_CONNECT_IDLE)
            {
                sock->state = STREAM_WRITE_FIRST;
            }
            SLPListLinkTail(&(sock->sendlist),(SLPListItem*)dup);
        }
        daentry = (SLPDAEntry*)daentry->listitem.next;
    }
}
Esempio n. 2
0
int CheckAndResizeBuffer(SLPBuffer * sendbuf, SLPBuffer tmp, size_t grow_size)
{
	int retVal = 0;

    if( (*sendbuf)->curpos + (tmp->end - tmp->start) > ( (*sendbuf)->start + (*sendbuf)->allocated) )
    {
		  /* Grow the sendbuf buffer - note that SLPBufferRealloc may potentially do a memset if the DEBUG flag is set
		     Therefore we have to copy the old contents into the buffer afterwards to be sure
		  */
#ifdef DEBUG
		  SLPBuffer duplicate = SLPBufferDup( (*sendbuf) );
#endif
		  /* store how far we are from the start of the buffer */
		  size_t currentPosFromStart = (*sendbuf)->curpos - (*sendbuf)->start;

		  /* check to make sure we're growing by at least the size of the tmp buffer */
		  *sendbuf = SLPBufferRealloc( (*sendbuf), ((*sendbuf)->allocated + ((size_t)(tmp->end - tmp->start) > grow_size?(tmp->end - tmp->start):grow_size)) );
	      if (*sendbuf == 0)
	      {
	         retVal = SLP_ERROR_INTERNAL_ERROR;
	      }
	      else
	      {
		     /* update the current position to what it was before */
		     (*sendbuf)->curpos = (*sendbuf)->start + currentPosFromStart;
#ifdef DEBUG
    		  memcpy( (*sendbuf)->start, duplicate->start, duplicate->end - duplicate->start );
#endif
	      }
#ifdef DEBUG
		  SLPBufferFree(duplicate);
		  duplicate = 0;
#endif
    }

    return retVal;
}
Esempio n. 3
0
/*-------------------------------------------------------------------------*/
SLPBoolean KnownDADiscoveryCallback(SLPError errorcode,
                                    struct sockaddr_in* peerinfo,
                                    SLPBuffer rplybuf, 
                                    void* cookie)
/*-------------------------------------------------------------------------*/
{
    SLPMessage      replymsg;
    SLPBuffer       dupbuf;
    struct hostent* he;
    SLPSrvURL*      srvurl;
    int*            count;
    SLPBoolean      result = SLP_TRUE;
    
    count = (int*)cookie;

    if(errorcode == 0)
    {
        dupbuf = SLPBufferDup(rplybuf);
        if(dupbuf)
        {
            replymsg = SLPMessageAlloc();
            if(replymsg)
            {
                 if(SLPMessageParseBuffer(peerinfo,dupbuf,replymsg) == 0 &&
                    replymsg->header.functionid == SLP_FUNCT_DAADVERT)
                 {
                    if(replymsg->body.daadvert.errorcode == 0)
                    {
                        /* TRICKY: NULL terminate the DA url */
                        ((char*)(replymsg->body.daadvert.url))[replymsg->body.daadvert.urllen] = 0;
                        if(SLPParseSrvURL(replymsg->body.daadvert.url, &srvurl) == 0)
                        {
                            he = gethostbyname(srvurl->s_pcHost);
                            SLPFree(srvurl);
			    if(he)
                            {
                                /* Reset the peer to the one in the URL */
                                replymsg->peer.sin_addr.s_addr = *((unsigned int*)(he->h_addr_list[0]));
                                
                                (*count) += 1;
                         
                                KnownDAAdd(replymsg,dupbuf);
                                 if(replymsg->header.flags & SLP_FLAG_MCAST)
                                 {
                                     return SLP_FALSE;
                                 }
                                 
                                 return SLP_TRUE;
                            }                            
                        }
                         
                     }
                     else if(replymsg->body.daadvert.errorcode == SLP_ERROR_INTERNAL_ERROR)
                     {
                        /* SLP_ERROR_INTERNAL_ERROR is a "end of stream" */
                        /* marker for looppack IPC                       */
                        result = SLP_FALSE;
                     }
                 }
                 
                 SLPMessageFree(replymsg);
            }

            SLPBufferFree(dupbuf);
        }
    }
            
    return result;
}
Esempio n. 4
0
/** Processes the recvbuf and places the results in sendbuf
 *
 * @param[in] peerinfo - The remote address the message was received from.
 * @param[in] localaddr - The local address the message was received on.
 * @param[in] recvbuf - The message to process.
 * @param[out] sendbuf - The address of storage for the results of the 
 *    processed message.
 * @param[out] sendlist - if non-0, this function will prune the message 
 *    with the processed xid from the sendlist.
 *
 * @return Zero on success if @p sendbuf contains a response to send, 
 *    or a non-zero value if @p sendbuf does not contain a response
 *    to send.
 */
int SLPDProcessMessage(struct sockaddr_storage * peerinfo, 
      struct sockaddr_storage * localaddr, SLPBuffer recvbuf,
      SLPBuffer * sendbuf, SLPList * psendlist)
{
   SLPHeader header;
   SLPMessage * message = 0;
   int errorcode = 0;

#ifdef DEBUG
   char addr_str[INET6_ADDRSTRLEN];
#endif

   SLPDLogMessage(SLPDLOG_TRACEMSG_IN, peerinfo, localaddr, recvbuf);

   /* set the sendbuf empty */
   if (*sendbuf)
      (*sendbuf)->end = (*sendbuf)->start;

   /* zero out the header before parsing it */
   memset(&header, 0, sizeof(header));

   /* Parse just the message header */
   recvbuf->curpos = recvbuf->start;
   errorcode = SLPMessageParseHeader(recvbuf, &header);

   /* Reset the buffer "curpos" pointer so that full message can be 
      parsed later 
    */
   recvbuf->curpos = recvbuf->start;

#if defined(ENABLE_SLPv1)   
   /* if version == 1 and the header was correct then parse message as a version 1 message */
   if ((errorcode == 0) && (header.version == 1))
      errorcode = SLPDv1ProcessMessage(peerinfo, recvbuf, sendbuf);
   else
#endif
   if (errorcode == 0)
   {
      /* TRICKY: Duplicate SRVREG recvbufs *before* parsing them
       * we do this because we are going to keep track of in the 
       * registration database.
       */
      if (header.functionid == SLP_FUNCT_SRVREG 
            || header.functionid == SLP_FUNCT_DAADVERT)
      {
         recvbuf = SLPBufferDup(recvbuf);
         if (recvbuf == 0)
            return SLP_ERROR_INTERNAL_ERROR;
      }

      /* Allocate the message descriptor */
      message = SLPMessageAlloc();
      if (message)
      {
         /* Parse the message and fill out the message descriptor */
         errorcode = SLPMessageParseBuffer(peerinfo, localaddr,
               recvbuf, message);
         if (errorcode == 0)
         {
            /* Process messages based on type */
            switch (message->header.functionid)
            {
               case SLP_FUNCT_SRVRQST:
                  errorcode = ProcessSrvRqst(message, sendbuf, errorcode);
                  break;

               case SLP_FUNCT_SRVREG:
                  errorcode = ProcessSrvReg(message, recvbuf, 
                        sendbuf, errorcode);
                  if (errorcode == 0)
                     SLPDKnownDAEcho(message, recvbuf);         
                  break;

               case SLP_FUNCT_SRVDEREG:
                  errorcode = ProcessSrvDeReg(message, sendbuf, errorcode);
                  if (errorcode == 0)
                     SLPDKnownDAEcho(message, recvbuf);         
                  break;

               case SLP_FUNCT_SRVACK:
                  errorcode = ProcessSrvAck(message, sendbuf, errorcode);
                  break;

               case SLP_FUNCT_ATTRRQST:
                  errorcode = ProcessAttrRqst(message, sendbuf, errorcode);
                  break;

               case SLP_FUNCT_DAADVERT:
                  errorcode = ProcessDAAdvert(message, recvbuf, 
                        sendbuf, errorcode);
                  break;

               case SLP_FUNCT_SRVTYPERQST:
                  errorcode = ProcessSrvTypeRqst(message, sendbuf, errorcode);
                  break;

               case SLP_FUNCT_SAADVERT:
                  errorcode = ProcessSAAdvert(message, sendbuf, errorcode);
                  break;

               default:
                  /* Should never happen... but we're paranoid */
                  errorcode = SLP_ERROR_PARSE_ERROR;
                  break;
            }
         }
         else
            SLPDLogParseWarning(peerinfo, recvbuf);

       /*If there was a send list, prune the xid, since the request has been processed*/
       if(psendlist)
       {
          SLPHeader bufhead;
          SLPBuffer pnext;
          SLPBuffer pbuf = (SLPBuffer) psendlist->head;

          while(pbuf)
          {
            pnext = (SLPBuffer) pbuf->listitem.next;

            if((0 == SLPMessageParseHeader(pbuf, &bufhead)) && (bufhead.xid == header.xid))
               SLPBufferFree((SLPBuffer)SLPListUnlink(psendlist, (SLPListItem*)pbuf));
            else 
               pbuf->curpos = pbuf->start;  /*We parsed the buffer enough to attempt the xid check, we need to reset it for the next parse*/

            pbuf = pnext;
          }
       }

         if (header.functionid == SLP_FUNCT_SRVREG 
               || header.functionid == SLP_FUNCT_DAADVERT)
         {
            /* TRICKY: If this is a reg or daadvert message we do not free 
             * the message descriptor or duplicated recvbuf because they are 
             * being kept in the database!
             */
            if (errorcode == 0)
               goto FINISHED;

            /* TRICKY: If there is an error we need to free the 
             * duplicated recvbuf
             */
            SLPBufferFree(recvbuf);                    
         }
         SLPMessageFree(message);
      }
      else
         errorcode = SLP_ERROR_INTERNAL_ERROR;  /* out of memory */
   }
   else
      SLPDLogParseWarning(peerinfo,recvbuf);

FINISHED:

#ifdef DEBUG
   if (errorcode)
      SLPDLog("\n*** DEBUG *** errorcode %i during processing "
            "of message from %s\n", errorcode, SLPNetSockAddrStorageToString(
            peerinfo, addr_str, sizeof(addr_str)));
#endif

   /* Log message silently ignored because of an error */
   if (errorcode)
      if (*sendbuf == 0 || (*sendbuf)->end == (*sendbuf)->start)
         SLPDLogMessage(SLPDLOG_TRACEDROP,peerinfo,localaddr,recvbuf);

   /* Log trace message */
   SLPDLogMessage(SLPDLOG_TRACEMSG_OUT, peerinfo, localaddr, *sendbuf);

   return errorcode;
}                
Esempio n. 5
0
/*=========================================================================*/
int SLPDv1ProcessMessage(struct sockaddr_in* peeraddr,
                         SLPBuffer recvbuf,
                         SLPBuffer* sendbuf)
/* Processes the SLPv1 message and places the results in sendbuf           */
/*                                                                         */
/* peeraddr - the socket the message was received on                       */
/*                                                                         */
/* recvbuf  - message to process                                           */
/*                                                                         */
/* sendbuf  - results of the processed message                             */
/*                                                                         */
/* Returns  - zero on success SLP_ERROR_PARSE_ERROR or                     */
/*            SLP_ERROR_INTERNAL_ERROR on ENOMEM.                          */
/*=========================================================================*/
{
    SLPHeader   header;
    SLPMessage  message;
    int         errorcode   = 0;

    if (!G_SlpdProperty.isDA)
    {
        /* SLPv1 messages are handled only by DAs */
        errorcode = SLP_ERROR_VER_NOT_SUPPORTED;
    }

    /* Parse just the message header the reset the buffer "curpos" pointer */
    recvbuf->curpos = recvbuf->start;
    errorcode = SLPv1MessageParseHeader(recvbuf, &header);

    /* TRICKY: Duplicate SRVREG recvbufs *before* parsing them   */
    /*         it because we are going to keep them in the       */
    if (header.functionid == SLP_FUNCT_SRVREG)
    {
        recvbuf = SLPBufferDup(recvbuf);
        if (recvbuf == NULL)
        {
            return SLP_ERROR_INTERNAL_ERROR;
        }
    }

    /* Allocate the message descriptor */
    message = SLPMessageAlloc();
    if (message)
    {
        /* Parse the message and fill out the message descriptor */
        errorcode = SLPv1MessageParseBuffer(peeraddr,recvbuf, message);
        if (errorcode == 0)
        {
            /* Process messages based on type */
            switch (message->header.functionid)
            {
            case SLP_FUNCT_SRVRQST:
                errorcode = v1ProcessSrvRqst(peeraddr, message, sendbuf, errorcode);
                break;

            case SLP_FUNCT_SRVREG:
                errorcode = v1ProcessSrvReg(peeraddr,
                                            message,
                                            recvbuf,
                                            sendbuf,
                                            errorcode);
                if (errorcode == 0)
                {
                    SLPDKnownDAEcho(message, recvbuf);      
                }
                break;

            case SLP_FUNCT_SRVDEREG:
                errorcode = v1ProcessSrvDeReg(peeraddr, message, sendbuf, errorcode);
                if (errorcode == 0)
                {
                    SLPDKnownDAEcho(message, recvbuf);      
                }
                break;

            case SLP_FUNCT_ATTRRQST:
                errorcode = v1ProcessAttrRqst(peeraddr, message, sendbuf, errorcode);
                break;

            case SLP_FUNCT_SRVTYPERQST:
                errorcode = v1ProcessSrvTypeRqst(peeraddr, message, sendbuf, errorcode);
                break;

            case SLP_FUNCT_DAADVERT:
                /* we are a SLPv2 DA, ignore other v1 DAs */
                (*sendbuf)->end = (*sendbuf)->start;
                break;

            default:
                /* Should never happen... but we're paranoid */
                errorcode = SLP_ERROR_PARSE_ERROR;
                break;
            }   
        }

        if (header.functionid == SLP_FUNCT_SRVREG)
        {
            /* TRICKY: Do not free the message descriptor for SRVREGs */
            /*         because we are keeping them in the database    */
            /*         unless there is an error then we free memory   */
            if (errorcode)
            {
                SLPMessageFree(message);
                SLPBufferFree(recvbuf);
            }
        }
        else
        {
            SLPMessageFree(message);
        }
    }
    else
    {
        /* out of memory */
        errorcode = SLP_ERROR_INTERNAL_ERROR;
    }

    return errorcode;
}