コード例 #1
0
/*=========================================================================*/
int main(int argc, char* argv[])
/*=========================================================================*/
{
    fd_set          readfds;
    fd_set          writefds;
    int             highfd;
    int             fdcount         = 0;

#ifdef DEBUG
    xmalloc_init("/var/log/slpd_xmalloc.log",0);
#endif

    /*------------------------*/
    /* Parse the command line */
    /*------------------------*/
    if(SLPDParseCommandLine(argc,argv))
    {
        SLPDFatal("Invalid command line\n");
    }

    /*------------------------------*/
    /* Make sure we are root        */
    /*------------------------------*/
    if(getuid() != 0)
    {
        SLPDFatal("slpd must be started by root\n");
    }

    /*--------------------------------------*/
    /* Make sure we are not already running */
    /*--------------------------------------*/
    if(CheckPid(G_SlpdCommandLine.pidfile))
    {
        SLPDFatal("slpd is already running. Check %s\n",
                 G_SlpdCommandLine.pidfile);
    }

    /*------------------------------*/
    /* Initialize the log file      */
    /*------------------------------*/
    if(SLPDLogFileOpen(G_SlpdCommandLine.logfile, 1))
    {
        SLPDFatal("Could not open logfile %s\n",G_SlpdCommandLine.logfile);
    }

    /*------------------------*/
    /* Seed the XID generator */
    /*------------------------*/
    SLPXidSeed();

    /*---------------------*/
    /* Log startup message */
    /*---------------------*/
    SLPDLog("****************************************\n");
    SLPDLogTime();
    SLPDLog("SLPD daemon started\n");
    SLPDLog("****************************************\n");
    SLPDLog("Command line = %s\n",argv[0]);
    SLPDLog("Using configuration file = %s\n",G_SlpdCommandLine.cfgfile);
    SLPDLog("Using registration file = %s\n",G_SlpdCommandLine.regfile);
#ifdef ENABLE_SECURITY
    SLPDLog("Using SPI file = %s\n",G_SlpdCommandLine.spifile);
#endif
   
    /*--------------------------------------------------*/
    /* Initialize for the first time                    */
    /*--------------------------------------------------*/
    if(SLPDPropertyInit(G_SlpdCommandLine.cfgfile) ||
#ifdef ENABLE_SECURITY
       SLPDSpiInit(G_SlpdCommandLine.spifile) ||
#endif     
       SLPDDatabaseInit(G_SlpdCommandLine.regfile) ||
       SLPDIncomingInit() ||
       SLPDOutgoingInit() ||
       SLPDKnownDAInit())
    {
        SLPDFatal("slpd initialization failed\n");
    }
    SLPDLog("Agent Interfaces = %s\n",G_SlpdProperty.interfaces);
    SLPDLog("Agent URL = %s\n",G_SlpdProperty.myUrl);

    /*---------------------------*/
    /* make slpd run as a daemon */
    /*---------------------------*/
    if(Daemonize(G_SlpdCommandLine.pidfile))
    {
        SLPDFatal("Could not daemonize\n");
    }

    /*-----------------------*/
    /* Setup signal handlers */
    /*-----------------------*/
    if(SetUpSignalHandlers())
    {
        SLPDFatal("Error setting up signal handlers.\n");
    }

    /*------------------------------*/
    /* Set up alarm to age database */
    /*------------------------------*/
    alarm(SLPD_AGE_INTERVAL);

    /*-----------*/
    /* Main loop */
    /*-----------*/
    SLPDLog("Startup complete entering main run loop ...\n\n");
    G_SIGALRM   = 0;
    G_SIGTERM   = 0;
    G_SIGHUP    = 0;    
#ifdef DEBUG
    G_SIGINT    = 0;
#endif

    while(G_SIGTERM == 0)
    {
        /*--------------------------------------------------------*/
        /* Load the fdsets up with all valid sockets in the list  */
        /*--------------------------------------------------------*/
        highfd = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds);
        LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds);

        /*--------------------------------------------------*/
        /* Before select(), check to see if we got a signal */
        /*--------------------------------------------------*/
        if(G_SIGALRM || G_SIGHUP)
        {
            goto HANDLE_SIGNAL;
        }

        /*-------------*/
        /* Main select */
        /*-------------*/
        fdcount = select(highfd+1,&readfds,&writefds,0,0);
        if(fdcount > 0) /* fdcount will be < 0 when interrupted by a signal */
        {
            SLPDIncomingHandler(&fdcount,&readfds,&writefds);
            SLPDOutgoingHandler(&fdcount,&readfds,&writefds);
        }

        /*----------------*/
        /* Handle signals */
        /*----------------*/
        HANDLE_SIGNAL:
        if(G_SIGHUP)
        {
            HandleSigHup();
            G_SIGHUP = 0;
        }
        if(G_SIGALRM)
        {
            HandleSigAlrm();
            G_SIGALRM = 0;
            alarm(SLPD_AGE_INTERVAL);
        }
#ifdef DEBUG
	if (G_SIGINT)
	{
	    HandleSigInt();
	    G_SIGINT = 0;
	}			
#endif

    } /* End of main loop */

    /* Got SIGTERM */
    HandleSigTerm();

    return 0;
}
コード例 #2
0
ファイル: slpd_regfile.c プロジェクト: eSDK/eSDK_OBS_API
/** Read service registrations from a text file.
 *
 * A really big and nasty function that reads service registrations from
 * from a file. Don't look at this too hard or you'll be sick. This is by
 * far the most horrible code in OpenSLP. Please volunteer to rewrite it!
 *
 * "THANK GOODNESS this function is only called at startup" -- Matt
 *
 * @param[in] fd - The file to read from.
 * @param[out] msg - A message describing the SrvReg in buf.
 * @param[out] buf - The buffer used to hold @p message data.
 *
 * @return Zero on success. A value greater than zero on error. A value
 *    less than zero on EOF.
 *
 * @note Eventually the caller needs to call SLPBufferFree and
 *    SLPMessageFree to free memory.
 */
