]> Cypherpunks.ru repositories - govpn.git/commitdiff
Rehandshake after every 4GiB of transferred data
authorSergey Matveev <stargrave@stargrave.org>
Sun, 11 Jan 2015 13:44:35 +0000 (16:44 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 11 Jan 2015 13:44:49 +0000 (16:44 +0300)
Signed-off-by: Sergey Matveev <stargrave@stargrave.org>
README
govpn.go

diff --git a/README b/README
index c529c3e67bbd359db466d789612da520658e8949..2852a09cd71045f15f9c9f52ee33a39a2d699c8b 100644 (file)
--- a/README
+++ b/README
@@ -26,7 +26,8 @@ High security and high performance are the goals for that daemon. It
 uses fast cryptography algorithms with 128bit security margin, strong
 mutual zero-knowledge authentication and perfect-forward secrecy
 property. An attacker can not know anything from captured traffic, even
-if pre-shared key is compromised.
+if pre-shared key is compromised. Rehandshake is performed by client
+every 4 GiB of transfered data.
 
 Also you can provide up and down scripts that will be executed after
 either connection is initiated (up-script in background), or is went
index 1e157107c33cafab4cbdd7631184bed511666acb..b4eda05acd98f559e79f5b31f57d86b21decf4ab 100644 (file)
--- a/govpn.go
+++ b/govpn.go
@@ -55,6 +55,8 @@ const (
        S20BS         = 64
        HeartBeatSize = 12
        HeartBeatMark = "\x00\x00\x00HEARTBEAT"
+       // Maximal amount of bytes transfered with single key (4 GiB)
+       MaxBytesPerKey = 4294967296
 )
 
 type TAP interface {
@@ -189,6 +191,7 @@ func main() {
        var p *Peer
 
        timeouts := 0
+       bytes := 0
        states := make(map[string]*Handshake)
        nonce := make([]byte, NonceSize)
        keyAuth := new([KeySize]byte)
@@ -203,6 +206,7 @@ func main() {
        }
 
        heartbeat := time.Tick(time.Second * time.Duration(timeout/3))
+       go func() { <-heartbeat }()
        heartbeatMark := []byte(HeartBeatMark)
 
        termSignal := make(chan os.Signal, 1)
@@ -213,6 +217,10 @@ func main() {
                if finished {
                        break
                }
+               if !serverMode && bytes > MaxBytesPerKey {
+                       states[remote.String()] = HandshakeStart(conn, remote, key)
+                       bytes = 0
+               }
                select {
                case <-termSignal:
                        finished = true
@@ -248,9 +256,11 @@ func main() {
                                }
                                if p != nil {
                                        fmt.Print("[HS-OK]")
+                                       if peer == nil {
+                                               go ScriptCall(upPath)
+                                       }
                                        peer = p
                                        delete(states, addr)
-                                       go ScriptCall(upPath)
                                }
                                continue
                        }
@@ -279,6 +289,7 @@ func main() {
                        peer.nonceRecv = nonceRecv
                        timeouts = 0
                        frame = buf[S20BS : S20BS+udpPkt.size-NonceSize-poly1305.TagSize]
+                       bytes += len(frame)
                        if string(frame[0:HeartBeatSize]) == HeartBeatMark {
                                continue
                        }
@@ -312,6 +323,7 @@ func main() {
                        copy(keyAuth[:], buf[:KeySize])
                        dataToSend := buf[S20BS-NonceSize : S20BS+ethPktSize]
                        poly1305.Sum(tag, dataToSend, keyAuth)
+                       bytes += len(dataToSend)
                        if _, err := conn.WriteTo(append(dataToSend, tag[:]...), peer.addr); err != nil {
                                log.Println("Error sending UDP", err)
                        }