/** 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()*/ }
/** Get the network interface addresses for this host. * * Returns either a complete list or a subset of the list of network interface * addresses for this host. If the user specifies a list, then network interfaces * * @param[in] useifaces - Pointer to comma delimited string of interface * IPv4 addresses to get interface information for. Pass 0 or the empty * string to get all interfaces (except the loopback interface). * @param[out] ifaceinfo - The address of a buffer in which to return * information about the requested interfaces. * @param[in] family - A hint indicating the address family to get info * for - can be AF_INET, AF_INET6, or AF_UNSPEC for both. * * @return Zero on success; A non-zero value (with errno set) on error. * * @remarks Does NOT return the loopback interface. */ int SLPIfaceGetInfo(const char * useifaces, SLPIfaceInfo * ifaceinfo, int family) { size_t useifaceslen = useifaces? strlen(useifaces): 0; int sts = 0; ifaceinfo->iface_count = 0; ifaceinfo->bcast_count = 0; if (!useifaceslen) { /* no specified list - get all available interface addresses */ if (SLPIfaceGetDefaultInfo(ifaceinfo, family) != 0) return -1; } else { /* list specified: parse it and use it */ /* only allow addresses in configured address set */ char * p = SLPPropertyXDup("net.slp.interfaces"); /* If there are no configured addresses, use the passed in addresses*/ if(p && (0 == strlen(p))) { xfree(p); p = xstrdup(useifaces); } if (p) { char * ep = p + strlen(p); char * slider1 = p; char * slider2 = p; while (slider1 < ep) { while (*slider2 != 0 && *slider2 != ',') slider2++; *slider2 = 0; if (SLPIfaceContainsAddr(useifaceslen, useifaces, strlen(slider1), slider1)) { sockfd_t fd; struct sockaddr_in v4addr; struct sockaddr_in6 v6addr; /* check if an ipv4 address was given */ if (inet_pton(AF_INET, slider1, &v4addr.sin_addr) == 1) { if (SLPNetIsIPV4() && ((family == AF_INET) || (family == AF_UNSPEC))) { fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd != SLP_INVALID_SOCKET) { v4addr.sin_family = AF_INET; v4addr.sin_port = 0; memset(v4addr.sin_zero, 0, sizeof(v4addr.sin_zero)); if ((sts = bind(fd, (struct sockaddr *)&v4addr, sizeof(v4addr))) == 0) memcpy(&ifaceinfo->iface_addr[ifaceinfo->iface_count++], &v4addr, sizeof(v4addr)); closesocket(fd); } } } else if (inet_pton(AF_INET6, slider1, &v6addr.sin6_addr) == 1) { if (SLPNetIsIPV6() && ((family == AF_INET6) || (family == AF_UNSPEC))) { v6addr.sin6_family = AF_INET6; v6addr.sin6_port = 0; v6addr.sin6_flowinfo = 0; if((sts = GetV6Scope(&v6addr)) == 0) memcpy(&ifaceinfo->iface_addr[ifaceinfo->iface_count++], &v6addr, sizeof(v6addr)); } } else sts = (errno = EINVAL), -1; /* not v4, not v6 */ } slider1 = ++slider2; } } xfree(p); } /* now stuff in a v4 broadcast address */ if (SLPNetIsIPV4() && ((family == AF_INET) || (family == AF_UNSPEC))) { struct sockaddr_storage sa; char * str = SLPPropertyXDup("net.slp.broadcastAddr"); if (!str || !*str) { unsigned long addr = INADDR_BROADCAST; SLPNetSetAddr(&sa, AF_INET, 0, &addr); memcpy(&ifaceinfo->bcast_addr[ifaceinfo->bcast_count++], &sa, sizeof(sa)); } else { unsigned long addr; if (inet_pton(AF_INET, str, &addr) == 1) { SLPNetSetAddr(&sa, AF_INET, 0, &addr); memcpy(&ifaceinfo->bcast_addr[ifaceinfo->bcast_count++], &sa, sizeof(sa)); } } xfree(str); } return sts; }