int SLPDRegFileReadSrvReg(FILE * fd, SLPMessage ** msg, SLPBuffer * buf)
{
   char * slider1;
   char * slider2;
   char line[4096];

   struct sockaddr_storage peer;
   int result = 0;
   size_t bufsize = 0;
   size_t langtaglen = 0;
   char * langtag = 0;
   size_t scopelistlen = 0;
   char * scopelist = 0;
   size_t urllen = 0;
   char * url = 0;
   int lifetime = 0;
   size_t srvtypelen = 0;
   char * srvtype = 0;
   size_t attrlistlen = 0;
   char * attrlist = 0;
   SLPBuffer tmp;

#ifdef ENABLE_SLPv2_SECURITY
   unsigned char * urlauth = 0;
   int urlauthlen = 0;
   unsigned char * attrauth = 0;
   int attrauthlen = 0;
#endif

   /* give the out params an initial NULL value */
   *buf = 0;
   *msg = 0;

   /* read the next non-white non-comment line from the stream */
   do
   {
      slider1 = RegFileReadLine(fd, line, 4096);
      if (slider1 == 0)
         return -1;

   } while (*slider1 == 0x0d ||  *slider1 == 0x0a);

   /* Parse the url-props */
   slider2 = strchr(slider1, ',');
   if (slider2)
   {
      /* srvurl */
      *slider2 = 0; /* squash comma to null terminate srvurl */
      url = xstrdup(TrimWhitespace(slider1));
      if (url == 0)
      {
         result = SLP_ERROR_INTERNAL_ERROR;
         goto CLEANUP;
      }
      urllen = strlen(url);

      /* derive srvtype from srvurl */
      srvtype = strstr(slider1, "://");
      if (srvtype == 0)
      {
         result = SLP_ERROR_INVALID_REGISTRATION;
         goto CLEANUP;
      }
      *srvtype = 0;
      srvtype=xstrdup(TrimWhitespace(slider1));
      if (srvtype == 0)
      {
         result = SLP_ERROR_INTERNAL_ERROR;
         goto CLEANUP;
      }
      srvtypelen = strlen(srvtype);
      slider1 = slider2 + 1;

      /*lang*/
      slider2 = strchr(slider1, ',');
      if (slider2)
      {
         *slider2 = 0; /* squash comma to null terminate lang */
         langtag = xstrdup(TrimWhitespace(slider1));
         if (langtag == 0)
         {
            result = SLP_ERROR_INVALID_REGISTRATION;
            goto CLEANUP;
         }
         langtaglen = strlen(langtag);
         slider1 = slider2 + 1;
      }
      else
      {
         result = SLP_ERROR_INVALID_REGISTRATION;
         goto CLEANUP;
      }

      /* ltime */
      slider2 = strchr(slider1,',');
      if (slider2)
      {
         *slider2 = 0; /* squash comma to null terminate ltime */
         lifetime = atoi(slider1);
         slider1 = slider2 + 1;
      }
      else
      {
         lifetime = atoi(slider1);
         slider1 = slider2;
      }
      if (lifetime < 1 || lifetime > SLP_LIFETIME_MAXIMUM)
      {
         result = SLP_ERROR_INVALID_REGISTRATION;
         goto CLEANUP;
      }

      /* get the srvtype if one was not derived by the srvurl */
      if (srvtype == 0)
      {
         srvtype = xstrdup(TrimWhitespace(slider1));
         if (srvtype == 0)
         {
            result = SLP_ERROR_INTERNAL_ERROR;
            goto CLEANUP;
         }
         srvtypelen = strlen(srvtype);
         if (srvtypelen == 0)
         {
            result = SLP_ERROR_INVALID_REGISTRATION;
            goto CLEANUP;
         }
      }
   }
   else
   {
      result = SLP_ERROR_INVALID_REGISTRATION;
      goto CLEANUP;
   }

   /* read all the attributes including the scopelist */
   *line=0;
   while (1)
   {
      slider1 = RegFileReadLine(fd,line,4096);
      if (slider1 == 0)
      {
         result = -1;
         break;
      }
      if (*slider1 == 0x0d || *slider1 == 0x0a)
         break;

      /* Check to see if it is the scopes line */
      /* FIXME We can collapse the scope stuff into the value getting and
         just make it a special case (do strcmp on the tag as opposed to the
         line) of attribute getting. */
      if (strncasecmp(slider1,"scopes", 6) == 0)
      {
         /* found scopes line */
         slider2 = strchr(slider1,'=');
         if (slider2)
         {
            slider2++;
            if (*slider2)
            {
               /* just in case some idiot puts multiple scopes lines */
               if (scopelist)
               {
                  result = SLP_ERROR_SCOPE_NOT_SUPPORTED;
                  goto CLEANUP;
               }

               /* make sure there are no spaces in the scope list
      NOTE: There's nothing in the spec that indicates that
      scopes can't contain spaces. Commenting out for now. --jmc
               if (strchr(slider2, ' '))
               {
                  result = SLP_ERROR_SCOPE_NOT_SUPPORTED;
                  goto CLEANUP;
               } */

               scopelist = xstrdup(TrimWhitespace(slider2));
               if (scopelist == 0)
               {
                  result = SLP_ERROR_INTERNAL_ERROR;
                  goto CLEANUP;
               }
               scopelistlen = strlen(scopelist);
            }
         }
      }
      else
      {
         /* line contains an attribute (slow but it works)*/
         /* TODO Fix this so we do not have to realloc memory each time! */
         TrimWhitespace(slider1);

         if (attrlist == 0)
         {
            attrlistlen += strlen(slider1) + 2;
            attrlist = xmalloc(attrlistlen + 1);
            if (attrlist == 0)
            {
               result = SLP_ERROR_INTERNAL_ERROR;
               goto CLEANUP;
            }
            *attrlist = 0;
         }
         else
         {
            char * tmp_attrlist;
            attrlistlen += strlen(slider1) + 3;
            if ((tmp_attrlist = xrealloc(attrlist, attrlistlen + 1)) == 0)
            {
               xfree(attrlist);
               result = SLP_ERROR_INTERNAL_ERROR;
               goto CLEANUP;
            }
            attrlist = tmp_attrlist;
            strcat(attrlist, ",");
         }

         if (attrlist == 0)
         {
            result = SLP_ERROR_INTERNAL_ERROR;
            goto CLEANUP;
         }

         /* we need special case for keywords (why do we need these)
            they seem like a waste of code.  Why not just use booleans */
         if (strchr(slider1, '='))
         {
            /* normal attribute (with '=') */
            strcat(attrlist, "(");
            strcat(attrlist, slider1);
            strcat(attrlist, ")");
         }
         else
         {
            /* keyword (no '=') */
            attrlistlen -= 2; /* subtract 2 bytes for no '(' or ')' */
            strcat(attrlist, slider1);
         }
      }
   }

   /* Set the scope set in properties if not is set */
   if (scopelist == 0)
   {
      scopelist = xstrdup(G_SlpdProperty.useScopes);
      if (scopelist == 0)
      {
         result = SLP_ERROR_INTERNAL_ERROR;
         goto CLEANUP;
      }
      scopelistlen = G_SlpdProperty.useScopesLen;
   }

#ifdef ENABLE_SLPv2_SECURITY
   /* generate authentication blocks */
   if (G_SlpdProperty.securityEnabled)
   {
      SLPAuthSignUrl(G_SlpdSpiHandle, 0, 0, urllen, url,
            &urlauthlen, &urlauth);
      SLPAuthSignString(G_SlpdSpiHandle, 0, 0, attrlistlen, attrlist,
            &attrauthlen, &attrauth);
   }
#endif

   /* allocate buffer for the SrvReg Message */
   bufsize = 14 + langtaglen;    /* 14 bytes for header    */
   bufsize += urllen + 6;        /*  1 byte for reserved   */
                                 /*  2 bytes for lifetime  */
                                 /*  2 bytes for urllen    */
                                 /*  1 byte for authcount  */
   bufsize += srvtypelen + 2;    /*  2 bytes for len field */
   bufsize += scopelistlen + 2;  /*  2 bytes for len field */
   bufsize += attrlistlen + 2;   /*  2 bytes for len field */
   bufsize += 1;                 /*  1 byte for authcount  */

#ifdef ENABLE_SLPv2_SECURITY
   bufsize += urlauthlen;
   bufsize += attrauthlen;
#endif

   tmp = *buf = SLPBufferAlloc(bufsize);
   if (tmp == 0)
   {
      result = SLP_ERROR_INTERNAL_ERROR;
      goto CLEANUP;
   }

   /* now build the SrvReg Message */

   /* version */
   *tmp->curpos++ = 2;

   /* function id */
   *tmp->curpos++ = SLP_FUNCT_SRVREG;

   /* length */
   PutUINT24(&tmp->curpos, bufsize);

   /* flags */
   PutUINT16(&tmp->curpos, 0);

   /* ext offset */
   PutUINT24(&tmp->curpos, 0);

   /* xid */
   PutUINT16(&tmp->curpos, 0);

   /* lang tag len */
   PutUINT16(&tmp->curpos, langtaglen);

   /* lang tag */
   memcpy(tmp->curpos, langtag, langtaglen);
   tmp->curpos += langtaglen;

   /* url-entry reserved */
   *tmp->curpos++ = 0;

   /* url-entry lifetime */
   PutUINT16(&tmp->curpos, lifetime);

   /* url-entry urllen */
   PutUINT16(&tmp->curpos, urllen);

   /* url-entry url */
   memcpy(tmp->curpos, url, urllen);
   tmp->curpos += urllen;

   /* url-entry authblock */
#ifdef ENABLE_SLPv2_SECURITY
   if (urlauth)
   {
      /* authcount */
      *tmp->curpos++ = 1;

      /* authblock */
      memcpy(tmp->curpos, urlauth, urlauthlen);
      tmp->curpos += urlauthlen;
   }
   else
#endif
      *tmp->curpos++ = 0;

   /* service type */
   PutUINT16(&tmp->curpos, srvtypelen);
   memcpy(tmp->curpos, srvtype, srvtypelen);
   tmp->curpos += srvtypelen;

   /* scope list */
   PutUINT16(&tmp->curpos, scopelistlen);
   memcpy(tmp->curpos, scopelist, scopelistlen);
   tmp->curpos += scopelistlen;

   /* attr list */
   PutUINT16(&tmp->curpos, attrlistlen);
   memcpy(tmp->curpos, attrlist, attrlistlen);
   tmp->curpos += attrlistlen;

   /* attribute auth block */
#ifdef ENABLE_SLPv2_SECURITY
   if (attrauth)
   {
      /* authcount */
      *tmp->curpos++ = 1;

      /* authblock */
      memcpy(tmp->curpos, attrauth, attrauthlen);
      tmp->curpos += attrauthlen;
   }
   else
#endif
      *tmp->curpos++ = 0;

   /* okay, now comes the really stupid (and lazy part) */
   *msg = SLPMessageAlloc();
   if (*msg == 0)
   {
      SLPBufferFree(*buf);
      *buf = 0;
      result = SLP_ERROR_INTERNAL_ERROR;
      goto CLEANUP;
   }

   /* this should be ok even if we are not supporting IPv4,
    * since it's a static service
    */
   memset(&peer, 0, sizeof(struct sockaddr_in));
   peer.ss_family = AF_UNSPEC;
   ((struct sockaddr_in *)&peer)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   result = SLPMessageParseBuffer(&peer, &peer, *buf, *msg);
   (*msg)->body.srvreg.source = SLP_REG_SOURCE_STATIC;

CLEANUP:

   /* check for errors and free memory */
   switch(result)
   {
      case SLP_ERROR_INTERNAL_ERROR:
         SLPDLog("\nERROR: Out of memory one reg file line:\n   %s\n", line);
         break;

      case SLP_ERROR_INVALID_REGISTRATION:
         SLPDLog("\nERROR: Invalid reg file format near:\n   %s\n", line);
         break;

      case SLP_ERROR_SCOPE_NOT_SUPPORTED:
         SLPDLog("\nERROR: Duplicate scopes or scope list with "
               "embedded spaces near:\n   %s\n", line);
         break;

      default:
         break;
   }

   xfree(langtag);
   xfree(scopelist);
   xfree(url);
   xfree(srvtype);
   xfree(attrlist);

#ifdef ENABLE_SLPv2_SECURITY
   xfree(urlauth);
   xfree(attrauth);
#endif

   return result;
}
コード例 #3
0
/** Delete entry from the index tree.
 *
 * Compares the value of the string with the value in the root node, then
 * either recursively deletes the value in the left or right sub-trees, or
 * deletes the value from the root node.
 * If the root_node needs to be deleted, then create a new tree from its
 * subtrees, re-balancing where necessary.
 * 
 * @param[in] root_node - a pointer to the root of the (sub-)tree.
 * @param[in] value_str_len - length of the string to be removed.
 * @param[in] value_str - A pointer to string to be removed.
 * @param[in] p - The "location" value associated with the string.
 * 
 * @return New root node of the tree, or null if the tree is now empty
 */
IndexTreeNode *index_tree_delete(
   IndexTreeNode *root_node,
   size_t value_str_len,
   const char *value_str,
   void *p)
{
   int cmp;
   
   if (!root_node)
      /* Shouldn't really happen, but nothing to do */
      return root_node;

   cmp = compare_with_tree_node(value_str_len, value_str, root_node);
   if (cmp < 0)
   {
      root_node->left_node = index_tree_delete(root_node->left_node, value_str_len, value_str, p);
      root_node->left_depth = tree_depth(root_node->left_node);
      if (root_node->left_node)
         root_node->left_node->parent_node = root_node;
   }
   else if (cmp > 0)
   {
      root_node->right_node = index_tree_delete(root_node->right_node, value_str_len, value_str, p);
      root_node->right_depth = tree_depth(root_node->right_node);
      if (root_node->right_node)
         root_node->right_node->parent_node = root_node;
   }
   else
   {
      IndexTreeNode *replacement_node;

      /* Find the given location in the value list */
      IndexTreeValue *entry = find_in_value_set(root_node->value, p);
      if (!entry)
         /* Shouldn't really happen, but nothing to do */
         return root_node;

      root_node->value = remove_from_value_set(root_node->value, entry);
      free_index_tree_value(entry);

      if (root_node->value)
         /* All we've done is remove one of the values in the set for this node,
          * so the tree structure does not need to be changed
          */
         return root_node;

      /* The node needs to be deleted, so replace this node by the leftmost
       * node of the right sub-tree, or the rightmost mode of the left
       * sub-tree, depending on which has the greater depth
       */
      if (root_node->left_depth > root_node->right_depth)
      {
         root_node->left_node = extract_rightmost(root_node->left_node, &replacement_node);
         root_node->left_depth = tree_depth(root_node->left_node);
      }
      else if (root_node->right_node)
      {
         root_node->right_node = extract_leftmost(root_node->right_node, &replacement_node);
         root_node->right_depth = tree_depth(root_node->right_node);
      }
      else
      {
         /* Both sub-trees are empty  ie. this is a leaf node */
         free_index_tree_node(root_node);
         return (IndexTreeNode *)0;
      }
      replacement_node->right_node = root_node->right_node;
      replacement_node->right_depth = root_node->right_depth;
      if (replacement_node->right_node)
         replacement_node->right_node->parent_node = replacement_node;
      replacement_node->left_node = root_node->left_node;
      replacement_node->left_depth = root_node->left_depth;
      if (replacement_node->left_node)
         replacement_node->left_node->parent_node = replacement_node;
      free_index_tree_node(root_node);
      root_node = replacement_node;
   }
   root_node = rebalance_tree(root_node);
#if defined(DEBUG) && defined(CHECKING)
   if (!check_tree(root_node))
   {
      SLPDLog("Index tree check fails deleting from tree %p\n", root_node);
   }
#endif
   return root_node;
}
コード例 #4
0
ファイル: slpd_incoming.c プロジェクト: eSDK/eSDK_OBS_API
/** Read an inbound datagram.
 *
 * @param[in] socklist - The list of monitored sockets.
 * @param[in] sock - The socket to be read.
 *
 * @internal
 */
