Ejemplo n.º 1
0
/** Release all unused socket on inbound socket list.
 *
 * Deinitialize incoming socket list to have appropriate sockets for all
 * network interfaces.
 *
 * @param[in] graceful - Flag indicates do NOT close sockets with pending 
 *    writes outstanding.
 *
 * @return Zero on success, or a non-zero value when pending writes 
 *    remain.
 */
int SLPDOutgoingDeinit(int graceful)
{
   SLPDSocket * del = 0;
   SLPDSocket * sock = (SLPDSocket *) G_OutgoingSocketList.head;

   while (sock)
   {
      /* graceful only closes sockets without pending I/O */
      if (graceful == 0)
         del = sock;
      else if (sock->state < SOCKET_PENDING_IO)
         del = sock;

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

      if (del)
      {
         SLPDSocketFree((SLPDSocket *)
               SLPListUnlink(&G_OutgoingSocketList, (SLPListItem *) del));
         del = 0;
      }
   }

   return G_OutgoingSocketList.count;
}
Ejemplo n.º 2
0
/*=========================================================================*/
int KnownDABadDA(struct sockaddr_in* peeraddr)
/* Mark a KnownDA as a Bad DA.                                             */
/*                                                                         */
/* peeraddr (IN) address of the bad DA                                     */
/*                                                                         */
/* Returns: zero on success.                                               */
/*=========================================================================*/
{
    SLPDAEntry* entry;

    entry = (SLPDAEntry*)G_KnownDACache.head;
    while(entry)
    {
        if(memcmp(&(peeraddr->sin_addr),
                  &(entry->daaddr),
                  sizeof(struct in_addr)) == 0)
        {
            /* Remove entry from list and free it */
            SLPDAEntryFree( (SLPDAEntry*)SLPListUnlink(&G_KnownDACache,
                                                       (SLPListItem*)entry) );
            break;
        }
        entry = (SLPDAEntry*) entry->listitem.next;
    }

    return 0;
}
Ejemplo n.º 3
0
/*=========================================================================*/
int SLPDOutgoingDeinit(int graceful)
/* Deinitialize incoming socket list to have appropriate sockets for all   */
/* network interfaces                                                      */
/*                                                                         */
/* graceful (IN) Do not close sockets with pending writes                  */
/*                                                                         */
/* Returns  Zero on success non-zero when pending writes remain            */
/*=========================================================================*/
{
    SLPDSocket* del  = 0;
    SLPDSocket* sock = (SLPDSocket*)G_OutgoingSocketList.head;

    while ( sock )
    {
        /* graceful only closes sockets without pending I/O */
        if ( graceful == 0 )
        {
            del = sock;
        }
        else if ( sock->state < SOCKET_PENDING_IO )
        {
            del = sock;
        }

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

        if ( del )
        {
            SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_OutgoingSocketList,(SLPListItem*)del));
            del = 0;
        }
    }

    return G_OutgoingSocketList.count;
}
Ejemplo n.º 4
0
/*=========================================================================*/
void SLPDDatabaseAge(int seconds)
/* Agea the database entries and clears new and deleted entry lists        */
/*                                                                         */
/* seconds  (IN) the number of seconds to age each entry by                */
/*                                                                         */
/* Returns  - None                                                         */
/*=========================================================================*/
{
    SLPDDatabaseEntry* entry;
    SLPDDatabaseEntry* del   = 0;

    /* Age the database */
    entry = (SLPDDatabaseEntry*)G_DatabaseList.head;
    while(entry)
    {
        /* don't age services with lifetime > SLP_LIFETIME_MAXIMUM */
        if(entry->lifetime < SLP_LIFETIME_MAXIMUM)
    	{
            entry->lifetime = entry->lifetime - seconds;
            if(entry->lifetime <= 0)
            {
                del = entry;
            }
    	}
        
        entry = (SLPDDatabaseEntry*)entry->listitem.next;

        if(del)
        {
            FreeEntry((SLPDDatabaseEntry*)SLPListUnlink(&G_DatabaseList,(SLPListItem*)del));
            del = 0;
        }                                                               
    }
}
Ejemplo n.º 5
0
/*=========================================================================*/
int SLPDDatabaseReInit(const char* regfile)
/* Re-initialize the database with changed registrations from a regfile.   */
/*                                                                         */
/* regfile  (IN)    the regfile to register.                               */
/*                                                                         */
/* Returns  - zero on success or non-zero on error.                        */
/*=========================================================================*/
{
    /* Delete all static registrations */
    SLPDDatabaseEntry* del;
    SLPDDatabaseEntry* entry = (SLPDDatabaseEntry*)G_DatabaseList.head;

    /* delete all the static entries */
    while(entry)
    {
        if(entry->regtype & SLPDDATABASE_REG_STATIC)
        {
            del = entry;
            entry = (SLPDDatabaseEntry*) entry->listitem.next;
            SLPDDatabaseEntryFree((SLPDDatabaseEntry*)SLPListUnlink(&G_DatabaseList,
                                  (SLPListItem*)del));
        }
        else
        {
            entry = (SLPDDatabaseEntry*) entry->listitem.next;
        }
    }

    /* reload all the static entries by calling the init function */
    return SLPDDatabaseInit(regfile);
}
Ejemplo n.º 6
0
/*=========================================================================*/
void SLPDSocketFree(SLPDSocket* sock)
/* Frees memory associated with the specified SLPDSocket                   */
/*                                                                         */
/* sock (IN) pointer to the socket to free                                 */
/*=========================================================================*/
{
    /* close the socket descriptor */
    CloseSocket(sock->fd);

    /* free receive buffer */
    if(sock->recvbuf)
    {
        SLPBufferFree(sock->recvbuf);
    }

    /* free send buffer(s) */
    if(sock->sendlist.count)
    {
        while(sock->sendlist.count)
        {
            SLPBufferFree((SLPBuffer)SLPListUnlink(&(sock->sendlist), sock->sendlist.head));
        }
    }
    else if(sock->sendbuf)
    {
        SLPBufferFree(sock->sendbuf);                        
    }

    /* free the actual socket structure */
    xfree(sock);
}
Ejemplo n.º 7
0
/*=========================================================================*/
void _xfree(const char* file,
            int line,
            void* buf)
