Olivier Tirat
2016-Oct-05 17:27 UTC
Dev: new option to mark all tincd socket of a tincd process
I know i'm new to the list but i'd like to propose something for tincd daemon. I'd like to mark all sockets established by a tincd process with a mark passed as an argument in the command line. What could be the purpose of this new option? The goal of this option is to be able to have several tincd process running at the same time using the same port but using different ip. In order to be able to give the right IP to outgoing packet i have to be able to mark them and to source nat the packet according to the mark. The advantage of this solution is to have fixed ports for traffic and firewalls and moving ip address that are much easier to manage. Do you think its something interesting? Do you think its a hard work to do? If not i could probably try to do it and propose a patch for that if you think it is interesting. Sincerely Yours Olivier
Guus Sliepen
2016-Oct-06 12:11 UTC
Dev: new option to mark all tincd socket of a tincd process
On Wed, Oct 05, 2016 at 07:27:54PM +0200, Olivier Tirat wrote:> I'd like to mark all sockets established by a tincd process with a mark > passed as an argument in the command line.[...]> Do you think its something interesting? > Do you think its a hard work to do? > If not i could probably try to do it and propose a patch for that if you > think it is interesting.I think it is relatively easy to do. There are two places in src/net_socket.c where you would have to call setsockopt() with the SO_MARK option: configure_tcp() and setup_vpn_in_socket(). The first one is run for all incoming and outgoing TCP sockets, the second one sets up the UDP sockets. Try it out and see if it really allows you to do the mark-based routing you want. If it works, you can submit a patch or pull request. -- Met vriendelijke groet / with kind regards, Guus Sliepen <guus at tinc-vpn.org> -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: <http://www.tinc-vpn.org/pipermail/tinc/attachments/20161006/8e2f4672/attachment.sig>
Etienne Dechamps
2016-Oct-06 20:06 UTC
Dev: new option to mark all tincd socket of a tincd process
You might be able to do this today without any changes to tinc, if you run your various tincd processes under different users, and then use something like: # iptables -A OUTPUT -m owner --uid-owner <username> -j MARK --set-mark ... On 5 October 2016 at 18:27, Olivier Tirat <olivier.tirat at byo-networks.com> wrote:> I know i'm new to the list but i'd like to propose something for tincd > daemon. > > I'd like to mark all sockets established by a tincd process with a mark > passed as an argument in the command line. > > What could be the purpose of this new option? > The goal of this option is to be able to have several tincd process > running at the same time using the same port but using different ip. > In order to be able to give the right IP to outgoing packet i have to be > able to mark them and to source nat the packet according to the mark. > The advantage of this solution is to have fixed ports for traffic and > firewalls and moving ip address that are much easier to manage. > > Do you think its something interesting? > Do you think its a hard work to do? > If not i could probably try to do it and propose a patch for that if you > think it is interesting. > > > Sincerely Yours > > Olivier > > > _______________________________________________ > tinc mailing list > tinc at tinc-vpn.org > https://www.tinc-vpn.org/cgi-bin/mailman/listinfo/tinc >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://www.tinc-vpn.org/pipermail/tinc/attachments/20161006/192d19d5/attachment.html>
Olivier Tirat
2016-Oct-10 18:55 UTC
Dev: new option to mark all tincd socket of a tincd process
you will find hereafter my patch that has not been done really smartly. I'm not sure i have understood all i did (probably not). But once done i still got packet with no mark. And i'm not able to have 2 tincd process working concurently with the same port but different addresses. Did i miss something? You will find hereafter some outputs of ps, netstat and iptables logs. ps -ef | grep tincd root 14131 1 0 16:41 ? 00:00:00 tincd -n tnid-00000002 -m 4096 --logfile=/var/log/tinc/tnid-00000002.log root 14898 1 0 19:28 ? 00:00:00 tincd -n tnid-00000001 -m 8192 --logfile=/var/log/tinc/tnid-00000001.log netstat -anp | grep 655 tcp 0 0 192.168.42.111:655 0.0.0.0:* LISTEN 14898/tincd tcp 0 0 192.168.42.110:655 0.0.0.0:* LISTEN 14131/tincd tcp 0 0 192.168.42.110:39626 192.168.42.172:655 ESTABLISHED 14131/tincd tcp 0 0 192.168.42.110:54492 192.168.42.175:655 ESTABLISHED 14898/tincd udp 0 0 192.168.42.111:655 0.0.0.0:* 14898/tincd udp 0 0 192.168.42.110:655 0.0.0.0:* 14131/tincd the expected trace for the 4th tcp connexion is: tcp 0 0 192.168.42.111:54492 192.168.42.175:655 ESTABLISHED 14898/tincd because it is linked to 14898 tincd process marked with 8192 mark cat /var/log/iptables.log | grep TCP | grep 54492 Oct 10 20:44:39 localhost kernel: output dport: IN= OUT=eth0 SRC=192.168.42.110 DST=192.168.42.175 LEN=54 TOS=0x10 PREC=0x00 TTL=64 ID=48981 DF PROTO=TCP SPT=54492 DPT=655 WINDOW=310 RES=0x00 ACK PSH URGP=0 Oct 10 20:44:39 localhost kernel: output dport: IN= OUT=eth0 SRC=192.168.42.110 DST=192.168.42.175 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=48982 DF PROTO=TCP SPT=54492 DPT=655 WINDOW=310 RES=0x00 ACK URGP=0 Oct 10 20:44:40 localhost kernel: output dport: IN= OUT=eth0 SRC=192.168.42.110 DST=192.168.42.175 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=48983 DF PROTO=TCP SPT=54492 DPT=655 WINDOW=310 RES=0x00 ACK URGP=0 Oct 10 20:44:40 localhost kernel: output dport: IN= OUT=eth0 SRC=192.168.42.110 DST=192.168.42.175 LEN=54 TOS=0x10 PREC=0x00 TTL=64 ID=48984 DF PROTO=TCP SPT=54492 DPT=655 WINDOW=310 RES=0x00 ACK PSH URGP=0 Oct 10 20:45:10 localhost kernel: output dport: IN= OUT=eth0 SRC=192.168.42.110 DST=192.168.42.175 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=48985 DF PROTO=TCP SPT=54492 DPT=655 WINDOW=310 RES=0x00 ACK URGP=0 Oct 10 20:45:39 localhost kernel: output dport: IN= OUT=eth0 SRC=192.168.42.110 DST=192.168.42.175 LEN=54 TOS=0x10 PREC=0x00 TTL=64 ID=48986 DF PROTO=TCP SPT=54492 DPT=655 WINDOW=310 RES=0x00 ACK PSH URGP=0 Oct 10 20:45:39 localhost kernel: output dport: IN= OUT=eth0 SRC=192.168.42.110 DST=192.168.42.175 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=48987 DF PROTO=TCP SPT=54492 DPT=655 WINDOW=310 RES=0x00 ACK URGP=0 Oct 10 20:45:40 localhost kernel: output dport: IN= OUT=eth0 SRC=192.168.42.110 DST=192.168.42.175 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=48988 DF PROTO=TCP SPT=54492 DPT=655 WINDOW=310 RES=0x00 ACK URGP=0 Oct 10 20:45:40 localhost kernel: output dport: IN= OUT=eth0 SRC=192.168.42.110 DST=192.168.42.175 LEN=54 TOS=0x10 PREC=0x00 TTL=64 ID=48989 DF PROTO=TCP SPT=54492 DPT=655 WINDOW=310 RES=0x00 ACK PSH URGP=0 Packet are not marked why? All outgoing packet marked with m=8192 are using 192.168.42.111 as source address as shown there cat /var/log/iptables.log | grep 192.168.42.111 Oct 10 20:44:32 localhost kernel: tincd: IN= OUT=eth0 SRC=192.168.42.175 DST=192.168.42.111 LEN=516 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=UDP SPT=655 DPT=655 LEN=496 MARK=0x2000 Oct 10 20:44:32 localhost kernel: tincd: IN= OUT=eth0 SRC=192.168.42.175 DST=192.168.42.111 LEN=516 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=UDP SPT=655 DPT=655 LEN=496 MARK=0x2000 Oct 10 20:44:32 localhost kernel: tincd: IN= OUT=eth0 SRC=192.168.42.175 DST=192.168.42.111 LEN=220 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=UDP SPT=655 DPT=655 LEN=200 MARK=0x2000 Oct 10 20:44:32 localhost kernel: tincd: IN= OUT=eth0 SRC=192.168.42.175 DST=192.168.42.111 LEN=220 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=UDP SPT=655 DPT=655 LEN=200 MARK=0x2000 Oct 10 20:44:32 localhost kernel: tincd: IN= OUT=eth0 SRC=192.168.42.111 DST=192.168.42.175 LEN=524 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=655 DPT=655 LEN=504 MARK=0x2000 Oct 10 20:44:32 localhost kernel: tincd: IN= OUT=eth0 SRC=192.168.42.111 DST=192.168.42.175 LEN=524 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=655 DPT=655 LEN=504 MARK=0x2000 Oct 10 20:44:32 localhost kernel: tincd: IN= OUT=eth0 SRC=192.168.42.111 DST=192.168.42.175 LEN=411 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=655 DPT=655 LEN=391 MARK=0x2000 Oct 10 20:44:32 localhost kernel: tincd: IN= OUT=eth0 SRC=192.168.42.111 DST=192.168.42.175 LEN=411 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=655 DPT=655 LEN=391 MARK=0x2000 Oct 10 20:44:32 localhost kernel: tincd: IN= OUT=eth0 SRC=192.168.42.111 DST=192.168.42.175 LEN=517 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=655 DPT=655 LEN=497 MARK=0x2000 Thank you guys for you help!!!! Olivier tinc-1.0.28 diff -ur tinc-1.0.28-orig/src/conf.h tinc-1.0.28/src/conf.h --- tinc-1.0.28-orig/src/conf.h 2014-08-27 10:40:51.000000000 +0200 +++ tinc-1.0.28/src/conf.h 2016-10-10 18:36:21.401842379 +0200 @@ -39,6 +39,7 @@ extern int pingtimeout; extern int maxtimeout; extern int mintimeout; +extern int mark; extern bool bypass_security; extern char *confbase; extern char *netname; Seulement dans tinc-1.0.28/src: Makefile diff -ur tinc-1.0.28-orig/src/net_socket.c tinc-1.0.28/src/net_socket.c --- tinc-1.0.28-orig/src/net_socket.c 2016-04-09 15:16:47.000000000 +0200 +++ tinc-1.0.28/src/net_socket.c 2016-10-10 18:41:01.081238670 +0200 @@ -69,25 +69,40 @@ logger(LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno)); } #endif - + + int one = 1; + int val = mark; + #if defined(SOL_TCP) && defined(TCP_NODELAY) option = 1; setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof(option)); + if ( mark != 0 ){ + setsockopt(c->socket, SOL_TCP, SO_MARK, (void *)&val, sizeof(one)); + } + #endif #if defined(SOL_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY) option = IPTOS_LOWDELAY; setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&option, sizeof(option)); + if ( mark != 0 ){ + setsockopt(c->socket, SOL_IP, SO_MARK, (void *)&val, sizeof(one)); + } #endif #if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY) option = IPTOS_LOWDELAY; setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof(option)); + if ( mark != 0 ){ + setsockopt(c->socket, IPPROTO_IPV6, SO_MARK, (void *)&val, sizeof(one)); + } #endif } static bool bind_to_interface(int sd) { char *iface; + int val = mark; + int one = 1; #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) struct ifreq ifr; @@ -108,6 +123,12 @@ logger(LOG_ERR, "Can't bind to interface %s: %s", ifr.ifr_ifrn.ifrn_name, strerror(errno)); return false; } + else{ + if ( mark != 0 ){ + setsockopt(sd, SOL_SOCKET, SO_MARK, (void *)&val, sizeof(one)); + } + } + #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */ logger(LOG_WARNING, "%s not supported on this platform", "BindToInterface"); @@ -121,13 +142,16 @@ char *addrstr; int option; char *iface; + int val = mark; + int one = 1; nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP); - + if(nfd < 0) { ifdebug(STATUS) logger(LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno)); return -1; } + #ifdef FD_CLOEXEC fcntl(nfd, F_SETFD, FD_CLOEXEC); @@ -137,6 +161,11 @@ option = 1; setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); + if ( mark != 0 ){ + setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&val, sizeof(one)); + } + + #if defined(SOL_IPV6) && defined(IPV6_V6ONLY) if(sa->sa.sa_family == AF_INET6) @@ -184,6 +213,7 @@ int nfd; char *addrstr; int option; + int one = 1; nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); @@ -221,6 +251,9 @@ option = 1; setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option)); + + option = mark; + setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&option, sizeof(one)); if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno)); diff -ur tinc-1.0.28-orig/src/tincd.c tinc-1.0.28/src/tincd.c --- tinc-1.0.28-orig/src/tincd.c 2016-04-09 15:41:35.000000000 +0200 +++ tinc-1.0.28/src/tincd.c 2016-10-10 18:36:21.402842391 +0200 @@ -82,6 +82,9 @@ /* If nonzero, generate public/private keypair for this host/net. */ int generate_keys = 0; +/* If nonzero, generate public/private keypair for this host/net. */ +int mark = 0; + /* If nonzero, use null ciphers and skip all key exchanges. */ bool bypass_security = false; @@ -120,6 +123,7 @@ {"logfile", optional_argument, NULL, 4}, {"pidfile", required_argument, NULL, 5}, {"option", required_argument, NULL, 'o'}, + {"mark", required_argument, NULL, 'm'}, {NULL, 0, NULL, 0} }; @@ -147,6 +151,7 @@ " -o, --option=[HOST.]KEY=VALUE Set global/host configuration value.\n" " -R, --chroot chroot to NET dir at startup.\n" " -U, --user=USER setuid to given USER at startup.\n" + " -m, --mark=MARK mark to address several output ip.\n" " --help Display this help and exit.\n" " --version Output version information and exit.\n\n"); printf("Report bugs to tinc at tinc-vpn.org.\n"); @@ -161,7 +166,7 @@ cmdline_conf = list_alloc((list_action_t)free_config); - while((r = getopt_long(argc, argv, "c:DLd::k::n:o:K::RU:", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "c:DLd::k::n:o:K::RU:m:", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; @@ -197,6 +202,16 @@ debug_level++; break; + case 'm': /* increase debug level */ + if(!optarg && optind < argc && *argv[optind] != '-') + optarg = argv[optind++]; + if(optarg) + mark = atoi(optarg); + else + mark = 0; + break; + + case 'k': /* kill old tincds */ #ifndef HAVE_MINGW if(!optarg && optind < argc && *argv[optind] != '-') Le 06/10/2016 à 14:11, Guus Sliepen a écrit :> On Wed, Oct 05, 2016 at 07:27:54PM +0200, Olivier Tirat wrote: > >> I'd like to mark all sockets established by a tincd process with a mark >> passed as an argument in the command line. > [...] >> Do you think its something interesting? >> Do you think its a hard work to do? >> If not i could probably try to do it and propose a patch for that if you >> think it is interesting. > I think it is relatively easy to do. There are two places in > src/net_socket.c where you would have to call setsockopt() with the > SO_MARK option: configure_tcp() and setup_vpn_in_socket(). The first one > is run for all incoming and outgoing TCP sockets, the second one sets up > the UDP sockets. > > Try it out and see if it really allows you to do the mark-based routing > you want. If it works, you can submit a patch or pull request. > > > > _______________________________________________ > tinc mailing list > tinc at tinc-vpn.org > https://www.tinc-vpn.org/cgi-bin/mailman/listinfo/tinc--- L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast. https://www.avast.com/antivirus -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://www.tinc-vpn.org/pipermail/tinc/attachments/20161010/c6bf5f25/attachment-0001.html> -------------- next part -------------- diff -ur tinc-1.0.28-orig/src/conf.h tinc-1.0.28/src/conf.h --- tinc-1.0.28-orig/src/conf.h 2014-08-27 10:40:51.000000000 +0200 +++ tinc-1.0.28/src/conf.h 2016-10-10 18:36:21.401842379 +0200 @@ -39,6 +39,7 @@ extern int pingtimeout; extern int maxtimeout; extern int mintimeout; +extern int mark; extern bool bypass_security; extern char *confbase; extern char *netname; Seulement dans tinc-1.0.28/src: Makefile diff -ur tinc-1.0.28-orig/src/net_socket.c tinc-1.0.28/src/net_socket.c --- tinc-1.0.28-orig/src/net_socket.c 2016-04-09 15:16:47.000000000 +0200 +++ tinc-1.0.28/src/net_socket.c 2016-10-10 18:41:01.081238670 +0200 @@ -69,25 +69,40 @@ logger(LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno)); } #endif - + + int one = 1; + int val = mark; + #if defined(SOL_TCP) && defined(TCP_NODELAY) option = 1; setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof(option)); + if ( mark != 0 ){ + setsockopt(c->socket, SOL_TCP, SO_MARK, (void *)&val, sizeof(one)); + } + #endif #if defined(SOL_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY) option = IPTOS_LOWDELAY; setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&option, sizeof(option)); + if ( mark != 0 ){ + setsockopt(c->socket, SOL_IP, SO_MARK, (void *)&val, sizeof(one)); + } #endif #if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY) option = IPTOS_LOWDELAY; setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof(option)); + if ( mark != 0 ){ + setsockopt(c->socket, IPPROTO_IPV6, SO_MARK, (void *)&val, sizeof(one)); + } #endif } static bool bind_to_interface(int sd) { char *iface; + int val = mark; + int one = 1; #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) struct ifreq ifr; @@ -108,6 +123,12 @@ logger(LOG_ERR, "Can't bind to interface %s: %s", ifr.ifr_ifrn.ifrn_name, strerror(errno)); return false; } + else{ + if ( mark != 0 ){ + setsockopt(sd, SOL_SOCKET, SO_MARK, (void *)&val, sizeof(one)); + } + } + #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */ logger(LOG_WARNING, "%s not supported on this platform", "BindToInterface"); @@ -121,13 +142,16 @@ char *addrstr; int option; char *iface; + int val = mark; + int one = 1; nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP); - + if(nfd < 0) { ifdebug(STATUS) logger(LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno)); return -1; } + #ifdef FD_CLOEXEC fcntl(nfd, F_SETFD, FD_CLOEXEC); @@ -137,6 +161,11 @@ option = 1; setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); + if ( mark != 0 ){ + setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&val, sizeof(one)); + } + + #if defined(SOL_IPV6) && defined(IPV6_V6ONLY) if(sa->sa.sa_family == AF_INET6) @@ -184,6 +213,7 @@ int nfd; char *addrstr; int option; + int one = 1; nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); @@ -221,6 +251,9 @@ option = 1; setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option)); + + option = mark; + setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&option, sizeof(one)); if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno)); diff -ur tinc-1.0.28-orig/src/tincd.c tinc-1.0.28/src/tincd.c --- tinc-1.0.28-orig/src/tincd.c 2016-04-09 15:41:35.000000000 +0200 +++ tinc-1.0.28/src/tincd.c 2016-10-10 18:36:21.402842391 +0200 @@ -82,6 +82,9 @@ /* If nonzero, generate public/private keypair for this host/net. */ int generate_keys = 0; +/* If nonzero, generate public/private keypair for this host/net. */ +int mark = 0; + /* If nonzero, use null ciphers and skip all key exchanges. */ bool bypass_security = false; @@ -120,6 +123,7 @@ {"logfile", optional_argument, NULL, 4}, {"pidfile", required_argument, NULL, 5}, {"option", required_argument, NULL, 'o'}, + {"mark", required_argument, NULL, 'm'}, {NULL, 0, NULL, 0} }; @@ -147,6 +151,7 @@ " -o, --option=[HOST.]KEY=VALUE Set global/host configuration value.\n" " -R, --chroot chroot to NET dir at startup.\n" " -U, --user=USER setuid to given USER at startup.\n" + " -m, --mark=MARK mark to address several output ip.\n" " --help Display this help and exit.\n" " --version Output version information and exit.\n\n"); printf("Report bugs to tinc at tinc-vpn.org.\n"); @@ -161,7 +166,7 @@ cmdline_conf = list_alloc((list_action_t)free_config); - while((r = getopt_long(argc, argv, "c:DLd::k::n:o:K::RU:", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "c:DLd::k::n:o:K::RU:m:", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; @@ -197,6 +202,16 @@ debug_level++; break; + case 'm': /* increase debug level */ + if(!optarg && optind < argc && *argv[optind] != '-') + optarg = argv[optind++]; + if(optarg) + mark = atoi(optarg); + else + mark = 0; + break; + + case 'k': /* kill old tincds */ #ifndef HAVE_MINGW if(!optarg && optind < argc && *argv[optind] != '-')