openslp/openslp.initda.diff

1355 lines
42 KiB
Diff

--- ./common/slp_message.h.orig 2016-09-13 10:56:06.324486007 +0000
+++ ./common/slp_message.h 2016-09-13 10:56:14.214459554 +0000
@@ -126,6 +126,7 @@
#define SLP_REG_SOURCE_REMOTE 1 /* from a remote host */
#define SLP_REG_SOURCE_LOCAL 2 /* from localhost or IPC */
#define SLP_REG_SOURCE_STATIC 3 /* from the slp.reg file */
+#define SLP_REG_SOURCE_PULL_PEER_DA 4 /* from another DA pulled at startup */
#define SLP_REG_WATCH_TCP (1<<0)
#define SLP_REG_WATCH_UDP (1<<1)
--- ./common/slp_property.c.orig 2016-09-13 10:56:06.324486007 +0000
+++ ./common/slp_property.c 2016-09-13 10:56:14.215459551 +0000
@@ -176,6 +176,11 @@ static int SetDefaultValues(void)
/* Additional properties that are specific to IPv6 */
{"net.slp.useIPv6", "false", 0},
{"net.slp.useIPv4", "true", 0},
+
+ {"net.slp.DASyncReg", "false", 0},
+ {"net.slp.isDABackup", "false", 0},
+ {"net.slp.DABackupInterval", "900", 0},
+ {"net.slp.DABackupLocalReg", "false", 0},
};
int i;
--- ./etc/slp.conf.orig 2012-11-28 17:07:04.000000000 +0000
+++ ./etc/slp.conf 2016-09-13 10:56:14.215459551 +0000
@@ -23,6 +23,20 @@
# which DAs to use. (Default is to use dynamic DA discovery)
;net.slp.DAAddresses = myDa1,myDa2,myDa3
+# Enables backup of registrations to /etc/slp.reg.d/slpd/DABackup.
+;net.slp.isDABackup = true
+
+# A 32 bit integer giving the number of seconds for the DABackup file update.
+# Default is 15 minutes (900 seconds). Ignored if isDA is false.
+;net.slp.DABackupInterval = 900
+
+# Include local registrations in the backup, too. The default is false.
+;net.slp.DABackupLocalReg = true
+
+# Enables slpd to sync service registration between SLP DAs on startup
+# Default is false
+;net.slp.DASyncReg = true
+
#----------------------------------------------------------------------------
# DA Specific Configuration
--- ./slpd/Makefile.am.orig 2012-11-28 17:07:04.000000000 +0000
+++ ./slpd/Makefile.am 2016-09-13 10:56:14.216459548 +0000
@@ -73,7 +73,8 @@ slpd_SOURCES = \
slpd_property.c \
slpd_regfile.c \
slpd_socket.c\
- slpd_index.c
+ slpd_index.c \
+ slpd_initda.c
noinst_HEADERS = \
$(slp_predicate_HDRS) \
@@ -90,7 +91,8 @@ noinst_HEADERS = \
slpd_regfile.h \
slpd_incoming.h \
slpd_socket.h\
- slpd_index.h
+ slpd_index.h \
+ slpd_initda.h
#if you're building on Irix, replace .la with .a below
slpd_LDADD = ../common/libcommonslpd.la ../libslpattr/libslpattr.la
--- ./slpd/slpd_database.c.orig 2016-09-13 10:56:06.332485980 +0000
+++ ./slpd/slpd_database.c 2016-09-13 10:56:14.217459544 +0000
@@ -50,6 +50,7 @@
#define _GNU_SOURCE
#include <string.h>
#include <dirent.h>
+#include <time.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/inet_diag.h>
@@ -531,7 +532,7 @@ int SLPDDatabaseReg(SLPMessage * msg, SL
{
/* check to ensure the source addr is the same
as the original */
- if (G_SlpdProperty.checkSourceAddr)
+ if (G_SlpdProperty.checkSourceAddr && entryreg->source != SLP_REG_SOURCE_PULL_PEER_DA)
{
if ((entry->msg->peer.ss_family == AF_INET
&& msg->peer.ss_family == AF_INET
@@ -567,6 +568,16 @@ int SLPDDatabaseReg(SLPMessage * msg, SL
return SLP_ERROR_AUTHENTICATION_FAILED;
}
#endif
+ if (reg->source == SLP_REG_SOURCE_PULL_PEER_DA && entryreg->source != SLP_REG_SOURCE_PULL_PEER_DA)
+ {
+ /* Do not update not-pulled registrations with pulled ones */
+ SLPDatabaseClose(dh);
+ freeNormalisedSrvtype(pNormalisedSrvtype);
+ if (attr)
+ SLPAttrFree(attr);
+ return SLP_ERROR_OK;
+ }
+
/* Remove the identical entry */
SLPDDatabaseRemove(dh, entry);
break;
@@ -697,7 +708,7 @@ int SLPDDatabaseDeReg(SLPMessage * msg)
{
/* Check to ensure the source addr is the same as */
/* the original */
- if (G_SlpdProperty.checkSourceAddr)
+ if (G_SlpdProperty.checkSourceAddr && entryreg->source != SLP_REG_SOURCE_PULL_PEER_DA)
{
if ((entry->msg->peer.ss_family == AF_INET
&& msg->peer.ss_family == AF_INET
@@ -1054,7 +1065,7 @@ static int SLPDDatabaseSrvRqstStartScan(
#ifdef ENABLE_PREDICATES
SLPDPredicateTreeNode *parse_tree,
#endif
- SLPDDatabaseSrvRqstResult ** result)
+ SLPDDatabaseSrvRqstResult ** result, int nopulled)
{
SLPDatabaseHandle dh;
SLPDatabaseEntry * entry;
@@ -1074,6 +1085,9 @@ static int SLPDDatabaseSrvRqstStartScan(
if (entry == 0)
return 0; /* This is the only successful way out */
+ if (nopulled && entry->msg->body.srvreg.source == SLP_REG_SOURCE_PULL_PEER_DA)
+ continue;
+
if (SLPDDatabaseSrvRqstTestEntry(msg,
#ifdef ENABLE_PREDICATES
parse_tree,
@@ -1150,6 +1164,20 @@ int SLPDDatabaseSrvRqstStart(SLPMessage
/* rewind enumeration in case we had to reallocate */
SLPDatabaseRewind(dh);
+ if (srvrqst->predicatelen == 29 && !strncmp(srvrqst->predicate, "(!(openslp-pulled-from-da=*))", 29))
+ {
+ /* this is the special "no pulled entries" predicate used in DA syncing */
+ start_result = SLPDDatabaseSrvRqstStartScan(msg,
+#ifdef ENABLE_PREDICATES
+ predicate_parse_tree,
+#endif
+ result, 1);
+ if (start_result == 0)
+ return 0;
+ G_SlpdDatabase.urlcount *= 2;
+ continue;
+ }
+
/* Check if we can use the srvtype index */
if (G_SlpdProperty.srvtypeIsIndexed)
{
@@ -1277,7 +1305,7 @@ int SLPDDatabaseSrvRqstStart(SLPMessage
#ifdef ENABLE_PREDICATES
predicate_parse_tree,
#endif
- result);
+ result, 0);
}
#ifdef ENABLE_PREDICATES
if (predicate_parse_tree)
@@ -1883,7 +1911,7 @@ int SLPDDatabaseReInit()
if (regfileFP)
{
rewind(regfileFP);
- while (SLPDRegFileReadSrvReg(regfileFP, &msg, &buf) == 0)
+ while (SLPDRegFileReadSrvReg(regfileFP, SLP_REG_SOURCE_STATIC, &msg, &buf) == 0)
{
if (SLPDDatabaseReg(msg, buf) != SLP_ERROR_OK)
{
@@ -1905,7 +1933,7 @@ int SLPDDatabaseReInit()
strcmp(filename+strlen(filename)-4, ".reg") == 0 &&
(fp = fopen(filename,"rb")) != 0)
{
- while (SLPDRegFileReadSrvReg(fp, &msg, &buf) == 0)
+ while (SLPDRegFileReadSrvReg(fp, SLP_REG_SOURCE_STATIC, &msg, &buf) == 0)
{
if (SLPDDatabaseReg(msg, buf) != SLP_ERROR_OK)
{
@@ -2211,6 +2239,65 @@ void SLPDDatabaseWatcher(void)
}
+void SLPDDatabaseReadDABackup(FILE *fp)
+{
+ SLPMessage * msg;
+ SLPBuffer buf;
+ time_t timediff;
+ long l;
+
+ SLPDLog("Reading registration backup file...\n");
+ rewind(fp);
+ if (fscanf(fp, "# Update timestamp: %ld\n", &l) != 1)
+ return;
+ timediff = time(NULL) - (time_t)l;
+ if (timediff < 0)
+ timediff = 0;
+ while (SLPDRegFileReadSrvReg(fp, SLP_REG_SOURCE_REMOTE, &msg, &buf) == 0)
+ {
+ if (!G_SlpdProperty.DABackupLocalReg && msg->body.srvreg.source == SLP_REG_SOURCE_LOCAL)
+ {
+ SLPMessageFree(msg);
+ SLPBufferFree(buf);
+ continue;
+ }
+ msg->body.srvreg.urlentry.lifetime -= timediff;
+ if (msg->body.srvreg.urlentry.lifetime > 0)
+ SLPDDatabaseReg(msg, buf);
+ else
+ {
+ SLPMessageFree(msg);
+ SLPBufferFree(buf);
+ }
+ }
+}
+
+void SLPDDatabaseWriteDABackup(FILE *fp)
+{
+ SLPDatabaseHandle dh;
+ SLPDatabaseEntry* entry;
+
+ SLPDLog("Writing registration backup file...\n");
+ rewind(fp);
+ (void)ftruncate(fileno(fp), 0);
+ fprintf(fp, "# Update timestamp: %ld\n\n", (long)time(NULL));
+ dh = SLPDatabaseOpen(&G_SlpdDatabase.database);
+ if (dh)
+ {
+ while ((entry = SLPDatabaseEnum(dh)) != NULL)
+ {
+ if (entry->msg->body.srvreg.source == SLP_REG_SOURCE_STATIC)
+ continue;
+ if (!G_SlpdProperty.DABackupLocalReg && entry->msg->body.srvreg.source == SLP_REG_SOURCE_LOCAL)
+ continue;
+ SLPDRegFileWriteSrvReg(fp, entry->msg);
+ }
+ SLPDatabaseClose(dh);
+ }
+ fflush(fp);
+}
+
+
#ifdef DEBUG
/** Cleans up all resources used by the database.
*/
--- ./slpd/slpd_database.h.orig 2016-09-13 10:56:06.326486000 +0000
+++ ./slpd/slpd_database.h 2016-09-13 10:56:14.217459544 +0000
@@ -105,7 +105,8 @@ int SLPDDatabaseIsEmpty(void);
int SLPDDatabaseInit(const char * regfile);
int SLPDDatabaseReInit();
void SLPDDatabaseWatcher(void);
-
+void SLPDDatabaseReadDABackup(FILE *fp);
+void SLPDDatabaseWriteDABackup(FILE *fp);
#ifdef DEBUG
void SLPDDatabaseDeinit(void);
--- ./slpd/slpd_initda.c.orig 2016-09-13 10:56:14.218459541 +0000
+++ ./slpd/slpd_initda.c 2016-09-13 10:56:14.218459541 +0000
@@ -0,0 +1,396 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "slpd.h"
+#include "slp_message.h"
+#include "slp_property.h"
+#include "slp_network.h"
+#include "slpd_database.h"
+#include "slpd_regfile.h"
+#include "slpd_property.h"
+#include "slpd_log.h"
+
+
+#define SLP_NETWORK_TIMED_OUT -19
+#define SLP_MEMORY_ALLOC_FAILED -21
+#define SLP_NETWORK_ERROR -23
+
+static int SLPDUnicastRqstRply(int sock, struct sockaddr_storage * destaddr, struct sockaddr_storage * localaddr,
+ const char * langtag, char * buf, char buftype, int bufsize,
+ int (*callback)(SLPMessage * message, void *cookie), void * cookie)
+{
+ struct timeval timeout;
+ SLPBuffer sendbuf = 0;
+ SLPBuffer recvbuf = 0;
+ SLPMessage * message = 0;
+ int result = 0;
+ int langtaglen = 0;
+ int xid = 0;
+ int mtu = 0;
+ int size = 0;
+ int timeouts[1];
+
+ /* Save off a few things we don't want to recalculate */
+ langtaglen = strlen(langtag);
+ xid = SLPXidGenerate();
+ mtu = SLPPropertyAsInteger("net.slp.MTU");
+ sendbuf = SLPBufferAlloc(mtu);
+ if(sendbuf == 0)
+ {
+ result = SLP_MEMORY_ALLOC_FAILED;
+ goto FINISHED;
+ }
+ SLPPropertyAsIntegerVector("net.slp.unicastTimeouts", timeouts, 1);
+ timeout.tv_sec = timeouts[0] / 1000;
+ timeout.tv_usec = (timeouts[0] % 1000) * 1000;
+ size = 16 + langtaglen + bufsize;
+ if((sendbuf = SLPBufferRealloc(sendbuf, size)) == 0)
+ {
+ result = SLP_MEMORY_ALLOC_FAILED;
+ goto FINISHED;
+ }
+ sendbuf->curpos = sendbuf->start;
+
+ /* Add the header to the send buffer */
+ /*version*/
+ *sendbuf->curpos++ = 2;
+ /*function id*/
+ *sendbuf->curpos++ = buftype;
+ /*length*/
+ PutUINT24(&sendbuf->curpos, size);
+ /*flags*/
+ PutUINT16(&sendbuf->curpos, SLP_FLAG_UCAST); /*this is a unicast */
+ /*ext offset*/
+ PutUINT24(&sendbuf->curpos, 0);
+ /*xid*/
+ PutUINT16(&sendbuf->curpos, xid);
+ /*lang tag len*/
+ PutUINT16(&sendbuf->curpos, langtaglen);
+ /*lang tag*/
+ memcpy(sendbuf->curpos, langtag, langtaglen);
+ sendbuf->curpos += langtaglen;
+ /*prlist*/
+ PutUINT16(&sendbuf->curpos, 0);
+
+ /* Add the rest of the message */
+ memcpy(sendbuf->curpos, buf, bufsize);
+ sendbuf->curpos += bufsize;
+
+ /* send the send buffer */
+ result = SLPNetworkSendMessage(sock, SOCK_STREAM, sendbuf, sendbuf->curpos - sendbuf->start, destaddr, &timeout);
+ if (result != 0)
+ {
+ result = errno == ETIMEDOUT ? SLP_NETWORK_TIMED_OUT : SLP_NETWORK_ERROR;
+ goto FINISHED;
+ }
+ result = SLPNetworkRecvMessage(sock, SOCK_STREAM, &recvbuf, destaddr, &timeout);
+ if (result != 0)
+ {
+ result = errno == ETIMEDOUT ? SLP_NETWORK_TIMED_OUT : SLP_NETWORK_ERROR;
+ goto FINISHED;
+ }
+ if(AS_UINT16(recvbuf->start + 10) != xid)
+ {
+ result = SLP_NETWORK_ERROR;
+ goto FINISHED;
+ }
+ message = SLPMessageAlloc();
+ result = SLPMessageParseBuffer(destaddr, localaddr, recvbuf, message);
+ if (result == 0)
+ {
+ result = callback(message, cookie);
+ }
+FINISHED:
+ SLPMessageFree(message);
+ SLPBufferFree(sendbuf);
+ SLPBufferFree(recvbuf);
+ return result;
+}
+
+typedef struct SLPURL {
+ struct SLPURL *next;
+ struct SLPURL *last;
+ char *serviceURL;
+ char *attrs;
+ char* scopelist;
+ char* serviceType;
+ unsigned short ltime;
+} SLPUrl;
+
+
+/* Cache collection structure */
+typedef struct SLPUrlList {
+ char * services; /* list of all services */
+ SLPUrl * slpUrl; /* linked list of URLs for all services */
+ SLPUrl * currentSLPUrl; /* next location to be used for update */
+ char * currentScope;
+ char * currentServiceType;
+} SLPUrlList;
+
+static SLPUrl * AllocateSLPUrl()
+{
+ SLPUrl* slpUrl = (SLPUrl*)malloc(sizeof(SLPUrl));
+ slpUrl->serviceURL = NULL;
+ slpUrl->ltime = 0;
+ slpUrl->scopelist = NULL;
+ slpUrl->serviceType = NULL;
+ slpUrl->attrs = NULL;
+ slpUrl->next = NULL;
+ slpUrl->last = NULL;
+ return slpUrl;
+}
+
+
+static void CleanUpSLPUrlList(SLPUrlList* slpUrlList)
+{
+ SLPUrl* slpUrl,*slpUrlNext;
+
+ slpUrl = slpUrlList->slpUrl;
+ while(slpUrl)
+ {
+ if (slpUrl->serviceURL)
+ free(slpUrl->serviceURL);
+ if (slpUrl->scopelist)
+ free(slpUrl->scopelist);
+ if (slpUrl->serviceType)
+ free(slpUrl->serviceType);
+ if (slpUrl->attrs)
+ free(slpUrl->attrs);
+ slpUrlNext = slpUrl->next;
+ free(slpUrl);
+ slpUrl = slpUrlNext;
+ }
+ slpUrlList->slpUrl = NULL;
+ if (slpUrlList->currentScope != NULL)
+ free(slpUrlList->currentScope);
+ if(slpUrlList->services != NULL)
+ free(slpUrlList->services);
+ if(slpUrlList->currentServiceType != NULL)
+ free(slpUrlList->currentServiceType);
+ free(slpUrlList);
+}
+
+static int SLPSrvTCallBack(SLPMessage * message, void * cookie)
+{
+ if (message->header.functionid != SLP_FUNCT_SRVTYPERPLY)
+ return SLP_NETWORK_ERROR;
+ if (message->body.srvtyperply.errorcode != 0)
+ return message->body.srvtyperply.errorcode;
+ /* null terminate as in libslp */
+ ((char *)message->body.srvtyperply.srvtypelist)[message->body.srvtyperply.srvtypelistlen] = 0;
+ ((SLPUrlList*)cookie)->services = strdup(message->body.srvtyperply.srvtypelist);
+ return 0;
+}
+
+static int SLPSrvCallBack(SLPMessage * message, void * cookie)
+{
+ SLPUrl *slpUrl = NULL;
+ char scopelist[4096];
+ int i;
+ SLPUrlEntry *srvurl;
+
+ if (message->header.functionid != SLP_FUNCT_SRVRPLY)
+ return SLP_NETWORK_ERROR;
+ if (message->body.srvrply.errorcode != 0)
+ return message->body.srvrply.errorcode;
+ for (i=0; i<message->body.srvrply.urlcount; i++)
+ {
+ srvurl = message->body.srvrply.urlarray + i;
+ /* null terminate url as in libslp, overwrites authcount */
+ ((char *)srvurl->url)[srvurl->urllen] = 0;
+ for (slpUrl = ((SLPUrlList*)cookie)->slpUrl; slpUrl ; slpUrl = slpUrl->next)
+ {
+ /* Check whether the same service URL is available as part of different scope*/
+ if( (slpUrl->serviceURL != NULL) && ( strcasecmp( slpUrl->serviceURL,srvurl->url) == 0))
+ break;
+ }
+ if (slpUrl)
+ {
+ snprintf(scopelist,sizeof(scopelist),"%s,%s",slpUrl->scopelist,((SLPUrlList*)cookie)->currentScope);
+ free(slpUrl->scopelist);
+ slpUrl->scopelist = strdup(scopelist);
+ }
+ else
+ {
+ slpUrl = AllocateSLPUrl();
+ slpUrl->serviceURL = strdup(srvurl->url);
+ slpUrl->ltime = srvurl->lifetime;
+ slpUrl->scopelist = strdup(((SLPUrlList*)cookie)->currentScope);
+ slpUrl->serviceType = strdup(((SLPUrlList*)cookie)->currentServiceType);
+ slpUrl->attrs = NULL;
+ slpUrl->next = ((SLPUrlList*)cookie)->slpUrl;
+ if(((SLPUrlList*)cookie)->slpUrl)
+ ((SLPUrlList*)cookie)->slpUrl->last = slpUrl;
+ ((SLPUrlList*)cookie)->slpUrl= slpUrl;
+ }
+ }
+ return 0;
+}
+
+static int SLPSrvAttrCallBack(SLPMessage * message, void * cookie)
+{
+ SLPUrl *lslpUrl = ((SLPUrlList*)cookie)->currentSLPUrl;
+ if (message->header.functionid != SLP_FUNCT_ATTRRPLY)
+ return SLP_NETWORK_ERROR;
+ if (message->body.attrrply.errorcode != 0)
+ return message->body.attrrply.errorcode;
+
+ /* null terminate as in libslp */
+ ((char *)message->body.attrrply.attrlist)[message->body.attrrply.attrlistlen] = 0;
+ lslpUrl->attrs = strdup(message->body.attrrply.attrlist);
+ return 0;
+}
+
+static char * createreq(int * sizep, char * url, char * scope, char * predicate, char * spi)
+{
+ char *buf, *cur;
+ int urllen = url ? strlen(url) : 0;
+ int scopelen = scope ? strlen(scope) : 0;
+ int predicatelen = predicate ? strlen(predicate) : 0;
+ int spilen = spi ? strlen(spi) : 0;
+ buf = malloc(2 + urllen + 2 + scopelen + 2 + predicatelen + 2 + spilen);
+ cur = buf;
+ if (url)
+ {
+ TO_UINT16(cur, urllen);
+ cur += 2;
+ memcpy(cur, url, urllen);
+ cur += urllen;
+ }
+ if (scope)
+ {
+ TO_UINT16(cur, scopelen);
+ cur += 2;
+ memcpy(cur, scope, scopelen);
+ cur += scopelen;
+ }
+ if (predicate)
+ {
+ TO_UINT16(cur, predicatelen);
+ cur += 2;
+ memcpy(cur, predicate, predicatelen);
+ cur += predicatelen;
+ }
+ if (spi)
+ {
+ TO_UINT16(cur, spilen);
+ cur += 2;
+ memcpy(cur, spi, spilen);
+ cur += spilen;
+ }
+ *sizep = cur - buf;
+ return buf;
+}
+
+
+int getSLPServiceURLs(int sock, struct sockaddr_storage * destaddr, struct sockaddr_storage * localaddr)
+{
+ char *strng, *services;
+ int gresult = 0, result;
+ SLPUrl * slpUrl;
+ char *scope = NULL, *scopelist = NULL;
+ char scopeptr[4096],serviceptr[4096];
+ SLPMessage * msg;
+ SLPBuffer buf;
+ const char *langtag;
+ char *outbuf;
+ int bufsize;
+ char *srvtype, *srvtype_end;
+
+ SLPUrlList* slpUrlList = (SLPUrlList*)malloc(sizeof(SLPUrlList));
+ slpUrlList->slpUrl = NULL;
+ slpUrlList->services = NULL;
+ slpUrlList->currentServiceType = NULL;
+ slpUrlList->currentScope = NULL;
+
+ langtag = SLPPropertyGet("net.slp.locale", 0, 0);
+
+ scopelist = strdup(G_SlpdProperty.useScopes);
+
+ for(scope = strtok_r(scopelist,",",(char**)&scopeptr); scope ; scope = strtok_r(NULL,",",(char**)&scopeptr))
+ {
+ slpUrlList->currentScope = strdup(scope);
+ outbuf = createreq(&bufsize, "", scope, NULL, NULL);
+ TO_UINT16(outbuf, 0xffff); /* 0xffff indicates all service types */
+ result = SLPDUnicastRqstRply(sock, destaddr, localaddr, langtag, outbuf, SLP_FUNCT_SRVTYPERQST, bufsize, SLPSrvTCallBack, slpUrlList);
+ free(outbuf);
+ if (result)
+ {
+ gresult = result; /* remember error with that scope */
+ SLPDLog("Error: SLPFindSrvTypes %d\n",result);
+ continue;
+ }
+ if(slpUrlList->services)
+ {
+ services = strdup(slpUrlList->services);
+ for(strng = strtok_r(services, ",",(char**)&serviceptr); strng ; strng = strtok_r(NULL, ",",(char**)&serviceptr))
+ {
+ if (!strcasecmp(strng, SLP_SA_SERVICE_TYPE))
+ continue;
+ if (!strcasecmp(strng, SLP_DA_SERVICE_TYPE))
+ continue;
+ slpUrlList->currentServiceType = strdup(strng);
+ outbuf = createreq(&bufsize, strng, scope, "", "");
+ result = SLPDUnicastRqstRply(sock, destaddr, localaddr, langtag, outbuf, SLP_FUNCT_SRVRQST, bufsize, SLPSrvCallBack, slpUrlList);
+ free(outbuf);
+ free(slpUrlList->currentServiceType);
+ slpUrlList->currentServiceType = NULL;
+ if(result != 0)
+ {
+ SLPDLog("Error: SLPFindSrvs %d\n", result);
+ continue;
+ }
+ }
+ free(services);
+ }
+ if (slpUrlList->currentScope != NULL)
+ {
+ free(slpUrlList->currentScope);
+ slpUrlList->currentScope = NULL;
+ }
+ if(slpUrlList->services != NULL)
+ {
+ free(slpUrlList->services);
+ slpUrlList->services = NULL;
+ }
+ }
+
+ /* we now have collected all services, fetch the attributes */
+
+ for(slpUrl = slpUrlList->slpUrl; slpUrl ; slpUrl = slpUrl->next)
+ {
+ slpUrl->attrs = NULL;
+ slpUrlList->currentSLPUrl = slpUrl;
+ outbuf = createreq(&bufsize, slpUrl->serviceURL, slpUrl->scopelist, "", "");
+ result = SLPDUnicastRqstRply(sock, destaddr, localaddr, langtag, outbuf, SLP_FUNCT_ATTRRQST, bufsize, SLPSrvAttrCallBack, slpUrlList);
+ free(outbuf);
+ if(result != 0)
+ {
+ SLPDLog("Error: SLPFindAttrs %d\n", result);
+ continue;
+ }
+ srvtype = strdup(slpUrl->serviceURL);
+ srvtype_end = strstr(srvtype, "://");
+ if (srvtype_end)
+ *srvtype_end = 0;
+ if (SLPDCreateSrvReg(SLP_REG_SOURCE_PULL_PEER_DA,
+ strlen(slpUrl->serviceURL), slpUrl->serviceURL,
+ strlen(langtag), (char *)langtag,
+ strlen(srvtype), srvtype,
+ strlen(slpUrl->scopelist), slpUrl->scopelist,
+ slpUrl->attrs ? strlen(slpUrl->attrs) : 0, slpUrl->attrs,
+ slpUrl->ltime, &msg, &buf) == 0)
+ {
+ msg->peer = *destaddr;
+ SLPDDatabaseReg(msg, buf);
+ }
+ free(srvtype);
+ }
+
+ CleanUpSLPUrlList(slpUrlList);
+ if(scopelist != NULL)
+ free(scopelist);
+ return gresult;
+}
+
--- ./slpd/slpd_initda.h.orig 2016-09-13 10:56:14.218459541 +0000
+++ ./slpd/slpd_initda.h 2016-09-13 10:56:14.218459541 +0000
@@ -0,0 +1,16 @@
+#ifndef SLPD_INITDA_H_INCLUDED
+#define SLPD_INITDA_H_INCLUDED
+
+#include "slpd.h"
+
+/*=========================================================================*/
+/* common code includes */
+/*=========================================================================*/
+#include "slpd_socket.h"
+
+
+int getSLPServiceURLs(int sock, struct sockaddr_storage *destaddr, struct sockaddr_storage *localaddr);
+
+#endif /* SLPD_INITDA_H_INCLUDED */
+
+/*=========================================================================*/
--- ./slpd/slpd_log.c.orig 2016-09-13 10:56:06.326486000 +0000
+++ ./slpd/slpd_log.c 2016-09-13 10:56:14.219459537 +0000
@@ -509,6 +509,12 @@ void SLPDLogRegistration(const char * pr
case SLP_REG_SOURCE_STATIC:
SLPDLog("static (slp.reg)\n");
break;
+
+ case SLP_REG_SOURCE_PULL_PEER_DA:
+ SLPDLog("pulled from peer DA (%s)\n",
+ SLPNetSockAddrStorageToString(&entry->msg->peer,
+ addr_str, sizeof(addr_str)));
+ break;
}
SLPDLogBuffer(" service-url = ",
entry->msg->body.srvreg.urlentry.urllen,
--- ./slpd/slpd_main.c.orig 2016-09-13 10:56:06.326486000 +0000
+++ ./slpd/slpd_main.c 2016-09-13 10:57:32.988195569 +0000
@@ -57,6 +57,7 @@
#include "slp_xmalloc.h"
#include "slp_xid.h"
#include "slp_net.h"
+#include "slp_network.h"
int G_SIGALRM;
int G_SIGTERM;
@@ -65,8 +66,27 @@ int G_SIGHUP;
int G_SIGINT; /* Signal being used for dumping registrations */
int G_SIGUSR1; /* Signal being used to dump information about the database */
#endif
+#include "slpd_initda.h"
char *reg_file_dir = "/etc/slp.reg.d";
+FILE *DABackupfp;
+
+static void SLPDOpenDABackupFile()
+{
+ FILE *fp;
+ char filename[1024];
+ snprintf(filename, sizeof(filename), "%s/slpd/%s", reg_file_dir, "DABackup");
+
+ fp = fopen(filename, "a+");
+ if (!DABackupfp && !fp)
+ SLPDLog("Could not open DABackup file\n");
+ if (fp)
+ {
+ if (DABackupfp)
+ fclose(DABackupfp);
+ DABackupfp = fp;
+ }
+}
/** Configures fd_set objects with sockets.
*
@@ -214,6 +234,10 @@ void HandleSigTerm(void)
SLPDLog("SLPD daemon shutting down\n");
SLPDLog("****************************************\n");
+ /* write backup file if configured */
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup && DABackupfp)
+ SLPDDatabaseWriteDABackup(DABackupfp);
+
/* unregister with all DAs */
SLPDKnownDADeinit();
@@ -282,6 +306,10 @@ void HandleSigHup(void)
SLPDLog("SLPD daemon reset by SIGHUP\n");
SLPDLog("****************************************\n\n");
+ /* write backup file if configured */
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup && DABackupfp)
+ SLPDDatabaseWriteDABackup(DABackupfp);
+
/* unregister with all DAs */
SLPDKnownDADeinit();
@@ -298,6 +326,10 @@ void HandleSigHup(void)
/* Re-read the static registration file (slp.reg)*/
SLPDDatabaseReInit();
+ /* Re-read the backup file if configured */
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup && DABackupfp)
+ SLPDDatabaseReadDABackup(DABackupfp);
+
/* Reopen listening sockets */
SLPDIncomingReinit();
@@ -666,6 +698,9 @@ int main(int argc, char * argv[])
if (G_SlpdProperty.port != SLP_RESERVED_PORT)
SLPDLog("Using port %d instead of default %d\n", G_SlpdProperty.port, SLP_RESERVED_PORT);
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup)
+ SLPDOpenDABackupFile();
+
/* init watcher */
SLPDDatabaseWatcher();
@@ -677,6 +712,43 @@ int main(int argc, char * argv[])
if (SetUpSignalHandlers())
SLPDFatal("Error setting up signal handlers.\n");
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup && DABackupfp)
+ {
+ SLPDDatabaseReadDABackup(DABackupfp);
+ }
+
+ if((G_SlpdProperty.isDA) && (G_SlpdProperty.DASyncReg))
+ {
+ /* HACK: at that point in time all outgoing sockets are DA connections
+ * and the incoming sockets are our interfaces */
+ SLPDLog("Pulling service list from other DAs...\n");
+ SLPDSocket* sock = (SLPDSocket*)G_OutgoingSocketList.head;
+ while (sock)
+ {
+ SLPDSocket* isock = (SLPDSocket*)G_IncomingSocketList.head;
+
+ /* make sure we're not connecting to ourself */
+ while (isock)
+ {
+ if (SLPNetCompareAddrs(&sock->peeraddr, &isock->peeraddr) == 0)
+ break;
+ isock = (SLPDSocket*)isock->listitem.next;
+ }
+ if (!isock)
+ {
+ int s = SLPNetworkConnectStream(&sock->peeraddr, 0);
+ if (s >= 0)
+ {
+ int result = getSLPServiceURLs(s, &sock->peeraddr, &sock->localaddr);
+ close(s);
+ if (result == 0)
+ break;
+ }
+ }
+ sock = (SLPDSocket*)sock->listitem.next;
+ }
+ }
+
/* Set up alarm to age database -- a shorter start, so SAs register with us quickly on our startup */
alarm(2);
@@ -748,6 +820,22 @@ HANDLE_SIGNAL:
}
#endif
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup && DABackupfp)
+ {
+ static time_t lastbck;
+ time_t now;
+
+ now = time(NULL);
+ if (!lastbck)
+ lastbck = now;
+ if (now - lastbck > G_SlpdProperty.DABackupInterval)
+ {
+ SLPDLog("Updating registration backup file\n");
+ SLPDDatabaseWriteDABackup(DABackupfp);
+ lastbck = now;
+ }
+ }
+
} /* End of main loop */
/* Got SIGTERM */
--- ./slpd/slpd_property.c.orig 2016-09-13 10:56:06.330485986 +0000
+++ ./slpd/slpd_property.c 2016-09-13 10:56:14.220459534 +0000
@@ -248,6 +248,11 @@ void SLPDPropertyReinit(void)
/* set up hostname */
G_SlpdProperty.myHostname = SLPDGetCanonHostname();
G_SlpdProperty.myHostnameLen = strlen(G_SlpdProperty.myHostname);
+
+ G_SlpdProperty.DASyncReg = SLPPropertyAsBoolean("net.slp.DASyncReg");
+ G_SlpdProperty.isDABackup = SLPPropertyAsBoolean("net.slp.isDABackup");
+ G_SlpdProperty.DABackupInterval = SLPPropertyAsInteger("net.slp.DABackupInterval");
+ G_SlpdProperty.DABackupLocalReg = SLPPropertyAsBoolean("net.slp.DABackupLocalReg");
}
/** Initialize the slpd property management subsystem.
--- ./slpd/slpd_property.h.orig 2016-09-13 10:56:06.330485986 +0000
+++ ./slpd/slpd_property.h 2016-09-13 10:56:14.220459534 +0000
@@ -117,6 +117,11 @@ typedef struct _SLPDProperty
int MTU;
int useDHCP;
int oversizedUDP;
+
+ int DASyncReg;
+ int isDABackup;
+ int DABackupInterval;
+ int DABackupLocalReg;
} SLPDProperty;
extern SLPDProperty G_SlpdProperty;
--- ./slpd/slpd_regfile.c.orig 2016-09-13 10:56:06.327485996 +0000
+++ ./slpd/slpd_regfile.c 2016-09-13 10:56:14.221459531 +0000
@@ -108,15 +108,190 @@ static char * RegFileReadLine(FILE * fd,
return line;
}
+/** Create a SrcReg Message from given data.
+ * Don't look at this too hard or you'll be sick. This is by far
+ * the most horrible code in OpenSLP. Please volunteer to rewrite it!
+ *
+ * "THANK GOODNESS this function is only called at startup" -- Matt
+ *
+ * @note Eventually the caller needs to call SLPBufferFree and
+ * SLPMessageFree to free memory.
+ */
+int SLPDCreateSrvReg(int source, int urllen, char * url,
+ int langtaglen, char * langtag,
+ int srvtypelen, char * srvtype,
+ int scopelistlen, char * scopelist,
+ int attrlistlen, char * attrlist,
+ int lifetime, SLPMessage ** msg, SLPBuffer * buf)
+{
+ struct sockaddr_storage peer;
+ int result = 0;
+ size_t bufsize = 0;
+ SLPBuffer tmp;
+#ifdef ENABLE_SLPv2_SECURITY
+ unsigned char * urlauth = 0;
+ int urlauthlen = 0;
+ unsigned char * attrauth = 0;
+ int attrauthlen = 0;
+#endif
+
+#ifdef ENABLE_SLPv2_SECURITY
+ /* generate authentication blocks */
+ if (G_SlpdProperty.securityEnabled)
+ {
+ SLPAuthSignUrl(G_SlpdSpiHandle, 0, 0, urllen, url,
+ &urlauthlen, &urlauth);
+ SLPAuthSignString(G_SlpdSpiHandle, 0, 0, attrlistlen, attrlist,
+ &attrauthlen, &attrauth);
+ }
+#endif
+
+ /* allocate buffer for the SrvReg Message */
+ bufsize = 14 + langtaglen; /* 14 bytes for header */
+ bufsize += urllen + 6; /* 1 byte for reserved */
+ /* 2 bytes for lifetime */
+ /* 2 bytes for urllen */
+ /* 1 byte for authcount */
+ bufsize += srvtypelen + 2; /* 2 bytes for len field */
+ bufsize += scopelistlen + 2; /* 2 bytes for len field */
+ bufsize += attrlistlen + 2; /* 2 bytes for len field */
+ bufsize += 1; /* 1 byte for authcount */
+
+#ifdef ENABLE_SLPv2_SECURITY
+ bufsize += urlauthlen;
+ bufsize += attrauthlen;
+#endif
+
+ tmp = *buf = SLPBufferAlloc(bufsize);
+ if (tmp == 0)
+ {
+ result = SLP_ERROR_INTERNAL_ERROR;
+ goto CLEANUP;
+ }
+
+ /* now build the SrvReg Message */
+
+ /* version */
+ *tmp->curpos++ = 2;
+
+ /* function id */
+ *tmp->curpos++ = SLP_FUNCT_SRVREG;
+
+ /* length */
+ PutUINT24(&tmp->curpos, bufsize);
+
+ /* flags */
+ PutUINT16(&tmp->curpos, 0);
+
+ /* ext offset */
+ PutUINT24(&tmp->curpos, 0);
+
+ /* xid */
+ PutUINT16(&tmp->curpos, 0);
+
+ /* lang tag len */
+ PutUINT16(&tmp->curpos, langtaglen);
+
+ /* lang tag */
+ memcpy(tmp->curpos, langtag, langtaglen);
+ tmp->curpos += langtaglen;
+
+ /* url-entry reserved */
+ *tmp->curpos++ = 0;
+
+ /* url-entry lifetime */
+ PutUINT16(&tmp->curpos, lifetime);
+
+ /* url-entry urllen */
+ PutUINT16(&tmp->curpos, urllen);
+
+ /* url-entry url */
+ memcpy(tmp->curpos, url, urllen);
+ tmp->curpos += urllen;
+
+ /* url-entry authblock */
+#ifdef ENABLE_SLPv2_SECURITY
+ if (urlauth)
+ {
+ /* authcount */
+ *tmp->curpos++ = 1;
+
+ /* authblock */
+ memcpy(tmp->curpos, urlauth, urlauthlen);
+ tmp->curpos += urlauthlen;
+ }
+ else
+#endif
+ *tmp->curpos++ = 0;
+
+ /* service type */
+ PutUINT16(&tmp->curpos, srvtypelen);
+ memcpy(tmp->curpos, srvtype, srvtypelen);
+ tmp->curpos += srvtypelen;
+
+ /* scope list */
+ PutUINT16(&tmp->curpos, scopelistlen);
+ memcpy(tmp->curpos, scopelist, scopelistlen);
+ tmp->curpos += scopelistlen;
+
+ /* attr list */
+ PutUINT16(&tmp->curpos, attrlistlen);
+ memcpy(tmp->curpos, attrlist, attrlistlen);
+ tmp->curpos += attrlistlen;
+
+ /* attribute auth block */
+#ifdef ENABLE_SLPv2_SECURITY
+ if (attrauth)
+ {
+ /* authcount */
+ *tmp->curpos++ = 1;
+
+ /* authblock */
+ memcpy(tmp->curpos, attrauth, attrauthlen);
+ tmp->curpos += attrauthlen;
+ }
+ else
+#endif
+ *tmp->curpos++ = 0;
+
+ /* okay, now comes the really stupid (and lazy part) */
+ *msg = SLPMessageAlloc();
+ if (*msg == 0)
+ {
+ SLPBufferFree(*buf);
+ *buf = 0;
+ result = SLP_ERROR_INTERNAL_ERROR;
+ goto CLEANUP;
+ }
+
+ /* this should be ok even if we are not supporting IPv4,
+ * since it's a static service
+ */
+ memset(&peer, 0, sizeof(struct sockaddr_in));
+ peer.ss_family = AF_UNSPEC;
+ ((struct sockaddr_in *)&peer)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ result = SLPMessageParseBuffer(&peer, &peer, *buf, *msg);
+ (*msg)->body.srvreg.source = source;
+
+CLEANUP:
+
+#ifdef ENABLE_SLPv2_SECURITY
+ xfree(urlauth);
+ xfree(attrauth);
+#endif
+
+ return result;
+}
+
+
+
/** Read service registrations from a text file.
*
* A really big and nasty function that reads service registrations from
- * from a file. Don't look at this too hard or you'll be sick. This is by
- * far the most horrible code in OpenSLP. Please volunteer to rewrite it!
- *
- * "THANK GOODNESS this function is only called at startup" -- Matt
+ * from a file.
*
* @param[in] fd - The file to read from.
+ * @param[in] source - The registration type (SLP_REG_SOURCE_STATIC)
* @param[out] msg - A message describing the SrvReg in buf.
* @param[out] buf - The buffer used to hold @p message data.
*
@@ -126,16 +301,14 @@ static char * RegFileReadLine(FILE * fd,
* @note Eventually the caller needs to call SLPBufferFree and
* SLPMessageFree to free memory.
*/
-int SLPDRegFileReadSrvReg(FILE * fd, SLPMessage ** msg, SLPBuffer * buf)
+int SLPDRegFileReadSrvReg(FILE * fd, int source, SLPMessage ** msg, SLPBuffer * buf)
{
char * slider1;
char * slider2;
char * p;
char line[4096];
- struct sockaddr_storage peer;
int result = 0;
- size_t bufsize = 0;
size_t langtaglen = 0;
char * langtag = 0;
size_t scopelistlen = 0;
@@ -147,14 +320,8 @@ int SLPDRegFileReadSrvReg(FILE * fd, SLP
char * srvtype = 0;
size_t attrlistlen = 0;
char * attrlist = 0;
- SLPBuffer tmp;
+ char * peerip = 0;
-#ifdef ENABLE_SLPv2_SECURITY
- unsigned char * urlauth = 0;
- int urlauthlen = 0;
- unsigned char * attrauth = 0;
- int attrauthlen = 0;
-#endif
int watchport = 0;
int watchflags = 0;
@@ -184,7 +351,7 @@ int SLPDRegFileReadSrvReg(FILE * fd, SLP
goto CLEANUP;
}
/* replace "$HOSTNAME" string in url */
- while ((p = strchr(url, '$')) && !strncmp(p, "$HOSTNAME", 9))
+ while (source == SLP_REG_SOURCE_STATIC && (p = strchr(url, '$')) && !strncmp(p, "$HOSTNAME", 9))
{
char *_url = xmalloc(strlen(url) - 9 + G_SlpdProperty.myHostnameLen + 1);
strncpy(_url, url, p - url);
@@ -326,6 +493,15 @@ int SLPDRegFileReadSrvReg(FILE * fd, SLP
}
}
}
+ else if(strncasecmp(slider1,"slp-source",10) == 0 && source != SLP_REG_SOURCE_STATIC)
+ {
+ slider2 = strchr(slider1,'=');
+ if(slider2)
+ {
+ slider2++;
+ peerip=xstrdup(TrimWhitespace(slider2));
+ }
+ }
else if(strncasecmp(slider1, "tcp-port", 8) == 0 || strncasecmp(slider1, "watch-port-tcp", 14) == 0)
{
slider2 = strchr(slider1,'=');
@@ -383,7 +559,7 @@ int SLPDRegFileReadSrvReg(FILE * fd, SLP
/* we need special case for keywords (why do we need these)
they seem like a waste of code. Why not just use booleans */
- if (strchr(slider1, '='))
+ if (strchr(slider1, '=') && source == SLP_REG_SOURCE_STATIC)
{
/* normal attribute (with '=') */
strcat(attrlist, "(");
@@ -411,146 +587,37 @@ int SLPDRegFileReadSrvReg(FILE * fd, SLP
scopelistlen = G_SlpdProperty.useScopesLen;
}
-#ifdef ENABLE_SLPv2_SECURITY
- /* generate authentication blocks */
- if (G_SlpdProperty.securityEnabled)
- {
- SLPAuthSignUrl(G_SlpdSpiHandle, 0, 0, urllen, url,
- &urlauthlen, &urlauth);
- SLPAuthSignString(G_SlpdSpiHandle, 0, 0, attrlistlen, attrlist,
- &attrauthlen, &attrauth);
- }
-#endif
-
- /* allocate buffer for the SrvReg Message */
- bufsize = 14 + langtaglen; /* 14 bytes for header */
- bufsize += urllen + 6; /* 1 byte for reserved */
- /* 2 bytes for lifetime */
- /* 2 bytes for urllen */
- /* 1 byte for authcount */
- bufsize += srvtypelen + 2; /* 2 bytes for len field */
- bufsize += scopelistlen + 2; /* 2 bytes for len field */
- bufsize += attrlistlen + 2; /* 2 bytes for len field */
- bufsize += 1; /* 1 byte for authcount */
-
-#ifdef ENABLE_SLPv2_SECURITY
- bufsize += urlauthlen;
- bufsize += attrauthlen;
-#endif
+ result = SLPDCreateSrvReg(source, urllen, url, langtaglen, langtag, srvtypelen, srvtype,
+ scopelistlen, scopelist, attrlistlen, attrlist, lifetime, msg, buf);
- tmp = *buf = SLPBufferAlloc(bufsize);
- if (tmp == 0)
- {
- result = SLP_ERROR_INTERNAL_ERROR;
+ if (result)
goto CLEANUP;
- }
-
- /* now build the SrvReg Message */
-
- /* version */
- *tmp->curpos++ = 2;
-
- /* function id */
- *tmp->curpos++ = SLP_FUNCT_SRVREG;
-
- /* length */
- PutUINT24(&tmp->curpos, bufsize);
-
- /* flags */
- PutUINT16(&tmp->curpos, 0);
-
- /* ext offset */
- PutUINT24(&tmp->curpos, 0);
-
- /* xid */
- PutUINT16(&tmp->curpos, 0);
-
- /* lang tag len */
- PutUINT16(&tmp->curpos, langtaglen);
-
- /* lang tag */
- memcpy(tmp->curpos, langtag, langtaglen);
- tmp->curpos += langtaglen;
-
- /* url-entry reserved */
- *tmp->curpos++ = 0;
-
- /* url-entry lifetime */
- PutUINT16(&tmp->curpos, lifetime);
-
- /* url-entry urllen */
- PutUINT16(&tmp->curpos, urllen);
-
- /* url-entry url */
- memcpy(tmp->curpos, url, urllen);
- tmp->curpos += urllen;
-
- /* url-entry authblock */
-#ifdef ENABLE_SLPv2_SECURITY
- if (urlauth)
- {
- /* authcount */
- *tmp->curpos++ = 1;
-
- /* authblock */
- memcpy(tmp->curpos, urlauth, urlauthlen);
- tmp->curpos += urlauthlen;
- }
- else
-#endif
- *tmp->curpos++ = 0;
- /* service type */
- PutUINT16(&tmp->curpos, srvtypelen);
- memcpy(tmp->curpos, srvtype, srvtypelen);
- tmp->curpos += srvtypelen;
-
- /* scope list */
- PutUINT16(&tmp->curpos, scopelistlen);
- memcpy(tmp->curpos, scopelist, scopelistlen);
- tmp->curpos += scopelistlen;
-
- /* attr list */
- PutUINT16(&tmp->curpos, attrlistlen);
- memcpy(tmp->curpos, attrlist, attrlistlen);
- tmp->curpos += attrlistlen;
-
- /* attribute auth block */
-#ifdef ENABLE_SLPv2_SECURITY
- if (attrauth)
+ if (source == SLP_REG_SOURCE_STATIC)
{
- /* authcount */
- *tmp->curpos++ = 1;
-
- /* authblock */
- memcpy(tmp->curpos, attrauth, attrauthlen);
- tmp->curpos += attrauthlen;
+ (*msg)->body.srvreg.watchflags = watchflags ? (watchflags | SLP_REG_WATCH_DEAD) : 0;
+ (*msg)->body.srvreg.watchport = watchport;
}
- else
-#endif
- *tmp->curpos++ = 0;
- /* okay, now comes the really stupid (and lazy part) */
- *msg = SLPMessageAlloc();
- if (*msg == 0)
+ if (peerip && source != SLP_REG_SOURCE_STATIC)
{
- SLPBufferFree(*buf);
- *buf = 0;
- result = SLP_ERROR_INTERNAL_ERROR;
- goto CLEANUP;
+ if (!strncmp(peerip, "pulled-from-da-", 15))
+ {
+ int one = 1;
+ SLPIfaceStringToSockaddrs(peerip + 15, &(*msg)->peer, &one);
+ (*msg)->body.srvreg.source = SLP_REG_SOURCE_PULL_PEER_DA;
+ }
+ else if (!strcmp(peerip, "local"))
+ {
+ (*msg)->body.srvreg.source = SLP_REG_SOURCE_LOCAL;
+ }
+ else
+ {
+ int one = 1;
+ SLPIfaceStringToSockaddrs(peerip, &(*msg)->peer, &one);
+ }
}
- /* this should be ok even if we are not supporting IPv4,
- * since it's a static service
- */
- memset(&peer, 0, sizeof(struct sockaddr_in));
- peer.ss_family = AF_UNSPEC;
- ((struct sockaddr_in *)&peer)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- result = SLPMessageParseBuffer(&peer, &peer, *buf, *msg);
- (*msg)->body.srvreg.source = SLP_REG_SOURCE_STATIC;
- (*msg)->body.srvreg.watchflags = watchflags ? (watchflags | SLP_REG_WATCH_DEAD) : 0;
- (*msg)->body.srvreg.watchport = watchport;
-
CLEANUP:
/* check for errors and free memory */
@@ -578,12 +645,31 @@ CLEANUP:
xfree(url);
xfree(srvtype);
xfree(attrlist);
+ xfree(peerip);
-#ifdef ENABLE_SLPv2_SECURITY
- xfree(urlauth);
- xfree(attrauth);
-#endif
+ return result;
+}
+
+int SLPDRegFileWriteSrvReg(FILE * fd, SLPMessage * msg)
+{
+ int result = 0;
+ char addr_str[INET6_ADDRSTRLEN];
+ if (fd)
+ {
+ fprintf(fd, "%s,%s,%d\n", msg->body.srvreg.urlentry.url, msg->header.langtag, msg->body.srvreg.urlentry.lifetime);
+ if (msg->body.srvreg.source == SLP_REG_SOURCE_PULL_PEER_DA)
+ fprintf(fd, "slp-source=pulled-from-da-%s\n", SLPNetSockAddrStorageToString(&msg->peer, addr_str, sizeof(addr_str)));
+ else if (msg->body.srvreg.source == SLP_REG_SOURCE_LOCAL)
+ fprintf(fd, "slp-source=local\n");
+ else
+ fprintf(fd, "slp-source=%s\n", SLPNetSockAddrStorageToString(&msg->peer, addr_str, sizeof(addr_str)));
+ if (msg->body.srvreg.scopelistlen)
+ fprintf(fd, "scopes=%.*s\n", (int)msg->body.srvreg.scopelistlen, msg->body.srvreg.scopelist);
+ if(msg->body.srvreg.attrlistlen)
+ fprintf(fd, "%.*s\n", (int)msg->body.srvreg.attrlistlen, msg->body.srvreg.attrlist);
+ fprintf(fd, "\n");
+ }
return result;
}
--- ./slpd/slpd_regfile.h.orig 2012-11-28 17:07:04.000000000 +0000
+++ ./slpd/slpd_regfile.h 2016-09-13 10:56:14.221459531 +0000
@@ -53,7 +53,12 @@
#include "slp_message.h"
#include "slpd.h"
-int SLPDRegFileReadSrvReg(FILE * fd, SLPMessage ** msg, SLPBuffer * buf);
+int SLPDCreateSrvReg(int source, int urllen, char * url, int langtaglen, char * langtag,
+ int srvtypelen, char * srvtype, int scopelistlen, char * scopelist,
+ int attrlistlen, char * attrlist, int lifetime, SLPMessage ** msg, SLPBuffer * buf);
+
+int SLPDRegFileReadSrvReg(FILE * fd, int source, SLPMessage ** msg, SLPBuffer * buf);
+int SLPDRegFileWriteSrvReg(FILE * fd, SLPMessage * msg);
/*! @} */