]> Cypherpunks.ru repositories - govpn.git/blobdiff - src/cypherpunks.ru/govpn/client/udp.go
Upgrade Client
[govpn.git] / src / cypherpunks.ru / govpn / client / udp.go
index bb7045ac711778f25e8a9f8d839dea3ae9f11d92..24702f3b6837e3e30a9162ec1c6459adc8f806b9 100644 (file)
@@ -1,6 +1,6 @@
 /*
 GoVPN -- simple secure free software virtual private network daemon
-Copyright (C) 2014-2017 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2014-2016 Sergey Matveev <stargrave@stargrave.org>
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,34 +19,51 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 package client
 
 import (
-       "fmt"
        "net"
        "sync/atomic"
        "time"
 
+       "github.com/pkg/errors"
+
        "cypherpunks.ru/govpn"
 )
 
 func (c *Client) startUDP() {
+       l := c.logger.WithField("func", "startUDP")
+
+       // TODO move resolution into the loop, as the name might change over time
+       l.Debug("Resolve UDP address")
        remote, err := net.ResolveUDPAddr("udp", c.config.RemoteAddress)
        if err != nil {
-               c.Error <- fmt.Errorf("Can not resolve remote address: %s", err)
+               c.Error <- errors.Wrapf(err, "net.ResolveUDPAddr %s", c.config.RemoteAddress)
                return
        }
+       l.WithField("remote", remote.String()).Debug("dial")
        conn, err := net.DialUDP("udp", nil, remote)
        if err != nil {
-               c.Error <- fmt.Errorf("Can not connect remote address: %s", err)
+               c.Error <- errors.Wrapf(err, "net.DialUDP %s", c.config.RemoteAddress)
+               return
+       }
+       l.WithFields(c.config.LogFields()).Info("Connected")
+
+       l.Debug("Handshake start")
+       hs, err := govpn.HandshakeStart(c.config.RemoteAddress, conn, c.config.Peer)
+       if err != nil {
+               govpn.CloseLog(conn, c.logger, c.LogFields())
+               c.Error <- errors.Wrap(err, "govpn.HandshakeStart")
                return
        }
-       govpn.Printf(`[connected remote="%s"]`, c.config.RemoteAddress)
+       l.Debug("Handshake done")
 
-       hs := govpn.HandshakeStart(c.config.RemoteAddress, conn, c.config.Peer)
-       buf := make([]byte, c.config.MTU*2)
+       buf := make([]byte, c.config.Peer.MTU*2)
        var n int
        var timeouts int
        var peer *govpn.Peer
+       var deadLine time.Time
        var terminator chan struct{}
        timeout := int(c.config.Peer.Timeout.Seconds())
+       l.Debug("Main cycle")
+
 MainCycle:
        for {
                select {
@@ -55,48 +72,58 @@ MainCycle:
                default:
                }
 
-               if err = conn.SetReadDeadline(time.Now().Add(time.Second)); err != nil {
-                       c.Error <- err
+               deadLine = time.Now().Add(time.Second)
+               if err = conn.SetReadDeadline(deadLine); err != nil {
+                       c.Error <- errors.Wrapf(err, "conn.SetReadDeadline %s", deadLine.String())
                        break MainCycle
                }
+               l.Debug("conn.Read")
                n, err = conn.Read(buf)
-               if timeouts == timeout {
-                       govpn.Printf(`[connection-timeouted remote="%s"]`, c.config.RemoteAddress)
+               if timeouts >= timeout {
+                       l.WithFields(c.LogFields()).Debug("Connection timeouted")
                        c.timeouted <- struct{}{}
                        break
                }
                if err != nil {
+                       l.WithError(err).WithFields(c.LogFields()).Debug("Can't read from connection")
                        timeouts++
                        continue
                }
                if peer != nil {
+                       c.logger.WithFields(c.LogFields()).Debug("No peer yet, process packet")
                        if peer.PktProcess(buf[:n], c.tap, true) {
+                               l.WithFields(c.LogFields()).Debug("Packet processed")
                                timeouts = 0
                        } else {
-                               govpn.Printf(`[packet-unauthenticated remote="%s"]`, c.config.RemoteAddress)
+                               l.WithFields(c.LogFields()).Debug("Packet unauthenticated")
                                timeouts++
                        }
                        if atomic.LoadUint64(&peer.BytesIn)+atomic.LoadUint64(&peer.BytesOut) > govpn.MaxBytesPerKey {
-                               govpn.Printf(`[rehandshake-required remote="%s"]`, c.config.RemoteAddress)
+                               l.WithFields(c.LogFields()).Debug("Rehandshake required")
                                c.rehandshaking <- struct{}{}
                                break MainCycle
                        }
                        continue
                }
-               if c.idsCache.Find(buf[:n]) == nil {
-                       govpn.Printf(`[identity-invalid remote="%s"]`, c.config.RemoteAddress)
+               if _, err = c.idsCache.Find(buf[:n]); err != nil {
+                       l.WithError(err).WithFields(c.LogFields()).Debug("Identity invalid")
                        continue
                }
                timeouts = 0
-               peer = hs.Client(buf[:n])
+               peer, err = hs.Client(buf[:n])
+               if err != nil {
+                       c.Error <- errors.Wrap(err, "hs.Client")
+                       continue
+               }
+               // no error, but handshake not yet completed
                if peer == nil {
                        continue
                }
-               govpn.Printf(`[handshake-completed remote="%s"]`, c.config.RemoteAddress)
+               l.WithFields(c.LogFields()).Info("Handshake completed")
                c.knownPeers = govpn.KnownPeers(map[string]**govpn.Peer{c.config.RemoteAddress: &peer})
-               if c.firstUpCall {
-                       go govpn.ScriptCall(c.config.UpPath, c.config.InterfaceName, c.config.RemoteAddress)
-                       c.firstUpCall = false
+               if err = c.postUpAction(); err != nil {
+                       c.Error <- errors.Wrap(err, "c.postUpAction")
+                       continue
                }
                hs.Zero()
                terminator = make(chan struct{})
@@ -109,6 +136,9 @@ MainCycle:
                hs.Zero()
        }
        if err = conn.Close(); err != nil {
-               c.Error <- err
+               c.Error <- errors.Wrap(err, "conn.Close")
+       }
+       if err = c.tap.Close(); err != nil {
+               c.Error <- errors.Wrap(err, logFuncPrefix+"Client.tap.Close")
        }
 }