예제 #1
0
/** Thread start procedure for asynchronous find services request.
 *
 * @param[in,out] handle - Contains the request parameters, returns the
 *    request result.
 *
 * @return An SLPError code.
 *
 * @internal
 */
static SLPError AsyncProcessSrvRqst(SLPHandleInfo * handle)
{
   SLPError serr = ProcessSrvRqst(handle);
   xfree((void *)handle->params.findsrvs.srvtype);
   xfree((void *)handle->params.findsrvs.scopelist);
   xfree((void *)handle->params.findsrvs.predicate);
   SLPSpinLockRelease(&handle->inUse);
   return serr;
}
예제 #2
0
/*-------------------------------------------------------------------------*/ 
SLPError AsyncProcessSrvRqst(PSLPHandleInfo handle)
/*-------------------------------------------------------------------------*/
{
    SLPError result = ProcessSrvRqst(handle);
    xfree((void*)handle->params.findsrvs.srvtype);
    xfree((void*)handle->params.findsrvs.scopelist);
    xfree((void*)handle->params.findsrvs.predicate);
    handle->inUse = SLP_FALSE;
    return result;
}
예제 #3
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;
}                
예제 #4
0
/*=========================================================================*/
SLPError SLPAPI SLPFindSrvs(SLPHandle  hSLP,
                     const char *pcServiceType,
                     const char *pcScopeList,
                     const char *pcSearchFilter,
                     SLPSrvURLCallback callback,
                     void *pvCookie)
/*                                                                         */
/* Issue the query for services 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 */
/*                  services.                                              */
/*                                                                         */
/* pcServiceType    The Service Type String, including authority string if */
/*                  any, for the request, such as can be discovered using  */
/*                  SLPSrvTypes(). This could be, for example              */
/*                  "service:printer:lpr" or "service:nfs".  May not be    */
/*                  the empty string or NULL.                              */
/*                                                                         */
/*                                                                         */
/* 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.                                      */
/*                                                                         */
/* pcSearchFilter   A query formulated of attribute pattern matching       */
/*                  expressions in the form of a LDAPv3 Search Filter.     */
/*                  If this filter is NULL or empty, i.e.  "", all         */
/*                  services of the requested type in the specified scopes */
/*                  are returned.                                          */
/*                                                                         */
/* 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 ||
       pcServiceType   == 0 ||
       *pcServiceType  == 0 ||  /* srvtype can't be empty string */
       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.findsrvs.srvtypelen   = strlen(pcServiceType);
    handle->params.findsrvs.srvtype      = pcServiceType;
    if(pcScopeList && *pcScopeList)
    {
        handle->params.findsrvs.scopelistlen = strlen(pcScopeList);
        handle->params.findsrvs.scopelist    = pcScopeList;
    }
    else
    {
        handle->params.findsrvs.scopelist    = SLPGetProperty("net.slp.useScopes");
        handle->params.findsrvs.scopelistlen = strlen(handle->params.findsrvs.scopelist);
    }

    if(pcSearchFilter)
    {
        handle->params.findsrvs.predicatelen = strlen(pcSearchFilter);
        handle->params.findsrvs.predicate    = pcSearchFilter;
    }
    else
    {
        handle->params.findsrvs.predicatelen = 0;
        handle->params.findsrvs.predicate  = (char*)&handle->params.findsrvs.predicatelen;
    }
    handle->params.findsrvs.callback     = callback;
    handle->params.findsrvs.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.findsrvs.srvtype = xstrdup(handle->params.findsrvs.srvtype);
        handle->params.findsrvs.scopelist = xstrdup(handle->params.findsrvs.scopelist);
        handle->params.findsrvs.predicate = xstrdup(handle->params.findsrvs.predicate);

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

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

        result = ProcessSrvRqst(handle);

        handle->inUse = SLP_FALSE;
    }

    return result;
}
예제 #5
0
/** Return a list of service matching a query specification.
 *
 * Issue the query for services on the language specific SLPHandle and
 * return the results through the @p callback. The parameters determine
 * the results.
 *
 * @param[in] hSLP - The language specific SLPHandle on which to search 
 *    for services.
 * @param[in] pcServiceType - The Service Type String, including authority 
 *    string if any, for the request, such as can be discovered using 
 *    SLPSrvTypes. This could be, for example "service:printer:lpr" or
 *    "service:nfs". May not be the empty string or NULL.
 * @param[in] pcScopeList - A pointer to a char containing a comma-separated 
 *    list of scope names. Pass in NULL or the empty string ("") to find 
 *    services in all the scopes the local host is configured to query.
 * @param[in] pcSearchFilter - A query formulated of attribute pattern 
 *    matching expressions in the form of a LDAPv3 Search Filter, see 
 *    [RFC 2254]. If this filter is empty, i.e. "" or NULL, all services 
 *    of the requested type in the specified scopes are returned.
 * @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.
 */
