Exemplo n.º 1
0
/*=========================================================================*/ 
SLPError NetworkRqstRply(int sock,
                         struct sockaddr_in* destaddr,
                         const char* langtag,
                         char* buf,
                         char buftype,
                         int bufsize,
                         NetworkRqstRplyCallback callback,
                         void * cookie)
/* Transmits and receives SLP messages via multicast convergence algorithm */
/*                                                                         */
/* Returns  -    SLP_OK on success                                         */
/*=========================================================================*/ 
{
    struct timeval      timeout;
    struct sockaddr_in  peeraddr;
    SLPBuffer           sendbuf         = 0;
    SLPBuffer           recvbuf         = 0;
    SLPMessage          msg             = 0;
    SLPError            result          = 0;
#ifdef WIN32 /* on WIN32 setsockopt takes a const char * argument */
    char                socktype        = 0;
#else
    int                 socktype        = 0;
#endif
    int                 langtaglen      = 0;
    int                 prlistlen       = 0;
    char*               prlist          = 0;
    int                 xid             = 0;
    int                 mtu             = 0;
    int                 size            = 0;
    int                 xmitcount       = 0;
    int                 rplycount       = 0;
    int                 maxwait         = 0;
    int                 totaltimeout    = 0;
    int                 timeouts[MAX_RETRANSMITS];

    /*----------------------------------------------------*/
    /* Save off a few things we don't want to recalculate */
    /*----------------------------------------------------*/
    langtaglen = strlen(langtag);
    xid = SLPXidGenerate();
    mtu = SLPPropertyAsInteger(SLPGetProperty("net.slp.MTU"));
    sendbuf = SLPBufferAlloc(mtu);
    if(sendbuf == 0)
    {                 
        result = SLP_MEMORY_ALLOC_FAILED;
        goto CLEANUP;
    }

    if(buftype == SLP_FUNCT_DASRVRQST)
    {
        /* do something special for SRVRQST that will be discovering DAs */
        maxwait = SLPPropertyAsInteger(SLPGetProperty("net.slp.DADiscoveryMaximumWait"));
        SLPPropertyAsIntegerVector(SLPGetProperty("net.slp.DADiscovertTimeouts"),
                                   timeouts,
                                   MAX_RETRANSMITS );
        /* SLP_FUNCT_DASRVRQST is a fake function.  We really want to */
        /* send a SRVRQST                                             */
        buftype = SLP_FUNCT_SRVRQST;
    }
     
    /* Figure unicast/multicast,TCP/UDP, wait and time out stuff */
    if(ntohl(destaddr->sin_addr.s_addr) > 0xe0000000)
    {
        /* Multicast or broadcast */
        maxwait = SLPPropertyAsInteger(SLPGetProperty("net.slp.multicastMaximumWait"));
        SLPPropertyAsIntegerVector(SLPGetProperty("net.slp.multicastTimeouts"), 
                                   timeouts, 
                                   MAX_RETRANSMITS );
        socktype = SOCK_DGRAM;
        xmitcount = 0;
    }
    else
    {
        maxwait = SLPPropertyAsInteger(SLPGetProperty("net.slp.unicastMaximumWait"));
        SLPPropertyAsIntegerVector(SLPGetProperty("net.slp.unicastTimeouts"), 
                                   timeouts, 
                                   MAX_RETRANSMITS );
        size = sizeof(socktype);
        getsockopt(sock,SOL_SOCKET,SO_TYPE,&socktype,&size);
        socktype = SOCK_STREAM;
        xmitcount = MAX_RETRANSMITS;
    }
    
    
    
    /*--------------------------------*/
    /* Allocate memory for the prlist */
    /*--------------------------------*/
    prlist = (char*)malloc(mtu);
    if(prlist == 0)
    {
        result = SLP_MEMORY_ALLOC_FAILED;
        goto CLEANUP;
    }
    *prlist = 0;
    prlistlen = 0;
    
    /*--------------------------*/
    /* Main retransmission loop */
    /*--------------------------*/
    while(xmitcount <= MAX_RETRANSMITS)
    {
        xmitcount++;

        /*--------------------*/
        /* setup recv timeout */
        /*--------------------*/
        if(socktype == SOCK_DGRAM)
        {   
            totaltimeout += timeouts[xmitcount];
            if(totaltimeout >= maxwait || timeouts[xmitcount] == 0)
            {
                /* we are all done */
                break;
            }
            timeout.tv_sec = timeouts[xmitcount] / 1000;
            timeout.tv_usec = (timeouts[xmitcount] % 1000) * 1000;
        }
        else
        {
            timeout.tv_sec = maxwait / 1000;
            timeout.tv_usec = (maxwait % 1000) * 1000;
        }
        
        size = 14 + langtaglen + 2 + prlistlen + bufsize;
        if(SLPBufferRealloc(sendbuf,size) == 0)
        {
            result = SLP_MEMORY_ALLOC_FAILED;
            goto CLEANUP;
        }

        /*-----------------------------------*/
        /* Add the header to the send buffer */
        /*-----------------------------------*/
        /*version*/
        *(sendbuf->start)       = 2;
        /*function id*/
        *(sendbuf->start + 1)   = buftype;
        /*length*/
        ToUINT24(sendbuf->start + 2, size);
        /*flags*/
        ToUINT16(sendbuf->start + 5, socktype == SOCK_STREAM ? 0 : SLP_FLAG_MCAST);
        /*ext offset*/
        ToUINT24(sendbuf->start + 7,0);
        /*xid*/
        ToUINT16(sendbuf->start + 10,xid);
        /*lang tag len*/
        ToUINT16(sendbuf->start + 12,langtaglen);
        /*lang tag*/
        memcpy(sendbuf->start + 14, langtag, langtaglen);
        sendbuf->curpos = sendbuf->start + langtaglen + 14 ;

        /*-----------------------------------*/
        /* Add the prlist to the send buffer */
        /*-----------------------------------*/
        if( buftype == SLP_FUNCT_SRVRQST ||
            buftype == SLP_FUNCT_ATTRRQST ||
            buftype == SLP_FUNCT_SRVTYPERQST)
        {
            ToUINT16(sendbuf->curpos,prlistlen);
            sendbuf->curpos = sendbuf->curpos + 2;
            memcpy(sendbuf->curpos, prlist, prlistlen);
            sendbuf->curpos = sendbuf->curpos + prlistlen;
        }
         
        /*-----------------------------*/
        /* Add the rest of the message */
        /*-----------------------------*/
        memcpy(sendbuf->curpos, buf, bufsize);
        
        /*----------------------*/
        /* send the send buffer */
        /*----------------------*/
        result = SLPNetworkSendMessage(sock,
                                       sendbuf,
                                       destaddr,
                                       &timeout);
        if(result != 0)
        {
            /* we could not send the message for some reason */
            /* we're done */
            result = SLP_NETWORK_ERROR;
            goto FINISHED;
        }
            
 
        /*----------------*/
        /* Main recv loop */
        /*----------------*/
        while(1)
        {
            
            if(SLPNetworkRecvMessage(sock,
                                     &recvbuf,
                                     &peeraddr,
                                     &timeout) != 0)
            {
                /* An error occured while receiving the message */
                /* probably a just time out error. Retry send.  */
                break;
            }
             
            /* Parse the message and call callback */
            msg = SLPMessageRealloc(msg);
            if(msg == 0)
            {
                result = SLP_MEMORY_ALLOC_FAILED;
                goto FINISHED;
            }

            if(SLPMessageParseBuffer(recvbuf, msg) == 0)
            {
                if (msg->header.xid == xid)
                {
                    rplycount = rplycount + 1;
                    if(callback(result, msg, cookie) == 0)
                    {
                        goto CLEANUP;
                    }
                }
            }
            
            if(socktype == SOCK_STREAM)
            {
                goto FINISHED;
            }

            /* add the peer to the previous responder list */
            if(prlistlen != 0)
            {
                strcat(prlist,",");
            }
            strcat(prlist,inet_ntoa(peeraddr.sin_addr));
            prlistlen =  strlen(prlist); 
        }
    }

    FINISHED:
    /*----------------*/
    /* We're all done */
    /*----------------*/
    if(rplycount == 0)
    {
        result = SLP_NETWORK_TIMED_OUT;
    }

    /*-------------------------------------*/
    /* Notify the callback that we're done */
    /*-------------------------------------*/
    callback(SLP_LAST_CALL,msg,cookie);
    
    /*----------------*/
    /* Free resources */
    /*----------------*/
    CLEANUP:
    if(prlist) free(prlist);
    SLPBufferFree(sendbuf);
    SLPBufferFree(recvbuf);
    SLPMessageFree(msg);
    close(sock);

    return result;
}
Exemplo n.º 2
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()*/

}
Exemplo n.º 3
0
int main(int argc, char * argv[])
{
   int ec, nval, ival;
   bool bval;
   int ivec[10];
   FILE * fp;
   char const * pval;

   /* create a global configuration file */
   fp = fopen(TEST_G_CFG_FILENAME, "w+");
   if (!fp)
      return FAIL;
   fputs("\n", fp);
   fputs(" \n", fp);
   fputs("# This is a comment.\n", fp);
   fputs(" # This is another comment.\n", fp);
   fputs(" \t\f# This is the last comment.\n", fp);
   fputs("\t\t   \f\tStrange Text with no equals sign\n", fp);
   fputs("net.slp.isDA=true\n", fp);         /* default value is false */
   fputs("net.slp.DAHeartBeat = 10801\n", fp);
   fputs("net.slp.DAAttributes=\n", fp);
   fputs("net.slp.useScopes =DEFAULT\n", fp);
   fputs("net.slp.DAAddresses\t\t\t=       \n", fp);
   fputs("net.slp.traceDATraffic = true\n", fp);
   fputs("net.slp.multicastTimeouts=1001,1251,1501,2001,4001\n", fp);
   fclose(fp);

   /* create an application configuration file */
   fp = fopen(TEST_A_CFG_FILENAME, "w+");
   if (!fp)
      return FAIL;
   fputs("net.slp.DAHeartBeat = 10802\n", fp);
   fclose(fp);

   /* specify app configuration file */
   ec = SLPPropertySetAppConfFile(TEST_A_CFG_FILENAME);
   if (ec != 0)
      return FAIL;

   /* specify global configuration file - initialize */
   ec = SLPPropertyInit(TEST_G_CFG_FILENAME);
   if (ec != 0)
      return FAIL;

   /* set a mutable value */
   ec = SLPPropertySet("net.slp.traceDATraffic", "false", 0);
   if (ec != 0)
      return FAIL;

   /* set a user-only settable value */
   ec = SLPPropertySet("net.slp.isDA", "false", SLP_PA_USERSET);
   if (ec != 0)
      return FAIL;

   pval = SLPPropertyGet("net.slp.traceDATraffic", 0, 0);
   if (pval == 0 || strcmp(pval, "false") != 0)
      return FAIL;

   ival = SLPPropertyAsInteger("net.slp.DAHeartBeat");
   if (ival != 10802)
      return FAIL;

   bval = SLPPropertyAsBoolean("net.slp.isDA");
   if (bval != false)
      return FAIL;

   nval = SLPPropertyAsIntegerVector("net.slp.multicastTimeouts", ivec, 10);
   if (nval != 5 || ivec[0] != 1001 || ivec[1] != 1251 || ivec[2] != 1501
         || ivec[3] != 2001 || ivec[4] != 4001)
      return FAIL;

   ival = SLPPropertyAsInteger("net.slp.fake");
   if (ival != 0)
      return FAIL;

   bval = SLPPropertyAsBoolean("net.slp.fake");
   if (bval != false)
      return FAIL;

   nval = SLPPropertyAsIntegerVector("net.slp.fake", ivec, 10);
   if (nval != 0)
      return FAIL;

   pval = SLPPropertyGet("net.slp.OpenSLPConfigFile", 0, 0);
   if (pval == 0 || strcmp(pval, TEST_G_CFG_FILENAME) != 0)
      return FAIL;

   /* reset a user-only settable value - indicate non-user is setting */
   ec = SLPPropertySet("net.slp.isDA", "true", 0);
   if (ec == 0)
      return FAIL;

   /* reset a user-only settable value - indicate user is setting */
   ec = SLPPropertySet("net.slp.isDA", "true", SLP_PA_USERSET);
   if (ec != 0)
      return FAIL;

   SLPPropertyExit();

   unlink(TEST_A_CFG_FILENAME);
   unlink(TEST_G_CFG_FILENAME);

   return PASS;
}