File openslp.hardmtu.diff of Package openslp.3206

--- ./common/slp_property.c.orig	2014-02-18 17:14:52.119092941 +0000
+++ ./common/slp_property.c	2014-02-18 17:15:01.462092925 +0000
@@ -181,6 +181,8 @@ static int SetDefaultValues(void)
       {"net.slp.isDABackup", "false", 0},
       {"net.slp.DABackupInterval", "900", 0},
       {"net.slp.DABackupLocalReg", "false", 0},
+
+      {"net.slp.hardMTU", "false", 0},
    };
 
    int i;
--- ./etc/slp.conf.orig	2014-02-18 17:14:52.109092941 +0000
+++ ./etc/slp.conf	2014-02-18 17:15:01.463092925 +0000
@@ -168,6 +168,12 @@
 # A integer giving the network packet MTU in bytes. (Default is 1400)
 ;net.slp.MTU = 1400
 
+# make sure that UDP packets really are smaller than the MTU. Normally
+# openslp will truncate packets so that they are a bit bigger than
+# the MTU, as a workaround for bugs in old openslp implementations.
+# (Default is false)
+;net.slp.hardMTU = false
+
 #
 # If operating as an SA or DA, this specifies the maximum number of interfaces
 # that can be active. (Default is 100)
--- ./slpd/slpd_incoming.c.orig	2014-02-18 17:14:52.103092941 +0000
+++ ./slpd/slpd_incoming.c	2014-02-18 17:15:01.464092925 +0000
@@ -89,6 +89,8 @@ static void IncomingDatagramRead(SLPList
       truncate = G_SlpdProperty.MTU;
       if (G_SlpdProperty.oversizedUDP)
          truncate = 0;
+      if (G_SlpdProperty.hardMTU)
+         truncate = G_SlpdProperty.MTU - 28;
 
       if (!sock->sendbuf)
          /* Some of the error handling code expects a sendbuf to be available
--- ./slpd/slpd_process.c.orig	2014-02-18 17:14:52.104092941 +0000
+++ ./slpd/slpd_process.c	2014-02-18 17:19:11.508092482 +0000
@@ -406,6 +406,7 @@ static int ProcessSrvRqst(SLPMessage * m
    SLPUrlEntry * urlentry;
    SLPDDatabaseSrvRqstResult * db = 0;
    size_t size = 0;
+   int truncated = 0;
    SLPBuffer result = *sendbuf;
 
    /* If errorcode is set, we can not be sure that message is good
@@ -509,9 +510,14 @@ RESPOND:
    {
       for (i = 0; i < db->urlcount; i++)
       {
+         int oldsize = size;
+
          /* check size limitation */
          if (truncate && size > truncate)
+         {
+            truncated = 1;
             break;
+         }
 
          /* urlentry is the url from the db result */
          urlentry = db->urlarray[i];
@@ -529,6 +535,12 @@ RESPOND:
          {
             size += urlentry->opaquelen;
          }
+         if (G_SlpdProperty.hardMTU && truncate && size > truncate)
+         {
+            size = oldsize;
+            truncated = 1;
+            break;
+         }
       }
    }
 
@@ -552,7 +564,7 @@ RESPOND:
    PutUINT24(&result->curpos, size);
 
    /* flags */
