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;
|
||||
}
|
||||
char *ret;
|
||||
if (peerAddr.sa_family == AF_UNIX) {
|
||||
if (port) {
|
||||
*port = 0;
|
||||
}
|
||||
check(ret = strdup("localhost"));
|
||||
return ret;
|
||||
}
|
||||
char host[256];
|
||||
if (numericHosts ||
|
||||
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) {
|
||||
*port = ntohs(((struct sockaddr_in *)&peerAddr)->sin_port);
|
||||
}
|
||||
char *ret;
|
||||
check(ret = strdup(host));
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -140,12 +140,12 @@ int x_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
|
|||
#define poll x_poll
|
||||
#endif
|
||||
|
||||
char unixDomainSocket[UNIX_PATH_MAX];
|
||||
time_t currentTime;
|
||||
|
||||
int unixDomainUser;
|
||||
int unixDomainGroup;
|
||||
int unixDomainChmod;
|
||||
char unixDomainSocket[UNIX_PATH_MAX];
|
||||
|
||||
struct PayLoad {
|
||||
int (*handler)(struct HttpConnection *, void *, const char *, int);
|
||||
|
@ -291,27 +291,36 @@ void initServer(struct Server *server, int localhostOnly, int portMin,
|
|||
|
||||
int true = 1;
|
||||
|
||||
if (unixDomainSocket[0]) {
|
||||
server->serverFd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (*unixDomainSocket) {
|
||||
|
||||
server->serverFd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
check(server->serverFd >= 0);
|
||||
check(!setsockopt(server->serverFd, SOL_SOCKET, SO_REUSEADDR,
|
||||
&true, sizeof(true)));
|
||||
struct sockaddr_un serverAddr = { 0 };
|
||||
&true, sizeof(true)));
|
||||
|
||||
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");
|
||||
struct stat st;
|
||||
if (!stat(unixDomainSocket, &st) && S_ISSOCK(st.st_mode)) {
|
||||
unlink(unixDomainSocket);
|
||||
}
|
||||
|
||||
check(!chown(unixDomainSocket, unixDomainUser, unixDomainGroup));
|
||||
check(!chmod(unixDomainSocket, unixDomainChmod));
|
||||
struct sockaddr_un serverAddr = { 0 };
|
||||
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));
|
||||
info("Listening on unix domain socket %s", unixDomainSocket);
|
||||
check(server->pollFds = malloc(sizeof(struct pollfd)));
|
||||
server->pollFds->fd = server->serverFd;
|
||||
server->pollFds->events = POLLIN;
|
||||
|
@ -387,7 +396,10 @@ void destroyServer(struct Server *server) {
|
|||
destroyTrie(&server->handlers);
|
||||
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