From: Guus Sliepen Date: Mon, 11 Feb 2002 15:59:18 +0000 (+0000) Subject: Added support for packet compression, thanks to Mark Glines. X-Git-Tag: release-1.0pre6~85 X-Git-Url: https://tinc-vpn.org/git/browse?a=commitdiff_plain;h=d9a62c6354d1e2ad78ee8c610518ae9f9ab012d1;p=tinc Added support for packet compression, thanks to Mark Glines. Add "Compression = " to the host config files, where level can be 0 (off), or any integer between 1 (fast) and 9 (best). --- diff --git a/THANKS b/THANKS index 0c50cf62..e4cfd6d0 100644 --- a/THANKS +++ b/THANKS @@ -17,6 +17,7 @@ We would like to thank * Jamie Briggs (for finding a lot of socket leaks) * Armijn Hemel (for being our very own PR manager) * Jerome Etienne (for a thorough security analysis of tinc) + * Mark Glines (for his compression patch) for their help, support and ideas. Thank you guys! diff --git a/configure.in b/configure.in index df0f2bcc..ec76e6d6 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Id: configure.in,v 1.13.2.39 2002/02/10 21:57:51 guus Exp $ +dnl $Id: configure.in,v 1.13.2.40 2002/02/11 15:59:18 guus Exp $ AC_INIT(src/tincd.c) AM_INIT_AUTOMAKE(tinc, 1.0-cvs) @@ -94,6 +94,7 @@ AC_CACHE_SAVE dnl These are defined in files in m4/ tinc_TUNTAP tinc_OPENSSL +tinc_ZLIB dnl Check if checkpoint tracing has to be enabled AC_ARG_ENABLE(tracing, diff --git a/doc/tinc.conf.5 b/doc/tinc.conf.5 index 547c75f1..642cc6b3 100644 --- a/doc/tinc.conf.5 +++ b/doc/tinc.conf.5 @@ -216,6 +216,9 @@ Any cipher supported by OpenSSL is recognised. Furthermore, specifying .Qq none will turn off packet encryption. +.It Va Compression Li = Ar level Pq 0 +This option sets the level of compression used for UDP packets. +Possible values are 0 (off), 1 (fast) and any integer up to 9 (best). .It Va Digest Li = Ar digest Pq sha1 The digest algorithm used to authenticate UDP packets. Any digest supported by OpenSSL is recognised. diff --git a/doc/tinc.texi b/doc/tinc.texi index ca399d5b..6bf9c1d1 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -1,5 +1,5 @@ \input texinfo @c -*-texinfo-*- -@c $Id: tinc.texi,v 1.8.4.19 2002/02/10 21:57:51 guus Exp $ +@c $Id: tinc.texi,v 1.8.4.20 2002/02/11 15:59:18 guus Exp $ @c %**start of header @setfilename tinc.info @settitle tinc Manual @@ -18,7 +18,7 @@ Copyright @copyright{} 1998-2002 Ivo Timmermans , Guus Sliepen and Wessel Dankers . -$Id: tinc.texi,v 1.8.4.19 2002/02/10 21:57:51 guus Exp $ +$Id: tinc.texi,v 1.8.4.20 2002/02/11 15:59:18 guus Exp $ Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -43,7 +43,7 @@ Copyright @copyright{} 1998-2002 Ivo Timmermans , Guus Sliepen and Wessel Dankers . -$Id: tinc.texi,v 1.8.4.19 2002/02/10 21:57:51 guus Exp $ +$Id: tinc.texi,v 1.8.4.20 2002/02/11 15:59:18 guus Exp $ Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -865,6 +865,11 @@ not the one that is internal to the VPN. The symmetric cipher algorithm used to encrypt UDP packets. Any cipher supported by OpenSSL is recognized. +@cindex Compression +@item Compression = (0) +This option sets the level of compression used for UDP packets. +Possible values are 0 (off), 1 (fast) and any integer up to 9 (best). + @cindex Digest @item Digest = (sha1) The digest algorithm used to authenticate UDP packets. diff --git a/m4/zlib.m4 b/m4/zlib.m4 new file mode 100644 index 00000000..8407838a --- /dev/null +++ b/m4/zlib.m4 @@ -0,0 +1,31 @@ +dnl Check to find the zlib headers/libraries + +AC_DEFUN(tinc_ZLIB, +[ + tinc_ac_save_CPPFLAGS="$CPPFLAGS" + + AC_ARG_WITH(zlib-include, + [ --with-zlib-include=DIR zlib headers directory], + [zlib_include="$withval" + CFLAGS="$CFLAGS -I$withval" + CPPFLAGS="$CPPFLAGS -I$withval"] + ) + + AC_ARG_WITH(zlib-lib, + [ --with-zlib-lib=DIR zlib library directory], + [zlib_lib="$withval" + LIBS="$LIBS -L$withval"] + ) + + AC_CHECK_HEADERS(zlib.h, + [], + [AC_MSG_ERROR("zlib header files not found."); break] + ) + + CPPFLAGS="$tinc_ac_save_CPPFLAGS" + + AC_CHECK_LIB(z, compress2, + [LIBS="$LIBS -lz"], + [AC_MSG_ERROR("zlib libraries not found.")] + ) +]) diff --git a/po/nl.po b/po/nl.po index 64895bf6..776e36d1 100644 --- a/po/nl.po +++ b/po/nl.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: tinc 1.0-cvs\n" -"POT-Creation-Date: 2002-02-09 21:32+0100\n" -"PO-Revision-Date: 2002-02-09 17:20+0100\n" +"POT-Creation-Date: 2002-02-11 16:57+0100\n" +"PO-Revision-Date: 2002-02-11 16:57+0100\n" "Last-Translator: Guus Sliepen \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" @@ -170,302 +170,315 @@ msgstr "Fout op metadata socket voor %s (%s) tijdens lezen: %m" msgid "Metadata read buffer overflow for %s (%s)" msgstr "Metadata leesbuffer overloop voor %s (%s)" -#: src/net.c:111 +#: src/net.c:118 #, c-format msgid "Got unauthenticated packet from %s (%s)" msgstr "Kreeg niet-geauthenticeerd pakket van %s (%s)" -#: src/net.c:134 +#: src/net.c:144 #, c-format msgid "Got late or replayed packet from %s (%s), seqno %d" msgstr "Kreeg laat of gedupliceerd pakket van %s (%s), seqno %d" -#: src/net.c:162 +#: src/net.c:161 +#, c-format +msgid "Error while uncompressing packet from %s (%s)" +msgstr "Fout tijdens decomprimeren pakket van %s (%s)" + +#: src/net.c:188 #, c-format msgid "Received packet of %d bytes from %s (%s)" msgstr "Ontvangst pakket van %d bytes van %s (%s)" -#: src/net.c:180 +#: src/net.c:210 #, c-format msgid "No valid key known yet for %s (%s), queueing packet" msgstr "" "Nog geen geldige sleutel bekend voor %s (%s), pakket wordt in wachtrij gezet" -#: src/net.c:225 +#: src/net.c:235 +#, c-format +msgid "Error while compressing packet to %s (%s)" +msgstr "Fout tijdens comprimeren pakket naar %s (%s)" + +#: src/net.c:278 #, c-format msgid "Error sending packet to %s (%s): %m" msgstr "Fout tijdens verzenden pakket naar %s (%s): %m" -#: src/net.c:240 +#: src/net.c:293 #, c-format msgid "Sending packet of %d bytes to %s (%s)" msgstr "Verzending pakket van %d bytes naar %s (%s)" -#: src/net.c:247 +#: src/net.c:300 msgid "Packet is looping back to us!" msgstr "Pakket komt terug naar ons!" -#: src/net.c:256 +#: src/net.c:309 #, c-format msgid "Node %s (%s) is not reachable" msgstr "Node %s (%s) is niet bereikbaar" -#: src/net.c:264 +#: src/net.c:317 #, c-format msgid "Sending packet to %s via %s (%s)" msgstr "Verzending pakket naar %s via %s (%s)" -#: src/net.c:284 +#: src/net.c:337 #, c-format msgid "Broadcasting packet of %d bytes from %s (%s)" msgstr "Verspreiding pakket van %d bytes van %s (%s)" -#: src/net.c:301 +#: src/net.c:354 #, c-format msgid "Flushing queue for %s (%s)" msgstr "Legen van wachtrij voor %s (%s)" -#: src/net.c:326 +#: src/net.c:379 #, c-format msgid "Creating metasocket failed: %m" msgstr "Aanmaak van metasocket mislukt: %m" -#: src/net.c:334 src/net.c:380 src/net.c:407 src/net.c:987 src/process.c:258 +#: src/net.c:387 src/net.c:433 src/net.c:460 src/net.c:1091 src/process.c:258 #: src/process.c:294 #, c-format msgid "System call `%s' failed: %m" msgstr "Systeemaanroep `%s' mislukte: %m" -#: src/net.c:354 +#: src/net.c:407 #, c-format msgid "Can't bind to interface %s: %m" msgstr "Kan niet aan interface %s binden: %m" -#: src/net.c:373 +#: src/net.c:426 #, c-format msgid "Can't bind to port %hd/tcp: %m" msgstr "Kan niet aan poort %hd/tcp binden: %m" -#: src/net.c:397 +#: src/net.c:450 #, c-format msgid "Creating socket failed: %m" msgstr "Aanmaak socket mislukte: %m" -#: src/net.c:420 +#: src/net.c:473 #, c-format msgid "Can't bind to port %hd/udp: %m" msgstr "Kan niet aan poort %hd/udp binden: %m" -#: src/net.c:442 +#: src/net.c:495 #, c-format msgid "Trying to re-establish outgoing connection in %d seconds" msgstr "Poging tot herstellen van uitgaande verbinding over %d seconden" -#: src/net.c:452 +#: src/net.c:505 #, c-format msgid "Trying to connect to %s (%s)" msgstr "Poging tot verbinden met %s (%s)" -#: src/net.c:458 +#: src/net.c:511 #, c-format msgid "Creating socket for %s port %d failed: %m" msgstr "Aanmaken socket voor %s poort %d mislukt: %m" -#: src/net.c:500 +#: src/net.c:553 #, c-format msgid "%s port %hd: %m" msgstr "%s poort %hd: %m" -#: src/net.c:509 +#: src/net.c:562 #, c-format msgid "fcntl for %s port %d: %m" msgstr "fcntl voor %s poort %d: %m" -#: src/net.c:515 +#: src/net.c:568 #, c-format msgid "Connected to %s port %hd" msgstr "Verbonden met %s poort %hd" -#: src/net.c:533 +#: src/net.c:586 #, c-format msgid "Already connected to %s" msgstr "Reeds verbonden met %s" -#: src/net.c:546 +#: src/net.c:599 #, c-format msgid "No address specified for %s" msgstr "Geen adres gespecificeerd voor %s" -#: src/net.c:558 +#: src/net.c:611 #, c-format msgid "Error looking up `%s': %m" msgstr "Fout bij het opzoeken van `%s': %m" -#: src/net.c:569 +#: src/net.c:622 #, c-format msgid "Could not set up a meta connection to %s (%s)" msgstr "Kon geen metaverbinding aangaan met %s (%s)" -#: src/net.c:610 +#: src/net.c:664 #, c-format msgid "Error reading RSA public key file `%s': %m" msgstr "Fout tijdens lezen RSA publieke sleutel bestand `%s': %m" -#: src/net.c:618 +#: src/net.c:674 #, c-format msgid "Reading RSA public key file `%s' failed: %m" msgstr "Lezen RSA publieke sleutel bestand `%s' mislukt: %m" -#: src/net.c:643 +#: src/net.c:702 #, c-format msgid "No public key for %s specified!" msgstr "Geen publieke sleutel bekend voor %s gespecificeerd!" -#: src/net.c:663 +#: src/net.c:728 #, c-format msgid "Error reading RSA private key file `%s': %m" msgstr "Fout tijdens lezen RSA privé sleutel bestand `%s': %m" -#: src/net.c:671 +#: src/net.c:738 #, c-format msgid "Reading RSA private key file `%s' failed: %m" msgstr "Fout tijdens lezen RSA privé sleutel bestand `%s': %m" -# -#: src/net.c:678 -msgid "No private key for tinc daemon specified!" -msgstr "Geen privé sleutel voor tinc daemon gespecificeerd!" - -#: src/net.c:699 src/net.c:700 +#: src/net.c:791 src/net.c:792 msgid "MYSELF" msgstr "MIJZELF" -#: src/net.c:707 +#: src/net.c:799 msgid "Name for tinc daemon required!" msgstr "Naam voor tinc daemon verplicht!" -#: src/net.c:713 +#: src/net.c:805 msgid "Invalid name for myself!" msgstr "Ongelige naam voor mijzelf!" -#: src/net.c:727 +#: src/net.c:819 msgid "Cannot open host configuration file for myself!" msgstr "Kan host configuratie bestand voor mijzelf niet openen!" -#: src/net.c:793 +#: src/net.c:829 +msgid "Invalid public/private keypair!" +msgstr "Ongeldig publiek/privé sleutelpaar!" + +#: src/net.c:884 msgid "Invalid routing mode!" msgstr "Ongelige routing modus!" -#: src/net.c:805 +#: src/net.c:896 msgid "Unable to set up a listening TCP socket!" msgstr "Kon geen TCP luistersocket aanmaken!" -#: src/net.c:811 +#: src/net.c:902 msgid "Unable to set up a listening UDP socket!" msgstr "Kon geen UDP luistersocket aanmaken!" -#: src/net.c:827 +#: src/net.c:918 msgid "Unrecognized cipher type!" msgstr "Onbekend cipher type!" -#: src/net.c:860 +#: src/net.c:951 msgid "Unrecognized digest type!" msgstr "Onbekend digest type!" -#: src/net.c:874 +#: src/net.c:965 msgid "MAC length exceeds size of digest!" msgstr "MAC lengte is groter dan dat van digest!" -#: src/net.c:879 +#: src/net.c:970 msgid "Bogus MAC length!" msgstr "Onzinnige MAC lengte!" -#: src/net.c:896 +#: src/net.c:984 +msgid "Bogus compression level!" +msgstr "Onzinnig compressieniveau!" + +#: src/net.c:1000 #, c-format msgid "Ready: listening on port %hd" msgstr "Gereed: luisterend op poort %hd" -#: src/net.c:1000 +#: src/net.c:1104 #, c-format msgid "Connection from %s port %d" msgstr "Verbinding van %s poort %d" -#: src/net.c:1045 +#: src/net.c:1149 #, c-format msgid "This is a bug: %s:%d: %d:%m" msgstr "Dit is een programmeerfout: %s:%d: %d:%m" -#: src/net.c:1051 +#: src/net.c:1155 #, c-format msgid "Incoming data socket error: %s" msgstr "Fout op socket voor inkomend verkeer: %s" -#: src/net.c:1057 +#: src/net.c:1161 #, c-format msgid "Receiving packet failed: %m" msgstr "Ontvangst pakket mislukt: %m" -#: src/net.c:1065 +#: src/net.c:1169 #, c-format msgid "Received UDP packet on port %hd from unknown source %x:%hd" msgstr "Ontvangst UDP pakket op poort %hd van onbekende oorsprong %x:%hd" -#: src/net.c:1088 +#: src/net.c:1192 msgid "Purging unreachable nodes" msgstr "Verwijderen onbereikbare nodes" -#: src/net.c:1098 +#: src/net.c:1202 #, c-format msgid "Purging node %s (%s)" msgstr "Verwijdering node %s (%s)" -#: src/net.c:1152 +#: src/net.c:1256 #, c-format msgid "Closing connection with %s (%s)" msgstr "Beëindigen verbinding met %s (%s)" -#: src/net.c:1223 +#: src/net.c:1327 #, c-format msgid "%s (%s) didn't respond to PING" msgstr "%s (%s) antwoordde niet op ping" -#: src/net.c:1236 +#: src/net.c:1340 #, c-format msgid "Timeout from %s (%s) during authentication" msgstr "Timeout van %s (%s) tijdens authenticatie" -#: src/net.c:1257 +#: src/net.c:1361 #, c-format msgid "Accepting a new connection failed: %m" msgstr "Aanname van nieuwe verbinding is mislukt: %m" -#: src/net.c:1265 +#: src/net.c:1369 msgid "Closed attempted connection" msgstr "Aangenomen verbinding verbroken" -#: src/net.c:1288 +#: src/net.c:1392 #, c-format msgid "Invalid name for outgoing connection in %s line %d" msgstr "Ongelige naam voor uitgaande verbinding in %s regel %d" -#: src/net.c:1384 +#: src/net.c:1488 #, c-format msgid "Error while waiting for input: %m" msgstr "Fout tijdens wachten op invoer: %m" -#: src/net.c:1391 +#: src/net.c:1495 msgid "Rereading configuration file and restarting in 5 seconds" msgstr "Herlezen configuratiebestand en herstart in 5 seconden" -#: src/net.c:1398 +#: src/net.c:1502 msgid "Unable to reread configuration file, exiting" msgstr "Kan configuratiebestand niet herlezen, beëindigen" -#: src/net.c:1430 +#: src/net.c:1534 msgid "Regenerating symmetric key" msgstr "Hergenereren symmetrische sleutel" -#: src/net.c:1440 +#: src/net.c:1544 msgid "Flushing event queue" msgstr "Legen taakrij" @@ -1010,11 +1023,11 @@ msgstr "Nodes:" #: src/node.c:166 #, c-format msgid "" -" %s at %s port %hd cipher %d digest %d maclength %d options %ld status %04x " -"nexthop %s via %s" +" %s at %s port %hd cipher %d digest %d maclength %d compression %d options %" +"ld status %04x nexthop %s via %s" msgstr "" -" %s op %s poort %hd cipher %d digest %d maclengte %d opties %ld status %04x " -"nexthop %s via %s" +" %s op %s poort %hd cipher %d digest %d maclengte %d compressie %d opties %" +"ld status %04x nexthop %s via %s" #: src/node.c:171 msgid "End of nodes." @@ -1043,69 +1056,69 @@ msgstr "Node %s (%s) werd bereikbaar" msgid "Node %s (%s) became unreachable" msgstr "Node %s (%s) is niet meer bereikbaar" -#: src/freebsd/device.c:69 src/linux/device.c:84 src/openbsd/device.c:73 +#: src/freebsd/device.c:69 src/linux/device.c:88 src/openbsd/device.c:73 #: src/solaris/device.c:74 #, c-format msgid "Could not open %s: %m" msgstr "Kon `%s' niet openen: %m" -#: src/linux/device.c:109 src/linux/device.c:119 +#: src/linux/device.c:113 src/linux/device.c:123 msgid "Linux tun/tap device" msgstr "Linux tun/tap apparaat" -#: src/linux/device.c:117 +#: src/linux/device.c:121 #, c-format msgid "Old ioctl() request was needed for %s" msgstr "Oud ioctl() verzoek was nodig voor %s" -#: src/linux/device.c:126 +#: src/linux/device.c:130 msgid "Linux ethertap device" msgstr "Linux ethertap apparaat" -#: src/freebsd/device.c:86 src/linux/device.c:130 src/openbsd/device.c:89 -#: src/solaris/device.c:128 +#: src/freebsd/device.c:86 src/linux/device.c:134 src/openbsd/device.c:89 +#: src/solaris/device.c:131 #, c-format msgid "%s is a %s" msgstr "%s is een %s" -#: src/freebsd/device.c:107 src/linux/device.c:153 src/linux/device.c:163 -#: src/openbsd/device.c:110 src/solaris/device.c:145 +#: src/freebsd/device.c:107 src/linux/device.c:157 src/linux/device.c:167 +#: src/openbsd/device.c:110 src/solaris/device.c:148 #, c-format msgid "Error while reading from %s %s: %m" msgstr "Fout tijdens lezen van %s %s: %m" -#: src/freebsd/device.c:116 src/linux/device.c:174 src/openbsd/device.c:125 -#: src/solaris/device.c:160 +#: src/freebsd/device.c:116 src/linux/device.c:178 src/openbsd/device.c:125 +#: src/solaris/device.c:163 #, c-format msgid "Read packet of %d bytes from %s" msgstr "Pakket van %d bytes gelezen van %s" -#: src/freebsd/device.c:127 src/linux/device.c:185 src/openbsd/device.c:138 -#: src/solaris/device.c:171 +#: src/freebsd/device.c:127 src/linux/device.c:189 src/openbsd/device.c:138 +#: src/solaris/device.c:174 #, c-format msgid "Writing packet of %d bytes to %s" msgstr "Pakket van %d bytes geschreven naar %s" -#: src/linux/device.c:192 src/linux/device.c:201 src/openbsd/device.c:148 -#: src/solaris/device.c:176 +#: src/linux/device.c:196 src/linux/device.c:205 src/openbsd/device.c:148 +#: src/solaris/device.c:179 #, c-format msgid "Can't write to %s %s: %m" msgstr "Kan niet schrijven naar %s %s: %m" -#: src/freebsd/device.c:143 src/linux/device.c:214 src/openbsd/device.c:159 -#: src/solaris/device.c:188 +#: src/freebsd/device.c:143 src/linux/device.c:218 src/openbsd/device.c:159 +#: src/solaris/device.c:191 #, c-format msgid "Statistics for %s %s:" msgstr "Statistieken voor %s %s:" -#: src/freebsd/device.c:144 src/linux/device.c:215 src/openbsd/device.c:160 -#: src/solaris/device.c:189 +#: src/freebsd/device.c:144 src/linux/device.c:219 src/openbsd/device.c:160 +#: src/solaris/device.c:192 #, c-format msgid " total bytes in: %10d" msgstr " totaal aantal bytes in: %10d" -#: src/freebsd/device.c:145 src/linux/device.c:216 src/openbsd/device.c:161 -#: src/solaris/device.c:190 +#: src/freebsd/device.c:145 src/linux/device.c:220 src/openbsd/device.c:161 +#: src/solaris/device.c:193 #, c-format msgid " total bytes out: %10d" msgstr " totaal aantal bytes uit: %10d" @@ -1153,14 +1166,6 @@ msgstr "Kon PPA %d niet instellen: %m" msgid "Can't link TUN device to IP: %m" msgstr "Kan TUN apparaat niet koppelen aan IP: %m" -#: src/solaris/device.c:116 +#: src/solaris/device.c:119 msgid "Solaris tun device" msgstr "Solaris tun apparaat" - -#~ msgid "No digest, MAC length ignored" -#~ msgstr "Geen digest, MAC lengte genegeerd" - -#~ msgid "Failed to setup all outgoing connections, will retry in %d seconds" -#~ msgstr "" -#~ "Poging tot maken van alle uitgaande verbinding faalde, nieuwe poging over " -#~ "%d seconden" diff --git a/src/net.c b/src/net.c index 71829534..c2170acd 100644 --- a/src/net.c +++ b/src/net.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: net.c,v 1.35.4.153 2002/02/11 14:20:21 guus Exp $ + $Id: net.c,v 1.35.4.154 2002/02/11 15:59:18 guus Exp $ */ #include "config.h" @@ -55,6 +55,8 @@ #define RAND_pseudo_bytes RAND_bytes #endif +#include + #include #include #include @@ -96,11 +98,16 @@ int sigalrm = 0; void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { - vpn_packet_t outpkt; + vpn_packet_t pkt1, pkt2; + vpn_packet_t *pkt[] = {&pkt1, &pkt2, &pkt1, &pkt2}; + int nextpkt = 0; + vpn_packet_t *outpkt = pkt[0]; int outlen, outpad; + long int complen = MTU + 12; EVP_CIPHER_CTX ctx; char hmac[EVP_MAX_MD_SIZE]; cp + /* Check the message authentication code */ if(myself->digest && myself->maclength) { @@ -117,30 +124,49 @@ cp if(myself->cipher) { + outpkt = pkt[nextpkt++]; + EVP_DecryptInit(&ctx, myself->cipher, myself->key, myself->key + myself->cipher->key_len); - EVP_DecryptUpdate(&ctx, (char *)&outpkt.seqno, &outlen, (char *)&inpkt->seqno, inpkt->len); - EVP_DecryptFinal(&ctx, (char *)&outpkt.seqno + outlen, &outpad); - outlen += outpad; - outpkt.len = outlen - sizeof(outpkt.seqno); - } - else - { - memcpy((char *)&outpkt.seqno, (char *)&inpkt->seqno, inpkt->len); - outpkt.len = inpkt->len - sizeof(outpkt.seqno); + EVP_DecryptUpdate(&ctx, (char *)&outpkt->seqno, &outlen, (char *)&inpkt->seqno, inpkt->len); + EVP_DecryptFinal(&ctx, (char *)&outpkt->seqno + outlen, &outpad); + + outpkt->len = outlen + outpad; + inpkt = outpkt; } - if (ntohl(outpkt.seqno) <= n->received_seqno) + /* Check the sequence number */ + + inpkt->len -= sizeof(inpkt->seqno); + inpkt->seqno = ntohl(inpkt->seqno); + + if(inpkt->seqno <= n->received_seqno) { - syslog(LOG_DEBUG, _("Got late or replayed packet from %s (%s), seqno %d"), n->name, n->hostname, ntohl(*(unsigned int *)&outpkt.seqno)); + syslog(LOG_DEBUG, _("Got late or replayed packet from %s (%s), seqno %d"), n->name, n->hostname, inpkt->seqno); return; } - n->received_seqno = ntohl(outpkt.seqno); + n->received_seqno = inpkt->seqno; if(n->received_seqno > MAX_SEQNO) keyexpires = 0; - receive_packet(n, &outpkt); + /* Decompress the packet */ + + if(myself->compression) + { + outpkt = pkt[nextpkt++]; + + if(uncompress(outpkt->data, &complen, inpkt->data, inpkt->len) != Z_OK) + { + syslog(LOG_ERR, _("Error while uncompressing packet from %s (%s)"), n->name, n->hostname); + return; + } + + outpkt->len = complen; + inpkt = outpkt; + } + + receive_packet(n, inpkt); cp } @@ -167,8 +193,12 @@ cp void send_udppacket(node_t *n, vpn_packet_t *inpkt) { - vpn_packet_t outpkt; + vpn_packet_t pkt1, pkt2; + vpn_packet_t *pkt[] = {&pkt1, &pkt2, &pkt1, &pkt2}; + int nextpkt = 0; + vpn_packet_t *outpkt; int outlen, outpad; + long int complen = MTU + 12; EVP_CIPHER_CTX ctx; struct sockaddr_in to; socklen_t tolen = sizeof(to); @@ -190,37 +220,60 @@ cp if(!n->status.waitingforkey) send_req_key(n->nexthop->connection, myself, n); + return; } - /* Encrypt the packet. */ + /* Compress the packet */ + + if(n->compression) + { + outpkt = pkt[nextpkt++]; + + if(compress2(outpkt->data, &complen, inpkt->data, inpkt->len, n->compression) != Z_OK) + { + syslog(LOG_ERR, _("Error while compressing packet to %s (%s)"), n->name, n->hostname); + return; + } + + outpkt->len = complen; + inpkt = outpkt; + } + + /* Add sequence number */ inpkt->seqno = htonl(++(n->sent_seqno)); + inpkt->len += sizeof(inpkt->seqno); + + /* Encrypt the packet */ if(n->cipher) { + outpkt = pkt[nextpkt++]; + EVP_EncryptInit(&ctx, n->cipher, n->key, n->key + n->cipher->key_len); - EVP_EncryptUpdate(&ctx, (char *)&outpkt.seqno, &outlen, (char *)&inpkt->seqno, inpkt->len + sizeof(inpkt->seqno)); - EVP_EncryptFinal(&ctx, (char *)&outpkt.seqno + outlen, &outpad); - outlen += outpad; - } - else - { - memcpy((char *)&outpkt.seqno, (char *)&inpkt->seqno, inpkt->len + sizeof(inpkt->seqno)); - outlen = inpkt->len + sizeof(inpkt->seqno); + EVP_EncryptUpdate(&ctx, (char *)&outpkt->seqno, &outlen, (char *)&inpkt->seqno, inpkt->len); + EVP_EncryptFinal(&ctx, (char *)&outpkt->seqno + outlen, &outpad); + + outpkt->len = outlen + outpad; + inpkt = outpkt; } + /* Add the message authentication code */ + if(n->digest && n->maclength) { - HMAC(n->digest, n->key, n->keylength, (char *)&outpkt.seqno, outlen, (char *)&outpkt.seqno + outlen, &outpad); - outlen += n->maclength; + HMAC(n->digest, n->key, n->keylength, (char *)&inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len, &outlen); + inpkt->len += n->maclength; } + /* Send the packet */ + to.sin_family = AF_INET; to.sin_addr.s_addr = htonl(n->address); to.sin_port = htons(n->port); - if((sendto(udp_socket, (char *)&outpkt.seqno, outlen, 0, (const struct sockaddr *)&to, tolen)) < 0) + if((sendto(udp_socket, (char *)&inpkt->seqno, inpkt->len, 0, (const struct sockaddr *)&to, tolen)) < 0) { syslog(LOG_ERR, _("Error sending packet to %s (%s): %m"), n->name, n->hostname); @@ -921,6 +974,19 @@ cp } else myself->maclength = 4; + + /* Compression */ + + if(get_config_int(lookup_config(myself->connection->config_tree, "Compression"), &myself->compression)) + { + if(myself->compression < 0 || myself->compression > 9) + { + syslog(LOG_ERR, _("Bogus compression level!")); + return -1; + } + } + else + myself->compression = 0; cp /* Done */ diff --git a/src/node.c b/src/node.c index 5307ea66..2abd7fbf 100644 --- a/src/node.c +++ b/src/node.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: node.c,v 1.1.2.8 2002/02/10 21:57:54 guus Exp $ + $Id: node.c,v 1.1.2.9 2002/02/11 15:59:18 guus Exp $ */ #include "config.h" @@ -163,8 +163,8 @@ cp for(node = node_tree->head; node; node = node->next) { n = (node_t *)node->data; - syslog(LOG_DEBUG, _(" %s at %s port %hd cipher %d digest %d maclength %d options %ld status %04x nexthop %s via %s"), - n->name, n->hostname, n->port, n->cipher?n->cipher->nid:0, n->digest?n->digest->type:0, n->maclength, n->options, + syslog(LOG_DEBUG, _(" %s at %s port %hd cipher %d digest %d maclength %d compression %d options %ld status %04x nexthop %s via %s"), + n->name, n->hostname, n->port, n->cipher?n->cipher->nid:0, n->digest?n->digest->type:0, n->maclength, n->compression, n->options, n->status, n->nexthop?n->nexthop->name:"-", n->via?n->via->name:"-"); } diff --git a/src/node.h b/src/node.h index 6d281e62..b662ccd0 100644 --- a/src/node.h +++ b/src/node.h @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: node.h,v 1.1.2.10 2002/02/10 21:57:54 guus Exp $ + $Id: node.h,v 1.1.2.11 2002/02/11 15:59:18 guus Exp $ */ #ifndef __TINC_NODE_H__ @@ -54,6 +54,8 @@ typedef struct node_t { const EVP_MD *digest; /* Digest type for MAC */ int maclength; /* Length of MAC */ + int compression; /* Compressionlevel, 0 = no compression */ + list_t *queue; /* Queue for packets awaiting to be encrypted */ struct node_t *nexthop; /* nearest node from us to him */ diff --git a/src/protocol.h b/src/protocol.h index 5528b98f..e1c8ca9a 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: protocol.h,v 1.5.4.25 2002/02/10 21:57:54 guus Exp $ + $Id: protocol.h,v 1.5.4.26 2002/02/11 15:59:18 guus Exp $ */ #ifndef __TINC_PROTOCOL_H__ @@ -31,7 +31,7 @@ incompatible version have different protocols. */ -#define PROT_CURRENT 12 +#define PROT_CURRENT 13 /* Request numbers */ diff --git a/src/protocol_key.c b/src/protocol_key.c index 3c72c294..621bb1b8 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: protocol_key.c,v 1.1.4.1 2002/02/11 10:05:58 guus Exp $ + $Id: protocol_key.c,v 1.1.4.2 2002/02/11 15:59:18 guus Exp $ */ #include "config.h" @@ -167,8 +167,8 @@ cp bin2hex(from->key, key, from->keylength); key[from->keylength * 2] = '\0'; cp - return send_request(c, "%d %s %s %s %d %d %d", ANS_KEY, - from->name, to->name, key, from->cipher?from->cipher->nid:0, from->digest?from->digest->type:0, from->maclength); + return send_request(c, "%d %s %s %s %d %d %d %d", ANS_KEY, + from->name, to->name, key, from->cipher?from->cipher->nid:0, from->digest?from->digest->type:0, from->maclength, from->compression); } int ans_key_h(connection_t *c) @@ -176,10 +176,10 @@ int ans_key_h(connection_t *c) char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE]; - int cipher, digest, maclength; + int cipher, digest, maclength, compression; node_t *from, *to; cp - if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d", from_name, to_name, key, &cipher, &digest, &maclength) != 6) + if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d", from_name, to_name, key, &cipher, &digest, &maclength, &compression) != 7) { syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ANS_KEY", c->name, c->hostname); @@ -265,6 +265,8 @@ cp from->digest = NULL; from->maclength = maclength; } + + from->compression = compression; flush_queue(from); cp