Пример #1
0
/** Thread start procedure for asynchronous service type request.
 *
 * @param[in,out] handle - Contains the request parameters, returns the
 *    request result.
 *
 * @return An SLPError code.
 *
 * @internal
 */
static SLPError AsyncProcessSrvTypeRqst(SLPHandleInfo * handle)
{
   SLPError result = ProcessSrvTypeRqst(handle);
   xfree((void *)handle->params.findsrvtypes.namingauth);
   xfree((void *)handle->params.findsrvtypes.scopelist);
   handle->inUse = SLP_FALSE;
   return result;
}
Пример #2
0
/*=========================================================================*/
int SLPDProcessMessage(SLPDPeerInfo* peerinfo,
                       SLPBuffer recvbuf,
                       SLPBuffer sendbuf)
/* Processes the recvbuf and places the results in sendbuf                 */
/*                                                                         */
/* recvfd   - 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.                          */
/*=========================================================================*/
{
    SLPMessage  message   = 0;
    int         result  = 0;

    message = SLPMessageAlloc();
    if(message == 0)
    {
        return SLP_ERROR_INTERNAL_ERROR;
    }

    result = SLPMessageParseBuffer(recvbuf, message);
    if(result == 0)
    {
        switch(message->header.functionid)
        {
        case SLP_FUNCT_SRVRQST:
            ProcessSrvRqst(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SRVREG:
            ProcessSrvReg(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SRVDEREG:
            ProcessSrvDeReg(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SRVACK:
            ProcessSrvAck(peerinfo,message,sendbuf);        
            break;
    
        case SLP_FUNCT_ATTRRQST:
            ProcessAttrRqst(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_DAADVERT:
            ProcessDAAdvert(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SRVTYPERQST:
            ProcessSrvTypeRqst(peerinfo,message,sendbuf);
            break;
    
        case SLP_FUNCT_SAADVERT:
            ProcessSAAdvert(peerinfo,message,sendbuf);
            break;
    
        default:
            /* this will NEVER happen */
            break;
        }

        /* Log traceMsg of message was received and the one that will be sent */
        if(G_SlpdProperty.traceMsg)
        {
            SLPDLogTraceMsg(peerinfo,recvbuf,sendbuf);
        }
    }
    else
    {
        /* TODO: Log here? */
    }
    
    SLPMessageFree(message);

    return result;
}                
Пример #3
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;
}                
Пример #4
0
/*=========================================================================*/
SLPError SLPFindSrvTypes(SLPHandle    hSLP,
                         const char  *pcNamingAuthority,
                         const char  *pcScopeList,
                         SLPSrvTypeCallback callback,
                         void *pvCookie)
/*                                                                         */
/* Issue the query for service types on the language specific SLPHandle    */
/* and return the results through the callback.  The parameters determine  */
/* the results                                                             */
/*                                                                         */
/* hSLP              The language specific SLPHandle on which to search    */
/*                   for service types.                                    */
/*                                                                         */
/* pcNamingAuthority The Naming Authority string for which service types   */
/*                   for which service types are returned                  */
/*                                                                         */
/* pcScopeList      A pointer to a char containing comma separated list of */
/*                  scope names.  Pass in the NULL or the empty string ""  */
/*                  to find services in all the scopes the local host is   */
/*                  configured query.                                      */
/*                                                                         */
/* callback         A callback function through which the results of the   */
/*                  operation are reported. May not be NULL                */
/*                                                                         */
/* pvCookie         Memory passed to the callback code from the client.    */
/*                  May be NULL.                                           */
/*                                                                         */
/* Returns:         If an error occurs in starting the operation, one of   */
/*                  the SLPError codes is returned.                        */
/*                                                                         */
/*=========================================================================*/
{
    PSLPHandleInfo      handle;
    SLPError            result;

    /*------------------------------*/
    /* check for invalid parameters */
    /*------------------------------*/
    if(hSLP == 0 ||
       *(unsigned int*)hSLP != SLP_HANDLE_SIG ||
       !pcNamingAuthority ||
       strcmp(pcNamingAuthority, "IANA") == 0 ||
       callback == 0)
    {
        return SLP_PARAMETER_BAD;
    }

    /*-----------------------------------------*/
    /* cast the SLPHandle into a SLPHandleInfo */
    /*-----------------------------------------*/
    handle = (PSLPHandleInfo)hSLP; 

    /*-----------------------------------------*/
    /* Check to see if the handle is in use    */
    /*-----------------------------------------*/
    if(handle->inUse == SLP_TRUE)
    {
        return SLP_HANDLE_IN_USE;
    }
    handle->inUse = SLP_TRUE;

    /*-------------------------------------------*/
    /* Set the handle up to reference parameters */
    /*-------------------------------------------*/
    handle->params.findsrvtypes.namingauthlen = strlen(pcNamingAuthority);
    handle->params.findsrvtypes.namingauth = pcNamingAuthority;
    if(pcScopeList && *pcScopeList)
    {
        handle->params.findsrvtypes.scopelist = pcScopeList;
    }
    else
    {
        handle->params.findsrvtypes.scopelist =
        SLPGetProperty("net.slp.useScopes"); 
    }
    handle->params.findsrvtypes.scopelistlen =
    strlen(handle->params.findsrvtypes.scopelist); 
    handle->params.findsrvtypes.callback     = callback;
    handle->params.findsrvtypes.cookie       = pvCookie; 

    /*----------------------------------------------*/
    /* Check to see if we should be async or sync   */
    /*----------------------------------------------*/
#ifdef ENABLE_ASYNC_API
    if(handle->isAsync)
    {
        /* COPY all the referenced parameters */
        handle->params.findsrvtypes.namingauth = xstrdup(handle->params.findsrvtypes.namingauth);
        handle->params.findsrvtypes.scopelist = xstrdup(handle->params.findsrvtypes.scopelist);

        /* make sure strdups did not fail */
        if(handle->params.findsrvtypes.namingauth &&
           handle->params.findsrvtypes.scopelist)
        {
            result = ThreadCreate((ThreadStartProc)AsyncProcessSrvTypeRqst,handle);
        }
        else
        {
            result = SLP_MEMORY_ALLOC_FAILED;    
        }

        if(result)
        {
            if(handle->params.findsrvtypes.namingauth) xfree((void*)handle->params.findsrvtypes.namingauth);
            if(handle->params.findsrvtypes.scopelist) xfree((void*)handle->params.findsrvtypes.scopelist);
            handle->inUse = SLP_FALSE;
        }
    }
    else
#endif /*ifdef ENABLE_ASYNC_API*/
    {
        /* Leave all parameters REFERENCED */

        result = ProcessSrvTypeRqst(handle);

        handle->inUse = SLP_FALSE;
    }

    return result;
}
Пример #5
0
/*=========================================================================*/
int SLPDProcessMessage(struct sockaddr_in* peerinfo,
                       SLPBuffer recvbuf,
                       SLPBuffer* sendbuf)
/* Processes the recvbuf and places the results in sendbuf                 */
/*                                                                         */
/* recvfd   - 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.                          */
/*=========================================================================*/
{
    SLPMessage  message   = 0;
    int         errorcode  = 0;

    message = SLPMessageAlloc();
    if(message == 0)
    {
        return SLP_ERROR_INTERNAL_ERROR;
    }

    errorcode = SLPMessageParseBuffer(recvbuf, message);

#if defined(ENABLE_SLPv1)
    if(message->header.version == 1)
        return SLPDv1ProcessMessage(peerinfo, recvbuf, sendbuf,
                                    message, errorcode);
#endif




    /* Log trace message */
    SLPDLogTraceMsg("IN",peerinfo,recvbuf);

    switch(message->header.functionid)
    {
    case SLP_FUNCT_SRVRQST:
        errorcode = ProcessSrvRqst(peerinfo, message, sendbuf, errorcode);
        break;

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

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

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

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

    case SLP_FUNCT_DAADVERT:
        errorcode = ProcessDAAdvert(peerinfo, message, sendbuf, errorcode);
        /* If necessary log that we received a DAAdvert */
        SLPDLogDATrafficMsg("IN", peerinfo, message);
        break;

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

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

    default:
        /* This may happen on a really early parse error or version not */
        /* supported error */

        /* TODO log errorcode here */

        break;
    }

    /* Log traceMsg of message was received and the one that will be sent */
    SLPDLogTraceMsg("OUT",peerinfo,*sendbuf);

    SLPMessageFree(message);

    /* Log reception of important errors */
    switch(errorcode)
    {
    case SLP_ERROR_DA_BUSY_NOW:
        SLPLog("DA_BUSY from %s\n",
               inet_ntoa(peerinfo->sin_addr));
        break;
    case SLP_ERROR_INTERNAL_ERROR:
        SLPLog("INTERNAL_ERROR from %s\n",
               inet_ntoa(peerinfo->sin_addr));
        break;
    case SLP_ERROR_PARSE_ERROR:
        SLPLog("PARSE_ERROR from %s\n",
               inet_ntoa(peerinfo->sin_addr));
        break;
    case SLP_ERROR_VER_NOT_SUPPORTED:
        SLPLog("VER_NOT_SUPPORTED from %s\n",
               inet_ntoa(peerinfo->sin_addr));
        break;                    
    }

    return errorcode;
}                
Пример #6
0
/** Return a list of service types available on the network.
 *
 * The SLPFindSrvType function issues an SLP service type request for
 * service types in the scopes indicated by the @p pcScopeList. The
 * results are returned through the @p callback parameter. The service
 * types are independent of language locale, but only for services
 * registered in one of scopes and for the indicated naming authority.
 *
 * @par
 * If the naming authority is "*", then results are returned for all
 * naming authorities. If the naming authority is the empty string,
 * i.e. "", then the default naming authority, "IANA", is used. "IANA"
 * is not a valid naming authority name, and it is a PARAMETER_BAD error
 * to include it explicitly.
 *
 * @par
 * The service type names are returned with the naming authority intact.
 * If the naming authority is the default (i.e. empty string) then it
 * is omitted, as is the separating ".". Service type names from URLs
 * of the service: scheme are returned with the "service:" prefix
 * intact. [RFC 2608] See [RFC 2609] for more information on the 
 * syntax of service type names.
 *
 * @param[in] hSLP - The SLPHandle on which to search for types.
 * @param[in] pcNamingAuthority - The naming authority to search. Use "*" 
 *    for all naming authorities and the empty string, "", for the default 
 *    naming authority.
 * @param[in] pcScopeList - A pointer to a char containing comma separated 
 *    list of scope names to search for service types. May not be the empty
 *    string, "".
 * @param[in] callback - A callback function through which the results of 
 *    the operation are reported.
 * @param[in] pvCookie - Memory passed to the @p callback code from the 
 *    client. May be NULL.
 *
 * @return If an error occurs in starting the operation, one of the 
 *    SLPError codes is returned.
 */
SLPError SLPAPI SLPFindSrvTypes(
      SLPHandle hSLP,
      const char * pcNamingAuthority,
      const char * pcScopeList,
      SLPSrvTypeCallback callback,
      void * pvCookie)
{
   bool inuse;
   SLPError serr = 0;
   SLPHandleInfo * handle = hSLP;

   /* Check for invalid parameters. */
   SLP_ASSERT(handle != 0);
   SLP_ASSERT(handle->sig == SLP_HANDLE_SIG);
   SLP_ASSERT(pcNamingAuthority != 0);
   SLP_ASSERT(strcmp(pcNamingAuthority, "IANA") != 0);
   SLP_ASSERT(callback != 0);

   if (handle == 0 || handle->sig != SLP_HANDLE_SIG
         || pcNamingAuthority == 0 
         || strcmp(pcNamingAuthority, "IANA") == 0
         || callback == 0)
      return SLP_PARAMETER_BAD;

   /* Check to see if the handle is in use. */
   inuse = SLPSpinLockTryAcquire(&handle->inUse);
   SLP_ASSERT(!inuse);
   if (inuse)
      return SLP_HANDLE_IN_USE;

   /* Get a scope list if none was specified. */
   if (pcScopeList == 0 || *pcScopeList == 0)
      pcScopeList = SLPPropertyGet("net.slp.useScopes", 0, 0);

   /* Set the handle up to reference parameters. */
   handle->params.findsrvtypes.namingauthlen = strlen(pcNamingAuthority);
   handle->params.findsrvtypes.namingauth = pcNamingAuthority;
   handle->params.findsrvtypes.scopelistlen = strlen(pcScopeList); 
   handle->params.findsrvtypes.scopelist = pcScopeList;
   handle->params.findsrvtypes.callback = callback;
   handle->params.findsrvtypes.cookie = pvCookie; 

   /* Check to see if we should be async or sync. */
#ifdef ENABLE_ASYNC_API
   if (handle->isAsync)
   {
      /* Copy all the referenced parameters. */
      handle->params.findsrvtypes.namingauth = 
            xstrdup(handle->params.findsrvtypes.namingauth);
      handle->params.findsrvtypes.scopelist = 
            xstrdup(handle->params.findsrvtypes.scopelist);

      /* Ensure strdups and thread create succeed. */
      if (handle->params.findsrvtypes.namingauth == 0
            || handle->params.findsrvtypes.scopelist == 0
            || (handle->th = SLPThreadCreate((SLPThreadStartProc)
                  AsyncProcessSrvTypeRqst, handle)) == 0)
      {
         serr = SLP_MEMORY_ALLOC_FAILED;
         xfree((void *)handle->params.findsrvtypes.namingauth);
         xfree((void *)handle->params.findsrvtypes.scopelist);
         SLPSpinLockRelease(&handle->inUse);
      }
      return serr;
   }
#endif

   /* Reference all parameters. */
   serr = ProcessSrvTypeRqst(handle);
   SLPSpinLockRelease(&handle->inUse);
   return serr;
}