static void IncomingDatagramRead(SLPList * socklist, SLPDSocket * sock)
{
   int bytesread;
   int byteswritten;
   socklen_t peeraddrlen = sizeof(struct sockaddr_storage);
   char addr_str[INET6_ADDRSTRLEN];
   sockfd_t sendsock = SLP_INVALID_SOCKET;

   (void)socklist;

   bytesread = recvfrom(sock->fd, (char*)sock->recvbuf->start,
         G_SlpdProperty.MTU, 0, (struct sockaddr *)&sock->peeraddr,
         &peeraddrlen);
   if (bytesread > 0)
   {
      sock->recvbuf->end = sock->recvbuf->start + bytesread;

      if (!sock->sendbuf)
         /* Some of the error handling code expects a sendbuf to be available
          * to be emptied, so make sure there is at least a minimal buffer
          */
         sock->sendbuf = SLPBufferAlloc(1);

      switch (SLPDProcessMessage(&sock->peeraddr, &sock->localaddr,
            sock->recvbuf, &sock->sendbuf, 0))
      {
         case SLP_ERROR_PARSE_ERROR:
         case SLP_ERROR_VER_NOT_SUPPORTED:
         case SLP_ERROR_MESSAGE_NOT_SUPPORTED:
            break;

         default:
#ifdef DARWIN
            /* If the socket is a multicast socket, find the designated UDP output socket for sending */
            if (sock->state == DATAGRAM_MULTICAST)
               if ((sendsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != SLP_INVALID_SOCKET)
                  SLPNetworkSetSndRcvBuf(sendsock);
#endif
            if (sendsock == SLP_INVALID_SOCKET)
               sendsock = sock->fd;

            /* check to see if we should send anything, breaking up individual packets in the buffer
               into different sendto calls (should only be an issue with the loopback DA response)*/
            if (sock->sendbuf)
            {
               sock->sendbuf->curpos = sock->sendbuf->start;
               while (sock->sendbuf->curpos < sock->sendbuf->end)
               {
                  int packetbytes = AS_UINT24(sock->sendbuf->curpos + 2);
                  byteswritten = sendto(sendsock, (char*)sock->sendbuf->curpos,
                        packetbytes, 0, (struct sockaddr *)&sock->peeraddr,
                        SLPNetAddrLen(&sock->peeraddr));

                  if (byteswritten != packetbytes)
                  {
                     /* May be an overflow reply */
                     int flags = AS_UINT16(sock->sendbuf->curpos + 5);
                     if ((byteswritten == -1) &&
#ifdef _WIN32
                           (WSAGetLastError() == WSAEMSGSIZE) &&
#else
                           (errno == EMSGSIZE) &&
#endif
                           (flags & SLP_FLAG_OVERFLOW))
                     {
                        int byteswrittenmax = sendto(sendsock, (char*)sock->sendbuf->curpos,
                                G_SlpdProperty.MTU, 0, (struct sockaddr *)&sock->peeraddr,
                                SLPNetAddrLen(&sock->peeraddr));
                        if (byteswrittenmax == G_SlpdProperty.MTU)
                           byteswritten = packetbytes;
                     }
                  }

                  if (byteswritten != packetbytes)
                     SLPDLog("NETWORK_ERROR - %d replying %s\n", errno,
                           SLPNetSockAddrStorageToString(&(sock->peeraddr),
                                 addr_str, sizeof(addr_str)));

                  sock->sendbuf->curpos += packetbytes;
               }

               /* Only close if we allocated a new socket */
               if (sendsock != sock->fd)
                  closesocket(sendsock);
            }
            break;
      }
   }
}
コード例 #5
0
ファイル: slpd_log.c プロジェクト: ncultra/openslp
/*-------------------------------------------------------------------------*/
void SLPDLogPeerAddr(struct sockaddr_in* peeraddr)
/*-------------------------------------------------------------------------*/
{
    SLPDLog("Peer IP address: %s\n", inet_ntoa(peeraddr->sin_addr));
}
コード例 #6
0
ファイル: slpd_log.c プロジェクト: ncultra/openslp
/*=========================================================================*/
void SLPDLogMessage(int msglogflags,
                    struct sockaddr_in* peerinfo,
                    SLPBuffer buf)
/* Log record of receiving or sending an SLP Message.  Logging will only   */
/* occur if message logging is enabled G_SlpProperty.traceMsg != 0         */
/*                                                                         */
/* msglogflags   (IN) What type of message to log                          */
/*                                                                         */
/* peerinfo (IN) the source or destination peer                            */
/*                                                                         */
/* msg      (IN) the message to log                                        */
/*                                                                         */
/* Returns: none                                                           */
/*=========================================================================*/
{
    SLPMessage msg;

    if (peerinfo == NULL ||
        buf == NULL)
    {
        return;
    }

    if ((G_SlpdProperty.traceMsg && (msglogflags & SLPDLOG_TRACEMSG)) ||
        (G_SlpdProperty.traceDrop && (msglogflags & SLPDLOG_TRACEDROP)) )
    {
        /* Don't log localhost traffic since it is probably IPC */
        /* and don't log empty messages                         */
        if (!ISLOCAL(peerinfo->sin_addr) && buf->end != buf->start)
        {
            msg = SLPMessageAlloc();
            if (msg)
            {
                SLPDLog("\n");
                SLPDLogTime();
                SLPDLog("MESSAGE - ");
                if (msglogflags == SLPDLOG_TRACEMSG_OUT)
                {
                    SLPDLog("Trace message (OUT)\n");
                }
                else if (msglogflags == SLPDLOG_TRACEMSG_IN)
                {
                    SLPDLog("Trace message (IN)\n");
                }
                else if (msglogflags == SLPDLOG_TRACEDROP)
                {
                    SLPDLog("Dropped message (following message silently ignored)\n");
                }
                else
                {
                    SLPDLog("\n");
                }

                if (SLPMessageParseBuffer(peerinfo,buf,msg) == 0)
                {
                    SLPDLogMessageInternals(msg);
                }
                else
                {
                    SLPDLog("Message parsing failed\n");
                    SLPDLog("Peer: \n");
                    SLPDLog("   IP address: %s\n", inet_ntoa(msg->peer.sin_addr));          
                }

                SLPMessageFree(msg);
            }
        }
    }
}
コード例 #7
0
/*=========================================================================*/
int SLPDIncomingInit()
/* Initialize incoming socket list to have appropriate sockets for all     */
/* network interfaces                                                      */
/*                                                                         */
/* Returns  Zero on success non-zero on error                              */
/*=========================================================================*/
{
    char*           begin = NULL;
    char*           beginSave = NULL;
    char*           end = NULL;
    int             finished;
    struct in_addr  myaddr;
    struct in_addr  mcastaddr;
    struct in_addr  bcastaddr;
    struct in_addr  loaddr;
    SLPDSocket*     sock;

    /*------------------------------------------------------------*/
    /* First, remove all of the sockets that might be in the list */
    /*------------------------------------------------------------*/
    while (G_IncomingSocketList.count)
    {
        SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_IncomingSocketList,G_IncomingSocketList.head));
    }


    /*--------------------------------------------------*/
    /* set up address to use for loopback and broadcast */
    /*--------------------------------------------------*/
    loaddr.s_addr = htonl(LOOPBACK_ADDRESS);
    bcastaddr.s_addr = htonl(SLP_BCAST_ADDRESS);
    mcastaddr.s_addr = htonl(SLP_MCAST_ADDRESS);

    /*--------------------------------------------------------------------*/
    /* Create SOCKET_LISTEN socket for LOOPBACK for the library to talk to*/
    /*--------------------------------------------------------------------*/
    sock = SLPDSocketCreateListen(&loaddr);
    if (sock)
    {
        SLPListLinkTail(&G_IncomingSocketList,(SLPListItem*)sock);
        SLPDLog("Listening on loopback...\n");
    }
    else
    {
        SLPDLog("NETWORK_ERROR - Could not listen on loopback\n");
        SLPDLog("INTERNAL_ERROR - No SLPLIB support will be available\n");
    }

    /*---------------------------------------------------------------------*/
    /* Create sockets for all of the interfaces in the interfaces property */
    /*---------------------------------------------------------------------*/

    /*---------------------------------------------------------------------*/
    /* Copy G_SlpdProperty.interfaces to a temporary buffer to parse the   */
    /*   string in a safety way                                            */
    /*---------------------------------------------------------------------*/

    if (G_SlpdProperty.interfaces != NULL)
    {
        begin = xstrdup((char *) G_SlpdProperty.interfaces);
        beginSave = begin;  /* save pointer for free() operation later */
        end = begin;
        finished = 0;
    }
    else
    {
        finished = 1; /* if no interface is defined,       */
                      /* don't even enter the parsing loop */
    }

    for (; (finished == 0); begin = ++end)
    {
        while (*end && *end != ',') end ++;
        if (*end == 0) finished = 1;
        *end = 0;                      /* Terminate string. */
        if (end <= begin) continue;    /* Skip empty entries */

        /* begin now points to a null terminated ip address string */
        myaddr.s_addr = inet_addr(begin);

        /*------------------------------------------------*/
        /* Create TCP_LISTEN that will handle unicast TCP */
        /*------------------------------------------------*/
        sock =  SLPDSocketCreateListen(&myaddr);
        if (sock)
        {
            SLPListLinkTail(&G_IncomingSocketList,(SLPListItem*)sock);
            SLPDLog("Listening on %s ...\n",inet_ntoa(myaddr));
        }


        /*----------------------------------------------------------------*/
        /* Create socket that will handle multicast UDP.                  */
        /*----------------------------------------------------------------*/

        sock =  SLPDSocketCreateBoundDatagram(&myaddr,
                                              &mcastaddr,
                                              DATAGRAM_MULTICAST);
        if (sock)
        {
            SLPListLinkTail(&G_IncomingSocketList,(SLPListItem*)sock);
            SLPDLog("Multicast socket on %s ready\n",inet_ntoa(myaddr));
        }
        else
        {
            SLPDLog("Couldn't bind to multicast for interface %s (%s)\n",
                    inet_ntoa(myaddr), strerror(errno));
        }

#if defined(ENABLE_SLPv1)
        if (G_SlpdProperty.isDA)
        {
            /*------------------------------------------------------------*/
            /* Create socket that will handle multicast UDP for SLPv1 DA  */
            /* Discovery.                                                 */
            /*------------------------------------------------------------*/
            mcastaddr.s_addr = htonl(SLPv1_DA_MCAST_ADDRESS);
            sock =  SLPDSocketCreateBoundDatagram(&myaddr,
                                                  &mcastaddr,
                                                  DATAGRAM_MULTICAST);
            if (sock)
            {
                SLPListLinkTail(&G_IncomingSocketList,(SLPListItem*)sock);
                SLPDLog("SLPv1 DA Discovery Multicast socket on %s ready\n",
                        inet_ntoa(myaddr));
            }
        }
#endif

        /*--------------------------------------------*/
        /* Create socket that will handle unicast UDP */
        /*--------------------------------------------*/
        sock =  SLPDSocketCreateBoundDatagram(&myaddr,
                                              &myaddr,
                                              DATAGRAM_UNICAST);
        if (sock)
        {
            SLPListLinkTail(&G_IncomingSocketList,(SLPListItem*)sock);
            SLPDLog("Unicast socket on %s ready\n",inet_ntoa(myaddr));
        }
    }     

    if (beginSave) xfree(beginSave);


    /*--------------------------------------------------------*/
    /* Create socket that will handle broadcast UDP           */
    /*--------------------------------------------------------*/
    sock =  SLPDSocketCreateBoundDatagram(&myaddr,
                                          &bcastaddr,
                                          DATAGRAM_BROADCAST);
    if (sock)
    {
        SLPListLinkTail(&G_IncomingSocketList,(SLPListItem*)sock);
        SLPDLog("Broadcast socket for %s ready\n", inet_ntoa(bcastaddr));
    }

    if (G_IncomingSocketList.count == 0)
    {
        SLPDLog("No usable interfaces\n");
        return 1;
    }

    return 0;
}
コード例 #8
0
ファイル: slpd_log.c プロジェクト: ncultra/openslp
/*-------------------------------------------------------------------------*/
void SLPDLogAttrRplyMessage(SLPAttrRply* attrrply)
/*-------------------------------------------------------------------------*/
{
    SLPDLog("Message ATTRRPLY:\n");
    SLPDLog("   errorcode = %i\n",attrrply->errorcode);
} 
コード例 #9
0
ファイル: slpd_main.c プロジェクト: Distrotech/openslp
/** Process main entry point.
 *
 * @param[in] argc - The number of command line arguments passed in @p argv.
 * @param[in] argv - An array of pointers to command line arguments.
 *
 * @return Zero on success, or a non-zero shell error code.
 *
 * @remarks This routine contains the main server loop.
 */
