1355 lines
42 KiB
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);
|
|
|
|
/*! @} */
|
|
|