C websockify: added pid file creation/removal for daemon & SIGHUP handler to reload whitelist.

This commit is contained in:
Samuel Brian 2016-11-07 16:36:13 +10:00
parent 6a87f5bfb2
commit 0ec8b7008c
3 changed files with 93 additions and 45 deletions

View File

@ -706,9 +706,16 @@ ws_ctx_t *do_handshake(int sock) {
void signal_handler(sig) { void signal_handler(sig) {
switch (sig) { switch (sig) {
case SIGHUP: break; // ignore for now case SIGHUP:
if (settings.whitelist != NULL) {
load_whitelist();
}
break;
case SIGPIPE: pipe_error = 1; break; // handle inline case SIGPIPE: pipe_error = 1; break; // handle inline
case SIGTERM: exit(0); break; case SIGTERM:
remove(settings.pid);
exit(0);
break;
} }
} }
@ -727,7 +734,17 @@ void daemonize(int keepfd) {
setsid(); // Obtain new process group setsid(); // Obtain new process group
pid = fork(); pid = fork();
if (pid<0) { fatal("fork error"); } if (pid<0) { fatal("fork error"); }
if (pid>0) { exit(0); } // parent exits if (pid>0) {
// parent exits
FILE *pidf = fopen(settings.pid, "w");
if (pidf) {
fprintf(pidf, "%d", pid);
fclose(pidf);
} else {
fprintf(stderr, "Could not write daemon PID file '%s': %s\n", settings.pid, strerror(errno));
}
exit(0);
}
/* Signal handling */ /* Signal handling */
signal(SIGHUP, signal_handler); // catch HUP signal(SIGHUP, signal_handler); // catch HUP

View File

@ -68,6 +68,7 @@ typedef struct {
int run_once; int run_once;
char *whitelist; char *whitelist;
char *pattern; char *pattern;
char *pid;
} settings_t; } settings_t;

View File

