/*=========================================================================*/ 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 NetworkConnectToMulticast(struct sockaddr_in* peeraddr) /*=========================================================================*/ { int sock = -1; if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.isBroadcastOnly")) == 0) { sock = SLPNetworkConnectToMulticast(peeraddr, atoi(SLPGetProperty("net.slp.multicastTTL"))); } if (sock < 0) { sock = SLPNetworkConnectToBroadcast(peeraddr); } return sock; }
/** Formats and sends an SLPFindSrvs wire buffer request. * * @param handle - The OpenSLP session handle, containing request * parameters. See docs for SLPFindSrvs. * * @return Zero on success, or an SLP API error code. * * @internal */ static SLPError ProcessSrvRqst(SLPHandleInfo * handle) { uint8_t * buf; uint8_t * curpos; SLPError serr; size_t spistrlen = 0; char * spistr = 0; struct sockaddr_storage peeraddr; struct sockaddr_in* destaddrs = 0; sockfd_t sock = SLP_INVALID_SOCKET; /* Is this a special attempt to locate DAs? */ if (strncasecmp(handle->params.findsrvs.srvtype, SLP_DA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen) == 0) { KnownDAProcessSrvRqst(handle); return 0; } #ifdef ENABLE_SLPv2_SECURITY if (SLPPropertyAsBoolean("net.slp.securityEnabled")) SLPSpiGetDefaultSPI(handle->hspi, SLPSPI_KEY_TYPE_PUBLIC, &spistrlen, &spistr); #endif /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <service-type> | <service-type> String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <scope-list> | <scope-list> String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of predicate string | Service Request <predicate> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <SLP SPI> string | <SLP SPI> String \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ buf = curpos = xmalloc( + 2 + handle->params.findsrvs.srvtypelen + 2 + handle->params.findsrvs.scopelistlen + 2 + handle->params.findsrvs.predicatelen + 2 + spistrlen); if (buf == 0) { xfree(spistr); return SLP_MEMORY_ALLOC_FAILED; } /* <service-type> */ PutL16String(&curpos, handle->params.findsrvs.srvtype, handle->params.findsrvs.srvtypelen); /* <scope-list> */ PutL16String(&curpos, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen); /* predicate string */ PutL16String(&curpos, handle->params.findsrvs.predicate, handle->params.findsrvs.predicatelen); /* <SLP SPI> */ PutL16String(&curpos, (char *)spistr, spistrlen); /* Call the RqstRply engine. */ do { #ifndef UNICAST_NOT_SUPPORTED if (handle->dounicast == 1) { serr = NetworkUcastRqstRply(handle, buf, SLP_FUNCT_SRVRQST, curpos - buf, ProcessSrvRplyCallback, handle, false); break; } if (SLPNetIsIPV4()) { if (KnownDASpanningListFromCache(handle, (int)handle->params.findsrvs.scopelistlen, handle->params.findsrvs.scopelist, &destaddrs) > 0) { serr = NetworkMultiUcastRqstRply(destaddrs, handle->langtag, (char*)buf, SLP_FUNCT_SRVRQST, curpos - buf, ProcessSrvRplyCallback, handle, false); xfree(destaddrs); break; } } #endif if (strncasecmp(handle->params.findsrvs.srvtype, SLP_SA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen) != 0) sock = NetworkConnectToDA(handle, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen, &peeraddr); if (sock == SLP_INVALID_SOCKET) { /* Use multicast as a last resort. */ serr = NetworkMcastRqstRply(handle, buf, SLP_FUNCT_SRVRQST, curpos - buf, ProcessSrvRplyCallback, 0, false); break; } serr = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_SRVRQST, curpos - buf, ProcessSrvRplyCallback, handle, false); if (serr) NetworkDisconnectDA(handle); } while (serr == SLP_NETWORK_ERROR); xfree(buf); xfree(spistr); return serr; }
/** SLPFindSrvs callback routine for NetworkRqstRply. * * @param[in] errorcode - The network operation error code. * @param[in] peeraddr - The network address of the responder. * @param[in] replybuf - The response buffer from the network request. * @param[in] cookie - Callback context data from ProcessSrvReg. * * @return SLP_FALSE (to stop any iterative callbacks). * * @internal */ static SLPBoolean ProcessSrvRplyCallback(SLPError errorcode, void * peeraddr, SLPBuffer replybuf, void * cookie) { SLPMessage * replymsg; SLPBoolean result = SLP_TRUE; SLPHandleInfo * handle = (SLPHandleInfo *)cookie; #ifdef ENABLE_SLPv2_SECURITY SLPBoolean securityEnabled = SLPPropertyAsBoolean("net.slp.securityEnabled"); #endif /* Check the errorcode and bail if it is set. */ if (errorcode != SLP_OK) return CollateToSLPSrvURLCallback(handle, 0, 0, errorcode); /* parse the replybuf */ replymsg = SLPMessageAlloc(); if (replymsg) { if (!SLPMessageParseBuffer(peeraddr, 0, replybuf, replymsg)) { if (replymsg->header.functionid == SLP_FUNCT_SRVRPLY && replymsg->body.srvrply.errorcode == 0) { int i; SLPUrlEntry * urlentry = replymsg->body.srvrply.urlarray; for (i = 0; i < replymsg->body.srvrply.urlcount; i++) { #ifdef ENABLE_SLPv2_SECURITY /* Validate the service authblocks. */ if (securityEnabled && SLPAuthVerifyUrl(handle->hspi, 1, &urlentry[i])) continue; /* Authentication failed, skip this URLEntry. */ #endif result = CollateToSLPSrvURLCallback(handle, urlentry[i].url, (unsigned short)urlentry[i].lifetime, SLP_OK); if (result == SLP_FALSE) break; } } else if (replymsg->header.functionid == SLP_FUNCT_DAADVERT && replymsg->body.daadvert.errorcode == 0) { #ifdef ENABLE_SLPv2_SECURITY if (securityEnabled && SLPAuthVerifyDAAdvert(handle->hspi, 1, &replymsg->body.daadvert)) { /* Verification failed. Ignore message. */ SLPMessageFree(replymsg); return SLP_TRUE; } #endif result = CollateToSLPSrvURLCallback(handle, replymsg->body.daadvert.url, SLP_LIFETIME_MAXIMUM, SLP_OK); } else if (replymsg->header.functionid == SLP_FUNCT_SAADVERT) { #ifdef ENABLE_SLPv2_SECURITY if (securityEnabled && SLPAuthVerifySAAdvert(handle->hspi, 1, &replymsg->body.saadvert)) { /* Verification failed. Ignore message. */ SLPMessageFree(replymsg); return SLP_TRUE; } #endif result = CollateToSLPSrvURLCallback(handle, replymsg->body.saadvert.url, SLP_LIFETIME_MAXIMUM, SLP_OK); } } SLPMessageFree(replymsg); } return result; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvReg(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { int sock; struct sockaddr_in peeraddr; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; #ifdef ENABLE_SECURITY int urlauthlen = 0; unsigned char* urlauth = 0; int attrauthlen = 0; unsigned char* attrauth = 0; if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled"))) { result = SLPAuthSignUrl(handle->hspi, 0, 0, handle->params.reg.urllen, handle->params.reg.url, &urlauthlen, &urlauth); if(result == 0) { result = SLPAuthSignString(handle->hspi, 0, 0, handle->params.reg.attrlistlen, handle->params.reg.attrlist, &attrauthlen, &attrauth); } bufsize += urlauthlen; bufsize += attrauthlen; } #endif /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVREG */ /*-------------------------------------------------------------------*/ bufsize += handle->params.reg.urllen + 6; /* 1 byte for reserved */ /* 2 bytes for lifetime */ /* 2 bytes for urllen */ /* 1 byte for authcount */ bufsize += handle->params.reg.srvtypelen + 2; /* 2 bytes for len field */ bufsize += handle->params.reg.scopelistlen + 2; /* 2 bytes for len field */ bufsize += handle->params.reg.attrlistlen + 2; /* 2 bytes for len field */ bufsize += 1; /* 1 byte for authcount */ buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVREG */ /*------------------------------------------------------------*/ /* url-entry reserved */ *curpos= 0; curpos = curpos + 1; /* url-entry lifetime */ ToUINT16(curpos,handle->params.reg.lifetime); curpos = curpos + 2; /* url-entry urllen */ ToUINT16(curpos,handle->params.reg.urllen); curpos = curpos + 2; /* url-entry url */ memcpy(curpos, handle->params.reg.url, handle->params.reg.urllen); curpos = curpos + handle->params.reg.urllen; /* url-entry authblock */ #ifdef ENABLE_SECURITY if(urlauth) { /* authcount */ *curpos = 1; curpos = curpos + 1; /* authblock */ memcpy(curpos,urlauth,urlauthlen); curpos = curpos + urlauthlen; } else #endif { /* authcount */ *curpos = 0; curpos = curpos + 1; } /* service type */ ToUINT16(curpos,handle->params.reg.srvtypelen); curpos = curpos + 2; memcpy(curpos, handle->params.reg.srvtype, handle->params.reg.srvtypelen); curpos = curpos + handle->params.reg.srvtypelen; /* scope list */ ToUINT16(curpos,handle->params.reg.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.reg.scopelist, handle->params.reg.scopelistlen); curpos = curpos + handle->params.reg.scopelistlen; /* attr list */ ToUINT16(curpos,handle->params.reg.attrlistlen); curpos = curpos + 2; memcpy(curpos, handle->params.reg.attrlist, handle->params.reg.attrlistlen); curpos = curpos + handle->params.reg.attrlistlen; /* attribute auth block */ #ifdef ENABLE_SECURITY if(attrauth) { /* authcount */ *curpos = 1; curpos = curpos + 1; /* authblock */ memcpy(curpos,attrauth,attrauthlen); curpos = curpos + attrauthlen; } else #endif { /* authcount */ *curpos = 0; curpos = curpos + 1; } /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ do { sock = NetworkConnectToSA(handle, handle->params.reg.scopelist, handle->params.reg.scopelistlen, &peeraddr); if(sock == -1) { result = SLP_NETWORK_INIT_FAILED; break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVREG, bufsize, CallbackSrvReg, handle); if(result) { NetworkDisconnectSA(handle); } }while(result == SLP_NETWORK_ERROR); FINISHED: if(buf) xfree(buf); #ifdef ENABLE_SECURITY if(urlauth) xfree(urlauth); if(attrauth) xfree(attrauth); #endif return result; }
/*=========================================================================*/ void SLPDPropertyInit(const char* conffile) /*=========================================================================*/ { struct in_addr ifaddr; struct utsname myname; struct hostent* myhostent; int i; SLPPropertyReadFile(conffile); memset(&G_SlpdProperty,0,sizeof(G_SlpdProperty)); /*-------------------------------------------------------------*/ /* Set the properties with out hard defaults */ /*-------------------------------------------------------------*/ G_SlpdProperty.isBroadcastOnly = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isBroadcastOnly")); G_SlpdProperty.passiveDADetection = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.passiveDADetection")); G_SlpdProperty.activeDADetection = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.activeDADetection")); G_SlpdProperty.activeDiscoveryAttempts = G_SlpdProperty.activeDADetection * 3; 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.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); G_SlpdProperty.useScopes = SLPPropertyGet("net.slp.useScopes"); G_SlpdProperty.useScopesLen = strlen(G_SlpdProperty.useScopes); G_SlpdProperty.isDA = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isDA")); G_SlpdProperty.locale = SLPPropertyGet("net.slp.locale"); G_SlpdProperty.localeLen = strlen(G_SlpdProperty.locale); /*-------------------------------------*/ /* Set the net.slp.interfaces property */ /*-------------------------------------*/ G_SlpdProperty.interfaces = SLPPropertyGet("net.slp.interfaces"); if(*G_SlpdProperty.interfaces == 0) { /* put in all interfaces if none specified */ if(uname(&myname) >= 0) { myhostent = gethostbyname(myname.nodename); if(myhostent != 0) { if(myhostent->h_addrtype == AF_INET) { /* count the interfaces */ for(i=0; myhostent->h_addr_list[i];i++); /* allocate memory 16 bytes per interface*/ G_SlpdProperty.interfaces = (char*)malloc((i * 16) + 1); if(G_SlpdProperty.interfaces == 0) { SLPFatal("slpd is out of memory!\n"); } *(char*)G_SlpdProperty.interfaces = 0; /* null terminate */ for(i=0; myhostent->h_addr_list[i];i++) { memcpy(&ifaddr,myhostent->h_addr_list[i],sizeof(ifaddr)); if(i) { strcat((char*)G_SlpdProperty.interfaces,","); } strcat((char*)G_SlpdProperty.interfaces,inet_ntoa(ifaddr)); } } } } } if(G_SlpdProperty.interfaces) { G_SlpdProperty.interfacesLen = strlen(G_SlpdProperty.interfaces); } /*---------------------------------------------------------*/ /* Set the value used internally as the url for this agent */ /*---------------------------------------------------------*/ G_SlpdProperty.myUrl = (const char*)malloc(25 + strlen(myname.nodename)); if(G_SlpdProperty.myUrl == 0) { SLPFatal("slpd is out of memory!\n"); } if(G_SlpdProperty.isDA) { strcpy((char*)G_SlpdProperty.myUrl,"service:directory-agent://"); } else { strcpy((char*)G_SlpdProperty.myUrl,"service:service-agent://"); } if(uname(&myname) >= 0) { /* 25 is the length of "service:directory-agent://" */ strcat((char*)G_SlpdProperty.myUrl,myname.nodename); } G_SlpdProperty.myUrlLen = strlen(G_SlpdProperty.myUrl); }
/** Formats and sends an SLPReg wire buffer request. * * @param handle - The OpenSLP session handle, containing request * parameters. See docs for SLPReg. * * @return Zero on success, or an SLP API error code. * * @internal */ static SLPError ProcessSrvReg(SLPHandleInfo * handle) { sockfd_t sock; uint8_t * buf; uint8_t * curpos; SLPError serr; size_t extoffset = 0; int urlauthlen = 0; uint8_t * urlauth = 0; int attrauthlen = 0; uint8_t * attrauth = 0; SLPBoolean watchRegPID; struct sockaddr_storage saaddr; #ifdef ENABLE_SLPv2_SECURITY if (SLPPropertyAsBoolean("net.slp.securityEnabled")) { int err = SLPAuthSignUrl(handle->hspi, 0, 0, handle->params.reg.urllen, handle->params.reg.url, &urlauthlen, &urlauth); if (err == 0) err = SLPAuthSignString(handle->hspi, 0, 0, handle->params.reg.attrlistlen, handle->params.reg.attrlist, &attrauthlen, &attrauth); if (err != 0) return SLP_AUTHENTICATION_ABSENT; } #endif /* Should we send the "Watch Registration PID" extension? */ watchRegPID = SLPPropertyAsBoolean("net.slp.watchRegistrationPID"); /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | <URL-Entry> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of service type string | <service-type> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <scope-list> | <scope-list> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of attr-list string | <attr-list> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |# of AttrAuths |(if present) Attribute Authentication Blocks...\ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | WATCH-PID extension ID | next extension offset \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | nxo (cont) | process identifier to be monitored \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | PID (cont) | +-+-+-+-+-+-+-+-+ */ buf = curpos = xmalloc( + SizeofURLEntry(handle->params.reg.urllen, urlauthlen) + 2 + handle->params.reg.srvtypelen + 2 + handle->params.reg.scopelistlen + 2 + handle->params.reg.attrlistlen + 1 + attrauthlen + (watchRegPID? (2 + 3 + 4): 0)); if (buf == 0) { xfree(urlauth); xfree(attrauth); return SLP_MEMORY_ALLOC_FAILED; } /* URL entry */ PutURLEntry(&curpos, handle->params.reg.lifetime, handle->params.reg.url, handle->params.reg.urllen, urlauth, urlauthlen); /* <service-type> */ PutL16String(&curpos, handle->params.reg.srvtype, handle->params.reg.srvtypelen); /* <scope-list> */ PutL16String(&curpos, handle->params.reg.scopelist, handle->params.reg.scopelistlen); /* <attr-list> */ PutL16String(&curpos, handle->params.reg.attrlist, handle->params.reg.attrlistlen); /** @todo Handle multiple attribute authentication blocks. */ /* Attribute Authentication Blocks */ *curpos++ = attrauth? 1: 0; memcpy(curpos, attrauth, attrauthlen); curpos += attrauthlen; /* SLP_EXTENSION_ID_REG_PID */ if (watchRegPID) { extoffset = curpos - buf; /** @todo In some future code base, this should be changed to use the * non-deprecated official version, SLP_EXTENSION_ID_REG_PID. For now * we need to use the EXPerimental version in order to interoperate * properly with OpenSLP 1.x SA's. */ PutUINT16(&curpos, SLP_EXTENSION_ID_REG_PID_EXP); PutUINT24(&curpos, 0); PutUINT32(&curpos, SLPPidGet()); } /* Call the Request-Reply engine. */ sock = NetworkConnectToSA(handle, handle->params.reg.scopelist, handle->params.reg.scopelistlen, &saaddr); if (sock != SLP_INVALID_SOCKET) { serr = NetworkRqstRply(sock, &saaddr, handle->langtag, extoffset, buf, SLP_FUNCT_SRVREG, curpos - buf, CallbackSrvReg, handle); if (serr) NetworkDisconnectSA(handle); } else serr = SLP_NETWORK_INIT_FAILED; xfree(buf); xfree(urlauth); xfree(attrauth); return serr; }
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; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvRqst(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { struct sockaddr_in peeraddr; int sock = -1; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; #ifdef ENABLE_SLPv2_SECURITY int spistrlen = 0; char* spistr = 0; #endif /*------------------------------------------*/ /* Is this a special attempt to locate DAs? */ /*------------------------------------------*/ if(strncasecmp(handle->params.findsrvs.srvtype, SLP_DA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen) == 0) { KnownDAProcessSrvRqst(handle); goto FINISHED; } #ifdef ENABLE_SLPv2_SECURITY if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled"))) { SLPSpiGetDefaultSPI(handle->hspi, SLPSPI_KEY_TYPE_PUBLIC, &spistrlen, &spistr); } #endif /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVRQST */ /*-------------------------------------------------------------------*/ bufsize = handle->params.findsrvs.srvtypelen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvs.scopelistlen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvs.predicatelen + 2; /* 2 bytes for len field */ bufsize += 2; /* 2 bytes for spistr len*/ #ifdef ENABLE_SLPv2_SECURITY bufsize += spistrlen; #endif buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVRQST */ /*------------------------------------------------------------*/ /* service type */ ToUINT16(curpos,handle->params.findsrvs.srvtypelen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.srvtype, handle->params.findsrvs.srvtypelen); curpos = curpos + handle->params.findsrvs.srvtypelen; /* scope list */ ToUINT16(curpos,handle->params.findsrvs.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen); curpos = curpos + handle->params.findsrvs.scopelistlen; /* predicate */ ToUINT16(curpos,handle->params.findsrvs.predicatelen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.predicate, handle->params.findsrvs.predicatelen); curpos = curpos + handle->params.findsrvs.predicatelen; #ifdef ENABLE_SLPv2_SECURITY ToUINT16(curpos,spistrlen); curpos = curpos + 2; memcpy(curpos,spistr,spistrlen); curpos = curpos + spistrlen; #else ToUINT16(curpos,0); #endif /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ do { #ifndef UNICAST_NOT_SUPPORTED if ( handle->dounicast == 1 ) { void *cookie = (PSLPHandleInfo) handle; result = NetworkUcastRqstRply(handle, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, cookie); break; } else #endif if(strncasecmp(handle->params.findsrvs.srvtype, SLP_SA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen)) { sock = NetworkConnectToDA(handle, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen, &peeraddr); } if(sock == -1) { /* use multicast as a last resort */ #ifndef MI_NOT_SUPPORTED result = NetworkMcastRqstRply(handle, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, NULL); #else result = NetworkMcastRqstRply(handle->langtag, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, handle); #endif /* MI_NOT_SUPPORTED */ break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, handle); if(result) { NetworkDisconnectDA(handle); } }while(result == SLP_NETWORK_ERROR); FINISHED: if(buf) xfree(buf); #ifdef ENABLE_SLPv2_SECURITY if(spistr) xfree(spistr); #endif return result; }
/*=========================================================================*/ 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; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvDeReg(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { int sock; struct sockaddr_storage peeraddr; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; #ifdef ENABLE_SLPv2_SECURITY int urlauthlen = 0; unsigned char* urlauth = 0; if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled"))) { result = SLPAuthSignUrl(handle->hspi, 0, 0, handle->params.dereg.urllen, handle->params.dereg.url, &urlauthlen, &urlauth); bufsize += urlauthlen; } #endif /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVDEREG */ /*-------------------------------------------------------------------*/ bufsize += handle->params.dereg.scopelistlen + 2; /* 2 bytes for len field*/ bufsize += handle->params.dereg.urllen + 6; /* 1 byte for reserved */ /* 2 bytes for lifetime */ /* 2 bytes for urllen */ /* 1 byte for authcount */ bufsize += 2; /* 2 bytes for taglistlen*/ /*--------------------------------------------*/ /* Allocate a buffer for the SRVDEREG message */ /*--------------------------------------------*/ buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVDEREG*/ /*------------------------------------------------------------*/ /* scope list */ ToUINT16(curpos,handle->params.dereg.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.dereg.scopelist, handle->params.dereg.scopelistlen); curpos = curpos + handle->params.dereg.scopelistlen; /* url-entry reserved */ *curpos = 0; curpos = curpos + 1; /* url-entry lifetime */ ToUINT16(curpos, 0); curpos = curpos + 2; /* url-entry urllen */ ToUINT16(curpos,handle->params.dereg.urllen); curpos = curpos + 2; /* url-entry url */ memcpy(curpos, handle->params.dereg.url, handle->params.dereg.urllen); curpos = curpos + handle->params.dereg.urllen; /* url-entry authcount */ #ifdef ENABLE_SLPv2_SECURITY if(urlauth) { /* authcount */ *(curpos) = 1; curpos = curpos + 1; /* authblock */ memcpy(curpos,urlauth,urlauthlen); curpos = curpos + urlauthlen; } else #endif { /* authcount */ *(curpos) = 0; curpos = curpos + 1; } /* tag list */ /* TODO: No tag list for now put in taglist stuff */ ToUINT16(curpos,0); /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ sock = NetworkConnectToSA(handle, handle->params.reg.scopelist, handle->params.reg.scopelistlen, &peeraddr); if(sock >= 0) { result = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_SRVDEREG, bufsize, CallbackSrvDeReg, handle); if (result) { NetworkDisconnectSA(handle); } } else { result = SLP_NETWORK_INIT_FAILED; goto FINISHED; } FINISHED: if(buf) xfree(buf); #ifdef ENABLE_SLPv2_SECURITY if(urlauth) xfree(urlauth); #endif return result; }
/*-------------------------------------------------------------------------*/ SLPBoolean ProcessAttrRplyCallback(SLPError errorcode, struct sockaddr_in* peerinfo, SLPBuffer replybuf, void* cookie) /*-------------------------------------------------------------------------*/ { SLPMessage replymsg; SLPAttrRply* attrrply; PSLPHandleInfo handle = (PSLPHandleInfo) cookie; SLPBoolean result = SLP_TRUE; #ifdef ENABLE_SLPv2_SECURITY int securityenabled; securityenabled = SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled")); #endif /*-------------------------------------------*/ /* Check the errorcode and bail if it is set */ /*-------------------------------------------*/ if(errorcode) { handle->params.findattrs.callback((SLPHandle)handle, 0, errorcode, handle->params.findattrs.cookie); return SLP_FALSE; } /*--------------------*/ /* Parse the replybuf */ /*--------------------*/ replymsg = SLPMessageAlloc(); if(replymsg) { if(SLPMessageParseBuffer(peerinfo,replybuf,replymsg) == 0 && replymsg->header.functionid == SLP_FUNCT_ATTRRPLY && replymsg->body.attrrply.errorcode == 0) { attrrply = &(replymsg->body.attrrply); if(attrrply->attrlistlen) { #ifdef ENABLE_SLPv2_SECURITY /*-------------------------------*/ /* Validate the authblocks */ /*-------------------------------*/ if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled")) && SLPAuthVerifyString(handle->hspi, 1, attrrply->attrlistlen, attrrply->attrlist, attrrply->authcount, attrrply->autharray)) { /* Could not verify the attr auth block */ SLPMessageFree(replymsg); return result; } #endif /*---------------------------------------*/ /* Send the attribute list to the caller */ /*---------------------------------------*/ /* TRICKY: null terminate the attrlist by setting the authcount to 0 */ ((char*)(attrrply->attrlist))[attrrply->attrlistlen] = 0; /* Call the callback function */ result = handle->params.findattrs.callback((SLPHandle)handle, attrrply->attrlist, attrrply->errorcode * -1, handle->params.findattrs.cookie); } } SLPMessageFree(replymsg); } return result; }
/*-------------------------------------------------------------------------*/ SLPError ProcessAttrRqst(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { int sock; struct sockaddr_in peeraddr; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; #ifdef ENABLE_SLPv2_SECURITY int spistrlen = 0; char* spistr = 0; if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled"))) { SLPSpiGetDefaultSPI(handle->hspi, SLPSPI_KEY_TYPE_PUBLIC, &spistrlen, &spistr); } #endif /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the ATTRRQST */ /*-------------------------------------------------------------------*/ bufsize = handle->params.findattrs.urllen + 2; /* 2 bytes for len field */ bufsize += handle->params.findattrs.scopelistlen + 2; /* 2 bytes for len field */ bufsize += handle->params.findattrs.taglistlen + 2; /* 2 bytes for len field */ bufsize += 2; /* 2 bytes for spistr len*/ #ifdef ENABLE_SLPv2_SECURITY bufsize += spistrlen; #endif buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the ATTRRQST*/ /*------------------------------------------------------------*/ /* url */ ToUINT16(curpos,handle->params.findattrs.urllen); curpos = curpos + 2; memcpy(curpos, handle->params.findattrs.url, handle->params.findattrs.urllen); curpos = curpos + handle->params.findattrs.urllen; /* scope list */ ToUINT16(curpos,handle->params.findattrs.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findattrs.scopelist, handle->params.findattrs.scopelistlen); curpos = curpos + handle->params.findattrs.scopelistlen; /* taglist */ ToUINT16(curpos,handle->params.findattrs.taglistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findattrs.taglist, handle->params.findattrs.taglistlen); curpos = curpos + handle->params.findattrs.taglistlen; #ifdef ENABLE_SLPv2_SECURITY ToUINT16(curpos,spistrlen); curpos = curpos + 2; memcpy(curpos,spistr,spistrlen); curpos = curpos + spistrlen; #else ToUINT16(curpos,0); #endif /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ do { sock = NetworkConnectToDA(handle, handle->params.findattrs.scopelist, handle->params.findattrs.scopelistlen, &peeraddr); if(sock == -1) { /* use multicast as a last resort */ result = NetworkMcastRqstRply(handle->langtag, buf, SLP_FUNCT_ATTRRQST, bufsize, ProcessAttrRplyCallback, handle); break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, 0, buf, SLP_FUNCT_ATTRRQST, bufsize, ProcessAttrRplyCallback, handle); if(result) { NetworkDisconnectDA(handle); } } while(result == SLP_NETWORK_ERROR); FINISHED: if(buf) xfree(buf); #ifdef ENABLE_SLPv2_SECURITY if(spistr) xfree(spistr); #endif return result; }
/*=========================================================================*/ 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); } }
/** Determine if we should use IPv4. * * @return A boolean value; True if IPv4 should be used, False if not. * * @todo Change this routine to get v4 net info, not property info. */ int SLPNetIsIPV4(void) { return SLPPropertyAsBoolean("net.slp.useIPv4")? 1: 0; }
/*-------------------------------------------------------------------------*/ SLPBoolean ProcessSrvRplyCallback(SLPError errorcode, struct sockaddr_in* peerinfo, SLPBuffer replybuf, void* cookie) /*-------------------------------------------------------------------------*/ { int i; SLPUrlEntry* urlentry; SLPMessage replymsg; PSLPHandleInfo handle = (PSLPHandleInfo) cookie; SLPBoolean result = SLP_TRUE; #ifdef ENABLE_SLPv2_SECURITY int securityenabled; securityenabled = SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled")); #endif /*-------------------------------------------*/ /* Check the errorcode and bail if it is set */ /*-------------------------------------------*/ if(errorcode != SLP_OK) { return ColateSLPSrvURLCallback((SLPHandle)handle, 0, 0, errorcode, handle->params.findsrvs.cookie); } /*--------------------*/ /* Parse the replybuf */ /*--------------------*/ replymsg = SLPMessageAlloc(); if(replymsg) { if(SLPMessageParseBuffer(peerinfo,replybuf,replymsg) == 0) { if(replymsg->header.functionid == SLP_FUNCT_SRVRPLY && replymsg->body.srvrply.errorcode == 0) { urlentry = replymsg->body.srvrply.urlarray; for(i=0;i<replymsg->body.srvrply.urlcount;i++) { #ifdef ENABLE_SLPv2_SECURITY /*-------------------------------*/ /* Validate the authblocks */ /*-------------------------------*/ if(securityenabled && SLPAuthVerifyUrl(handle->hspi, 1, &(urlentry[i]))) { /* authentication failed skip this URLEntry */ continue; } #endif /*--------------------------------*/ /* Send the URL to the API caller */ /*--------------------------------*/ /* TRICKY: null terminate the url by setting the authcount to 0 */ ((char*)(urlentry[i].url))[urlentry[i].urllen] = 0; result = ColateSLPSrvURLCallback((SLPHandle)handle, urlentry[i].url, (unsigned short)urlentry[i].lifetime, SLP_OK, handle->params.findsrvs.cookie); if(result == SLP_FALSE) { break; } } } else if(replymsg->header.functionid == SLP_FUNCT_DAADVERT && replymsg->body.daadvert.errorcode == 0) { #ifdef ENABLE_SLPv2_SECURITY if(securityenabled && SLPAuthVerifyDAAdvert(handle->hspi, 1, &(replymsg->body.daadvert))) { /* Verification failed. Ignore message */ SLPMessageFree(replymsg); return SLP_TRUE; } #endif ((char*)(replymsg->body.daadvert.url))[replymsg->body.daadvert.urllen] = 0; result = ColateSLPSrvURLCallback((SLPHandle)handle, replymsg->body.daadvert.url, SLP_LIFETIME_MAXIMUM, SLP_OK, handle->params.findsrvs.cookie); } else if(replymsg->header.functionid == SLP_FUNCT_SAADVERT) { #ifdef ENABLE_SLPv2_SECURITY if(securityenabled && SLPAuthVerifySAAdvert(handle->hspi, 1, &(replymsg->body.saadvert))) { /* Verification failed. Ignore message */ SLPMessageFree(replymsg); return SLP_TRUE; } #endif ((char*)(replymsg->body.saadvert.url))[replymsg->body.saadvert.urllen] = 0; result = ColateSLPSrvURLCallback((SLPHandle)handle, replymsg->body.saadvert.url, SLP_LIFETIME_MAXIMUM, SLP_OK, handle->params.findsrvs.cookie); } } SLPMessageFree(replymsg); } return result; }
/** 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()*/ }
/*=========================================================================*/ 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 }