From eea92d41611a6123d7d1120d6e32af42be3cf863 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Sun, 31 May 2015 20:20:08 +0300 Subject: [PATCH] Move UDP-network related code from the transport file Signed-off-by: Sergey Matveev --- src/govpn/cmd/govpn-client/main.go | 10 +++--- src/govpn/cmd/govpn-server/main.go | 10 +++--- src/govpn/netconn.go | 58 ++++++++++++++++++++++++++++++ src/govpn/transport.go | 34 ------------------ 4 files changed, 66 insertions(+), 46 deletions(-) create mode 100644 src/govpn/netconn.go diff --git a/src/govpn/cmd/govpn-client/main.go b/src/govpn/cmd/govpn-client/main.go index 9b65677..627001a 100644 --- a/src/govpn/cmd/govpn-client/main.go +++ b/src/govpn/cmd/govpn-client/main.go @@ -95,14 +95,13 @@ func main() { if err != nil { log.Fatalln("Can not listen on TAP interface:", err) } - udpSink, udpBuf, udpReady := govpn.ConnListen(conn) + udpSink, udpReady := govpn.ConnListenUDP(conn) timeouts := 0 firstUpCall := true var peer *govpn.Peer var ethPkt []byte var udpPkt govpn.UDPPkt - var udpPktData []byte knownPeers := govpn.KnownPeers(map[string]**govpn.Peer{remote.String(): &peer}) log.Println(govpn.VersionGet()) @@ -151,19 +150,18 @@ MainCycle: continue } - udpPktData = udpBuf[:udpPkt.Size] if peer == nil { if udpPkt.Addr.String() != remote.String() { udpReady <- struct{}{} log.Println("Unknown handshake message") continue } - if govpn.IDsCache.Find(udpPktData) == nil { + if govpn.IDsCache.Find(udpPkt.Data) == nil { log.Println("Invalid identity in handshake packet") udpReady <- struct{}{} continue } - if p := handshake.Client(conn, udpPktData); p != nil { + if p := handshake.Client(conn, udpPkt.Data); p != nil { log.Println("Handshake completed") if firstUpCall { go govpn.ScriptCall(*upPath, *ifaceName) @@ -180,7 +178,7 @@ MainCycle: udpReady <- struct{}{} continue } - if peer.UDPProcess(udpPktData, tap, udpReady) { + if peer.UDPProcess(udpPkt.Data, tap, udpReady) { timeouts = 0 } } diff --git a/src/govpn/cmd/govpn-server/main.go b/src/govpn/cmd/govpn-server/main.go index 9fb7ae1..15f8681 100644 --- a/src/govpn/cmd/govpn-server/main.go +++ b/src/govpn/cmd/govpn-server/main.go @@ -97,7 +97,7 @@ func main() { if err != nil { log.Fatalln("Can listen on UDP:", err) } - udpSink, udpBuf, udpReady := govpn.ConnListen(conn) + udpSink, udpReady := govpn.ConnListenUDP(conn) termSignal := make(chan os.Signal, 1) signal.Notify(termSignal, os.Interrupt, os.Kill) @@ -116,7 +116,6 @@ func main() { knownPeers := govpn.KnownPeers(make(map[string]**govpn.Peer)) var peerReady PeerReadyEvent var udpPkt govpn.UDPPkt - var udpPktData []byte var ethEvent EthEvent var peerId *govpn.PeerId var peerConf *govpn.PeerConf @@ -204,12 +203,11 @@ MainCycle: udpReady <- struct{}{} continue } - udpPktData = udpBuf[:udpPkt.Size] addr = udpPkt.Addr.String() handshakeProcessForce = false HandshakeProcess: if _, exists = peers[addr]; handshakeProcessForce || !exists { - peerId = govpn.IDsCache.Find(udpPktData) + peerId = govpn.IDsCache.Find(udpPkt.Data) if peerId == nil { log.Println("Unknown identity from", addr) udpReady <- struct{}{} @@ -226,7 +224,7 @@ MainCycle: state = govpn.HandshakeNew(udpPkt.Addr, peerConf) states[addr] = state } - peer = state.Server(conn, udpPktData) + peer = state.Server(conn, udpPkt.Data) if peer != nil { log.Println("Peer handshake finished", peer) if _, exists = peers[addr]; exists { @@ -261,7 +259,7 @@ MainCycle: } // If it fails during processing, then try to work with it // as with handshake packet - if !peerState.peer.UDPProcess(udpPktData, peerState.tap, udpReady) { + if !peerState.peer.UDPProcess(udpPkt.Data, peerState.tap, udpReady) { handshakeProcessForce = true goto HandshakeProcess } diff --git a/src/govpn/netconn.go b/src/govpn/netconn.go new file mode 100644 index 0000000..35eb981 --- /dev/null +++ b/src/govpn/netconn.go @@ -0,0 +1,58 @@ +/* +GoVPN -- simple secure free software virtual private network daemon +Copyright (C) 2014-2015 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 +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package govpn + +import ( + "net" + "time" +) + +type UDPPkt struct { + Addr *net.UDPAddr + Data []byte +} + +// Create UDP listening goroutine. +// This function takes already listening UDP socket and a buffer where +// all UDP packet data will be saved, channel where information about +// remote address and number of written bytes are stored, and a channel +// used to tell that buffer is ready to be overwritten. +func ConnListenUDP(conn *net.UDPConn) (chan UDPPkt, chan struct{}) { + buf := make([]byte, MTU) + sink := make(chan UDPPkt) + sinkReady := make(chan struct{}) + go func(conn *net.UDPConn) { + var n int + var addr *net.UDPAddr + var err error + for { + <-sinkReady + conn.SetReadDeadline(time.Now().Add(time.Second)) + n, addr, err = conn.ReadFromUDP(buf) + if err != nil { + // This is needed for ticking the timeouts counter outside + sink <- UDPPkt{nil, nil} + continue + } + sink <- UDPPkt{addr, buf[:n]} + } + }(conn) + sinkReady <- struct{}{} + return sink, sinkReady +} diff --git a/src/govpn/transport.go b/src/govpn/transport.go index 2f5a345..7eca502 100644 --- a/src/govpn/transport.go +++ b/src/govpn/transport.go @@ -42,11 +42,6 @@ const ( TimeoutHeartbeat = 4 ) -type UDPPkt struct { - Addr *net.UDPAddr - Size int -} - type Peer struct { Addr *net.UDPAddr Id *PeerId @@ -184,35 +179,6 @@ func TAPListen(ifaceName string, timeout time.Duration, cpr int) (*TAP, chan []b return tap, sink, sinkReady, sinkTerminate, nil } -// Create UDP listening goroutine. -// This function takes already listening UDP socket and a buffer where -// all UDP packet data will be saved, channel where information about -// remote address and number of written bytes are stored, and a channel -// used to tell that buffer is ready to be overwritten. -func ConnListen(conn *net.UDPConn) (chan UDPPkt, []byte, chan struct{}) { - buf := make([]byte, MTU) - sink := make(chan UDPPkt) - sinkReady := make(chan struct{}) - go func(conn *net.UDPConn) { - var n int - var addr *net.UDPAddr - var err error - for { - <-sinkReady - conn.SetReadDeadline(time.Now().Add(time.Second)) - n, addr, err = conn.ReadFromUDP(buf) - if err != nil { - // This is needed for ticking the timeouts counter outside - sink <- UDPPkt{nil, 0} - continue - } - sink <- UDPPkt{addr, n} - } - }(conn) - sinkReady <- struct{}{} - return sink, buf, sinkReady -} - func newNonceCipher(key *[32]byte) *xtea.Cipher { nonceKey := make([]byte, 16) salsa20.XORKeyStream( -- 2.44.0