]> Cypherpunks.ru repositories - govpn.git/commitdiff
Merge branch 'develop' 3.1
authorSergey Matveev <stargrave@stargrave.org>
Mon, 4 May 2015 16:48:03 +0000 (19:48 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Mon, 4 May 2015 16:48:03 +0000 (19:48 +0300)
Signed-off-by: Sergey Matveev <stargrave@stargrave.org>
19 files changed:
VERSION
doc/developer.texi
doc/download.texi
doc/govpn.texi
doc/handshake.texi
doc/handshake.txt
doc/installation.texi
doc/integrity.texi [new file with mode: 0644]
doc/keywords.texi
doc/news.texi
doc/overview.texi
doc/precautions.texi
doc/sources.texi [new file with mode: 0644]
doc/thanks.texi
doc/verifierstruct.texi
handshake.go
transport.go
transport_test.go
utils/makedist.sh

diff --git a/VERSION b/VERSION
index 9f55b2ccb5f234fc6b87ada62389a3d73815d0d1..8c50098d8aed57b02fd10f40a670a7c673b7c5a5 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.0
+3.1
index 3fd23ed817fae43d18409af8c9862dc351163aad..be57f2c8a3f117d87b6988c8154b2a1324281804 100644 (file)
@@ -11,6 +11,8 @@
 @item Password authenticated key agreement
 DH-A-EKE powered by @url{http://cr.yp.to/ecdh.html, Curve25519}
 and @url{http://ed25519.cr.yp.to/, Ed25519}
+@item DH elliptic-curve point encoding for public keys
+@url{http://elligator.cr.yp.to/, Elligator}
 @item Key derivation function for verifier generation
 @url{https://en.wikipedia.org/wiki/PBKDF2, PBKDF2} based on
 @url{https://en.wikipedia.org/wiki/SHA-2, SHA-512}
index 9c6193b8f707a65e44b01941a395e85412c3068e..68e596a2ffd8411ecb49e54dc397b47f9b6edf13 100644 (file)
@@ -1,3 +1,6 @@
+@node Prepared tarballs
+@section Prepared tarballs
+
 You can obtain releases source code prepared tarballs from the links below:
 
 @multitable {XXXXX} {XXXX KiB} {link sign} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@@ -23,13 +26,12 @@ You can obtain releases source code prepared tarballs from the links below:
 @tab @url{download/govpn-2.4.tar.xz, link} @url{download/govpn-2.4.tar.xz.sig, sign}
 @tab @code{df45225bac2384c5eed73c5cdb05dc3581495e08d365317beb03a2487d46b98c}
 
+@item 3.0 @tab 53 KiB
+@tab @url{download/govpn-3.0.tar.xz, link} @url{download/govpn-3.0.tar.xz.sig, sign}
+@tab @code{12579c5c3cccfe73c66b5893335bc70c42d7b13b8e94c7751ec65d421eaff9a5}
+
 @end multitable
 
-Also you can try it's @ref{Contacts, .onion} version.
+Also you can try its @ref{Contacts, .onion} version.
 Sourceforge.net also provides mirror for the files above:
 @url{http://sourceforge.net/projects/govpn/files/}.
-
-You can obtain it's development source code by cloning
-Git repository: @code{git clone https://github.com/stargrave/govpn.git}.
-Pay attention that it does not contain compiled documentation and is not
-recommended for porters because of that.
index fe842b3a04d73c9f6944f52d6b60d629836f3d12..a22e85f98efe9e633c825c5a31f348f22e8b33b7 100644 (file)
@@ -7,7 +7,7 @@
 This manual is for GoVPN -- simple secure free software virtual private
 network (VPN) daemon, written entirely on Go programming language.
 
-Copyright @copyright{} 2014-2015 Sergey Matveev @email{stargrave@@stargrave.org}
+Copyright @copyright{} 2014-2015 @email{stargrave@@stargrave.org, Sergey Matveev}
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
index 6f1e37e32a72098cb00abb3b28238fe8ae1cfcf2..0b7f4bd840dea447bbaaab0d5e895c26f59165b9 100644 (file)
@@ -23,19 +23,20 @@ Client computes verifier which produces @code{DSAPriv} and
 @item
 Client generates DH keypair: @code{CDHPub} and @code{CDHPriv}.
 Also it generates random 64-bit @code{R} that is used as a nonce for
-symmetric encryption.
+symmetric encryption. @code{El()} is Elligator point encoding algorithm.
 @end enumerate
 
 @strong{Interaction stage}:
 
 @enumerate
 @item
-@verb{|R + enc(H(DSAPub), R, CDHPub) + IDtag -> Server|} [48 bytes]
+@verb{|R + enc(H(DSAPub), R, El(CDHPub)) + IDtag -> Server|} [48 bytes]
 
 @item
 @itemize @bullet
 @item Server remembers client address.
-@item Decrypts @code{CDHPub}.
+@item Decrypts @code{El(CDHPub)}.
+@item Inverts @code{El()} encoding and gets @code{CDHPub}.
 @item Generates DH keypair: @code{SDHPriv}/@code{SDHPub}.
 @item Computes common shared key @code{K = H(DH(SDHPriv, CDHPub))}.
 @item Generates 64-bit random number @code{RS}.
@@ -43,11 +44,12 @@ symmetric encryption.
 @end itemize
 
 @item
-@verb{|enc(H(DSAPub), R+1, SDHPub) + enc(K, R, RS + SS) + IDtag -> Client|} [80 bytes]
+@verb{|enc(H(DSAPub), R+1, El(SDHPub)) + enc(K, R, RS + SS) + IDtag -> Client|} [80 bytes]
 
 @item
 @itemize @bullet
-@item Client decrypts @code{SDHPub}.
+@item Client decrypts @code{El(SDHPub)}.
+@item Inverts @code{El()} encoding and gets @code{SDHPub}.
 @item Computes @code{K}.
 @item Decrypts @code{RS} and @code{SS}.
 @item Remembers @code{SS}.
@@ -64,9 +66,9 @@ symmetric encryption.
     @item Server decrypts @code{RS}, @code{RC}, @code{SC},
     @code{Sign(DSAPriv, K)}.
 
-    @item Compares @code{RS} with it's own one sent before. Server
+    @item Compares @code{RS} with its own one sent before. Server
     decrypts @code{RS}, @code{RC}, @code{SC} with key @code{K}, compares
-    @code{RS} with it's own one sent before.
+    @code{RS} with its own one sent before.
 
     @item Verifies @code{K} signature with verifier @code{DSAPub}.
 
@@ -80,7 +82,7 @@ symmetric encryption.
 @item
 @itemize @bullet
 @item Client decrypts @code{RC}
-@item Compares with it's own one sent before.
+@item Compares with its own one sent before.
 @item Computes final session encryption key as server did.
 @end itemize
 
index 8c3eb3898be080c96303456a928645b296292610..8804ae1cc684211b3f248d5cbf22824920de57cd 100644 (file)
@@ -4,12 +4,12 @@ participant Server
 
 Client -> Client : R=rand(64bit)
 Client -> Client : CDHPriv=rand(256bit)
-Client -> Server : R, enc(H(DSAPub), R, CDHPub)
+Client -> Server : R, enc(H(DSAPub), R, El(CDHPub))
 Server -> Server : SDHPriv=rand(256bit)
 Server -> Server : K=H(DH(SDHPriv, CDHPub))
 Server -> Server : RS=rand(64bit)
 Server -> Server : SS=rand(256bit)
-Server -> Client : enc(H(DSAPub), R+1, SDHPub); enc(K, R, RS+SS)
+Server -> Client : enc(H(DSAPub), R+1, El(SDHPub)); enc(K, R, RS+SS)
 Client -> Client : K=H(DH(CDHPriv, SDHPub))
 Client -> Client : RC=rand(64bit); SC=rand(256bit)
 Client -> Server : enc(K, R+1, RS+RC+SC+Sign(DSAPriv, K))
index 13d215919fbcbc194eba6f804edc6c1ffcc60fd1..727647696575480551788b5a4bc2e4eca41fda5e 100644 (file)
@@ -19,20 +19,7 @@ using @emph{Make}):
 @item @code{github.com/bigeagle/water} @tab GNU/Linux @tab BSD 3-Clause
 @end multitable
 
-@include download.texi
-
-You @strong{have to} verify downloaded archives integrity and check
-their signature to be sure that you have got trusted, untampered
-software. For integrity and authentication of downloaded binaries
-@url{https://www.gnupg.org/, The GNU Privacy Guard} is used. You must
-download signature provided with the tarball.
-
-For the very first time you have to import signing public keys. They
-are provided below, but be sure that you are reading them from the
-trusted source. Alternatively check this page from
-@ref{Contacts, other sources} and look for the mailing list announcements.
-
-For example you can get tarball, set proper @code{$GOPATH} and run
+You can get tarball, set proper @code{$GOPATH} and run
 @code{make} (that will install all necessary libraries and build
 @emph{govpn-client}, @emph{govpn-server}, @emph{govpn-verifier} binaries:
 
@@ -48,4 +35,12 @@ For example you can get tarball, set proper @code{$GOPATH} and run
 % gmake -C govpn/src/govpn all
 @end example
 
-@include pubkey.texi
+@menu
+* Prepared tarballs::
+* Development source code::
+* Tarballs integrity check::
+@end menu
+
+@include download.texi
+@include sources.texi
+@include integrity.texi
diff --git a/doc/integrity.texi b/doc/integrity.texi
new file mode 100644 (file)
index 0000000..01badc5
--- /dev/null
@@ -0,0 +1,15 @@
+@node Tarballs integrity check
+@section Tarballs integrity check
+
+You @strong{have to} verify downloaded archives integrity and check
+their signature to be sure that you have got trusted, untampered
+software. For integrity and authentication of downloaded binaries
+@url{https://www.gnupg.org/, The GNU Privacy Guard} is used. You must
+download signature provided with the tarball.
+
+For the very first time you need to import signing public keys. They
+are provided below, but be sure that you are reading them from the
+trusted source. Alternatively check this page from
+@ref{Contacts, other sources} and look for the mailing list announcements.
+
+@include pubkey.texi
index 39a20e33dc439b44312ebc9a965701d04d04ab9d..a513724a640648574277389211b6c56f4627447c 100644 (file)
@@ -2,7 +2,7 @@ Some keywords describing this project: encryption, authentication, key
 exchange, EKE, Diffie-Hellman, DH, DH-EKE, Augmented EKE, A-EKE,
 security, encrypted key exchange, 128-bit margin, DPI, censorship,
 resistance, free software, GPLv3+, reviewability, easy, simple,
-Curve25519, Ed25519, SHA-512, Salsa20, Poly1305, AEAD, XTEA, PBKDF2,
+Curve25519, Ed25519, Elligator, SHA-512, Salsa20, Poly1305, AEAD, XTEA, PBKDF2,
 PRP, signatures, asymmetric cryptography, zero-knowledge password proof,
 PAKE, password, passphrase, password authenticated key exchange, perfect
 forward secrecy, PFS, MAC, nonce, verifier, rehandshake, heartbeat,
index 75ec725137b1b9640dd0dc3bb7e0b1505ff05aa8..be9bc6043e93c7becc7af86aaffd571b5bd01874 100644 (file)
@@ -2,6 +2,16 @@
 @unnumbered News
 
 @table @strong
+@item Release 3.1
+@itemize @bullet
+@item
+Diffie-Hellman public keys are encoded with Elligator algorithm when
+sending over the wire, making them indistinguishable from the random
+strings, preventing detection of successful decryption try when guessing
+passwords (that are used to create DSA public keys). But this will
+consume twice entropy for DH key generation in average.
+@end itemize
+
 @item Release 3.0
 @itemize @bullet
 @item
@@ -23,7 +33,7 @@ packets became smaller
 
 @item
 Ability to hide underlying packets lengths by appending noise, junk
-data during transmission. Each packet can be fill up-ed to it's
+data during transmission. Each packet can be fill up-ed to its
 maximal MTU size.
 
 @item
index f6b81ac771075f02233896e49d58619ac6f45b16..dc68994470bfa4776cb60685c1fd9545b5e4d260 100644 (file)
@@ -20,8 +20,9 @@ function based on @url{https://en.wikipedia.org/wiki/SHA-2, SHA-512}
 hash function,
 @url{https://en.wikipedia.org/wiki/Encrypted_key_exchange,
 Diffie-Hellman Augmented Encrypted Key Exchange}
-(DH-A-EKE) powered by @url{http://cr.yp.to/ecdh.html, Curve25519} and
-@url{http://ed25519.cr.yp.to/, Ed25519} signatures.
+(DH-A-EKE) powered by @url{http://cr.yp.to/ecdh.html, Curve25519},
+@url{http://ed25519.cr.yp.to/, Ed25519} signatures and
+@url{http://elligator.cr.yp.to/, Elligator} curve-point encoding.
 Strong
 @url{https://en.wikipedia.org/wiki/Zero-knowledge_password_proof, zero-knowledge}
 mutual authentication with key exchange stage is invulnerable
index 93b179e427f6829246d6a45e4b70bb0cb0f8068e..cd759ea72708dd0503cb77fd01d3f226c0b6f3f5 100644 (file)
@@ -3,13 +3,13 @@
 
 The very important precaution is the @strong{cryptographically good}
 pseudo random number generator. GoVPN uses native operating system PRNG
-as entropy source. You have no way to check it's quality in closed
+as entropy source. You have no way to check its quality in closed
 source code operating systems, so it is recommended not to use them if
 you really needs security. Moreover it is possible that those OS leaks
 information about possible PRNG states. And at least Apple OS X and
 Microsoft Windows are already known to have weak CSPRNGs.
 
-GoVPN could use it's own PRNG implementation like
+GoVPN could use its own PRNG implementation like
 @url{https://www.schneier.com/fortuna.html, Fortuna}, but it is
 much easier to use the right OS, to use free software.
 
@@ -19,6 +19,6 @@ If it fails, produces equal values at least once, then all you traffic
 related to that key could be decrypted.
 
 We use password (passphrase) authentication, so overall security fully
-depends on it's strength. So you should use long, high-entropy
+depends on its strength. So you should use long, high-entropy
 passphrases. Also remember to keep passphrase on temporary file as
 described in @ref{Verifier}.
diff --git a/doc/sources.texi b/doc/sources.texi
new file mode 100644 (file)
index 0000000..acecea7
--- /dev/null
@@ -0,0 +1,22 @@
+@node Development source code
+@section Development source code
+
+Development source contains the latest version of the code. It may be
+buggy. Also it does not contain compiled documentation and is not
+recommended for porters because of that.
+
+You can obtain it by cloning Git repository:
+@code{git clone https://github.com/stargrave/govpn.git}.
+
+Also there is mirror of dependent libraries for safety if their native
+repositories will be unavailable (they are seldom updated):
+
+@multitable @columnfractions .50 .50
+@headitem Software/library @tab Mirror
+@item @code{govpn} @tab @url{git://git.cypherpunks.ru/govpn.git}
+@item @code{golang.org/x/crypto/poly1305} @tab @url{git://git.cypherpunks.ru/crypto.git}
+@item @code{golang.org/x/crypto/salsa20} @tab @url{git://git.cypherpunks.ru/crypto.git}
+@item @code{golang.org/x/crypto/xtea} @tab @url{git://git.cypherpunks.ru/crypto.git}
+@item @code{golang.org/x/crypto/pbkdf2} @tab @url{git://git.cypherpunks.ru/crypto.git}
+@item @code{github.com/agl/ed25519} @tab @url{git://git.cypherpunks.ru/ed25519.git}
+@end multitable
index 69223702f4e025fee3b04e6f777eefbe98ab78bd..5d68d1c217af2b4d01ae73a1b19db86e90da6ea2 100644 (file)
@@ -4,16 +4,18 @@
 @itemize @bullet
 @item
 @url{https://www.schneier.com/books/applied_cryptography/, Applied Cryptography}
-@copyright{} 1996 Bruce Schneier
+@copyright{} 1996 Bruce Schneier.
 @item
 @url{http://tnlandforms.us/cns05/speke.pdf, Strong Password-Only Authenticated Key Exchange}
-@copyright{} 1996 David P. Jablon
+@copyright{} 1996 David P. Jablon.
 @item
 @url{https://www.cs.columbia.edu/~smb/papers/aeke.pdf, Augmented Encrypted Key Exchange}:
 a Password-Based Protocol Secure Against Dictionary Attacks and Password
-File Compromise @copyright{} Steven M. Belloving, Michael Merrit
-@item @url{http://cr.yp.to/ecdh.html, A state-of-the-art Diffie-Hellman function}
-@item @url{http://cr.yp.to/snuffle.html, Snuffle 2005: the Salsa20 encryption function}
-@item @url{http://cr.yp.to/mac.html, A state-of-the-art message-authentication code}
-@item @url{http://ed25519.cr.yp.to/, Ed25519: high-speed high-security signatures}
+File Compromise @copyright{} Steven M. Belloving, Michael Merrit.
+@item @url{http://cr.yp.to/ecdh.html, A state-of-the-art Diffie-Hellman function}.
+@item @url{http://cr.yp.to/snuffle.html, Snuffle 2005: the Salsa20 encryption function}.
+@item @url{http://cr.yp.to/mac.html, A state-of-the-art message-authentication code}.
+@item @url{http://ed25519.cr.yp.to/, Ed25519: high-speed high-security signatures}.
+@item @email{watsonbladd@@gmail.com, Watson Ladd} for suggestion of
+    @url{http://elligator.cr.yp.to/, Elligator} encoding.
 @end itemize
index 3b969dc07ac09f57752f228fcc38216e41473002..b508b483536d4b9e4aebef987362d126b42abe5d 100644 (file)
@@ -3,7 +3,7 @@
 
 Verifier is a derivative of the password. It is resistant to
 dictionary attacks and can not be used for authentication (only
-it's verifying).
+its verifying).
 
 @verbatim
 SOURCE = PBKDF2(SALT=PeerId, PASSWORD, 1<<16, SHA512)
index 0fee82c77d0e70db8d23d8febf4aaa8021f92394..73cb4e2d35f39c3256e81d278328d30e38ff6c3b 100644 (file)
@@ -27,6 +27,7 @@ import (
        "time"
 
        "github.com/agl/ed25519"
+       "github.com/agl/ed25519/extra25519"
        "golang.org/x/crypto/curve25519"
        "golang.org/x/crypto/salsa20"
        "golang.org/x/crypto/salsa20/salsa"
@@ -100,12 +101,18 @@ func (h *Handshake) rNonceNext(count uint64) []byte {
        return nonce
 }
 
-func dhPrivGen() *[32]byte {
-       dh := new([32]byte)
-       if _, err := rand.Read(dh[:]); err != nil {
-               panic("Can not read random for DH private key")
+func dhKeypairGen() (*[32]byte, *[32]byte) {
+       priv := new([32]byte)
+       pub := new([32]byte)
+       repr := new([32]byte)
+       reprFound := false
+       for !reprFound {
+               if _, err := rand.Read(priv[:]); err != nil {
+                       panic("Can not read random for DH private key")
+               }
+               reprFound = extra25519.ScalarBaseMult(pub, repr, priv)
        }
-       return dh
+       return priv, repr
 }
 
 func dhKeyGen(priv, pub *[32]byte) *[32]byte {
@@ -146,16 +153,15 @@ func idTag(id *PeerId, data []byte) []byte {
 func HandshakeStart(conf *PeerConf, conn *net.UDPConn, addr *net.UDPAddr) *Handshake {
        state := HandshakeNew(addr, conf)
 
-       state.dhPriv = dhPrivGen()
-       dhPub := new([32]byte)
-       curve25519.ScalarBaseMult(dhPub, state.dhPriv)
+       var dhPubRepr *[32]byte
+       state.dhPriv, dhPubRepr = dhKeypairGen()
 
        state.rNonce = new([RSize]byte)
        if _, err := rand.Read(state.rNonce[:]); err != nil {
                panic("Can not read random for handshake nonce")
        }
        enc := make([]byte, 32)
-       salsa20.XORKeyStream(enc, dhPub[:], state.rNonce[:], state.dsaPubH)
+       salsa20.XORKeyStream(enc, dhPubRepr[:], state.rNonce[:], state.dsaPubH)
        data := append(state.rNonce[:], enc...)
        data = append(data, idTag(state.Conf.Id, state.rNonce[:])...)
        if _, err := conn.WriteTo(data, addr); err != nil {
@@ -171,23 +177,29 @@ func HandshakeStart(conf *PeerConf, conn *net.UDPConn, addr *net.UDPAddr) *Hands
 // will be created and used as a transport. If no mutually
 // authenticated Peer is ready, then return nil.
 func (h *Handshake) Server(conn *net.UDPConn, data []byte) *Peer {
-       // R + ENC(H(DSAPub), R, CDHPub) + IDtag
+       // R + ENC(H(DSAPub), R, El(CDHPub)) + IDtag
        if len(data) == 48 && h.rNonce == nil {
-               // Generate private DH key
-               h.dhPriv = dhPrivGen()
-               dhPub := new([32]byte)
-               curve25519.ScalarBaseMult(dhPub, h.dhPriv)
+               // Generate DH keypair
+               var dhPubRepr *[32]byte
+               h.dhPriv, dhPubRepr = dhKeypairGen()
 
                h.rNonce = new([RSize]byte)
                copy(h.rNonce[:], data[:RSize])
 
                // Decrypt remote public key and compute shared key
-               dec := new([32]byte)
-               salsa20.XORKeyStream(dec[:], data[RSize:RSize+32], h.rNonce[:], h.dsaPubH)
-               h.key = dhKeyGen(h.dhPriv, dec)
+               cDHRepr := new([32]byte)
+               salsa20.XORKeyStream(
+                       cDHRepr[:],
+                       data[RSize:RSize+32],
+                       h.rNonce[:],
+                       h.dsaPubH,
+               )
+               cDH := new([32]byte)
+               extra25519.RepresentativeToPublicKey(cDH, cDHRepr)
+               h.key = dhKeyGen(h.dhPriv, cDH)
 
                encPub := make([]byte, 32)
-               salsa20.XORKeyStream(encPub, dhPub[:], h.rNonceNext(1), h.dsaPubH)
+               salsa20.XORKeyStream(encPub, dhPubRepr[:], h.rNonceNext(1), h.dsaPubH)
 
                // Generate R* and encrypt them
                h.rServer = new([RSize]byte)
@@ -259,16 +271,18 @@ func (h *Handshake) Server(conn *net.UDPConn, data []byte) *Peer {
 // authenticated Peer is ready, then return nil.
 func (h *Handshake) Client(conn *net.UDPConn, data []byte) *Peer {
        switch len(data) {
-       case 80: // ENC(H(DSAPub), R+1, SDHPub) + ENC(K, R, RS + SS) + IDtag
+       case 80: // ENC(H(DSAPub), R+1, El(SDHPub)) + ENC(K, R, RS + SS) + IDtag
                if h.key != nil {
                        log.Println("Invalid handshake stage from", h.addr)
                        return nil
                }
 
                // Decrypt remote public key and compute shared key
-               dec := new([32]byte)
-               salsa20.XORKeyStream(dec[:], data[:32], h.rNonceNext(1), h.dsaPubH)
-               h.key = dhKeyGen(h.dhPriv, dec)
+               sDHRepr := new([32]byte)
+               salsa20.XORKeyStream(sDHRepr[:], data[:32], h.rNonceNext(1), h.dsaPubH)
+               sDH := new([32]byte)
+               extra25519.RepresentativeToPublicKey(sDH, sDHRepr)
+               h.key = dhKeyGen(h.dhPriv, sDH)
 
                // Decrypt Rs
                decRs := make([]byte, RSize+SSize)
index ddcfbf90dc28f21904f3230de0c6f9e5cea0adb4..f46eeefb62b3aae5c9af6fbebe46705d9688e1b7 100644 (file)
@@ -21,7 +21,6 @@ package govpn
 import (
        "encoding/binary"
        "io"
-       "log"
        "net"
        "time"
 
@@ -78,6 +77,8 @@ type Peer struct {
        frame     []byte
        nonce     []byte
        pktSize   uint64
+       size      int
+       now       time.Time
 
        // Statistics
        BytesIn         int64
@@ -269,18 +270,18 @@ func newPeer(addr *net.UDPAddr, conf *PeerConf, nonce int, key *[SSize]byte) *Pe
 // free to receive new packets. Authenticated and decrypted packets
 // will be written to the interface immediately (except heartbeat ones).
 func (p *Peer) UDPProcess(udpPkt []byte, tap io.Writer, ready chan struct{}) bool {
-       size := len(udpPkt)
+       p.size = len(udpPkt)
        copy(p.buf, Emptiness)
-       copy(p.tag[:], udpPkt[size-poly1305.TagSize:])
-       copy(p.buf[S20BS:], udpPkt[NonceSize:size-poly1305.TagSize])
+       copy(p.tag[:], udpPkt[p.size-poly1305.TagSize:])
+       copy(p.buf[S20BS:], udpPkt[NonceSize:p.size-poly1305.TagSize])
        salsa20.XORKeyStream(
-               p.buf[:S20BS+size-poly1305.TagSize],
-               p.buf[:S20BS+size-poly1305.TagSize],
+               p.buf[:S20BS+p.size-poly1305.TagSize],
+               p.buf[:S20BS+p.size-poly1305.TagSize],
                udpPkt[:NonceSize],
                p.Key,
        )
        copy(p.keyAuth[:], p.buf[:SSize])
-       if !poly1305.Verify(p.tag, udpPkt[:size-poly1305.TagSize], p.keyAuth) {
+       if !poly1305.Verify(p.tag, udpPkt[:p.size-poly1305.TagSize], p.keyAuth) {
                ready <- struct{}{}
                p.FramesUnauth++
                return false
@@ -294,7 +295,7 @@ func (p *Peer) UDPProcess(udpPkt []byte, tap io.Writer, ready chan struct{}) boo
        }
        ready <- struct{}{}
        p.FramesIn++
-       p.BytesIn += int64(size)
+       p.BytesIn += int64(p.size)
        p.LastPing = time.Now()
        p.NonceRecv = p.nonceRecv
        p.pktSize, _ = binary.Uvarint(p.buf[S20BS : S20BS+PktSizeSize])
@@ -308,8 +309,8 @@ func (p *Peer) UDPProcess(udpPkt []byte, tap io.Writer, ready chan struct{}) boo
        return true
 }
 
-type WriteToer interface {
-       WriteTo([]byte, net.Addr) (int, error)
+type WriteToUDPer interface {
+       WriteToUDP([]byte, *net.UDPAddr) (int, error)
 }
 
 // Process incoming Ethernet packet.
@@ -317,19 +318,19 @@ type WriteToer interface {
 // ready channel is TAPListen's synchronization channel used to tell him
 // that he is free to receive new packets. Encrypted and authenticated
 // packets will be sent to remote Peer side immediately.
-func (p *Peer) EthProcess(ethPkt []byte, conn WriteToer, ready chan struct{}) {
-       now := time.Now()
-       size := len(ethPkt)
+func (p *Peer) EthProcess(ethPkt []byte, conn WriteToUDPer, ready chan struct{}) {
+       p.now = time.Now()
+       p.size = len(ethPkt)
        // If this heartbeat is necessary
-       if size == 0 && !p.LastSent.Add(p.Timeout).Before(now) {
+       if p.size == 0 && !p.LastSent.Add(p.Timeout).Before(p.now) {
                return
        }
        copy(p.buf, Emptiness)
-       if size > 0 {
+       if p.size > 0 {
                copy(p.buf[S20BS+PktSizeSize:], ethPkt)
                ready <- struct{}{}
-               binary.PutUvarint(p.buf[S20BS:S20BS+PktSizeSize], uint64(size))
-               p.BytesPayloadOut += int64(size)
+               binary.PutUvarint(p.buf[S20BS:S20BS+PktSizeSize], uint64(p.size))
+               p.BytesPayloadOut += int64(p.size)
        } else {
                p.HeartbeatSent++
        }
@@ -345,7 +346,7 @@ func (p *Peer) EthProcess(ethPkt []byte, conn WriteToer, ready chan struct{}) {
        if p.NoiseEnable {
                p.frame = p.buf[S20BS-NonceSize : S20BS+MTU-NonceSize-poly1305.TagSize]
        } else {
-               p.frame = p.buf[S20BS-NonceSize : S20BS+PktSizeSize+size]
+               p.frame = p.buf[S20BS-NonceSize : S20BS+PktSizeSize+p.size]
        }
        poly1305.Sum(p.tag, p.frame, p.keyAuth)
 
@@ -354,13 +355,11 @@ func (p *Peer) EthProcess(ethPkt []byte, conn WriteToer, ready chan struct{}) {
 
        if p.CPRCycle != time.Duration(0) {
                p.willSentCycle = p.LastSent.Add(p.CPRCycle)
-               if p.willSentCycle.After(now) {
-                       time.Sleep(p.willSentCycle.Sub(now))
-                       now = p.willSentCycle
+               if p.willSentCycle.After(p.now) {
+                       time.Sleep(p.willSentCycle.Sub(p.now))
+                       p.now = p.willSentCycle
                }
        }
-       p.LastSent = now
-       if _, err := conn.WriteTo(append(p.frame, p.tag[:]...), p.Addr); err != nil {
-               log.Println("Error sending UDP", err)
-       }
+       p.LastSent = p.now
+       conn.WriteToUDP(append(p.frame, p.tag[:]...), p.Addr)
 }
index 0dc54f992b24210a9623c8a60683651a5d6656c1..51f0e6e322f17efa25edfabe9484c8a587b6e134 100644 (file)
@@ -40,7 +40,7 @@ func init() {
 
 type Dummy struct{}
 
-func (d *Dummy) WriteTo(b []byte, addr net.Addr) (int, error) {
+func (d *Dummy) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) {
        ciphertext = b
        return len(b), nil
 }
index 9e2e3656c38b88678b980701ed703a3be2732ef3..6ff776ca7131767dc9d6d4d5c793efe8ee54b19f 100755 (executable)
@@ -9,7 +9,12 @@ cd $tmp/govpn-$release
 git checkout $release
 rm -fr .git
 find . -name .gitignore -delete
-echo > doc/download.texi
+cat > doc/download.texi <<EOF
+@node Prepared tarballs
+@section Prepared tarballs
+You can obtain releases source code prepared tarballs on
+@url{http://www.cypherpunks.ru/govpn/}.
+EOF
 rm utils/makedist.sh
 make -C doc
 cd $tmp