/*=========================================================================*/
{
    xallocation_t* x;
     
    x =_xmalloc_find(buf);
    if(x == NULL)
    {
        if(G_xmalloc_fh)
        {
            fprintf(G_xmalloc_fh, 
                    "*** xfree called on non xmalloced memory ***\n");
        }

        return;
    }

    if(G_xmalloc_fh)
    {
        fprintf(G_xmalloc_fh,"Called xfree() %s:%i ",file,line);
        _xmalloc_log(x);
    }
    
    G_xmalloc_allocmem -= x->size;
    
    free(x->buf);
    
    free(SLPListUnlink(&G_xmalloc_list, (SLPListItem*)x));
}
Ejemplo n.º 8
0
/*-------------------------------------------------------------------------*/
void LoadFdSets(SLPList* socklist, 
                int* highfd, 
                fd_set* readfds, 
                fd_set* writefds)
/*-------------------------------------------------------------------------*/
{
    SLPDSocket* sock = 0;
    SLPDSocket* del = 0;

    sock = (SLPDSocket*)socklist->head;
    while(sock)
    {
        if(sock->fd > *highfd)
        {
            *highfd = sock->fd;
        }

        switch(sock->state)
        {
        case DATAGRAM_UNICAST:
        case DATAGRAM_MULTICAST:
        case DATAGRAM_BROADCAST:
            FD_SET(sock->fd,readfds);
            break;

        case SOCKET_LISTEN:
            if(socklist->count < SLPD_MAX_SOCKETS)
            {
                FD_SET(sock->fd,readfds);
            }
            break;

        case STREAM_READ:
        case STREAM_READ_FIRST:
            FD_SET(sock->fd,readfds);
            break;

        case STREAM_WRITE:
        case STREAM_WRITE_FIRST:
        case STREAM_CONNECT_BLOCK:
            FD_SET(sock->fd,writefds);
            break;

        case SOCKET_CLOSE:
            del = sock;
            break;

        default:
            break;
        }

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

        if(del)
        {
            SLPDSocketFree((SLPDSocket*)SLPListUnlink(socklist,(SLPListItem*)del));     
            del = 0;
        }
    }
}
Ejemplo n.º 9
0
/*-------------------------------------------------------------------------*/
void FreeAllEntries(SLPList* list)
/*-------------------------------------------------------------------------*/
{
    while(list->count)
    {
        FreeEntry((SLPDDatabaseEntry*)SLPListUnlink(list,list->head));
    }
}
Ejemplo n.º 10
0
/*=========================================================================*/
void SLPDDatabaseDeinit()
/* De-initialize the database.  Free all resources taken by registrations  */
/*=========================================================================*/
{
    while(G_DatabaseList.count)
    {
        SLPDDatabaseEntryFree((SLPDDatabaseEntry*)SLPListUnlink(&G_DatabaseList,
                              G_DatabaseList.head));
    }
}
Ejemplo n.º 11
0
/** Set a new value for a property by name.
 * 
 * If the value is NULL or empty, then simply erase the existing value and
 * return.
 *
 * @param[in] name - The name of the desired property.
 * @param[in] value - The new value to which @p name should be set or
 *    NULL if the existing value should be removed.
 * @param[in] attrs - The attributes of this property - zero means no
 *    attributes are assigned, other values include SLP_PA_USERSET and 
 *    SLP_PA_READONLY.
 *
 * @return Zero on success; -1 on error, with errno set.
 * 
 * @remarks The @p attrs parameter contains a set of bit flags indicating
 * various attributes of the property. These attributes control write 
 * permissions mostly. SLP_PA_USERSET means that an attribute may not
 * be changed by reading a configuration file, except in a complete 
 * re-initialization scenario. SLP_PA_READONLY sounds like the same thing, 
 * but it's not. The difference is that once set, properties with the 
 * SLP_PA_READONLY attribute may NEVER be reset (again, except in a complete 
 * re-initialization scenario), while properties with the SLP_PA_USERSET 
 * attribute may only be reset by passing this same flag in @p attrs, 
 * indicating that the caller is actually a user, and so has the right
 * to reset the property value.
 */
