Example #1
0
/** Convert an array of sockaddr_storage buffers to a comma-delimited list.
 * 
 * Converts an array of sockaddr_storage buffers to a comma-delimited list of
 * addresses in presentation (string) format.
 *
 * @param[in] addrs - A pointer to array of sockaddr_storages to convert.
 * @param[in] addrcount - The number of elements in @p addrs.
 * @param[out] addrstr - The address in which to return a pointer to an
 *    allocated comma-delimited list of addresses.
 *
 * @return Zero on success, non-zero (with errno set) on error.
 *
 * @remarks The caller must free @p addrstr when no longer needed.
 */
int SLPIfaceSockaddrsToString(struct sockaddr_storage const * addrs,
      int addrcount, char ** addrstr)
{
   int i;

   SLP_ASSERT(addrs && addrcount && addrstr);
   if (!addrs || !addrcount || !addrstr)
      return (errno = EINVAL), -1;

   /* 40 is the maximum size of a string representation of
    * an IPv6 address (including the comma for the list) 
    */
   if ((*addrstr = xmalloc(addrcount * 40)) == 0)
      return (errno = ENOMEM), -1;

   **addrstr = 0;

   for (i = 0; i < addrcount; i++)
   {
      char buf[1024] = "";

      SLPNetSockAddrStorageToString(&addrs[i], buf, sizeof(buf));

      strcat(*addrstr, buf);
      if (i != addrcount - 1)
         strcat(*addrstr, ",");
   }
   return 0;
}  
Example #2
0
/*-------------------------------------------------------------------------*/
void SLPDLogPeerAddr(struct sockaddr_storage* peeraddr)
/*-------------------------------------------------------------------------*/
{
    char    addr_str[INET6_ADDRSTRLEN];

    SLPDLog("Peer IP address: %s\n", SLPNetSockAddrStorageToString(peeraddr, addr_str, sizeof(addr_str)));
}
Example #3
0
/** Dump outbound socket data.
 *
 * @note This routine is compiled in Debug code only.
 */
void SLPDOutgoingSocketDump(void) 
{
   char str1[INET6_ADDRSTRLEN];
   char str2[INET6_ADDRSTRLEN];
   char str3[INET6_ADDRSTRLEN];
   SLPDSocket * sock = (SLPDSocket *) G_OutgoingSocketList.head;
   SLPDLog("========================================================================\n");
   SLPDLog("Dumping OutgoingSocketList\n");
   SLPDLog("========================================================================\n");
   while (sock)
   {
      SLPDLog("localaddr=%s peeraddr=%s mcastaddr=%s\n",
         SLPNetSockAddrStorageToString(&(sock->localaddr), str1, sizeof(str1)),
         SLPNetSockAddrStorageToString(&(sock->peeraddr), str2, sizeof(str2)),
         SLPNetSockAddrStorageToString(&(sock->mcastaddr), str3, sizeof(str3)));
      sock = (SLPDSocket *) sock->listitem.next;
   }
}
Example #4
0
/*=========================================================================*/
void SLPDLogRegistration(const char* prefix, SLPDatabaseEntry* entry)
/* Log record of having added a registration to the database.  Logging of  */
/* registraions will only occur if registration trace is enabled           */
/* G_SlpProperty.traceReg != 0                                             */
/*                                                                         */
/* prefix   (IN) an informative prefix for the log entry                   */
/*                                                                         */
/* entry    (IN) the database entry that was affected                      */
/*                                                                         */
/* Returns: none                                                           */
/*=========================================================================*/
{
    char    addr_str[INET6_ADDRSTRLEN];

    if (prefix == NULL ||
        entry == NULL)
    {
        return;
    }

    if (G_SlpdProperty.traceReg)
    {
        SLPDLog("\n");
        SLPDLogTime();
        SLPDLog("DATABASE - %s:\n",prefix);
        SLPDLog("    SA address = ");
        switch (entry->msg->body.srvreg.source)
        {
        case SLP_REG_SOURCE_UNKNOWN:
            SLPDLog("<unknown>\n");
            break;
        case SLP_REG_SOURCE_REMOTE:
            SLPDLog("remote (%s)\n", SLPNetSockAddrStorageToString(&(entry->msg->peer), addr_str, sizeof(addr_str)));
            break;
        case SLP_REG_SOURCE_LOCAL:
            SLPDLog("IPC (libslp)\n");
            break;
        case SLP_REG_SOURCE_STATIC:
            SLPDLog("static (slp.reg)\n");
            break;
        }
        SLPDLogBuffer("    service-url = ",
                      entry->msg->body.srvreg.urlentry.urllen,
                      entry->msg->body.srvreg.urlentry.url);
        SLPDLogBuffer("    scope = ",
                      entry->msg->body.srvreg.scopelistlen,
                      entry->msg->body.srvreg.scopelist);
        SLPDLogBuffer("    attributes = ",
                      entry->msg->body.srvreg.attrlistlen,
                      entry->msg->body.srvreg.attrlist);
    }
}
Example #5
0
/*=========================================================================*/
void SLPDLogDAAdvertisement(const char* prefix,
                            SLPDatabaseEntry* entry)
