Dev: new option to mark all tincd socket of a tincd process
Olivier Tirat
olivier.tirat at byo-networks.com
Mon Oct 10 20:55:00 CEST 2016
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] != '-')
More information about the tinc
mailing list