int SLPPropertySet(char const * name, char const * value, unsigned attrs)
{
   size_t namesz, valuesz;
   SLPProperty * oldprop;
   SLPProperty * newprop = 0;    /* we may be just removing the old */
   bool update = true;           /* reset if old property exists */

   /* property names must not be null or empty */
   SLP_ASSERT(name && *name);
   if (!name || !*name)
      return -1;

   if (value)
   {
      /* allocate property entry for this new value */
      namesz = strlen(name) + 1;
      valuesz = strlen(value) + 1;
      if ((newprop = (SLPProperty*)xmalloc(
            sizeof(SLPProperty) - 1 + namesz + valuesz)) == 0)
      {
         errno = ENOMEM;
         return -1;
      }

      /* set internal pointers to trailing buffer space, copy values */
      newprop->attrs = attrs;
      memcpy(newprop->name, name, namesz);
      newprop->value = newprop->name + namesz;
      memcpy(newprop->value, value, valuesz);
   }

   SLPMutexAcquire(s_PropDbLock);

   /* locate and possibly remove old property */
   if ((oldprop = Find(name))!= 0)
   {
      /* update ONLY if old is clean, or new and old are user-settable . */
      update = !oldprop->attrs 
            || (oldprop->attrs == SLP_PA_USERSET && attrs == SLP_PA_USERSET);
      if (update)
         SLPListUnlink(&s_PropertyList, (SLPListItem *)oldprop);
   }

   /* link in new property, if specified and old property was removed */
   if (newprop && update)
      SLPListLinkHead(&s_PropertyList, (SLPListItem *)newprop);

   SLPMutexRelease(s_PropDbLock);

   /* if old property was not removed, delete the new one instead */
   xfree(update? oldprop: newprop);

   return update? 0: ((errno = EACCES), -1);
}
Ejemplo n.º 12
0
/** Initialize outgoing socket list for all network interfaces.
 *
 * @return Zero - always.
 */
int SLPDOutgoingInit(void)
{
   /*------------------------------------------------------------*/
   /* First, remove all of the sockets that might be in the list */
   /*------------------------------------------------------------*/
   while (G_OutgoingSocketList.count)
      SLPDSocketFree((SLPDSocket *)
            SLPListUnlink(&G_OutgoingSocketList,
                  (SLPListItem *) G_OutgoingSocketList.head));

   return 0;
}
Ejemplo n.º 13
0
/** Deinitialize the debug memory allocator.
 */
void xmalloc_deinit(void)
{
   xmalloc_report();

   if (G_xmalloc_fh)
   {
      fclose(G_xmalloc_fh);
      G_xmalloc_fh = NULL;
   }
   while (G_xmalloc_list.count)
      free(SLPListUnlink(&G_xmalloc_list, G_xmalloc_list.head));

   memset(&G_xmalloc_list, 0, sizeof(G_xmalloc_list));
}
Ejemplo n.º 14
0
/*=========================================================================*/
int SLPDDatabaseDeReg(SLPSrvDeReg* srvdereg)
/* Remove a service registration from the database                         */
/*                                                                         */
/* regfile  -   (IN) filename of the registration file to read into the    */
/*              database. Pass in NULL for no file.                        */
/*                                                                         */
/* Returns  -   Zero on success.  Non-zero if syntax error in registration */
/*              file.                                                      */
/*=========================================================================*/

