[Openslp-devel] [PATCH] change MAX_SLP_IFACES to be a run-time configurable value
Brought to you by:
jcalcote
|
From: David L S. <dls...@us...> - 2012-09-11 23:52:23
|
[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 <dls...@us...>
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();
}
|