Minor fixes for unix domain sockets
* Improved user input checking and error handling for code from #320. * Added some guards for unlinking socket file in server init and destroy functions. * Added peer name handling for AF_UNIX type connections in HTTP handling code.
This commit is contained in:
parent
c7b41ad4ce
commit
c6186530bb
2 changed files with 36 additions and 17 deletions
|
@ -287,6 +287,14 @@ static char *getPeerName(int fd, int *port, int numericHosts) {
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
char *ret;
|
||||||
|
if (peerAddr.sa_family == AF_UNIX) {
|
||||||
|
if (port) {
|
||||||
|
*port = 0;
|
||||||
|
}
|
||||||
|
check(ret = strdup("localhost"));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
char host[256];
|
char host[256];
|
||||||
if (numericHosts ||
|
if (numericHosts ||
|
||||||
getnameinfo(&peerAddr, sockLen, host, sizeof(host), NULL, 0, NI_NOFQDN)){
|
getnameinfo(&peerAddr, sockLen, host, sizeof(host), NULL, 0, NI_NOFQDN)){
|
||||||
|
@ -297,7 +305,6 @@ static char *getPeerName(int fd, int *port, int numericHosts) {
|
||||||
if (port) {
|
if (port) {
|
||||||
*port = ntohs(((struct sockaddr_in *)&peerAddr)->sin_port);
|
*port = ntohs(((struct sockaddr_in *)&peerAddr)->sin_port);
|
||||||
}
|
}
|
||||||
char *ret;
|
|
||||||
check(ret = strdup(host));
|
check(ret = strdup(host));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,12 +140,12 @@ int x_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
|
||||||
#define poll x_poll
|
#define poll x_poll
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char unixDomainSocket[UNIX_PATH_MAX];
|
|
||||||
time_t currentTime;
|
time_t currentTime;
|
||||||
|
|
||||||
int unixDomainUser;
|
int unixDomainUser;
|
||||||
int unixDomainGroup;
|
int unixDomainGroup;
|
||||||
int unixDomainChmod;
|
int unixDomainChmod;
|
||||||
|
char unixDomainSocket[UNIX_PATH_MAX];
|
||||||
|
|
||||||
struct PayLoad {
|
struct PayLoad {
|
||||||
int (*handler)(struct HttpConnection *, void *, const char *, int);
|
int (*handler)(struct HttpConnection *, void *, const char *, int);
|
||||||
|
@ -291,27 +291,36 @@ void initServer(struct Server *server, int localhostOnly, int portMin,
|
||||||
|
|
||||||
int true = 1;
|
int true = 1;
|
||||||
|
|
||||||
if (unixDomainSocket[0]) {
|
if (*unixDomainSocket) {
|
||||||
|
|
||||||
server->serverFd = socket(AF_UNIX, SOCK_STREAM, 0);
|
server->serverFd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
check(server->serverFd >= 0);
|
check(server->serverFd >= 0);
|
||||||
check(!setsockopt(server->serverFd, SOL_SOCKET, SO_REUSEADDR,
|
check(!setsockopt(server->serverFd, SOL_SOCKET, SO_REUSEADDR,
|
||||||
&true, sizeof(true)));
|
&true, sizeof(true)));
|
||||||
struct sockaddr_un serverAddr = { 0 };
|
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (!stat(unixDomainSocket, &st) && S_ISSOCK(st.st_mode)) {
|
||||||
unlink(unixDomainSocket);
|
unlink(unixDomainSocket);
|
||||||
|
|
||||||
serverAddr.sun_family = AF_UNIX;
|
|
||||||
strcpy(serverAddr.sun_path, unixDomainSocket);
|
|
||||||
int servlen = sizeof(serverAddr.sun_family) + strlen(unixDomainSocket);
|
|
||||||
|
|
||||||
if (bind(server->serverFd, (struct sockaddr *)&serverAddr, servlen)) {
|
|
||||||
fatal("Failed to bind to unix socket");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check(!chown(unixDomainSocket, unixDomainUser, unixDomainGroup));
|
struct sockaddr_un serverAddr = { 0 };
|
||||||
check(!chmod(unixDomainSocket, unixDomainChmod));
|
serverAddr.sun_family = AF_UNIX;
|
||||||
|
strcpy(serverAddr.sun_path, unixDomainSocket);
|
||||||
|
int servlen = sizeof(serverAddr.sun_family)
|
||||||
|
+ strlen(unixDomainSocket);
|
||||||
|
|
||||||
|
if (bind(server->serverFd, (struct sockaddr *)&serverAddr, servlen)) {
|
||||||
|
fatal("Failed to bind to unix socket! [%d: %s]", errno, strerror(errno));
|
||||||
|
}
|
||||||
|
if (chown(unixDomainSocket, unixDomainUser, unixDomainGroup)) {
|
||||||
|
fatal("Unable to change ownership on unix socket!");
|
||||||
|
}
|
||||||
|
if (chmod(unixDomainSocket, unixDomainChmod)) {
|
||||||
|
fatal("Unable to change premission on unix socket!");
|
||||||
|
}
|
||||||
|
|
||||||
check(!listen(server->serverFd, SOMAXCONN));
|
check(!listen(server->serverFd, SOMAXCONN));
|
||||||
|
info("Listening on unix domain socket %s", unixDomainSocket);
|
||||||
check(server->pollFds = malloc(sizeof(struct pollfd)));
|
check(server->pollFds = malloc(sizeof(struct pollfd)));
|
||||||
server->pollFds->fd = server->serverFd;
|
server->pollFds->fd = server->serverFd;
|
||||||
server->pollFds->events = POLLIN;
|
server->pollFds->events = POLLIN;
|
||||||
|
@ -387,7 +396,10 @@ void destroyServer(struct Server *server) {
|
||||||
destroyTrie(&server->handlers);
|
destroyTrie(&server->handlers);
|
||||||
destroySSL(&server->ssl);
|
destroySSL(&server->ssl);
|
||||||
|
|
||||||
if (unixDomainSocket[0]) unlink(unixDomainSocket);
|
struct stat st;
|
||||||
|
if (*unixDomainSocket && !stat(unixDomainSocket, &st) && S_ISSOCK(st.st_mode)) {
|
||||||
|
unlink(unixDomainSocket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue