OBS-URL: https://build.opensuse.org/package/show/network:utilities/openslp?expand=0&rev=052ac759f139234c41238b1ece1ecbe8
1449 lines
50 KiB
Diff
1449 lines
50 KiB
Diff
--- ./common/Makefile.am.orig 2010-09-30 10:42:25.789407000 +0000
|
|
+++ ./common/Makefile.am 2010-09-30 10:43:08.404049000 +0000
|
|
@@ -48,6 +48,7 @@ libcommonslpd_la_SOURCES = \
|
|
slp_predicate.c \
|
|
slp_dhcp.c \
|
|
slp_mdns.c \
|
|
+ slp_network.c \
|
|
$(slp_v1message_SRCS) \
|
|
$(slp_security_SRCS)
|
|
|
|
--- ./common/slp_message.h.orig 2010-09-30 10:42:26.243407000 +0000
|
|
+++ ./common/slp_message.h 2010-09-30 10:43:08.413054000 +0000
|
|
@@ -170,6 +170,7 @@ typedef UINT32* PUINT32;
|
|
#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 2010-09-30 10:42:25.817415000 +0000
|
|
+++ ./common/slp_property.c 2010-09-30 10:43:08.422048000 +0000
|
|
@@ -213,6 +213,10 @@ int SetDefaultValues()
|
|
#else /* UNIX */
|
|
result |= SLPPropertySet("net.slp.OpenSLPVersion", VERSION);
|
|
#endif
|
|
+ result |= SLPPropertySet("net.slp.DASyncReg","false");
|
|
+ result |= SLPPropertySet("net.slp.isDABackup","false");
|
|
+ result |= SLPPropertySet("net.slp.DABackupInterval","900");
|
|
+ result |= SLPPropertySet("net.slp.DABackupLocalReg","false");
|
|
|
|
return result;
|
|
}
|
|
--- ./etc/slp.conf.orig 2002-06-11 17:25:40.000000000 +0000
|
|
+++ ./etc/slp.conf 2010-09-30 10:43:08.426050000 +0000
|
|
@@ -40,6 +40,20 @@
|
|
# if isDA is false.
|
|
;net.slp.DAHeartBeat = 10800
|
|
|
|
+# 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
|
|
+
|
|
|
|
#----------------------------------------------------------------------------
|
|
# SA Specific Configuration
|
|
--- ./slpd/Makefile.am.orig 2010-09-30 10:42:25.901413000 +0000
|
|
+++ ./slpd/Makefile.am 2010-09-30 10:43:08.432047000 +0000
|
|
@@ -39,6 +39,7 @@ slpd_knownda.c \
|
|
slpd_incoming.c \
|
|
slpd_outgoing.c \
|
|
slpd_mdns.c \
|
|
+slpd_initda.c \
|
|
slpd.h \
|
|
slpd_knownda.h \
|
|
slpd_process.h \
|
|
@@ -51,6 +52,7 @@ slpd_outgoing.h \
|
|
slpd_regfile.h \
|
|
slpd_incoming.h \
|
|
slpd_mdns.h \
|
|
+slpd_initda.h \
|
|
slpd_socket.h
|
|
|
|
slpd_LDADD = ../common/libcommonslpd.la \
|
|
--- ./slpd/slpd_database.c.orig 2010-09-30 10:42:26.270411000 +0000
|
|
+++ ./slpd/slpd_database.c 2010-09-30 10:43:37.168731000 +0000
|
|
@@ -76,6 +76,7 @@ FILE *regfileFP;
|
|
/* standard header files */
|
|
/*=========================================================================*/
|
|
#include <dirent.h>
|
|
+#include <time.h>
|
|
#include <linux/netlink.h>
|
|
#include <linux/inet_diag.h>
|
|
#include <sched.h>
|
|
@@ -212,6 +213,7 @@ int SLPDDatabaseReg(SLPMessage msg, SLPB
|
|
/* Check to ensure the source addr is the same */
|
|
/* as the original */
|
|
if ( G_SlpdProperty.checkSourceAddr &&
|
|
+ entryreg->source != SLP_REG_SOURCE_PULL_PEER_DA &&
|
|
memcmp(&(entry->msg->peer.sin_addr),
|
|
&(msg->peer.sin_addr),
|
|
sizeof(struct in_addr)) )
|
|
@@ -228,6 +230,13 @@ int SLPDDatabaseReg(SLPMessage msg, SLPB
|
|
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);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
/* Remove the identical entry */
|
|
SLPDatabaseRemove(dh,entry);
|
|
break;
|
|
@@ -322,6 +331,7 @@ int SLPDDatabaseDeReg(SLPMessage msg)
|
|
/* Check to ensure the source addr is the same as */
|
|
/* the original */
|
|
if ( G_SlpdProperty.checkSourceAddr &&
|
|
+ entry->msg->body.srvreg.source != SLP_REG_SOURCE_PULL_PEER_DA &&
|
|
memcmp(&(entry->msg->peer.sin_addr),
|
|
&(msg->peer.sin_addr),
|
|
sizeof(struct in_addr)) )
|
|
@@ -465,6 +475,12 @@ int SLPDDatabaseSrvRqstStart(SLPMessage
|
|
}
|
|
}
|
|
#endif
|
|
+ if (srvrqst->predicatelen == 29 && !strncmp(srvrqst->predicate, "(!(openslp-pulled-from-da=*))", 29))
|
|
+ {
|
|
+ /* this is the special "no pulled entries" predicate used in DA syncing */
|
|
+ if (entryreg->source == SLP_REG_SOURCE_PULL_PEER_DA)
|
|
+ continue; /* skip it */
|
|
+ }
|
|
if ( (*result)->urlcount + 1 > G_SlpdDatabase.urlcount )
|
|
{
|
|
/* Oops we did not allocate a big enough result */
|
|
@@ -1203,7 +1219,7 @@ int SLPDDatabaseReInit()
|
|
if ( regfileFP )
|
|
{
|
|
rewind(regfileFP);
|
|
- while ( SLPDRegFileReadSrvReg(regfileFP, &msg, &buf) == 0 )
|
|
+ while ( SLPDRegFileReadSrvReg(regfileFP, SLP_REG_SOURCE_STATIC, &msg, &buf) == 0 )
|
|
{
|
|
SLPDDatabaseReg(msg, buf);
|
|
}
|
|
@@ -1223,7 +1239,7 @@ int SLPDDatabaseReInit()
|
|
strcmp(filename+strlen(filename)-4, ".reg") == 0 &&
|
|
(fd=fopen(filename,"rb")) )
|
|
{
|
|
- while ( SLPDRegFileReadSrvReg(fd, &msg, &buf) == 0 )
|
|
+ while ( SLPDRegFileReadSrvReg(fd, SLP_REG_SOURCE_STATIC, &msg, &buf) == 0 )
|
|
{
|
|
SLPDDatabaseReg(msg, buf);
|
|
}
|
|
@@ -1238,6 +1254,69 @@ int SLPDDatabaseReInit()
|
|
return 0;
|
|
}
|
|
|
|
+/*=========================================================================*/
|
|
+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
|
|
/*=========================================================================*/
|
|
void SLPDDatabaseDeinit(void)
|
|
--- ./slpd/slpd_database.h.orig 2010-09-30 10:42:25.916410000 +0000
|
|
+++ ./slpd/slpd_database.h 2010-09-30 10:43:08.464052000 +0000
|
|
@@ -286,6 +286,14 @@ int SLPDDatabaseReInit();
|
|
|
|
void SLPDDatabaseWatcher(void);
|
|
|
|
+/*=========================================================================*/
|
|
+void SLPDDatabaseReadDABackup(FILE *fp);
|
|
+/*=========================================================================*/
|
|
+
|
|
+/*=========================================================================*/
|
|
+void SLPDDatabaseWriteDABackup(FILE *fp);
|
|
+/*=========================================================================*/
|
|
+
|
|
#ifdef DEBUG
|
|
/*=========================================================================*/
|
|
void SLPDDatabaseDeinit(void);
|
|
--- ./slpd/slpd_initda.c.orig 2010-09-30 10:43:08.469052000 +0000
|
|
+++ ./slpd/slpd_initda.c 2010-09-30 10:43:08.472049000 +0000
|
|
@@ -0,0 +1,407 @@
|
|
+#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_in* destaddr,
|
|
+ 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 maxwait = 0;
|
|
+ int timeouts[1];
|
|
+
|
|
+ /*----------------------------------------------------*/
|
|
+ /* Save off a few things we don't want to recalculate */
|
|
+ /*----------------------------------------------------*/
|
|
+ langtaglen = strlen(langtag);
|
|
+ xid = SLPXidGenerate();
|
|
+ mtu = SLPPropertyAsInteger(SLPPropertyGet("net.slp.MTU"));
|
|
+ sendbuf = SLPBufferAlloc(mtu);
|
|
+ if(sendbuf == 0)
|
|
+ {
|
|
+ result = SLP_MEMORY_ALLOC_FAILED;
|
|
+ goto FINISHED;
|
|
+ }
|
|
+ maxwait = SLPPropertyAsInteger(SLPPropertyGet("net.slp.unicastMaximumWait"));
|
|
+ SLPPropertyAsIntegerVector(SLPPropertyGet("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;
|
|
+ }
|
|
+ /*-----------------------------------*/
|
|
+ /* Add the header to the send buffer */
|
|
+ /*-----------------------------------*/
|
|
+ /*version*/
|
|
+ *(sendbuf->start) = 2;
|
|
+ /*function id*/
|
|
+ *(sendbuf->start + 1) = buftype;
|
|
+ /*length*/
|
|
+ ToUINT24(sendbuf->start + 2, size);
|
|
+ /*flags*/
|
|
+ ToUINT16(sendbuf->start + 5, SLP_FLAG_UCAST); /*this is a unicast */
|
|
+ /*ext offset*/
|
|
+ ToUINT24(sendbuf->start + 7,0);
|
|
+ /*xid*/
|
|
+ ToUINT16(sendbuf->start + 10,xid);
|
|
+ /*lang tag len*/
|
|
+ ToUINT16(sendbuf->start + 12,langtaglen);
|
|
+ /*lang tag*/
|
|
+ memcpy(sendbuf->start + 14, langtag, langtaglen);
|
|
+ sendbuf->curpos = sendbuf->start + langtaglen + 14 ;
|
|
+ ToUINT16(sendbuf->curpos,0);
|
|
+ sendbuf->curpos = sendbuf->curpos + 2;
|
|
+ /*-----------------------------*/
|
|
+ /* Add the rest of the message */
|
|
+ /*-----------------------------*/
|
|
+ memcpy(sendbuf->curpos, buf, bufsize);
|
|
+ /*----------------------*/
|
|
+ /* send the send buffer */
|
|
+ /*----------------------*/
|
|
+
|
|
+ result = SLPNetworkSendMessage(sock, SOCK_STREAM, sendbuf, 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(AsUINT16(recvbuf->start+10) != xid)
|
|
+ {
|
|
+ result = SLP_NETWORK_ERROR;
|
|
+ goto FINISHED;
|
|
+ }
|
|
+ message = SLPMessageAlloc();
|
|
+ result = SLPMessageParseBuffer(destaddr, 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)
|
|
+ {
|
|
+ ToUINT16(cur, urllen);
|
|
+ cur += 2;
|
|
+ memcpy(cur, url, urllen);
|
|
+ cur += urllen;
|
|
+ }
|
|
+ if (scope)
|
|
+ {
|
|
+ ToUINT16(cur, scopelen);
|
|
+ cur += 2;
|
|
+ memcpy(cur, scope, scopelen);
|
|
+ cur += scopelen;
|
|
+ }
|
|
+ if (predicate)
|
|
+ {
|
|
+ ToUINT16(cur, predicatelen);
|
|
+ cur += 2;
|
|
+ memcpy(cur, predicate, predicatelen);
|
|
+ cur += predicatelen;
|
|
+ }
|
|
+ if (spi)
|
|
+ {
|
|
+ ToUINT16(cur, spilen);
|
|
+ cur += 2;
|
|
+ memcpy(cur, spi, spilen);
|
|
+ cur += spilen;
|
|
+ }
|
|
+ *sizep = cur - buf;
|
|
+ return buf;
|
|
+}
|
|
+
|
|
+
|
|
+/*=========================================================================*/
|
|
+int getSLPServiceURLs(int sock, struct sockaddr_in *destaddr)
|
|
+/*=========================================================================*/
|
|
+{
|
|
+ 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");
|
|
+
|
|
+ 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);
|
|
+ ToUINT16(outbuf, 0xffff); /* 0xffff indicates all service types */
|
|
+ result = SLPDUnicastRqstRply(sock, destaddr, 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))
|
|
+ {
|
|
+ slpUrlList->currentServiceType = strdup(strng);
|
|
+ outbuf = createreq(&bufsize, strng, scope, "", "");
|
|
+ result = SLPDUnicastRqstRply(sock, destaddr, 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, 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 2010-09-30 10:43:08.475048000 +0000
|
|
+++ ./slpd/slpd_initda.h 2010-09-30 10:43:08.476048000 +0000
|
|
@@ -0,0 +1,16 @@
|
|
+#ifndef SLPD_INITDA_H_INCLUDE
|
|
+#define SLPD_INITDA_H_INCLUDE
|
|
+
|
|
+#include "slpd.h"
|
|
+
|
|
+/*=========================================================================*/
|
|
+/* common code includes */
|
|
+/*=========================================================================*/
|
|
+#include "slpd_socket.h"
|
|
+
|
|
+
|
|
+/*=========================================================================*/
|
|
+int getSLPServiceURLs(int sock, struct sockaddr_in *destaddr);
|
|
+/*=========================================================================*/
|
|
+
|
|
+#endif
|
|
--- ./slpd/slpd_log.c.orig 2010-09-30 10:42:25.931413000 +0000
|
|
+++ ./slpd/slpd_log.c 2010-09-30 10:43:08.484053000 +0000
|
|
@@ -476,6 +476,9 @@ void SLPDLogRegistration(const char* pre
|
|
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", inet_ntoa(entry->msg->peer.sin_addr));
|
|
+ break;
|
|
}
|
|
SLPDLogBuffer(" service-url = ",
|
|
entry->msg->body.srvreg.urlentry.urllen,
|
|
--- ./slpd/slpd_main.c.orig 2010-09-30 10:42:26.098408000 +0000
|
|
+++ ./slpd/slpd_main.c 2010-09-30 10:43:08.493052000 +0000
|
|
@@ -63,6 +63,7 @@
|
|
#ifdef ENABLE_SLPv2_SECURITY
|
|
#include "slpd_spi.h"
|
|
#endif
|
|
+#include "slpd_initda.h"
|
|
|
|
/*=========================================================================*/
|
|
/* common code includes */
|
|
@@ -76,12 +77,34 @@ int G_SIGALRM;
|
|
int G_SIGTERM;
|
|
int G_SIGHUP;
|
|
char *reg_file_dir;
|
|
+FILE *DABackupfp;
|
|
|
|
#ifdef DEBUG
|
|
int G_SIGINT; /* Signal being used for dumping registrations */
|
|
#endif
|
|
/*==========================================================================*/
|
|
|
|
+
|
|
+/*-------------------------------------------------------------------------*/
|
|
+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;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
#ifdef HAVE_POLL
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
@@ -239,6 +262,10 @@ void HandleSigTerm()
|
|
SLPDLog("SLPD daemon shutting down\n");
|
|
SLPDLog("****************************************\n");
|
|
|
|
+ /* write backup file if configured */
|
|
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup && DABackupfp)
|
|
+ SLPDDatabaseWriteDABackup(DABackupfp);
|
|
+
|
|
/* close all incoming sockets */
|
|
SLPDIncomingDeinit();
|
|
#ifdef ENABLE_MDNS_SLPD
|
|
@@ -301,6 +328,10 @@ void HandleSigHup()
|
|
SLPDLog("SLPD daemon reset by SIGHUP\n");
|
|
SLPDLog("****************************************\n\n");
|
|
|
|
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup && DABackupfp)
|
|
+ {
|
|
+ SLPDDatabaseWriteDABackup(DABackupfp);
|
|
+ }
|
|
/* unregister with all DAs */
|
|
SLPDKnownDADeinit();
|
|
|
|
@@ -322,6 +353,11 @@ void HandleSigHup()
|
|
/* Re-read the static registration file (slp.reg)*/
|
|
SLPDDatabaseReInit();
|
|
|
|
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup && DABackupfp)
|
|
+ {
|
|
+ SLPDDatabaseReadDABackup(DABackupfp);
|
|
+ }
|
|
+
|
|
/* Rebuild Known DA database */
|
|
SLPDKnownDAInit();
|
|
|
|
@@ -654,6 +690,9 @@ int main(int argc, char* argv[])
|
|
SLPDLog("Agent Interfaces = %s\n",G_SlpdProperty.interfaces);
|
|
SLPDLog("Agent URL = %s\n",G_SlpdProperty.myUrl);
|
|
|
|
+ if (G_SlpdProperty.isDA && G_SlpdProperty.isDABackup)
|
|
+ SLPDOpenDABackupFile();
|
|
+
|
|
/*---------------------------*/
|
|
/* init watcher */
|
|
/*---------------------------*/
|
|
@@ -675,6 +714,43 @@ int main(int argc, char* argv[])
|
|
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 (sock->peeraddr.sin_addr.s_addr == isock->peeraddr.sin_addr.s_addr)
|
|
+ break;
|
|
+ isock = (SLPDSocket*)isock->listitem.next;
|
|
+ }
|
|
+ if (!isock)
|
|
+ {
|
|
+ int s = SLPNetworkConnectStream(&sock->peeraddr, 0);
|
|
+ if (s >= 0)
|
|
+ {
|
|
+ int result = getSLPServiceURLs(s, &sock->peeraddr);
|
|
+ close(s);
|
|
+ if (result == 0)
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ sock = (SLPDSocket*)sock->listitem.next;
|
|
+ }
|
|
+ }
|
|
+
|
|
/*------------------------------*/
|
|
/* Set up alarm to age database */
|
|
/*------------------------------*/
|
|
@@ -753,6 +829,22 @@ int main(int argc, char* argv[])
|
|
}
|
|
#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 2010-09-30 10:42:26.221408000 +0000
|
|
+++ ./slpd/slpd_property.c 2010-09-30 10:43:08.500046000 +0000
|
|
@@ -232,6 +232,11 @@ int SLPDPropertyInit(const char* conffil
|
|
G_SlpdProperty.nextActiveDiscovery = 0; /* ensures xmit on first call to SLPDKnownDAActiveDiscovery() */
|
|
G_SlpdProperty.nextPassiveDAAdvert = 0; /* ensures xmit on first call to SLPDKnownDAPassiveDiscovery()*/
|
|
|
|
+ G_SlpdProperty.DASyncReg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.DASyncReg"));
|
|
+ G_SlpdProperty.DASyncReg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.DASyncReg"));
|
|
+ G_SlpdProperty.isDABackup = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isDABackup"));
|
|
+ G_SlpdProperty.DABackupInterval = SLPPropertyAsInteger(SLPPropertyGet("net.slp.DABackupInterval"));
|
|
+ G_SlpdProperty.DABackupLocalReg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.DABackupLocalReg"));
|
|
return 0;
|
|
}
|
|
|
|
--- ./slpd/slpd_property.h.orig 2010-09-30 10:42:26.216411000 +0000
|
|
+++ ./slpd/slpd_property.h 2010-09-30 10:43:08.507046000 +0000
|
|
@@ -96,6 +96,10 @@ typedef struct _SLPDProperty
|
|
int DAHeartBeat;
|
|
int oversizedUDP;
|
|
int allowDoubleEqualInPredicate;
|
|
+ int DASyncReg;
|
|
+ int isDABackup;
|
|
+ int DABackupInterval;
|
|
+ int DABackupLocalReg;
|
|
}SLPDProperty;
|
|
|
|
|
|
--- ./slpd/slpd_regfile.c.orig 2010-09-30 10:42:25.984413000 +0000
|
|
+++ ./slpd/slpd_regfile.c 2010-09-30 10:43:08.516048000 +0000
|
|
@@ -128,19 +128,213 @@ char* RegFileReadLine(FILE* fd, char* li
|
|
return line;
|
|
}
|
|
|
|
+
|
|
/*=========================================================================*/
|
|
-int SLPDRegFileReadSrvReg(FILE* fd,
|
|
- SLPMessage* msg,
|
|
- SLPBuffer* buf)
|
|
-/* A really big and nasty function that reads an service registration from */
|
|
-/* from a file. Don't look at this too hard or you'll be sick. This is by */
|
|
+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)
|
|
+/* 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 result = 0;
|
|
+ int bufsize = 0;
|
|
+ struct sockaddr_in peer;
|
|
+#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
|
|
+ *buf = SLPBufferAlloc(bufsize);
|
|
+ if(*buf == 0)
|
|
+ {
|
|
+ result = SLP_ERROR_INTERNAL_ERROR;
|
|
+ goto CLEANUP;
|
|
+ }
|
|
+
|
|
+ /*------------------------------*/
|
|
+ /* Now build the SrvReg Message */
|
|
+ /*------------------------------*/
|
|
+ /*version*/
|
|
+ *((*buf)->start) = 2;
|
|
+ /*function id*/
|
|
+ *((*buf)->start + 1) = SLP_FUNCT_SRVREG;
|
|
+ /*length*/
|
|
+ ToUINT24((*buf)->start + 2, bufsize);
|
|
+ /*flags*/
|
|
+ ToUINT16((*buf)->start + 5, 0);
|
|
+ /*ext offset*/
|
|
+ ToUINT24((*buf)->start + 7,0);
|
|
+ /*xid*/
|
|
+ ToUINT16((*buf)->start + 10, 0);
|
|
+ /*lang tag len*/
|
|
+ ToUINT16((*buf)->start + 12,langtaglen);
|
|
+ /*lang tag*/
|
|
+ memcpy((*buf)->start + 14, langtag, langtaglen);
|
|
+ (*buf)->curpos = (*buf)->start + langtaglen + 14 ;
|
|
+ /* url-entry reserved */
|
|
+ *(*buf)->curpos= 0;
|
|
+ (*buf)->curpos = (*buf)->curpos + 1;
|
|
+ /* url-entry lifetime */
|
|
+ ToUINT16((*buf)->curpos,lifetime);
|
|
+ (*buf)->curpos = (*buf)->curpos + 2;
|
|
+ /* url-entry urllen */
|
|
+ ToUINT16((*buf)->curpos,urllen);
|
|
+ (*buf)->curpos = (*buf)->curpos + 2;
|
|
+ /* url-entry url */
|
|
+ memcpy((*buf)->curpos,url,urllen);
|
|
+ (*buf)->curpos = (*buf)->curpos + urllen;
|
|
+ /* url-entry authblock */
|
|
+#ifdef ENABLE_SLPv2_SECURITY
|
|
+ if(urlauth)
|
|
+ {
|
|
+ /* authcount */
|
|
+ *(*buf)->curpos = 1;
|
|
+ (*buf)->curpos = (*buf)->curpos + 1;
|
|
+ /* authblock */
|
|
+ memcpy((*buf)->curpos,urlauth,urlauthlen);
|
|
+ (*buf)->curpos = (*buf)->curpos + urlauthlen;
|
|
+ }
|
|
+ else
|
|
+#endif
|
|
+ {
|
|
+ /* authcount */
|
|
+ *(*buf)->curpos = 0;
|
|
+ (*buf)->curpos += 1;
|
|
+ }
|
|
+ /* service type */
|
|
+ ToUINT16((*buf)->curpos,srvtypelen);
|
|
+ (*buf)->curpos = (*buf)->curpos + 2;
|
|
+ memcpy((*buf)->curpos,srvtype,srvtypelen);
|
|
+ (*buf)->curpos = (*buf)->curpos + srvtypelen;
|
|
+ /* scope list */
|
|
+ ToUINT16((*buf)->curpos,scopelistlen);
|
|
+ (*buf)->curpos = (*buf)->curpos + 2;
|
|
+ memcpy((*buf)->curpos,scopelist,scopelistlen);
|
|
+ (*buf)->curpos = (*buf)->curpos + scopelistlen;
|
|
+ /* attr list */
|
|
+ ToUINT16((*buf)->curpos,attrlistlen);
|
|
+ (*buf)->curpos = (*buf)->curpos + 2;
|
|
+ memcpy((*buf)->curpos,attrlist,attrlistlen);
|
|
+ (*buf)->curpos = (*buf)->curpos + attrlistlen;
|
|
+ /* attribute auth block */
|
|
+#ifdef ENABLE_SLPv2_SECURITY
|
|
+ if(attrauth)
|
|
+ {
|
|
+ /* authcount */
|
|
+ *(*buf)->curpos = 1;
|
|
+ (*buf)->curpos = (*buf)->curpos + 1;
|
|
+ /* authblock */
|
|
+ memcpy((*buf)->curpos,attrauth,attrauthlen);
|
|
+ (*buf)->curpos = (*buf)->curpos + attrauthlen;
|
|
+ }
|
|
+ else
|
|
+#endif
|
|
+ {
|
|
+ /* authcount */
|
|
+ *(*buf)->curpos = 0;
|
|
+ (*buf)->curpos = (*buf)->curpos + 1;
|
|
+ }
|
|
+
|
|
+ /*------------------------------------------------*/
|
|
+ /* Ok Now comes the really stupid (and lazy part) */
|
|
+ /*------------------------------------------------*/
|
|
+ *msg = SLPMessageAlloc();
|
|
+ if(*msg == 0)
|
|
+ {
|
|
+ SLPBufferFree(*buf);
|
|
+ *buf=0;
|
|
+ result = SLP_ERROR_INTERNAL_ERROR;
|
|
+ goto CLEANUP;
|
|
+ }
|
|
+ peer.sin_addr.s_addr = htonl(LOOPBACK_ADDRESS);
|
|
+ result = SLPMessageParseBuffer(&peer,*buf,*msg);
|
|
+ (*msg)->body.srvreg.source = source;
|
|
+
|
|
+
|
|
+CLEANUP:
|
|
+#ifdef ENABLE_SLPv2_SECURITY
|
|
+ if(urlauth) xfree(urlauth);
|
|
+ if(attrauth) xfree(attrauth);
|
|
+#endif
|
|
+
|
|
+ return result;
|
|
+}
|
|
+
|
|
+
|
|
+/*=========================================================================*/
|
|
+int SLPDRegFileReadSrvReg(FILE* fd,
|
|
+ int source,
|
|
+ SLPMessage* msg,
|
|
+ SLPBuffer* buf)
|
|
+/* A really big and nasty function that reads an service registration from */
|
|
+/* from a file. */
|
|
/* */
|
|
/* fd (IN) file to read from */
|
|
/* */
|
|
+/* source (IN) registration type (SLP_REG_SOURCE_STATIC) */
|
|
+/* */
|
|
/* msg (OUT) message describing the SrvReg in buf */
|
|
/* */
|
|
/* buf (OUT) buffer containing the SrvReg */
|
|
@@ -156,9 +350,7 @@ int SLPDRegFileReadSrvReg(FILE* fd,
|
|
char* p;
|
|
char line[4096];
|
|
|
|
- struct sockaddr_in peer;
|
|
int result = 0;
|
|
- int bufsize = 0;
|
|
int langtaglen = 0;
|
|
char* langtag = 0;
|
|
int scopelistlen = 0;
|
|
@@ -170,14 +362,9 @@ int SLPDRegFileReadSrvReg(FILE* fd,
|
|
char* srvtype = 0;
|
|
int attrlistlen = 0;
|
|
char* attrlist = 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;
|
|
+ int watchport = 0;
|
|
+ int watchflags = 0;
|
|
+ char* peerip = 0;
|
|
|
|
|
|
/*-------------------------------------------*/
|
|
@@ -217,14 +404,17 @@ int SLPDRegFileReadSrvReg(FILE* fd,
|
|
}
|
|
|
|
/* replace "$HOSTNAME" string in url */
|
|
- while ((p = strchr(url, '$')) && !strncmp(p, "$HOSTNAME", 9))
|
|
+ if (source == SLP_REG_SOURCE_STATIC)
|
|
{
|
|
- char *_url = (char*)malloc(strlen(url) - 9 + G_SlpdProperty.myHostnameLen + 1);
|
|
- strncpy(_url, url, p - url);
|
|
- strncpy(_url + (p - url), G_SlpdProperty.myHostname, G_SlpdProperty.myHostnameLen);
|
|
- strcpy(_url + (p - url) + G_SlpdProperty.myHostnameLen, url + (p - url) + 9);
|
|
- free(url);
|
|
- url = _url;
|
|
+ while ((p = strchr(url, '$')) && !strncmp(p, "$HOSTNAME", 9))
|
|
+ {
|
|
+ char *_url = (char*)malloc(strlen(url) - 9 + G_SlpdProperty.myHostnameLen + 1);
|
|
+ strncpy(_url, url, p - url);
|
|
+ strncpy(_url + (p - url), G_SlpdProperty.myHostname, G_SlpdProperty.myHostnameLen);
|
|
+ strcpy(_url + (p - url) + G_SlpdProperty.myHostnameLen, url + (p - url) + 9);
|
|
+ free(url);
|
|
+ url = _url;
|
|
+ }
|
|
}
|
|
urllen = strlen(url);
|
|
|
|
@@ -310,6 +500,7 @@ int SLPDRegFileReadSrvReg(FILE* fd,
|
|
/*-------------------------------------------------*/
|
|
/* Read all the attributes including the scopelist */
|
|
/*-------------------------------------------------*/
|
|
+
|
|
*line=0;
|
|
while(1)
|
|
{
|
|
@@ -363,6 +554,15 @@ int SLPDRegFileReadSrvReg(FILE* fd,
|
|
}
|
|
}
|
|
}
|
|
+ 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,'=');
|
|
@@ -407,7 +607,7 @@ int SLPDRegFileReadSrvReg(FILE* fd,
|
|
|
|
/* 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,"(");
|
|
@@ -436,157 +636,26 @@ int SLPDRegFileReadSrvReg(FILE* fd,
|
|
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
|
|
-
|
|
+ result = SLPDCreateSrvReg(source, urllen, url, langtaglen, langtag, srvtypelen, srvtype, scopelistlen, scopelist, attrlistlen, attrlist, lifetime, msg, buf);
|
|
+ if (result)
|
|
+ goto CLEANUP;
|
|
|
|
- /*----------------------------------------*/
|
|
- /* 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
|
|
- *buf = SLPBufferAlloc(bufsize);
|
|
- if(*buf == 0)
|
|
- {
|
|
- result = SLP_ERROR_INTERNAL_ERROR;
|
|
- goto CLEANUP;
|
|
- }
|
|
-
|
|
- /*------------------------------*/
|
|
- /* Now build the SrvReg Message */
|
|
- /*------------------------------*/
|
|
- /*version*/
|
|
- *((*buf)->start) = 2;
|
|
- /*function id*/
|
|
- *((*buf)->start + 1) = SLP_FUNCT_SRVREG;
|
|
- /*length*/
|
|
- ToUINT24((*buf)->start + 2, bufsize);
|
|
- /*flags*/
|
|
- ToUINT16((*buf)->start + 5, 0);
|
|
- /*ext offset*/
|
|
- ToUINT24((*buf)->start + 7,0);
|
|
- /*xid*/
|
|
- ToUINT16((*buf)->start + 10, 0);
|
|
- /*lang tag len*/
|
|
- ToUINT16((*buf)->start + 12,langtaglen);
|
|
- /*lang tag*/
|
|
- memcpy((*buf)->start + 14, langtag, langtaglen);
|
|
- (*buf)->curpos = (*buf)->start + langtaglen + 14 ;
|
|
- /* url-entry reserved */
|
|
- *(*buf)->curpos= 0;
|
|
- (*buf)->curpos = (*buf)->curpos + 1;
|
|
- /* url-entry lifetime */
|
|
- ToUINT16((*buf)->curpos,lifetime);
|
|
- (*buf)->curpos = (*buf)->curpos + 2;
|
|
- /* url-entry urllen */
|
|
- ToUINT16((*buf)->curpos,urllen);
|
|
- (*buf)->curpos = (*buf)->curpos + 2;
|
|
- /* url-entry url */
|
|
- memcpy((*buf)->curpos,url,urllen);
|
|
- (*buf)->curpos = (*buf)->curpos + urllen;
|
|
- /* url-entry authblock */
|
|
-#ifdef ENABLE_SLPv2_SECURITY
|
|
- if(urlauth)
|
|
- {
|
|
- /* authcount */
|
|
- *(*buf)->curpos = 1;
|
|
- (*buf)->curpos = (*buf)->curpos + 1;
|
|
- /* authblock */
|
|
- memcpy((*buf)->curpos,urlauth,urlauthlen);
|
|
- (*buf)->curpos = (*buf)->curpos + urlauthlen;
|
|
- }
|
|
- else
|
|
-#endif
|
|
- {
|
|
- /* authcount */
|
|
- *(*buf)->curpos = 0;
|
|
- (*buf)->curpos += 1;
|
|
- }
|
|
- /* service type */
|
|
- ToUINT16((*buf)->curpos,srvtypelen);
|
|
- (*buf)->curpos = (*buf)->curpos + 2;
|
|
- memcpy((*buf)->curpos,srvtype,srvtypelen);
|
|
- (*buf)->curpos = (*buf)->curpos + srvtypelen;
|
|
- /* scope list */
|
|
- ToUINT16((*buf)->curpos,scopelistlen);
|
|
- (*buf)->curpos = (*buf)->curpos + 2;
|
|
- memcpy((*buf)->curpos,scopelist,scopelistlen);
|
|
- (*buf)->curpos = (*buf)->curpos + scopelistlen;
|
|
- /* attr list */
|
|
- ToUINT16((*buf)->curpos,attrlistlen);
|
|
- (*buf)->curpos = (*buf)->curpos + 2;
|
|
- memcpy((*buf)->curpos,attrlist,attrlistlen);
|
|
- (*buf)->curpos = (*buf)->curpos + attrlistlen;
|
|
- /* attribute auth block */
|
|
-#ifdef ENABLE_SLPv2_SECURITY
|
|
- if(attrauth)
|
|
- {
|
|
- /* authcount */
|
|
- *(*buf)->curpos = 1;
|
|
- (*buf)->curpos = (*buf)->curpos + 1;
|
|
- /* authblock */
|
|
- memcpy((*buf)->curpos,attrauth,attrauthlen);
|
|
- (*buf)->curpos = (*buf)->curpos + attrauthlen;
|
|
- }
|
|
- else
|
|
-#endif
|
|
+ if (source == SLP_REG_SOURCE_STATIC)
|
|
{
|
|
- /* authcount */
|
|
- *(*buf)->curpos = 0;
|
|
- (*buf)->curpos = (*buf)->curpos + 1;
|
|
+ (*msg)->body.srvreg.watchflags = watchflags ? (watchflags | SLP_REG_WATCH_DEAD) : 0;
|
|
+ (*msg)->body.srvreg.watchport = watchport;
|
|
}
|
|
-
|
|
- /*------------------------------------------------*/
|
|
- /* Ok 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)) {
|
|
+ inet_aton(peerip + 15, &(*msg)->peer.sin_addr);
|
|
+ (*msg)->body.srvreg.source = SLP_REG_SOURCE_PULL_PEER_DA;
|
|
+ } else if (!strcmp(peerip, "local")) {
|
|
+ (*msg)->body.srvreg.source = SLP_REG_SOURCE_LOCAL;
|
|
+ } else {
|
|
+ inet_aton(peerip, &(*msg)->peer.sin_addr);
|
|
+ }
|
|
}
|
|
- peer.sin_addr.s_addr = htonl(LOOPBACK_ADDRESS);
|
|
- result = SLPMessageParseBuffer(&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:
|
|
|
|
@@ -612,11 +681,39 @@ CLEANUP:
|
|
if(scopelist) xfree(scopelist);
|
|
if(url) xfree(url);
|
|
if(srvtype) xfree(srvtype);
|
|
- if(attrlist)xfree(attrlist);
|
|
-#ifdef ENABLE_SLPv2_SECURITY
|
|
- if(urlauth) xfree(urlauth);
|
|
- if(attrauth) xfree(attrauth);
|
|
-#endif
|
|
+ if(attrlist) xfree(attrlist);
|
|
+ if(peerip) xfree(peerip);
|
|
|
|
return result;
|
|
}
|
|
+
|
|
+/*=========================================================================*/
|
|
+int SLPDRegFileWriteSrvReg(FILE* fd,
|
|
+ SLPMessage msg)
|
|
+/* Write a service registration to a file */
|
|
+/* */
|
|
+/* fd (IN) file to write to */
|
|
+/* */
|
|
+/* msg (in) message describing the SrvReg */
|
|
+/* */
|
|
+/*=========================================================================*/
|
|
+{
|
|
+ int result = 0;
|
|
+ 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", inet_ntoa(msg->peer.sin_addr));
|
|
+ else if (msg->body.srvreg.source == SLP_REG_SOURCE_LOCAL)
|
|
+ fprintf(fd, "slp-source=local\n");
|
|
+ else
|
|
+ fprintf(fd, "slp-source=%s\n", inet_ntoa(msg->peer.sin_addr));
|
|
+ if (msg->body.srvreg.scopelistlen)
|
|
+ fprintf(fd, "scopes=%.*s\n", msg->body.srvreg.scopelistlen, msg->body.srvreg.scopelist);
|
|
+ if(msg->body.srvreg.attrlistlen)
|
|
+ fprintf(fd, "%.*s\n", msg->body.srvreg.attrlistlen, msg->body.srvreg.attrlist);
|
|
+ fprintf(fd, "\n");
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
--- ./slpd/slpd_regfile.h.orig 2001-05-10 15:04:19.000000000 +0000
|
|
+++ ./slpd/slpd_regfile.h 2010-09-30 10:43:08.522049000 +0000
|
|
@@ -61,18 +61,42 @@
|
|
|
|
|
|
/*=========================================================================*/
|
|
-int SLPDRegFileReadSrvReg(FILE* fd,
|
|
- SLPMessage* msg,
|
|
- SLPBuffer* buf);
|
|
-/* A really big and nasty function that reads an service registration from */
|
|
-/* from a file. Don't look at this too hard or you'll be sick. This is by */
|
|
+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);
|
|
+/* 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 SLPDRegFileReadSrvReg(FILE* fd,
|
|
+ int source,
|
|
+ SLPMessage* msg,
|
|
+ SLPBuffer* buf);
|
|
+/* A really big and nasty function that reads an service registration from */
|
|
+/* from a file. */
|
|
/* */
|
|
/* fd (IN) file to read from */
|
|
/* */
|
|
+/* source (IN) registration type (SLP_REG_SOURCE_STATIC) */
|
|
+/* */
|
|
/* msg (OUT) message describing the SrvReg in buf */
|
|
/* */
|
|
/* buf (OUT) buffer containing the SrvReg */
|
|
@@ -83,5 +107,16 @@ int SLPDRegFileReadSrvReg(FILE* fd,
|
|
/* SLPMessageFree() to free memory */
|
|
/*=========================================================================*/
|
|
|
|
+/*=========================================================================*/
|
|
+int SLPDRegFileWriteSrvReg(FILE* fd,
|
|
+ SLPMessage msg);
|
|
+/* Write a service registration to a file */
|
|
+/* */
|
|
+/* fd (IN) file to write to */
|
|
+/* */
|
|
+/* msg (in) message describing the SrvReg */
|
|
+/* */
|
|
+/*=========================================================================*/
|
|
+
|
|
|
|
#endif
|