1 #include "common.h"
2
3 extern struct uwsgi_tuntap utt;
4
5 // error reporting
uwsgi_tuntap_error_do(struct uwsgi_tuntap_peer * uttp,char * msg,char * file,int line)6 void uwsgi_tuntap_error_do(struct uwsgi_tuntap_peer *uttp, char *msg, char *file, int line) {
7 if (uttp) {
8 uwsgi_log_verbose("[tuntap] peer fd: %d ip: %s %s: %s [%s line %d]\n", uttp->fd, uttp->ip, msg, strerror(errno), file, line);
9 }
10 else {
11 uwsgi_log_verbose("[tuntap] %s: %s [%s line %d]\n", msg, strerror(errno), file, line);
12 }
13 }
14
15 // create a new peer
uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router * uttr,int fd,int is_router)16 struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router *uttr, int fd, int is_router) {
17
18 struct uwsgi_tuntap_peer *uttp = uwsgi_calloc(sizeof(struct uwsgi_tuntap_peer));
19 uttp->fd = fd;
20 // leave space fot he uwsgi header
21 uttp->buf = uwsgi_malloc(utt.buffer_size + 4);
22 uttp->write_buf = uwsgi_malloc(utt.buffer_size);
23
24 if (uttr->peers_tail) {
25 uttr->peers_tail->next = uttp;
26 uttp->prev = uttr->peers_tail;
27 uttr->peers_tail = uttp;
28 }
29 else {
30 uttr->peers_head = uttp;
31 uttr->peers_tail = uttp;
32 }
33
34 if (!is_router) {
35 if (utt.use_credentials) {
36 uwsgi_log_verbose("[uwsgi-tuntap] waiting for privileges drop...\n");
37 for(;;) {
38 if (getuid() > 0) break;
39 sleep(1);
40 }
41 uwsgi_log_verbose("[uwsgi-tuntap] privileges dropped\n");
42 if (uwsgi_pass_cred(fd, "uwsgi-tuntap", 12)) {
43 // better to exit
44 exit(1);
45 }
46 }
47
48 uwsgi_tuntap_peer_send_rules(fd, uttp);
49 }
50
51 return uttp;
52 }
53
54 // destroy a peer
uwsgi_tuntap_peer_destroy(struct uwsgi_tuntap_router * uttr,struct uwsgi_tuntap_peer * uttp)55 void uwsgi_tuntap_peer_destroy(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp) {
56 struct uwsgi_tuntap_peer *prev = uttp->prev;
57 struct uwsgi_tuntap_peer *next = uttp->next;
58
59 if (prev) {
60 prev->next = next;
61 }
62
63 if (next) {
64 next->prev = prev;
65 }
66
67 if (uttp == uttr->peers_head) {
68 uttr->peers_head = next;
69 }
70
71 if (uttp == uttr->peers_tail) {
72 uttr->peers_tail = prev;
73 }
74
75 free(uttp->buf);
76 free(uttp->write_buf);
77 if (uttp->rules) free(uttp->rules);
78 close(uttp->fd);
79 free(uttp);
80 }
81
82
83 // get a peer by addr
uwsgi_tuntap_peer_get_by_addr(struct uwsgi_tuntap_router * uttr,uint32_t addr)84 struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_get_by_addr(struct uwsgi_tuntap_router *uttr, uint32_t addr) {
85 struct uwsgi_tuntap_peer *uttp = uttr->peers_head;
86 while (uttp) {
87 if (uttp->addr == addr)
88 return uttp;
89 uttp = uttp->next;
90 }
91
92 return NULL;
93 }
94
95 // block all reading peers
uwsgi_tuntap_block_reads(struct uwsgi_tuntap_router * uttr)96 void uwsgi_tuntap_block_reads(struct uwsgi_tuntap_router *uttr) {
97 struct uwsgi_tuntap_peer *uttp = uttr->peers_head;
98 while (uttp) {
99 if (!uttp->blocked_read) {
100 if (!uttp->wait_for_write) {
101 if (event_queue_del_fd(uttr->queue, uttp->fd, event_queue_read())) {
102 struct uwsgi_tuntap_peer *tmp_uttp = uttp;
103 uttp = uttp->next;
104 uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
105 continue;
106 }
107 }
108 else {
109 if (event_queue_fd_readwrite_to_write(uttr->queue, uttp->fd)) {
110 struct uwsgi_tuntap_peer *tmp_uttp = uttp;
111 uttp = uttp->next;
112 uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
113 continue;
114 }
115 }
116 uttp->blocked_read = 1;
117 }
118 uttp = uttp->next;
119 }
120 }
121
122 //unblock all reading peers
uwsgi_tuntap_unblock_reads(struct uwsgi_tuntap_router * uttr)123 void uwsgi_tuntap_unblock_reads(struct uwsgi_tuntap_router *uttr) {
124 struct uwsgi_tuntap_peer *uttp = uttr->peers_head;
125 while (uttp) {
126 if (uttp->blocked_read) {
127 if (!uttp->wait_for_write) {
128 if (event_queue_add_fd_read(uttr->queue, uttp->fd)) {
129 struct uwsgi_tuntap_peer *tmp_uttp = uttp;
130 uttp = uttp->next;
131 uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
132 continue;
133 }
134 }
135 else {
136 if (event_queue_fd_write_to_readwrite(uttr->queue, uttp->fd)) {
137 struct uwsgi_tuntap_peer *tmp_uttp = uttp;
138 uttp = uttp->next;
139 uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
140 continue;
141 }
142 }
143 uttp->blocked_read = 0;
144 }
145 uttp = uttp->next;
146 }
147 }
148
149 // enqueue a packet in the tuntap device
uwsgi_tuntap_enqueue(struct uwsgi_tuntap_router * uttr)150 void uwsgi_tuntap_enqueue(struct uwsgi_tuntap_router *uttr) {
151 ssize_t rlen = write(uttr->fd, uttr->write_buf + uttr->write_pos, uttr->write_pktsize - uttr->write_pos);
152 // error on the tuntap device, destroy !!!
153 if (rlen == 0) {
154 uwsgi_error("uwsgi_tuntap_enqueue()/write()");
155 exit(1);
156 }
157
158 if (rlen < 0) {
159 if (uwsgi_is_again())
160 goto retry;
161 uwsgi_error("uwsgi_tuntap_enqueue()/write()");
162 exit(1);
163 }
164
165 uttr->write_pos += rlen;
166 if (uttr->write_pos >= uttr->write_pktsize) {
167 uttr->write_pos = 0;
168 if (uttr->wait_for_write) {
169 if (event_queue_fd_write_to_read(uttr->queue, uttr->fd)) {
170 uwsgi_error("uwsgi_tuntap_enqueue()/event_queue_fd_read_to_write()");
171 exit(1);
172 }
173 uttr->wait_for_write = 0;
174 }
175 uwsgi_tuntap_unblock_reads(uttr);
176 return;
177 }
178
179 retry:
180 if (!uttr->wait_for_write) {
181 uwsgi_tuntap_block_reads(uttr);
182 if (event_queue_fd_read_to_write(uttr->queue, uttr->fd)) {
183 uwsgi_error("uwsgi_tuntap_enqueue()/event_queue_fd_read_to_write()");
184 exit(1);
185 }
186 uttr->wait_for_write = 1;
187 }
188 }
189
uwsgi_tuntap_register_addr(struct uwsgi_tuntap_router * uttr,struct uwsgi_tuntap_peer * uttp)190 int uwsgi_tuntap_register_addr(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp) {
191
192 struct uwsgi_tuntap_peer *tmp_uttp = uwsgi_tuntap_peer_get_by_addr(uttr, uttp->addr);
193 char ip[INET_ADDRSTRLEN + 1];
194 memset(ip, 0, INET_ADDRSTRLEN + 1);
195 if (!inet_ntop(AF_INET, &uttp->addr, ip, INET_ADDRSTRLEN)) {
196 uwsgi_tuntap_error(uttp, "uwsgi_tuntap_register_addr()/inet_ntop()");
197 return -1;
198 }
199 if (uttp != tmp_uttp) {
200 uwsgi_log("[tuntap-router] detected ip collision for %s\n", ip);
201 uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
202 }
203 uwsgi_log("[tuntap-router] registered new peer %s (fd: %d)\n", ip, uttp->fd);
204 memcpy(uttp->ip, ip, INET_ADDRSTRLEN + 1);
205 return 0;
206 }
207
208 // receive a packet from the client
uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router * uttr,struct uwsgi_tuntap_peer * uttp,int is_router)209 int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp, int is_router) {
210 // get body
211 if (uttp->header_pos >= 4) {
212 ssize_t rlen = read(uttp->fd, uttp->buf + uttp->buf_pos, uttp->buf_pktsize - uttp->buf_pos);
213 if (rlen == 0)
214 return -1;
215 if (rlen < 0) {
216 if (uwsgi_is_again())
217 return 0;
218 uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_dequeue()/read()");
219 return -1;
220 }
221 uttp->buf_pos += rlen;
222 uttp->rx += rlen;
223 // a whole pkt has been received
224 if (uttp->buf_pos >= uttp->buf_pktsize) {
225
226 uttp->header_pos = 0;
227 uttp->buf_pos = 0;
228
229 if (!is_router) goto enqueue;
230
231 // a rule block
232 if (uttp->header[3] == 1) {
233 if (uttp->rules) free(uttp->rules);
234 uttp->rules = uwsgi_malloc(uttp->buf_pktsize);
235 memcpy(uttp->rules, uttp->buf, uttp->buf_pktsize);
236 uttp->rules_cnt = uttp->buf_pktsize / sizeof(struct uwsgi_tuntap_peer_rule);
237 return 0;
238 }
239
240 if (uwsgi_tuntap_firewall_check(utt.fw_out, uttp->buf, uttp->buf_pktsize)) return 0;
241
242 // if there is no associated address store the source
243 if (!uttp->addr) {
244 // close on invalid first packet
245 if (uttp->buf_pktsize < 20) return -1;
246 uint32_t *src_ip = (uint32_t *) (&uttp->buf[12]);
247 uttp->addr = *src_ip;
248 // drop invalid ip addresses
249 if (!uttp->addr)
250 return -1;
251
252 if (uwsgi_tuntap_register_addr(uttr, uttp)) {
253 return -1;
254 }
255
256 }
257
258 if (uwsgi_tuntap_peer_rules_check(uttr, uttp, uttp->buf, uttp->buf_pktsize, 1)) return 0;
259
260 // check four routing rule
261 if (uttr->gateway_fd > -1) {
262 if (uwsgi_tuntap_route_check(uttr->gateway_fd, uttp->buf, uttp->buf_pktsize)) return 0;
263 }
264 enqueue:
265
266 memcpy(uttr->write_buf, uttp->buf, uttp->buf_pktsize);
267 uttr->write_pktsize = uttp->buf_pktsize;
268 uwsgi_tuntap_enqueue(uttr);
269 }
270 return 0;
271 }
272 ssize_t rlen = read(uttp->fd, uttp->header + uttp->header_pos, 4 - uttp->header_pos);
273 if (rlen == 0)
274 return -1;
275 if (rlen < 0) {
276 if (uwsgi_is_again())
277 return 0;
278 uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_dequeue()/read()");
279 return -1;
280 }
281 uttp->header_pos += rlen;
282 if (uttp->header_pos >= 4) {
283 uint16_t *pktsize = (uint16_t *) &uttp->header[1];
284 uttp->buf_pktsize = *pktsize;
285 uttp->rx += 4;
286 }
287 return 0;
288 }
289
290 // enqueue a packet to the client
uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_router * uttr,struct uwsgi_tuntap_peer * uttp)291 int uwsgi_tuntap_peer_enqueue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp) {
292
293 ssize_t rlen = write(uttp->fd, uttp->write_buf + uttp->written, uttp->write_buf_pktsize - uttp->written);
294 if (rlen == 0) {
295 uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/write()");
296 return -1;
297 }
298
299 if (rlen < 0) {
300 if (uwsgi_is_again())
301 goto retry;
302 uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/write()");
303 return -1;
304 }
305
306 uttp->written += rlen;
307 uttp->tx += rlen;
308 if (uttp->written >= uttp->write_buf_pktsize) {
309 uttp->written = 0;
310 uttp->write_buf_pktsize = 0;
311 if (uttp->wait_for_write) {
312 // if the write ends while we are writing to the tuntap, block the reads
313 if (uttr->wait_for_write) {
314 uttp->blocked_read = 1;
315 if (event_queue_del_fd(uttr->queue, uttp->fd, event_queue_write())) {
316 uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/event_queue_del_fd()");
317 return -1;
318 }
319 }
320 else {
321 if (event_queue_fd_readwrite_to_read(uttr->queue, uttp->fd)) {
322 uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/event_queue_fd_write_to_read()");
323 return -1;
324 }
325 }
326 uttp->wait_for_write = 0;
327 }
328 return 0;
329 }
330
331 memmove(uttp->write_buf, uttp->write_buf + rlen, uttp->write_buf_pktsize - rlen);
332 uttp->write_buf_pktsize -= rlen;
333
334 retry:
335 if (!uttp->wait_for_write) {
336 if (event_queue_fd_read_to_readwrite(uttr->queue, uttp->fd)) {
337 uwsgi_tuntap_error(uttp, "uwsgi_tuntap_peer_enqueue()/event_queue_fd_read_to_write()");
338 return -1;
339 }
340 uttp->wait_for_write = 1;
341 }
342
343 return 0;
344 }
345
uwsgi_tuntap_device(char * name)346 int uwsgi_tuntap_device(char *name) {
347 struct ifreq ifr;
348 int fd = open(UWSGI_TUNTAP_DEVICE, O_RDWR);
349 if (fd < 0) {
350 uwsgi_error_open(UWSGI_TUNTAP_DEVICE);
351 exit(1);
352 }
353
354 memset(&ifr, 0, sizeof(struct ifreq));
355
356 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
357 strncpy(ifr.ifr_name, name, IFNAMSIZ);
358
359 if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
360 uwsgi_error("uwsgi_tuntap_device()/ioctl()");
361 exit(1);
362 }
363
364 uwsgi_log("initialized tuntap device %s (fd: %d)\n", ifr.ifr_name, fd);
365
366 return fd;
367 }
368
369