/* Log record of addition or removal of a DA to the store of known DAs.    */
/* Will only occur if DA Advertisment message logging is enabled           */
/* G_SlpProperty.traceDATraffic != 0                                       */
/*                                                                         */
/* prefix   (IN) an informative prefix for the log entry                   */
/*                                                                         */
/* entry    (IN) the database entry that was affected                      */
/*                                                                         */
/* Returns: none                                                           */
/*=========================================================================*/
{
    char    addr_str[INET6_ADDRSTRLEN];

    if (prefix == NULL ||
        entry == NULL)
    {
        return;
    }

    if (G_SlpdProperty.traceDATraffic)
    {
        SLPDLog("\n");
        SLPDLogTime();
        SLPDLog("KNOWNDA - %s:\n",prefix);
        SLPDLog("    DA address = %s\n",SLPNetSockAddrStorageToString(&(entry->msg->peer), addr_str, sizeof(addr_str)));
        SLPDLogBuffer("    directory-agent-url = ",
                      entry->msg->body.daadvert.urllen,
                      entry->msg->body.daadvert.url);
        SLPDLog("    bootstamp = %x\n",entry->msg->body.daadvert.bootstamp);
        SLPDLogBuffer("    scope = ",
                      entry->msg->body.daadvert.scopelistlen,
                      entry->msg->body.daadvert.scopelist);
        SLPDLogBuffer("    attributes = ",
                      entry->msg->body.daadvert.attrlistlen,
                      entry->msg->body.daadvert.attrlist);
#ifdef ENABLE_SLPV2_SECURITY
        SLPDLogBuffer("    SPI list = ",
                      entry->msg->body.daadvert.spilistlen,
                      entry->msg->body.daadvert.spilist);
#endif /*ENABLE_SLPV2_SECURITY*/
    }
}
Example #6
0
/*=========================================================================*/
void SLPDLogMessage(int msglogflags,
                    struct sockaddr_storage* peerinfo,
                    struct sockaddr_storage* localaddr,
                    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                            */
/*                                                                         */
/* peerinfo (IN) the local address                                         */
/*                                                                         */
/* msg      (IN) the message to log                                        */
/*                                                                         */
/* Returns: none                                                           */
/*=========================================================================*/
{
    SLPMessage msg;
    char addr_str[INET6_ADDRSTRLEN];

    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 (!SLPNetIsLocal(peerinfo) && 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,localaddr,buf,msg) == 0)
                {
                    SLPDLogMessageInternals(msg);
                }
                else
                {
                    SLPDLog("Message parsing failed\n");
                    SLPDLog("Peer: \n");
                    SLPDLog("   IP address: %s\n", SLPNetSockAddrStorageToString(&(msg->peer), addr_str, sizeof(addr_str)));
                }

                SLPMessageFree(msg);
            }
        }
    }
}
Example #7
0
/*=========================================================================*/
void SLPDLogMessageInternals(SLPMessage message)
/*=========================================================================*/
{
    char    addr_str[INET6_ADDRSTRLEN];

    SLPDLog("Peer: \n");
    SLPDLog("   IP address: %s\n", SLPNetSockAddrStorageToString(&(message->peer), addr_str, sizeof(addr_str)));
    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;
    }
}
Example #8
0
int main(int argc, char * argv[])
{
   char addrString[1024];
   int sts;
   int errorCount = 0;
   struct sockaddr_storage addr;

#ifdef _WIN32
   WSADATA wsadata;
   WSAStartup(MAKEWORD(2, 2), &wsadata);
#endif

   sts = SLPNetResolveHostToAddr("localhost", &addr);
   if (sts != 0)
   {
      printf("error %d with SLPNetResolveHostToAddr.\r\n", sts);
      errorCount++;
   }
   else
   {
      printf("addr family = %d\r\n", addr.ss_family);
      SLPNetSockAddrStorageToString(&addr, addrString, sizeof(addrString));
      printf("address = %s\r\n", addrString);
   }

   sts = SLPNetResolveHostToAddr("::1", &addr);
   if (sts != 0)
   {
      printf("error %d with SLPNetResolveHostToAddr.\r\n", sts);
      errorCount++;
   }
   else
   {
      printf("addr family = %d\r\n", addr.ss_family);
      SLPNetSockAddrStorageToString(&addr, addrString, sizeof(addrString));
      printf("address = %s\r\n", addrString);
   }

   sts = SLPPropertyReadFile("e:\\source\\Hogwarts_ActiveX\\OpenSLP\\"
                         "ipv6\\win32\\slpd\\slp.conf");
   if (sts == 0)
      printf("Read config file\r\n");
   else
      printf("No config file found - using defaults.\r\n");

   sts = SLPNetIsIPV6();
   if (sts == 0)
      printf("Not using ipv6\r\n");
   else
      printf("Using ipv6\r\n");

   sts = SLPNetIsIPV4();
   if (sts == 0)
      printf("Not using ipv4\r\n");
   else
      printf("Using ipv4\r\n");
   {
      struct sockaddr_storage a1;
      struct sockaddr_storage a2;
      char testaddr[] = "1:2:3:4:5::6";
      struct sockaddr_in * p41 = (struct sockaddr_in *)&a1;
      struct sockaddr_in6 * p61 = (struct sockaddr_in6 *)&a1;
      struct sockaddr_in * p42 = (struct sockaddr_in *)&a2;
      struct sockaddr_in6 * p62 = (struct sockaddr_in6 *)&a2;

      memset(&a1, 0, sizeof(a1));
      memset(&a2, 0, sizeof(a2));
      SLPNetSetAddr(&a1, AF_INET6, 2, testaddr, sizeof(testaddr));
      memcpy(&a2, &a1, sizeof(a1));
      sts = SLPNetCompareAddrs(&a1, &a2);
      if (sts != 0)
         printf("Error, address a1 does not equal a2 - copy failed\r\n");
      memset(&a2, 0, sizeof(a2));
      a2.ss_family = AF_INET6;
      memcpy(p62->sin6_addr.s6_addr, testaddr, sizeof(testaddr));
      p62->sin6_family = AF_INET6;
      p62->sin6_port = htons(2);
      sts = SLPNetCompareAddrs(&a1, &a2);
      if (sts != 0)
         printf("Error, address a1 does not equal a2\r\n");
   }
   /* now test the ipv6 expansion */
   {
      char t1[] = "::";
      char a1[] = "0000:0000:0000:0000:0000:0000:0000:0000";

      char t2[] = "1::";
      char a2[] = "0001:0000:0000:0000:0000:0000:0000:0000";

      char t3[] = "::1";
      char a3[] = "0000:0000:0000:0000:0000:0000:0000:0001";

      char t4[] = "12::34";
      char a4[] = "0012:0000:0000:0000:0000:0000:0000:0034";

      char t5[] = "1111:2222:3333::5555:6666:7777:8888";
      char a5[] = "1111:2222:3333:0000:5555:6666:7777:8888";

      char t6[] = "1:02::003:0004";
      char a6[] = "0001:0002:0000:0000:0000:0000:0003:0004";

      char t7[] = "0001:0002:0003:0004:0005:0006:0007:0008";
      char a7[] = "0001:0002:0003:0004:0005:0006:0007:0008";

      char t8[] = "1:02:003:0004:0005:006:07:8";
      char a8[] = "0001:0002:0003:0004:0005:0006:0007:0008";

      char i1[] = "1::2::3";
      char i2[] = "1:::3";

      char buf[40];  /* min buf size - 8*4 + 7 + null */
      int sts;

      sts = SLPNetExpandIpv6Addr(t1, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a1) != 0))
         printf("Error expanding ipv6 address t1\r\n");

      sts = SLPNetExpandIpv6Addr(t2, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a2) != 0))
         printf("Error expanding ipv6 address t2\r\n");

      sts = SLPNetExpandIpv6Addr(t3, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a3) != 0))
         printf("Error expanding ipv6 address t3\r\n");

      sts = SLPNetExpandIpv6Addr(t4, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a4) != 0))
         printf("Error expanding ipv6 address t4\r\n");

      sts = SLPNetExpandIpv6Addr(t5, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a5) != 0))
         printf("Error expanding ipv6 address t5\r\n");

      sts = SLPNetExpandIpv6Addr(t6, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a6) != 0))
         printf("Error expanding ipv6 address t6\r\n");

      sts = SLPNetExpandIpv6Addr(t7, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a7) != 0))
         printf("Error expanding ipv6 address t7\r\n");

      sts = SLPNetExpandIpv6Addr(t8, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a8) != 0))
         printf("Error expanding ipv6 address t8\r\n");

      sts = SLPNetExpandIpv6Addr(i1, buf, sizeof(buf));
      sts = SLPNetExpandIpv6Addr(i2, buf, sizeof(buf));
      sts = SLPNetExpandIpv6Addr(t6, buf, 5);
      if (sts == 0)
         printf("Error, size not checked for expansion\r\n");
   }

   /* int SLPNetIsMCast(const struct sockaddr_storage *addr);
    * int SLPNetIsLocal(const struct sockaddr_storage *addr);
    */

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

