From: Dave H. <hel...@us...> - 2012-12-30 01:30:37
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "SFCB - Small Footprint CIM Broker". The branch, master has been updated via 1f674ccd5e27659a951ecaf9584340348bc486a1 (commit) from 75145bf63e1e6a3eae4275c097466e8d5c3d7a11 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1f674ccd5e27659a951ecaf9584340348bc486a1 Author: Dave Heller <hel...@us...> Date: Sat Dec 29 20:24:30 2012 -0500 [ 3597806 ] Bind to arbitrary list of IP addresses in SFCB ----------------------------------------------------------------------- Summary of changes: diff --git a/NEWS b/NEWS index 289848f..64d90fc 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Everything in 1.3.17 (see below), plus: New features: - 3597805 Restart HTTP daemon without restarting SFCB +- 3597806 Bind to arbitrary list of IP addresses in SFCB Bugs fixed: diff --git a/control.c b/control.c index ff3903b..2af05c4 100644 --- a/control.c +++ b/control.c @@ -54,11 +54,15 @@ typedef struct control { static UtilHashTable *ct = NULL; char *configfile = NULL; +char *ip4List= NULL; +char *ip6List= NULL; // Control initial values // { property, type, value} // Type: 0=string, 1=num, 2=bool, 3=unstripped string Control init[] = { + {"ip4AddrList", 0, NULL}, + {"ip6AddrList", 0, NULL}, {"httpPort", 1, "5988"}, {"enableHttp", 2, "true"}, {"enableUds", 2, "true"}, diff --git a/httpAdapter.c b/httpAdapter.c index 9b0b447..509370f 100644 --- a/httpAdapter.c +++ b/httpAdapter.c @@ -145,6 +145,7 @@ extern char *getErrTrailer(int id, int rc, char *m); extern void dumpTiming(int pid); extern char *configfile; extern int inet_aton(const char *cp, struct in_addr *inp); +extern int inet_pton(int af, const char *cp, void *buf); static unsigned int sessionId; extern char *opsName[]; @@ -1651,15 +1652,14 @@ bindSocketToDevice(int sockfd) } static int -getSocket() +getSocket(sa_family_t fam) { - int fd; + int fd = -1; int ru = 1; #ifdef HAVE_IPV6 // need to check - fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); + if (fam==AF_INET6) fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); if (fd < 0) { - mlogf(M_INFO, M_SHOW, "--- Using IPv4 address\n"); fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); fallback_ipv4 = 1; } @@ -1674,7 +1674,7 @@ getSocket() #ifdef HAVE_IPV6 static struct sockaddr * -prepSockAddr6(int port, void *ssin, socklen_t * sin_len) +prepSockAddr6(char *ip, int port, void *ssin, socklen_t * sin_len) { struct sockaddr_in6 *sin = ssin; @@ -1682,10 +1682,14 @@ prepSockAddr6(int port, void *ssin, socklen_t * sin_len) memset(sin, 0, *sin_len); sin->sin6_family = AF_INET6; - if (httpLocalOnly) + if (httpLocalOnly) { sin->sin6_addr = in6addr_loopback; - else - sin->sin6_addr = in6addr_any; + } else { + if (!inet_pton(AF_INET6, ip, &(sin->sin6_addr))) { + mlogf(M_ERROR, M_SHOW, "--- IP: %s is not a valid IPv6 address\n", ip); + return NULL; + } + } sin->sin6_port = htons(port); return (struct sockaddr *) sin; @@ -1694,7 +1698,7 @@ prepSockAddr6(int port, void *ssin, socklen_t * sin_len) static struct sockaddr * -prepSockAddr4(int port, void *ssin, socklen_t * sin_len) +prepSockAddr4(char *ip, int port, void *ssin, socklen_t * sin_len) { struct sockaddr_in *sin = ssin; @@ -1705,15 +1709,19 @@ prepSockAddr4(int port, void *ssin, socklen_t * sin_len) if (httpLocalOnly) { const char *loopback_int = "127.0.0.1"; inet_aton(loopback_int, &(sin->sin_addr)); - } else - sin->sin_addr.s_addr = INADDR_ANY; + } else { + if (!inet_aton(ip, &(sin->sin_addr))) { + mlogf(M_ERROR, M_SHOW, "--- IP: %s is not a valid IPv4 address\n", ip); + return NULL; + } + } sin->sin_port = htons(port); return (struct sockaddr *) sin; } static int -bindToPort(int sock, int port, void *ssin, socklen_t * sin_len) +bindToPort(int sock, int port, char *ip, void *ssin, socklen_t * sin_len) { struct sockaddr *sin; @@ -1725,21 +1733,17 @@ bindToPort(int sock, int port, void *ssin, socklen_t * sin_len) char *l = ""; char *r = ""; - char *ip; - - ip = httpLocalOnly ? "127.0.0.1" : "0.0.0.0"; #ifdef HAVE_IPV6 if (!fallback_ipv4) { l = "["; r = "]"; - ip = httpLocalOnly ? "::1" : "::"; - if (!(sin = prepSockAddr6(port, ssin, sin_len))) + if (!(sin = prepSockAddr6(ip, port, ssin, sin_len))) return 1; } else #endif - if (!(sin = prepSockAddr4(port, ssin, sin_len))) + if (!(sin = prepSockAddr4(ip, port, ssin, sin_len))) return 1; int maxtries = 5; @@ -1916,7 +1920,8 @@ initSSL() #endif // USE_SSL int -httpDaemon(int argc, char *argv[], int sslMode) +httpDaemon(int argc, char *argv[], int sslMode, char *ipAddr, + sa_family_t ipAddrFam, int sfcbPid) { #ifdef HAVE_IPV6 @@ -2093,11 +2098,11 @@ httpDaemon(int argc, char *argv[], int sslMode) } if (enableHttp) { - httpListenFd = getSocket(); + httpListenFd = getSocket(ipAddrFam); } #ifdef USE_SSL if (sslMode) { - httpsListenFd = getSocket(); + httpsListenFd = getSocket(ipAddrFam); } #endif // USE_SSL #ifdef HAVE_UDS @@ -2120,12 +2125,12 @@ httpDaemon(int argc, char *argv[], int sslMode) int bindrc = 0; if (enableHttp) { - bindrc = bindToPort(httpListenFd, httpPort, &httpSin, &httpSin_len); + bindrc = bindToPort(httpListenFd, httpPort, ipAddr, &httpSin, &httpSin_len); } #ifdef USE_SSL if (sslMode) { bindrc |= - bindToPort(httpsListenFd, httpsPort, &httpsSin, &httpsSin_len); + bindToPort(httpsListenFd, httpsPort, ipAddr, &httpsSin, &httpsSin_len); } #endif #ifdef HAVE_UDS diff --git a/sfcBroker.c b/sfcBroker.c index eadb338..745191b 100644 --- a/sfcBroker.c +++ b/sfcBroker.c @@ -64,7 +64,7 @@ extern int init_sfcBroker(); extern CMPIBroker *Broker; extern void initProvProcCtl(int); extern void processTerminated(int pid); -extern int httpDaemon(int argc, char *argv[], int sslMode); +extern int httpDaemon(int argc, char *argv[], int sslMode, char *ipAddr, sa_family_t ipAddrFam); extern void processProviderMgrRequests(); extern int stopNextProc(); @@ -107,6 +107,8 @@ long sslMode=0; static int startHttpd(int argc, char *argv[], int sslMode); extern char *configfile; +extern char *ip4List; +extern char *ip6List; int trimws = 1; @@ -126,6 +128,14 @@ typedef struct startedThreadAdapter { StartedThreadAdapter *lastStartedThreadAdapter = NULL; +typedef struct ipAddr { + char * addrStr; + sa_family_t addrFam; +} IpAddr; + +IpAddr *ipAddrList=NULL; +int ipAddrCnt = 0; + void addStartedAdapter(int pid) { @@ -466,33 +476,38 @@ startHttpd(int argc, char *argv[], int sslMode) } } - pid = fork(); - if (pid < 0) { - char *emsg = strerror(errno); - mlogf(M_ERROR, M_SHOW, "-#- http fork: %s", emsg); - exit(2); - } - if (pid == 0) { - currentProc = getpid(); - if (!httpSFCB) { - // Set the real and effective uids - rc = setreuid(httpuid, httpuid); - if (rc == -1) { - mlogf(M_ERROR, M_SHOW, "--- Changing uid for http failed.\n"); - exit(2); + int i; + for (i = 0; i < ipAddrCnt; i++) { + mlogf(M_INFO, M_SHOW, "--- Starting adapter for IP: %s\n", + (ipAddrList + i)->addrStr); + pid = fork(); + if (pid < 0) { + char *emsg = strerror(errno); + mlogf(M_ERROR, M_SHOW, "-#- http fork: %s", emsg); + exit(2); + } + if (pid == 0) { + currentProc = getpid(); + if (!httpSFCB) { + // Set the real and effective uids + rc = setreuid(httpuid, httpuid); + if (rc == -1) { + mlogf(M_ERROR, M_SHOW, "--- Changing uid for http failed.\n"); + exit(2); + } + } + if (httpDaemon(argc, argv, sslMode, (ipAddrList + i)->addrStr, + (ipAddrList + i)->addrFam)) { + //kill(sfcPid, 3); /* if port in use, shutdown */ + /* (don't do this anymore - xxxxxxx) */ } + closeSocket(&sfcbSockets,cRcv,"startHttpd"); + closeSocket(&resultSockets,cAll,"startHttpd"); + exit(0); } - - if (httpDaemon(argc, argv, sslMode)) { - //kill(sfcPid, 3); /* if port in use, shutdown */ - /* (don't do this anymore - 3597805) */ + else { + addStartedAdapter(pid); } - - closeSocket(&sfcbSockets, cRcv, "startHttpd"); - closeSocket(&resultSockets, cAll, "startHttpd"); - exit(0); - } else { - addStartedAdapter(pid); } return 0; } @@ -551,6 +566,8 @@ usage(int status) " components to trace; ? lists the available", " components with their bitmask and exits", " -v, --version output version information and exit", + " -4, --ipv4-addr-list comma-separated list of IPv4 addresses to bind", + " -6, --ipv6-addr-list comma-separated list of IPv6 addresses to bind", " -i, --disable-repository-default-inst-prov To disable entry into the default provider", "", "For SBLIM package updates and additional information, please see", @@ -661,12 +678,14 @@ main(int argc, char *argv[]) {"syslog-level", required_argument, 0, 'l'}, {"trace-components", required_argument, 0, 't'}, {"version", no_argument, 0, 'v'}, + {"ipv4-addr-list", required_argument, 0, '4'}, + {"ipv6-addr-list", required_argument, 0, '6'}, {"disable-repository-default-inst-provider", no_argument, 0, 'i'}, {0, 0, 0, 0} }; while ((c = - getopt_long(argc, argv, "c:dhkst:vil:", long_options, + getopt_long(argc, argv, "c:dhkst:v4:6:il:", long_options, 0)) != -1) { switch (c) { case 0: @@ -712,6 +731,14 @@ main(int argc, char *argv[]) case 'v': version(); + case '4': + ip4List = strdup(optarg); + break; + + case '6': + ip6List = strdup(optarg); + break; + case 'i': disableDefaultProvider = 1; break; @@ -903,6 +930,68 @@ main(int argc, char *argv[]) exit(1); } +#ifndef LOCAL_CONNECT_ONLY_ENABLE + if ((ipAddrList = calloc(1, sizeof(IpAddr))) == 0) { + mlogf(M_ERROR,M_SHOW,"-#- Failed to alloc memory for ipAddrList.\n"); + exit(2); + } + // Command line option takes precedence over config file + if (!ip4List) + getControlChars("ip4AddrList",&ip4List); + if (ip4List && !httpLocalOnly) { + char* t = strtok(ip4List,","); + while(t) { + ipAddrList[ipAddrCnt].addrStr = strdup(t); + ipAddrList[ipAddrCnt].addrFam = AF_INET; + ipAddrCnt++; + t = strtok(NULL,","); + if ((ipAddrList = realloc(ipAddrList,(ipAddrCnt+1)*sizeof(IpAddr))) == 0) { + mlogf(M_ERROR,M_SHOW,"-#- Failed to realloc memory for ipAddrList.\n"); + exit(2); + } + } + } +#ifdef HAVE_IPV6 + if (!ip6List) + getControlChars("ip6AddrList",&ip6List); + if (ip6List && !httpLocalOnly) { + char* t = strtok(ip6List,","); + while(t) { + ipAddrList[ipAddrCnt].addrStr = strdup(t); + ipAddrList[ipAddrCnt].addrFam = AF_INET6; + ipAddrCnt++; + t = strtok(NULL,","); + if ((ipAddrList = realloc(ipAddrList,(ipAddrCnt+1)*sizeof(IpAddr))) == 0) { + mlogf(M_ERROR,M_SHOW,"-#- Failed to realloc memory for ipAddrList.\n"); + exit(2); + } + } + } + if (ipAddrCnt == 0) { + if (httpLocalOnly) { + mlogf(M_INFO,M_SHOW,"--- Bind to loopback address\n"); + ipAddrList[ipAddrCnt].addrStr = "::1"; + } else { + mlogf(M_INFO,M_SHOW,"--- Bind to any available IP address\n"); + ipAddrList[ipAddrCnt].addrStr = "::"; + } + ipAddrList[ipAddrCnt].addrFam = AF_INET6; + ipAddrCnt++; + } +#endif + if (ipAddrCnt == 0) { + if (httpLocalOnly) { + mlogf(M_INFO,M_SHOW,"--- Bind to loopback address\n"); + ipAddrList[ipAddrCnt].addrStr = "127.0.0.1"; + } else { + mlogf(M_INFO,M_SHOW,"--- Bind to any available IP address\n"); + ipAddrList[ipAddrCnt].addrStr = "0.0.0.0"; + } + ipAddrList[ipAddrCnt].addrFam = AF_INET6; + ipAddrCnt++; + } +#endif // LOCAL_CONNECT_ONLY_ENABLE + initSem(pSockets); initProvProcCtl(pSockets); init_sfcBroker(); diff --git a/sfcb.cfg.pre.in b/sfcb.cfg.pre.in index 545a779..28ebdb1 100644 --- a/sfcb.cfg.pre.in +++ b/sfcb.cfg.pre.in @@ -12,6 +12,27 @@ ## ##------------------------------------- HTTP ---------------------------------- +## List of IPv4 addresses to bind to. The default behavior is to bind to any +## available IP address. To bind to specific IPs enter a comma delimited list +## of IPv4 addresses here. Note that a loopback address must be explicitly +## listed if that is desired. Do not include "0.0.0.0" (i.e. INADDR_ANY) as it +## will conflict with other addresses. All addresses are bound to http and/or +## https according to the values of enableHttp and enableHttps. +## The value listed here is ignored if the -4 option is set on the command line. +## Default is an empty list, which implies bind to any available IP. +#ip4AddrList: + +## List of IPv6 addresses to bind to. The default behavior is to bind to any +## available IP address. To bind to specific IPs enter a comma delimited list +## of IPv6 addresses here. These addresses are bound in addition to any IPv4 +## addresses listed above. Note that a loopback address must be explicitly +## listed if that is desired. Do not include "::" (i.e. IN6ADDR_ANY) as it +## will conflict with other addresses. All addresses are bound to http and/or +## https according to the values of enableHttp and enableHttps. +## The value listed here is ignored if the -6 option is set on the command line. +## Default is an empty list, which implies bind to any available IP. +#ip6AddrList: + ## Enable HTTP. ## Default is true. If HTTPS is configured, default is false. enableHttp: @SFCB_CONF_HTTP@ @@ -39,7 +60,8 @@ httpPort: 5988 ## Default is 8 httpProcs: 8 -## Do not allow HTTP request from anywhere except localhost. +## Do not allow HTTP request from anywhere except localhost. Overrides all +## other IP address configuration. ## Default is false #httpLocalOnly: false hooks/post-receive -- SFCB - Small Footprint CIM Broker |