{
    SLPDDatabaseEntry* del = 0;
    SLPDDatabaseEntry* entry = (SLPDDatabaseEntry*)G_DatabaseList.head;


    while(entry)
    {
        if(SLPCompareString(entry->urllen,
                            entry->url,
                            srvdereg->urlentry.urllen,
                            srvdereg->urlentry.url) == 0)
        {
            if(SLPIntersectStringList(entry->scopelistlen,
                                      entry->scopelist,
                                      srvdereg->scopelistlen,
                                      srvdereg->scopelist) > 0)
            {
                if(G_SlpdProperty.traceReg)
                {
                    SLPDLogTraceReg("SrvDeReg",entry);
                }
                
                del = entry;
                
                break;
            } 
        }             
        
        entry = (SLPDDatabaseEntry*) entry->listitem.next;

        if(del)
        {
            FreeEntry((SLPDDatabaseEntry*)SLPListUnlink(&G_DatabaseList,(SLPListItem*)del));
            del = 0;
        }
    }

    return 0;
}
Ejemplo n.º 15
0
/*=========================================================================*/
void xmalloc_deinit()
/*=========================================================================*/
{
    xmalloc_report();

    if(G_xmalloc_fh)
    {
        fclose(G_xmalloc_fh);
    }

    while(G_xmalloc_list.count)
    {
        free((xallocation_t*)SLPListUnlink(&G_xmalloc_list,G_xmalloc_list.head));
    }
    memset(&G_xmalloc_list,0,sizeof(G_xmalloc_list));
}
Ejemplo n.º 16
0
/*=========================================================================*/
int KnownDAConnect(const char* scopelist, 
                   int scopelistlen,
                   struct sockaddr_in* peeraddr,
                   struct timeval* timeout)
/*=========================================================================*/
{
    int                 sock;
    SLPDAEntry*         entry;
    SLPDAEntry*         del   = 0;
    
    /* TODO THIS FUNCTION MUST BE SYNCRONIZED !! */

    memset(peeraddr,0,sizeof(struct sockaddr_in));
    peeraddr->sin_family = AF_INET;
    peeraddr->sin_port   = htons(SLP_RESERVED_PORT);

    entry = (SLPDAEntry*)G_KnownDAList.head;
    while(entry)
    {
        if(SLPIntersectStringList(entry->scopelistlen,
                                  entry->scopelist,
                                  scopelistlen,
                                  scopelist))
        {
            peeraddr->sin_addr   = entry->daaddr;
            sock = SLPNetworkConnectStream(peeraddr,timeout);
            if(sock >= 0)
            {
                return sock;
            }

            del = entry;
        }
        
        entry = (SLPDAEntry*) entry->listitem.next;

        if (del)
        {
          SLPDAEntryFree((SLPDAEntry*)SLPListUnlink(&G_KnownDAList,(SLPListItem*)del));
          KnownDASaveHints();
        }

    }

    return -1;
}
Ejemplo n.º 17
0
/*-------------------------------------------------------------------------*/
int SlpPerfTest1_slpdereg (SLPHandle hslp, 
                           SLPList* service_list,
                           double* ave_slpdereg,
                           int* count_slpdereg)
