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())
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)
udpReady <- struct{}{}
continue
}
- if peer.UDPProcess(udpPktData, tap, udpReady) {
+ if peer.UDPProcess(udpPkt.Data, tap, udpReady) {
timeouts = 0
}
}
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)
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
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{}{}
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 {
}
// 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
}
--- /dev/null
+/*
+GoVPN -- simple secure free software virtual private network daemon
+Copyright (C) 2014-2015 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
+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 <http://www.gnu.org/licenses/>.
+*/
+
+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
+}
TimeoutHeartbeat = 4
)
-type UDPPkt struct {
- Addr *net.UDPAddr
- Size int
-}
-
type Peer struct {
Addr *net.UDPAddr
Id *PeerId
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(