Date: Sun, 10 Jun 2007 22:30:05 GMT From: Matus Harvan <mharvan@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 121366 for review Message-ID: <200706102230.l5AMU5Wn042230@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=121366 Change 121366 by mharvan@mharvan_twoflower on 2007/06/10 22:29:54 Updated with responses from Max and Brooks from 2007-04-23. Affected files ... .. //depot/projects/soc2007/mharvan-mtund/mtund.doc/design.txt#2 edit Differences ... ==== //depot/projects/soc2007/mharvan-mtund/mtund.doc/design.txt#2 (text+ko) ==== @@ -4,8 +4,10 @@ mentors. TODO: -* update with responses from Max from 2007-04-23 -* update with responses from Brooks from 2007-04-23 +o use libevent (http://www.monkey.org/~provos/libevent/) +o configuration of tun iface done by daemon (call ifconfig&friends) +o man page +o port skeleton TUN(4) INTERFACE (OR SOMETHING ELSE?) My original idea, as described in the proposal is to use the tun(4) @@ -29,29 +31,27 @@ others could not. Or maybe this would be doable with one of the firewalls available on FreeBSD? -One problem I have recently learned about is that by default it tags -packets as being IPv4. To have IPv6 working over it, one has to disable -the the IFF_NO_PI flag and prefix each packet with a 4-byte struct -specifying the type of traffic (ETH_P_IPV6). These are the flag -constants on linux, as I am currently writing code on linux. On FreeBSD, -the flag seems to be TUNSLMODE. Another approach would be to change the -kernel code to look at the first byte of the packet (the version field -for both IPv4 and IPv6) and determine from that if it's IPv4 or IPv6. On -FreeBSD 6.1, the hardcoded value is set on line 865 in file -/sys/net/if_tun.c. But then, I'm not sure if we care for IPv6 at the -moment. +One problem with IPv6 and tun(4) is that by default it tags packets as +being IPv4. However, at the moment IPv4 is the main goal and IPv6 +support is left for later. To have IPv6 working over it, one has to +disable the the IFF_NO_PI flag and prefix each packet with a 4-byte +struct specifying the type of traffic (ETH_P_IPV6). These are the flag +constants on linux, as I am currently writing code on linux. On +FreeBSD, the flag seems to be TUNSLMODE. Another approach would be to +change the kernel code to look at the first byte of the packet (the +version field for both IPv4 and IPv6) and determine from that if it's +IPv4 or IPv6. On FreeBSD 6.1, the hardcoded value is set on line 865 +in file /sys/net/if_tun.c. -Max has mentioned netgraph as an alternative for tun. I have never used -netgraph and do not know much about it. Would the plugins then have to -be implemented in the kernel space or could they still live in the -userspace? Do you think that it would make more sense to use that rather -than tun(4) or should I start with tun(4) and maybe later change to -netgraph? Or do you think that something completely different should be -used? +Max has mentioned netgraph as an alternative for tun. However, it has +been decided that tun(4) would be used rather than netgraph. MULTIPLEXING BETWEEN DIFFERENT FILE DESCRIPTORS -The easiest way that came to my mind was using select(2). The plugins of -course have to register their file descriptors to be watched. +The easiest way that came to my mind was using select(2). The plugins +of course have to register their file descriptors to be watched. The +code will be rewritten to use libevent. This will allow to easily use +timeouts for checking the connectivity of plugins or do other +timeout-related things. Another alternative would be to fork a process for each plugin or to use threads. It may give more flexibility to the plugins, but at the moment @@ -70,37 +70,45 @@ interval. If that fails N times, the connection is declared malfunctioning. -For the implementation I was thinking about registering a timer and -having a handler for the timer signal. I do not know yet exactly how to -do that, but I think that I have seen somewhere some code doing it. One -issue is that I might receive the timer signal at an inappropriate time -and would have to properly protect shared variables. +For the implementation, things should get easier with the use of +libevent. This would easily allow signalling timeouts. One issue is +that I might receive the timer signal at an inappropriate time and +would have to properly protect shared variables. This has to be +checked. In general, synchronization and multi-threaded safety should +be considered. Another way would be to use select(2) with a struct timeval *timeout -(5th argument), which might be easier. I think I would first try to -implement this approach. +(5th argument), which might be easier. For this part, having plugins written as threads/processes might give them more flexibility. However, I do not think that such flexibility is needed. At least not at the moment. REDIRECTING ONLY CERTAIN PORTS -I think Brooks has mentioned that we might want to allow for redirecting -only certain ports via the tunnel while leaving others to go directly. I -do not know how I could do that or where would be the right place to -enter a hook for that. Shall we ignore this at the moment and look at it -once I have more plugins and the daemon running or should we accomodate -for this in the design already now? +We might want to allow for redirecting only certain ports via the +tunnel while leaving others to go directly. One way to achieve this +would be to use pf anchors. Examples can be found in usr.sbin/authpf +in base or ftp/ftp-proxy in ports. Currently, this is consider an +optional feature and hence left for later, MULTI USER SUPPORT ON THE SERVER -Brooks has mentioned that some sort of multi user support on the server -would be nice. My understanding of that is that one server should be -able to server several clients at the same time. I have not really -thought about this yet. Maybe a separate tun(4) interface could be -created for each user on the server and the burden of multiplexing -between them and assigning traffic to the right tun interface (and hence -mtund instance) would be the responsibility of the kernel by using -entries in the routing table or tracking connections when natting. +The server shall support multiple users concurrently. This is an +important feature and the design has to be changed appropriately to +accomodate for it. + +At the moment, it is unclear how the multi user support could be +achieved, but some session management, possibly with some +atuhentication/handshake out-of-band. Some encapsulations such as UDP +and TCP offer port and addresses for identifiyng the sessions/clients +while for others (ICMP) the session may have to be signalled +in-band. In particular, with the former a separate file descriptor +represents each client, making things easier. + +Maybe a separate tun(4) interface could be created for each user on +the server and the burden of multiplexing between them and assigning +traffic to the right tun interface (and hence mtund instance) would be +the responsibility of the kernel by using entries in the routing table +or tracking connections when natting. AUTODETECTION I'm not sure what/how could/should be autodetected. I guess some proxy @@ -113,31 +121,46 @@ offering dns, http proxying,... QUEUING -Should we do some queuing of packets in the daemon? Or after read(2) we -immediately call write(2) and that's it? If fragmentation is needed, -some queuing might be needed. +The current implementation with blocking I/O does queuing of one +packet. If this approach turns out to be problematic, different +queuing strategies would have to be investigated. FRAGMENTATION -What if the encapsulation provides a smaler MTU? This might be the case -for DNS tunnelling. We should hten probably fragment packets and -reassmble fragments on the other end. +What if the encapsulation provides a smaler MTU? This might be the +case for DNS tunnelling. We should then probably fragment packets and +reassemble fragments on the other end. For this, in-band signalling +might be needed. + +In additiona, for TCP we have to do STREAM <-> MSG dissection, for MSG +based protocols we have to figure out MSS (probably without the help +of ICMP) and fragment accordingly. + +Max thinks the absolute minimum we should provide is a MTU of 1300 +(1280 + 20) which will allow to run a gif tunnel over the mtund tunnel +without the need for IPv4 fragmentation for the gif tunnel. CRYPTO +The easiest way to secure the tunnel would be to put IPSec on the tun +interface. Other options would likely not be investigated, but +nevertheless are descibed in this document. + Offering basic encryption support should be easy. Putting a symmetric -key onto both, the client and the server, encapsulated payload could be -encrypted with blowfish, aes or another symmetric cipher. +key onto both, the client and the server, encapsulated payload could +be encrypted with blowfish, aes or another symmetric cipher. Adding authentication might be harder and I'm not sure it's a high priority. CONFIG FILE -What should be configurable? What should the config file then look like? +What should be configurable? What should the config file then look +like? The config file would be plain text file. It's format and +contents will be determined later. PROJECT SCHEDULE I have put a rough estimate of a schedule in the proposal: * core tunnel daemon, config file parsing, plugin interface - 2 weeks -* probing/checking strategy for unreliable protocols (UDP, ICMP) - 1 -* week +* probing/checking strategy for unreliable protocols (UDP, ICMP) + - 1 week * TCP, UDP plugins - 1 week * ICMP plugin - 1 week * HTTP plugin - 1 week
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200706102230.l5AMU5Wn042230>