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 [email protected].\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
[email protected]
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
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 [email protected].\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] !=
'-')
_______________________________________________
tinc mailing list
[email protected]
https://www.tinc-vpn.org/cgi-bin/mailman/listinfo/tinc