int main(int argc, char * argv[])
{
   fd_set readfds;
   fd_set writefds;
   int highfd;
   int fdcount = 0;
   time_t curtime;
   struct timeval timeout;

#ifdef DEBUG
   xmalloc_init("/var/log/slpd_xmalloc.log", 0);
#endif

   /* Parse the command line */
   if (SLPDParseCommandLine(argc,argv))
      SLPDFatal("Invalid command line\n");

   /* make sure we are root */
   if (getuid() != 0)
      SLPDFatal("slpd must be started by root\n");

   /* make sure we are not already running */
   if (CheckPid(G_SlpdCommandLine.pidfile))
      SLPDFatal("slpd is already running. Check %s\n",
            G_SlpdCommandLine.pidfile);

   /* Initialize the preferences so we know if the log file is to be
      overwritten or appended.*/
   if (SLPDPropertyInit(G_SlpdCommandLine.cfgfile))
      SLPDFatal("slpd initialization failed during property load\n");

   /* make slpd run as a daemon */
   if (Daemonize(G_SlpdCommandLine.pidfile))
      SLPDFatal("Could not daemonize\n");

   /* initialize the log file */
   if (SLPDLogFileOpen(G_SlpdCommandLine.logfile, G_SlpdProperty.appendLog))
      SLPDFatal("Could not open logfile %s\n",G_SlpdCommandLine.logfile);

   /* seed the XID generator */
   SLPXidSeed();

   /* log startup message */
   SLPDLog("****************************************\n");
   SLPDLogTime();
   SLPDLog("SLPD daemon started\n");
   SLPDLog("****************************************\n");
   SLPDLog("Command line = %s\n", argv[0]);
   SLPDLog("Using configuration file = %s\n", G_SlpdCommandLine.cfgfile);
   SLPDLog("Using registration file = %s\n", G_SlpdCommandLine.regfile);
#ifdef ENABLE_SLPv2_SECURITY
   SLPDLog("Using SPI file = %s\n", G_SlpdCommandLine.spifile);
#endif

   /* initialize for the first time */
   SLPDPropertyReinit();  /*So we get any property-related log messages*/
   if (
#ifdef ENABLE_SLPv2_SECURITY
         SLPDSpiInit(G_SlpdCommandLine.spifile) ||
#endif     
         SLPDDatabaseInit(G_SlpdCommandLine.regfile)
         || SLPDIncomingInit() 
         || SLPDOutgoingInit() 
         || SLPDKnownDAInit())
      SLPDFatal("slpd initialization failed\n");
   SLPDLog("Agent Interfaces = %s\n", G_SlpdProperty.interfaces);
   if (G_SlpdProperty.port != SLP_RESERVED_PORT)
      SLPDLog("Using port %d instead of default %d\n", G_SlpdProperty.port, SLP_RESERVED_PORT);

   /* drop privileges to reduce security risk */
   if (DropPrivileges())
      SLPDFatal("Could not drop privileges\n");

   /* Setup signal handlers */
   if (SetUpSignalHandlers())
      SLPDFatal("Error setting up signal handlers.\n");

   /* Set up alarm to age database -- a shorter start, so SAs register with us quickly on our startup */
   alarm(2);

   /* Main loop */
   SLPDLog("Startup complete entering main run loop ...\n\n");
   G_SIGALRM   = 0;
   G_SIGTERM   = 0;
   G_SIGHUP    = 0;    
#ifdef DEBUG
   G_SIGINT    = 0;
   G_SIGUSR1   = 0;    
#endif

   while (G_SIGTERM == 0)
   {
      /* load the fdsets up with all valid sockets in the list  */
      highfd = 0;
      FD_ZERO(&readfds);
      FD_ZERO(&writefds);
      LoadFdSets(&G_IncomingSocketList, &highfd, &readfds, &writefds);
      LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds, &writefds);

      /* before select(), check to see if we got a signal */
      if (G_SIGALRM || G_SIGHUP)
         goto HANDLE_SIGNAL;

      /* main select -- we time out every second so the outgoing retries can occur*/
      time(&curtime);  
      timeout.tv_sec = 1;
      timeout.tv_usec = 0;
      fdcount = select(highfd + 1, &readfds, &writefds, 0, &timeout);
      if (fdcount > 0) /* fdcount will be < 0 when interrupted by a signal */
      {
         SLPDIncomingHandler(&fdcount, &readfds, &writefds);
         SLPDOutgoingHandler(&fdcount, &readfds, &writefds);
         SLPDOutgoingRetry(time(0) - curtime);
      }
      else if (fdcount == 0)
         SLPDOutgoingRetry(time(0) - curtime);


HANDLE_SIGNAL:

      if (G_SIGHUP)
      {
         HandleSigHup();
         G_SIGHUP = 0;
      }
      if (G_SIGALRM)
      {
         HandleSigAlrm();
         G_SIGALRM = 0;
         alarm(SLPD_AGE_INTERVAL);
      }

#ifdef DEBUG
      if (G_SIGINT)
      {
         HandleSigInt();
         G_SIGINT = 0;
      }        

      if (G_SIGUSR1)
      {
         HandleSigUsr1();
         G_SIGUSR1 = 0;
      }
#endif

   } /* End of main loop */

   /* Got SIGTERM */
   HandleSigTerm();

   return 0;
}
コード例 #10
0
/*-------------------------------------------------------------------------*/
void IncomingStreamRead(SLPList* socklist, SLPDSocket* sock)
/*-------------------------------------------------------------------------*/
{
    int     bytesread, recvlen = 0;
    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)
        {

            if (*peek == 2)
                recvlen = AsUINT24(peek + 2);
            else if (*peek == 1) /* SLPv1 packet */
                recvlen = AsUINT16(peek + 2);
            /* allocate the recvbuf big enough for the whole message */
            sock->recvbuf = SLPBufferRealloc(sock->recvbuf,recvlen);
            if (sock->recvbuf)
            {
                sock->state = STREAM_READ; 
            }
            else
            {
                SLPDLog("INTERNAL_ERROR - out of memory!\n");
                sock->state = SOCKET_CLOSE;
            }
        }
        else
        {
            sock->state = SOCKET_CLOSE;
            return;
        }        
    }

    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 to max because of activity */
            sock->age = 0;
            sock->recvbuf->curpos += bytesread;
            if (sock->recvbuf->curpos == sock->recvbuf->end)
            {
                switch (SLPDProcessMessage(&sock->peeraddr,
                                           sock->recvbuf,
                                           &(sock->sendbuf)))
                {
                case SLP_ERROR_PARSE_ERROR:
                case SLP_ERROR_VER_NOT_SUPPORTED:
                case SLP_ERROR_MESSAGE_NOT_SUPPORTED:
                    sock->state = SOCKET_CLOSE;
                    break;                    
                default:
                    sock->state = STREAM_WRITE_FIRST;
                    IncomingStreamWrite(socklist, sock);
                }
            }
        }
        else
        {
            /* error in recv() */
            sock->state = SOCKET_CLOSE;
        }
    }
}
コード例 #11
0
ファイル: slpd_win32.c プロジェクト: ncultra/openslp
/*--------------------------------------------------------------------------*/
void ServiceStart (int argc, char **argv) 
/*--------------------------------------------------------------------------*/
{
    fd_set          readfds;
    fd_set          writefds;
    int             highfd;
    int             fdcount         = 0;
    time_t          curtime;
    time_t          alarmtime;
    struct timeval  timeout;
    WSADATA         wsaData; 
    WORD            wVersionRequested = MAKEWORD(1,1); 

    /*------------------------*/
    /* Service initialization */
    /*------------------------*/
    if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state*/
                            NO_ERROR,              /* exit code    */
                            3000))                 /* wait hint    */
    {
        goto cleanup;
    }

    if(WSAStartup(wVersionRequested, &wsaData) != 0)
    {
        (void)ReportStatusToSCMgr(SERVICE_STOP_PENDING, 
                                  NO_ERROR, 
                                  0); 
        goto cleanup;
    }

    /*------------------------*/
    /* Parse the command line */
    /*------------------------*/
    if(SLPDParseCommandLine(argc,argv))
    {
        ReportStatusToSCMgr(SERVICE_STOP_PENDING, /* service state    */
                            NO_ERROR,             /* exit code    */
                            0);                   /* wait hint    */
        goto cleanup_winsock;
    }
    if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state    */
                            NO_ERROR,              /* exit code    */
                            3000))                 /* wait hint    */
    {
        goto cleanup_winsock;
    }

    /*------------------------------*/
    /* Initialize the log file      */
    /*------------------------------*/
    if(SLPDLogFileOpen(G_SlpdCommandLine.logfile, 1))
    {
        SLPDLog("Could not open logfile %s\n",G_SlpdCommandLine.logfile);
        goto cleanup_winsock;
    }

    /*------------------------*/
    /* Seed the XID generator */
    /*------------------------*/
    SLPXidSeed();

    /*---------------------*/
    /* Log startup message */
    /*---------------------*/
    SLPDLog("****************************************\n");
    SLPDLogTime();
    SLPDLog("SLPD daemon started\n");
    SLPDLog("****************************************\n");
    SLPDLog("Command line = %s\n",argv[0]);
    SLPDLog("Using configuration file = %s\n",G_SlpdCommandLine.cfgfile);
    SLPDLog("Using registration file = %s\n",G_SlpdCommandLine.regfile);
    if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state    */
                            NO_ERROR,              /* exit code    */
                            3000))                 /* wait hint    */
    {
        goto cleanup_winsock;
    }


    /*--------------------------------------------------*/
    /* Initialize for the first time                    */
    /*--------------------------------------------------*/
    if(SLPDPropertyInit(G_SlpdCommandLine.cfgfile) ||
       SLPDDatabaseInit(G_SlpdCommandLine.regfile) ||
       SLPDIncomingInit() ||
       SLPDOutgoingInit() ||
       SLPDKnownDAInit())
    {
        SLPDLog("slpd initialization failed\n");
        goto cleanup_winsock;
    }
    SLPDLog("Agent Interfaces = %s\n",G_SlpdProperty.interfaces);

    /* Service is now running, perform work until shutdown    */
    if(!ReportStatusToSCMgr(SERVICE_RUNNING,       /* service state    */
                            NO_ERROR,              /* exit code    */
                            0))                    /* wait hint    */
    {
        goto cleanup_winsock;
    }


    /*-----------*/
    /* Main loop */
    /*-----------*/
    SLPDLog("Startup complete entering main run loop ...\n\n");
    G_SIGTERM   = 0;
    curtime = time(&alarmtime);
    alarmtime = curtime + SLPD_AGE_INTERVAL;
    while(G_SIGTERM == 0)
    {
        /*--------------------------------------------------------*/
        /* Load the fdsets up with all valid sockets in the list  */
        /*--------------------------------------------------------*/
        highfd = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds);
        LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds);

        /*--------------------------------------------------*/
        /* Before select(), check to see if we got a signal */
        /*--------------------------------------------------*/
        if(G_SIGALRM)
        {
            goto HANDLE_SIGNAL;
        }

        /*-------------*/
        /* Main select */
        /*-------------*/
        timeout.tv_sec = SLPD_AGE_INTERVAL;
        timeout.tv_usec = 0;
        fdcount = select(highfd+1,&readfds,&writefds,0,&timeout);
        if(fdcount > 0) /* fdcount will be < 0 when timed out */
        {
            SLPDIncomingHandler(&fdcount,&readfds,&writefds);
            SLPDOutgoingHandler(&fdcount,&readfds,&writefds);
        }

        /*----------------*/
        /* Handle signals */
        /*----------------*/
        HANDLE_SIGNAL:
        curtime = time(&curtime);
        if(curtime >= alarmtime)
        {
            HandleSigAlrm();
            alarmtime = curtime + SLPD_AGE_INTERVAL;
        }

    } /* End of main loop */

    /* Got SIGTERM */
    HandleSigTerm();
    cleanup_winsock:
    WSACleanup();     cleanup: 
    ;
} 
コード例 #12
0
ファイル: slpd_outgoing.c プロジェクト: Distrotech/openslp
/** Reconnect an outbound socket.
 *
 * @param[in] socklist - The list of sockets being monitored.
 * @param[in] sock - The socket to be reconnected.
 */
