X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcypherpunks.ru%2Fgovpn%2Fclient%2Fudp.go;h=24702f3b6837e3e30a9162ec1c6459adc8f806b9;hb=b46602d3396ec3beb4a66002dfc8dafd87f541c8;hp=bb7045ac711778f25e8a9f8d839dea3ae9f11d92;hpb=1872444c2bc15cd9af8b8819080165159f688800;p=govpn.git diff --git a/src/cypherpunks.ru/govpn/client/udp.go b/src/cypherpunks.ru/govpn/client/udp.go index bb7045a..24702f3 100644 --- a/src/cypherpunks.ru/govpn/client/udp.go +++ b/src/cypherpunks.ru/govpn/client/udp.go @@ -1,6 +1,6 @@ /* GoVPN -- simple secure free software virtual private network daemon -Copyright (C) 2014-2017 Sergey Matveev +Copyright (C) 2014-2016 Sergey Matveev 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 . 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") } }