Browse Source

Confirm all handed over sockets match the configured sockets

master
Con Kolivas 10 years ago
parent
commit
65f52112ba
  1. 53
      src/connector.c
  2. 36
      src/libckpool.c
  3. 1
      src/libckpool.h

53
src/connector.c

@ -70,8 +70,6 @@ struct connector_data {
/* Array of server fds */ /* Array of server fds */
int *serverfd; int *serverfd;
/* Number of server fds */
int serverfds;
/* All time count of clients connected */ /* All time count of clients connected */
int nfds; int nfds;
@ -358,8 +356,8 @@ reparse:
void *receiver(void *arg) void *receiver(void *arg)
{ {
cdata_t *cdata = (cdata_t *)arg; cdata_t *cdata = (cdata_t *)arg;
int ret, epfd, i, serverfds;
struct epoll_event event; struct epoll_event event;
int ret, epfd, i;
rename_proc("creceiver"); rename_proc("creceiver");
@ -368,8 +366,9 @@ void *receiver(void *arg)
LOGEMERG("FATAL: Failed to create epoll in receiver"); LOGEMERG("FATAL: Failed to create epoll in receiver");
return NULL; return NULL;
} }
serverfds = cdata->ckp->serverurls;
/* Add all the serverfds to the epoll */ /* Add all the serverfds to the epoll */
for (i = 0; i < cdata->serverfds; i++) { for (i = 0; i < serverfds; i++) {
/* The small values will be easily identifiable compared to /* The small values will be easily identifiable compared to
* pointers */ * pointers */
event.data.u64 = i; event.data.u64 = i;
@ -399,7 +398,7 @@ void *receiver(void *arg)
} }
if (unlikely(!ret)) if (unlikely(!ret))
continue; continue;
if (event.data.u64 < (uint64_t)cdata->serverfds) { if (event.data.u64 < (uint64_t)serverfds) {
ret = accept_client(cdata, epfd, event.data.u64); ret = accept_client(cdata, epfd, event.data.u64);
if (unlikely(ret < 0)) { if (unlikely(ret < 0)) {
LOGEMERG("FATAL: Failed to accept_client in receiver"); LOGEMERG("FATAL: Failed to accept_client in receiver");
@ -726,7 +725,7 @@ retry:
int fdno = -1; int fdno = -1;
sscanf(buf, "getxfd%d", &fdno); sscanf(buf, "getxfd%d", &fdno);
if (fdno > -1 && fdno < cdata->serverfds) if (fdno > -1 && fdno < ckp->serverurls)
send_fd(cdata->serverfd[fdno], sockd); send_fd(cdata->serverfd[fdno], sockd);
} else } else
LOGWARNING("Unhandled connector message: %s", buf); LOGWARNING("Unhandled connector message: %s", buf);
@ -740,7 +739,6 @@ out:
int connector(proc_instance_t *pi) int connector(proc_instance_t *pi)
{ {
cdata_t *cdata = ckzalloc(sizeof(cdata_t)); cdata_t *cdata = ckzalloc(sizeof(cdata_t));
char *url = NULL, *port = NULL;
ckpool_t *ckp = pi->ckp; ckpool_t *ckp = pi->ckp;
int sockd, ret = 0, i; int sockd, ret = 0, i;
const int on = 1; const int on = 1;
@ -755,19 +753,11 @@ int connector(proc_instance_t *pi)
else else
cdata->serverfd = ckalloc(sizeof(int *) * ckp->serverurls); cdata->serverfd = ckalloc(sizeof(int *) * ckp->serverurls);
for (i = 0; i < ckp->serverurls; i++) { if (!ckp->serverurls) {
if (!ckp->oldconnfd[i]) /* No serverurls have been specified. Bind to all interfaces
break; * on default sockets. */
cdata->serverfd[i] = ckp->oldconnfd[i];
cdata->serverfds++;
}
if (!cdata->serverfds && !ckp->serverurls) {
/* No serverurls have been specified and no sockets have been
* inherited. Bind to all interfaces on default sockets. */
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
cdata->serverfds = 1;
sockd = socket(AF_INET, SOCK_STREAM, 0); sockd = socket(AF_INET, SOCK_STREAM, 0);
if (sockd < 0) { if (sockd < 0) {
LOGERR("Connector failed to open socket"); LOGERR("Connector failed to open socket");
@ -798,24 +788,35 @@ int connector(proc_instance_t *pi)
} }
cdata->serverfd[0] = sockd; cdata->serverfd[0] = sockd;
} else { } else {
for ( ; cdata->serverfds < ckp->serverurls; cdata->serverfds++) { for (i = 0; i < ckp->serverurls; i++) {
char *serverurl = ckp->serverurl[cdata->serverfds]; char oldurl[INET6_ADDRSTRLEN], oldport[8];
char newurl[INET6_ADDRSTRLEN], newport[8];
char *serverurl = ckp->serverurl[i];
if (!extract_sockaddr(serverurl, &url, &port)) { if (!url_from_serverurl(serverurl, newurl, newport)) {
LOGWARNING("Failed to extract server address from %s", serverurl); LOGWARNING("Failed to extract resolved url from %s", serverurl);
ret = 1; ret = 1;
goto out; goto out;
} }
sockd = ckp->oldconnfd[i];
if (url_from_socket(sockd, oldurl, oldport)) {
if (strcmp(newurl, oldurl) || strcmp(newport, oldport)) {
LOGWARNING("Handed over socket url %s:%s does not match config %s:%s, creating new socket",
oldurl, oldport, newurl, newport);
Close(sockd);
}
}
do { do {
sockd = bind_socket(url, port); if (sockd > 0)
break;
sockd = bind_socket(newurl, newport);
if (sockd > 0) if (sockd > 0)
break; break;
LOGWARNING("Connector failed to bind to socket, retrying in 5s"); LOGWARNING("Connector failed to bind to socket, retrying in 5s");
sleep(5); sleep(5);
} while (++tries < 25); } while (++tries < 25);
dealloc(url);
dealloc(port);
if (sockd < 0) { if (sockd < 0) {
LOGERR("Connector failed to bind to socket for 2 minutes"); LOGERR("Connector failed to bind to socket for 2 minutes");
ret = 1; ret = 1;
@ -826,7 +827,7 @@ int connector(proc_instance_t *pi)
Close(sockd); Close(sockd);
goto out; goto out;
} }
cdata->serverfd[cdata->serverfds] = sockd; cdata->serverfd[i] = sockd;
} }
} }

36
src/libckpool.c

@ -342,6 +342,8 @@ void cksem_destroy(sem_t *sem)
sem_destroy(sem); sem_destroy(sem);
} }
/* Extract just the url and port information from a url string, allocating
* heap memory for sockaddr_url and sockaddr_port. */
bool extract_sockaddr(char *url, char **sockaddr_url, char **sockaddr_port) bool extract_sockaddr(char *url, char **sockaddr_url, char **sockaddr_port)
{ {
char *url_begin, *url_end, *ipv6_begin, *ipv6_end, *port_start = NULL; char *url_begin, *url_end, *ipv6_begin, *ipv6_end, *port_start = NULL;
@ -418,12 +420,12 @@ bool url_from_sockaddr(const struct sockaddr *addr, char *url, char *port)
const struct sockaddr_in6 *inet6_in; const struct sockaddr_in6 *inet6_in;
case AF_INET: case AF_INET:
inet4_in = (struct sockaddr_in *)url; inet4_in = (struct sockaddr_in *)addr;
inet_ntop(AF_INET, &inet4_in->sin_addr, url, INET6_ADDRSTRLEN); inet_ntop(AF_INET, &inet4_in->sin_addr, url, INET6_ADDRSTRLEN);
port_no = htons(inet4_in->sin_port); port_no = htons(inet4_in->sin_port);
break; break;
case AF_INET6: case AF_INET6:
inet6_in = (struct sockaddr_in6 *)url; inet6_in = (struct sockaddr_in6 *)addr;
inet_ntop(AF_INET6, &inet6_in->sin6_addr, url, INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &inet6_in->sin6_addr, url, INET6_ADDRSTRLEN);
port_no = htons(inet6_in->sin6_port); port_no = htons(inet6_in->sin6_port);
break; break;
@ -446,11 +448,39 @@ bool addrinfo_from_url(const char *url, const char *port, struct addrinfo *addri
return false; return false;
if (!servinfo) if (!servinfo)
return false; return false;
memcpy(addrinfo, servinfo->ai_addr, sizeof(struct addrinfo)); memcpy(addrinfo, servinfo->ai_addr, servinfo->ai_addrlen);
freeaddrinfo(servinfo); freeaddrinfo(servinfo);
return true; return true;
} }
/* Extract a resolved url and port from a serverurl string. newurl must be
* a string of at least INET6_ADDRSTRLEN and newport at least 6 bytes. */
bool url_from_serverurl(char *serverurl, char *newurl, char *newport)
{
char *url = NULL, *port = NULL;
struct addrinfo addrinfo;
bool ret = false;
if (!extract_sockaddr(serverurl, &url, &port)) {
LOGWARNING("Failed to extract server address from %s", serverurl);
goto out;
}
if (!addrinfo_from_url(url, port, &addrinfo)) {
LOGWARNING("Failed to extract addrinfo from url %s:%s", url, port);
goto out;
}
if (!url_from_sockaddr((const struct sockaddr *)&addrinfo, newurl, newport)) {
LOGWARNING("Failed to extract url from sockaddr for original url: %s:%s",
url, port);
goto out;
}
ret = true;
out:
dealloc(url);
dealloc(port);
return ret;
}
/* Convert a socket into a url and port. URL should be a string of /* Convert a socket into a url and port. URL should be a string of
* INET6_ADDRSTRLEN size, port at least a string of 6 bytes */ * INET6_ADDRSTRLEN size, port at least a string of 6 bytes */
bool url_from_socket(const int sockd, char *url, char *port) bool url_from_socket(const int sockd, char *url, char *port)

1
src/libckpool.h

@ -425,6 +425,7 @@ static inline bool sock_timeout(void)
bool extract_sockaddr(char *url, char **sockaddr_url, char **sockaddr_port); bool extract_sockaddr(char *url, char **sockaddr_url, char **sockaddr_port);
bool url_from_sockaddr(const struct sockaddr *addr, char *url, char *port); bool url_from_sockaddr(const struct sockaddr *addr, char *url, char *port);
bool addrinfo_from_url(const char *url, const char *port, struct addrinfo *addrinfo); bool addrinfo_from_url(const char *url, const char *port, struct addrinfo *addrinfo);
bool url_from_serverurl(char *serverurl, char *newurl, char *newport);
bool url_from_socket(const int sockd, char *url, char *port); bool url_from_socket(const int sockd, char *url, char *port);
void keep_sockalive(int fd); void keep_sockalive(int fd);

Loading…
Cancel
Save