Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
* ALPN support
* Reimplement configuration reloading
* Improved table backend lookup, currently this is a linear search
** Considering splitting hostname at label boundaries and search backwards from TLD
Expand Down
23 changes: 14 additions & 9 deletions sniproxy.conf
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,13 @@ listen [2001:0db8::10]:80 {
}

listen unix:/var/run/proxy.sock {
protocol http
# this will use default table
protocol tls alpn
table alpn_protocol_hosts
}

# named tables are defined with the table directive
table http_hosts {
example.com 192.0.2.10:8001
example.net 192.0.2.10:8002
example.org 192.0.2.10:8003

# Each table entry is composed of three parts:
# Each table entry is composed of two parts:
#
# pattern:
# valid Perl-compatible Regular Expression that matches the
Expand All @@ -85,13 +81,16 @@ table http_hosts {
# pattern target
#.*\.itunes\.apple\.com$ *:443
#.* 127.0.0.1:4443
example.com 192.0.2.10:8001
example.net 192.0.2.10:8002
example.org 192.0.2.10:8003
}

# named tables are defined with the table directive
table https_hosts {
# When proxying to local sockets you should use different tables since the
# local socket server most likely will not autodetect which protocol is
# being used
# local socket server most likely will not detect which protocol is being
# used
example.org unix:/var/run/server.sock
}

Expand All @@ -102,3 +101,9 @@ table {
example.com 192.0.2.10
example.net 192.0.2.20
}

table alpn_protocol_hosts {
http/1.1 192.0.2.31
http/2.0 192.0.2.32
spdy/3 192.0.2.33
}
5 changes: 4 additions & 1 deletion src/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,10 @@ parse_client_request(struct Connection *con) {
ssize_t payload_len = buffer_coalesce(con->client.buffer, (const void **)&payload);
char *hostname = NULL;

int result = con->listener->protocol->parse_packet(payload, payload_len, &hostname);
int result = con->listener->protocol->parse_packet(
con->listener->protocol_data,
payload, payload_len,
&hostname);
if (result < 0) {
char client[INET6_ADDRSTRLEN + 8];

Expand Down
4 changes: 2 additions & 2 deletions src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static const char http_503[] =
"Connection: close\r\n\r\n"
"Backend not available";

static int parse_http_header(const char *, size_t, char **);
static int parse_http_header(void *, const char *, size_t, char **);
static int get_header(const char *, const char *, int, char **);
static int next_header(const char **, int *);

Expand All @@ -66,7 +66,7 @@ const struct Protocol *const http_protocol = &http_protocol_st;
*
*/
static int
parse_http_header(const char* data, size_t data_len, char **hostname) {
parse_http_header(void *unused __attribute__((unused)), const char* data, size_t data_len, char **hostname) {
int result, i;

if (hostname == NULL)
Expand Down
54 changes: 45 additions & 9 deletions src/listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ new_listener() {
listener->address = NULL;
listener->fallback_address = NULL;
listener->source_address = NULL;
listener->protocol = tls_protocol;
listener->protocol = NULL;
listener->protocol_data = NULL;
listener->access_log = NULL;
listener->log_bad_requests = 0;

Expand Down Expand Up @@ -130,15 +131,33 @@ accept_listener_table_name(struct Listener *listener, char *table_name) {

int
accept_listener_protocol(struct Listener *listener, char *protocol) {
if (strncasecmp(protocol, http_protocol->name, strlen(protocol)) == 0)
size_t protocol_len = strlen(protocol);

if (listener->protocol == NULL
&& strncasecmp(protocol, http_protocol->name, protocol_len) == 0) {
listener->protocol = http_protocol;
else

return 1;
}

if (listener->protocol == NULL
&& strncasecmp(protocol, tls_protocol->name, protocol_len) == 0) {
listener->protocol = tls_protocol;
listener->protocol_data = new_tls_data();

if (address_port(listener->address) == 0)
address_set_port(listener->address, listener->protocol->default_port);
return 1;
}

return 1;
if (listener->protocol == tls_protocol
&& strncasecmp(protocol, "alpn", protocol_len) == 0) {
listener->protocol_data =
tls_data_use_alpn(listener->protocol_data, 1);

return 1;
}

fprintf(stderr, "unexpected additional argument on listener protocol: %s", protocol);
return -1;
}

int
Expand Down Expand Up @@ -261,8 +280,14 @@ valid_listener(const struct Listener *listener) {

int
init_listener(struct Listener *listener, const struct Table_head *tables) {
int sockfd;
int on = 1;
/* Default protocol to TLS if not set */
if (listener->protocol == NULL) {
listener->protocol = tls_protocol;
listener->protocol_data = new_tls_data();
}

if (address_port(listener->address) == 0)
address_set_port(listener->address, listener->protocol->default_port);

listener->table = table_lookup(tables, listener->table_name);
if (listener->table == NULL) {
Expand All @@ -271,20 +296,30 @@ init_listener(struct Listener *listener, const struct Table_head *tables) {
}
init_table(listener->table);

if (listener->protocol == tls_protocol
&& tls_data_alpn(listener->protocol_data)) {
struct Backend *iter;
STAILQ_FOREACH(iter, &listener->table->backends, entries) {
listener->protocol_data =
tls_data_append_alpn_protocol(listener->protocol_data, iter->name, strlen(iter->name));
}
}

/* If no port was specified on the fallback address, inherit the address
* from the listening address */
if (listener->fallback_address &&
address_port(listener->fallback_address) == 0)
address_set_port(listener->fallback_address,
address_port(listener->address));

sockfd = socket(address_sa(listener->address)->sa_family, SOCK_STREAM, 0);
int sockfd = socket(address_sa(listener->address)->sa_family, SOCK_STREAM, 0);
if (sockfd < 0) {
err("socket failed: %s", strerror(errno));
return -2;
}

/* set SO_REUSEADDR on server socket to facilitate restart */
int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

if (bind(sockfd, address_sa(listener->address),
Expand Down Expand Up @@ -396,6 +431,7 @@ free_listener(struct Listener *listener) {
free(listener->address);
free(listener->fallback_address);
free(listener->source_address);
free(listener->protocol_data);
free(listener->table_name);
free_logger(listener->access_log);
free(listener);
Expand Down
1 change: 1 addition & 0 deletions src/listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct Listener {
/* Configuration fields */
struct Address *address, *fallback_address, *source_address;
const struct Protocol *protocol;
void *protocol_data;
char *table_name;
struct Logger *access_log;
int log_bad_requests;
Expand Down
2 changes: 1 addition & 1 deletion src/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
struct Protocol {
const char *const name;
const int default_port;
int (*const parse_packet)(const char*, size_t, char **);
int (*const parse_packet)(void *, const char*, size_t, char **);
const char *const abort_message;
const size_t abort_message_len;
};
Expand Down
Loading