2 * curvetun - the cipherspace wormhole creator
3 * Part of the netsniff-ng project
4 * By Daniel Borkmann <daniel@netsniff-ng.org>
5 * Copyright 2011 Daniel Borkmann <daniel@netsniff-ng.org>,
21 #include <netinet/in.h>
22 #include <netinet/tcp.h>
23 #include <netinet/udp.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
28 #include <sys/epoll.h>
29 #include <arpa/inet.h>
33 #include "write_or_die.h"
50 struct worker_struct
{
54 struct parent_info parent
;
55 int (*handler
)(int fd
, const struct worker_struct
*ws
,
56 char *buff
, size_t len
);
59 static struct worker_struct
*threadpool
= NULL
;
61 extern sig_atomic_t sigint
;
63 static int handler_udp_tun_to_net(int fd
, const struct worker_struct
*ws
,
64 char *buff
, size_t len
) __pure
;
65 static int handler_udp_net_to_tun(int fd
, const struct worker_struct
*ws
,
66 char *buff
, size_t len
) __pure
;
67 static int handler_udp(int fd
, const struct worker_struct
*ws
,
68 char *buff
, size_t len
) __pure
;
69 static int handler_tcp_tun_to_net(int fd
, const struct worker_struct
*ws
,
70 char *buff
, size_t len
) __pure
;
71 static int handler_tcp_net_to_tun(int fd
, const struct worker_struct
*ws
,
72 char *buff
, size_t len
) __pure
;
73 static int handler_tcp(int fd
, const struct worker_struct
*ws
,
74 char *buff
, size_t len
) __pure
;
75 static void *worker(void *self
) __pure
;
77 static int handler_udp_tun_to_net(int fd
, const struct worker_struct
*ws
,
78 char *buff
, size_t len
)
80 int dfd
, state
, keep
= 1;
82 ssize_t rlen
, err
, plen
;
84 struct sockaddr_storage naddr
;
88 while ((rlen
= read(fd
, buff
+ sizeof(struct ct_proto
),
89 len
- sizeof(struct ct_proto
))) > 0) {
92 memset(&naddr
, 0, sizeof(naddr
));
94 hdr
= (struct ct_proto
*) buff
;
95 hdr
->canary
= htons(CANARY
);
98 trie_addr_lookup(buff
+ sizeof(struct ct_proto
),
99 rlen
- sizeof(struct ct_proto
),
100 ws
->parent
.ipv4
, &dfd
, &naddr
,
103 if (dfd
< 0 || nlen
== 0) {
104 syslog(LOG_INFO
, "CPU%u: UDP tunnel lookup failed: "
105 "unknown destination\n", ws
->cpu
);
109 plen
= z_deflate(buff
+ sizeof(struct ct_proto
),
110 rlen
- sizeof(struct ct_proto
), &pbuff
);
112 syslog(LOG_ERR
, "CPU%u: UDP tunnel deflate error: %s\n",
113 ws
->cpu
, strerror(errno
));
117 hdr
->payload
= htons((uint16_t) plen
);
120 setsockopt(dfd
, IPPROTO_UDP
, UDP_CORK
, &state
, sizeof(state
));
122 err
= sendto(dfd
, hdr
, sizeof(struct ct_proto
), 0,
123 (struct sockaddr
*) &naddr
, nlen
);
125 syslog(LOG_ERR
, "CPU%u: UDP tunnel write error: %s\n",
126 ws
->cpu
, strerror(errno
));
128 err
= sendto(dfd
, pbuff
, plen
, 0, (struct sockaddr
*) &naddr
,
131 syslog(LOG_ERR
, "CPU%u: UDP tunnel write error: %s\n",
132 ws
->cpu
, strerror(errno
));
135 setsockopt(dfd
, IPPROTO_UDP
, UDP_CORK
, &state
, sizeof(state
));
140 if (rlen
< 0 && errno
!= EAGAIN
)
141 syslog(LOG_ERR
, "CPU%u: UDP tunnel read error: %s\n",
142 ws
->cpu
, strerror(errno
));
147 static void handler_udp_notify_close(int fd
, struct sockaddr_storage
*addr
,
153 memset(&hdr
, 0, sizeof(hdr
));
154 hdr
.flags
|= PROTO_FLAG_EXIT
;
156 hdr
.canary
= htons(CANARY
);
158 err
= sendto(fd
, &hdr
, sizeof(hdr
), 0, (struct sockaddr
*) addr
, len
);
161 static int handler_udp_net_to_tun(int fd
, const struct worker_struct
*ws
,
162 char *buff
, size_t len
)
166 ssize_t rlen
, err
, plen
;
167 struct ct_proto
*hdr
;
168 struct sockaddr_storage naddr
;
171 nlen
= sizeof(naddr
);
172 memset(&naddr
, 0, sizeof(naddr
));
175 while ((rlen
= recvfrom(fd
, buff
, len
, 0, (struct sockaddr
*) &naddr
,
177 hdr
= (struct ct_proto
*) buff
;
179 if (unlikely(rlen
< sizeof(struct ct_proto
)))
181 if (unlikely(rlen
- sizeof(*hdr
) != ntohs(hdr
->payload
)))
183 if (unlikely(ntohs(hdr
->canary
) != CANARY
))
185 if (unlikely(ntohs(hdr
->payload
) == 0))
188 err
= trie_addr_maybe_update(buff
+ sizeof(struct ct_proto
),
189 rlen
- sizeof(struct ct_proto
),
193 syslog(LOG_INFO
, "CPU%u: Malicious packet dropped "
194 "from id %d\n", ws
->cpu
, fd
);
198 if (hdr
->flags
& PROTO_FLAG_EXIT
) {
200 trie_addr_remove_addr(&naddr
, nlen
);
201 handler_udp_notify_close(fd
, &naddr
, nlen
);
202 nlen
= sizeof(naddr
);
203 memset(&naddr
, 0, sizeof(naddr
));
207 plen
= z_inflate(buff
+ sizeof(struct ct_proto
),
208 rlen
- sizeof(struct ct_proto
), &pbuff
);
210 syslog(LOG_ERR
, "CPU%u: UDP net inflate error: %s\n",
211 ws
->cpu
, strerror(errno
));
215 err
= write(ws
->parent
.tunfd
, pbuff
, plen
);
217 syslog(LOG_ERR
, "CPU%u: UDP net write error: %s\n",
218 ws
->cpu
, strerror(errno
));
221 nlen
= sizeof(naddr
);
222 memset(&naddr
, 0, sizeof(naddr
));
226 if (rlen
< 0 && errno
!= EAGAIN
)
227 syslog(LOG_ERR
, "CPU%u: UDP net read error: %s\n",
228 ws
->cpu
, strerror(errno
));
233 static int handler_udp(int fd
, const struct worker_struct
*ws
,
234 char *buff
, size_t len
)
237 if (fd
== ws
->parent
.tunfd
)
238 ret
= handler_udp_tun_to_net(fd
, ws
, buff
, len
);
240 ret
= handler_udp_net_to_tun(fd
, ws
, buff
, len
);
244 static int handler_tcp_tun_to_net(int fd
, const struct worker_struct
*ws
,
245 char *buff
, size_t len
)
247 int dfd
, state
, keep
= 1;
249 ssize_t rlen
, err
, plen
;
250 struct ct_proto
*hdr
;
254 while ((rlen
= read(fd
, buff
+ sizeof(struct ct_proto
),
255 len
- sizeof(struct ct_proto
))) > 0) {
258 hdr
= (struct ct_proto
*) buff
;
259 hdr
->canary
= htons(CANARY
);
262 trie_addr_lookup(buff
+ sizeof(struct ct_proto
),
263 rlen
- sizeof(struct ct_proto
),
264 ws
->parent
.ipv4
, &dfd
, NULL
,
268 syslog(LOG_INFO
, "CPU%u: TCP tunnel lookup failed: "
269 "unknown destination\n", ws
->cpu
);
273 plen
= z_deflate(buff
+ sizeof(struct ct_proto
),
274 rlen
- sizeof(struct ct_proto
), &pbuff
);
276 syslog(LOG_ERR
, "CPU%u: TCP tunnel deflate error: %s\n",
277 ws
->cpu
, strerror(errno
));
281 hdr
->payload
= htons((uint16_t) plen
);
284 setsockopt(dfd
, IPPROTO_TCP
, TCP_CORK
, &state
, sizeof(state
));
286 err
= write_exact(dfd
, hdr
, sizeof(struct ct_proto
), 0);
288 syslog(LOG_ERR
, "CPU%u: TCP tunnel write error: %s\n",
289 ws
->cpu
, strerror(errno
));
291 err
= write_exact(dfd
, pbuff
, plen
, 0);
293 syslog(LOG_ERR
, "CPU%u: TCP tunnel write error: %s\n",
294 ws
->cpu
, strerror(errno
));
297 setsockopt(dfd
, IPPROTO_TCP
, TCP_CORK
, &state
, sizeof(state
));
302 if (rlen
< 0 && errno
!= EAGAIN
)
303 syslog(LOG_ERR
, "CPU%u: TCP tunnel read error: %s\n",
304 ws
->cpu
, strerror(errno
));
309 ssize_t
handler_tcp_read(int fd
, char *buff
, size_t len
)
312 struct ct_proto
*hdr
= (struct ct_proto
*) buff
;
314 /* May exit on EAGAIN if 0 Byte read */
315 rlen
= read_exact(fd
, buff
, sizeof(struct ct_proto
), 1);
319 /* May not exit on EAGAIN if 0 Byte read */
320 rlen
= read_exact(fd
, buff
+ sizeof(struct ct_proto
),
321 ntohs(hdr
->payload
), 0);
325 return sizeof(struct ct_proto
) + rlen
;
328 static void handler_tcp_notify_close(int fd
)
333 memset(&hdr
, 0, sizeof(hdr
));
334 hdr
.flags
|= PROTO_FLAG_EXIT
;
336 hdr
.canary
= htons(CANARY
);
338 err
= write(fd
, &hdr
, sizeof(hdr
));
341 static int handler_tcp_net_to_tun(int fd
, const struct worker_struct
*ws
,
342 char *buff
, size_t len
)
344 int keep
= 1, count
= 0;
346 ssize_t rlen
, err
, plen
;
347 struct ct_proto
*hdr
;
351 while ((rlen
= handler_tcp_read(fd
, buff
, len
)) > 0) {
352 hdr
= (struct ct_proto
*) buff
;
354 if (unlikely(rlen
< sizeof(struct ct_proto
)))
356 if (unlikely(rlen
- sizeof(*hdr
) != ntohs(hdr
->payload
)))
358 if (unlikely(ntohs(hdr
->canary
) != CANARY
))
360 if (unlikely(ntohs(hdr
->payload
) == 0))
363 err
= trie_addr_maybe_update(buff
+ sizeof(struct ct_proto
),
364 rlen
- sizeof(struct ct_proto
),
365 ws
->parent
.ipv4
, fd
, NULL
, 0);
367 syslog(LOG_INFO
, "CPU%u: Malicious packet dropped "
368 "from id %d\n", ws
->cpu
, fd
);
372 if (hdr
->flags
& PROTO_FLAG_EXIT
) {
375 trie_addr_remove(fd
);
376 handler_tcp_notify_close(fd
);
377 rlen
= write(ws
->parent
.efd
, &fd64
, sizeof(fd64
));
378 if (rlen
!= sizeof(fd64
))
379 syslog(LOG_ERR
, "CPU%u: TCP event write error: %s\n",
380 ws
->cpu
, strerror(errno
));
385 plen
= z_inflate(buff
+ sizeof(struct ct_proto
),
386 rlen
- sizeof(struct ct_proto
), &pbuff
);
388 syslog(LOG_ERR
, "CPU%u: TCP net inflate error: %s\n",
389 ws
->cpu
, strerror(errno
));
393 err
= write(ws
->parent
.tunfd
, pbuff
, plen
);
395 syslog(LOG_ERR
, "CPU%u: TCP net write error: %s\n",
396 ws
->cpu
, strerror(errno
));
400 err
= write_exact(ws
->efd
[1], &fd
, sizeof(fd
), 1);
401 if (err
!= sizeof(fd
))
402 syslog(LOG_ERR
, "CPU%u: TCP net put fd back in "
403 "pipe error: %s\n", ws
->cpu
, strerror(errno
));
410 if (rlen
< 0 && errno
!= EAGAIN
&& errno
!= EBADF
)
411 syslog(LOG_ERR
, "CPU%u: TCP net read error: %s\n",
412 ws
->cpu
, strerror(errno
));
417 static int handler_tcp(int fd
, const struct worker_struct
*ws
,
418 char *buff
, size_t len
)
421 if (fd
== ws
->parent
.tunfd
)
422 ret
= handler_tcp_tun_to_net(fd
, ws
, buff
, len
);
424 ret
= handler_tcp_net_to_tun(fd
, ws
, buff
, len
);
428 static void *worker(void *self
)
432 size_t blen
= TUNBUFF_SIZ
; //FIXME
433 const struct worker_struct
*ws
= self
;
440 buff
= xmalloc(blen
);
441 syslog(LOG_INFO
, "curvetun thread on CPU%u up!\n", ws
->cpu
);
442 pthread_cleanup_push(xfree
, buff
);
444 while (likely(!sigint
)) {
446 if ((fds
.revents
& POLLIN
) != POLLIN
)
448 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &old_state
);
449 while ((ret
= read_exact(ws
->efd
[0], &fd
, sizeof(fd
), 1)) > 0) {
450 if (ret
!= sizeof(fd
)) {
451 syslog(LOG_ERR
, "CPU%u: Thread could not read "
452 "event descriptor!\n", ws
->cpu
);
457 ret
= ws
->handler(fd
, ws
, buff
, blen
);
459 ret
= write_exact(ws
->parent
.refd
, &fd
, sizeof(fd
), 1);
460 if (ret
!= sizeof(fd
))
461 syslog(LOG_ERR
, "CPU%u: Retriggering failed: "
462 "%s\n", ws
->cpu
, strerror(errno
));
465 pthread_setcancelstate(old_state
, NULL
);
468 syslog(LOG_INFO
, "curvetun thread on CPU%u down!\n", ws
->cpu
);
469 pthread_cleanup_pop(1);
470 pthread_exit((void *) ((long) ws
->cpu
));
473 static void thread_spawn_or_panic(unsigned int cpus
, int efd
, int refd
,
474 int tunfd
, int ipv4
, int udp
)
478 unsigned int threads
;
480 threads
= cpus
* THREADS_PER_CPU
;
481 for (i
= 0; i
< threads
; ++i
) {
483 threadpool
[i
].cpu
= i
% cpus
;
484 CPU_SET(threadpool
[i
].cpu
, &cpuset
);
486 ret
= pipe2(threadpool
[i
].efd
, O_NONBLOCK
);
488 panic("Cannot create event socket!\n");
490 threadpool
[i
].parent
.efd
= efd
;
491 threadpool
[i
].parent
.refd
= refd
;
492 threadpool
[i
].parent
.tunfd
= tunfd
;
493 threadpool
[i
].parent
.ipv4
= ipv4
;
494 threadpool
[i
].parent
.udp
= udp
;
495 threadpool
[i
].handler
= udp
? handler_udp
: handler_tcp
;
497 ret
= pthread_create(&threadpool
[i
].trid
, NULL
,
498 worker
, &threadpool
[i
]);
500 panic("Thread creation failed!\n");
502 ret
= pthread_setaffinity_np(threadpool
[i
].trid
,
503 sizeof(cpu_set_t
), &cpuset
);
505 panic("Thread CPU migration failed!\n");
507 pthread_detach(threadpool
[i
].trid
);
513 static void thread_finish(unsigned int cpus
)
516 unsigned int threads
;
518 threads
= cpus
* THREADS_PER_CPU
;
519 for (i
= 0; i
< threads
; ++i
) {
520 ret
= pthread_join(threadpool
[i
].trid
, NULL
);
523 close(threadpool
[i
].efd
[0]);
524 close(threadpool
[i
].efd
[1]);
528 int server_main(int port
, int udp
, int lnum
)
530 int lfd
= -1, kdpfd
, nfds
, nfd
, curfds
, efd
[2], refd
[2], tunfd
;
532 unsigned int cpus
= 0, threads
;
534 struct epoll_event ev
, *events
;
535 struct addrinfo hints
, *ahead
, *ai
;
537 openlog("curvetun", LOG_PID
| LOG_CONS
| LOG_NDELAY
, LOG_DAEMON
);
538 syslog(LOG_INFO
, "curvetun server booting!\n");
540 ret
= z_alloc_or_maybe_die(Z_DEFAULT_COMPRESSION
);
542 panic("Cannot init zLib!\n");
544 memset(&hints
, 0, sizeof(hints
));
545 hints
.ai_family
= PF_UNSPEC
;
546 hints
.ai_socktype
= udp
? SOCK_DGRAM
: SOCK_STREAM
;
547 hints
.ai_protocol
= udp
? IPPROTO_UDP
: IPPROTO_TCP
;
548 hints
.ai_flags
= AI_PASSIVE
;
550 ret
= getaddrinfo(NULL
, "6666", &hints
, &ahead
);
552 panic("Cannot get address info!\n");
554 for (ai
= ahead
; ai
!= NULL
&& lfd
< 0; ai
= ai
->ai_next
) {
555 lfd
= socket(ai
->ai_family
, ai
->ai_socktype
, ai
->ai_protocol
);
558 if (ai
->ai_family
== AF_INET6
) {
561 ret
= setsockopt(lfd
, IPPROTO_IPV6
, IPV6_V6ONLY
,
572 #endif /* IPV6_V6ONLY */
575 ret
= bind(lfd
, ai
->ai_addr
, ai
->ai_addrlen
);
582 ret
= listen(lfd
, 5);
589 ipv4
= (ai
->ai_family
== AF_INET6
? 0 :
590 (ai
->ai_family
== AF_INET
? 1 : -1));
591 syslog(LOG_INFO
, "curvetun on IPv%d via %s!\n",
592 ipv4
? 4 : 6, udp
? "UDP" : "TCP");
596 if (lfd
< 0 || ipv4
< 0)
597 panic("Cannot create socket!\n");
599 tunfd
= tun_open_or_die(DEVNAME_SERVER
);
601 ret
= pipe2(efd
, O_NONBLOCK
);
603 panic("Cannot create parent event fd!\n");
605 ret
= pipe2(refd
, O_NONBLOCK
);
607 panic("Cannot create parent (r)event fd!\n");
609 set_nonblocking(lfd
);
611 events
= xzmalloc(MAX_EPOLL_SIZE
* sizeof(*events
));
612 for (i
= 0; i
< MAX_EPOLL_SIZE
; ++i
)
613 events
[i
].data
.fd
= -1;
615 kdpfd
= epoll_create(MAX_EPOLL_SIZE
);
617 panic("Cannot create socket!\n");
619 memset(&ev
, 0, sizeof(ev
));
620 ev
.events
= udp
? EPOLLIN
| EPOLLET
| EPOLLONESHOT
: EPOLLIN
;
622 ret
= epoll_ctl(kdpfd
, EPOLL_CTL_ADD
, lfd
, &ev
);
624 panic("Cannot add socket for epoll!\n");
626 memset(&ev
, 0, sizeof(ev
));
629 ret
= epoll_ctl(kdpfd
, EPOLL_CTL_ADD
, efd
[0], &ev
);
631 panic("Cannot add socket for events!\n");
633 memset(&ev
, 0, sizeof(ev
));
635 ev
.data
.fd
= refd
[0];
636 ret
= epoll_ctl(kdpfd
, EPOLL_CTL_ADD
, refd
[0], &ev
);
638 panic("Cannot add socket for (r)events!\n");
640 memset(&ev
, 0, sizeof(ev
));
641 ev
.events
= EPOLLIN
| EPOLLET
| EPOLLONESHOT
;
643 ret
= epoll_ctl(kdpfd
, EPOLL_CTL_ADD
, tunfd
, &ev
);
645 panic("Cannot add socket for tundev!\n");
651 cpus
= get_number_cpus_online();
652 threads
= cpus
* THREADS_PER_CPU
;
653 if (!((threads
!= 0) && ((threads
& (threads
- 1)) == 0)))
654 panic("thread number not power of two!\n");
655 threadpool
= xzmalloc(sizeof(*threadpool
) * threads
);
656 thread_spawn_or_panic(cpus
, efd
[1], refd
[1], tunfd
, ipv4
, udp
);
658 init_cpusched(threads
, MAX_EPOLL_SIZE
);
659 register_socket(tunfd
);
660 register_socket(lfd
);
662 syslog(LOG_INFO
, "tunnel id: %d, listener id: %d\n", tunfd
, lfd
);
663 syslog(LOG_INFO
, "curvetun up and running!\n");
665 while (likely(!sigint
)) {
666 nfds
= epoll_wait(kdpfd
, events
, curfds
, -1);
668 syslog(LOG_ERR
, "epoll_wait error: %s\n",
673 for (i
= 0; i
< nfds
; ++i
) {
674 if (unlikely(events
[i
].data
.fd
< 0))
676 if (events
[i
].data
.fd
== lfd
&& !udp
) {
678 char hbuff
[256], sbuff
[256];
679 struct sockaddr_storage taddr
;
682 tlen
= sizeof(taddr
);
683 nfd
= accept(lfd
, (struct sockaddr
*) &taddr
,
686 syslog(LOG_ERR
, "accept error: %s\n",
691 if (curfds
+ 1 > MAX_EPOLL_SIZE
) {
697 ncpu
= register_socket(nfd
);
699 memset(hbuff
, 0, sizeof(hbuff
));
700 memset(sbuff
, 0, sizeof(sbuff
));
702 getnameinfo((struct sockaddr
*) &taddr
, tlen
,
703 hbuff
, sizeof(hbuff
),
704 sbuff
, sizeof(sbuff
),
705 NI_NUMERICHOST
| NI_NUMERICSERV
);
707 syslog(LOG_INFO
, "New connection from %s:%s "
708 "with id %d on CPU%d, %d active!\n",
709 hbuff
, sbuff
, nfd
, ncpu
, curfds
);
711 set_nonblocking(nfd
);
714 setsockopt(nfd
, SOL_SOCKET
, SO_KEEPALIVE
,
717 setsockopt(nfd
, IPPROTO_TCP
, TCP_NODELAY
,
720 memset(&ev
, 0, sizeof(ev
));
721 ev
.events
= EPOLLIN
| EPOLLET
| EPOLLONESHOT
;
723 ret
= epoll_ctl(kdpfd
, EPOLL_CTL_ADD
, nfd
, &ev
);
725 syslog(LOG_ERR
, "Epoll ctl add error"
726 "on id %d: %s\n", nfd
,
732 } else if (events
[i
].data
.fd
== refd
[0]) {
735 ret
= read_exact(refd
[0], &fd_one
, sizeof(fd_one
), 1);
736 if (ret
!= sizeof(fd_one
) || fd_one
<= 0)
739 memset(&ev
, 0, sizeof(ev
));
740 ev
.events
= EPOLLIN
| EPOLLET
| EPOLLONESHOT
;
742 ret
= epoll_ctl(kdpfd
, EPOLL_CTL_MOD
, fd_one
, &ev
);
744 syslog(LOG_ERR
, "Epoll ctl mod "
745 "error on id %d: %s\n",
746 fd_one
, strerror(errno
));
750 } else if (events
[i
].data
.fd
== efd
[0]) {
753 ret
= read_exact(efd
[0], &fd_del
, sizeof(fd_del
), 1);
754 if (ret
!= sizeof(fd_del
) || fd_del
<= 0)
757 ret
= read(fd_del
, &test
, sizeof(test
));
758 if (ret
< 0 && errno
== EBADF
)
761 ret
= epoll_ctl(kdpfd
, EPOLL_CTL_DEL
, fd_del
, &ev
);
763 syslog(LOG_ERR
, "Epoll ctl del "
764 "error on id %d: %s\n",
765 fd_del
, strerror(errno
));
771 unregister_socket(fd_del
);
773 syslog(LOG_INFO
, "Closed connection with "
774 "id %d, %d active!\n",
777 int cpu
, fd_work
= events
[i
].data
.fd
;
778 cpu
= socket_to_cpu(fd_work
);
780 ret
= write_exact(threadpool
[cpu
].efd
[1],
781 &fd_work
, sizeof(fd_work
), 1);
782 if (ret
!= sizeof(fd_work
))
783 syslog(LOG_ERR
, "Write error on event "
784 "dispatch: %s\n", strerror(errno
));
789 syslog(LOG_INFO
, "curvetun prepare shut down!\n");
802 unregister_socket(lfd
);
803 unregister_socket(tunfd
);
808 syslog(LOG_INFO
, "curvetun shut down!\n");