Commit c53fae30 authored by Antoine Catton's avatar Antoine Catton

Patch shellinabox in order to support listening on IPv6

parent e788d280
No related merge requests found
From 50ec7439e80bd6a77346dc6482895e481d8cd43a Mon Sep 17 00:00:00 2001
From: Antoine Catton <acatton@tiolive.com>
Date: Tue, 10 Jan 2012 18:30:20 +0100
Subject: [PATCH] Switch to IPv6
---
libhttp/http.h | 4 ++--
libhttp/httpconnection.c | 11 ++++++++++-
libhttp/server.c | 33 +++++++++++++++++++--------------
libhttp/server.h | 6 +++---
shellinabox/shellinaboxd.c | 14 +++++++-------
5 files changed, 41 insertions(+), 27 deletions(-)
diff --git a/libhttp/http.h b/libhttp/http.h
index e7840fa..5cd61e3 100644
--- a/libhttp/http.h
+++ b/libhttp/http.h
@@ -66,8 +66,8 @@ typedef struct ServerConnection ServerConnection;
typedef struct Server Server;
typedef struct URL URL;
-Server *newCGIServer(int localhostOnly, int portMin, int portMax, int timeout);
-Server *newServer(int localhostOnly, int port);
+Server *newCGIServer(char *ipv6, int portMin, int portMax, int timeout);
+Server *newServer(char *ipv6, int port);
void deleteServer(Server *server);
int serverGetListeningPort(Server *server);
int serverGetFd(Server *server);
diff --git a/libhttp/httpconnection.c b/libhttp/httpconnection.c
index c8e69f6..cae467f 100644
--- a/libhttp/httpconnection.c
+++ b/libhttp/httpconnection.c
@@ -823,8 +823,17 @@ static int httpHandleCommand(struct HttpConnection *http,
const char *host = getFromHashMap(&http->header,
"host");
if (host) {
+ int brackets = 0; // For IPv6 hosts
for (char ch; (ch = *host) != '\000'; host++) {
- if (ch == ':') {
+ if (ch == '[') {
+ brackets = 1;
+ break;
+ }
+ if (ch == ']') {
+ brackets = 0;
+ break;
+ }
+ if (!brackets && ch == ':') {
*(char *)host = '\000';
break;
}
diff --git a/libhttp/server.c b/libhttp/server.c
index f52a269..2c30bd8 100644
--- a/libhttp/server.c
+++ b/libhttp/server.c
@@ -170,19 +170,19 @@ static int serverQuitHandler(struct HttpConnection *http, void *arg) {
return HTTP_DONE;
}
-struct Server *newCGIServer(int localhostOnly, int portMin, int portMax,
+struct Server *newCGIServer(char *ipv6, int portMin, int portMax,
int timeout) {
struct Server *server;
check(server = malloc(sizeof(struct Server)));
- initServer(server, localhostOnly, portMin, portMax, timeout);
+ initServer(server, ipv6, portMin, portMax, timeout);
return server;
}
-struct Server *newServer(int localhostOnly, int port) {
- return newCGIServer(localhostOnly, port, port, -1);
+struct Server *newServer(char *ipv6, int port) {
+ return newCGIServer(ipv6, port, port, -1);
}
-void initServer(struct Server *server, int localhostOnly, int portMin,
+void initServer(struct Server *server, char *ipv6, int portMin,
int portMax, int timeout) {
server->looping = 0;
server->exitAll = 0;
@@ -192,14 +192,19 @@ void initServer(struct Server *server, int localhostOnly, int portMin,
server->numConnections = 0;
int true = 1;
- server->serverFd = socket(PF_INET, SOCK_STREAM, 0);
+ server->serverFd = socket(PF_INET6, SOCK_STREAM, 0);
check(server->serverFd >= 0);
check(!setsockopt(server->serverFd, SOL_SOCKET, SO_REUSEADDR,
&true, sizeof(true)));
- struct sockaddr_in serverAddr = { 0 };
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_addr.s_addr = htonl(localhostOnly
- ? INADDR_LOOPBACK : INADDR_ANY);
+ struct sockaddr_in6 serverAddr = { 0 };
+ serverAddr.sin6_family = AF_INET6;
+ if (ipv6 != NULL) {
+ if (!inet_pton(AF_INET6, ipv6, serverAddr.sin6_addr.s6_addr)) {
+ fatal("Bad ipv6 address");
+ }
+ } else {
+ serverAddr.sin6_addr = in6addr_any;
+ }
// Linux unlike BSD does not have support for picking a local port range.
// So, we have to randomly pick a port from our allowed port range, and then
@@ -214,14 +219,14 @@ void initServer(struct Server *server, int localhostOnly, int portMin,
int portStart = rand() % (portMax - portMin + 1) + portMin;
for (int p = 0; p <= portMax-portMin; p++) {
int port = (p+portStart)%(portMax-portMin+1)+ portMin;
- serverAddr.sin_port = htons(port);
+ serverAddr.sin6_port = htons(port);
if (!bind(server->serverFd, (struct sockaddr *)&serverAddr,
sizeof(serverAddr))) {
break;
}
- serverAddr.sin_port = 0;
+ serverAddr.sin6_port = 0;
}
- if (!serverAddr.sin_port) {
+ if (!serverAddr.sin6_port) {
fatal("Failed to find any available port");
}
}
@@ -231,7 +236,7 @@ void initServer(struct Server *server, int localhostOnly, int portMin,
check(!getsockname(server->serverFd, (struct sockaddr *)&serverAddr,
&socklen));
check(socklen == sizeof(serverAddr));
- server->port = ntohs(serverAddr.sin_port);
+ server->port = ntohs(serverAddr.sin6_port);
info("Listening on port %d", server->port);
check(server->pollFds = malloc(sizeof(struct pollfd)));
diff --git a/libhttp/server.h b/libhttp/server.h
index bb879fb..5ffb698 100644
--- a/libhttp/server.h
+++ b/libhttp/server.h
@@ -78,10 +78,10 @@ struct Server {
struct SSLSupport ssl;
};
-struct Server *newCGIServer(int localhostOnly, int portMin, int portMax,
+struct Server *newCGIServer(char *ipv6, int portMin, int portMax,
int timeout);
-struct Server *newServer(int localhostOnly, int port);
-void initServer(struct Server *server, int localhostOnly, int portMin,
+struct Server *newServer(char *ipv6, int port);
+void initServer(struct Server *server, char *ipv6, int portMin,
int portMax, int timeout);
void destroyServer(struct Server *server);
void deleteServer(struct Server *server);
diff --git a/shellinabox/shellinaboxd.c b/shellinabox/shellinaboxd.c
index dcf05ff..2d1d758 100644
--- a/shellinabox/shellinaboxd.c
+++ b/shellinabox/shellinaboxd.c
@@ -80,7 +80,7 @@
static int port;
static int portMin;
static int portMax;
-static int localhostOnly = 0;
+static char *ipv6 = NULL;
static int noBeep = 0;
static int numericHosts = 0;
static int enableSSL = 1;
@@ -747,7 +747,7 @@ static void usage(void) {
" -g, --group=GID switch to this group (default: %s)\n"
" -h, --help print this message\n"
" --linkify=[none|normal|agressive] default is \"normal\"\n"
- " --localhost-only only listen on 127.0.0.1\n"
+ " --ipv6 listen on a specific ipv6\n"
" --no-beep suppress all audio output\n"
" -n, --numeric do not resolve hostnames\n"
" -p, --port=PORT select a port (default: %d)\n"
@@ -839,7 +839,7 @@ static void parseArgs(int argc, char * const argv[]) {
{ "static-file", 1, 0, 'f' },
{ "group", 1, 0, 'g' },
{ "linkify", 1, 0, 0 },
- { "localhost-only", 0, 0, 0 },
+ { "ipv6", 1, 0, 0 },
{ "no-beep", 0, 0, 0 },
{ "numeric", 0, 0, 'n' },
{ "port", 1, 0, 'p' },
@@ -1001,8 +1001,8 @@ static void parseArgs(int argc, char * const argv[]) {
"\"none\", \"normal\", or \"aggressive\".");
}
} else if (!idx--) {
- // Localhost Only
- localhostOnly = 1;
+ // IPv6
+ ipv6 = optarg;
} else if (!idx--) {
// No Beep
noBeep = 1;
@@ -1197,7 +1197,7 @@ int main(int argc, char * const argv[]) {
// Create a new web server
Server *server;
if (port) {
- check(server = newServer(localhostOnly, port));
+ check(server = newServer(ipv6, port));
dropPrivileges();
setUpSSL(server);
} else {
@@ -1217,7 +1217,7 @@ int main(int argc, char * const argv[]) {
_exit(0);
}
check(!NOINTR(close(fds[0])));
- check(server = newCGIServer(localhostOnly, portMin, portMax,
+ check(server = newCGIServer(ipv6, portMin, portMax,
AJAX_TIMEOUT));
cgiServer = server;
setUpSSL(server);
--
1.7.6.5
......@@ -2,9 +2,16 @@
extends =
../zlib/buildout.cfg
../openssl/buildout.cfg
../patch/buildout.cfg
parts = shellinabox
[shellinabox-ipv6-patch]
recipe = hexagonit.recipe.download
filename = 0001-Switch-to-IPv6.patch
url = ${:_profile_base_location_}/${:filename}
download-only = true
[shellinabox]
recipe = hexagonit.recipe.cmmi
url = http://shellinabox.googlecode.com/files/shellinabox-2.10.tar.gz
......@@ -13,3 +20,7 @@ environment =
CFLAGS = -I${zlib:location}/include -I${openssl:location}/include
LDFLAGS = -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${openssl:location}/lib -Wl,-rpath=${openssl:location}/lib
PKG_CONFIG_PATH = ${openssl:location}/lib/pkgconfig/
patch-binary = ${patch:location}/bin/patch
patch-options = -p1
patches =
${shellinabox-ipv6-patch:location}/${shellinabox-ipv6-patch:filename}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment