[resubmission; can anyone review this?]

We have customers who have a need to use SLP on systems that have more than
current maximum number of interfaces (MAX_SLP_IFACES) of 100.

The following patch converts the compile-time maximum to be a run-time
configurable value to allow an administrator to increase it on systems with
large numbers of interfaces.

Signed-off-by: David L Stevens <dlstev...@us.ibm.com>

diff --git a/common/slp_iface.c b/common/slp_iface.c
index 2563f8f..59bb72a 100644
--- a/common/slp_iface.c
+++ b/common/slp_iface.c
@@ -55,6 +55,8 @@
 /** The max interface name lenght is 20 */
 #define MAX_IFACE_LEN 20
 
+int slp_max_ifaces = SLP_MAX_IFACES;
+
 /** Custom designed wrapper for inet_pton to allow <ip>%<iface> format
  *
  *
@@ -352,7 +354,7 @@ static int SLPIfaceGetV6Addr(SLPIfaceInfo * ifaceinfo)
    if (getifaddrs(&ifaddrs))
       return -1;
 
-   for (ifa = ifaddrs; ifa && ifaceinfo->iface_count < SLP_MAX_IFACES; ifa = 
ifa->ifa_next)
+   for (ifa = ifaddrs; ifa && ifaceinfo->iface_count < slp_max_ifaces; ifa = 
ifa->ifa_next)
    {
       if(ifa->ifa_addr->sa_family != AF_INET6)
           continue;
@@ -374,6 +376,11 @@ static int SLPIfaceGetV6Addr(SLPIfaceInfo * ifaceinfo)
       ++ifaceinfo->iface_count;
    }
    freeifaddrs(ifaddrs);
+   if (ifa)
+   {
+      errno = ENOBUFS;
+      return -1;
+   }
    return 0;
 }
 
@@ -429,14 +436,18 @@ int sizeof_ifreq(struct ifreq* ifr)
 int SLPIfaceGetDefaultInfo(SLPIfaceInfo * ifaceinfo, int family)
 {
    sockfd_t fd;
-   struct ifreq ifrlist[SLP_MAX_IFACES];
+   struct ifreq *ifrlist;
    struct ifreq ifrflags;
    struct ifreq * ifr;
    struct sockaddr* sa;
    char * p;
 
    struct ifconf ifc;
-   ifc.ifc_len = sizeof(struct ifreq) * SLP_MAX_IFACES;
+   ifrlist = malloc(sizeof(struct ifreq) * slp_max_ifaces);
+   if (ifrlist == NULL) {
+      return -1;
+   }
+   ifc.ifc_len = sizeof(struct ifreq) * slp_max_ifaces;
    ifc.ifc_req = ifrlist;
 
    if ((family == AF_INET6) || (family == AF_UNSPEC))
@@ -454,10 +465,11 @@ int SLPIfaceGetDefaultInfo(SLPIfaceInfo * ifaceinfo, int 
family)
 #endif
          {
             closesocket(fd);
+            xfree(ifrlist);
             return -1;
          }
 
-         for (p = ifc.ifc_buf; p < ifc.ifc_buf + ifc.ifc_len && 
ifaceinfo->iface_count < SLP_MAX_IFACES;)
+         for (p = ifc.ifc_buf; p < ifc.ifc_buf + ifc.ifc_len && 
ifaceinfo->iface_count < slp_max_ifaces;)
          {
             ifr = (struct ifreq*) p;
             sa = (struct sockaddr*)&(ifr->ifr_addr);
@@ -480,7 +492,7 @@ int SLPIfaceGetDefaultInfo(SLPIfaceInfo * ifaceinfo, int 
family)
    }
 
    /* reset ifc_len for next get */
-   ifc.ifc_len = sizeof(struct ifreq) * SLP_MAX_IFACES;
+   ifc.ifc_len = sizeof(struct ifreq) * slp_max_ifaces;
 
    if ((family == AF_INET) || (family == AF_UNSPEC))
    {
@@ -494,10 +506,11 @@ int SLPIfaceGetDefaultInfo(SLPIfaceInfo * ifaceinfo, int 
family)
 #endif
          {
             closesocket(fd);
+            xfree(ifrlist);
             return -1;
          }
 
-         for (p = ifc.ifc_buf; p < ifc.ifc_buf + ifc.ifc_len && 
ifaceinfo->iface_count < SLP_MAX_IFACES;)
+         for (p = ifc.ifc_buf; p < ifc.ifc_buf + ifc.ifc_len && 
ifaceinfo->iface_count < slp_max_ifaces;)
          {
             ifr = (struct ifreq*) p;
             sa = (struct sockaddr*)&(ifr->ifr_addr);
@@ -516,6 +529,7 @@ int SLPIfaceGetDefaultInfo(SLPIfaceInfo * ifaceinfo, int 
family)
          closesocket(fd);
       }
    }