/*-------------------------------------------------------------------------*/
{
    struct timezone tz;
    struct timeval  start;
    struct timeval  end;
    TestService_T*  srv;
    SLPError        errorcode;
    
    srv = FindRandomTestService(service_list);

       /* mark start time */
    gettimeofday(&start,&tz);
    
    /* call SLP API */
    errorcode = SLPDereg(hslp,
                         srv->serviceurl,
                         SlpPerfTest1_deregreport,
                         srv);
    if(errorcode != SLP_OK)
    {
        printf("SLPDereg(hslp,%s,callback,0) returned %i\n",
               srv->serviceurl,
               errorcode);
        
        printf("This should not happen!\n");
        
        return -1;
    }

    /* mark end time */
    gettimeofday(&end,&tz);
    
    /* unlink the registered service from the list and free it*/
    free(SLPListUnlink(service_list,(SLPListItem*)srv));

    /* recalculate average time */
    *ave_slpdereg = (*ave_slpdereg) * (*count_slpdereg) + ElapsedTime(&start,&end);
    *count_slpdereg = *count_slpdereg + 1;
    *ave_slpdereg = *ave_slpdereg / *count_slpdereg;

    return 0;
}
Ejemplo n.º 18
0
/*=========================================================================*/
void SLPDDatabaseAge(int seconds, int ageall)
/* Agea the database entries and clears new and deleted entry lists        */
/*                                                                         */
/* seconds  (IN) the number of seconds to age each entry by                */
/*																		   */
/* ageall   (IN) age even entries with SLP_LIFETIME_MAX					   */
/*                                                                         */
/* Returns  - None                                                         */
/*=========================================================================*/
{
    SLPDDatabaseEntry* entry;
    SLPDDatabaseEntry* del   = 0;

    /* Age the database */
    entry = (SLPDDatabaseEntry*)G_DatabaseList.head;
    while(entry)
    {
        /*-----------------------------------------------------------*/
        /* OK, if an entry is local and has a lifetime of 			 */
        /* SLP_LIFETIME_MAXIMUM then it must never ever ever be aged */
        /*-----------------------------------------------------------*/
        if(!(entry->regtype & SLPDDATABASE_REG_LOCAL && entry->lifetime == SLP_LIFETIME_MAXIMUM))
        {
            /*---------------------------------------------------------*/
            /* don't age services with lifetime > SLP_LIFETIME_MAXIMUM */
            /* unless explicitly told to                               */
            /*---------------------------------------------------------*/
            if(ageall ||
                    entry->lifetime < SLP_LIFETIME_MAXIMUM)
            {
                entry->lifetime = entry->lifetime - seconds;
                if(entry->lifetime <= 0)
                {
                    del = entry;
                }
            }
        }

        entry = (SLPDDatabaseEntry*)entry->listitem.next;
        if(del)
        {
            SLPDDatabaseEntryFree((SLPDDatabaseEntry*)SLPListUnlink(&G_DatabaseList,(SLPListItem*)del));
            del = 0;
        }
    }
}
Ejemplo n.º 19
0
/*=========================================================================*/
void SLPDIncomingAge(time_t seconds)
/*=========================================================================*/
{
    SLPDSocket* del  = 0;
    SLPDSocket* sock = (SLPDSocket*)G_IncomingSocketList.head;
    while (sock)
    {
        switch (sock->state)
        {
        case STREAM_READ_FIRST:
        case STREAM_READ:
        case STREAM_WRITE_FIRST:
        case STREAM_WRITE:
            if (G_IncomingSocketList.count > SLPD_COMFORT_SOCKETS)
            {
                /* Accellerate ageing cause we are low on sockets */
                if (sock->age > SLPD_CONFIG_BUSY_CLOSE_CONN)
                {
                    del = sock;
                }
            }
            else
            {
                if (sock->age > SLPD_CONFIG_CLOSE_CONN)
                {
                    del = sock;
                }
            }
            sock->age = sock->age + seconds;
            break;

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

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

        if (del)
        {
            SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_IncomingSocketList,(SLPListItem*)del));
            del = 0;
        }
    }                                                 
}
Ejemplo n.º 20
0
/*=========================================================================*/
void SLPDIncomingAge(time_t seconds)
/*=========================================================================*/
{
    SLPDSocket* del  = 0;
    SLPDSocket* sock = (SLPDSocket*)G_IncomingSocketList.head;
    while(sock)
    {
      	switch (sock->state)
        {
    	case STREAM_READ_FIRST:
    	case STREAM_READ:
    	case STREAM_WRITE_FIRST:
    	case STREAM_WRITE:
    	    sock->age = sock->age + seconds;
    	    if(G_IncomingSocketList.count > SLPD_COMFORT_SOCKETS)
            {
                if (sock->age > G_SlpdProperty.unicastMaximumWait)
                {
                    del = sock;
    		    }                                   
            }
            else
            {
                if (sock->age > SLPD_MAX_SOCKET_LIFETIME)
                {
                    del = sock;
                }
            }
    	    break;
    	
    	default:
    	    /* don't age the other sockets at all */
    	    break;
        }
        	
        sock = (SLPDSocket*)sock->listitem.next;

    	if(del)
    	{
    	    SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_IncomingSocketList,(SLPListItem*)del));
            del = 0;
    	}   
    }                                                 
}
Ejemplo n.º 21
0
/*=========================================================================*/
int SLPDOutgoingInit()
/* Initialize outgoing socket list to have appropriate sockets for all     */
/* network interfaces                                                      */
/*                                                                         */
/* list     (IN/OUT) pointer to a socket list to be filled with sockets    */
/*                                                                         */
/* Returns  Zero on success non-zero on error                              */
/*=========================================================================*/
{
    /*------------------------------------------------------------*/
    /* First, remove all of the sockets that might be in the list */
    /*------------------------------------------------------------*/
    while ( G_OutgoingSocketList.count )
    {
        SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_OutgoingSocketList,(SLPListItem*)G_OutgoingSocketList.head));
    }

    return 0;
}
Ejemplo n.º 22
0
/*=========================================================================*/
int SLPDIncomingDeinit()
/* Deinitialize incoming socket list to have appropriate sockets for all   */
/* network interfaces                                                      */
/*                                                                         */
/* Returns  Zero on success non-zero on error                              */
/*=========================================================================*/
{
    SLPDSocket* del  = 0;
    SLPDSocket* sock = (SLPDSocket*)G_IncomingSocketList.head;
    while (sock)
    {
        del = sock;
        sock = (SLPDSocket*)sock->listitem.next;
        if (del)
        {
            SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_IncomingSocketList,(SLPListItem*)del));
            del = 0;
        }
    } 

    return 0;
}
Ejemplo n.º 23
0
/** Free's a block of memory (DEBUG).
 *
 * @param[in] file - The file where @e xfree was called.
 * @param[in] line - The line number where @e xfree was called.
 * @param[in] ptr - The address of the block to be free'd.
 */