SLPEXP SLPError SLPAPI SLPFindSrvs(
      SLPHandle hSLP,
      const char * pcServiceType,
      const char * pcScopeList,
      const char * pcSearchFilter,
      SLPSrvURLCallback 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(pcServiceType != 0);
   SLP_ASSERT(*pcServiceType != 0);
   SLP_ASSERT(callback != 0);

   if (handle == 0 || handle->sig != SLP_HANDLE_SIG 
         || pcServiceType == 0 || *pcServiceType == 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 not supplied. */
   if (pcScopeList == 0 || *pcScopeList == 0)
      pcScopeList = SLPPropertyGet("net.slp.useScopes", 0, 0);

   /* Ensure there's a scope list of some sort... */
   if (pcScopeList == 0)
      pcScopeList = "";

   /* Get a search filter if not supplied */
   if (pcSearchFilter == 0)
      pcSearchFilter = "";

   /* Set the handle up to reference parameters. */
   handle->params.findsrvs.srvtypelen = strlen(pcServiceType);
   handle->params.findsrvs.srvtype = pcServiceType;
   handle->params.findsrvs.scopelistlen = strlen(pcScopeList);
   handle->params.findsrvs.scopelist = pcScopeList;
   handle->params.findsrvs.predicatelen = strlen(pcSearchFilter);
   handle->params.findsrvs.predicate = pcSearchFilter;
   handle->params.findsrvs.callback = callback;
   handle->params.findsrvs.cookie = pvCookie; 

   /* Check to see if we should be async or sync. */
#ifdef ENABLE_ASYNC_API
   if (handle->isAsync)
   {
      /* Copy all of the referenced parameters before creating thread. */
      handle->params.findsrvs.srvtype = xstrdup(handle->params.findsrvs.srvtype);
      handle->params.findsrvs.scopelist = xstrdup(handle->params.findsrvs.scopelist);
      handle->params.findsrvs.predicate = xstrdup(handle->params.findsrvs.predicate);

      /* Ensure strdups and thread create succeed. */
      if (handle->params.findsrvs.srvtype == 0
            || handle->params.findsrvs.scopelist == 0
            || handle->params.findsrvs.predicate == 0
            || (handle->th = SLPThreadCreate((SLPThreadStartProc)
                  AsyncProcessSrvRqst, handle)) == 0)
      {
         serr = SLP_MEMORY_ALLOC_FAILED;    
         xfree((void *)handle->params.findsrvs.srvtype);
         xfree((void *)handle->params.findsrvs.scopelist);
         xfree((void *)handle->params.findsrvs.predicate);
         SLPSpinLockRelease(&handle->inUse);
      }
   }
   else
#endif
   {
      /* Leave all parameters referenced. */
      serr = ProcessSrvRqst(handle);
      SLPSpinLockRelease(&handle->inUse);
   }
   return serr;
}
예제 #6
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;
}                
예제 #7
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;
}