Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added statuslistener #358

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
5 changes: 5 additions & 0 deletions sniproxy.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ group nogroup
# PID file, needs to be placed in directory writable by user
pidfile /var/run/sniproxy.pid

# This will return a list of connections that aren't in the access_log yet.
# It doesn't matter what request you send, it will always repond with a http ok
# header followed by the list
statuslistener 8080

# The DNS resolver is required for tables configured using wildcard or hostname
# targets. If no resolver is specified, the nameserver and search domain are
# loaded from /etc/resolv.conf.
Expand Down
8 changes: 6 additions & 2 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ static struct Keyword global_grammar[] = {
.block_grammar=table_stanza_grammar,
.finalize=(int(*)(void *, void *))end_table_stanza,
},
{
.keyword="statuslistener",
.create=(void *(*)())new_statuslistener,
.parse_arg=(int(*)(void *, const char *))accept_listener_arg,
.finalize=(int(*)(void *, void *))end_listener_stanza,
},
{
.keyword = NULL,
},
Expand Down Expand Up @@ -378,8 +384,6 @@ accept_pidfile(struct Config *config, const char *pidfile) {

static int
end_listener_stanza(struct Config *config, struct Listener *listener) {
listener->accept_cb = &accept_connection;

if (valid_listener(listener) <= 0) {
err("Invalid listener");
print_listener_config(stderr, listener);
Expand Down
90 changes: 64 additions & 26 deletions src/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static struct Connection *new_connection(struct ev_loop *);
static void log_connection(struct Connection *);
static void log_bad_request(struct Connection *, const char *, size_t, int);
static void free_connection(struct Connection *);
static void print_connection(FILE *, const struct Connection *);
static void print_connection(int, const struct Connection *);
static void free_resolv_cb_data(struct resolv_cb_data *);


Expand Down Expand Up @@ -161,6 +161,42 @@ accept_connection(struct Listener *listener, struct ev_loop *loop) {
return 1;
}

/**
* Accept a new incoming connection that will report the status
*
* Returns 1 on success or 0 on error;
*/
int
accept_statusconnection(struct Listener *listener, struct ev_loop * loop) {
(void)loop;
struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);

#ifdef HAVE_ACCEPT4
int sockfd = accept4(listener->watcher.fd,
(struct sockaddr *)&addr,
&addr_len,
SOCK_NONBLOCK);
#else
int sockfd = accept(listener->watcher.fd,
(struct sockaddr *)&addr,
&addr_len);
#endif
if (sockfd < 0) {
int saved_errno = errno;

warn("accept failed: %s", strerror(errno));

errno = saved_errno;
return 0;
}
const char *header = "HTTP/1.1 200 OK\n\n";
write(sockfd , header , strlen(header));
print_connections(sockfd);
close(sockfd);
return 1;
}

/*
* Close and free all connections
*/
Expand All @@ -174,9 +210,18 @@ free_connections(struct ev_loop *loop) {
}
}

/* dumps a list of all connections for debugging */
/* dumps a list of all connections to the file descriptor*/
void
print_connections(int fd) {
struct Connection *iter;
TAILQ_FOREACH(iter, &connections, entries)
print_connection(fd, iter);
return;
}

/* dumps a list of all connections for debugging to a temporary file */
void
print_connections() {
print_connections_file() {
char filename[] = "/tmp/sniproxy-connections-XXXXXX";

int fd = mkstemp(filename);
Expand All @@ -185,19 +230,11 @@ print_connections() {
return;
}

FILE *temp = fdopen(fd, "w");
if (temp == NULL) {
warn("fdopen failed: %s", strerror(errno));
return;
}
dprintf(fd, "Running connections:\n");
print_connections(fd);

fprintf(temp, "Running connections:\n");
struct Connection *iter;
TAILQ_FOREACH(iter, &connections, entries)
print_connection(temp, iter);

if (fclose(temp) < 0)
warn("fclose failed: %s", strerror(errno));
if (close(fd) < 0)
warn("close failed: %s", strerror(errno));

notice("Dumped connections to %s", filename);
}
Expand Down Expand Up @@ -896,53 +933,54 @@ free_connection(struct Connection *con) {
}

static void
print_connection(FILE *file, const struct Connection *con) {
print_connection(int file, const struct Connection *con) {
char client[INET6_ADDRSTRLEN + 8];
char server[INET6_ADDRSTRLEN + 8];

switch (con->state) {
case NEW:
fprintf(file, "NEW -\t-\n");
dprintf(file, "NEW\t-\t-\n");
break;
case ACCEPTED:
fprintf(file, "ACCEPTED %s %zu/%zu\t-\n",
dprintf(file, "ACCEPTED\t%s %zu/%zu\t-\n",
display_sockaddr(&con->client.addr, client, sizeof(client)),
buffer_len(con->client.buffer), buffer_size(con->client.buffer));
break;
case PARSED:
fprintf(file, "PARSED %s %zu/%zu\t-\n",
dprintf(file, "PARSED\t%s %zu/%zu\t-\n",
display_sockaddr(&con->client.addr, client, sizeof(client)),
buffer_len(con->client.buffer), buffer_size(con->client.buffer));
break;
case RESOLVING:
fprintf(file, "RESOLVING %s %zu/%zu\t-\n",
dprintf(file, "RESOLVING\t%s %zu/%zu\t-\n",
display_sockaddr(&con->client.addr, client, sizeof(client)),
buffer_len(con->client.buffer), buffer_size(con->client.buffer));
break;
case RESOLVED:
fprintf(file, "RESOLVED %s %zu/%zu\t-\n",
dprintf(file, "RESOLVED\t%s %zu/%zu\t-\n",
display_sockaddr(&con->client.addr, client, sizeof(client)),
buffer_len(con->client.buffer), buffer_size(con->client.buffer));
break;
case CONNECTED:
fprintf(file, "CONNECTED %s %zu/%zu\t%s %zu/%zu\n",
dprintf(file, "CONNECTED\t%s %zu/%zu\t%s %zu/%zu\t%s\n",
display_sockaddr(&con->client.addr, client, sizeof(client)),
buffer_len(con->client.buffer), buffer_size(con->client.buffer),
display_sockaddr(&con->server.addr, server, sizeof(server)),
buffer_len(con->server.buffer), buffer_size(con->server.buffer));
buffer_len(con->server.buffer), buffer_size(con->server.buffer),
con->hostname);
break;
case SERVER_CLOSED:
fprintf(file, "SERVER_CLOSED %s %zu/%zu\t-\n",
dprintf(file, "SERVER_CLOSED\t%s %zu/%zu\t-\n",
display_sockaddr(&con->client.addr, client, sizeof(client)),
buffer_len(con->client.buffer), buffer_size(con->client.buffer));
break;
case CLIENT_CLOSED:
fprintf(file, "CLIENT_CLOSED -\t%s %zu/%zu\n",
dprintf(file, "CLIENT_CLOSED\t-\t%s %zu/%zu\n",
display_sockaddr(&con->server.addr, server, sizeof(server)),
buffer_len(con->server.buffer), buffer_size(con->server.buffer));
break;
case CLOSED:
fprintf(file, "CLOSED -\t-\n");
dprintf(file, "CLOSED\t-\t-\n");
break;
}
}
4 changes: 3 additions & 1 deletion src/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ struct Connection {

void init_connections();
int accept_connection(struct Listener *, struct ev_loop *);
int accept_statusconnection(struct Listener *, struct ev_loop *);
void free_connections(struct ev_loop *);
void print_connections();
void print_connections_file();
void print_connections(int);

#endif
25 changes: 19 additions & 6 deletions src/listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "protocol.h"
#include "tls.h"
#include "http.h"
#include "connection.h"

static void close_listener(struct ev_loop *, struct Listener *);
static void accept_cb(struct ev_loop *, struct ev_io *, int);
Expand Down Expand Up @@ -226,10 +227,18 @@ new_listener() {
ev_io_init(&listener->watcher, accept_cb, -1, EV_READ);
ev_timer_init(&listener->backoff_timer, backoff_timer_cb, 0.0, 0.0);
listener->table = NULL;
listener->accept_cb = &accept_connection;

return listener;
}

struct Listener *
new_statuslistener() {
struct Listener * listener = new_listener();
listener->accept_cb = &accept_statusconnection;
return listener;
}

int
accept_listener_arg(struct Listener *listener, const char *arg) {
if (listener->address == NULL && !is_numeric(arg)) {
Expand Down Expand Up @@ -493,13 +502,17 @@ static int
init_listener(struct Listener *listener, const struct Table_head *tables,
struct ev_loop *loop) {
char address[ADDRESS_BUFFER_SIZE];
struct Table *table = table_lookup(tables, listener->table_name);
if (table == NULL) {
err("Table \"%s\" not defined", listener->table_name);
return -1;

if (listener->accept_cb != &accept_statusconnection) {
struct Table *table = table_lookup(tables, listener->table_name);
if (table == NULL) {
err("Table \"%s\" not defined", listener->table_name);
return -1;
}

init_table(table);
listener->table = table_ref_get(table);
}
init_table(table);
listener->table = table_ref_get(table);

/* If no port was specified on the fallback address, inherit the address
* from the listening address */
Expand Down
1 change: 1 addition & 0 deletions src/listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct Listener {


struct Listener *new_listener();
struct Listener *new_statuslistener();
int accept_listener_arg(struct Listener *, const char *);
int accept_listener_table_name(struct Listener *, const char *);
int accept_listener_fallback_address(struct Listener *, const char *);
Expand Down
2 changes: 1 addition & 1 deletion src/sniproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ signal_cb(struct ev_loop *loop, struct ev_signal *w, int revents) {
reload_config(config, loop);
break;
case SIGUSR1:
print_connections();
print_connections_file();
break;
case SIGINT:
case SIGTERM:
Expand Down