void OutgoingStreamReconnect(SLPList * socklist, SLPDSocket * sock)
{
   char addr_str[INET6_ADDRSTRLEN];

   (void)socklist;

   /*-----------------------------------------------------------------*/
   /* If socket is already being reconnected but is reconnect blocked */
   /* just return.  Blocking connect sockets will eventually time out */
   /*-----------------------------------------------------------------*/
   if (sock->state == STREAM_CONNECT_BLOCK)
      return;

#ifdef DEBUG
   /* Log that reconnect warning */
   SLPDLog("WARNING: Reconnect to agent at %s.  "
           "Agent may not be making efficient \n"
           "         use of TCP.\n",
         SLPNetSockAddrStorageToString(&sock->peeraddr,
               addr_str, sizeof(addr_str)));
#endif

   /*----------------------------------------------------------------*/
   /* Make sure we have not reconnected too many times               */
   /* We only allow SLPD_CONFIG_MAX_RECONN reconnection retries      */
   /* before we stop                                                 */
   /*----------------------------------------------------------------*/
   sock->reconns += 1;
   if (sock->reconns > SLPD_CONFIG_MAX_RECONN)
   {
      SLPDLog("WARNING: Reconnect tries to agent at %s "
              "exceeded maximum. It\n         is possible that "
              "the agent is malicious. Check it out!\n",
            SLPNetSockAddrStorageToString(&sock->peeraddr, 
                  addr_str, sizeof(addr_str)));

      /*Since we can't connect, remove it as a DA*/
      SLPDKnownDARemove(&(sock->peeraddr));
      sock->state = SOCKET_CLOSE;
      return;
   }

   /*----------------------------------------------------------------*/
   /* Close the existing socket to clean the stream  and open an new */
   /* socket                                                         */
   /*----------------------------------------------------------------*/
   closesocket(sock->fd);

   if (sock->peeraddr.ss_family == AF_INET)
      sock->fd = socket(PF_INET, SOCK_STREAM, 0);
   else if (sock->peeraddr.ss_family == AF_INET6)
      sock->fd = socket(PF_INET6, SOCK_STREAM, 0);

   if (sock->fd == SLP_INVALID_SOCKET)
   {
      sock->state = SOCKET_CLOSE;
      return;
   }

   /*---------------------------------------------*/
   /* Set the new socket to enable nonblocking IO */
   /*---------------------------------------------*/
#ifdef _WIN32
   {
      u_long fdflags = 1;
      ioctlsocket(sock->fd, FIONBIO, &fdflags);
   }
#else
   {
      int fdflags = fcntl(sock->fd, F_GETFL, 0);
      fcntl(sock->fd, F_SETFL, fdflags | O_NONBLOCK);
   }
#endif

   /*--------------------------*/
   /* Connect a the new socket */
   /*--------------------------*/
   if (connect(sock->fd, (struct sockaddr *)&sock->peeraddr,
         sizeof(struct sockaddr_storage)))
   {
#ifdef _WIN32
      if (WSAEWOULDBLOCK == WSAGetLastError())
#else
      if (errno == EINPROGRESS)
#endif
      {
         /* Connect blocked */
         sock->state = STREAM_CONNECT_BLOCK;
         return;
      }
   }

   /* Connection occured immediately. Set to WRITE_FIRST so whole */
   /* packet will be written                                      */
   sock->state = STREAM_WRITE_FIRST;
}
コード例 #13
0
ファイル: slpd_outgoing.c プロジェクト: Distrotech/openslp
/** Resend messages on sockets whose timeout has expired
 *
 * @param[in] seconds - The number of seconds old a socket must be to have
 * its messages resent.
 *
 * @remarks - Ideally, this would be at a resolution lower than one second, 
 * but given the default timeout values, this isn't too far off the mark, and
 * should not add too much of a burden to the main loop.
 */
void SLPDOutgoingRetry(time_t seconds)
{
   SLPDSocket * del = 0;
   SLPDSocket * sock = (SLPDSocket *) G_OutgoingSocketList.head;

   if(seconds <= 0)
      return;

   while (sock)
   {
      switch (sock->state)
      {
       case DATAGRAM_UNICAST:
          if(0 == sock->sendlist.count)  /*Clean up as fast as we can, as all messages were sent*/
             del = sock;
          else
          {
             sock->age += seconds;
             if(sock->age >= G_SlpdProperty.unicastTimeouts[sock->reconns] / 1000)
             {
               ++sock->reconns;
               if(sock->reconns >= MAX_RETRANSMITS)  
               {
                  char addr_str[INET6_ADDRSTRLEN];
                  SLPDLog("SLPD: Didn't receive response from DA at %s, removing it from list.\n",
                  SLPNetSockAddrStorageToString(&sock->peeraddr, addr_str, sizeof(addr_str)));
            
                  SLPDKnownDARemove(&(sock->peeraddr));
                  del = sock;
               }
               else
               {
                  SLPBuffer pbuf;
                  sock->age = 0;
                  for(pbuf = (SLPBuffer) sock->sendlist.head; pbuf; pbuf = (SLPBuffer) pbuf->listitem.next)
                     SLPDOutgoingDatagramWrite(sock, pbuf);
               }
             }
          }
            break;

         case DATAGRAM_MULTICAST:
         case DATAGRAM_BROADCAST:
         case STREAM_READ_FIRST:
         case STREAM_WRITE_FIRST:
         case STREAM_CONNECT_BLOCK:
         case STREAM_READ:
         case STREAM_WRITE:
         case STREAM_CONNECT_IDLE:
         case STREAM_WRITE_WAIT:
         default:
            break;
      }

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

      if (del)
      {
         SLPDSocketFree((SLPDSocket *)
               SLPListUnlink(&G_OutgoingSocketList, (SLPListItem *) del));
         del = 0;
      }
   }
}
コード例 #14
0
/** Reinitialize the slpd property management subsystem.
 *
 * Clears and rereads configuration parameters from files into the system.
 * Resets slpd-specific overrides.
 */
void SLPDPropertyReinit(void)
{
    int sts;
    char * myinterfaces = 0;
    int family = AF_UNSPEC;

    /* free previous settings (if any) */
    xfree(G_SlpdProperty.useScopes);
    xfree(G_SlpdProperty.DAAddresses);
    xfree(G_SlpdProperty.interfaces);
    xfree(G_SlpdProperty.locale);

    /* reinitialize property sub-system */
    (void)SLPPropertyReinit();

    /* set the properties without hard defaults */
    G_SlpdProperty.isDA = SLPPropertyAsBoolean("net.slp.isDA");
    G_SlpdProperty.activeDADetection = SLPPropertyAsBoolean("net.slp.activeDADetection");

    if (G_SlpdProperty.activeDADetection)
    {
        G_SlpdProperty.DAActiveDiscoveryInterval = SLPPropertyAsInteger("net.slp.DAActiveDiscoveryInterval");
        if (G_SlpdProperty.DAActiveDiscoveryInterval > 1
                && G_SlpdProperty.DAActiveDiscoveryInterval < SLPD_CONFIG_DA_FIND)
            G_SlpdProperty.DAActiveDiscoveryInterval = SLPD_CONFIG_DA_FIND;
    }
    else
        G_SlpdProperty.DAActiveDiscoveryInterval = 0;

    G_SlpdProperty.passiveDADetection = SLPPropertyAsBoolean("net.slp.passiveDADetection");
    G_SlpdProperty.staleDACheckPeriod = SLPPropertyAsInteger("net.slp.staleDACheckPeriod");
    if (G_SlpdProperty.staleDACheckPeriod > 0)
    {
        if (G_SlpdProperty.staleDACheckPeriod < (SLPD_HEARTBEATS_PER_CHECK_PERIOD + 1) * SLPD_AGE_INTERVAL)
            G_SlpdProperty.staleDACheckPeriod = (SLPD_HEARTBEATS_PER_CHECK_PERIOD + 1) * SLPD_AGE_INTERVAL;
        SLPDLog("staleDACheckPeriod = %ds\n", G_SlpdProperty.staleDACheckPeriod);
    }

    G_SlpdProperty.isBroadcastOnly = SLPPropertyAsBoolean("net.slp.isBroadcastOnly");
    G_SlpdProperty.multicastTTL = SLPPropertyAsInteger("net.slp.multicastTTL");
    G_SlpdProperty.multicastMaximumWait = SLPPropertyAsInteger("net.slp.multicastMaximumWait");
    G_SlpdProperty.unicastMaximumWait = SLPPropertyAsInteger("net.slp.unicastMaximumWait");
    SLPPropertyAsIntegerVector("net.slp.unicastTimeouts", G_SlpdProperty.unicastTimeouts, MAX_RETRANSMITS);
    G_SlpdProperty.randomWaitBound = SLPPropertyAsInteger("net.slp.randomWaitBound");
    G_SlpdProperty.maxResults = SLPPropertyAsInteger("net.slp.maxResults");
    G_SlpdProperty.traceMsg = SLPPropertyAsBoolean("net.slp.traceMsg");
    G_SlpdProperty.traceReg = SLPPropertyAsBoolean("net.slp.traceReg");
    G_SlpdProperty.traceDrop = SLPPropertyAsBoolean("net.slp.traceDrop");
    G_SlpdProperty.traceDATraffic = SLPPropertyAsBoolean("net.slp.traceDATraffic");
    G_SlpdProperty.appendLog = SLPPropertyAsBoolean("net.slp.appendLog");

    if ((G_SlpdProperty.DAAddresses = SLPPropertyXDup("net.slp.DAAddresses")) != 0)
        G_SlpdProperty.DAAddressesLen = strlen(G_SlpdProperty.DAAddresses);

    /** @todo Make sure that we are using scopes correctly. What about DHCP, etc? */

    if ((G_SlpdProperty.useScopes = SLPPropertyXDup("net.slp.useScopes")) != 0)
        G_SlpdProperty.useScopesLen = strlen(G_SlpdProperty.useScopes);

    if ((G_SlpdProperty.locale = SLPPropertyXDup("net.slp.locale")) != 0)
        G_SlpdProperty.localeLen = strlen(G_SlpdProperty.locale);

    G_SlpdProperty.securityEnabled = SLPPropertyAsBoolean("net.slp.securityEnabled");
    G_SlpdProperty.checkSourceAddr = SLPPropertyAsBoolean("net.slp.checkSourceAddr");
    G_SlpdProperty.DAHeartBeat = SLPPropertyAsInteger("net.slp.DAHeartBeat");
    if (G_SlpdProperty.staleDACheckPeriod > 0)
    {
        /* Adjust the heartbeat interval if we need to send it faster for
         * stale DA detection
         */
        int maxHeartbeat = G_SlpdProperty.staleDACheckPeriod / SLPD_HEARTBEATS_PER_CHECK_PERIOD;
        if ((G_SlpdProperty.DAHeartBeat == 0) ||
                (G_SlpdProperty.DAHeartBeat > maxHeartbeat))
        {
            SLPDLog("Overriding heartbeat to %ds for stale DA check\n", maxHeartbeat);
            G_SlpdProperty.DAHeartBeat = maxHeartbeat;
        }
    }
    /* Can't send it out more frequently than every interval */
    if (G_SlpdProperty.DAHeartBeat < SLPD_AGE_INTERVAL)
        G_SlpdProperty.DAHeartBeat = SLPD_AGE_INTERVAL;

    G_SlpdProperty.port = (uint16_t)SLPPropertyAsInteger("net.slp.port");

    /* set the net.slp.interfaces property */
    if (SLPNetIsIPV4() && SLPNetIsIPV6())
        family = AF_UNSPEC;
    else if (SLPNetIsIPV4())
        family = AF_INET;
    else if (SLPNetIsIPV6())
        family = AF_INET6;

    myinterfaces = SLPPropertyXDup("net.slp.interfaces");
    sts = SLPIfaceGetInfo(myinterfaces, &G_SlpdProperty.ifaceInfo, family);
    xfree(myinterfaces);

    if (!G_SlpdProperty.indexingPropertiesSet)
    {
#ifdef ENABLE_PREDICATES
        G_SlpdProperty.indexedAttributesLen = 0;
        if ((G_SlpdProperty.indexedAttributes = SLPPropertyXDup("net.slp.indexedAttributes")) != 0)
            G_SlpdProperty.indexedAttributesLen = strlen(G_SlpdProperty.indexedAttributes);
#endif

        G_SlpdProperty.srvtypeIsIndexed = SLPPropertyAsBoolean("net.slp.indexSrvtype");
        G_SlpdProperty.indexingPropertiesSet = 1;
    }
    else
    {
#ifdef ENABLE_PREDICATES
        int attrchg = 0;
        char *indexedAttributes = SLPPropertyXDup("net.slp.indexedAttributes");
        if (!indexedAttributes && G_SlpdProperty.indexedAttributes)
            attrchg = 1;
        else if (indexedAttributes && !G_SlpdProperty.indexedAttributes)
            attrchg = 1;
        else if (indexedAttributes)
        {
            if (strcmp(indexedAttributes, G_SlpdProperty.indexedAttributes) != 0)
                attrchg = 1;
        }
        if (attrchg)
            SLPDLog("Cannot change value of net.slp.indexedAttributes without restarting the daemon\n");
        xfree(indexedAttributes);
#endif
        if (G_SlpdProperty.srvtypeIsIndexed != SLPPropertyAsBoolean("net.slp.indexSrvtype"))
            SLPDLog("Cannot change value of net.slp.indexSrvtype without restarting the daemon\n");
    }

    if (sts == 0)
    {
        myinterfaces = 0;
        if (SLPIfaceSockaddrsToString(G_SlpdProperty.ifaceInfo.iface_addr,
                                      G_SlpdProperty.ifaceInfo.iface_count, &myinterfaces) == 0)
        {
            SLPPropertySet("net.slp.interfaces", myinterfaces, SLP_PA_USERSET);
            G_SlpdProperty.interfaces = myinterfaces;
            G_SlpdProperty.interfacesLen = strlen(G_SlpdProperty.interfaces);
        }
    }

    /* set the value used internally as the url for this agent */
    strcpy(G_SlpdProperty.urlPrefix, G_SlpdProperty.isDA? SLP_DA_SERVICE_TYPE: SLP_SA_SERVICE_TYPE);
    strcat(G_SlpdProperty.urlPrefix, "://");
    G_SlpdProperty.urlPrefixLen = strlen(G_SlpdProperty.urlPrefix);

    /* set other values used internally */
    G_SlpdProperty.DATimestamp = (uint32_t)time(0);     /* DATimestamp must be the boot time of the process */
    G_SlpdProperty.activeDiscoveryXmits = 3;  /* ensures xmit on first 3 calls to SLPDKnownDAActiveDiscovery() */
    G_SlpdProperty.nextActiveDiscovery = 0;   /* ensures xmit on first call to SLPDKnownDAActiveDiscovery() */
    G_SlpdProperty.nextPassiveDAAdvert = 0;   /* ensures xmit on first call to SLPDKnownDAPassiveDiscovery()*/

}
コード例 #15
0
ファイル: slpd_process.c プロジェクト: Distrotech/openslp
/** 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;
}                
コード例 #16
0
ファイル: slpd_log.c プロジェクト: ncultra/openslp
/*-------------------------------------------------------------------------*/
void SLPDLogSrvAckMessage(SLPSrvAck* srvack)
/*-------------------------------------------------------------------------*/
{
    SLPDLog("Message SRVACK:\n");
    SLPDLog("   errorcode = %i\n",srvack->errorcode);
}
コード例 #17
0
ファイル: slpd_process.c プロジェクト: Distrotech/openslp
/** Process a DA service request message.
 *
 * @param[in] message - The message to process.
 * @param[out] sendbuf - The response buffer to fill.
 * @param[in] errorcode - The error code from the client request.
 *
 * @return Zero on success, or a non-zero SLP error on failure.
 *
 * @internal
 */
