mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-06 13:41:28 +00:00
support for multiple routers
This commit is contained in:
+50
-50
@@ -3,7 +3,7 @@
|
||||
extern struct uwsgi_tuntap utt;
|
||||
|
||||
// create a new peer
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(int fd) {
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router *uttr, int fd) {
|
||||
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_calloc(sizeof(struct uwsgi_tuntap_peer));
|
||||
uttp->fd = fd;
|
||||
@@ -11,21 +11,21 @@ struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(int fd) {
|
||||
uttp->buf = uwsgi_malloc(utt.buffer_size + 4);
|
||||
uttp->write_buf = uwsgi_malloc(utt.buffer_size);
|
||||
|
||||
if (utt.peers_tail) {
|
||||
utt.peers_tail->next = uttp;
|
||||
uttp->prev = utt.peers_tail;
|
||||
utt.peers_tail = uttp;
|
||||
if (uttr->peers_tail) {
|
||||
uttr->peers_tail->next = uttp;
|
||||
uttp->prev = uttr->peers_tail;
|
||||
uttr->peers_tail = uttp;
|
||||
}
|
||||
else {
|
||||
utt.peers_head = uttp;
|
||||
utt.peers_tail = uttp;
|
||||
uttr->peers_head = uttp;
|
||||
uttr->peers_tail = uttp;
|
||||
}
|
||||
|
||||
return uttp;
|
||||
}
|
||||
|
||||
// destroy a peer
|
||||
void uwsgi_tuntap_peer_destroy(struct uwsgi_tuntap_peer *uttp) {
|
||||
void uwsgi_tuntap_peer_destroy(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp) {
|
||||
struct uwsgi_tuntap_peer *prev = uttp->prev;
|
||||
struct uwsgi_tuntap_peer *next = uttp->next;
|
||||
|
||||
@@ -37,12 +37,12 @@ void uwsgi_tuntap_peer_destroy(struct uwsgi_tuntap_peer *uttp) {
|
||||
next->prev = prev;
|
||||
}
|
||||
|
||||
if (uttp == utt.peers_head) {
|
||||
utt.peers_head = next;
|
||||
if (uttp == uttr->peers_head) {
|
||||
uttr->peers_head = next;
|
||||
}
|
||||
|
||||
if (uttp == utt.peers_tail) {
|
||||
utt.peers_tail = prev;
|
||||
if (uttp == uttr->peers_tail) {
|
||||
uttr->peers_tail = prev;
|
||||
}
|
||||
|
||||
free(uttp->buf);
|
||||
@@ -53,8 +53,8 @@ void uwsgi_tuntap_peer_destroy(struct uwsgi_tuntap_peer *uttp) {
|
||||
|
||||
|
||||
// get a peer by addr
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_get_by_addr(uint32_t addr) {
|
||||
struct uwsgi_tuntap_peer *uttp = utt.peers_head;
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_get_by_addr(struct uwsgi_tuntap_router *uttr, uint32_t addr) {
|
||||
struct uwsgi_tuntap_peer *uttp = uttr->peers_head;
|
||||
while (uttp) {
|
||||
if (uttp->addr == addr)
|
||||
return uttp;
|
||||
@@ -65,23 +65,23 @@ struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_get_by_addr(uint32_t addr) {
|
||||
}
|
||||
|
||||
// block all reading peers
|
||||
void uwsgi_tuntap_block_reads() {
|
||||
struct uwsgi_tuntap_peer *uttp = utt.peers_head;
|
||||
void uwsgi_tuntap_block_reads(struct uwsgi_tuntap_router *uttr) {
|
||||
struct uwsgi_tuntap_peer *uttp = uttr->peers_head;
|
||||
while (uttp) {
|
||||
if (!uttp->blocked_read) {
|
||||
if (!uttp->wait_for_write) {
|
||||
if (event_queue_del_fd(utt.queue, uttp->fd, event_queue_read())) {
|
||||
if (event_queue_del_fd(uttr->queue, uttp->fd, event_queue_read())) {
|
||||
struct uwsgi_tuntap_peer *tmp_uttp = uttp;
|
||||
uttp = uttp->next;
|
||||
uwsgi_tuntap_peer_destroy(tmp_uttp);
|
||||
uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (event_queue_fd_readwrite_to_write(utt.queue, uttp->fd)) {
|
||||
if (event_queue_fd_readwrite_to_write(uttr->queue, uttp->fd)) {
|
||||
struct uwsgi_tuntap_peer *tmp_uttp = uttp;
|
||||
uttp = uttp->next;
|
||||
uwsgi_tuntap_peer_destroy(tmp_uttp);
|
||||
uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -92,23 +92,23 @@ void uwsgi_tuntap_block_reads() {
|
||||
}
|
||||
|
||||
//unblock all reading peers
|
||||
void uwsgi_tuntap_unblock_reads() {
|
||||
struct uwsgi_tuntap_peer *uttp = utt.peers_head;
|
||||
void uwsgi_tuntap_unblock_reads(struct uwsgi_tuntap_router *uttr) {
|
||||
struct uwsgi_tuntap_peer *uttp = uttr->peers_head;
|
||||
while (uttp) {
|
||||
if (uttp->blocked_read) {
|
||||
if (!uttp->wait_for_write) {
|
||||
if (event_queue_add_fd_read(utt.queue, uttp->fd)) {
|
||||
if (event_queue_add_fd_read(uttr->queue, uttp->fd)) {
|
||||
struct uwsgi_tuntap_peer *tmp_uttp = uttp;
|
||||
uttp = uttp->next;
|
||||
uwsgi_tuntap_peer_destroy(tmp_uttp);
|
||||
uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (event_queue_fd_write_to_readwrite(utt.queue, uttp->fd)) {
|
||||
if (event_queue_fd_write_to_readwrite(uttr->queue, uttp->fd)) {
|
||||
struct uwsgi_tuntap_peer *tmp_uttp = uttp;
|
||||
uttp = uttp->next;
|
||||
uwsgi_tuntap_peer_destroy(tmp_uttp);
|
||||
uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -119,8 +119,8 @@ void uwsgi_tuntap_unblock_reads() {
|
||||
}
|
||||
|
||||
// enqueue a packet in the tuntap device
|
||||
void uwsgi_tuntap_enqueue() {
|
||||
ssize_t rlen = write(utt.fd, utt.write_buf + utt.write_pos, utt.write_pktsize - utt.write_pos);
|
||||
void uwsgi_tuntap_enqueue(struct uwsgi_tuntap_router *uttr) {
|
||||
ssize_t rlen = write(uttr->fd, uttr->write_buf + uttr->write_pos, uttr->write_pktsize - uttr->write_pos);
|
||||
// error on the tuntap device, destroy !!!
|
||||
if (rlen == 0) {
|
||||
uwsgi_error("uwsgi_tuntap_enqueue()/write()");
|
||||
@@ -134,33 +134,33 @@ void uwsgi_tuntap_enqueue() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
utt.write_pos += rlen;
|
||||
if (utt.write_pos >= utt.write_pktsize) {
|
||||
utt.write_pos = 0;
|
||||
if (utt.wait_for_write) {
|
||||
if (event_queue_fd_write_to_read(utt.queue, utt.fd)) {
|
||||
uttr->write_pos += rlen;
|
||||
if (uttr->write_pos >= uttr->write_pktsize) {
|
||||
uttr->write_pos = 0;
|
||||
if (uttr->wait_for_write) {
|
||||
if (event_queue_fd_write_to_read(uttr->queue, uttr->fd)) {
|
||||
uwsgi_error("uwsgi_tuntap_enqueue()/event_queue_fd_read_to_write()");
|
||||
exit(1);
|
||||
}
|
||||
utt.wait_for_write = 0;
|
||||
uttr->wait_for_write = 0;
|
||||
}
|
||||
uwsgi_tuntap_unblock_reads();
|
||||
uwsgi_tuntap_unblock_reads(uttr);
|
||||
return;
|
||||
}
|
||||
|
||||
retry:
|
||||
if (!utt.wait_for_write) {
|
||||
uwsgi_tuntap_block_reads();
|
||||
if (event_queue_fd_read_to_write(utt.queue, utt.fd)) {
|
||||
if (!uttr->wait_for_write) {
|
||||
uwsgi_tuntap_block_reads(uttr);
|
||||
if (event_queue_fd_read_to_write(uttr->queue, uttr->fd)) {
|
||||
uwsgi_error("uwsgi_tuntap_enqueue()/event_queue_fd_read_to_write()");
|
||||
exit(1);
|
||||
}
|
||||
utt.wait_for_write = 1;
|
||||
uttr->wait_for_write = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// receive a packet from the client
|
||||
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_peer *uttp) {
|
||||
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp) {
|
||||
// get body
|
||||
if (uttp->header_pos >= 4) {
|
||||
ssize_t rlen = read(uttp->fd, uttp->buf + uttp->buf_pos, uttp->buf_pktsize - uttp->buf_pos);
|
||||
@@ -190,7 +190,7 @@ int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_peer *uttp) {
|
||||
if (!uttp->addr)
|
||||
return -1;
|
||||
|
||||
struct uwsgi_tuntap_peer *tmp_uttp = uwsgi_tuntap_peer_get_by_addr(uttp->addr);
|
||||
struct uwsgi_tuntap_peer *tmp_uttp = uwsgi_tuntap_peer_get_by_addr(uttr, uttp->addr);
|
||||
char ip[INET_ADDRSTRLEN + 1];
|
||||
memset(ip, 0, INET_ADDRSTRLEN + 1);
|
||||
if (!inet_ntop(AF_INET, &uttp->addr, ip, INET_ADDRSTRLEN)) {
|
||||
@@ -199,14 +199,14 @@ int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_peer *uttp) {
|
||||
}
|
||||
if (uttp != tmp_uttp) {
|
||||
uwsgi_log("[tuntap-router] detected ip collision for %s\n", ip);
|
||||
uwsgi_tuntap_peer_destroy(tmp_uttp);
|
||||
uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
|
||||
}
|
||||
uwsgi_log("[tuntap-router] registered new peer %s (fd: %d)\n", ip, uttp->fd);
|
||||
}
|
||||
|
||||
memcpy(utt.write_buf, uttp->buf, uttp->buf_pktsize);
|
||||
utt.write_pktsize = uttp->buf_pktsize;
|
||||
uwsgi_tuntap_enqueue();
|
||||
memcpy(uttr->write_buf, uttp->buf, uttp->buf_pktsize);
|
||||
uttr->write_pktsize = uttp->buf_pktsize;
|
||||
uwsgi_tuntap_enqueue(uttr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_peer *uttp) {
|
||||
}
|
||||
|
||||
// enqueue a packet to the client
|
||||
int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_peer *uttp) {
|
||||
int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp) {
|
||||
|
||||
ssize_t rlen = write(uttp->fd, uttp->write_buf + uttp->written, uttp->write_buf_pktsize - uttp->written);
|
||||
if (rlen == 0) {
|
||||
@@ -251,15 +251,15 @@ int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_peer *uttp) {
|
||||
uttp->write_buf_pktsize = 0;
|
||||
if (uttp->wait_for_write) {
|
||||
// if the write ends while we are writing to the tuntap, block the reads
|
||||
if (utt.wait_for_write) {
|
||||
if (uttr->wait_for_write) {
|
||||
uttp->blocked_read = 1;
|
||||
if (event_queue_del_fd(utt.queue, uttp->fd, event_queue_write())) {
|
||||
if (event_queue_del_fd(uttr->queue, uttp->fd, event_queue_write())) {
|
||||
uwsgi_error("uwsgi_tuntap_peer_enqueue()/event_queue_del_fd()");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (event_queue_fd_readwrite_to_read(utt.queue, uttp->fd)) {
|
||||
if (event_queue_fd_readwrite_to_read(uttr->queue, uttp->fd)) {
|
||||
uwsgi_error("uwsgi_tuntap_peer_enqueue()/event_queue_fd_write_to_read()");
|
||||
return -1;
|
||||
}
|
||||
@@ -274,7 +274,7 @@ int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_peer *uttp) {
|
||||
|
||||
retry:
|
||||
if (!uttp->wait_for_write) {
|
||||
if (event_queue_fd_read_to_readwrite(utt.queue, uttp->fd)) {
|
||||
if (event_queue_fd_read_to_readwrite(uttr->queue, uttp->fd)) {
|
||||
uwsgi_error("uwsgi_tuntap_peer_enqueue()/event_queue_fd_read_to_write()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
+17
-14
@@ -43,33 +43,36 @@ struct uwsgi_tuntap_firewall_rule {
|
||||
struct uwsgi_tuntap_firewall_rule *next;
|
||||
};
|
||||
|
||||
struct uwsgi_tuntap {
|
||||
char *addr;
|
||||
char *device;
|
||||
int fd;
|
||||
struct uwsgi_tuntap_router {
|
||||
int fd;
|
||||
int server_fd;
|
||||
int queue;
|
||||
uint16_t buffer_size;
|
||||
char *buf;
|
||||
char *buf;
|
||||
char *write_buf;
|
||||
struct uwsgi_tuntap_peer *peers_head;
|
||||
struct uwsgi_tuntap_peer *peers_tail;
|
||||
uint16_t write_pktsize;
|
||||
uint16_t write_pos;
|
||||
int wait_for_write;
|
||||
struct uwsgi_tuntap_peer *peers_head;
|
||||
struct uwsgi_tuntap_peer *peers_tail;
|
||||
};
|
||||
|
||||
struct uwsgi_tuntap {
|
||||
struct uwsgi_string_list *routers;
|
||||
struct uwsgi_string_list *devices;
|
||||
uint16_t buffer_size;
|
||||
struct uwsgi_tuntap_firewall_rule *fw_in;
|
||||
struct uwsgi_tuntap_firewall_rule *fw_out;
|
||||
};
|
||||
|
||||
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_peer *);
|
||||
int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_peer *);
|
||||
void uwsgi_tuntap_enqueue();
|
||||
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *);
|
||||
int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *);
|
||||
void uwsgi_tuntap_enqueue(struct uwsgi_tuntap_router *);
|
||||
|
||||
int uwsgi_tuntap_firewall_check(struct uwsgi_tuntap_firewall_rule *, char *, uint16_t);
|
||||
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(int);
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_get_by_addr(uint32_t);
|
||||
void uwsgi_tuntap_peer_destroy(struct uwsgi_tuntap_peer *);
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router *, int);
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_get_by_addr(struct uwsgi_tuntap_router *,uint32_t);
|
||||
void uwsgi_tuntap_peer_destroy(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *);
|
||||
|
||||
int uwsgi_tuntap_device(char *);
|
||||
|
||||
|
||||
+78
-66
@@ -58,8 +58,8 @@ struct uwsgi_tuntap utt;
|
||||
*/
|
||||
|
||||
static struct uwsgi_option uwsgi_tuntap_options[] = {
|
||||
{"tuntap-router", required_argument, 0, "run the tuntap router (syntax: <device> <socket>)", uwsgi_opt_set_str, &utt.addr, 0},
|
||||
{"tuntap-device", required_argument, 0, "add a tuntap device to the instance (syntax: <device>[ <socket>])", uwsgi_opt_set_str, &utt.device, 0},
|
||||
{"tuntap-router", required_argument, 0, "run the tuntap router (syntax: <device> <socket>)", uwsgi_opt_add_string_list, &utt.routers, 0},
|
||||
{"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},
|
||||
{NULL, 0, 0, NULL, NULL, NULL, 0},
|
||||
@@ -75,57 +75,57 @@ static void *uwsgi_tuntap_loop(void *arg) {
|
||||
#endif
|
||||
pthread_sigmask(SIG_BLOCK, &smask, NULL);
|
||||
|
||||
int fd = utt.fd;
|
||||
struct uwsgi_tuntap_router *uttr = (struct uwsgi_tuntap_router *) arg;
|
||||
|
||||
uwsgi_socket_nb(fd);
|
||||
uwsgi_socket_nb(uttr->fd);
|
||||
|
||||
if (!utt.buffer_size)
|
||||
utt.buffer_size = 8192;
|
||||
utt.buf = uwsgi_malloc(utt.buffer_size);
|
||||
utt.write_buf = uwsgi_malloc(utt.buffer_size);
|
||||
uttr->buf = uwsgi_malloc(utt.buffer_size);
|
||||
uttr->write_buf = uwsgi_malloc(utt.buffer_size);
|
||||
|
||||
utt.queue = event_queue_init();
|
||||
uttr->queue = event_queue_init();
|
||||
|
||||
event_queue_add_fd_read(utt.queue, fd);
|
||||
event_queue_add_fd_read(uttr->queue, uttr->fd);
|
||||
int server_fd = uwsgi_connect("/tmp/tuntap.socket", 30, 0);
|
||||
if (server_fd < 0) {
|
||||
uwsgi_error("uwsgi_tuntap_loop()/uwsgi_connect()");
|
||||
exit(1);
|
||||
}
|
||||
if (event_queue_add_fd_read(utt.queue, server_fd)) {
|
||||
if (event_queue_add_fd_read(uttr->queue, server_fd)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_socket_nb(server_fd);
|
||||
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_create(server_fd);
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_create(uttr, server_fd);
|
||||
|
||||
for (;;) {
|
||||
int interesting_fd = -1;
|
||||
int ret = event_queue_wait(utt.queue, -1, &interesting_fd);
|
||||
int ret = event_queue_wait(uttr->queue, -1, &interesting_fd);
|
||||
|
||||
if (ret <= 0)
|
||||
continue;
|
||||
|
||||
if (interesting_fd == fd) {
|
||||
if (utt.wait_for_write) {
|
||||
uwsgi_tuntap_enqueue();
|
||||
if (interesting_fd == uttr->fd) {
|
||||
if (uttr->wait_for_write) {
|
||||
uwsgi_tuntap_enqueue(uttr);
|
||||
continue;
|
||||
}
|
||||
ssize_t rlen = read(fd, utt.buf, utt.buffer_size);
|
||||
ssize_t rlen = read(uttr->fd, uttr->buf, utt.buffer_size);
|
||||
if (rlen <= 0) {
|
||||
uwsgi_error("uwsgi_tuntap_loop()/read()");
|
||||
exit(1);
|
||||
}
|
||||
uint16_t pktsize = rlen;
|
||||
char *ptr = uttp->write_buf + uttp->write_buf_pktsize;
|
||||
memcpy(ptr + 4, utt.buf, rlen);
|
||||
memcpy(ptr + 4, uttr->buf, rlen);
|
||||
ptr[0] = 0;
|
||||
ptr[1] = (uint8_t) (pktsize & 0xff);
|
||||
ptr[2] = (uint8_t) ((pktsize >> 8) & 0xff);
|
||||
ptr[3] = 0;
|
||||
uttp->write_buf_pktsize+= pktsize+4;
|
||||
if (uwsgi_tuntap_peer_enqueue(uttp)) {
|
||||
if (uwsgi_tuntap_peer_enqueue(uttr, uttp)) {
|
||||
uwsgi_log("server disconnected...\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -136,19 +136,19 @@ static void *uwsgi_tuntap_loop(void *arg) {
|
||||
if (interesting_fd == server_fd) {
|
||||
// read from the client
|
||||
if (!uttp->wait_for_write) {
|
||||
if (uwsgi_tuntap_peer_dequeue(uttp)) {
|
||||
if (uwsgi_tuntap_peer_dequeue(uttr, uttp)) {
|
||||
uwsgi_log("server disconnected...\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// something is wrong (the tuntap device is blocked)
|
||||
if (utt.wait_for_write) {
|
||||
if (uttr->wait_for_write) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// write to the client
|
||||
if (uwsgi_tuntap_peer_enqueue(uttp)) {
|
||||
if (uwsgi_tuntap_peer_enqueue(uttr, uttp)) {
|
||||
uwsgi_log("server disconnected...\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -161,45 +161,52 @@ static void *uwsgi_tuntap_loop(void *arg) {
|
||||
|
||||
static void uwsgi_tuntap_client() {
|
||||
|
||||
if (!utt.device) return;
|
||||
if (!utt.devices) return;
|
||||
|
||||
struct uwsgi_string_list *usl;
|
||||
uwsgi_foreach(usl, utt.devices) {
|
||||
struct uwsgi_tuntap_router *uttr = uwsgi_calloc(sizeof(struct uwsgi_tuntap_router));
|
||||
uttr->fd = uwsgi_tuntap_device(usl->value);
|
||||
|
||||
utt.fd = uwsgi_tuntap_device(utt.device);
|
||||
|
||||
pthread_t t;
|
||||
pthread_create(&t, NULL, uwsgi_tuntap_loop, NULL);
|
||||
pthread_t t;
|
||||
pthread_create(&t, NULL, uwsgi_tuntap_loop, uttr);
|
||||
}
|
||||
}
|
||||
|
||||
void uwsgi_tuntap_router_loop(int id, void *foobar) {
|
||||
void uwsgi_tuntap_router_loop(int id, void *arg) {
|
||||
int i;
|
||||
utt.buf = uwsgi_malloc(utt.buffer_size);
|
||||
utt.write_buf = uwsgi_malloc(utt.buffer_size);
|
||||
utt.queue = event_queue_init();
|
||||
|
||||
struct uwsgi_tuntap_router *uttr = (struct uwsgi_tuntap_router *) arg;
|
||||
uttr->buf = uwsgi_malloc(utt.buffer_size);
|
||||
uttr->write_buf = uwsgi_malloc(utt.buffer_size);
|
||||
uttr->queue = event_queue_init();
|
||||
|
||||
void *events = event_queue_alloc(64);
|
||||
if (event_queue_add_fd_read(utt.queue, utt.server_fd))
|
||||
if (event_queue_add_fd_read(uttr->queue, uttr->server_fd))
|
||||
exit(1);
|
||||
if (event_queue_add_fd_read(utt.queue, utt.fd))
|
||||
if (event_queue_add_fd_read(uttr->queue, uttr->fd))
|
||||
exit(1);
|
||||
|
||||
for (;;) {
|
||||
int nevents = event_queue_wait_multi(utt.queue, -1, events, 64);
|
||||
int nevents = event_queue_wait_multi(uttr->queue, -1, events, 64);
|
||||
for (i = 0; i < nevents; i++) {
|
||||
int interesting_fd = event_queue_interesting_fd(events, i);
|
||||
if (interesting_fd == utt.fd) {
|
||||
if (interesting_fd == uttr->fd) {
|
||||
// if writing, continue enqueuing
|
||||
if (utt.wait_for_write) {
|
||||
uwsgi_tuntap_enqueue();
|
||||
if (uttr->wait_for_write) {
|
||||
uwsgi_tuntap_enqueue(uttr);
|
||||
continue;
|
||||
}
|
||||
ssize_t rlen = read(utt.fd, utt.buf, utt.buffer_size);
|
||||
ssize_t rlen = read(uttr->fd, uttr->buf, utt.buffer_size);
|
||||
if (rlen <= 0) {
|
||||
uwsgi_error("uwsgi_tuntap_router_loop()/read()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (uwsgi_tuntap_firewall_check(utt.fw_in, utt.buf, rlen)) continue;
|
||||
if (uwsgi_tuntap_firewall_check(utt.fw_in, uttr->buf, rlen)) continue;
|
||||
|
||||
uint32_t *dst_ip = (uint32_t *) & utt.buf[16];
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_get_by_addr(*dst_ip);
|
||||
uint32_t *dst_ip = (uint32_t *) & uttr->buf[16];
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_get_by_addr(uttr, *dst_ip);
|
||||
if (!uttp)
|
||||
continue;
|
||||
|
||||
@@ -211,50 +218,50 @@ void uwsgi_tuntap_router_loop(int id, void *foobar) {
|
||||
|
||||
uint16_t pktsize = rlen;
|
||||
char *ptr = uttp->write_buf + uttp->write_buf_pktsize;
|
||||
memcpy(ptr + 4, utt.buf, rlen);
|
||||
memcpy(ptr + 4, uttr->buf, rlen);
|
||||
ptr[0] = 0;
|
||||
ptr[1] = (uint8_t) (pktsize & 0xff);
|
||||
ptr[2] = (uint8_t) ((pktsize >> 8) & 0xff);
|
||||
ptr[3] = 0;
|
||||
uttp->write_buf_pktsize+= pktsize+4;
|
||||
if (uwsgi_tuntap_peer_enqueue(uttp)) {
|
||||
uwsgi_tuntap_peer_destroy(uttp);
|
||||
if (uwsgi_tuntap_peer_enqueue(uttr, uttp)) {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (interesting_fd == utt.server_fd) {
|
||||
int client_fd = uwsgi_accept(utt.server_fd);
|
||||
if (interesting_fd == uttr->server_fd) {
|
||||
int client_fd = uwsgi_accept(uttr->server_fd);
|
||||
if (client_fd < 0) {
|
||||
uwsgi_error("uwsgi_tuntap_server_loop()/accept()");
|
||||
continue;
|
||||
}
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_create(client_fd);
|
||||
if (event_queue_add_fd_read(utt.queue, uttp->fd)) {
|
||||
uwsgi_tuntap_peer_destroy(uttp);
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_create(uttr, client_fd);
|
||||
if (event_queue_add_fd_read(uttr->queue, uttp->fd)) {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
struct uwsgi_tuntap_peer *uttp = utt.peers_head;
|
||||
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(uttp)) {
|
||||
uwsgi_tuntap_peer_destroy(uttp);
|
||||
if (uwsgi_tuntap_peer_dequeue(uttr, uttp)) {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (event_queue_interesting_fd_is_write(events, i)) {
|
||||
// something is wrong (the tuntap device is blocked)
|
||||
if (utt.wait_for_write)
|
||||
if (uttr->wait_for_write)
|
||||
break;
|
||||
|
||||
// write to the client
|
||||
if (uwsgi_tuntap_peer_enqueue(uttp)) {
|
||||
uwsgi_tuntap_peer_destroy(uttp);
|
||||
if (uwsgi_tuntap_peer_enqueue(uttr, uttp)) {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -268,26 +275,31 @@ void uwsgi_tuntap_router_loop(int id, void *foobar) {
|
||||
|
||||
static void uwsgi_tuntap_router() {
|
||||
|
||||
if (!utt.addr) return;
|
||||
if (!utt.routers) return;
|
||||
|
||||
if (!utt.buffer_size)
|
||||
utt.buffer_size = 8192;
|
||||
|
||||
char *space = strchr(utt.addr, ' ');
|
||||
if (!space) {
|
||||
uwsgi_log("invalid tuntap router syntax, must be <device> <socket>\n");
|
||||
exit(1);
|
||||
}
|
||||
struct uwsgi_string_list *usl;
|
||||
uwsgi_foreach(usl, utt.routers) {
|
||||
char *space = strchr(usl->value, ' ');
|
||||
if (!space) {
|
||||
uwsgi_log("invalid tuntap router syntax, must be <device> <socket>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
utt.server_fd = bind_to_unix(space+1, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
struct uwsgi_tuntap_router *uttr = uwsgi_calloc(sizeof(struct uwsgi_tuntap_router));
|
||||
|
||||
*space = 0 ;
|
||||
utt.fd = uwsgi_tuntap_device(utt.addr);
|
||||
*space = ' ';
|
||||
uttr->server_fd = bind_to_unix(space+1, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
||||
|
||||
if (register_gateway("uWSGI tuntap router", uwsgi_tuntap_router_loop, NULL) == NULL) {
|
||||
uwsgi_log("unable to register the tuntap server gateway\n");
|
||||
exit(1);
|
||||
*space = 0 ;
|
||||
uttr->fd = uwsgi_tuntap_device(usl->value);
|
||||
*space = ' ';
|
||||
|
||||
if (register_gateway("uWSGI tuntap router", uwsgi_tuntap_router_loop, uttr) == NULL) {
|
||||
uwsgi_log("unable to register the tuntap server gateway\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user