added tuntaprouter stats

This commit is contained in:
Unbit
2013-12-14 16:16:28 +01:00
parent b44c2208d9
commit 22bf9b33b0
3 changed files with 117 additions and 5 deletions
+7 -2
View File
@@ -160,7 +160,7 @@ retry:
}
// receive a packet from the client
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp) {
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp, int is_router) {
// get body
if (uttp->header_pos >= 4) {
ssize_t rlen = read(uttp->fd, uttp->buf + uttp->buf_pos, uttp->buf_pktsize - uttp->buf_pos);
@@ -180,11 +180,13 @@ int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tun
uttp->header_pos = 0;
uttp->buf_pos = 0;
if (!is_router) goto enqueue;
if (uwsgi_tuntap_firewall_check(utt.fw_out, uttp->buf, uttp->buf_pktsize)) return 0;
// if there is no associated address store the source
if (!uttp->addr) {
uint32_t *src_ip = (uint32_t *) & uttp->buf[12];
uint32_t *src_ip = (uint32_t *) (&uttp->buf[12]);
uttp->addr = *src_ip;
// drop invalid ip addresses
if (!uttp->addr)
@@ -202,8 +204,11 @@ int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tun
uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
}
uwsgi_log("[tuntap-router] registered new peer %s (fd: %d)\n", ip, uttp->fd);
memcpy(uttp->ip, ip, INET_ADDRSTRLEN + 1);
}
enqueue:
memcpy(uttr->write_buf, uttp->buf, uttp->buf_pktsize);
uttr->write_pktsize = uttp->buf_pktsize;
uwsgi_tuntap_enqueue(uttr);
+4 -1
View File
@@ -15,6 +15,7 @@
struct uwsgi_tuntap_peer {
int fd;
uint32_t addr;
char ip[INET_ADDRSTRLEN+1];
int wait_for_write;
int blocked_read;
size_t written;
@@ -54,6 +55,7 @@ struct uwsgi_tuntap_router {
uint16_t write_pktsize;
uint16_t write_pos;
int wait_for_write;
int stats_server_fd;
};
struct uwsgi_tuntap {
@@ -62,9 +64,10 @@ struct uwsgi_tuntap {
uint16_t buffer_size;
struct uwsgi_tuntap_firewall_rule *fw_in;
struct uwsgi_tuntap_firewall_rule *fw_out;
char *stats_server;
};
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *);
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *, int);
int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *);
void uwsgi_tuntap_enqueue(struct uwsgi_tuntap_router *);
+106 -2
View File
@@ -61,6 +61,7 @@ static struct uwsgi_option uwsgi_tuntap_options[] = {
{"tuntap-device", required_argument, 0, "add a tuntap device to the instance (syntax: <device>[ <socket>])", uwsgi_opt_add_string_list, &utt.devices, 0},
{"tuntap-router-firewall-in", required_argument, 0, "add a firewall rule to the tuntap router (syntax: <action> <src/mask> <dst/mask>)", uwsgi_tuntap_opt_firewall, &utt.fw_in, 0},
{"tuntap-router-firewall-out", required_argument, 0, "add a firewall rule to the tuntap router (syntax: <action> <src/mask> <dst/mask>)", uwsgi_tuntap_opt_firewall, &utt.fw_out, 0},
{"tuntap-router-stats", required_argument, 0, "run the tuntap router stats server", uwsgi_opt_set_str, &utt.stats_server, 0},
{NULL, 0, 0, NULL, NULL, NULL, 0},
};
@@ -132,7 +133,7 @@ static void *uwsgi_tuntap_loop(void *arg) {
if (interesting_fd == uttr->server_fd) {
// read from the client
if (!uttp->wait_for_write) {
if (uwsgi_tuntap_peer_dequeue(uttr, uttp)) {
if (uwsgi_tuntap_peer_dequeue(uttr, uttp, 0)) {
uwsgi_log("server disconnected...\n");
exit(1);
}
@@ -185,6 +186,8 @@ static void uwsgi_tuntap_client() {
}
}
void tuntaprouter_send_stats(struct uwsgi_tuntap_router *);
void uwsgi_tuntap_router_loop(int id, void *arg) {
int i;
@@ -193,12 +196,31 @@ void uwsgi_tuntap_router_loop(int id, void *arg) {
uttr->write_buf = uwsgi_malloc(utt.buffer_size);
uttr->queue = event_queue_init();
uttr->stats_server_fd = -1;
void *events = event_queue_alloc(64);
if (event_queue_add_fd_read(uttr->queue, uttr->server_fd))
exit(1);
if (event_queue_add_fd_read(uttr->queue, uttr->fd))
exit(1);
if (utt.stats_server) {
char *tcp_port = strchr(utt.stats_server, ':');
if (tcp_port) {
// disable deferred accept for this socket
int current_defer_accept = uwsgi.no_defer_accept;
uwsgi.no_defer_accept = 1;
uttr->stats_server_fd = bind_to_tcp(utt.stats_server, uwsgi.listen_queue, tcp_port);
uwsgi.no_defer_accept = current_defer_accept;
}
else {
uttr->stats_server_fd = bind_to_unix(utt.stats_server, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
}
if (event_queue_add_fd_read(uttr->queue, uttr->stats_server_fd)) exit(1);
uwsgi_log("*** tuntap stats server enabled on %s fd: %d ***\n", utt.stats_server, uttr->stats_server_fd);
}
for (;;) {
int nevents = event_queue_wait_multi(uttr->queue, -1, events, 64);
for (i = 0; i < nevents; i++) {
@@ -255,12 +277,17 @@ void uwsgi_tuntap_router_loop(int id, void *arg) {
continue;
}
if (uttr->stats_server_fd > -1 && interesting_fd == uttr->stats_server_fd) {
tuntaprouter_send_stats(uttr);
continue;
}
struct uwsgi_tuntap_peer *uttp = uttr->peers_head;
while (uttp) {
if (interesting_fd == uttp->fd) {
// read from the client
if (event_queue_interesting_fd_is_read(events, i)) {
if (uwsgi_tuntap_peer_dequeue(uttr, uttp)) {
if (uwsgi_tuntap_peer_dequeue(uttr, uttp, 1)) {
uwsgi_tuntap_peer_destroy(uttr, uttp);
break;
}
@@ -315,6 +342,83 @@ static void uwsgi_tuntap_router() {
}
}
void tuntaprouter_send_stats(struct uwsgi_tuntap_router *uttr) {
struct sockaddr_un client_src;
socklen_t client_src_len = 0;
int client_fd = accept(uttr->stats_server_fd, (struct sockaddr *) &client_src, &client_src_len);
if (client_fd < 0) {
uwsgi_error("tuntaprouter_send_stats()/accept()");
return;
}
if (uwsgi.stats_http) {
if (uwsgi_send_http_stats(client_fd)) {
close(client_fd);
return;
}
}
struct uwsgi_stats *us = uwsgi_stats_new(8192);
if (uwsgi_stats_keyval_comma(us, "version", UWSGI_VERSION)) goto end;
if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) getpid())) goto end;
if (uwsgi_stats_keylong_comma(us, "uid", (unsigned long long) getuid())) goto end;
if (uwsgi_stats_keylong_comma(us, "gid", (unsigned long long) getgid())) goto end;
char *cwd = uwsgi_get_cwd();
if (uwsgi_stats_keyval_comma(us, "cwd", cwd)) goto end0;
if (uwsgi_stats_key(us , "peers")) goto end0;
if (uwsgi_stats_list_open(us)) goto end0;
struct uwsgi_tuntap_peer *uttp = uttr->peers_head;
while (uttp) {
if (uwsgi_stats_object_open(us)) goto end0;
if (uwsgi_stats_keyval_comma(us, "addr", uttp->ip)) goto end0;
if (uwsgi_stats_keylong_comma(us, "addr_32", uttp->addr)) goto end0;
if (uwsgi_stats_keylong_comma(us, "tx", uttp->tx)) goto end0;
if (uwsgi_stats_keylong_comma(us, "rx", uttp->rx)) goto end0;
if (uwsgi_stats_keylong(us, "dropped", uttp->dropped)) goto end0;
if (uwsgi_stats_object_close(us)) goto end0;
uttp = uttp->next;
if (uttp) {
if (uwsgi_stats_comma(us)) goto end0;
}
}
if (uwsgi_stats_list_close(us)) goto end0;
if (uwsgi_stats_object_close(us)) goto end0;
size_t remains = us->pos;
off_t pos = 0;
while(remains > 0) {
int ret = uwsgi_waitfd_write(client_fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
if (ret <= 0) {
goto end0;
}
ssize_t res = write(client_fd, us->base + pos, remains);
if (res <= 0) {
if (res < 0) {
uwsgi_error("write()");
}
goto end0;
}
pos += res;
remains -= res;
}
end0:
free(cwd);
end:
free(us->base);
free(us);
close(client_fd);
}
struct uwsgi_plugin tuntap_plugin = {
.name = "tuntap",
.options = uwsgi_tuntap_options,