mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-06 13:41:28 +00:00
added tuntaprouter stats
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user