diff --git a/configure.in b/configure.in index 3061fcb..5816650 100644 --- a/configure.in +++ b/configure.in @@ -35,6 +35,13 @@ AC_ARG_WITH( [do_threads=$withval], [do_threads=check]) +AC_ARG_WITH( + [secure-sockets], + [AC_HELP_STRING([--with-secure-sockets], + [enable support for secure sockets (default is on)])], + [do_secure=$withval], + [do_secure=check]) + # # Note: the following environment variables may be # set to override the defaults. @@ -1825,70 +1832,63 @@ then ], AC_DEFINE(HAVE_FNDELAY) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) fi -dnl check for NSS/NSPR -AC_ARG_WITH([nss], - AS_HELP_STRING([--without-nss], - [Do not use NSS even if present])) - -have_nss=no -nss_incflags= -nspr_incflags= -lib_for_nss= -lib_for_nspr= -nss_inc_dir= -nspr_inc_dir= -if test "x$with_nss" != "xno" +dnl Check for Network Security Services +if test "$do_secure" = "check" -o "$do_secure" = "yes" then - AC_CHECK_FILE([/usr/include/nss3], nssdir=nss3, [ - AC_CHECK_FILE([/usr/include/nss], nssdir=nss) + enable_secure=true + + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -I/usr/include/nss -I/usr/include/nss3" + CFLAGS="$CFLAGS -I/usr/include/nspr -I/usr/include/nspr4" + AC_CHECK_HEADERS([nss/nss.h], [nss_inc_dir=/usr/include/nss], [ + AC_CHECK_HEADERS([nss3/nss.h], [nss_inc_dir=/usr/include/nss3], [ + enable_secure=false + if test "$do_secure" = "yes" + then + AC_MSG_ERROR(cannot enable secure sockets mode - no NSS header) + fi + ]) ]) - AC_CHECK_FILE([/usr/include/nspr4], nsprdir=nspr4, [ - AC_CHECK_FILE([/usr/include/nspr], nsprdir=nspr) + AC_CHECK_HEADERS([nspr/nspr.h], [nspr_inc_dir=/usr/include/nspr], [ + AC_CHECK_HEADERS([nspr4/nspr.h], [nspr_inc_dir=/usr/include/nspr4], [ + enable_secure=false + if test "$do_secure" = "yes" + then + AC_MSG_ERROR(cannot enable secure sockets mode - no NSPR header) + fi + ]) ]) - if test "x$nssdir" != "x" -a "x$nsprdir" != "x" - then - nss_inc_dir=/usr/include/$nssdir - nspr_inc_dir=/usr/include/$nsprdir - nss_incflags="-I$nss_inc_dir" - nspr_incflags="-I$nspr_inc_dir" - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$incflags $nss_incflags $nspr_incflags" - have_nss_includes=yes - AC_CHECK_HEADERS(["$nssdir/nss.h" "$nsprdir/nspr.h"], [], have_nss_includes=no) - CPPFLAGS="$save_CPPFLAGS" - have_nss_libs=no - AC_CHECK_LIB($nssdir, NSS_Init, [ - AC_CHECK_LIB($nsprdir, PR_Init, have_nss_libs=yes) - ]) - fi - if test "x${have_nss_includes}${have_nss_libs}" = "xyesyes" + AC_SUBST(nspr_inc_dir) + AC_SUBST(nss_inc_dir) + + AC_CHECK_LIB(nss, NSS_Init, [lib_for_nss="-lnss"], [ + AC_CHECK_LIB(nss3, NSS_Init, [lib_for_nss="-lnss3"], [ + enable_secure=false + if test "$do_secure" = "yes" + then + AC_MSG_ERROR(cannot enable secure sockets mode - no NSS library) + fi + ]) + ]) + AC_SUBST(lib_for_nss) + + AC_CHECK_LIB(nspr, PR_Init, [lib_for_nspr="-lnspr"], [ + AC_CHECK_LIB(nspr4, PR_Init, [lib_for_nspr="-lnspr4"], [ + enable_secure=false + if test "$do_secure" = "yes" + then + AC_MSG_ERROR(cannot enable secure sockets mode - no NSPR library) + fi + ]) + ]) + AC_SUBST(lib_for_nspr) + + if test "$enable_secure" = "true" then - have_nss=yes - else - if test "x${have_nss_includes}" != "xyes" - then - AC_MSG_WARN([NSS Headers not found]) - fi - if test "x${have_nss_libs}" != "xyes" - then - AC_MSG_WARN([NSS Libraries not found]) - fi + AC_DEFINE(HAVE_SECURE_SOCKETS) fi + CFLAGS="$saved_CFLAGS" fi -if test $have_nss = yes -then - lib_for_nss=-l$nssdir - lib_for_nspr=-l$nsprdir - AC_DEFINE(HAVE_NSS) -fi -AC_SUBST(nss_incflags) -AC_SUBST(nspr_incflags) -AC_SUBST(lib_for_nss) -AC_SUBST(lib_for_nspr) -pcp_nss_inc_dir=`eval echo $nss_inc_dir` -AC_SUBST(pcp_nss_inc_dir) -pcp_nspr_inc_dir=`eval echo $nspr_inc_dir` -AC_SUBST(pcp_nspr_inc_dir) dnl check for array sessions if test -f /usr/include/sn/arsess.h diff --git a/qa/src/chkacc1.c b/qa/src/chkacc1.c index 848c1de..4d1de2e 100644 --- a/qa/src/chkacc1.c +++ b/qa/src/chkacc1.c @@ -12,7 +12,7 @@ main() int s, sts, op, host; unsigned int i; char name[20]; - __pmInAddr inaddr; + struct __pmInAddr *inaddr; __pmIPAddr ipaddr; sts = 0; @@ -32,7 +32,7 @@ main() for (host = 0; host < WORD_BIT; host++) { sprintf(name, "155.%d.%d.%d", host * 3, 17+host, host); if ((s = __pmAccAddHost(name, 1 << host, 1 << host, 0)) < 0) { - printf("cant't add host for op%d: %s\n", host, strerror(s)); + printf("cannot add host for op%d: %s\n", host, strerror(s)); sts = s; } } @@ -42,11 +42,13 @@ main() putc('\n', stderr); __pmAccDumpHosts(stderr); + inaddr = __pmAllocInAddr(); for (host = 0; host < WORD_BIT; host++) { char buf[20]; + sprintf(buf, "%d.%d.%d.%d", 155, host * 3, 17+host, host); - __pmStringToInAddr(buf, &inaddr); - ipaddr = __pmInAddrToIPAddr(&inaddr); + __pmStringToInAddr(buf, inaddr); + ipaddr = __pmInAddrToIPAddr(inaddr); sts = __pmAccAddClient(ipaddr, &i); if (sts < 0) { printf("add client from host %d: %s\n", host, pmErrStr(sts)); @@ -57,6 +59,7 @@ main() host, i, 1 << host); } + __pmFreeInAddr(inaddr); putc('\n', stderr); __pmAccDumpHosts(stderr); diff --git a/qa/src/chkacc2.c b/qa/src/chkacc2.c index 72013d1..d79b723 100644 --- a/qa/src/chkacc2.c +++ b/qa/src/chkacc2.c @@ -16,7 +16,7 @@ main() int s, sts, op, host; unsigned int i; char name[20]; - __pmInAddr inaddr; + struct __pmInAddr *inaddr; __pmIPAddr ipaddr; sts = 0; @@ -32,7 +32,7 @@ main() for (host = 0; host < WORD_BIT; host++) { sprintf(name, "155.%d.%d.%d", host * 3, 17+host, host); if ((s = __pmAccAddHost(name, ~(1 << host), ~(1 << host), host)) < 0) { - printf("cant't add host for op%d: %s\n", host, strerror(s)); + printf("cannot add host for op%d: %s\n", host, strerror(s)); sts = s; } } @@ -42,14 +42,15 @@ main() putc('\n', stderr); __pmAccDumpHosts(stderr); + inaddr = __pmAllocInAddr(); for (host = 0; host < WORD_BIT; host++) { int j; for (j = 0; j <= host; j++) { char buf[20]; sprintf(buf, "%d.%d.%d.%d", 155, host * 3, 17+host, host); - __pmStringToInAddr(buf, &inaddr); - ipaddr = __pmInAddrToIPAddr(&inaddr); + __pmStringToInAddr(buf, inaddr); + ipaddr = __pmInAddrToIPAddr(inaddr); sts = __pmAccAddClient(ipaddr, &i); if (sts < 0) { if (j == host && sts == PM_ERR_CONNLIMIT) @@ -63,6 +64,7 @@ main() host, i, ~(1 << host)); } } + __pmFreeInAddr(inaddr); putc('\n', stderr); __pmAccDumpHosts(stderr); diff --git a/qa/src/chkacc3.c b/qa/src/chkacc3.c index 8e9b5c0..dce4976 100644 --- a/qa/src/chkacc3.c +++ b/qa/src/chkacc3.c @@ -20,7 +20,7 @@ main() unsigned int perm; char name[20]; char *wnames[4] = { "*", "38.*", "38.202.*", "38.202.16.*" }; - __pmInAddr inaddr; + struct __pmInAddr *inaddr; __pmIPAddr ipaddr; /* there are 10 ops numbered from 0 to 9 */ @@ -73,7 +73,7 @@ main() */ for (i = 0; i < 4; i++) { if ((s = __pmAccAddHost(wnames[i], 0x300, (i << 8), 0)) < 0) { - fprintf(stderr, "cant't add host for op%d: %s\n", i, strerror(s)); + fprintf(stderr, "cannot add host for op%d: %s\n", i, strerror(s)); sts = s; } } @@ -84,6 +84,8 @@ main() __pmAccDumpHosts(stderr); putc('\n', stderr); + inaddr = __pmAllocInAddr(); + for (i = 0; i < 2; i++) for (ai = 0; ai < 4; ai++) for (bi = 0; bi < 4; bi++) @@ -92,10 +94,10 @@ main() char buf[20]; char *host; sprintf(buf, "%d.%d.%d.%d", a[ai]+i, b[bi]+i, c[ci]+i, d[di]+i); - __pmStringToInAddr(buf, &inaddr); - ipaddr = __pmInAddrToIPAddr(&inaddr); + __pmStringToInAddr(buf, inaddr); + ipaddr = __pmInAddrToIPAddr(inaddr); s = __pmAccAddClient(ipaddr, &perm); - host = __pmInAddrToString(&inaddr); + host = __pmInAddrToString(inaddr); if (s < 0) { fprintf(stderr, "from %s error: %s\n", host, pmErrStr(s)); free(host); @@ -105,5 +107,6 @@ main() free(host); } + __pmFreeInAddr(inaddr); exit(0); } diff --git a/src/include/builddefs.in b/src/include/builddefs.in index a1aa2ee..9370fdc 100644 --- a/src/include/builddefs.in +++ b/src/include/builddefs.in @@ -109,23 +109,23 @@ ifeq "$(TARGET_OS)" "freebsd" DSOSUFFIX = so endif -NSS_CFLAGS = @nss_incflags@ -NSPR_CFLAGS = @nspr_incflags@ - CFLAGS_ABI = @cflags_abi@ CFLAGS += $(CFLAGS_ABI) $(PCFLAGS) $(LCFLAGS) $(WARN_OFF) -O2 -g -DPCP_DEBUG \ -DPCP_VERSION=\"$(PCP_VERSION)\" \ - -I$(TOPDIR)/src/include -I$(TOPDIR)/src/include/pcp $(NSS_CFLAGS) $(NSPR_CFLAGS) + -I$(TOPDIR)/src/include -I$(TOPDIR)/src/include/pcp PIECFLAGS = @PIECFLAGS@ PIELDFLAGS = @PIELDFLAGS@ +NSSCFLAGS = -I@nss_inc_dir@ +NSPRCFLAGS = -I@nspr_inc_dir@ + LDFLAGS += $(CFLAGS_ABI) $(PLDFLAGS) $(WARN_OFF) $(PCP_LIBS) $(LLDFLAGS) SRCFILES = GNUmakefile $(HFILES) $(CFILES) $(MFILES) \ $(LSRCFILES) $(LFILES) $(YFILES) $(PYFILES) -LDLIBS = $(LLDLIBS) $(PLDLIBS) $(LIB_FOR_NSS) $(LIB_FOR_NSPR) +LDLIBS = $(LLDLIBS) $(PLDLIBS) MAKEOPTS = --no-print-directory DIRT = $(LDIRT) dep dep.bak $(OBJECTS) $(CMDTARGET) \ $(LIBTARGET) $(STATICLIBTARGET) \ diff --git a/src/include/pcp/impl.h b/src/include/pcp/impl.h index c8c365b..bd080a2 100644 --- a/src/include/pcp/impl.h +++ b/src/include/pcp/impl.h @@ -53,14 +53,6 @@ #include #endif -/* - * Network Security Services (NSS) support - */ -#if defined(HAVE_NSS) -#include -#include -#endif - #ifdef __cplusplus extern "C" { #endif @@ -497,7 +489,6 @@ typedef struct { int pc_timeout; /* set if connect times out */ int pc_tout_sec; /* timeout for __pmGetPDU */ time_t pc_again; /* time to try again */ - struct sockaddr pc_addr; /* server address */ } __pmPMCDCtl; extern int __pmConnectPMCD(pmHostSpec *, int); @@ -510,26 +501,21 @@ extern void __pmDropHostPort(pmHostSpec *); extern void __pmConnectGetPorts(pmHostSpec *); /* SSL/TLS/IPv6 support via NSS/NSPR. */ -#ifdef HAVE_NSS -typedef PRNetAddr __pmSockAddr; -typedef PRNetAddr __pmSockAddrIn; -typedef PRNetAddr __pmInAddr; +#ifdef HAVE_SECURE_SOCKETS typedef unsigned long __pmIPAddr; -typedef PRHostEnt __pmHostEnt; typedef struct { fd_set native_set; fd_set nspr_set; int num_native_fds; int num_nspr_fds; } __pmFdSet; -#else /* ! HAVE_NSS */ -typedef struct sockaddr __pmSockAddr; -typedef struct sockaddr_in __pmSockAddrIn; -typedef struct in_addr __pmInAddr; +#else typedef unsigned int __pmIPAddr; -typedef struct hostent __pmHostEnt; typedef fd_set __pmFdSet; #endif +struct __pmInAddr; +struct __pmHostEnt; +struct __pmSockAddrIn; extern int __pmCreateSocket(void); extern int __pmInitSocket(int); @@ -543,7 +529,7 @@ extern int __pmListen(int, int); extern int __pmAccept(int, void *, __pmSockLen *); extern ssize_t __pmSend(int, const void *, size_t, int); extern ssize_t __pmRecv(int, void *, size_t, int); -extern int __pmConnectTo(int, const __pmSockAddrIn *, int); +extern int __pmConnectTo(int, const struct __pmSockAddrIn *, int); extern int __pmConnectCheckError(int); extern int __pmConnectRestoreFlags(int, int); extern int __pmConnectHandshake(int); @@ -561,27 +547,33 @@ extern void __pmFD_COPY(__pmFdSet *, const __pmFdSet *); extern int __pmSelectRead(int, __pmFdSet *, struct timeval *); extern int __pmSelectWrite(int, __pmFdSet *, struct timeval *); -extern void __pmInitSockAddr(__pmSockAddrIn *, int, int); -extern void __pmSetSockAddr(__pmSockAddrIn *, __pmHostEnt *); -extern void __pmSetPort(__pmSockAddrIn *, int); +extern struct __pmSockAddrIn *__pmAllocSockAddrIn(void); +extern size_t __pmSockAddrInSize(void); +extern void __pmFreeSockAddrIn(struct __pmSockAddrIn *); +extern void __pmInitSockAddr(struct __pmSockAddrIn *, int, int); +extern void __pmSetSockAddr(struct __pmSockAddrIn *, struct __pmHostEnt *); +extern void __pmSetPort(struct __pmSockAddrIn *, int); extern void __pmSetIPAddr (__pmIPAddr *, unsigned int); extern __pmIPAddr *__pmMaskIPAddr(__pmIPAddr *, const __pmIPAddr *); extern int __pmCompareIPAddr (const __pmIPAddr *, const __pmIPAddr *); extern int __pmIPAddrIsLoopBack(const __pmIPAddr *); extern __pmIPAddr __pmLoopbackAddress(void); -extern __pmIPAddr __pmSockAddrInToIPAddr(const __pmSockAddrIn *); -extern __pmIPAddr __pmInAddrToIPAddr(const __pmInAddr *); +extern struct __pmInAddr *__pmAllocInAddr(void); +extern void __pmFreeInAddr(struct __pmInAddr *); +extern __pmIPAddr __pmSockAddrInToIPAddr(const struct __pmSockAddrIn *); +extern __pmIPAddr __pmInAddrToIPAddr(const struct __pmInAddr *); extern int __pmIPAddrToInt(const __pmIPAddr *); -extern char *__pmInAddrToString(__pmInAddr *); -extern char *__pmSockAddrInToString(__pmSockAddrIn *); -extern int __pmStringToInAddr(const char *, __pmInAddr *); +extern char *__pmInAddrToString(struct __pmInAddr *); +extern char *__pmSockAddrInToString(struct __pmSockAddrIn *); +extern int __pmStringToInAddr(const char *, struct __pmInAddr *); -extern char *__pmAllocHostEntBuffer (void); -extern void __pmFreeHostEntBuffer (char *); -extern __pmHostEnt *__pmGetHostByName(const char *, __pmHostEnt *, char *); -extern __pmHostEnt *__pmGetHostByAddr(__pmSockAddrIn *, __pmHostEnt *, char *); -extern __pmIPAddr __pmHostEntGetIPAddr(const __pmHostEnt *, int); +extern struct __pmHostEnt *__pmAllocHostEnt(void); +extern void __pmFreeHostEnt(struct __pmHostEnt *); +extern char *__pmHostEntName(const struct __pmHostEnt *); +extern struct __pmHostEnt *__pmGetHostByName(const char *, struct __pmHostEnt *); +extern struct __pmHostEnt *__pmGetHostByAddr(struct __pmSockAddrIn *, struct __pmHostEnt *); +extern __pmIPAddr __pmHostEntGetIPAddr(const struct __pmHostEnt *, int); /* * per context controls for archives and logs @@ -983,16 +975,14 @@ typedef int (*__pmConnectHostType)(int, int); extern int __pmSetSocketIPC(int); extern int __pmSetVersionIPC(int, int); +extern int __pmSetDataIPC(int, void *); extern int __pmLastVersionIPC(); extern int __pmVersionIPC(int); extern int __pmSocketIPC(int); +extern void *__pmDataIPC(int); extern void __pmOverrideLastFd(int); extern void __pmPrintIPC(void); extern void __pmResetIPC(int); -#if defined(HAVE_NSS) -extern int __pmSetNSPRFdIPC(int fd, PRFileDesc *); -extern PRFileDesc *__pmNSPRFdIPC(int); -#endif /* safely insert an atom value into a pmValue */ extern int __pmStuffValue(const pmAtomValue *, pmValue *, int); diff --git a/src/include/pcp/platform_header.h.in b/src/include/pcp/platform_header.h.in index 3f25c8c..a79342d 100644 --- a/src/include/pcp/platform_header.h.in +++ b/src/include/pcp/platform_header.h.in @@ -137,7 +137,6 @@ extern "C" { #undef HAVE_SYS_ENDIAN_H #undef HAVE_SYS_MACHINE_H #undef HAVE_MACHINE_ENDIAN_H -#undef HAVE_READLINE #if defined(HAVE_MALLOC_H) #include @@ -190,7 +189,9 @@ extern "C" { #endif /* define which libraries are available */ +#undef HAVE_SECURE_SOCKETS #undef HAVE_LIBREGEX +#undef HAVE_READLINE /* define which libc functions are available */ #undef HAVE_WAIT3 diff --git a/src/libpcp/src/GNUmakefile b/src/libpcp/src/GNUmakefile index 18adb88..596f60d 100644 --- a/src/libpcp/src/GNUmakefile +++ b/src/libpcp/src/GNUmakefile @@ -49,6 +49,15 @@ LLDLIBS += $(LIB_FOR_MATH) $(LIB_FOR_PTHREADS) LCFLAGS += -DLIBPCP_INTERNAL '-DEXEC_SUFFIX="$(EXECSUFFIX)"' \ '-DDSO_SUFFIX="$(DSOSUFFIX)"' +ifneq "$(LIB_FOR_NSS)" "" +LCFLAGS += $(NSSCFLAGS) +LLDLIBS += $(LIB_FOR_NSS) +endif +ifneq "$(LIB_FOR_NSPR)" "" +LCFLAGS += $(NSPRCFLAGS) +LLDLIBS += $(LIB_FOR_NSPR) +endif + DSOVERSION = 3 STATICLIBTARGET = libpcp.a LIBTARGET = libpcp.$(DSOSUFFIX).$(DSOVERSION) diff --git a/src/libpcp/src/access.c b/src/libpcp/src/access.c index e95491c..e76c748 100644 --- a/src/libpcp/src/access.c +++ b/src/libpcp/src/access.c @@ -85,24 +85,23 @@ static char myhostname[MAXHOSTNAMELEN+1]; static int getmyhostid(void) { - __pmHostEnt he; - char *hebuf; + struct __pmHostEnt *host; (void)gethostname(myhostname, MAXHOSTNAMELEN); myhostname[MAXHOSTNAMELEN-1] = '\0'; + host = __pmAllocHostEnt(); PM_LOCK(__pmLock_libpcp); - hebuf = __pmAllocHostEntBuffer(); - if (__pmGetHostByName(myhostname, &he, hebuf) == NULL) { + if (__pmGetHostByName(myhostname, host) == NULL) { __pmNotifyErr(LOG_ERR, "__pmGetHostByName(%s), %s\n", myhostname, hoststrerror()); - __pmFreeHostEntBuffer(hebuf); PM_UNLOCK(__pmLock_libpcp); + __pmFreeHostEnt(host); return -1; } - myhostid = __pmHostEntGetIPAddr(&he, 0); - __pmFreeHostEntBuffer(hebuf); + myhostid = __pmHostEntGetIPAddr(host, 0); PM_UNLOCK(__pmLock_libpcp); + __pmFreeHostEnt(host); gotmyhostid = 1; return 0; } @@ -228,8 +227,7 @@ __pmAccAddHost(const char *name, unsigned int specOps, unsigned int denyOps, int size_t need; int i, n, sts; unsigned int ip, mask; - __pmHostEnt he; - char * hebuf; + struct __pmHostEnt *host; int level = 0; /* Wildcarding level */ __pmIPAddr hostid, hostmask; const char *p; @@ -311,19 +309,19 @@ __pmAccAddHost(const char *name, unsigned int specOps, unsigned int denyOps, int } else realname = name; + host = __pmAllocHostEnt(); PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); - hebuf = __pmAllocHostEntBuffer(); - if (__pmGetHostByName(realname, &he, hebuf) == NULL) { + if (__pmGetHostByName(realname, host) == NULL) { __pmNotifyErr(LOG_ERR, "__pmGetHostByName(%s), %s\n", realname, hoststrerror()); - __pmFreeHostEntBuffer(hebuf); PM_UNLOCK(__pmLock_libpcp); + __pmFreeHostEnt(host); return -EHOSTUNREACH; /* host error unsuitable to return */ } - hostid = __pmHostEntGetIPAddr(&he, 0); - __pmFreeHostEntBuffer(hebuf); + hostid = __pmHostEntGetIPAddr(host, 0); PM_UNLOCK(__pmLock_libpcp); + __pmFreeHostEnt(host); __pmSetIPAddr(&hostmask, 0xffffffff); level = 0; } diff --git a/src/libpcp/src/auxconnect.c b/src/libpcp/src/auxconnect.c index b69ba57..7838bbc 100644 --- a/src/libpcp/src/auxconnect.c +++ b/src/libpcp/src/auxconnect.c @@ -15,15 +15,82 @@ #include "pmapi.h" #include "impl.h" -#include -#include -#ifdef HAVE_NETINET_TCP_H -#include + +/* + * Network Security Services (NSS) support + */ +#ifdef HAVE_SECURE_SOCKETS +#include +#include +#include + +struct __pmSockAddrIn { + PRNetAddr sockaddr; +}; +struct __pmInAddr { + PRNetAddr inaddr; +}; +struct __pmHostEnt { + PRHostEnt hostent; + char buffer[PR_NETDB_BUF_SIZE]; +}; +#else /* ! HAVE_SECURE_SOCKETS */ +struct __pmSockAddrIn { + struct sockaddr_in sockaddr; +}; +struct __pmInAddr { + struct in_addr inaddr; +}; +struct __pmHostEnt { + struct hostent hostent; +}; #endif /* default connect timeout is 5 seconds */ static struct timeval canwait = { 5, 000000 }; +struct __pmHostEnt * +__pmAllocHostEnt(void) +{ + return malloc(sizeof(struct __pmHostEnt)); +} + +void +__pmFreeHostEnt(struct __pmHostEnt *hostent) +{ + free(hostent); +} + +struct __pmInAddr * +__pmAllocInAddr(void) +{ + return malloc(sizeof(struct __pmInAddr)); +} + +void +__pmFreeInAddr(struct __pmInAddr *inaddr) +{ + free(inaddr); +} + +struct __pmSockAddrIn * +__pmAllocSockAddrIn(void) +{ + return malloc(sizeof(struct __pmSockAddrIn)); +} + +size_t +__pmSockAddrInSize(void) +{ + return sizeof(struct __pmSockAddrIn); +} + +void +__pmFreeSockAddrIn(struct __pmSockAddrIn *sockaddr) +{ + free(sockaddr); +} + int __pmInitSocket(int fd) { @@ -57,10 +124,10 @@ __pmInitSocket(int fd) } int -__pmConnectTo(int fd, const __pmSockAddrIn *addr, int port) +__pmConnectTo(int fd, const struct __pmSockAddrIn *addr, int port) { int sts, fdFlags = __pmGetFileStatusFlags(fd); - __pmSockAddrIn myAddr; + struct __pmSockAddrIn myAddr; myAddr = *addr; __pmSetPort(&myAddr, port); @@ -206,24 +273,25 @@ __pmAuxConnectPMCD(const char *hostname) int __pmAuxConnectPMCDPort(const char *hostname, int pmcd_port) { - __pmSockAddrIn myAddr; - __pmHostEnt servInfo; - char *sibuf; + struct __pmSockAddrIn myAddr; + struct __pmHostEnt *servInfo; int fd; /* Fd for socket connection to pmcd */ int sts; int fdFlags; + if ((servInfo = __pmAllocHostEnt()) == NULL) + return -ENOMEM; + PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); - sibuf = __pmAllocHostEntBuffer(); - if (__pmGetHostByName(hostname, &servInfo, sibuf) == NULL) { + if (__pmGetHostByName(hostname, servInfo) == NULL) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_CONTEXT) { fprintf(stderr, "__pmAuxConnectPMCDPort(%s, %d) : hosterror=%d, ``%s''\n", hostname, pmcd_port, hosterror(), hoststrerror()); } #endif - __pmFreeHostEntBuffer(sibuf); + __pmFreeHostEnt(servInfo); PM_UNLOCK(__pmLock_libpcp); return -EHOSTUNREACH; } @@ -231,14 +299,14 @@ __pmAuxConnectPMCDPort(const char *hostname, int pmcd_port) __pmConnectTimeout(); if ((fd = __pmCreateSocket()) < 0) { - __pmFreeHostEntBuffer(sibuf); + __pmFreeHostEnt(servInfo); PM_UNLOCK(__pmLock_libpcp); return fd; } __pmInitSockAddr(&myAddr, htonl(INADDR_ANY), 0); - __pmSetSockAddr(&myAddr, &servInfo); - __pmFreeHostEntBuffer(sibuf); + __pmSetSockAddr(&myAddr, servInfo); + __pmFreeHostEnt(servInfo); PM_UNLOCK(__pmLock_libpcp); if ((fdFlags = __pmConnectTo(fd, &myAddr, pmcd_port)) >= 0) { @@ -276,7 +344,7 @@ __pmAuxConnectPMCDPort(const char *hostname, int pmcd_port) return fdFlags; } -#if !defined(HAVE_NSS) +#if !defined(HAVE_SECURE_SOCKETS) int __pmCreateSocket(void) @@ -316,24 +384,24 @@ __pmGetSockOpt(int socket, int level, int option_name, void *option_value, } void -__pmInitSockAddr(__pmSockAddrIn *addr, int address, int port) +__pmInitSockAddr(struct __pmSockAddrIn *addr, int address, int port) { memset(addr, 0, sizeof(*addr)); - addr->sin_family = AF_INET; - addr->sin_addr.s_addr = address; - addr->sin_port = port; + addr->sockaddr.sin_family = AF_INET; + addr->sockaddr.sin_addr.s_addr = address; + addr->sockaddr.sin_port = port; } void -__pmSetSockAddr(__pmSockAddrIn *addr, __pmHostEnt *he) +__pmSetSockAddr(struct __pmSockAddrIn *addr, struct __pmHostEnt *he) { - memcpy(&addr->sin_addr, he->h_addr, he->h_length); + memcpy(&addr->sockaddr.sin_addr, he->hostent.h_addr, he->hostent.h_length); } void -__pmSetPort(__pmSockAddrIn *addr, int port) +__pmSetPort(struct __pmSockAddrIn *addr, int port) { - addr->sin_port = htons(port); + addr->sockaddr.sin_port = htons(port); } int @@ -439,42 +507,37 @@ __pmSelectWrite(int nfds, __pmFdSet *writefds, struct timeval *timeout) } char * -__pmAllocHostEntBuffer(void) +__pmHostEntName(const struct __pmHostEnt *hostEntry) { - return NULL; + return hostEntry->hostent.h_name; } -void -__pmFreeHostEntBuffer(char *buffer) +struct __pmHostEnt * +__pmGetHostByName(const char *hostName, struct __pmHostEnt *hostEntry) { - /* No buffer was actually allocated. Our work here is done. */ -} - -__pmHostEnt * -__pmGetHostByName(const char *hostName, __pmHostEnt *hostEntry, char *buffer) -{ - __pmHostEnt *he = gethostbyname(hostName); + struct hostent *he = gethostbyname(hostName); if (he == NULL) return NULL; - *hostEntry = *he; + memcpy(&hostEntry->hostent, he, sizeof(*he)); return hostEntry; } -__pmHostEnt * -__pmGetHostByAddr(__pmSockAddrIn *address, __pmHostEnt *hostEntry, char *buffer) +struct __pmHostEnt * +__pmGetHostByAddr(struct __pmSockAddrIn *address, struct __pmHostEnt *hostEntry) { - __pmHostEnt *he = gethostbyaddr((void *)&address->sin_addr.s_addr, sizeof(address->sin_addr.s_addr), AF_INET); + struct hostent *he = gethostbyaddr((void *)&address->sockaddr.sin_addr.s_addr, + sizeof(address->sockaddr.sin_addr.s_addr), AF_INET); if (he == NULL) return NULL; - *hostEntry = *he; + memcpy(&hostEntry->hostent, he, sizeof(*he)); return hostEntry; } __pmIPAddr -__pmHostEntGetIPAddr(const __pmHostEnt *he, int ix) +__pmHostEntGetIPAddr(const struct __pmHostEnt *he, int ix) { - return ((struct in_addr *)he->h_addr_list[ix])->s_addr; + return ((struct in_addr *)he->hostent.h_addr_list[ix])->s_addr; } void @@ -509,15 +572,15 @@ __pmLoopbackAddress(void) } __pmIPAddr -__pmSockAddrInToIPAddr(const __pmSockAddrIn *inaddr) +__pmSockAddrInToIPAddr(const struct __pmSockAddrIn *inaddr) { - return __pmInAddrToIPAddr(&inaddr->sin_addr); + return inaddr->sockaddr.sin_addr.s_addr; } __pmIPAddr -__pmInAddrToIPAddr(const __pmInAddr *inaddr) +__pmInAddrToIPAddr(const struct __pmInAddr *inaddr) { - return inaddr->s_addr; + return inaddr->inaddr.s_addr; } int @@ -531,9 +594,9 @@ __pmIPAddrToInt(const __pmIPAddr *addr) * The caller must free the buffer. */ char * -__pmInAddrToString(__pmInAddr *address) +__pmInAddrToString(struct __pmInAddr *address) { - char *buf = inet_ntoa(*address); + char *buf = inet_ntoa(address->inaddr); if (buf == NULL) return NULL; @@ -541,7 +604,7 @@ __pmInAddrToString(__pmInAddr *address) } int -__pmStringToInAddr(const char *cp, __pmInAddr *inp) +__pmStringToInAddr(const char *cp, struct __pmInAddr *inp) { #ifdef IS_MINGW unsigned long in; @@ -549,14 +612,14 @@ __pmStringToInAddr(const char *cp, __pmInAddr *inp) inaddr.s_addr = in; return in == INADDR_NONE ? 0 : 1; #else - return inet_aton(cp, inp); + return inet_aton(cp, &inp->inaddr); #endif } char * -__pmSockAddrInToString(__pmSockAddrIn *address) +__pmSockAddrInToString(struct __pmSockAddrIn *address) { - return __pmInAddrToString(&address->sin_addr); + return __pmInAddrToString((struct __pmInAddr *)&address->sockaddr.sin_addr); } #else /* NSS */ @@ -627,7 +690,7 @@ __pmCreateSocket(void) return -neterror(); fd = newNSPRHandle(); - __pmSetNSPRFdIPC(fd, nsprFd); /* Must be before __pmInitSocket */ + __pmSetDataIPC(fd, nsprFd); /* Must be before __pmInitSocket */ if ((sts = __pmInitSocket(fd)) < 0) return sts; @@ -638,7 +701,7 @@ __pmCreateSocket(void) void __pmCloseSocket(int fd) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); __pmResetIPC(fd); if (nsprFd) { @@ -675,7 +738,7 @@ __pmSetSockOpt(int socket, int level, int option_name, const void *option_value, /* Map the request to the NSPR equivalent, if possible. */ PRSocketOptionData odata; PRStatus prStatus; - PRFileDesc *nsprFd = __pmNSPRFdIPC(socket); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(socket); if (nsprFd) { switch(level) { @@ -736,11 +799,11 @@ int __pmGetSockOpt(int socket, int level, int option_name, void *option_value, __pmSockLen *option_len) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(socket); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(socket); /* Map the request to the NSPR equivalent, if possible. */ if (nsprFd) { - switch(level) { + switch (level) { case SOL_SOCKET: switch(option_name) { case SO_ERROR: { @@ -767,44 +830,46 @@ __pmGetSockOpt(int socket, int level, int option_name, void *option_value, } void -__pmInitSockAddr(__pmSockAddrIn *addr, int address, int port) +__pmInitSockAddr(struct __pmSockAddrIn *addr, int address, int port) { + PRStatus prStatus = PR_InitializeNetAddr (PR_IpAddrNull, ntohs(port), &addr->sockaddr); /* We expect the address and port number to be on network byte order. PR_InitializeNetAddr expects the port in host byte order. The ip field of __pmSockAddrIn (PRNetAddr) must be in network byte order. */ - PRStatus prStatus = PR_InitializeNetAddr (PR_IpAddrNull, ntohs(port), addr); + if (prStatus != PR_SUCCESS) __pmNotifyErr(LOG_ERR, "__pmInitSockAddr: PR_InitializeNetAddr failure: %d\n", PR_GetError()); - addr->inet.ip = address; + addr->sockaddr.inet.ip = address; } void -__pmSetSockAddr(__pmSockAddrIn *addr, __pmHostEnt *he) +__pmSetSockAddr(struct __pmSockAddrIn *addr, struct __pmHostEnt *he) { PRUint16 port = 0; /* The port in the address is in network byte forder, but PR_EnumerateHostEnt expects it in host byte order. */ - if (addr->raw.family == PR_AF_INET) - port = ntohs(addr->inet.port); - else if (addr->raw.family == PR_AF_INET6) - port = ntohs(addr->ipv6.port); - PR_EnumerateHostEnt(0, he, port, addr); + if (addr->sockaddr.raw.family == PR_AF_INET) + port = ntohs(addr->sockaddr.inet.port); + else if (addr->sockaddr.raw.family == PR_AF_INET6) + port = ntohs(addr->sockaddr.ipv6.port); + PR_EnumerateHostEnt(0, &he->hostent, port, &addr->sockaddr); } void -__pmSetPort(__pmSockAddrIn *addr, int port) +__pmSetPort(struct __pmSockAddrIn *addr, int port) { - if (addr->raw.family == PR_AF_INET) - addr->inet.port = htons(port); - else if (addr->raw.family == PR_AF_INET6) - addr->ipv6.port = htons(port); + if (addr->sockaddr.raw.family == PR_AF_INET) + addr->sockaddr.inet.port = htons(port); + else if (addr->sockaddr.raw.family == PR_AF_INET6) + addr->sockaddr.ipv6.port = htons(port); } int __pmListen(int fd, int backlog) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); + if (nsprFd) { PRStatus prStatus; prStatus = PR_Listen(nsprFd, backlog); @@ -818,15 +883,15 @@ __pmListen(int fd, int backlog) int __pmAccept(int fd, void *addr, __pmSockLen *addrlen) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); if (nsprFd) { PRFileDesc *newSocket; - newSocket = PR_Accept(nsprFd, (PRNetAddr *)addr, PR_INTERVAL_NO_TIMEOUT); + newSocket = PR_Accept(nsprFd, addr, PR_INTERVAL_NO_TIMEOUT); if (newSocket == NULL) return -1; /* Add the accepted socket to the fd table. */ fd = newNSPRHandle(); - __pmSetNSPRFdIPC(fd, newSocket); + __pmSetDataIPC(fd, newSocket); return fd; } @@ -837,7 +902,8 @@ __pmAccept(int fd, void *addr, __pmSockLen *addrlen) int __pmBind(int fd, void *addr, __pmSockLen addrlen) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); + if (nsprFd) { PRStatus prStatus; prStatus = PR_Bind(nsprFd, (PRNetAddr *)addr); @@ -851,7 +917,7 @@ __pmBind(int fd, void *addr, __pmSockLen addrlen) int __pmConnect(int fd, void *addr, __pmSockLen addrlen) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); if (nsprFd) { PRStatus prStatus; prStatus = PR_Connect(nsprFd, (PRNetAddr *)addr, PR_INTERVAL_NO_TIMEOUT); @@ -865,7 +931,8 @@ __pmConnect(int fd, void *addr, __pmSockLen addrlen) int __pmGetFileStatusFlags(int fd) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); + if (nsprFd) { /* There is no direct mapping of this function in NSPR. The best we can do is to use the native fd and call fcntl on that handle. */ @@ -877,7 +944,8 @@ __pmGetFileStatusFlags(int fd) int __pmSetFileStatusFlags(int fd, int flags) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); + if (nsprFd) { /* There is no direct mapping of this function in NSPR. The best we can do is to use the native fd and call fcntl on that handle. */ @@ -889,7 +957,7 @@ __pmSetFileStatusFlags(int fd, int flags) int __pmGetFileDescriptorFlags(int fd) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); if (nsprFd) { /* There is no direct mapping of this function in NSPR. The best we can do is to use the native fd and call fcntl on that handle. */ @@ -901,7 +969,8 @@ __pmGetFileDescriptorFlags(int fd) int __pmSetFileDescriptorFlags(int fd, int flags) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); + if (nsprFd) { /* There is no direct mapping of this function in NSPR. The best we can do is to use the native fd and call fcntl on that handle. */ @@ -914,7 +983,8 @@ ssize_t __pmSend(int socket, const void *buffer, size_t length, int flags) { /* Map the request to the NSPR equivalent, if possible. */ - PRFileDesc *nsprFd = __pmNSPRFdIPC(socket); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(socket); + if (nsprFd) { return PR_Write (nsprFd, buffer, length); } @@ -927,7 +997,8 @@ ssize_t __pmRecv(int socket, void *buffer, size_t length, int flags) { /* Map the request to the NSPR equivalent, if possible. */ - PRFileDesc *nsprFd = __pmNSPRFdIPC(socket); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(socket); + if (nsprFd) { return PR_Read (nsprFd, buffer, length); } @@ -939,7 +1010,8 @@ __pmRecv(int socket, void *buffer, size_t length, int flags) void __pmFD_CLR(int fd, __pmFdSet *set) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); + if (nsprFd) { fd -= NSPR_HANDLE_BASE; FD_CLR(fd, &set->nspr_set); @@ -968,7 +1040,8 @@ __pmFD_CLR(int fd, __pmFdSet *set) int __pmFD_ISSET(int fd, __pmFdSet *set) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); + if (nsprFd) { fd -= NSPR_HANDLE_BASE; return FD_ISSET(fd, &set->nspr_set); @@ -979,7 +1052,8 @@ __pmFD_ISSET(int fd, __pmFdSet *set) void __pmFD_SET(int fd, __pmFdSet *set) { - PRFileDesc *nsprFd = __pmNSPRFdIPC(fd); + PRFileDesc *nsprFd = (PRFileDesc *)__pmDataIPC(fd); + if (nsprFd) { fd -= NSPR_HANDLE_BASE; FD_SET(fd, &set->nspr_set); @@ -1037,7 +1111,7 @@ nsprSelect(int rwflag, __pmFdSet *fds, struct timeval *timeout) /* Now add the native fds associated with the NSPR fds in nspr_set, if any. */ for (fd = 0; fd < fds->num_nspr_fds; ++fd) { if (FD_ISSET(fd, &fds->nspr_set)) { - nsprFD = __pmNSPRFdIPC(NSPR_HANDLE_BASE + fd); + nsprFD = (PRFileDesc *)__pmDataIPC(NSPR_HANDLE_BASE + fd); nativeFD = PR_FileDesc2NativeHandle(nsprFD); FD_SET(nativeFD, &combined); if (nativeFD >= numCombined) @@ -1060,7 +1134,7 @@ nsprSelect(int rwflag, __pmFdSet *fds, struct timeval *timeout) /* Separate the results into their corresponding sets again. */ for (fd = 0; fd < fds->num_nspr_fds; ++fd) { if (FD_ISSET(fd, &fds->nspr_set)) { - nsprFD = __pmNSPRFdIPC(NSPR_HANDLE_BASE + fd); + nsprFD = (PRFileDesc *)__pmDataIPC(NSPR_HANDLE_BASE + fd); nativeFD = PR_FileDesc2NativeHandle(nsprFD); /* As we copy the result to the nspr set, make sure the bit is cleared in the @@ -1097,44 +1171,35 @@ __pmSelectWrite(int nfds, __pmFdSet *writefds, struct timeval *timeout) } char * -__pmAllocHostEntBuffer(void) +__pmHostEntName(const struct __pmHostEnt *he) { - char *buffer = malloc(PR_NETDB_BUF_SIZE); - if (buffer == NULL) - __pmNoMem("__pmAllocHostEntBuffer", PR_NETDB_BUF_SIZE, PM_FATAL_ERR); - return buffer; + return he->hostent.h_name; } -void -__pmFreeHostEntBuffer(char *buffer) +struct __pmHostEnt * +__pmGetHostByName(const char *hostName, struct __pmHostEnt *he) { - free(buffer); + PRStatus prStatus = PR_GetHostByName(hostName, &he->buffer[0], PR_NETDB_BUF_SIZE, &he->hostent); + return prStatus == PR_SUCCESS ? he : NULL; } -__pmHostEnt * -__pmGetHostByName(const char *hostName, __pmHostEnt *hostEntry, char *buffer) +struct __pmHostEnt * +__pmGetHostByAddr(struct __pmSockAddrIn *address, struct __pmHostEnt *he) { - PRStatus prStatus = PR_GetHostByName(hostName, buffer, PR_NETDB_BUF_SIZE, hostEntry); - return prStatus == PR_SUCCESS ? hostEntry : NULL; -} - -__pmHostEnt * -__pmGetHostByAddr(__pmSockAddrIn *address, __pmHostEnt *hostEntry, char *buffer) -{ - PRStatus prStatus = PR_GetHostByAddr(address, buffer, PR_NETDB_BUF_SIZE, hostEntry); - return prStatus == PR_SUCCESS ? hostEntry : NULL; + PRStatus prStatus = PR_GetHostByAddr(&address->sockaddr, &he->buffer[0], PR_NETDB_BUF_SIZE, &he->hostent); + return prStatus == PR_SUCCESS ? he : NULL; } __pmIPAddr -__pmHostEntGetIPAddr(const __pmHostEnt *he, int ix) +__pmHostEntGetIPAddr(const struct __pmHostEnt *he, int ix) { PRNetAddr address; - PRIntn rc = PR_EnumerateHostEnt(0, he, 0, &address); + PRIntn rc = PR_EnumerateHostEnt(0, &he->hostent, 0, &address); if (rc < 0) { __pmNotifyErr(LOG_ERR, "__pmHostEntGetIPAddr: unable to obtain host address\n"); return 0; } - return __pmInAddrToIPAddr(&address); + return address.inet.ip; } void @@ -1169,15 +1234,15 @@ __pmLoopbackAddress(void) } __pmIPAddr -__pmSockAddrInToIPAddr(const __pmSockAddrIn *inaddr) +__pmSockAddrInToIPAddr(const struct __pmSockAddrIn *inaddr) { - return __pmInAddrToIPAddr(inaddr); + return inaddr->sockaddr.inet.ip; } __pmIPAddr -__pmInAddrToIPAddr(const __pmInAddr *inaddr) +__pmInAddrToIPAddr(const struct __pmInAddr *inaddr) { - return inaddr->inet.ip; + return inaddr->inaddr.inet.ip; } int @@ -1193,31 +1258,32 @@ __pmIPAddrToInt(const __pmIPAddr *addr) #define PM_NET_ADDR_STRING_SIZE 46 /* from the NSPR API reference */ char * -__pmInAddrToString(__pmInAddr *address) +__pmInAddrToString(struct __pmInAddr *address) { - PRStatus prStatus; - char *buf = malloc(PM_NET_ADDR_STRING_SIZE); - if (buf == NULL) - return strdup("unknown"); - prStatus = PR_NetAddrToString(address, buf, PM_NET_ADDR_STRING_SIZE); - if (prStatus != PR_SUCCESS) { - free(buf); - return NULL; - } - return buf; + PRStatus prStatus; + char *buf = malloc(PM_NET_ADDR_STRING_SIZE); + + if (buf == NULL) + return strdup("unknown"); + prStatus = PR_NetAddrToString(&address->inaddr, buf, PM_NET_ADDR_STRING_SIZE); + if (prStatus != PR_SUCCESS) { + free(buf); + return NULL; + } + return buf; } int -__pmStringToInAddr(const char *cp, __pmInAddr *inp) +__pmStringToInAddr(const char *cp, struct __pmInAddr *inp) { - PRStatus prStatus = PR_StringToNetAddr(cp, inp); - return prStatus == PR_SUCCESS ? 1 : 0; + PRStatus prStatus = PR_StringToNetAddr(cp, &inp->inaddr); + return prStatus == PR_SUCCESS ? 1 : 0; } char * -__pmSockAddrInToString(__pmSockAddrIn *address) +__pmSockAddrInToString(struct __pmSockAddrIn *address) { - return __pmInAddrToString(address); + return __pmInAddrToString((struct __pmInAddr *)address); } -#endif /* NSS */ +#endif /* HAVE_SECURE_SOCKETS */ diff --git a/src/libpcp/src/ipc.c b/src/libpcp/src/ipc.c index 797ffac..25db17e 100644 --- a/src/libpcp/src/ipc.c +++ b/src/libpcp/src/ipc.c @@ -33,14 +33,13 @@ * * If NSS/NSPR is available, then we also keep NSPR file descriptor information * here. This allows us to handle NSPR sockets which in turn allows us to support - * SSL/TLS. + * SSL/TLS. This is handled through an opaque pointer, to restrict the footprint + * of including NSS/NSPR types (include files). */ typedef struct { int version; /* one or two */ int socket; /* true or false */ -#if defined(HAVE_NSS) - PRFileDesc *nsprFD; -#endif + void *data; /* an opaque pointer */ } __pmIPC; static int __pmLastUsedFd = -INT_MAX; @@ -174,14 +173,13 @@ __pmSocketIPC(int fd) return sts; } -#if defined(HAVE_NSS) int -__pmSetNSPRFdIPC(int fd, PRFileDesc *nsprFD) +__pmSetDataIPC(int fd, void *data) { - int sts; + int sts; if (pmDebug & DBG_TRACE_CONTEXT) - fprintf(stderr, "__pmSetSocketIPC: fd=%d\n", fd); + fprintf(stderr, "__pmSetDataIPC: fd=%d data=%p\n", fd, data); PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); @@ -190,7 +188,7 @@ __pmSetNSPRFdIPC(int fd, PRFileDesc *nsprFD) return sts; } - __pmIPCTablePtr[fd].nsprFD = nsprFD; + __pmIPCTablePtr[fd].data = data; __pmLastUsedFd = fd; if (pmDebug & DBG_TRACE_CONTEXT) @@ -200,23 +198,22 @@ __pmSetNSPRFdIPC(int fd, PRFileDesc *nsprFD) return sts; } -PRFileDesc * -__pmNSPRFdIPC(int fd) +void * +__pmDataIPC(int fd) { - PRFileDesc *sts; + void *data; PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); if (__pmIPCTablePtr == NULL || fd < 0 || fd >= ipctablesize) { PM_UNLOCK(__pmLock_libpcp); - return 0; + return NULL; } - sts = __pmIPCTablePtr[fd].nsprFD; + data = __pmIPCTablePtr[fd].data; PM_UNLOCK(__pmLock_libpcp); - return sts; + return data; } -#endif /* defined(HAVE_NSS) */ /* * Called by log readers who need version info for result decode, diff --git a/src/libpcp/src/logconnect.c b/src/libpcp/src/logconnect.c index 283750e..de08d34 100644 --- a/src/libpcp/src/logconnect.c +++ b/src/libpcp/src/logconnect.c @@ -74,9 +74,8 @@ __pmConnectLogger(const char *hostname, int *pid, int *port) { int n, sts; __pmLogPort *lpp; - __pmSockAddrIn myAddr; - __pmHostEnt servinfo; - char *servbuf; + struct __pmSockAddrIn *myAddr; + struct __pmHostEnt *servInfo; int fd; /* Fd for socket connection to pmcd */ __pmPDU *pb; __pmPDUHdr *php; @@ -133,33 +132,40 @@ __pmConnectLogger(const char *hostname, int *pid, int *port) #endif } - servbuf = __pmAllocHostEntBuffer(); + servInfo = __pmAllocHostEnt(); + myAddr = __pmAllocSockAddrIn(); + PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); - if (__pmGetHostByName(hostname, &servinfo, servbuf) == NULL) { + if (__pmGetHostByName(hostname, servInfo) == NULL) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_CONTEXT) fprintf(stderr, "__pmConnectLogger: gethostbyname: %s\n", hoststrerror()); #endif PM_UNLOCK(__pmLock_libpcp); - __pmFreeHostEntBuffer(servbuf); + __pmFreeSockAddrIn(myAddr); + __pmFreeHostEnt(servInfo); return -ECONNREFUSED; } /* Create socket and attempt to connect to the pmlogger control port */ if ((fd = __pmCreateSocket()) < 0) { PM_UNLOCK(__pmLock_libpcp); - __pmFreeHostEntBuffer(servbuf); + __pmFreeSockAddrIn(myAddr); + __pmFreeHostEnt(servInfo); return fd; } - __pmInitSockAddr(&myAddr, 0, htons(*port)); - __pmSetSockAddr(&myAddr, &servinfo); + __pmInitSockAddr(myAddr, 0, htons(*port)); + __pmSetSockAddr(myAddr, servInfo); PM_UNLOCK(__pmLock_libpcp); - __pmFreeHostEntBuffer(servbuf); - sts = __pmConnect(fd, (__pmSockAddr *)&myAddr, sizeof(myAddr)); + sts = __pmConnect(fd, myAddr, __pmSockAddrInSize()); + + __pmFreeSockAddrIn(myAddr); + __pmFreeHostEnt(servInfo); + if (sts < 0) { sts = -neterror(); __pmCloseSocket(fd); diff --git a/src/libpcp_gui/src/timeclient.c b/src/libpcp_gui/src/timeclient.c index cc4c079..e60ebb9 100644 --- a/src/libpcp_gui/src/timeclient.c +++ b/src/libpcp_gui/src/timeclient.c @@ -48,7 +48,7 @@ pmServerExec(int fd, int livemode) static int pmConnectHandshake(int fd, int port, pmTime *pkt) { - __pmSockAddrIn myaddr; + struct __pmSockAddrIn *myaddr; char buffer[4096]; pmTime *ack; int sts; @@ -57,11 +57,18 @@ pmConnectHandshake(int fd, int port, pmTime *pkt) * Connect to pmtime - pmtime guaranteed started by now, due to the * port number read(2) earlier, or -p option (so no race there). */ - __pmInitSockAddr(&myaddr, htonl(INADDR_LOOPBACK), htons(port)); - if ((sts = __pmConnect(fd, (__pmSockAddr *)&myaddr, sizeof(myaddr))) < 0) { + if ((myaddr = __pmAllocSockAddrIn()) == NULL) { + setoserror(ENOMEM); + goto error; + } + + __pmInitSockAddr(myaddr, htonl(INADDR_LOOPBACK), htons(port)); + if ((sts = __pmConnect(fd, (void *)myaddr, __pmSockAddrInSize())) < 0) { setoserror(neterror()); goto error; } + __pmFreeSockAddrIn(myaddr); + myaddr = NULL; /* * Write the packet, then wait for an ACK. @@ -92,6 +99,8 @@ pmConnectHandshake(int fd, int port, pmTime *pkt) return 0; error: + if (myaddr) + __pmFreeSockAddrIn(myaddr); __pmCloseSocket(fd); return -1; } diff --git a/src/libpcp_pmcd/src/client.c b/src/libpcp_pmcd/src/client.c index f184086..a7c343e 100644 --- a/src/libpcp_pmcd/src/client.c +++ b/src/libpcp_pmcd/src/client.c @@ -29,24 +29,24 @@ void ShowClients(FILE *f) { int i; - __pmHostEnt h; - char *hbuf, *sbuf; + struct __pmHostEnt *host; + char *sbuf; fprintf(f, " fd client connection from ipc ver operations denied\n"); fprintf(f, " == ======================================== ======= =================\n"); - hbuf = __pmAllocHostEntBuffer(); + host = __pmAllocHostEnt(); for (i = 0; i < nClients; i++) { if (client[i].status.connected == 0) continue; fprintf(f, " %3d ", client[i].fd); - if (__pmGetHostByAddr(&client[i].addr, &h, hbuf) == NULL) { + if (__pmGetHostByAddr(&client[i].addr, host) == NULL) { sbuf = __pmSockAddrInToString(&client[i].addr); fprintf(f, "%s", sbuf); free(sbuf); } else { - fprintf(f, "%-40.40s", h.h_name); + fprintf(f, "%-40.40s", __pmHostEntName(host)); } fprintf(f, " %7d", __pmVersionIPC(client[i].fd)); @@ -60,6 +60,6 @@ ShowClients(FILE *f) fputc('\n', f); } - __pmFreeHostEntBuffer(hbuf); + __pmFreeHostEnt(host); fputc('\n', f); } diff --git a/src/libpcp_pmda/src/open.c b/src/libpcp_pmda/src/open.c index 558611c..47ae2b8 100644 --- a/src/libpcp_pmda/src/open.c +++ b/src/libpcp_pmda/src/open.c @@ -35,8 +35,8 @@ __pmdaOpenInet(char *sockname, int myport, int *infd, int *outfd) { int sts; int sfd; - __pmSockAddrIn myaddr; - __pmSockAddrIn from; + struct __pmSockAddrIn *myaddr; + struct __pmSockAddrIn *from; struct servent *service; __pmSockLen addrlen; int one = 1; @@ -78,8 +78,12 @@ __pmdaOpenInet(char *sockname, int myport, int *infd, int *outfd) } #endif - __pmInitSockAddr(&myaddr, htonl(INADDR_ANY), htons(myport)); - sts = __pmBind(sfd, (__pmSockAddr*) &myaddr, sizeof(myaddr)); + if ((myaddr =__pmAllocSockAddrIn()) == NULL) { + __pmNotifyErr(LOG_CRIT, "__pmdaOpenInet: sock addr alloc failed\n"); + exit(1); + } + __pmInitSockAddr(myaddr, htonl(INADDR_ANY), htons(myport)); + sts = __pmBind(sfd, (void *)myaddr, __pmSockAddrInSize()); if (sts < 0) { __pmNotifyErr(LOG_CRIT, "__pmdaOpenInet: inet bind: %s\n", netstrerror()); @@ -92,15 +96,18 @@ __pmdaOpenInet(char *sockname, int myport, int *infd, int *outfd) netstrerror()); exit(1); } - addrlen = sizeof(from); + from = myaddr; + addrlen = __pmSockAddrInSize(); /* block here, waiting for a connection */ - if ((*infd = __pmAccept(sfd, (__pmSockAddr *)&from, &addrlen)) < 0) { + if ((*infd = __pmAccept(sfd, (void *)from, &addrlen)) < 0) { __pmNotifyErr(LOG_CRIT, "__pmdaOpenInet: inet accept: %s\n", netstrerror()); exit(1); } __pmCloseSocket(sfd); __pmSetSocketIPC(*infd); + __pmFreeSockAddrIn(myaddr); + *outfd = *infd; } diff --git a/src/perl/PMDA/local.c b/src/perl/PMDA/local.c index a0476e8..2facda0 100644 --- a/src/perl/PMDA/local.c +++ b/src/perl/PMDA/local.c @@ -188,7 +188,7 @@ local_sock(char *host, int port, scalar_t *callback, int cookie) myaddr.sin_family = AF_INET; memcpy(&myaddr.sin_addr, servinfo->h_addr, servinfo->h_length); myaddr.sin_port = htons(port); - if (__pmConnect(fd, (__pmSockAddr *)&myaddr, sizeof(myaddr)) < 0) { + if (__pmConnect(fd, (void *)&myaddr, sizeof(myaddr)) < 0) { __pmNotifyErr(LOG_ERR, "__pmConnect (%s): %s", host, netstrerror()); exit(1); } @@ -281,30 +281,33 @@ local_log_rotated(files_t *file) static void local_reconnector(files_t *file) { - __pmSockAddrIn myaddr; - __pmHostEnt servinfo; - char *servbuf; + struct __pmSockAddrIn *myaddr = NULL; + struct __pmHostEnt *servinfo = NULL; int fd; if (file->fd >= 0) /* reconnect-needed flag */ - return; - servbuf = __pmAllocHostEntBuffer(); - if (__pmGetHostByName(file->me.sock.host, &servinfo, servbuf) == NULL) { - __pmFreeHostEntBuffer(servbuf); - return; - } - if ((fd = __pmCreateSocket()) < 0) { - __pmFreeHostEntBuffer(servbuf); - return; - } - __pmInitSockAddr(&myaddr, 0, htons(files->me.sock.port)); - __pmSetSockAddr(&myaddr, &servinfo); - __pmFreeHostEntBuffer(servbuf); - if (__pmConnect(fd, (__pmSockAddr *)&myaddr, sizeof(myaddr)) < 0) { + goto done; + if ((myaddr = __pmAllocSockAddrIn()) == NULL) + goto done; + if ((servinfo = __pmAllocHostEnt()) == NULL) + goto done; + if (__pmGetHostByName(file->me.sock.host, servinfo) == NULL) + goto done; + if ((fd = __pmCreateSocket()) < 0) + goto done; + __pmInitSockAddr(myaddr, 0, htons(files->me.sock.port)); + __pmSetSockAddr(myaddr, servinfo); + if (__pmConnect(fd, (void *)myaddr, __pmSockAddrInSize()) < 0) { __pmCloseSocket(fd); - return; + goto done; } files->fd = fd; + +done: + if (myaddr) + __pmFreeSockAddrIn(myaddr); + if (servinfo) + __pmFreeHostEnt(servinfo); } static void diff --git a/src/pmcd/src/client.c b/src/pmcd/src/client.c index 3bd0cd2..49c4a8c 100644 --- a/src/pmcd/src/client.c +++ b/src/pmcd/src/client.c @@ -87,8 +87,8 @@ AcceptNewClient(int reqfd) struct timeval now; i = NewClient(); - addrlen = sizeof(client[i].addr); - fd = __pmAccept(reqfd, (__pmSockAddr *)&client[i].addr, &addrlen); + addrlen = __pmSockAddrInSize(); + fd = __pmAccept(reqfd, (void *)client[i].addr, &addrlen); if (fd == -1) { if (neterror() == EPERM) { __pmNotifyErr(LOG_NOTICE, "AcceptNewClient(%d): " @@ -128,11 +128,23 @@ AcceptNewClient(int reqfd) if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "AcceptNewClient(%d): client[%d] (fd %d)\n", reqfd, i, fd); #endif - pmcd_trace(TR_ADD_CLIENT, __pmSockAddrInToIPAddr(&client[i].addr), fd, client[i].seq); + pmcd_trace(TR_ADD_CLIENT, ClientIPAddr(&client[i]), fd, client[i].seq); return &client[i]; } +struct __pmSockAddrIn * +ClientAddr(ClientInfo *cp) +{ + return (struct __pmSockAddrIn *) &cp->addr[0]; +} + +__pmIPAddr +ClientIPAddr(ClientInfo *cp) +{ + return __pmSockAddrInToIPAddr(ClientAddr(cp)); +} + int NewClient(void) { @@ -144,9 +156,10 @@ NewClient(void) if (i == clientSize) { int j; + clientSize = clientSize ? clientSize * 2 : MIN_CLIENTS_ALLOC; client = (ClientInfo*) - realloc(client, sizeof(ClientInfo) * clientSize); + realloc(client, (sizeof(ClientInfo)+__pmSockAddrInSize()) * clientSize); if (client == NULL) { __pmNoMem("NewClient", sizeof(ClientInfo) * clientSize, PM_RECOV_ERR); Shutdown(); diff --git a/src/pmcd/src/client.h b/src/pmcd/src/client.h index f7ae614..c185462 100644 --- a/src/pmcd/src/client.h +++ b/src/pmcd/src/client.h @@ -23,7 +23,6 @@ /* The table of clients, used by pmcd */ typedef struct { int fd; /* Socket descriptor */ - __pmSockAddrIn addr; /* Address of client */ struct { /* Status of connection to client */ unsigned int connected : 1; /* Client connected */ unsigned int changes : 3; /* PMCD_* bits for changes since last fetch */ @@ -38,6 +37,7 @@ typedef struct { __pmPDUInfo pduInfo; unsigned int seq; /* client sequence number */ time_t start; /* time client connected */ + char addr[0]; /* Address of client [size(__pmSockAddrIn)] */ } ClientInfo; PMCD_EXTERN ClientInfo *client; /* Array of clients */ @@ -50,6 +50,8 @@ PMCD_EXTERN int this_client_id; /* client for current request */ extern ClientInfo *AcceptNewClient(int); extern int NewClient(void); extern void DeleteClient(ClientInfo *); +extern struct __pmSockAddrIn *ClientAddr(ClientInfo *); +extern __pmIPAddr ClientIPAddr(ClientInfo *); PMCD_EXTERN void ShowClients(FILE *m); #ifdef PCP_DEBUG diff --git a/src/pmcd/src/config.c b/src/pmcd/src/config.c index 0a5bb3f..f7777e6 100644 --- a/src/pmcd/src/config.c +++ b/src/pmcd/src/config.c @@ -1321,27 +1321,39 @@ ConnectSocketAgent(AgentInfo *aPtr) int fd; if (aPtr->ipc.socket.addrDomain == AF_INET) { - __pmSockAddrIn addr; - __pmHostEnt hostInfo; - char *hibuf; + struct __pmSockAddrIn *addr; + struct __pmHostEnt *host; + + if ((host = __pmAllocHostEnt()) == NULL) { + fputs("pmcd: Error allocing host entry\n", stderr); + return -1; + } + if ((addr = __pmAllocSockAddrIn()) == NULL) { + fputs("pmcd: Error allocing sock addr\n", stderr); + __pmFreeHostEnt(host); + return -1; + } fd = __pmCreateSocket(); if (fd < 0) { fprintf(stderr, "pmcd: Error creating socket for \"%s\" agent : %s\n", aPtr->pmDomainLabel, netstrerror()); + __pmFreeSockAddrIn(addr); + __pmFreeHostEnt(host); return -1; } - hibuf = __pmAllocHostEntBuffer(); - if (__pmGetHostByName("localhost", &hostInfo, hibuf) == NULL) { + if (__pmGetHostByName("localhost", host) == NULL) { fputs("pmcd: Error getting inet address for localhost\n", stderr); - __pmFreeHostEntBuffer(hibuf); + __pmFreeSockAddrIn(addr); + __pmFreeHostEnt(host); goto error; } - __pmInitSockAddr(&addr, 0, htons(aPtr->ipc.socket.port)); - __pmSetSockAddr(&addr, &hostInfo); - __pmFreeHostEntBuffer(hibuf); - sts = __pmConnect(fd, (__pmSockAddr *) &addr, sizeof(addr)); + __pmInitSockAddr(addr, 0, htons(aPtr->ipc.socket.port)); + __pmSetSockAddr(addr, host); + sts = __pmConnect(fd, (void *)addr, __pmSockAddrInSize()); + __pmFreeSockAddrIn(addr); + __pmFreeHostEnt(host); } else { #if defined(HAVE_SYS_UN_H) @@ -2270,7 +2282,7 @@ ParseRestartAgents(char *fileName) ClientInfo *cp = &client[i]; int s; - if ((s = __pmAccAddClient(__pmSockAddrInToIPAddr(&cp->addr), &cp->denyOps)) < 0) { + if ((s = __pmAccAddClient(ClientIPAddr(cp), &cp->denyOps)) < 0) { /* ignore errors, the client is being terminated in any case */ if (_pmcd_trace_mask) pmcd_trace(TR_XMIT_PDU, cp->fd, PDU_ERROR, s); diff --git a/src/pmcd/src/pmcd.c b/src/pmcd/src/pmcd.c index 0c6b57c..8100644 100644 --- a/src/pmcd/src/pmcd.c +++ b/src/pmcd/src/pmcd.c @@ -359,7 +359,7 @@ OpenRequestSocket(int port, int ipAddr) { int fd; int one, sts; - __pmSockAddrIn myAddr; + struct __pmSockAddrIn *myAddr; fd = __pmCreateSocket(); if (fd < 0) { @@ -400,9 +400,10 @@ OpenRequestSocket(int port, int ipAddr) goto fail; } - __pmInitSockAddr(&myAddr, ipAddr, htons(port)); - - sts = __pmBind(fd, (__pmSockAddr*)&myAddr, sizeof(myAddr)); + myAddr = __pmAllocSockAddrIn(); + __pmInitSockAddr(myAddr, ipAddr, htons(port)); + sts = __pmBind(fd, (void *)myAddr, __pmSockAddrInSize()); + __pmFreeSockAddrIn(myAddr); if (sts < 0) { sts = neterror(); __pmNotifyErr(LOG_ERR, "OpenRequestSocket(%d, 0x%x) __pmBind: %s\n", @@ -825,7 +826,7 @@ ClientLoop(void) if (cp == NULL) continue; - sts = __pmAccAddClient(__pmSockAddrInToIPAddr(&cp->addr), &cp->denyOps); + sts = __pmAccAddClient(ClientIPAddr(cp), &cp->denyOps); if (sts >= 0) { cp->pduInfo.zero = 0; cp->pduInfo.version = PDU_VERSION; @@ -1177,7 +1178,7 @@ static int szBadHosts = 0; static __pmIPAddr *badHost = NULL; static int -AddBadHost(__pmSockAddrIn *hostId) +AddBadHost(struct __pmSockAddrIn *hostId) { int i, need; @@ -1225,10 +1226,10 @@ CleanupClient(ClientInfo *cp, int sts) * been dinged for an access violation since startup or reconfiguration */ if (sts == PM_ERR_PERMISSION || sts == PM_ERR_CONNLIMIT) { - if ( (msg = AddBadHost(&cp->addr)) ) { - caddr = __pmSockAddrInToString(&cp->addr); + if ( (msg = AddBadHost(ClientAddr(cp))) ) { + caddr = __pmSockAddrInToString(ClientAddr(cp)); fprintf(stderr, "access violation from host %s:\n", caddr); - free(client); + free(caddr); } } else @@ -1249,7 +1250,7 @@ CleanupClient(ClientInfo *cp, int sts) * count */ if (sts != PM_ERR_PERMISSION && sts != PM_ERR_CONNLIMIT) - __pmAccDelClient(__pmSockAddrInToIPAddr(&cp->addr)); + __pmAccDelClient(ClientIPAddr(cp)); pmcd_trace(TR_DEL_CLIENT, cp->fd, sts, 0); DeleteClient(cp); diff --git a/src/pmlogger/ports.c b/src/pmlogger/ports.c index b38a988..c033413 100644 --- a/src/pmlogger/ports.c +++ b/src/pmlogger/ports.c @@ -182,10 +182,9 @@ GetPort(char *file) int mapfd; FILE *mapstream; int sts; - __pmSockAddrIn myAddr; static int port_base = -1; - __pmHostEnt he; - char *hebuf; + struct __pmSockAddrIn *myAddr; + struct __pmHostEnt *host; fd = __pmCreateSocket(); if (fd < 0) { @@ -217,9 +216,10 @@ GetPort(char *file) * try to allocate ports from port_base. If port already in use, add one * and try again. */ + myAddr = __pmAllocSockAddrIn(); for (ctlport = port_base; ; ctlport++) { - __pmInitSockAddr(&myAddr, htonl(INADDR_ANY), htons(ctlport)); - sts = __pmBind(fd, (__pmSockAddr*)&myAddr, sizeof(myAddr)); + __pmInitSockAddr(myAddr, htonl(INADDR_ANY), htons(ctlport)); + sts = __pmBind(fd, (void *)myAddr, __pmSockAddrInSize()); if (sts < 0) { if (neterror() != EADDRINUSE) { fprintf(stderr, "bind(%d): %s\n", ctlport, netstrerror()); @@ -229,6 +229,7 @@ GetPort(char *file) else break; } + __pmFreeSockAddrIn(myAddr); sts = __pmListen(fd, 5); /* Max. of 5 pending connection requests */ if (sts == -1) { fprintf(stderr, "__pmListen: %s\n", netstrerror()); @@ -253,11 +254,11 @@ GetPort(char *file) fprintf(mapstream, "%d\n", ctlport); /* then the PMCD host */ - hebuf = __pmAllocHostEntBuffer(); - if (__pmGetHostByName(pmcd_host, &he, hebuf) != NULL) - fprintf(mapstream, "%s", he.h_name); + host = __pmAllocHostEnt(); + if (__pmGetHostByName(pmcd_host, host) != NULL) + fprintf(mapstream, "%s", __pmHostEntName(host)); fprintf(mapstream, "\n"); - __pmFreeHostEntBuffer(hebuf); + __pmFreeHostEnt(host); /* then the full pathname to the archive base */ __pmNativePath(archBase); @@ -405,15 +406,20 @@ int control_req(void) { int fd, sts; - __pmSockAddrIn addr; - __pmHostEnt h; - char *hbuf, *abuf; + struct __pmSockAddrIn *addr; + struct __pmHostEnt *host; + char *abuf; __pmSockLen addrlen; - addrlen = sizeof(addr); - fd = __pmAccept(ctlfd, (__pmSockAddr *)&addr, &addrlen); + if ((addr = __pmAllocSockAddrIn()) == NULL) { + fputs("error allocating space for client\n", stderr); + return 0; + } + addrlen = __pmSockAddrInSize(); + fd = __pmAccept(ctlfd, (void *)addr, &addrlen); if (fd == -1) { fprintf(stderr, "error accepting client: %s\n", netstrerror()); + __pmFreeSockAddrIn(addr); return 0; } __pmSetSocketIPC(fd); @@ -426,6 +432,7 @@ control_req(void) if (sts < 0) fprintf(stderr, "error sending connection NACK to client: %s\n", pmErrStr(sts)); + __pmFreeSockAddrIn(addr); __pmCloseSocket(fd); return 0; } @@ -434,25 +441,30 @@ control_req(void) if (sts < 0) { __pmSendError(fd, FROM_ANON, sts); fprintf(stderr, "error connecting to client: %s\n", pmErrStr(sts)); + __pmFreeSockAddrIn(addr); __pmCloseSocket(fd); return 0; } - hbuf = __pmAllocHostEntBuffer(); - if (__pmGetHostByAddr(& addr, &h, hbuf) == NULL || strlen(h.h_name) > MAXHOSTNAMELEN-1) { - abuf = __pmSockAddrInToString(&addr); + host = __pmAllocHostEnt(); + if (__pmGetHostByAddr(addr, host) == NULL || strlen(__pmHostEntName(host)) > MAXHOSTNAMELEN-1) { + abuf = __pmSockAddrInToString(addr); sprintf(pmlc_host, "%s", abuf); free(abuf); } - else + else { /* this is safe, due to strlen() test above */ - strcpy(pmlc_host, h.h_name); - __pmFreeHostEntBuffer(hbuf); + strcpy(pmlc_host, __pmHostEntName(host)); + } + + sts = __pmAccAddClient(__pmSockAddrInToIPAddr(addr), &clientops); + __pmFreeSockAddrIn(addr); + __pmFreeHostEnt(host); - if ((sts = __pmAccAddClient(__pmSockAddrInToIPAddr(&addr), &clientops)) < 0) { + if (sts < 0) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_CONTEXT) { - abuf = __pmSockAddrInToString(&addr); + abuf = __pmSockAddrInToString(addr); fprintf(stderr, "client addr: %s\n", abuf); free(abuf); __pmAccDumpHosts(stderr); diff --git a/src/pmproxy/client.c b/src/pmproxy/client.c index d1e9f75..2cdfb7f 100644 --- a/src/pmproxy/client.c +++ b/src/pmproxy/client.c @@ -29,7 +29,7 @@ extern void Shutdown(void); static int NewClient(void) { - int i; + int i, allocSize; for (i = 0; i < nClients; i++) if (!client[i].status.connected) @@ -37,10 +37,10 @@ NewClient(void) if (i == clientSize) { clientSize = clientSize ? clientSize * 2 : MIN_CLIENTS_ALLOC; - client = (ClientInfo*) - realloc(client, sizeof(ClientInfo) * clientSize); + allocSize = (sizeof(ClientInfo) + __pmSockAddrInSize()) * clientSize; + client = (ClientInfo *) realloc(client, allocSize); if (client == NULL) { - __pmNoMem("NewClient", sizeof(ClientInfo) * clientSize, PM_RECOV_ERR); + __pmNoMem("NewClient", allocSize, PM_RECOV_ERR); Shutdown(); exit(1); } @@ -50,6 +50,12 @@ NewClient(void) return i; } +static struct __pmSockAddrIn * +ClientAddr(ClientInfo *client) +{ + return (struct __pmSockAddrIn *) &client->addr[0]; +} + /* MY_BUFLEN needs to big enough to hold "hostname port" */ #define MY_BUFLEN (MAXHOSTNAMELEN+10) #define MY_VERSION "pmproxy-server 1\n" @@ -68,8 +74,8 @@ AcceptNewClient(int reqfd) char *abufp; i = NewClient(); - addrlen = sizeof(client[i].addr); - fd = __pmAccept(reqfd, (__pmSockAddr *)&client[i].addr, &addrlen); + addrlen = __pmSockAddrInSize(); + fd = __pmAccept(reqfd, (void *)ClientAddr(&client[i]), &addrlen); if (fd == -1) { __pmNotifyErr(LOG_ERR, "AcceptNewClient(%d) __pmAccept failed: %s", reqfd, netstrerror()); @@ -115,7 +121,7 @@ AcceptNewClient(int reqfd) } if (!ok) { - abufp = __pmSockAddrInToString(&client[i].addr); + abufp = __pmSockAddrInToString(ClientAddr(&client[i])); __pmNotifyErr(LOG_WARNING, "Bad version string from client at %s", abufp); free(abufp); fprintf(stderr, "AcceptNewClient: bad version string was \""); @@ -127,7 +133,7 @@ AcceptNewClient(int reqfd) } if (__pmSend(fd, MY_VERSION, strlen(MY_VERSION), 0) != strlen(MY_VERSION)) { - abufp = __pmSockAddrInToString(&client[i].addr); + abufp = __pmSockAddrInToString(ClientAddr(&client[i])); __pmNotifyErr(LOG_WARNING, "AcceptNewClient: failed to send version " "string (%s) to client at %s\n", MY_VERSION, abufp); free(abufp); @@ -159,9 +165,10 @@ AcceptNewClient(int reqfd) bp++; client[i].pmcd_port = (int)strtoul(bp, &endp, 10); if (*endp != '\0') { - abufp = __pmSockAddrInToString(&client[i].addr); + abufp = __pmSockAddrInToString(ClientAddr(&client[i])); __pmNotifyErr(LOG_WARNING, "AcceptNewClient: bad pmcd port " "\"%s\" from client at %s", bp, abufp); + free(abufp); DeleteClient(&client[i]); return NULL; } @@ -170,7 +177,7 @@ AcceptNewClient(int reqfd) } if (client[i].pmcd_hostname == NULL) { - abufp = __pmSockAddrInToString(&client[i].addr); + abufp = __pmSockAddrInToString(ClientAddr(&client[i])); __pmNotifyErr(LOG_WARNING, "AcceptNewClient: failed to get PMCD " "hostname (%s) from client at %s", buf, abufp); free(abufp); @@ -184,9 +191,10 @@ AcceptNewClient(int reqfd) * note error message gets appended to once pmcd connection is * made in ClientLoop() */ - abufp = __pmSockAddrInToString(&client[i].addr); + abufp = __pmSockAddrInToString(ClientAddr(&client[i])); fprintf(stderr, "AcceptNewClient [%d] fd=%d from %s to %s (port %s)", i, fd, abufp, client[i].pmcd_hostname, bp); + free(abufp); } #endif diff --git a/src/pmproxy/pmproxy.c b/src/pmproxy/pmproxy.c index 5d75474..973ab2e 100644 --- a/src/pmproxy/pmproxy.c +++ b/src/pmproxy/pmproxy.c @@ -226,7 +226,7 @@ OpenRequestSocket(int port, __uint32_t ipAddr) { int fd; int sts; - __pmSockAddrIn myAddr; + struct __pmSockAddrIn *myAddr; int one = 1; fd = __pmCreateSocket(); @@ -268,14 +268,22 @@ OpenRequestSocket(int port, __uint32_t ipAddr) DontStart(); } - __pmInitSockAddr(&myAddr, ipAddr, htons(port)); - sts = __pmBind(fd, (__pmSockAddr *)&myAddr, sizeof(myAddr)); - if (sts < 0){ + myAddr = __pmAllocSockAddrIn(); + if (myAddr == NULL) { + __pmNotifyErr(LOG_ERR, "OpenRequestSocket(%d, 0x%x) addr alloc failed\n", + port, ipAddr); + DontStart(); + } + __pmInitSockAddr(myAddr, ipAddr, htons(port)); + sts = __pmBind(fd, (void *)myAddr, __pmSockAddrInSize()); + if (sts < 0) { __pmNotifyErr(LOG_ERR, "OpenRequestSocket(%d) __pmBind: %s\n", port, netstrerror()); - __pmNotifyErr(LOG_ERR, "pmproxy is already running\n"); + if (neterror() == EADDRINUSE) + __pmNotifyErr(LOG_ERR, "pmproxy is already running\n"); DontStart(); } + __pmFreeSockAddrIn(myAddr); sts = __pmListen(fd, 5); /* Max. of 5 pending connection requests */ if (sts == -1) { diff --git a/src/pmproxy/pmproxy.h b/src/pmproxy/pmproxy.h index e8b2977..a7318cf 100644 --- a/src/pmproxy/pmproxy.h +++ b/src/pmproxy/pmproxy.h @@ -26,13 +26,13 @@ typedef struct { int fd; /* client socket descriptor */ int version; /* proxy-client protocol version */ - __pmSockAddrIn addr; /* address of client */ struct { /* Status of connection to client */ unsigned int connected : 1; /* Client connected */ } status; char *pmcd_hostname; /* PMCD hostname */ int pmcd_port; /* PMCD port */ int pmcd_fd; /* PMCD socket descriptor */ + char addr[0]; /* address of client [__pmSockAddrIn] */ } ClientInfo; extern ClientInfo *client; /* Array of clients */