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
16 changes: 16 additions & 0 deletions sniproxy.conf
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,17 @@ listen 80 {

listen 443 {
proto tls

# The prefer keyword enables sniproxy to select which handler
# will take precedence if both ALPN and SNI tables are set, and
# the client sends both extensions.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to nest the backend selection, i.e. the alpn table points to an sni table?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most should be fixed now except that. I can't say I fully understand what you propose, but it does look a bit more complex to me. I guess you suggest making the backend list, a tree?


prefer alpn
# prefer sni

table https_hosts
ALPNtable service_hosts
fallback localhost:8080
}

listen 192.0.2.10:80 {
Expand Down Expand Up @@ -85,3 +95,9 @@ table {
example.com 192.0.2.10
example.net 192.0.2.20
}

ALPNtable service_hosts {
http/1.1 192.0.2.10
http/2.0 192.0.2.20
spdy/3 192.0.2.25
}
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ sniproxy_SOURCES = address.c \
connection.h \
http.c \
http.h \
types.h \
listener.c \
listener.h \
logger.c \
Expand Down
10 changes: 6 additions & 4 deletions src/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,17 @@ init_backend(struct Backend *backend) {
}

struct Backend *
lookup_backend(const struct Backend_head *head, const char *hostname) {
lookup_backend(const struct Backend_head *head, const char *name, size_t name_size) {
struct Backend *iter;

if (hostname == NULL)
hostname = "";
if (name == NULL) {
name = "";
name_size = 0;
}

STAILQ_FOREACH(iter, head, entries)
if (pcre_exec(iter->hostname_re, NULL,
hostname, strlen(hostname), 0, 0, NULL, 0) >= 0)
name, name_size, 0, 0, NULL, 0) >= 0)
return iter;

return NULL;
Expand Down
4 changes: 2 additions & 2 deletions src/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
STAILQ_HEAD(Backend_head, Backend);

struct Backend {
char *hostname;
char *hostname; /* name actually */
struct Address *address;

/* Runtime fields */
Expand All @@ -44,7 +44,7 @@ struct Backend {

void add_backend(struct Backend_head *, struct Backend *);
int init_backend(struct Backend *);
struct Backend *lookup_backend(const struct Backend_head *, const char *);
struct Backend *lookup_backend(const struct Backend_head *, const char *, size_t);
int open_backend_socket(struct Backend *, const char *);
void print_backend_config(FILE *, const struct Backend *);
void remove_backend(struct Backend_head *, struct Backend *);
Expand Down
39 changes: 39 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ static int accept_username(struct Config *, char *);
static int accept_pidfile(struct Config *, char *);
static int end_listener_stanza(struct Config *, struct Listener *);
static int end_table_stanza(struct Config *, struct Table *);
static int end_alpn_table_stanza(struct Config *, struct Table *);
static int end_backend(struct Table *, struct Backend *);
static struct LoggerBuilder *new_logger_builder();
static int accept_logger_filename(struct LoggerBuilder *, char *);
Expand All @@ -55,11 +56,21 @@ struct Keyword listener_stanza_grammar[] = {
(int(*)(void *, char *))accept_listener_protocol,
NULL,
NULL},
{ "prefer",
NULL,
(int(*)(void *, char *))prefer_in_listener,
NULL,
NULL},
{ "table",
NULL,
(int(*)(void *, char *))accept_listener_table_name,
NULL,
NULL},
{ "ALPNtable",
NULL,
(int(*)(void *, char *))accept_listener_alpn_table_name,
NULL,
NULL},
{ "fallback",
NULL,
(int(*)(void *, char *))accept_listener_fallback_address,
Expand All @@ -76,6 +87,14 @@ static struct Keyword table_stanza_grammar[] = {
(int(*)(void *, void *))end_backend},
};

static struct Keyword alpn_table_stanza_grammar[] = {
{ NULL,
(void *(*)())new_backend,
(int(*)(void *, char *))accept_backend_arg,
NULL,
(int(*)(void *, void *))end_backend},
};

static struct Keyword logger_stanza_grammar[] = {
{ "filename",
NULL,
Expand Down Expand Up @@ -121,6 +140,11 @@ static struct Keyword global_grammar[] = {
(int(*)(void *, char *))accept_table_arg,
table_stanza_grammar,
(int(*)(void *, void *))end_table_stanza},
{ "ALPNtable",
(void *(*)())new_table,
(int(*)(void *, char *))accept_table_arg,
alpn_table_stanza_grammar,
(int(*)(void *, void *))end_alpn_table_stanza},
{ NULL, NULL, NULL, NULL, NULL }
};

Expand All @@ -142,6 +166,7 @@ init_config(const char *filename) {
config->pidfile = NULL;
SLIST_INIT(&config->listeners);
SLIST_INIT(&config->tables);
SLIST_INIT(&config->alpn_tables);

config->filename = strdup(filename);
if (config->filename == NULL) {
Expand Down Expand Up @@ -186,6 +211,7 @@ free_config(struct Config *config) {
free_listeners(&config->listeners);

free_tables(&config->tables);
free_tables(&config->alpn_tables);

free(config);
}
Expand Down Expand Up @@ -224,6 +250,10 @@ print_config(FILE *file, struct Config *config) {
SLIST_FOREACH(table, &config->tables, entries) {
print_table_config(file, table);
}

SLIST_FOREACH(table, &config->alpn_tables, entries) {
print_table_config(file, table);
}
}

static int
Expand Down Expand Up @@ -271,6 +301,15 @@ end_table_stanza(struct Config *config, struct Table *table) {
return 1;
}

static int
end_alpn_table_stanza(struct Config *config, struct Table *table) {
/* TODO check table */

add_table(&config->alpn_tables, table);

return 1;
}

static int
end_backend(struct Table *table, struct Backend *backend) {
/* TODO check backend */
Expand Down
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct Config {
char *pidfile;
struct Listener_head listeners;
struct Table_head tables;
struct Table_head alpn_tables;
};

struct Config *init_config(const char *);
Expand Down
20 changes: 14 additions & 6 deletions src/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,14 +299,15 @@ static void
handle_connection_client_hello(struct Connection *con, struct ev_loop *loop) {
char buffer[1460]; /* TCP MSS over standard Ethernet and IPv4 */
ssize_t len;
char *hostname = NULL;
int parse_result;
char peer_ip[INET6_ADDRSTRLEN + 8];
int sockfd = -1;
struct ProtocolRes pres;

len = buffer_peek(con->client.buffer, buffer, sizeof(buffer));

parse_result = con->listener->protocol->parse_packet(buffer, len, &hostname);
parse_result = con->listener->protocol->parse_packet(con->listener, buffer, len,
&pres);
if (parse_result == -1) {
return; /* incomplete request: try again */
} else if (parse_result < -1) {
Expand All @@ -329,12 +330,19 @@ handle_connection_client_hello(struct Connection *con, struct ev_loop *loop) {
return;
}
}
con->hostname = hostname;
con->hostname = pres.name;

if (pres.name == NULL) {
warn("name returned from parse_packet is null");
return;
}

/* TODO break the remainder out into other states */

/* lookup server for hostname and connect */
/* lookup server for name and connect */
struct Address *server_address =
listener_lookup_server_address(con->listener, hostname);
listener_lookup_server_address(con->listener, pres.name, pres.name_size, pres.name_type);

if (server_address == NULL) {
close_client_socket(con, loop);
return;
Expand Down Expand Up @@ -399,7 +407,7 @@ handle_connection_client_hello(struct Connection *con, struct ev_loop *loop) {
}

if (sockfd < 0) {
warn("Server connection failed to %s", hostname);
warn("Server connection failed to %.*s", pres.name_size, pres.name);
close_client_socket(con, loop);
return;
}
Expand Down
19 changes: 13 additions & 6 deletions src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,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(const struct Listener *, const char*, size_t, struct ProtocolRes*);
static int get_header(const char *, const char *, int, char **);
static int next_header(const char **, int *);

Expand All @@ -69,13 +69,15 @@ const struct Protocol *http_protocol = &http_protocol_st;
*
*/
static int
parse_http_header(const char* data, size_t data_len, char **hostname) {
parse_http_header(const struct Listener * t, const char* data, size_t data_len,
struct ProtocolRes* pres) {
int result, i;
char* hostname;

if (hostname == NULL)
if (pres == NULL)
return -3;

result = get_header("Host:", data, data_len, hostname);
result = get_header("Host:", data, data_len, &hostname);
if (result < 0)
return result;

Expand All @@ -85,12 +87,17 @@ parse_http_header(const char* data, size_t data_len, char **hostname) {
* so we trim off port portion
*/
for (i = result - 1; i >= 0; i--)
if ((*hostname)[i] == ':') {
(*hostname)[i] = '\0';
if (hostname[i] == ':') {
hostname[i] = '\0';
result = i;

break;
}

pres->name = hostname;
pres->name_size = result;
pres->name_type = NTYPE_HOST;

return result;
}

Expand Down
Loading