void _xfree(const char * file, int line, void * ptr)
{
   xallocation_t * x;

   x =_xmalloc_find(ptr);
   if (x == 0)
   {
      if (G_xmalloc_fh)
         fprintf(G_xmalloc_fh, "*** xfree called on "
               "non-xmalloc'd memory ***\n");
      return;
   }
   if (G_xmalloc_fh)
   {
      fprintf(G_xmalloc_fh, "Called xfree at %s:%i ", file, line);
      _xmalloc_log(x);
   }

   G_xmalloc_allocmem -= x->size;

   free(x->buf);
   free(SLPListUnlink(&G_xmalloc_list, (SLPListItem *)x));
}
Ejemplo n.º 24
0
/*-------------------------------------------------------------------------*/
int KnownDAListRemove(SLPList* dalist, SLPDAEntry* remove)
/* Remove an entry to the KnownDA cach                                     */
/*-------------------------------------------------------------------------*/
{
    SLPDAEntry*     entry;

    entry = (SLPDAEntry*)dalist->head;
    while(entry)
    {
        if(SLPCompareString(remove->urllen,
                            remove->url,
                            entry->urllen,
                            entry->url) == 0)
        {
            /* Remove entry from list and free it */
            SLPDAEntryFree( (SLPDAEntry*)SLPListUnlink(dalist, (SLPListItem*)entry) );
            break;
        }

        entry = (SLPDAEntry*) entry->listitem.next;
    }

    return 0;
}
Ejemplo n.º 25
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;
}                
Ejemplo n.º 26
0
/*=========================================================================*/
int SLPPropertySet(const char *pcName,
                   const char *pcValue)
/*=========================================================================*/
{
    int             pcNameSize; 
    int             pcValueSize;
    SLPProperty*    newProperty; 

    if(pcValue == 0)
    {
       /* Bail for right now */
       return 0;
    }
    
    newProperty = Find(pcName);
    pcNameSize = strlen(pcName) + 1;
    pcValueSize = strlen(pcValue) + 1;

    if(newProperty == 0)
    {
        /* property does not exist in the list */
        newProperty = (SLPProperty*)xmalloc(sizeof(SLPProperty) + pcNameSize + pcValueSize);
        if(newProperty == 0)
        {
            /* out of memory */
            errno = ENOMEM;
            return -1;
        }

        /* set the pointers in the SLPProperty structure to point to areas of    */
        /* the previously allocated block of memory                              */
        newProperty->propertyName   = ((char*)newProperty) + sizeof(SLPProperty); 
        newProperty->propertyValue  = newProperty->propertyName + pcNameSize;

        /* copy the passed in name and value */
        memcpy(newProperty->propertyName,pcName,pcNameSize);
        memcpy(newProperty->propertyValue,pcValue,pcValueSize);

        /* Link the new property into the list */
        SLPListLinkHead(&G_SLPPropertyList,(SLPListItem*)newProperty);
    }
    else
    {
        SLPListUnlink(&G_SLPPropertyList,(SLPListItem*)newProperty);

        /* property already exists in the list */
        newProperty = (SLPProperty*)xrealloc(newProperty,sizeof(SLPProperty) + pcNameSize + pcValueSize);    
        if(newProperty == 0)
        {
            /* out of memory */
            errno = ENOMEM;
            return -1;
        }

        /* set the pointers in the SLPProperty structure to point to areas of    */
        /* the previously allocated block of memory                              */
        newProperty->propertyName   = ((char*)newProperty) + sizeof(SLPProperty); 
        newProperty->propertyValue  = newProperty->propertyName + pcNameSize;

        /* copy the passed in name and value */
        memcpy(newProperty->propertyName,pcName,pcNameSize);
        memcpy(newProperty->propertyValue,pcValue,pcValueSize);

        SLPListLinkHead(&G_SLPPropertyList,(SLPListItem*)newProperty);
    }

    return 0;
}
Ejemplo n.º 27
0
/*-------------------------------------------------------------------------*/
SLPBoolean ColateSLPSrvURLCallback(SLPHandle hSLP,
                                   const char* pcSrvURL,
                                   unsigned short sLifetime,
                                   SLPError errCode,
                                   void *pvCookie)
/*-------------------------------------------------------------------------*/
{
    SLPSrvUrlColatedItem*   collateditem;
    PSLPHandleInfo          handle;
        
    handle = (PSLPHandleInfo) hSLP;
    handle->callbackcount ++;
    
#ifdef ENABLE_ASYNC_API
    /* Do not colate for async calls */
    if(handle->isAsync)
    {
        return handle->params.findsrvs.callback(hSLP,
                                                pcSrvURL,
                                                sLifetime,
                                                errCode,
                                                pvCookie);
    }
#endif
    
    if(errCode == SLP_LAST_CALL || 
       handle->callbackcount > SLPPropertyAsInteger(SLPGetProperty("net.slp.maxResults")))
    {
        /* We are done so call the caller's callback for each      */
        /* service URL colated item and clean up the colation list */
        handle->params.findsrvs.callback((SLPHandle)handle,
                                         NULL,
                                         0,
                                         SLP_LAST_CALL,
                                         handle->params.findsrvs.cookie);
        goto CLEANUP;
    }
    else if(errCode != SLP_OK)
    {
        return SLP_TRUE;
    }

    /* Add the service URL to the colation list */
    collateditem = (SLPSrvUrlColatedItem*) handle->collatedsrvurls.head;
    while(collateditem)
    {
        if(strcmp(collateditem->srvurl,pcSrvURL) == 0)
        {
            break;
        }
        collateditem = (SLPSrvUrlColatedItem*)collateditem->listitem.next;
    }
                                     
    /* create a new item if none was found */
    if(collateditem == NULL)
    {
        collateditem = (SLPSrvUrlColatedItem*) xmalloc(sizeof(SLPSrvUrlColatedItem) + \
                                                       strlen(pcSrvURL) + 1);
        if(collateditem)
        {
            memset(collateditem,0,sizeof(SLPSrvUrlColatedItem));
            collateditem->srvurl = (char*)(collateditem + 1);
            strcpy(collateditem->srvurl,pcSrvURL);
            collateditem->lifetime = sLifetime;

            /* Add the new item to the collated list */
            SLPListLinkTail(&(handle->collatedsrvurls),
                            (SLPListItem*)collateditem);

            /* Call the caller's callback */
            if(handle->params.findsrvs.callback((SLPHandle)handle,
                                                pcSrvURL,
                                                sLifetime,
                                                SLP_OK,
                                                handle->params.findsrvs.cookie) == SLP_FALSE)
            {
                goto CLEANUP;
            }
        }
    }
    
    return SLP_TRUE;

CLEANUP:
    /* free the collation list */
    while(handle->collatedsrvurls.count)
    {
        collateditem = (SLPSrvUrlColatedItem*)SLPListUnlink(&(handle->collatedsrvurls),
                                                            handle->collatedsrvurls.head);
        xfree(collateditem);
    }   
    handle->callbackcount = 0;

    return SLP_FALSE;
}
Ejemplo n.º 28
0
/** Collates response data to user callback for SLPFindSrv requests.
 *
 * @param[in] hSLP - The SLP handle object associated with the request.
 * @param[in] pcSrvURL - The service URL for this pass.
 * @param[in] sLifetime - The lifetime value for @p pcSrvURL.
 * @param[in] errorcode - The error code received on this pass.
 *
 * @return An SLP boolean value; SLP_TRUE indicates we are finished; 
 *    SLP_FALSE indicates we should continue.
 *
 * @todo Trace the logic of CollateToSLPSrvURLCallback to ensure 
 *    that it works.
 *
 * @internal
 */
