/** Associates a unicast IP address with an open SLP handle. * * Associates an IP address @p unicast_ip with a particular SLPHandle * @p hSLP. @p unicast_ip is the IP address of the SA/DA from which service * is requested. * * @param[in] hSLP - The SLPHandle with which the @p unicast_ip address is * to be associated. * * @param[in] unicast_ip - IP address of the SA/DA from which service * is requested. * * @return An SLPError code. */ SLPEXP SLPError SLPAPI SLPAssociateIP( SLPHandle hSLP, const char * unicast_ip) { #ifndef UNICAST_NOT_SUPPORTED SLPHandleInfo * handle; int result; SLP_ASSERT(hSLP != 0); SLP_ASSERT(*(unsigned int *)hSLP == SLP_HANDLE_SIG); SLP_ASSERT(unicast_ip != 0); SLP_ASSERT(*unicast_ip != 0); /* check for invalid parameters */ if (!hSLP || *(unsigned int*)hSLP != SLP_HANDLE_SIG || !unicast_ip || !*unicast_ip) return SLP_PARAMETER_BAD; handle = (SLPHandleInfo *)hSLP; handle->dounicast = SLP_TRUE; /** @todo Verify error conditions in associate ip address. */ result = SLPNetResolveHostToAddr(unicast_ip, &handle->ucaddr); if (SLPNetSetPort(&handle->ucaddr, (uint16_t)SLPPropertyAsInteger("net.slp.port")) != 0) return SLP_PARAMETER_BAD; return SLP_OK; #else (void)hSLP; (void)unicast_ip; return SLP_NOT_IMPLEMENTED; #endif /* ! UNICAST_NOT_SUPPORTED */ }
/** Multicast a message. * * @param[in] ifaceinfo - A pointer to the SLPIfaceInfo structure that * contains information about the interfaces on which to send. * @param[in] msg - The buffer to be sent. * @param[out] socks - The address of storage for the sockets that were used * to multicast. * @param[in] dst - The target address, if using ipv6; can be null for IPv4. * * @return Zero on sucess, or a non-zero value, with errno set on error. * * @remarks May be used to receive responses. Must be close by caller using * SLPXcastSocketsClose. */ int SLPMulticastSend(const SLPIfaceInfo * ifaceinfo, const SLPBuffer msg, SLPXcastSockets * socks, struct sockaddr_storage * dst) { int flags = 0; int xferbytes; #ifdef MSG_NOSIGNAL flags = MSG_NOSIGNAL; #endif for (socks->sock_count = 0; socks->sock_count < ifaceinfo->iface_count; socks->sock_count++) { int family = ifaceinfo->iface_addr[socks->sock_count].ss_family; socks->sock[socks->sock_count] = socket(family, SOCK_DGRAM, 0); if((socks->sock[socks->sock_count] == SLP_INVALID_SOCKET) || (SetMulticastIF(family, socks->sock[socks->sock_count], &ifaceinfo->iface_addr[socks->sock_count]) || (SetMulticastTTL(family, socks->sock[socks->sock_count], SLPPropertyAsInteger("net.slp.multicastTTL"))))) return -1; /* error creating socket or setting socket option */ SLPNetworkSetSndRcvBuf(socks->sock[socks->sock_count]); memcpy(&socks->peeraddr[socks->sock_count], dst, sizeof(struct sockaddr_storage)); xferbytes = sendto(socks->sock[socks->sock_count], (char *)msg->start, (int)(msg->end - msg->start), flags, (struct sockaddr *)&socks->peeraddr[socks->sock_count], SLPNetAddrLen(&socks->peeraddr[socks->sock_count])); if (xferbytes <= 0) return -1; /* error sending */ } return 0; }
/*=========================================================================*/ int KnownDADiscover(struct timeval* timeout) /* Returns: the number of DAs discovered */ /*=========================================================================*/ { int fd; int result = 0; /* TODO THIS FUNCTION MUST BE SYNCRONIZED !! */ /* two threads must not be in here at the same time */ /*----------------------------------------------------*/ /* Check values from the net.slp.DAAddresses property */ /*----------------------------------------------------*/ result = KnownDADiscoveryByProperties(timeout); if (result) { KnownDASaveHints(); return result; } /*------------------------------*/ /* Check data from DHCP Options */ /*------------------------------*/ /* TODO put code here when you can */ /*-----------------------------------*/ /* Load G_KnownDAListhead from hints */ /*-----------------------------------*/ fd = open(SLPGetProperty("net.slp.HintsFile"),O_RDONLY); if (fd >= 0) { SLPDAEntryListRead(fd, &G_KnownDAList); close(fd); if (G_KnownDAList.count) { return G_KnownDAList.count; } } /*-------------------*/ /* Multicast for DAs */ /*-------------------*/ if (SLPPropertyAsBoolean(SLPGetProperty("net.slp.activeDADetection")) && SLPPropertyAsInteger(SLPGetProperty("net.slp.DAActiveDiscoveryInterval"))) { result = KnownDADiscoveryByMulticast(); if (result) { KnownDASaveHints(); return result; } } return 0; }
/*-------------------------------------------------------------------------*/ int KnownDADiscoverFromProperties() /* Locates DAs from a list of DA hostnames */ /* */ /* Returns: number of *new* DAs found */ /*-------------------------------------------------------------------------*/ { char* temp; char* tempend; char* slider1; char* slider2; int sockfd; struct hostent* he; struct sockaddr_in peeraddr; struct timeval timeout; int result = 0; memset(&peeraddr,0,sizeof(peeraddr)); peeraddr.sin_family = AF_INET; peeraddr.sin_port = htons(SLP_RESERVED_PORT); slider1 = slider2 = temp = strdup(SLPGetProperty("net.slp.DAAddresses")); if(temp) { tempend = temp + strlen(temp); while(slider1 != tempend) { timeout.tv_sec = SLPPropertyAsInteger(SLPGetProperty("net.slp.DADiscoveryMaximumWait")); timeout.tv_usec = (timeout.tv_sec % 1000) * 1000; timeout.tv_sec = timeout.tv_sec / 1000; while(*slider2 && *slider2 != ',') slider2++; *slider2 = 0; he = gethostbyname(slider1); if(he) { peeraddr.sin_addr.s_addr = *((unsigned int*)(he->h_addr_list[0])); sockfd = SLPNetworkConnectStream(&peeraddr,&timeout); if(sockfd >= 0) { result = KnownDADiscoveryRqstRply(sockfd,&peeraddr,0,""); close(sockfd); if(result) { break; } } } slider1 = slider2; slider2++; } free(temp); } return result; }
/*=========================================================================*/ int KnownDAConnect(int scopelistlen, const char* scopelist, struct sockaddr_in* peeraddr) /* Get a connected socket to a DA that supports the specified scope */ /* */ /* scopelistlen (IN) stringlen of the scopelist */ /* */ /* scopelist (IN) DA must support this scope */ /* */ /* peeraddr (OUT) the peer that was connected to */ /* */ /* */ /* returns: valid socket file descriptor or -1 if no DA is found */ /*=========================================================================*/ { struct timeval timeout; SLPDAEntry* daentry; int sock = -1; /* Set up connect timeout */ timeout.tv_sec = SLPPropertyAsInteger(SLPGetProperty("net.slp.DADiscoveryMaximumWait")); timeout.tv_usec = (timeout.tv_sec % 1000) * 1000; timeout.tv_sec = timeout.tv_sec / 1000; while(1) { daentry = KnownDAFromCache(scopelistlen,scopelist); if(daentry == 0) { break; } memset(peeraddr,0,sizeof(peeraddr)); peeraddr->sin_family = AF_INET; peeraddr->sin_port = htons(SLP_RESERVED_PORT); peeraddr->sin_addr = daentry->daaddr; sock = SLPNetworkConnectStream(peeraddr,&timeout); if(sock >= 0) { break; } KnownDAListRemove(&G_KnownDACache,daentry); } return sock; }
/** Determines an IPv6 multi-cast address for a specified service type. * * The multi-cast address is determined from a hash value calculated on the * string name of the service type. * * @param[in] pSrvType - The service type string. * @param[in] len - The length of @p pSrvType in bytes. * @param[in] scope - The scope associated with this request. * @param[out] addr - The address buffer in which to return the address. * * @return Zero on success, or a non-zero value on failure. */ int SLPNetGetSrvMcastAddr(const char * pSrvType, size_t len, int scope, void * addr) { struct sockaddr_in6 * a = (struct sockaddr_in6 *)addr; unsigned long group_id = 0; struct in6_addr * v6; if (a == 0 || pSrvType == 0) return -1; memset(a, 0, sizeof(struct sockaddr_in6)); /* Run Hash to get group id */ while (len-- != 0) { group_id *= 33; group_id += *pSrvType++; } group_id &= 0x3FF; v6 = &a->sin6_addr; if (scope == SLP_SCOPE_NODE_LOCAL) memcpy(v6, &in6addr_service_node_mask, sizeof(struct in6_addr)); else if (scope == SLP_SCOPE_LINK_LOCAL) memcpy(v6, &in6addr_service_link_mask, sizeof(struct in6_addr)); else if (scope == SLP_SCOPE_SITE_LOCAL) memcpy(v6, &in6addr_service_site_mask, sizeof(struct in6_addr)); else return -1; #ifndef _WIN32 /*Linux needs to have the scope set to the multicast scope*/ a->sin6_scope_id = scope; #endif v6->s6_addr[15] |= (group_id & 0xFF); v6->s6_addr[14] |= (group_id >> 8); a->sin6_family = AF_INET6; #ifdef HAVE_SOCKADDR_STORAGE_SS_LEN a->sin6_len = sizeof(struct sockaddr_in6); #endif a->sin6_port = htons((uint16_t)SLPPropertyAsInteger("net.slp.port")); return 0; }
/*=========================================================================*/ int NetworkConnectToDA(const char* scopelist, int scopelistlen, struct sockaddr_in* peeraddr) /* Connects to slpd and provides a peeraddr to send to */ /* */ /* scopelist (IN) Scope that must be supported by DA. Pass in NULL */ /* for any scope */ /* */ /* scopelistlen (IN) Length of the scope list in bytes. Ignored if */ /* scopelist is NULL */ /* */ /* peeraddr (OUT) pointer to receive the connected DA's address */ /* */ /* Returns Connected socket or -1 if no DA connection can be made */ /*=========================================================================*/ { time_t curtime; int dinterval; int sock; struct timeval timeout; timeout.tv_sec = SLPPropertyAsInteger(SLPGetProperty("net.slp.DADiscoveryMaximumWait")); timeout.tv_usec = (timeout.tv_sec % 1000) * 1000; timeout.tv_sec = timeout.tv_sec / 1000; sock = KnownDAConnect(scopelist,scopelistlen,peeraddr,&timeout); if(sock < 0) { time(&curtime); dinterval = atoi(SLPGetProperty("net.slp.DAActiveDiscoveryInterval")); if(dinterval < MINIMUM_DISCOVERY_INTERVAL) { dinterval = MINIMUM_DISCOVERY_INTERVAL; } if(curtime - G_LastDADiscovery > dinterval) { KnownDADiscover(&timeout); sock = KnownDAConnect(scopelist,scopelistlen,peeraddr,&timeout); time(&G_LastDADiscovery); } } return sock; }
/** Broadcast a message. * * @param[in] ifaceinfo - A pointer to the SLPIfaceInfo structure that * contains information about the interfaces on which to send. * @param[in] msg - The buffer to be sent. * @param[out] socks - The address of storage for returning the sockets * that were used to broadcast. * * @return Zero on sucess, or a non-zero value with @a errno set on error. * * @remarks The sockets returned in @p socks may be used to receive * responses. Must be close by caller using SLPXcastSocketsClose. */ int SLPBroadcastSend(const SLPIfaceInfo * ifaceinfo, const SLPBuffer msg, SLPXcastSockets * socks) { int xferbytes; so_bool_t on = 1; for (socks->sock_count = 0; socks->sock_count < ifaceinfo->bcast_count; socks->sock_count++) { if (ifaceinfo[socks->sock_count].bcast_addr->ss_family == AF_INET) { socks->sock[socks->sock_count] = socket(ifaceinfo[socks->sock_count] .bcast_addr->ss_family, SOCK_DGRAM, 0); if (socks->sock[socks->sock_count] == SLP_INVALID_SOCKET) return -1; /* error creating socket */ SLPNetworkSetSndRcvBuf(socks->sock[socks->sock_count]); if (setsockopt(socks->sock[socks->sock_count], SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) != 0) return -1; /* Error setting socket option */ memcpy(&socks->peeraddr[socks->sock_count], &ifaceinfo->bcast_addr[socks->sock_count], sizeof(ifaceinfo->bcast_addr[socks->sock_count])); SLPNetSetAddr(&socks->peeraddr[socks->sock_count], AF_INET, (uint16_t)SLPPropertyAsInteger("net.slp.port"), 0); xferbytes = sendto(socks->sock[socks->sock_count], (char *)msg->start, (int)(msg->end - msg->start), 0, (struct sockaddr *)&socks->peeraddr[socks->sock_count], SLPNetAddrLen(&socks->peeraddr[socks->sock_count])); if (xferbytes < 0) return -1; /* Error sending to broadcast */ } else socks->sock[socks->sock_count] = 0; /* assume bcast for IPV4 only */ } return 0; }
/*=========================================================================*/ int SLPPropertyAsIntegerVector(const char* property, int* vector, int vectorsize) /*=========================================================================*/ { int i; char* slider1; char* slider2; char* temp; char* end; memset(vector,0,sizeof(int)*vectorsize); temp = xstrdup(property); if(temp == 0) { return 0; } end = temp + strlen(property); slider1 = slider2 = temp; for(i=0;i<vectorsize;i++) { while(*slider2 && *slider2 != ',') slider2++; *slider2 = 0; vector[i] = SLPPropertyAsInteger(slider1); slider2++; if(slider2 >= end) { break; } slider1 = slider2; } xfree(temp); return i; }
/*-------------------------------------------------------------------------*/ SLPBoolean ColateSLPSrvURLCallback(SLPHandle hSLP, const char* pcSrvURL, unsigned short sLifetime, SLPError errCode, void *pvCookie) /*-------------------------------------------------------------------------*/ { SLPSrvUrlColatedItem* collateditem; PSLPHandleInfo handle; handle = (PSLPHandleInfo) hSLP; handle->callbackcount ++; #ifdef ENABLE_ASYNC_API /* Do not colate for async calls */ if(handle->isAsync) { return handle->params.findsrvs.callback(hSLP, pcSrvURL, sLifetime, errCode, pvCookie); } #endif if(errCode == SLP_LAST_CALL || handle->callbackcount > SLPPropertyAsInteger(SLPGetProperty("net.slp.maxResults"))) { /* We are done so call the caller's callback for each */ /* service URL colated item and clean up the colation list */ handle->params.findsrvs.callback((SLPHandle)handle, NULL, 0, SLP_LAST_CALL, handle->params.findsrvs.cookie); goto CLEANUP; } else if(errCode != SLP_OK) { return SLP_TRUE; } /* Add the service URL to the colation list */ collateditem = (SLPSrvUrlColatedItem*) handle->collatedsrvurls.head; while(collateditem) { if(strcmp(collateditem->srvurl,pcSrvURL) == 0) { break; } collateditem = (SLPSrvUrlColatedItem*)collateditem->listitem.next; } /* create a new item if none was found */ if(collateditem == NULL) { collateditem = (SLPSrvUrlColatedItem*) xmalloc(sizeof(SLPSrvUrlColatedItem) + \ strlen(pcSrvURL) + 1); if(collateditem) { memset(collateditem,0,sizeof(SLPSrvUrlColatedItem)); collateditem->srvurl = (char*)(collateditem + 1); strcpy(collateditem->srvurl,pcSrvURL); collateditem->lifetime = sLifetime; /* Add the new item to the collated list */ SLPListLinkTail(&(handle->collatedsrvurls), (SLPListItem*)collateditem); /* Call the caller's callback */ if(handle->params.findsrvs.callback((SLPHandle)handle, pcSrvURL, sLifetime, SLP_OK, handle->params.findsrvs.cookie) == SLP_FALSE) { goto CLEANUP; } } } return SLP_TRUE; CLEANUP: /* free the collation list */ while(handle->collatedsrvurls.count) { collateditem = (SLPSrvUrlColatedItem*)SLPListUnlink(&(handle->collatedsrvurls), handle->collatedsrvurls.head); xfree(collateditem); } handle->callbackcount = 0; return SLP_FALSE; }
/*=========================================================================*/ void KnownDADiscover(struct timeval* timeout) /*=========================================================================*/ { int fd; struct stat hintstat; const char* hintfile = SLPGetProperty("net.slp.HintsFile"); /* TODO THIS FUNCTION MUST BE SYNCRONIZED !! */ /*-------------------------------------------*/ /* Check hints file to and load it if it */ /*-------------------------------------------*/ if(stat(hintfile,&hintstat) == 0) { if(hintstat.st_mtime != G_HintStat.st_mtime) { fd = open(hintfile,O_RDONLY); if(fd >= 0) { SLPDAEntryListRead(fd, &G_KnownDAListHead); close(fd); } } } /* if (hints file changed) */ /* { */ /* if(load hints file) */ /* { */ /* return; */ /* } */ /* } */ /* The logic of the following if(G_KnownDAListHead) statements is an */ /* attempt to reduce wasted time and network bandwidth due to unneeded */ /* communication with DAs and multicast */ if(G_KnownDAListHead == 0) { /*----------------------------------------------------*/ /* Check values from the net.slp.DAAddresses property */ /*----------------------------------------------------*/ KnownDADiscoveryByProperties(timeout); /*------------------------------*/ /* Check data from DHCP Options */ /*------------------------------*/ if(G_KnownDAListHead) { return; } } /*-------------*/ /* IPC to slpd */ /*-------------*/ /*-------------------*/ /* Multicast for DAs */ /*-------------------*/ if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.activeDADetection")) && SLPPropertyAsInteger(SLPGetProperty("net.slp.DAActiveDiscoveryInterval"))) { KnownDADiscoveryByMulticast(); } /*---------------------*/ /* Save the hints file */ /*---------------------*/ fd = open(hintfile, O_RDONLY | O_CREAT, S_IROTH | S_IWOTH | S_IRGRP| S_IWGRP | S_IRUSR, S_IWUSR); if(fd >= 0) { SLPDAEntryListWrite(fd, &G_KnownDAListHead); close(fd); stat(hintfile,&G_HintStat); } }
/** Collates response data to user callback for SLPFindSrv requests. * * @param[in] hSLP - The SLP handle object associated with the request. * @param[in] pcSrvURL - The service URL for this pass. * @param[in] sLifetime - The lifetime value for @p pcSrvURL. * @param[in] errorcode - The error code received on this pass. * * @return An SLP boolean value; SLP_TRUE indicates we are finished; * SLP_FALSE indicates we should continue. * * @todo Trace the logic of CollateToSLPSrvURLCallback to ensure * that it works. * * @internal */ static SLPBoolean CollateToSLPSrvURLCallback(SLPHandle hSLP, const char * pcSrvURL, unsigned short sLifetime, SLPError errorcode) { int maxResults; SLPHandleInfo * handle = hSLP; SLPSrvUrlCollatedItem * collateditem; #ifdef ENABLE_ASYNC_API /* Do not collate for async calls. */ if (handle->isAsync) return handle->params.findsrvs.callback(hSLP, pcSrvURL, sLifetime, errorcode, handle->params.findsrvs.cookie); #endif /* Configure behaviour for desired max results */ maxResults = SLPPropertyAsInteger("net.slp.maxResults"); if (maxResults == -1) maxResults = INT_MAX; if (errorcode == SLP_LAST_CALL || handle->callbackcount > maxResults) { /* We are done so call the caller's callback for each * service URL collated item and clean up the collation list. */ handle->params.findsrvs.callback(handle, 0, 0, SLP_LAST_CALL, handle->params.findsrvs.cookie); goto CLEANUP; } else if (errorcode != SLP_OK) return SLP_TRUE; /* We're adding another result - increment result count. */ handle->callbackcount++; /* Add the service URL to the colation list. */ collateditem = (SLPSrvUrlCollatedItem *)handle->collatedsrvurls.head; while (collateditem) { if (strcmp(collateditem->srvurl, pcSrvURL) == 0) break; collateditem = (SLPSrvUrlCollatedItem *)collateditem->listitem.next; } /* Create a new item if none was found. */ if (collateditem == 0) { collateditem = xmalloc(sizeof(SLPSrvUrlCollatedItem) + strlen(pcSrvURL) + 1); if (collateditem) { memset(collateditem, 0, sizeof(SLPSrvUrlCollatedItem)); collateditem->srvurl = (char *)(collateditem + 1); strcpy(collateditem->srvurl, pcSrvURL); collateditem->lifetime = sLifetime; /* Add the new item to the collated list. */ SLPListLinkTail(&handle->collatedsrvurls, (SLPListItem *)collateditem); /* Call the caller's callback. */ if (handle->params.findsrvs.callback(handle, pcSrvURL, sLifetime, SLP_OK, handle->params.findsrvs.cookie) == SLP_FALSE) goto CLEANUP; } } return SLP_TRUE; CLEANUP: /* Free the collation list. */ while (handle->collatedsrvurls.count) { collateditem = (SLPSrvUrlCollatedItem *)SLPListUnlink( &handle->collatedsrvurls, handle->collatedsrvurls.head); xfree(collateditem); } handle->callbackcount = 0; return SLP_FALSE; }
/** Collates response data to user callback for SLPFindSrvType requests. * * @param[in] hSLP - The SLP handle object associated with the request. * @param[in] pcSrvTypes - The service type for this pass. * @param[in] errorcode - The error code received on this pass. * * @return An SLP boolean value; SLP_TRUE indicates we are finished; * SLP_FALSE indicates we should continue. * * @todo Trace the logic of CollateToSLPSrvTypeCallback to ensure that * it works. * * @internal */ static SLPBoolean CollateToSLPSrvTypeCallback(SLPHandle hSLP, const char * pcSrvTypes, SLPError errorcode) { int maxResults; char * srvtypes; size_t srvtypeslen; SLPHandleInfo * handle = hSLP; handle->callbackcount++; #ifdef ENABLE_ASYNC_API /* Do not collate for async calls. */ if (handle->isAsync) return handle->params.findsrvtypes.callback(hSLP, pcSrvTypes, errorcode, handle->params.findsrvtypes.cookie); #endif /* Configure behaviour for desired max results. */ maxResults = SLPPropertyAsInteger("net.slp.maxResults"); if (maxResults == -1) maxResults = INT_MAX; if (errorcode == SLP_LAST_CALL || handle->callbackcount > maxResults) { /* We're done. Send back the collated srvtype string. */ if (handle->collatedsrvtypes) if (handle->params.findsrvtypes.callback(handle, handle->collatedsrvtypes, SLP_OK, handle->params.findsrvtypes.cookie) == SLP_TRUE) handle->params.findsrvtypes.callback(handle, 0, SLP_LAST_CALL, handle->params.findsrvtypes.cookie); /* Free the collatedsrvtype string. */ if (handle->collatedsrvtypes) { xfree(handle->collatedsrvtypes); handle->collatedsrvtypes = 0; } handle->callbackcount = 0; return SLP_FALSE; } else if (errorcode != SLP_OK) return SLP_TRUE; /* Add the service types to the colation. */ srvtypeslen = strlen(pcSrvTypes) + 1; /* +1 - terminator */ if (handle->collatedsrvtypes) srvtypeslen += strlen(handle->collatedsrvtypes) + 1; /* +1 - comma */ srvtypes = xmalloc(srvtypeslen); if (srvtypes) { if (handle->collatedsrvtypes) { if (SLPUnionStringList(strlen(handle->collatedsrvtypes), handle->collatedsrvtypes, strlen(pcSrvTypes), pcSrvTypes, &srvtypeslen, srvtypes) != (int)srvtypeslen) { xfree(handle->collatedsrvtypes); handle->collatedsrvtypes = srvtypes; } else { #ifndef COLLATION_CHANGES xfree(handle->collatedsrvtypes); handle->collatedsrvtypes = srvtypes; handle->collatedsrvtypes[srvtypeslen] = 0; #else xfree(srvtypes); #endif } } else { strcpy(srvtypes, pcSrvTypes); handle->collatedsrvtypes = srvtypes; } } return SLP_TRUE; }
/** 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()*/ }
/*=========================================================================*/ 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; }
/*----------------------------------------------------------------------------*/ SLPBoolean ColateSrvTypeCallback(SLPHandle hSLP, const char* pcSrvTypes, SLPError errCode, void *pvCookie) /*----------------------------------------------------------------------------*/ { PSLPHandleInfo handle; SLPBoolean result; int srvtypeslen; char* srvtypes; handle = (PSLPHandleInfo) hSLP; handle->callbackcount ++; #ifdef ENABLE_ASYNC_API /* Do not colate for async calls */ if(handle->isAsync) { return handle->params.findsrvtypes.callback(hSLP, pcSrvTypes, errCode, pvCookie); } #endif if(errCode == SLP_LAST_CALL || handle->callbackcount > SLPPropertyAsInteger(SLPGetProperty("net.slp.maxResults"))) { /* We're done. Send back the colated srvtype string */ result = SLP_TRUE; if(handle->collatedsrvtypes) { result = handle->params.findsrvtypes.callback((SLPHandle)handle, handle->collatedsrvtypes, SLP_OK, handle->params.findsrvtypes.cookie); if(result == SLP_TRUE) { handle->params.findsrvtypes.callback((SLPHandle)handle, NULL, SLP_LAST_CALL, handle->params.findsrvtypes.cookie); } } /* Free the colatedsrvtype string */ if(handle->collatedsrvtypes) { xfree(handle->collatedsrvtypes); handle->collatedsrvtypes = NULL; } handle->callbackcount = 0; return SLP_FALSE; } else if(errCode != SLP_OK) { return SLP_TRUE; } /* Add the service types to the colation */ srvtypeslen = strlen(pcSrvTypes) + 1; if(handle->collatedsrvtypes) { srvtypeslen += strlen(handle->collatedsrvtypes); } srvtypes = xmalloc(srvtypeslen); if(srvtypes) { if(handle->collatedsrvtypes) { if(SLPUnionStringList(strlen(handle->collatedsrvtypes), handle->collatedsrvtypes, strlen(pcSrvTypes), pcSrvTypes, &srvtypeslen, srvtypes) != srvtypeslen) { xfree(handle->collatedsrvtypes); handle->collatedsrvtypes = srvtypes; } else { xfree(srvtypes); } } else { strcpy(srvtypes,pcSrvTypes); handle->collatedsrvtypes = srvtypes; } } return SLP_TRUE; }
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; }
/*=========================================================================*/ int KnownDAConnect(PSLPHandleInfo handle, int scopelistlen, const char* scopelist, struct sockaddr_in* peeraddr) /* Get a connected socket to a DA that supports the specified scope */ /* */ /* scopelistlen (IN) stringlen of the scopelist */ /* */ /* scopelist (IN) DA must support this scope */ /* */ /* peeraddr (OUT) the peer that was connected to */ /* */ /* */ /* returns: valid socket file descriptor or -1 if no DA is found */ /*=========================================================================*/ { struct timeval timeout; int sock = -1; int spistrlen = 0; char* spistr = 0; #ifdef ENABLE_SLPv2_SECURITY if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled"))) { SLPSpiGetDefaultSPI(handle->hspi, SLPSPI_KEY_TYPE_PUBLIC, &spistrlen, &spistr); } #endif /* Set up connect timeout */ timeout.tv_sec = SLPPropertyAsInteger(SLPGetProperty("net.slp.DADiscoveryMaximumWait")); timeout.tv_usec = (timeout.tv_sec % 1000) * 1000; timeout.tv_sec = timeout.tv_sec / 1000; while(1) { memset(peeraddr,0,sizeof(peeraddr)); if(KnownDAFromCache(scopelistlen, scopelist, spistrlen, spistr, &(peeraddr->sin_addr)) == 0) { break; } peeraddr->sin_family = PF_INET; peeraddr->sin_port = htons(SLP_RESERVED_PORT); sock = SLPNetworkConnectStream(peeraddr,&timeout); if(sock >= 0) { break; } KnownDABadDA(&(peeraddr->sin_addr)); } #ifdef ENABLE_SLPv2_SECURITY if(spistr) xfree(spistr); #endif return sock; }
/*=========================================================================*/ int SLPDPropertyInit(const char* conffile) /*=========================================================================*/ { char* myname = 0; char* myinterfaces = 0; char* myurl = 0; SLPPropertyReadFile(conffile); memset(&G_SlpdProperty,0,sizeof(G_SlpdProperty)); /*-------------------------------------------------------------*/ /* Set the properties without hard defaults */ /*-------------------------------------------------------------*/ G_SlpdProperty.isDA = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isDA")); G_SlpdProperty.activeDADetection = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.activeDADetection")); if(G_SlpdProperty.activeDADetection) { G_SlpdProperty.DAActiveDiscoveryInterval = atoi(SLPPropertyGet("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(SLPPropertyGet("net.slp.passiveDADetection")); G_SlpdProperty.isBroadcastOnly = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isBroadcastOnly")); G_SlpdProperty.multicastTTL = atoi(SLPPropertyGet("net.slp.multicastTTL")); G_SlpdProperty.multicastMaximumWait = atoi(SLPPropertyGet("net.slp.multicastMaximumWait")); G_SlpdProperty.unicastMaximumWait = atoi(SLPPropertyGet("net.slp.unicastMaximumWait")); G_SlpdProperty.randomWaitBound = atoi(SLPPropertyGet("net.slp.randomWaitBound")); G_SlpdProperty.maxResults = atoi(SLPPropertyGet("net.slp.maxResults")); G_SlpdProperty.traceMsg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceMsg")); G_SlpdProperty.traceReg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceReg")); G_SlpdProperty.traceDrop = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceDrop")); G_SlpdProperty.traceDATraffic = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceDATraffic")); G_SlpdProperty.DAAddresses = SLPPropertyGet("net.slp.DAAddresses"); G_SlpdProperty.DAAddressesLen = strlen(G_SlpdProperty.DAAddresses); /* TODO make sure that we are using scopes correctly. What about DHCP, etc*/ G_SlpdProperty.useScopes = SLPPropertyGet("net.slp.useScopes"); G_SlpdProperty.useScopesLen = strlen(G_SlpdProperty.useScopes); G_SlpdProperty.locale = SLPPropertyGet("net.slp.locale"); G_SlpdProperty.localeLen = strlen(G_SlpdProperty.locale); G_SlpdProperty.securityEnabled = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.securityEnabled")); G_SlpdProperty.checkSourceAddr = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.checkSourceAddr")); G_SlpdProperty.DAHeartBeat = SLPPropertyAsInteger(SLPPropertyGet("net.slp.DAHeartBeat")); /*-------------------------------------*/ /* Set the net.slp.interfaces property */ /*-------------------------------------*/ if(SLPIfaceGetInfo(SLPPropertyGet("net.slp.interfaces"),&G_SlpdProperty.ifaceInfo) == 0) { if(SLPPropertyGet("net.slp.interfaces")) { if(SLPIfaceSockaddrsToString(G_SlpdProperty.ifaceInfo.iface_addr, G_SlpdProperty.ifaceInfo.iface_count, &myinterfaces) == 0) { if(myinterfaces) { SLPPropertySet("net.slp.interfaces", myinterfaces); xfree(myinterfaces); } } } G_SlpdProperty.interfaces = SLPPropertyGet("net.slp.interfaces"); } G_SlpdProperty.interfacesLen = strlen(G_SlpdProperty.interfaces); /*---------------------------------------------------------*/ /* Set the value used internally as the url for this agent */ /*---------------------------------------------------------*/ /* 27 is the size of "service:directory-agent://(NULL)" */ if(SLPNetGetThisHostname(&myname,1) == 0) { myurl = (char*)xmalloc(27 + strlen(myname)); if(G_SlpdProperty.isDA) { strcpy(myurl,SLP_DA_SERVICE_TYPE); } else { strcpy(myurl,SLP_SA_SERVICE_TYPE); } strcat(myurl,"://"); strcat(myurl,myname); SLPPropertySet("net.slp.agentUrl",myurl); G_SlpdProperty.myUrl = SLPPropertyGet("net.slp.agentUrl"); G_SlpdProperty.myUrlLen = strlen(G_SlpdProperty.myUrl); xfree(myurl); xfree(myname); } /*----------------------------------*/ /* Set other values used internally */ /*----------------------------------*/ G_SlpdProperty.DATimestamp = 1; /* DATimestamp must start at 1 */ 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()*/ return 0; }
/** * Initializes the MTU configuration property value. If the user specified * value is more than the value that is allowed by the kernel, MTU value is * adjusted to the actual value set by the kernel. If the default values of * SO_SNDBUF and SO_RCVBUF are greater than the global MTU value, SO_SNDBUF * and SO_RCVBUF are not set explicitly. * * @internal */ static void InitializeMTUPropertyValue() { #ifndef _WIN32 int mtuChanged = 0; int family; sockfd_t sock; int value = 0; socklen_t valSize = sizeof(int); #endif s_GlobalPropertyInternalRcvBufSize = s_GlobalPropertyInternalSndBufSize = 0; s_GlobalPropertyMTU = SLPPropertyAsInteger("net.slp.MTU"); #ifndef _WIN32 family = SLPPropertyAsBoolean("net.slp.useIPv4") ? AF_INET : AF_INET6; if ((sock = socket(family, SOCK_DGRAM, 0)) != SLP_INVALID_SOCKET) { if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &value, &valSize) != -1) { if (value < s_GlobalPropertyMTU) { setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &s_GlobalPropertyMTU, sizeof(int)); s_GlobalPropertyInternalRcvBufSize = s_GlobalPropertyMTU; } } if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &value, &valSize) != -1) { if (value < s_GlobalPropertyMTU) { setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &s_GlobalPropertyMTU, sizeof(int)); s_GlobalPropertyInternalSndBufSize = s_GlobalPropertyMTU; } } // If the actual value set by the kernel is less than the MTU value, // adjust here. if (s_GlobalPropertyInternalRcvBufSize && getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &value, &valSize) != -1) { if (value < s_GlobalPropertyMTU) { s_GlobalPropertyInternalRcvBufSize = value; } } if (s_GlobalPropertyInternalSndBufSize && getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &value, &valSize) != -1) { if (value < s_GlobalPropertyMTU) { s_GlobalPropertyInternalSndBufSize = value; } } close(sock); // If both values are set adjust the s_GlobalPropertyMTU value. if (s_GlobalPropertyInternalRcvBufSize && s_GlobalPropertyInternalSndBufSize) { s_GlobalPropertyMTU = s_GlobalPropertyInternalRcvBufSize; if (s_GlobalPropertyMTU < s_GlobalPropertyInternalSndBufSize) { s_GlobalPropertyMTU = s_GlobalPropertyInternalSndBufSize; } mtuChanged = 1; } } if (mtuChanged) { char tmp[13]; snprintf(tmp, 13, "%d", s_GlobalPropertyMTU); SLPPropertySet("net.slp.MTU", tmp, 0); } #endif }