Another update for unix domain sockets support

* Changed initialization of variables and handling of unix socket path.
* Added fixes for command line argument parsing, that I forgot in previous
  commit.
This commit is contained in:
KLuka 2015-07-07 10:48:11 +02:00
parent c6186530bb
commit bdca920abc
3 changed files with 52 additions and 43 deletions

View file

@ -141,11 +141,10 @@ int x_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
#endif #endif
time_t currentTime; time_t currentTime;
char *unixDomainPath = NULL;
int unixDomainUser; int unixDomainUser = 0;
int unixDomainGroup; int unixDomainGroup = 0;
int unixDomainChmod; int unixDomainChmod = 0;
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,7 +290,7 @@ void initServer(struct Server *server, int localhostOnly, int portMin,
int true = 1; int true = 1;
if (*unixDomainSocket) { if (unixDomainPath && *unixDomainPath) {
server->serverFd = socket(AF_UNIX, SOCK_STREAM, 0); server->serverFd = socket(AF_UNIX, SOCK_STREAM, 0);
check(server->serverFd >= 0); check(server->serverFd >= 0);
@ -299,28 +298,30 @@ void initServer(struct Server *server, int localhostOnly, int portMin,
&true, sizeof(true))); &true, sizeof(true)));
struct stat st; struct stat st;
if (!stat(unixDomainSocket, &st) && S_ISSOCK(st.st_mode)) { if (!stat(unixDomainPath, &st) && S_ISSOCK(st.st_mode)) {
unlink(unixDomainSocket); unlink(unixDomainPath);
} }
struct sockaddr_un serverAddr = { 0 }; struct sockaddr_un serverAddr = { 0 };
serverAddr.sun_family = AF_UNIX; serverAddr.sun_family = AF_UNIX;
strcpy(serverAddr.sun_path, unixDomainSocket); strcpy(serverAddr.sun_path, unixDomainPath);
int servlen = sizeof(serverAddr.sun_family) int servlen = sizeof(serverAddr.sun_family)
+ strlen(unixDomainSocket); + strlen(unixDomainPath);
if (bind(server->serverFd, (struct sockaddr *)&serverAddr, servlen)) { if (bind(server->serverFd, (struct sockaddr *)&serverAddr, servlen)) {
fatal("Failed to bind to unix socket! [%d: %s]", errno, strerror(errno)); fatal("Failed to bind to unix socket! [%d: %s]", errno, strerror(errno));
} }
if (chown(unixDomainSocket, unixDomainUser, unixDomainGroup)) { if (chown(unixDomainPath, unixDomainUser, unixDomainGroup)) {
fatal("Unable to change ownership on unix socket!"); fatal("Unable to change ownership on unix socket! [%d: %s]",
errno, strerror(errno));
} }
if (chmod(unixDomainSocket, unixDomainChmod)) { if (chmod(unixDomainPath, unixDomainChmod)) {
fatal("Unable to change premission on unix socket!"); fatal("Unable to change premission on unix socket! [%d: %s)",
errno, strerror(errno));
} }
check(!listen(server->serverFd, SOMAXCONN)); check(!listen(server->serverFd, SOMAXCONN));
info("Listening on unix domain socket %s", unixDomainSocket); info("Listening on unix domain socket %s", unixDomainPath);
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;
@ -396,9 +397,12 @@ void destroyServer(struct Server *server) {
destroyTrie(&server->handlers); destroyTrie(&server->handlers);
destroySSL(&server->ssl); destroySSL(&server->ssl);
if (unixDomainPath) {
struct stat st; struct stat st;
if (*unixDomainSocket && !stat(unixDomainSocket, &st) && S_ISSOCK(st.st_mode)) { if (*unixDomainPath && !stat(unixDomainPath, &st) && S_ISSOCK(st.st_mode)) {
unlink(unixDomainSocket); unlink(unixDomainPath);
}
free(unixDomainPath);
} }
} }
} }

View file

@ -56,10 +56,6 @@
#define UNIX_PATH_MAX 108 #define UNIX_PATH_MAX 108
#endif #endif
extern int unixDomainUser;
extern int unixDomainGroup;
extern int unixDomainChmod;
extern char unixDomainSocket[UNIX_PATH_MAX];
struct Server; struct Server;
@ -130,5 +126,9 @@ void serverSetNumericHosts(struct Server *server, int numericHosts);
struct Trie *serverGetHttpHandlers(struct Server *server); struct Trie *serverGetHttpHandlers(struct Server *server);
extern time_t currentTime; extern time_t currentTime;
extern char *unixDomainPath;
extern int unixDomainUser;
extern int unixDomainGroup;
extern int unixDomainChmod;
#endif #endif

View file

@ -1139,34 +1139,39 @@ static void parseArgs(int argc, char * const argv[]) {
} }
char *ptr, *s, *tmp; char *ptr, *s, *tmp;
// Unix domain path
s = optarg; s = optarg;
ptr = strchr(s, ':'); ptr = strchr(s, ':');
if (ptr == NULL) { if (ptr == NULL || ptr == s || ptr - s >= UNIX_PATH_MAX) {
fatal("Syntax error in unixdomain-only definition \"%s\".", optarg); fatal("Syntax error in unixdomain-only path definition \"%s\".", optarg);
} }
check(ptr - s < UNIX_PATH_MAX); check(unixDomainPath = strndup(s, ptr - s));
memcpy(unixDomainSocket, s, ptr - s);
unixDomainSocket[ptr - s] = '\000';
// Unix domain user
s = ptr + 1; s = ptr + 1;
ptr = strchr(s, ':'); ptr = strchr(s, ':');
if (ptr == NULL) { if (ptr == NULL || ptr == s) {
fatal("Syntax error in unixdomain-only definition \"%s\".", optarg); fatal("Syntax error in unixdomain-only user definition \"%s\".", optarg);
} }
check(tmp = strndup(s, ptr - s)); check(tmp = strndup(s, ptr - s));
unixDomainUser = parseUserArg(tmp, NULL); unixDomainUser = parseUserArg(tmp, NULL);
free(tmp); free(tmp);
// Unix domain group
s = ptr + 1; s = ptr + 1;
ptr = strchr(s, ':'); ptr = strchr(s, ':');
if (ptr == NULL) { if (ptr == NULL || ptr == s) {
fatal("Syntax error in unixdomain-only definition \"%s\".", optarg); fatal("Syntax error in unixdomain-only group definition \"%s\".", optarg);
} }
check(tmp = strndup(s, ptr - s)); check(tmp = strndup(s, ptr - s));
unixDomainGroup = parseGroupArg(tmp, NULL); unixDomainGroup = parseGroupArg(tmp, NULL);
free(tmp); free(tmp);
// Unix domain chmod
s = ptr + 1; s = ptr + 1;
if (strlen(ptr) == 1) {
fatal("Syntax error in unixdomain-only chmod definition \"%s\".", optarg);
}
unixDomainChmod = strtol(s, NULL, 0); unixDomainChmod = strtol(s, NULL, 0);
} else if (!idx--) { } else if (!idx--) {