static int ProcessDASrvRqst(SLPMessage * message, SLPBuffer * sendbuf, int errorcode)
{
   SLPBuffer tmp = 0;
   SLPMessage * msg = 0;
   void * eh = 0;
   /* TODO should really be a configurable property, maybe G_SlpdProperty.MTU? Left at 4096 to retain same behaviour */
   size_t initial_buffer_size = 4096;
   size_t grow_size = initial_buffer_size;

   /* Special case for when libslp asks slpd (through the loopback) about
      a known DAs. Fill sendbuf with DAAdverts from all known DAs.        
    */
   if (SLPNetIsLoopback(&message->peer))
   {
      *sendbuf = SLPBufferRealloc(*sendbuf, initial_buffer_size);
      if (*sendbuf == 0)
         return SLP_ERROR_INTERNAL_ERROR;

      if (errorcode == 0)
      {
         /* Note: The weird *sendbuf code is making a single SLPBuffer
            that contains multiple DAAdverts.  This is a special
            process that only happens for the DA SrvRqst through
            loopback to the SLPAPI
          */

         /*If we are a DA, always have ourself at the start of the list, so the
           lib requests can be handled locally for speed */
         if(G_SlpdProperty.isDA)
         {
            struct sockaddr_storage loaddr;

            if(SLPNetIsIPV4())
            {
               int addr = INADDR_LOOPBACK;
               SLPNetSetAddr(&loaddr, AF_INET, G_SlpdProperty.port, &addr);
            }
            else
			{
               SLPNetSetAddr(&loaddr, AF_INET6, G_SlpdProperty.port, &slp_in6addr_loopback);
			}

            if(0 == SLPDKnownDAGenerateMyDAAdvert(&loaddr, 0, 0, 0, message->header.xid, &tmp))
            {
               memcpy((*sendbuf)->curpos, tmp->start, tmp->end - tmp->start);
               (*sendbuf)->curpos = ((*sendbuf)->curpos) + (tmp->end - tmp->start);
               SLPBufferFree(tmp);
               tmp = 0;
            }
			else 
			{
				SLPDLog("Unable to add initial DAAdvert due to error\n");
			}
         }

         eh = SLPDKnownDAEnumStart();
         if (eh)
         {
            while (1)
            {
               /* iterate over all database entries */
               if (SLPDKnownDAEnum(eh, &msg, &tmp) == 0) 
			   {
                  break;
			   }

               /* if we resize succesfully.. */
               if( CheckAndResizeBuffer(sendbuf, tmp, grow_size) == 0 )
               {
            	   /* buffer should now be resized to an appropriate size to handle all current database entries */

                   /* TRICKY: Fix up the XID and clear the flags. */
                   tmp->curpos = tmp->start + 10;
                   TO_UINT16(tmp->curpos, message->header.xid);
                   if (*(tmp->start) == 1)
                       *(tmp->start + 4) = 0;
                   else
                       TO_UINT16(tmp->start + 5, 0);   

    			   /* copy all data out of tmp into the sendbuf */
                   memcpy((*sendbuf)->curpos, tmp->start, tmp->end - tmp->start);
    			   /* increment the current position in sendbuf */
                   (*sendbuf)->curpos = ((*sendbuf)->curpos) + (tmp->end - tmp->start);
               }
               else
               {
            	   errorcode = SLP_ERROR_INTERNAL_ERROR;
               }
            }
            SLPDKnownDAEnumEnd(eh);
         }
 		/* tmp can store database entries which should not be freed by anyone else so reset the pointer to prevent double deletion */
 		tmp = 0;

 		/* Tack on a "terminator" DAAdvert
 		   Note that this function *always* returns the error code passed as its second parameter (or SLP_ERROR_INTERNAL_ERROR if the buffer fails to resize)
 		   The errorcode is also inserted into the srvrply header by this function
 		*/
 		SLPDKnownDAGenerateMyDAAdvert(&message->localaddr, SLP_ERROR_INTERNAL_ERROR, 0, 0, message->header.xid, &tmp);

 		/* if we resize succesfully.. */
        if ( CheckAndResizeBuffer(sendbuf, tmp, grow_size) == 0 )
        {
     		memcpy((*sendbuf)->curpos, tmp->start, tmp->end - tmp->start);
     		(*sendbuf)->curpos = ((*sendbuf)->curpos) + (tmp->end - tmp->start);

     		/* mark the end of the sendbuf */
     		(*sendbuf)->end = (*sendbuf)->curpos;

        }
        else
        {
     	   errorcode = SLP_ERROR_INTERNAL_ERROR;
        }

        SLPBufferFree(tmp);
 		tmp = 0;
      }
      return errorcode;
   }
   
   /* Normal case where a remote Agent asks for a DA */

   *sendbuf = SLPBufferRealloc(*sendbuf, G_SlpdProperty.MTU);
   if (*sendbuf == 0)
      return SLP_ERROR_INTERNAL_ERROR;
   if (G_SlpdProperty.isDA)
   {
      if (message->body.srvrqst.scopelistlen == 0 
            || SLPIntersectStringList(message->body.srvrqst.scopelistlen,
                  message->body.srvrqst.scopelist, G_SlpdProperty.useScopesLen,
                  G_SlpdProperty.useScopes))
      {
         errorcode = SLPDKnownDAGenerateMyDAAdvert(&message->localaddr, 
               errorcode, 0, 0, message->header.xid, sendbuf);           
      }
      else
         errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
   }
   else
      errorcode = SLP_ERROR_MESSAGE_NOT_SUPPORTED;       

   /* don't return errorcodes to multicast messages */
   if (errorcode != 0)
   {
      if (message->header.flags & SLP_FLAG_MCAST 
            || SLPNetIsMCast(&(message->peer)))
         (*sendbuf)->end = (*sendbuf)->start;
   }
   return errorcode;
}
コード例 #18
0
ファイル: slpd_log.c プロジェクト: ncultra/openslp
/*-------------------------------------------------------------------------*/
void SLPDLogSrvTypeRplyMessage(SLPSrvTypeRply* srvtyperply)
/*-------------------------------------------------------------------------*/ 
{
    SLPDLog("Message SRVTYPERPLY:\n");
    SLPDLog("   errorcode = %i\n",srvtyperply->errorcode);
}        
コード例 #19
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);
            }
        }
    }
}
コード例 #20
0
ファイル: slpd_log.c プロジェクト: ncultra/openslp
/*=========================================================================*/
void SLPDLogMessageInternals(SLPMessage message)
/*=========================================================================*/
{
    SLPDLog("Peer: \n");
    SLPDLog("   IP address: %s\n", inet_ntoa(message->peer.sin_addr));
    SLPDLog("Header:\n");
    SLPDLog("   version = %i\n",message->header.version);
    SLPDLog("   functionid = %i\n",message->header.functionid);
    SLPDLog("   length = %i\n",message->header.length);
    SLPDLog("   flags = %i\n",message->header.flags);
    SLPDLog("   extoffset = %i\n",message->header.extoffset);
    SLPDLog("   xid = %i\n",message->header.xid);
    SLPDLogBuffer("   langtag = ", message->header.langtaglen, message->header.langtag); 

    switch (message->header.functionid)
    {
    case SLP_FUNCT_SRVRQST:
        SLPDLogSrvRqstMessage(&(message->body.srvrqst));
        break;

    case SLP_FUNCT_SRVRPLY:
        SLPDLogSrvRplyMessage(&(message->body.srvrply));
        break;

    case SLP_FUNCT_SRVREG:
        SLPDLogSrvRegMessage(&(message->body.srvreg));
        break;

    case SLP_FUNCT_SRVDEREG:
        SLPDLogSrvDeRegMessage(&(message->body.srvdereg));
        break;

    case SLP_FUNCT_SRVACK:
        SLPDLogSrvAckMessage(&(message->body.srvack));
        break;

    case SLP_FUNCT_ATTRRQST:
        SLPDLogAttrRqstMessage(&(message->body.attrrqst));
        break;

    case SLP_FUNCT_ATTRRPLY:
        SLPDLogAttrRplyMessage(&(message->body.attrrply));
        break;

    case SLP_FUNCT_DAADVERT:
        SLPDLogDAAdvertMessage(&(message->body.daadvert));
        break;

    case SLP_FUNCT_SRVTYPERQST:
        SLPDLogSrvTypeRqstMessage(&(message->body.srvtyperqst));
        break;

    case SLP_FUNCT_SRVTYPERPLY:
        SLPDLogSrvTypeRplyMessage(&(message->body.srvtyperply));
        break;

    case SLP_FUNCT_SAADVERT:
        SLPDLogSAAdvertMessage(&(message->body.saadvert));
        break;

    default:
        SLPDLog("Message %i UNKNOWN:\n",message->header.functionid);
        SLPDLog("   This is really bad\n");
        break;
    }
}
コード例 #21
0
/*-------------------------------------------------------------------------*/
void OutgoingStreamWrite(SLPList* socklist, SLPDSocket* sock)
/*-------------------------------------------------------------------------*/
{
    int        byteswritten;
    int        flags = 0;

#if defined(MSG_DONTWAIT)
    flags = MSG_DONTWAIT;
#endif

    if ( sock->state == STREAM_WRITE_FIRST )
    {
        /* make sure that there is something to do list */
        sock->sendbuf = (SLPBuffer)sock->sendlist.head;
        if ( sock->sendbuf == 0 )
        {
            /* there is nothing in the to do list */
            sock->state = STREAM_CONNECT_IDLE;
            /* reset the reconnect count because the socket */
            /* appears to be healthy again                  */
            sock->reconns = 0;
            return;
        }

        /* make sure that the start and curpos pointers are the same */
        sock->sendbuf->curpos = sock->sendbuf->start;
        sock->state = STREAM_WRITE;
    }

    if ( sock->sendbuf->end - sock->sendbuf->start > 0 )
    {
        byteswritten = send(sock->fd,
                            sock->sendbuf->curpos,
                            sock->sendbuf->end - sock->sendbuf->start,
                            flags);
        if ( byteswritten > 0 )
        {
            /* reset age because of activity */
            sock->age = 0; 

            /* move buffer pointers */
            sock->sendbuf->curpos += byteswritten;

            /* check to see if everything was written */
            if ( sock->sendbuf->curpos == sock->sendbuf->end )
            {
                /* Message is completely sent. Set state to read the reply */
                sock->state = STREAM_READ_FIRST;
            }
        }
        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);
            }
        }
    }
    else
    {
        /* nothing to write */
#ifdef DEBUG
        SLPDLog("yikes, an empty socket is being written!\n");
#endif
        sock->state = SOCKET_CLOSE;
    }
}
コード例 #22
0
/** Re-balance the (sub-)tree, if necessary. 
 *
 * Checks whether the tree is balanced, and performs rotations as required to
 * re-balance if necessary.
 * 
 * @param[in] root_node - a pointer to the root of the (sub-)tree.
 * 
 * @return New root node of the tree
 */
static IndexTreeNode *rebalance_tree(
   IndexTreeNode *root_node)
{
   /* Check whether we need to re-balance the (sub-)tree */
   if (root_node->left_depth - root_node->right_depth == 2)
   {
      /* Need to perform a right-rotation */
      IndexTreeNode *parent_node;
      IndexTreeNode *pivot = root_node->left_node;
      if (tree_depth(pivot->right_node) > tree_depth(pivot->left_node))
      {
         /* Rotate the pivot tree left first, as the right subtree will be
          * going beneath the current root node which will be going beneath
          * the pivot node, so will increase the depth.  By rotating the
          * subtrees, we ensure that the shallower sub-tree has its depth
          * increased, to minimise the difference in depth
          */
         IndexTreeNode *new_pivot = pivot->right_node;
         parent_node = pivot->parent_node;
         pivot->right_node = new_pivot->left_node;
         if (pivot->right_node)
            pivot->right_node->parent_node = pivot;
         pivot->right_depth = new_pivot->left_depth;
         pivot->parent_node = new_pivot;
         new_pivot->left_node = pivot;
         new_pivot->left_depth = tree_depth(pivot);
         new_pivot->parent_node = parent_node;
         pivot = new_pivot;
      }
      /* Now perform the right rotation */
      parent_node = root_node->parent_node;
      root_node->left_node = pivot->right_node;
      if (root_node->left_node)
         root_node->left_node->parent_node = root_node;
      root_node->left_depth = pivot->right_depth;
      root_node->parent_node = pivot;
      pivot->right_node = root_node;
      pivot->right_depth = tree_depth(root_node);
      pivot->parent_node = parent_node;
      root_node = pivot;
   }
   else if (root_node->right_depth - root_node->left_depth == 2)
   {
      /* Need to perform a left-rotation */
      IndexTreeNode *parent_node;
      IndexTreeNode *pivot = root_node->right_node;
      if (tree_depth(pivot->left_node) > tree_depth(pivot->right_node))
      {
         /* Rotate the pivot tree right first, as the left subtree will be
          * going beneath the current root node which will be going beneath
          * the pivot node, so will increase the depth.  By rotating the
          * subtrees, we ensure that the shallower sub-tree has its depth
          * increased, to minimise the difference in depth
          */
         IndexTreeNode *new_pivot = pivot->left_node;
         parent_node = pivot->parent_node;
         pivot->left_node = new_pivot->right_node;
         if (pivot->left_node)
            pivot->left_node->parent_node = pivot;
         pivot->left_depth = new_pivot->right_depth;
         pivot->parent_node = new_pivot;
         new_pivot->right_node = pivot;
         new_pivot->right_depth = tree_depth(pivot);
         new_pivot->parent_node = parent_node;
         pivot = new_pivot;
      }
      /* Now perform the left rotation */
      parent_node = root_node->parent_node;
      root_node->right_node = pivot->left_node;
      if (root_node->right_node)
         root_node->right_node->parent_node = root_node;
      root_node->right_depth = pivot->left_depth;
      root_node->parent_node = pivot;
      pivot->left_node = root_node;
      pivot->left_depth = tree_depth(root_node);
      pivot->parent_node = parent_node;
      root_node = pivot;
   }
#if defined(DEBUG) && defined(CHECKING)
   if (!check_tree(root_node)) {
      SLPDLog("Index tree check fails after rebalancing tree %p\n", root_node);
   }
#endif
   return root_node;
}
コード例 #23
0
/*-------------------------------------------------------------------------*/
void OutgoingStreamReconnect(SLPList* socklist, SLPDSocket* sock)
/*-------------------------------------------------------------------------*/
{
#ifdef WIN32
    u_long              fdflags;
#else    
    int                 fdflags;
#endif

    /*-----------------------------------------------------------------*/
    /* If socket is already being reconnected but is reconnect blocked */
    /* just return.  Blocking connect sockets will eventually time out */
    /*-----------------------------------------------------------------*/
    if(sock->state == STREAM_CONNECT_BLOCK)
    {
        return;
    }

    #ifdef DEBUG
    /* Log that reconnect warning */
    SLPDLog("WARNING: Reconnect to agent at %s.  Agent may not be making efficient \n"
            "         use of TCP.\n",
            inet_ntoa(sock->peeraddr.sin_addr));
    #endif

    /*----------------------------------------------------------------*/
    /* Make sure we have not reconnected too many times               */
    /* We only allow SLPD_CONFIG_MAX_RECONN reconnection retries      */
    /* before we stop                                                 */
    /*----------------------------------------------------------------*/
    sock->reconns += 1;
    if ( sock->reconns > SLPD_CONFIG_MAX_RECONN )
    {
        sock->state = SOCKET_CLOSE;
        SLPDLog("WARNING: Reconnect tries to agent at %s exceeded maximum. It\n"
                "         is possible that the agent is malicious.  Check it out!\n",
                inet_ntoa(sock->peeraddr.sin_addr));
        return;
    }

    /*----------------------------------------------------------------*/
    /* Close the existing socket to clean the stream  and open an new */
    /* socket                                                         */
    /*----------------------------------------------------------------*/
    CloseSocket(sock->fd);
    sock->fd = socket(PF_INET,SOCK_STREAM,0);
    if ( sock->fd < 0 )
    {
        sock->state = SOCKET_CLOSE;
        return;
    }

    /*---------------------------------------------*/
    /* Set the new socket to enable nonblocking IO */
    /*---------------------------------------------*/
#ifdef WIN32
    fdflags = 1;
    ioctlsocket(sock->fd, FIONBIO, &fdflags);
#else
    fdflags = fcntl(sock->fd, F_GETFL, 0);
    fcntl(sock->fd,F_SETFL, fdflags | O_NONBLOCK);
#endif


    /*--------------------------*/
    /* Connect a the new socket */
    /*--------------------------*/
    if ( connect(sock->fd, 
                 (struct sockaddr *)&(sock->peeraddr), 
                 sizeof(struct sockaddr_in)) )
    {
#ifdef WIN32
        if ( WSAEWOULDBLOCK == WSAGetLastError() )
#else
        if ( errno == EINPROGRESS )
#endif
        {
            /* Connect blocked */
            sock->state = STREAM_CONNECT_BLOCK;
            return;
        }
    }

    /* Connection occured immediately. Set to WRITE_FIRST so whole */
    /* packet will be written                                      */
    sock->state = STREAM_WRITE_FIRST;
}
コード例 #24
0
ファイル: slpd_log.c プロジェクト: ncultra/openslp
/*-------------------------------------------------------------------------*/
void SLPDLogSrvRplyMessage(SLPSrvRply* srvrply)
/*-------------------------------------------------------------------------*/
{
    SLPDLog("Message SRVRPLY:\n");
    SLPDLog("   errorcode = %i\n",srvrply->errorcode);
}
コード例 #25
0
ファイル: slpd_incoming.c プロジェクト: eSDK/eSDK_OBS_API
/** Read inbound stream data.
 *
 * @param[in] socklist - The list of monitored sockets.
 * @param[in] sock - The socket to be read.
 *
 * @internal
 */
static void IncomingStreamRead(SLPList * socklist, SLPDSocket * sock)
{
   int bytesread;
   size_t recvlen = 0;
   char peek[16];
   socklen_t peeraddrlen = sizeof(struct sockaddr_storage);

   if (sock->state == STREAM_READ_FIRST)
   {
      /*---------------------------------------------------*/
      /* take a peek at the packet to get size information */
      /*---------------------------------------------------*/
      bytesread = recvfrom(sock->fd, (char *)peek, 16, MSG_PEEK,
            (struct sockaddr *)&sock->peeraddr, &peeraddrlen);
      if (bytesread > 0 && bytesread >= (*peek == 2? 5: 4))
      {
         recvlen = PEEK_LENGTH(peek);

         /* allocate the recvbuf big enough for the whole message */
         sock->recvbuf = SLPBufferRealloc(sock->recvbuf, recvlen);
         if (sock->recvbuf)
            sock->state = STREAM_READ;
         else
         {
            SLPDLog("INTERNAL_ERROR - out of memory!\n");
            sock->state = SOCKET_CLOSE;
         }
      }
      else
      {
         sock->state = SOCKET_CLOSE;
         return;
      }
   }

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

      if (bytesread > 0)
      {
         /* reset age to max because of activity */
         sock->age = 0;
         sock->recvbuf->curpos += bytesread;
         if (sock->recvbuf->curpos == sock->recvbuf->end) {
            if (!sock->sendbuf)
               /* Some of the error handling code expects a sendbuf to be available
                * to be emptied, so make sure there is at least a minimal buffer
                */
               sock->sendbuf = SLPBufferAlloc(1);
            switch (SLPDProcessMessage(&sock->peeraddr,
                  &sock->localaddr, sock->recvbuf, &sock->sendbuf, 0))
            {
               case SLP_ERROR_PARSE_ERROR:
               case SLP_ERROR_VER_NOT_SUPPORTED:
               case SLP_ERROR_MESSAGE_NOT_SUPPORTED:
                  sock->state = SOCKET_CLOSE;
                  break;

               default:
                  if (!sock->sendbuf || sock->sendbuf->end == sock->sendbuf->start)
                  {
                     /* no answer available, just close socket */
                     sock->state = SOCKET_CLOSE;
                     break;
                  }

                  /* some clients cannot cope with the OVERFLOW
                   * bit set on a TCP stream, so always clear it
                   */
                  if (sock->sendbuf->end - sock->sendbuf->start > 5)
                  {
                     if (sock->sendbuf->start[0] == 1)
                        sock->sendbuf->start[4] &= ~SLPv1_FLAG_OVERFLOW;
                     else
                        sock->sendbuf->start[5] &= ~(SLP_FLAG_OVERFLOW >> 8);
                  }
                  sock->state = STREAM_WRITE_FIRST;
                  IncomingStreamWrite(socklist, sock);
            }
         }
      }