#ifdef DEBUG
   char addr_str[INET6_ADDRSTRLEN];
#endif

   SLPDLogMessage(SLPDLOG_TRACEMSG_IN, peerinfo, localaddr, recvbuf);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            pbuf = pnext;
          }
       }

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

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

FINISHED:

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

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

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

   return errorcode;
}                
Example #10
0
int main(int argc, char * argv[])
{
   int i;
   int addrscount = 10;
   struct sockaddr_storage addrs[10];
   SLPIfaceInfo ifaceinfo;
   char * addrstr;

#ifdef _WIN32
   WSADATA wsadata;
   WSAStartup(MAKEWORD(2, 2), &wsadata);
#endif

   if (SLPIfaceGetInfo(0, &ifaceinfo, AF_INET) == 0)
      for (i = 0; i < ifaceinfo.iface_count; i++)
      {
         char myname[MAX_HOST_NAME];

         SLPNetSockAddrStorageToString(&ifaceinfo.iface_addr[i], myname,
               sizeof(myname));
         printf("v4 found iface = %s\n", myname);
         SLPNetSockAddrStorageToString(&ifaceinfo.bcast_addr[i], myname,
               sizeof(myname));
         printf("v4 bcast addr = %s\n", myname);
      }

   if (SLPIfaceGetInfo(0, &ifaceinfo, AF_INET6) == 0)
   {
      for (i = 0; i < ifaceinfo.iface_count; i++)
      {
         char myname[MAX_HOST_NAME];

         SLPNetSockAddrStorageToString(&ifaceinfo.iface_addr[i], myname,
               sizeof(myname));
         printf("v6 found iface = %s\n", myname);
      }
      for (i = 0; i < ifaceinfo.bcast_count; i++)
      {
         char myname[MAX_HOST_NAME];

         SLPNetSockAddrStorageToString(&ifaceinfo.bcast_addr[i], myname,
               sizeof(myname));
         printf("v6 bcast addr = %s\n", myname);
      }
   }

   SLPIfaceGetInfo("fec0:0:0:0001:0:0:0:3,5:6::7,10.0.25.82", &ifaceinfo,
         AF_INET6);
   SLPIfaceGetInfo("fec0:0:0:0001:0:0:0:3,5:6::7,10.0.25.82", &ifaceinfo,
         AF_INET);
   if (SLPIfaceStringToSockaddrs("192.168.100.1,192.168.101.1", addrs,
            &addrscount) == 0)
      if (SLPIfaceSockaddrsToString(addrs, addrscount, &addrstr) == 0)
      {
         printf("sock addr string v4 = %s\n", addrstr);
         xfree(addrstr);
      }

   if (SLPIfaceStringToSockaddrs("1:2:0:0:0::4,10:0:0:0:0:0:0:11", addrs,
            &addrscount) == 0)
      if (SLPIfaceSockaddrsToString(addrs, addrscount, &addrstr) == 0)
      {
         printf("sock addr string v6 = %s\n", addrstr);
         xfree(addrstr);
      }

#ifdef _WIN32
   WSACleanup();
#endif
}
Example #11
0
/** 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;
}
Example #12
0
/** 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;
      }
   }
}
Example #13
0
/** 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;
      }
   }
}