static SLPBoolean CollateToSLPSrvURLCallback(SLPHandle hSLP, 
      const char * pcSrvURL, unsigned short sLifetime, 
      SLPError errorcode)
{
   int maxResults;
   SLPHandleInfo * handle = hSLP;
   SLPSrvUrlCollatedItem * collateditem;

#ifdef ENABLE_ASYNC_API
   /* Do not collate for async calls. */
   if (handle->isAsync)
      return handle->params.findsrvs.callback(hSLP, pcSrvURL, 
            sLifetime, errorcode, handle->params.findsrvs.cookie);
#endif

   /* Configure behaviour for desired max results */
   maxResults = SLPPropertyAsInteger("net.slp.maxResults");
   if (maxResults == -1)
      maxResults = INT_MAX;

   if (errorcode == SLP_LAST_CALL || handle->callbackcount > maxResults)
   {
      /* We are done so call the caller's callback for each
       * service URL collated item and clean up the collation list.
       */
      handle->params.findsrvs.callback(handle, 0, 0, 
            SLP_LAST_CALL, handle->params.findsrvs.cookie);
      goto CLEANUP;
   }
   else if (errorcode != SLP_OK)
      return SLP_TRUE;

   /* We're adding another result - increment result count. */
   handle->callbackcount++;

   /* Add the service URL to the colation list. */
   collateditem = (SLPSrvUrlCollatedItem *)handle->collatedsrvurls.head;
   while (collateditem)
   {
      if (strcmp(collateditem->srvurl, pcSrvURL) == 0)
         break;
      collateditem = (SLPSrvUrlCollatedItem *)collateditem->listitem.next;
   }

   /* Create a new item if none was found. */
   if (collateditem == 0)
   {
      collateditem = xmalloc(sizeof(SLPSrvUrlCollatedItem) 
            + strlen(pcSrvURL) + 1);
      if (collateditem)
      {
         memset(collateditem, 0, sizeof(SLPSrvUrlCollatedItem));
         collateditem->srvurl = (char *)(collateditem + 1);
         strcpy(collateditem->srvurl, pcSrvURL);
         collateditem->lifetime = sLifetime;

         /* Add the new item to the collated list. */
         SLPListLinkTail(&handle->collatedsrvurls, 
               (SLPListItem *)collateditem);

         /* Call the caller's callback. */
         if (handle->params.findsrvs.callback(handle, pcSrvURL, sLifetime, 
               SLP_OK, handle->params.findsrvs.cookie) == SLP_FALSE)
            goto CLEANUP;
      }
   }
   return SLP_TRUE;

CLEANUP:

   /* Free the collation list. */
   while (handle->collatedsrvurls.count)
   {
      collateditem = (SLPSrvUrlCollatedItem *)SLPListUnlink(
            &handle->collatedsrvurls, handle->collatedsrvurls.head);
      xfree(collateditem);
   }   
   handle->callbackcount = 0;

   return SLP_FALSE;
}
Ejemplo n.º 29
0
/*-------------------------------------------------------------------------*/
void OutgoingStreamRead(SLPList* socklist, SLPDSocket* sock)
/*-------------------------------------------------------------------------*/
{
    int     bytesread;
    char    peek[16];
    int     peeraddrlen = sizeof(struct sockaddr_in);

    if ( sock->state == STREAM_READ_FIRST )
    {
        /*---------------------------------------------------*/
        /* take a peek at the packet to get size information */
        /*---------------------------------------------------*/
        bytesread = recvfrom(sock->fd,
                             peek,
                             16,
                             MSG_PEEK,
                             (struct sockaddr *)&(sock->peeraddr),
                             &peeraddrlen);
        if ( bytesread > 0 )
        {
            /* allocate the recvbuf big enough for the whole message */
            sock->recvbuf = SLPBufferRealloc(sock->recvbuf,AsUINT24(peek+2));
            if ( sock->recvbuf )
            {
                sock->state = STREAM_READ;
            }
            else
            {
                SLPDLog("INTERNAL_ERROR - out of memory!\n");
                sock->state = SOCKET_CLOSE;
            }
        }
        else
        {
#ifdef WIN32
            if ( WSAEWOULDBLOCK != WSAGetLastError() )
#else
            if ( errno != EWOULDBLOCK )
#endif
            {
                /* Error occured or connection was closed. Try to reconnect */
                /* Socket will be closed if connect times out               */
                OutgoingStreamReconnect(socklist,sock);
            }
        }       
    }

    if ( sock->state == STREAM_READ )
    {
        /*------------------------------*/
        /* recv the rest of the message */
        /*------------------------------*/
        bytesread = recv(sock->fd,
                         sock->recvbuf->curpos,
                         sock->recvbuf->end - sock->recvbuf->curpos,
                         0);
        if ( bytesread > 0 )
        {
            /* reset age because of activity */
            sock->age = 0;

            /* move buffer pointers */
            sock->recvbuf->curpos += bytesread;

            /* check to see if everything was read */
            if ( sock->recvbuf->curpos == sock->recvbuf->end )
            {
                switch ( SLPDProcessMessage(&(sock->peeraddr),
                                            sock->recvbuf,
                                            &(sock->sendbuf)) )
                {
                case SLP_ERROR_DA_BUSY_NOW:
                    sock->state = STREAM_WRITE_WAIT;
                    break;
                case SLP_ERROR_PARSE_ERROR:
                case SLP_ERROR_VER_NOT_SUPPORTED:
                    sock->state = SOCKET_CLOSE;
                    break;
                default:
                    /* End of outgoing message exchange. Unlink   */
                    /* send buf from to do list and free it       */
                    SLPBufferFree((SLPBuffer)SLPListUnlink(&(sock->sendlist),(SLPListItem*)(sock->sendbuf)));
                    sock->state = STREAM_WRITE_FIRST;
                    /* clear the reconnection count since we actually
                     * transmitted a successful message exchange
                     */
                    sock->reconns = 0;
                    break;
                }
            }
        }
        else
        {
#ifdef WIN32
            if ( WSAEWOULDBLOCK != WSAGetLastError() )
#else
            if ( errno != EWOULDBLOCK )
#endif
            {
                /* Error occured or connection was closed. Try to reconnect */
                /* Socket will be closed if connect times out               */
                OutgoingStreamReconnect(socklist,sock);
            }
        }
    }
}
Ejemplo n.º 30
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;
        }
    }                                                 
}