wswrap: WSWRAP_PORT envvar and wswrap script.
wswrapper.so will only interpose on the listen port specified in WSWRAP_PORT. Add simple wswrap script that sets the WSWRAP_PORT, LD_PRELOAD and invokes the command line to wrap.
This commit is contained in:
parent
e46719100c
commit
70c585968b
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $(basename $0) PORT CMDLINE"
|
||||||
|
echo
|
||||||
|
echo " PORT Port to wrap with WebSockets support"
|
||||||
|
echo " CMDLINE Command line to wrap"
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parameter defaults
|
||||||
|
mydir=$(dirname ${0})
|
||||||
|
|
||||||
|
# Process parameters
|
||||||
|
#while [ "${1}" != "${1#-}" ]; do
|
||||||
|
# param=$1; shift
|
||||||
|
#done
|
||||||
|
|
||||||
|
export WSWRAP_PORT="${1}"; shift
|
||||||
|
|
||||||
|
LD_PRELOAD=${mydir}/wswrapper.so "${@}"
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
/*
|
||||||
|
* wswrap/wswrapper: Add WebSockets support to any service.
|
||||||
|
* Copyright 2010 Joel Martin
|
||||||
|
* Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
|
||||||
|
*
|
||||||
|
* Use wswrap to run a program using the wrapper.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* WARNING: multi-threaded programs are not supported */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -47,14 +57,25 @@ Connection: Upgrade\r\n\
|
||||||
%sWebSocket-Protocol: sample\r\n\
|
%sWebSocket-Protocol: sample\r\n\
|
||||||
\r\n%s";
|
\r\n%s";
|
||||||
|
|
||||||
/* WARNING: threading not supported */
|
/*
|
||||||
|
* If WSWRAP_PORT environment variable is set then listen to the bind fd that
|
||||||
|
* matches WSWRAP_PORT, otherwise listen to the first socket fd that bind is
|
||||||
|
* called on.
|
||||||
|
*/
|
||||||
|
int _WS_listen_fd = 0;
|
||||||
|
int _WS_sockfd = 0;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char _WS_rbuf[65536];
|
||||||
|
char _WS_sbuf[65536];
|
||||||
|
} _WS_connection;
|
||||||
|
|
||||||
int _WS_bufsize = 65536;
|
int _WS_bufsize = 65536;
|
||||||
char *_WS_rbuf = NULL;
|
char *_WS_rbuf = NULL;
|
||||||
char *_WS_sbuf = NULL;
|
char *_WS_sbuf = NULL;
|
||||||
int _WS_rcarry_cnt = 0;
|
int _WS_rcarry_cnt = 0;
|
||||||
char _WS_rcarry[3] = "";
|
char _WS_rcarry[3] = "";
|
||||||
int _WS_newframe = 1;
|
int _WS_newframe = 1;
|
||||||
int _WS_sockfd = 0;
|
|
||||||
|
|
||||||
int _WS_init() {
|
int _WS_init() {
|
||||||
if (! (_WS_rbuf = malloc(_WS_bufsize)) ) {
|
if (! (_WS_rbuf = malloc(_WS_bufsize)) ) {
|
||||||
|
@ -525,16 +546,48 @@ int socket(int domain, int type, int protocol)
|
||||||
|
|
||||||
return (int) func(domain, type, protocol);
|
return (int) func(domain, type, protocol);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
static void * (*func)();
|
static void * (*func)();
|
||||||
|
struct sockaddr_in * addr_in = (struct sockaddr_in *)addr;
|
||||||
|
char * WSWRAP_PORT, * end;
|
||||||
|
int fd, envport, bindport = htons(addr_in->sin_port);
|
||||||
if (!func) func = (void *(*)()) dlsym(RTLD_NEXT, "bind");
|
if (!func) func = (void *(*)()) dlsym(RTLD_NEXT, "bind");
|
||||||
DEBUG("bind(%d, _, %d) called\n", sockfd, addrlen);
|
DEBUG("bind(%d, _, %d) called\n", sockfd, addrlen);
|
||||||
|
|
||||||
return (int) func(sockfd, addr, addrlen);
|
fd = (int) func(sockfd, addr, addrlen);
|
||||||
|
|
||||||
|
if (addr_in->sin_family != AF_INET) {
|
||||||
|
// TODO: handle IPv6
|
||||||
|
DEBUG("bind, ignoring non-IPv4 socket\n");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
WSWRAP_PORT = getenv("WSWRAP_PORT");
|
||||||
|
if ((! WSWRAP_PORT) || (*WSWRAP_PORT == '\0')) {
|
||||||
|
// TODO: interpose on all sockets
|
||||||
|
DEBUG("bind, not interposing: WSWRAP_PORT is not set\n");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
envport = strtol(WSWRAP_PORT, &end, 10);
|
||||||
|
if ((envport == 0) || (*end != '\0')) {
|
||||||
|
MSG("bind, not interposing: WSWRAP_PORT is not a number\n");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (envport != bindport) {
|
||||||
|
DEBUG("bind, not interposing on port %d\n", bindport);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG("bind, interposing on port: %d\n", envport);
|
||||||
|
_WS_listen_fd = envport;
|
||||||
|
|
||||||
|
return fd;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||||
{
|
{
|
||||||
|
@ -545,7 +598,13 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||||
|
|
||||||
fd = (int) func(sockfd, addr, addrlen);
|
fd = (int) func(sockfd, addr, addrlen);
|
||||||
|
|
||||||
|
if (_WS_listen_fd == 0) {
|
||||||
|
DEBUG("not interposing\n");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
if (_WS_sockfd == 0) {
|
if (_WS_sockfd == 0) {
|
||||||
|
// TODO: not just first connection
|
||||||
_WS_sockfd = fd;
|
_WS_sockfd = fd;
|
||||||
|
|
||||||
if (!_WS_rbuf) {
|
if (!_WS_rbuf) {
|
||||||
|
|
Loading…
Reference in New Issue