proxy: always multiprocess and add --verbose.
Always fork handlers processes. Instead printing traffic when single-processing, print traffic if verbose flag given.
This commit is contained in:
parent
f1b4494504
commit
59bc03a23a
@ -45,7 +45,7 @@ unsigned int bufsize, dbufsize;
|
|||||||
settings_t settings;
|
settings_t settings;
|
||||||
|
|
||||||
void traffic(char * token) {
|
void traffic(char * token) {
|
||||||
if ((! settings.daemon) && (! settings.multiprocess)) {
|
if ((settings.verbose) && (! settings.daemon)) {
|
||||||
fprintf(stdout, "%s", token);
|
fprintf(stdout, "%s", token);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
@ -427,7 +427,7 @@ void daemonize(int keepfd) {
|
|||||||
for (i=getdtablesize(); i>=0; --i) {
|
for (i=getdtablesize(); i>=0; --i) {
|
||||||
if (i != keepfd) {
|
if (i != keepfd) {
|
||||||
close(i);
|
close(i);
|
||||||
} else {
|
} else if (settings.verbose) {
|
||||||
printf("keeping fd %d\n", keepfd);
|
printf("keeping fd %d\n", keepfd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -480,21 +480,16 @@ void start_server() {
|
|||||||
daemonize(lsock);
|
daemonize(lsock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.multiprocess) {
|
// Reep zombies
|
||||||
printf("Waiting for connections on %s:%d\n",
|
signal(SIGCHLD, SIG_IGN);
|
||||||
settings.listen_host, settings.listen_port);
|
|
||||||
// Reep zombies
|
printf("Waiting for connections on %s:%d\n",
|
||||||
signal(SIGCHLD, SIG_IGN);
|
settings.listen_host, settings.listen_port);
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
clilen = sizeof(cli_addr);
|
clilen = sizeof(cli_addr);
|
||||||
pipe_error = 0;
|
pipe_error = 0;
|
||||||
pid = 0;
|
pid = 0;
|
||||||
if (! settings.multiprocess) {
|
|
||||||
printf("Waiting for connection on %s:%d\n",
|
|
||||||
settings.listen_host, settings.listen_port);
|
|
||||||
}
|
|
||||||
csock = accept(lsock,
|
csock = accept(lsock,
|
||||||
(struct sockaddr *) &cli_addr,
|
(struct sockaddr *) &cli_addr,
|
||||||
&clilen);
|
&clilen);
|
||||||
@ -508,21 +503,15 @@ void start_server() {
|
|||||||
* 20 for WS '\x00' / '\xff' and good measure */
|
* 20 for WS '\x00' / '\xff' and good measure */
|
||||||
dbufsize = (bufsize * 3)/4 - 20;
|
dbufsize = (bufsize * 3)/4 - 20;
|
||||||
|
|
||||||
if (settings.multiprocess) {
|
handler_msg("forking handler process\n");
|
||||||
handler_msg("forking handler process\n");
|
pid = fork();
|
||||||
pid = fork();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid == 0) { // handler process
|
if (pid == 0) { // handler process
|
||||||
ws_ctx = do_handshake(csock);
|
ws_ctx = do_handshake(csock);
|
||||||
if (ws_ctx == NULL) {
|
if (ws_ctx == NULL) {
|
||||||
close(csock);
|
close(csock);
|
||||||
if (settings.multiprocess) {
|
handler_msg("No connection after handshake");
|
||||||
handler_msg("No connection after handshake");
|
break; // Child process exits
|
||||||
break; // Child process exits
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.handler(ws_ctx);
|
settings.handler(ws_ctx);
|
||||||
@ -530,10 +519,8 @@ void start_server() {
|
|||||||
handler_emsg("Closing due to SIGPIPE\n");
|
handler_emsg("Closing due to SIGPIPE\n");
|
||||||
}
|
}
|
||||||
close(csock);
|
close(csock);
|
||||||
if (settings.multiprocess) {
|
handler_msg("handler exit\n");
|
||||||
handler_msg("handler exit\n");
|
break; // Child process exits
|
||||||
break; // Child process exits
|
|
||||||
}
|
|
||||||
} else { // parent process
|
} else { // parent process
|
||||||
settings.handler_id += 1;
|
settings.handler_id += 1;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,13 @@ typedef struct {
|
|||||||
} ws_ctx_t;
|
} ws_ctx_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
int verbose;
|
||||||
char listen_host[256];
|
char listen_host[256];
|
||||||
int listen_port;
|
int listen_port;
|
||||||
void (*handler)(ws_ctx_t*);
|
void (*handler)(ws_ctx_t*);
|
||||||
int handler_id;
|
int handler_id;
|
||||||
int ssl_only;
|
int ssl_only;
|
||||||
int daemon;
|
int daemon;
|
||||||
int multiprocess;
|
|
||||||
char *record;
|
char *record;
|
||||||
char *cert;
|
char *cert;
|
||||||
} settings_t;
|
} settings_t;
|
||||||
@ -38,11 +38,7 @@ ssize_t ws_send(ws_ctx_t *ctx, const void *buf, size_t len);
|
|||||||
|
|
||||||
#define gen_handler_msg(stream, ...) \
|
#define gen_handler_msg(stream, ...) \
|
||||||
if (! settings.daemon) { \
|
if (! settings.daemon) { \
|
||||||
if (settings.multiprocess) { \
|
fprintf(stream, " %d: ", settings.handler_id); \
|
||||||
fprintf(stream, " %d: ", settings.handler_id); \
|
|
||||||
} else { \
|
|
||||||
fprintf(stream, " "); \
|
|
||||||
} \
|
|
||||||
fprintf(stream, __VA_ARGS__); \
|
fprintf(stream, __VA_ARGS__); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ from urlparse import urlsplit
|
|||||||
from cgi import parse_qsl
|
from cgi import parse_qsl
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
|
'verbose' : False,
|
||||||
'listen_host' : '',
|
'listen_host' : '',
|
||||||
'listen_port' : None,
|
'listen_port' : None,
|
||||||
'handler' : None,
|
'handler' : None,
|
||||||
@ -29,7 +30,6 @@ settings = {
|
|||||||
'cert' : None,
|
'cert' : None,
|
||||||
'ssl_only' : False,
|
'ssl_only' : False,
|
||||||
'daemon' : True,
|
'daemon' : True,
|
||||||
'multiprocess': False,
|
|
||||||
'record' : None, }
|
'record' : None, }
|
||||||
|
|
||||||
server_handshake = """HTTP/1.1 101 Web Socket Protocol Handshake\r
|
server_handshake = """HTTP/1.1 101 Web Socket Protocol Handshake\r
|
||||||
@ -47,16 +47,13 @@ class EClose(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def traffic(token="."):
|
def traffic(token="."):
|
||||||
if not settings['daemon'] and not settings['multiprocess']:
|
if settings['verbose'] and not settings['daemon']:
|
||||||
sys.stdout.write(token)
|
sys.stdout.write(token)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
def handler_msg(msg):
|
def handler_msg(msg):
|
||||||
if not settings['daemon']:
|
if not settings['daemon']:
|
||||||
if settings['multiprocess']:
|
print " %d: %s" % (settings['handler_id'], msg)
|
||||||
print " %d: %s" % (settings['handler_id'], msg)
|
|
||||||
else:
|
|
||||||
print " %s" % msg
|
|
||||||
|
|
||||||
def encode(buf):
|
def encode(buf):
|
||||||
buf = b64encode(buf)
|
buf = b64encode(buf)
|
||||||
@ -172,7 +169,7 @@ def daemonize(keepfd=None):
|
|||||||
try:
|
try:
|
||||||
if fd != keepfd:
|
if fd != keepfd:
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
else:
|
elif settings['verbose']:
|
||||||
print "Keeping fd: %d" % fd
|
print "Keeping fd: %d" % fd
|
||||||
except OSError, exc:
|
except OSError, exc:
|
||||||
if exc.errno != errno.EBADF: raise
|
if exc.errno != errno.EBADF: raise
|
||||||
@ -193,34 +190,27 @@ def start_server():
|
|||||||
if settings['daemon']:
|
if settings['daemon']:
|
||||||
daemonize(keepfd=lsock.fileno())
|
daemonize(keepfd=lsock.fileno())
|
||||||
|
|
||||||
if settings['multiprocess']:
|
# Reep zombies
|
||||||
print 'Waiting for connections on %s:%s' % (
|
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
|
||||||
settings['listen_host'], settings['listen_port'])
|
|
||||||
# Reep zombies
|
print 'Waiting for connections on %s:%s' % (
|
||||||
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
|
settings['listen_host'], settings['listen_port'])
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
csock = startsock = None
|
csock = startsock = None
|
||||||
pid = 0
|
pid = 0
|
||||||
if not settings['multiprocess']:
|
|
||||||
print 'Waiting for connection on %s:%s' % (
|
|
||||||
settings['listen_host'], settings['listen_port'])
|
|
||||||
startsock, address = lsock.accept()
|
startsock, address = lsock.accept()
|
||||||
handler_msg('got client connection from %s' % address[0])
|
handler_msg('got client connection from %s' % address[0])
|
||||||
|
|
||||||
if settings['multiprocess']:
|
handler_msg("forking handler process")
|
||||||
handler_msg("forking handler process")
|
pid = os.fork()
|
||||||
pid = os.fork()
|
|
||||||
|
|
||||||
if pid == 0: # handler process
|
if pid == 0: # handler process
|
||||||
csock = do_handshake(startsock)
|
csock = do_handshake(startsock)
|
||||||
if not csock:
|
if not csock:
|
||||||
if settings['multiprocess']:
|
handler_msg("No connection after handshake");
|
||||||
handler_msg("No connection after handshake");
|
break
|
||||||
break
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
settings['handler'](csock)
|
settings['handler'](csock)
|
||||||
else: # parent process
|
else: # parent process
|
||||||
settings['handler_id'] += 1
|
settings['handler_id'] += 1
|
||||||
@ -234,5 +224,4 @@ def start_server():
|
|||||||
if pid == 0:
|
if pid == 0:
|
||||||
if csock: csock.close()
|
if csock: csock.close()
|
||||||
if startsock and startsock != csock: startsock.close()
|
if startsock and startsock != csock: startsock.close()
|
||||||
|
break # Child process exits
|
||||||
if settings['multiprocess']: break # Child process exits
|
|
||||||
|
@ -230,7 +230,7 @@ void proxy_handler(ws_ctx_t *ws_ctx) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((! settings.daemon) && (! settings.multiprocess)) {
|
if ((settings.verbose) && (! settings.daemon)) {
|
||||||
printf("%s", traffic_legend);
|
printf("%s", traffic_legend);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,12 +242,12 @@ void proxy_handler(ws_ctx_t *ws_ctx) {
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int fd, c, option_index = 0;
|
int fd, c, option_index = 0;
|
||||||
static int ssl_only = 0, foreground = 0, multi = 0;
|
static int ssl_only = 0, foreground = 0, verbose = 0;
|
||||||
char *found;
|
char *found;
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
|
{"verbose", no_argument, &verbose, 'v'},
|
||||||
{"ssl-only", no_argument, &ssl_only, 1 },
|
{"ssl-only", no_argument, &ssl_only, 1 },
|
||||||
{"foreground", no_argument, &foreground, 'f'},
|
{"foreground", no_argument, &foreground, 'f'},
|
||||||
{"multiprocess", no_argument, &multi, 'm'},
|
|
||||||
/* ---- */
|
/* ---- */
|
||||||
{"cert", required_argument, 0, 'c'},
|
{"cert", required_argument, 0, 'c'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
@ -256,7 +256,7 @@ int main(int argc, char *argv[])
|
|||||||
settings.cert = realpath("self.pem", NULL);
|
settings.cert = realpath("self.pem", NULL);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
c = getopt_long (argc, argv, "fmc:",
|
c = getopt_long (argc, argv, "vfc:",
|
||||||
long_options, &option_index);
|
long_options, &option_index);
|
||||||
|
|
||||||
/* Detect the end */
|
/* Detect the end */
|
||||||
@ -267,12 +267,12 @@ int main(int argc, char *argv[])
|
|||||||
break; // ignore
|
break; // ignore
|
||||||
case 1:
|
case 1:
|
||||||
break; // ignore
|
break; // ignore
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
foreground = 1;
|
foreground = 1;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
|
||||||
multi = 1;
|
|
||||||
break;
|
|
||||||
case 'r':
|
case 'r':
|
||||||
if ((fd = open(optarg, O_CREAT,
|
if ((fd = open(optarg, O_CREAT,
|
||||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < -1) {
|
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < -1) {
|
||||||
@ -290,9 +290,9 @@ int main(int argc, char *argv[])
|
|||||||
usage("");
|
usage("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
settings.verbose = verbose;
|
||||||
settings.ssl_only = ssl_only;
|
settings.ssl_only = ssl_only;
|
||||||
settings.daemon = foreground ? 0: 1;
|
settings.daemon = foreground ? 0: 1;
|
||||||
settings.multiprocess = multi;
|
|
||||||
|
|
||||||
if ((argc-optind) != 2) {
|
if ((argc-optind) != 2) {
|
||||||
usage("Invalid number of arguments\n");
|
usage("Invalid number of arguments\n");
|
||||||
@ -329,9 +329,9 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//printf(" verbose: %d\n", settings.verbose);
|
||||||
//printf(" ssl_only: %d\n", settings.ssl_only);
|
//printf(" ssl_only: %d\n", settings.ssl_only);
|
||||||
//printf(" daemon: %d\n", settings.daemon);
|
//printf(" daemon: %d\n", settings.daemon);
|
||||||
//printf(" multiproces: %d\n", settings.multiprocess);
|
|
||||||
//printf(" cert: %s\n", settings.cert);
|
//printf(" cert: %s\n", settings.cert);
|
||||||
|
|
||||||
settings.handler = proxy_handler;
|
settings.handler = proxy_handler;
|
||||||
|
@ -112,7 +112,7 @@ def proxy_handler(client):
|
|||||||
tsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
tsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
tsock.connect((target_host, target_port))
|
tsock.connect((target_host, target_port))
|
||||||
|
|
||||||
if not settings['daemon'] and not settings['multiprocess']:
|
if settings['verbose'] and not settings['daemon']:
|
||||||
print traffic_legend
|
print traffic_legend
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -128,14 +128,13 @@ if __name__ == '__main__':
|
|||||||
usage = "%prog [--record FILE]"
|
usage = "%prog [--record FILE]"
|
||||||
usage += " [source_addr:]source_port target_addr:target_port"
|
usage += " [source_addr:]source_port target_addr:target_port"
|
||||||
parser = optparse.OptionParser(usage=usage)
|
parser = optparse.OptionParser(usage=usage)
|
||||||
|
parser.add_option("--verbose", "-v", action="store_true",
|
||||||
|
help="verbose messages and per frame traffic")
|
||||||
parser.add_option("--record",
|
parser.add_option("--record",
|
||||||
help="record session to a file", metavar="FILE")
|
help="record session to a file", metavar="FILE")
|
||||||
parser.add_option("--foreground", "-f",
|
parser.add_option("--foreground", "-f",
|
||||||
dest="daemon", default=True, action="store_false",
|
dest="daemon", default=True, action="store_false",
|
||||||
help="stay in foreground, do not daemonize")
|
help="stay in foreground, do not daemonize")
|
||||||
parser.add_option("--multiprocess", "-m",
|
|
||||||
dest="multiprocess", action="store_true",
|
|
||||||
help="fork handler processes")
|
|
||||||
parser.add_option("--ssl-only", action="store_true",
|
parser.add_option("--ssl-only", action="store_true",
|
||||||
help="disallow non-encrypted connections")
|
help="disallow non-encrypted connections")
|
||||||
parser.add_option("--cert", default="self.pem",
|
parser.add_option("--cert", default="self.pem",
|
||||||
@ -160,13 +159,13 @@ if __name__ == '__main__':
|
|||||||
if options.ssl_only and not os.path.exists(options.cert):
|
if options.ssl_only and not os.path.exists(options.cert):
|
||||||
parser.error("SSL only and %s not found" % options.cert)
|
parser.error("SSL only and %s not found" % options.cert)
|
||||||
|
|
||||||
|
settings['verbose'] = options.verbose
|
||||||
settings['listen_host'] = host
|
settings['listen_host'] = host
|
||||||
settings['listen_port'] = port
|
settings['listen_port'] = port
|
||||||
settings['handler'] = proxy_handler
|
settings['handler'] = proxy_handler
|
||||||
settings['cert'] = os.path.abspath(options.cert)
|
settings['cert'] = os.path.abspath(options.cert)
|
||||||
settings['ssl_only'] = options.ssl_only
|
settings['ssl_only'] = options.ssl_only
|
||||||
settings['daemon'] = options.daemon
|
settings['daemon'] = options.daemon
|
||||||
settings['multiprocess'] = options.multiprocess
|
|
||||||
if options.record:
|
if options.record:
|
||||||
settings['record'] = os.path.abspath(options.record)
|
settings['record'] = os.path.abspath(options.record)
|
||||||
start_server()
|
start_server()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user