+   xfree(ifrlist);
    return 0;
 }
 
@@ -572,7 +586,7 @@ int SLPIfaceGetDefaultInfo(SLPIfaceInfo* ifaceinfo, int 
family)
                return (errno = WSAGetLastError()), -1;
             }
             plist = (SOCKET_ADDRESS_LIST*)buffer;
-            for (i = 0; i < plist->iAddressCount && ifaceinfo->iface_count < 
SLP_MAX_IFACES; ++i)
+            for (i = 0; i < plist->iAddressCount && ifaceinfo->iface_count < 
slp_max_ifaces; ++i)
                if ((plist->Address[i].lpSockaddr->sa_family == AF_INET6) &&
                    (0 == GetV6Scope((struct 
sockaddr_in6*)plist->Address[i].lpSockaddr, NULL)) &&
                    /*Ignore Teredo and loopback pseudo-interfaces*/
@@ -609,7 +623,7 @@ int SLPIfaceGetDefaultInfo(SLPIfaceInfo* ifaceinfo, int 
family)
                return (errno = WSAGetLastError()), -1;
             }
             plist = (SOCKET_ADDRESS_LIST*)buffer;
-            for (i = 0; i < plist->iAddressCount && ifaceinfo->iface_count < 
SLP_MAX_IFACES; ++i)
+            for (i = 0; i < plist->iAddressCount && ifaceinfo->iface_count < 
slp_max_ifaces; ++i)
                if (plist->Address[i].lpSockaddr->sa_family == AF_INET)
                   memcpy(&ifaceinfo->iface_addr[ifaceinfo->iface_count++], 
                         plist->Address[i].lpSockaddr, sizeof(struct 
sockaddr_in));
@@ -1078,6 +1092,21 @@ int main(int argc, char * argv[])
    WSAStartup(MAKEWORD(2, 2), &wsadata);
 #endif
 