-   PutUINT16(&result->curpos, (size > (size_t)G_SlpdProperty.MTU?
+   PutUINT16(&result->curpos, (truncated || size > (size_t)G_SlpdProperty.MTU?
          SLP_FLAG_OVERFLOW: 0));
 
    /* ext offset */
@@ -580,8 +592,12 @@ RESPOND:
       for (i = 0; i < db->urlcount; i++)
       {
          /* check size limitation */
-         if (truncate && result->curpos - result->start > truncate)
+         if (result->curpos - result->start >= size)
+         {
+            /* reached size limit due to truncation. fix up url count */
+            TO_UINT16(result->start + 14 + message->header.langtaglen + 2, i);
             break;
+         }
 
          /* urlentry is the url from the db result */
          urlentry = db->urlarray[i];
@@ -880,10 +896,12 @@ static int ProcessSrvAck(SLPMessage * me
  * @internal
  */
 static int ProcessAttrRqst(SLPMessage * message, SLPBuffer * sendbuf,
-      int errorcode)
+      int errorcode, int truncate)
 {
    SLPDDatabaseAttrRqstResult * db = 0;
    size_t size = 0;
+   int truncated = 1;
+   size_t attrlistlen = 0;
    SLPBuffer result = *sendbuf;
 
 #ifdef ENABLE_SLPv2_SECURITY
@@ -1032,6 +1050,15 @@ RESPOND:
       }
 #endif
 
+      /* truncate if needed */
+      attrlistlen = db->attrlistlen;
+      if (truncate && size > truncate && G_SlpdProperty.hardMTU)
+      {
+         attrlistlen = 0;
+         opaqueauth = 0;
+         size = message->header.langtaglen + 19; /* 14 bytes for header */
+         truncated = 1;
+      }
    }
 
    /* alloc the  buffer */
@@ -1054,7 +1081,7 @@ RESPOND:
    PutUINT24(&result->curpos, size);
 
    /* flags */
-   PutUINT16(&result->curpos, (size > (size_t)G_SlpdProperty.MTU?
+   PutUINT16(&result->curpos, (truncated || size > (size_t)G_SlpdProperty.MTU?
          SLP_FLAG_OVERFLOW: 0));
 
    /* ext offset */
@@ -1078,10 +1105,10 @@ RESPOND:
    if (errorcode == 0)
    {
       /* attr-list len */
-      PutUINT16(&result->curpos, db->attrlistlen);
-      if (db->attrlistlen)
-         memcpy(result->curpos, db->attrlist, db->attrlistlen);
-      result->curpos += db->attrlistlen;
+      PutUINT16(&result->curpos, attrlistlen);
+      if (attrlistlen)
+         memcpy(result->curpos, db->attrlist, attrlistlen);
+      result->curpos += attrlistlen;
 
       /* authentication block */
 #ifdef ENABLE_SLPv2_SECURITY
@@ -1187,9 +1214,11 @@ RESPOND:
  * @internal
  */
 static int ProcessSrvTypeRqst(SLPMessage * message, SLPBuffer * sendbuf,
-      int errorcode)
+      int errorcode, int truncate)
 {
    size_t size = 0;
+   int truncated = 0;
+   size_t typelistlen = 0;
    SLPDDatabaseSrvTypeRqstResult * db = 0;
    SLPBuffer result = *sendbuf;
 
@@ -1233,7 +1262,18 @@ RESPOND:
                                              /*  2 bytes for error code */
                                              /*  2 bytes for srvtype len */
    if (errorcode == 0)
+   {
       size += db->srvtypelistlen;
+      typelistlen = db->srvtypelistlen;
+
+      /* truncate result if needed */
+      if (truncate && size > truncate && G_SlpdProperty.hardMTU)
+      {
+         typelistlen = 0;
+         size -= db->srvtypelistlen;
+         truncated = 1;
+      }
+   }
 
    /* Reallocate the result buffer */
    result = SLPBufferRealloc(result, size);
@@ -1255,7 +1295,7 @@ RESPOND:
    PutUINT24(&result->curpos, size);
 
    /* flags */
-   PutUINT16(&result->curpos, (size > (size_t)G_SlpdProperty.MTU?
+   PutUINT16(&result->curpos, (truncated || size > (size_t)G_SlpdProperty.MTU?
          SLP_FLAG_OVERFLOW: 0));
 
    /* ext offset */
@@ -1279,9 +1319,10 @@ RESPOND:
    if (errorcode == 0)
    {
       /* length of srvtype-list */
-      PutUINT16(&result->curpos, db->srvtypelistlen);
-      memcpy(result->curpos, db->srvtypelist, db->srvtypelistlen);
-      result->curpos += db->srvtypelistlen;
+      PutUINT16(&result->curpos, typelistlen);
+      if (typelistlen)
+         memcpy(result->curpos, db->srvtypelist, typelistlen);
+      result->curpos += typelistlen;
    }
 
 FINISHED:
@@ -1412,7 +1453,7 @@ int SLPDProcessMessage(struct sockaddr_s
                   break;
 
                case SLP_FUNCT_ATTRRQST:
-                  errorcode = ProcessAttrRqst(message, sendbuf, errorcode);
+                  errorcode = ProcessAttrRqst(message, sendbuf, errorcode, truncate);
                   break;
 
                case SLP_FUNCT_DAADVERT:
@@ -1421,7 +1462,7 @@ int SLPDProcessMessage(struct sockaddr_s
                   break;
 
                case SLP_FUNCT_SRVTYPERQST:
-                  errorcode = ProcessSrvTypeRqst(message, sendbuf, errorcode);
+                  errorcode = ProcessSrvTypeRqst(message, sendbuf, errorcode, truncate);
                   break;
 
                case SLP_FUNCT_SAADVERT:
--- ./slpd/slpd_property.c.orig	2014-02-18 17:14:52.112092941 +0000
+++ ./slpd/slpd_property.c	2014-02-18 17:15:01.465092925 +0000
@@ -250,6 +250,8 @@ void SLPDPropertyReinit(void)
    G_SlpdProperty.myHostname = SLPDGetCanonHostname();
    G_SlpdProperty.myHostnameLen = strlen(G_SlpdProperty.myHostname);
 
+   G_SlpdProperty.hardMTU = SLPPropertyAsBoolean("net.slp.hardMTU");
+
    G_SlpdProperty.DASyncReg = SLPPropertyAsBoolean("net.slp.DASyncReg");
    G_SlpdProperty.isDABackup = SLPPropertyAsBoolean("net.slp.isDABackup");
    G_SlpdProperty.DABackupInterval = SLPPropertyAsInteger("net.slp.DABackupInterval");
--- ./slpd/slpd_property.h.orig	2014-02-18 17:14:52.113092941 +0000
+++ ./slpd/slpd_property.h	2014-02-18 17:15:01.465092925 +0000
@@ -117,6 +117,7 @@ typedef struct _SLPDProperty
    int MTU;
    int useDHCP;
    int oversizedUDP;
+   int hardMTU;
 
    int DASyncReg;
    int isDABackup;