@ -17,6 +17,7 @@
#include <sys/select.h> #include <sys/select.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <signal.h>
#include "websocket.h" #include "websocket.h"
char traffic_legend[] = "\n\ char traffic_legend[] = "\n\
@ -40,7 +41,8 @@ char USAGE[] = "Usage: [options] " \
" --ssl-only disallow non-encrypted connections\n" \ " --ssl-only disallow non-encrypted connections\n" \
" --whitelist|-w LIST new-line separated target port whitelist file\n" \ " --whitelist|-w LIST new-line separated target port whitelist file\n" \
" (target_port is not required only with this option)\n" \ " (target_port is not required only with this option)\n" \
" --pattern|-p target port request pattern. Default: '/%d'"; " --pattern|-P target port request pattern. Default: '/%d'\n" \
" --pid|-p desired path of pid file. Default: '/var/run/websockify.pid'";
#define usage(fmt, args...) \ #define usage(fmt, args...) \
do { \ do { \
@ -298,6 +300,62 @@ void proxy_handler(ws_ctx_t *ws_ctx) {
close(tsock); close(tsock);
} }
int load_whitelist() {
printf("loading port whitelist '%s'\n", settings.whitelist);
FILE *whitelist = fopen(settings.whitelist, "r");
if (whitelist == NULL) {
fprintf(stderr, "Error opening whitelist file '%s':\n\t%s\n",
settings.whitelist, strerror(errno));
return -1;
}
const int tplen_grow = 512;
int tplen = tplen_grow, tpcount = 0;
target_ports = (int*)malloc(tplen*sizeof(int));
if (target_ports == NULL) {
fprintf(stderr, "Whitelist port malloc error");
return -2;
}
char *line = NULL;
ssize_t n = 0, nread = 0;
while ((nread = getline(&line, &n, whitelist)) > 0) {
if (line[0] == '\n') continue;
line[nread-1] = '\x00';
long int port = strtol(line, NULL, 10);
if (port < 1 || port > 65535) {
fprintf(stderr,
"Whitelist port '%s' is not between valid range 1 and 65535", line);
return -3;
}
tpcount++;
if (tpcount >= tplen) {
tplen += tplen_grow;
target_ports = (int*)realloc(target_ports, tplen*sizeof(int));
if (target_ports == NULL) {
fprintf(stderr, "Whitelist port realloc error");
return -2;
}
}
target_ports[tpcount-1] = port;
}
if (line != NULL) free(line);
if (tpcount == 0) {
fprintf(stderr, "0 ports read from whitelist file '%s'\n",
settings.whitelist);
return -4;
}
target_ports = (int*)realloc(target_ports, (tpcount + 1)*sizeof(int));
if (target_ports == NULL) {
fprintf(stderr, "Whitelist port realloc error");
return -2;
}
target_ports[tpcount] = 0;
return 0;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int fd, c, option_index = 0; int fd, c, option_index = 0;
@ -311,7 +369,8 @@ int main(int argc, char *argv[])
{"cert", required_argument, 0, 'c'}, {"cert", required_argument, 0, 'c'},
{"key", required_argument, 0, 'k'}, {"key", required_argument, 0, 'k'},
{"whitelist", required_argument, 0, 'w'}, {"whitelist", required_argument, 0, 'w'},
{"pattern", required_argument, 0, 'p'}, {"pattern", required_argument, 0, 'P'},
{"pid", required_argument, 0, 'p'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
@ -322,9 +381,10 @@ int main(int argc, char *argv[])
} }
settings.key = ""; settings.key = "";
settings.pattern = "/%d"; settings.pattern = "/%d";
settings.pid = "/var/run/websockify.pid";
while (1) { while (1) {
c = getopt_long (argc, argv, "vDrc:k:w:p:", c = getopt_long (argc, argv, "vDrc:k:w:p:P:",
long_options, &option_index); long_options, &option_index);
/* Detect the end */ /* Detect the end */
@ -362,6 +422,12 @@ int main(int argc, char *argv[])
usage("No whitelist file at %s\n", optarg); usage("No whitelist file at %s\n", optarg);
} }
break; break;
case 'P':
settings.pattern = optarg;
break;
case 'p':
settings.pid = optarg;
break;
default: default:
usage(" "); usage(" ");
} }
@ -390,45 +456,9 @@ int main(int argc, char *argv[])
target_port = strtol(found+1, NULL, 10); target_port = strtol(found+1, NULL, 10);
target_ports = NULL; target_ports = NULL;
} else if (!found && settings.whitelist != NULL) { } else if (!found && settings.whitelist != NULL) {
FILE *whitelist = fopen(settings.whitelist, "r"); if (load_whitelist()) {
if (whitelist == NULL) { usage("Whitelist error.");
usage("Error opening whitelist file '%s':\n\t%s\n",
settings.whitelist, strerror(errno));
} }
const int tplen_grow = 512;
int tplen = tplen_grow, tpcount = 0;
target_ports = (int*)malloc(tplen*sizeof(int));
if (target_ports == NULL) usage("Whitelist port malloc error");
char *line = NULL;
ssize_t n = 0, nread = 0;
while ((nread = getline(&line, &n, whitelist)) > 0) {
if (line[0] == '\n') continue;
line[nread-1] = '\x00';
long int port = strtol(line, NULL, 10);
if (port < 1 || port > 65535) {
usage("Whitelist port '%s' is not between valid range 1 and 65535",
line);
}
tpcount++;
if (tpcount >= tplen) {
tplen += tplen_grow;
target_ports = (int*)realloc(target_ports, tplen*sizeof(int));
if (target_ports == NULL) usage("Whitelist port realloc error");
}
target_ports[tpcount-1] = port;
}
if (line != NULL) free(line);
if (tpcount == 0) {
usage("0 ports read from whitelist file '%s'\n", settings.whitelist);
}
target_ports = (int*)realloc(target_ports, (tpcount + 1)*sizeof(int));
if (target_ports == NULL) usage("Whitelist port realloc error");
target_ports[tpcount] = 0;
memcpy(target_host, argv[optind], strlen(argv[optind])); memcpy(target_host, argv[optind], strlen(argv[optind]));
target_port = -1; target_port = -1;