+   ifaceinfo.iface_addr = malloc(slp_max_ifaces*sizeof(struct 
sockaddr_storage);
+   if (ifaceinfo.iface_addr == NULL)
+   {
+      fprintf(stderr, "iface_addr malloc(%d) failed\n",
+         slp_max_ifaces * sizeof(struct sockaddr_storage));
+      exit(1);
+   }
+   ifaceinfo.bcast_addr = malloc(slp_max_ifaces*sizeof(struct 
sockaddr_storage);
+   if (ifaceinfo.bcast_addr == NULL)
+   {
+      fprintf(stderr, "bcast_addr malloc(%d) failed\n",
+         slp_max_ifaces * sizeof(struct sockaddr_storage));
+      exit(1);
+   }
+
    if (SLPIfaceGetInfo(0, &ifaceinfo, AF_INET) == 0)
       for (i = 0; i < ifaceinfo.iface_count; i++)
       {
@@ -1130,6 +1159,8 @@ int main(int argc, char * argv[])
          printf("sock addr string v6 = %s\n", addrstr);
          xfree(addrstr);
       }
+   xfree(ifaceinfo.iface_addr);
+   xfree(ifaceinfo.bcast_addr);
 
 #ifdef _WIN32
    WSACleanup();
diff --git a/common/slp_iface.h b/common/slp_iface.h
index e9bfd5a..ce0d111 100644
--- a/common/slp_iface.h
+++ b/common/slp_iface.h
@@ -52,14 +52,15 @@
 
 /** The maximum number of interfaces we can handle. */
 #define SLP_MAX_IFACES 100
+extern int slp_max_ifaces;
 
 /** Interface information structure */
 typedef struct _SLPInterfaceInfo
 {
    int iface_count;
    int bcast_count;
-   struct sockaddr_storage iface_addr[SLP_MAX_IFACES];
-   struct sockaddr_storage bcast_addr[SLP_MAX_IFACES];
+   struct sockaddr_storage *iface_addr;
+   struct sockaddr_storage *bcast_addr;
 } SLPIfaceInfo;
 
 int SLPIfaceGetInfo(char const * useifaces, SLPIfaceInfo * ifaceinfo, 
diff --git a/common/slp_xcast.c b/common/slp_xcast.c
index b891769..3dca0dc 100644
--- a/common/slp_xcast.c
+++ b/common/slp_xcast.c
@@ -371,6 +371,47 @@ int main(void)
    struct sockaddr_storage dst;
    int mtu;
 
+   socks.sock = malloc(slp_max_ifaces*sizeof(sockfd_t));
+   if (socks.sock == NULL)
+   {
+      fprintf(stderr, "socks.sock malloc(%d) failed\n",
+         slp_max_ifaces*sizeof(sockfd_t));
+      exit(1);
+   }
+   socks.peeraddr = malloc(slp_max_ifaces*sizeof(struct sockaddr_storage));
+   if (socks.peeraddr == NULL)
+   {
+      fprintf(stderr, "socks.peeraddr malloc(%d) failed\n",
+         slp_max_ifaces*sizeof(struct sockaddr_storage));
+      exit(1);
+   }
+   ifaceinfo.iface_addr = malloc(slp_max_ifaces*sizeof(struct 
sockaddr_storage);
+   if (ifaceinfo.iface_addr == NULL)
+   {
+      fprintf(stderr, "ifaceinfo.iface_addr malloc(%d) failed\n",
+         slp_max_ifaces*sizeof(struct sockaddr_storage));
+      exit(1);
+   }
+   ifaceinfo.bcast_addr = malloc(slp_max_ifaces*sizeof(struct 
sockaddr_storage);
+   if (ifaceinfo.bcast_addr == NULL)
+   {
+      fprintf(stderr, "ifaceinfo.bcast_addr malloc(%d) failed\n",
+         slp_max_ifaces*sizeof(struct sockaddr_storage));
+      exit(1);
+   }
+   ifaceinfo6.iface_addr = malloc(slp_max_ifaces*sizeof(struct 
sockaddr_storage);
+   if (ifaceinfo.bcast_addr == NULL)
+   {
+      fprintf(stderr, "ifaceinfo6.iface_addr malloc(%d) failed\n",
+         slp_max_ifaces*sizeof(struct sockaddr_storage));
+      exit(1);
+   }
+   ifaceinfo6.bcast_addr = malloc(slp_max_ifaces*sizeof(struct 
sockaddr_storage);
+   if (ifaceinfo.bcast_addr == NULL) {
+      fprintf(stderr, "ifaceinfo6.bcast_addr malloc(%d) failed\n",
+         slp_max_ifaces*sizeof(struct sockaddr_storage));
+      exit(1);
+   }
 #ifdef _WIN32
    WSADATA wsadata;
    WSAStartup(MAKEWORD(2, 2), &wsadata);
@@ -409,6 +450,12 @@ int main(void)
 
       SLPBufferFree(buffer);
    }
+   xfree(ifaceinfo.iface_addr);
+   xfree(ifaceinfo.bcast_addr);
+   xfree(ifaceinfo6.iface_addr);
+   xfree(ifaceinfo6.bcast_addr);
+   xfree(socks.sock);
+   xfree(socks.peeraddr);
 
 #ifdef _WIN32
    WSACleanup();
diff --git a/common/slp_xcast.h b/common/slp_xcast.h
index c671b2b..49e4682 100644
--- a/common/slp_xcast.h
+++ b/common/slp_xcast.h
@@ -57,10 +57,10 @@ typedef struct _SLPXcastSockets
    int sock_count;
 
    /** An array of sockets managed by this structure. */
-   sockfd_t sock[SLP_MAX_IFACES];
+   sockfd_t *sock;
 
    /** An array of addresses that matches each socket in the sock array. */
-   struct sockaddr_storage peeraddr[SLP_MAX_IFACES];
+   struct sockaddr_storage *peeraddr;
 
 } SLPXcastSockets;
 
diff --git a/etc/slp.conf b/etc/slp.conf
index be57e77..156b6d7 100644
--- a/etc/slp.conf
+++ b/etc/slp.conf
@@ -148,6 +148,11 @@
 # A integer giving the network packet MTU in bytes. (Default is 1400)
 ;net.slp.MTU = 1400
 
+#
+# If operating as an SA or DA, this specifies the maximum number of interfaces
+# that can be active. (Default is 100)
+;net.slp.max_ifaces = 100
+
 # If operating as an SA or DA, then any local addresses that are going to be
 # used must be specified.  Both IPv4 and IPv6 addresses may be specified.
 # Only link-local addresses can be used for IPv6 SLP multicast.  Any
diff --git a/libslp/libslp_network.c b/libslp/libslp_network.c
index 2530bfe..cd10255 100644
--- a/libslp/libslp_network.c
+++ b/libslp/libslp_network.c
@@ -828,6 +828,7 @@ SLPError NetworkMcastRqstRply(SLPHandleInfo * handle, void 
* buf,
    SLPIfaceInfo v4outifaceinfo;
    SLPIfaceInfo v6outifaceinfo;
    SLPXcastSockets xcastsocks;
+   int alistsize;
    int currIntf = 0;
    int requestSent;
 
@@ -841,6 +842,16 @@ SLPError NetworkMcastRqstRply(SLPHandleInfo * handle, void 
* buf,
    /* save off a few things we don't want to recalculate */
    langtaglen = strlen(handle->langtag);
 
+   /* initialize pointers freed on error */
+   dstifaceinfo.iface_addr = NULL;
+   dstifaceinfo.bcast_addr = NULL;
+   v4outifaceinfo.iface_addr = NULL;
+   v4outifaceinfo.bcast_addr = NULL;
+   v6outifaceinfo.iface_addr = NULL;
+   v6outifaceinfo.bcast_addr = NULL;
+   xcastsocks.sock = NULL;
+   xcastsocks.peeraddr = NULL;
+
    xid = SLPXidGenerate();
    mtu = SLPPropertyGetMTU();
    sendbuf = SLPBufferAlloc(mtu);
@@ -850,9 +861,60 @@ SLPError NetworkMcastRqstRply(SLPHandleInfo * handle, void 
* buf,
       goto FINISHED;
    }
 
+   alistsize = slp_max_ifaces * sizeof(struct sockaddr_storage);
+
+   dstifaceinfo.iface_count = 0;
+   dstifaceinfo.iface_addr = malloc(alistsize);
+   if (dstifaceinfo.iface_addr == NULL)
+   {
+      result = SLP_MEMORY_ALLOC_FAILED;
+      goto FINISHED;
+   }
+   dstifaceinfo.bcast_addr = malloc(alistsize);
+   if (dstifaceinfo.bcast_addr == NULL)
+   {
+      result = SLP_MEMORY_ALLOC_FAILED;
+      goto FINISHED;
+   }
    v4outifaceinfo.iface_count = 0;
+   v4outifaceinfo.iface_addr = malloc(alistsize);
+   if (v4outifaceinfo.iface_addr == NULL)
+   {
+      result = SLP_MEMORY_ALLOC_FAILED;
+      goto FINISHED;
+   }
+   v4outifaceinfo.bcast_addr = malloc(alistsize);
+   if (v4outifaceinfo.bcast_addr == NULL)
+   {
+      result = SLP_MEMORY_ALLOC_FAILED;
+      goto FINISHED;
+   }
    v6outifaceinfo.iface_count = 0;
+   v6outifaceinfo.iface_addr = malloc(alistsize);
+   if (v6outifaceinfo.iface_addr == NULL)
+   {
+      result = SLP_MEMORY_ALLOC_FAILED;
+      goto FINISHED;
+   }
+   v6outifaceinfo.bcast_addr = malloc(alistsize);
+   if (v6outifaceinfo.bcast_addr == NULL)
+   {
+      result = SLP_MEMORY_ALLOC_FAILED;
+      goto FINISHED;
+   }
    xcastsocks.sock_count = 0;
+   xcastsocks.sock = malloc(slp_max_ifaces * sizeof(sockfd_t));
+   if (xcastsocks.sock == NULL)
+   {
+      result = SLP_MEMORY_ALLOC_FAILED;
+      goto FINISHED;
+   }
+   xcastsocks.peeraddr = malloc(alistsize);
+   if (xcastsocks.peeraddr == NULL)
+   {
+      result = SLP_MEMORY_ALLOC_FAILED;
+      goto FINISHED;
+   }
 
 #if !defined(MI_NOT_SUPPORTED)
    /* Determine which multicast addresses to send to. */
@@ -1168,6 +1230,14 @@ CLEANUP:
    SLPBufferFree(sendbuf);
    SLPBufferFree(recvbuf);
    SLPXcastSocketsClose(&xcastsocks);
+   xfree(xcastsocks.sock);
+   xfree(xcastsocks.peeraddr);
+   xfree(dstifaceinfo.iface_addr);
+   xfree(dstifaceinfo.bcast_addr);
+   xfree(v4outifaceinfo.iface_addr);
+   xfree(v4outifaceinfo.bcast_addr);
+   xfree(v6outifaceinfo.iface_addr);
+   xfree(v6outifaceinfo.bcast_addr);
 
    return result;
 }
diff --git a/slpd/slpd_incoming.c b/slpd/slpd_incoming.c
index 0371455..e427d22 100644
--- a/slpd/slpd_incoming.c
+++ b/slpd/slpd_incoming.c
@@ -752,9 +752,26 @@ int SLPDIncomingInit(void)
    /*   string in a safety way                                            */
    /*---------------------------------------------------------------------*/
 
+   ifaces.iface_addr = malloc(slp_max_ifaces*sizeof(struct sockaddr_storage));
+   if (ifaces.iface_addr == NULL)
+   {
+      SLPDLog("can't allocate %d iface_addrs\n", slp_max_ifaces);
+      exit(1);
+   }
+   ifaces.bcast_addr = malloc(slp_max_ifaces*sizeof(struct sockaddr_storage));
+   if (ifaces.bcast_addr == NULL)
+   {
+      SLPDLog("can't allocate %d bcast_addrs\n", slp_max_ifaces);
+      exit(1);
+   }
+   ifaces.bcast_addr = malloc(slp_max_ifaces*sizeof(struct sockaddr_storage));
    if (G_SlpdProperty.interfaces != NULL)
-      SLPIfaceGetInfo(G_SlpdProperty.interfaces, &ifaces, AF_UNSPEC);
-   else
+   {
+      if (SLPIfaceGetInfo(G_SlpdProperty.interfaces, &ifaces, AF_UNSPEC) < 0) {
+         SLPDLog("SLPIfaceGetInfo failed: %s\n", strerror(errno));
+         exit(1);
+      }
+   } else
       ifaces.iface_count = 0;
 
    for (i = 0; i < ifaces.iface_count; i++)
diff --git a/slpd/slpd_property.c b/slpd/slpd_property.c
index 81b6a8e..f9c64bb 100644
--- a/slpd/slpd_property.c
+++ b/slpd/slpd_property.c
@@ -66,6 +66,8 @@ void SLPDPropertyReinit(void)
    xfree(G_SlpdProperty.DAAddresses);
    xfree(G_SlpdProperty.interfaces);
    xfree(G_SlpdProperty.locale);
+   xfree(G_SlpdProperty.ifaceInfo.iface_addr);
+   xfree(G_SlpdProperty.ifaceInfo.bcast_addr);
 
    /* reinitialize property sub-system */
    (void)SLPPropertyReinit();
@@ -149,7 +151,22 @@ void SLPDPropertyReinit(void)
    else if (SLPNetIsIPV6())
       family = AF_INET6;
 
+   slp_max_ifaces = SLPPropertyAsInteger("net.slp.max_ifaces");
+   if (slp_max_ifaces <= 0)
+      slp_max_ifaces = SLP_MAX_IFACES;
    myinterfaces = SLPPropertyXDup("net.slp.interfaces");
+   G_SlpdProperty.ifaceInfo.iface_addr = malloc(slp_max_ifaces *
+      sizeof(struct sockaddr_storage));
+   if (G_SlpdProperty.ifaceInfo.iface_addr == NULL)
+   {
+      SLPDLog("Cannot allocate iface_addr for %d addresses\n", slp_max_ifaces);
+   }
+   G_SlpdProperty.ifaceInfo.bcast_addr = malloc(slp_max_ifaces *
+      sizeof(struct sockaddr_storage));
+   if (G_SlpdProperty.ifaceInfo.bcast_addr == NULL)
+   {
+      SLPDLog("Cannot allocate bcast_addr for %d addresses\n", slp_max_ifaces);
+   }
    sts = SLPIfaceGetInfo(myinterfaces, &G_SlpdProperty.ifaceInfo, family);
    xfree(myinterfaces);
 
@@ -246,6 +263,8 @@ void SLPDPropertyDeinit(void)
    xfree(G_SlpdProperty.indexedAttributes);
 #endif
    xfree(G_SlpdProperty.locale);
+   xfree(G_SlpdProperty.ifaceInfo.iface_addr);
+   xfree(G_SlpdProperty.ifaceInfo.bcast_addr);
 
    SLPPropertyExit();
 }


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Openslp-devel mailing list
Openslp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openslp-devel

Reply via email to