]> Cypherpunks.ru repositories - govpn.git/blobdiff - cmd/govpn-server/main.go
Use A-EKE instead of EKE. Doc refactoring. Preparing for 3.0 release
[govpn.git] / cmd / govpn-server / main.go
index 4fa5c96f8baa184c350e4362178b196dc14f1009..8aa26ec83bdb8878766fd28efd96c06f6a6e9d98 100644 (file)
@@ -35,9 +35,8 @@ import (
 var (
        bindAddr  = flag.String("bind", "[::]:1194", "Bind to address")
        peersPath = flag.String("peers", "peers", "Path to peers keys directory")
-       mtu       = flag.Int("mtu", 1500, "MTU")
-       nonceDiff = flag.Int("noncediff", 1, "Allow nonce difference")
-       timeoutP  = flag.Int("timeout", 60, "Timeout seconds")
+       stats     = flag.String("stats", "", "Enable stats retrieving on host:port")
+       mtu       = flag.Int("mtu", 1452, "MTU for outgoing packets")
 )
 
 type PeerReadyEvent struct {
@@ -54,7 +53,7 @@ type PeerState struct {
 }
 
 func NewPeerState(peer *govpn.Peer, iface string) *PeerState {
-       tap, sink, ready, terminate, err := govpn.TAPListen(iface)
+       tap, sink, ready, terminate, err := govpn.TAPListen(iface, peer.Timeout, peer.CPR)
        if err != nil {
                log.Println("Unable to create Eth", err)
                return nil
@@ -77,13 +76,11 @@ type EthEvent struct {
 
 func main() {
        flag.Parse()
-       timeout := time.Second * time.Duration(*timeoutP)
+       timeout := time.Second * time.Duration(govpn.TimeoutDefault)
        var err error
        log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
 
        govpn.MTU = *mtu
-       govpn.Timeout = *timeoutP
-       govpn.Noncediff = *nonceDiff
        govpn.PeersInit(*peersPath)
 
        bind, err := net.ResolveUDPAddr("udp", *bindAddr)
@@ -110,13 +107,26 @@ func main() {
        states := make(map[string]*govpn.Handshake)
        peers := make(map[string]*PeerState)
        peerReadySink := make(chan PeerReadyEvent)
+       knownPeers := govpn.KnownPeers(make(map[string]**govpn.Peer))
        var peerReady PeerReadyEvent
-       var udpPkt *govpn.UDPPkt
+       var udpPkt govpn.UDPPkt
        var udpPktData []byte
        var ethEvent EthEvent
+       var peerId *govpn.PeerId
+       var peerConf *govpn.PeerConf
+       var handshakeProcessForce bool
        ethSink := make(chan EthEvent)
 
-       log.Println("Server version", govpn.Version)
+       log.Println(govpn.VersionGet())
+       log.Println("Max MTU on TAP interface:", govpn.TAPMaxMTU())
+       if *stats != "" {
+               log.Println("Stats are going to listen on", *stats)
+               statsPort, err := net.Listen("tcp", *stats)
+               if err != nil {
+                       panic(err)
+               }
+               go govpn.StatsProcessor(statsPort, &knownPeers)
+       }
        log.Println("Server started")
 
 MainCycle:
@@ -129,6 +139,7 @@ MainCycle:
                        for addr, hs := range states {
                                if hs.LastPing.Add(timeout).Before(now) {
                                        log.Println("Deleting handshake state", addr)
+                                       hs.Zero()
                                        delete(states, addr)
                                }
                        }
@@ -136,6 +147,7 @@ MainCycle:
                                if state.peer.LastPing.Add(timeout).Before(now) {
                                        log.Println("Deleting peer", state.peer)
                                        delete(peers, addr)
+                                       delete(knownPeers, addr)
                                        downPath := path.Join(
                                                govpn.PeersPath,
                                                state.peer.Id.String(),
@@ -143,6 +155,7 @@ MainCycle:
                                        )
                                        go govpn.ScriptCall(downPath, state.tap.Name)
                                        state.terminate <- struct{}{}
+                                       state.peer.Zero()
                                }
                        }
                case peerReady = <-peerReadySink:
@@ -151,7 +164,9 @@ MainCycle:
                                        continue
                                }
                                delete(peers, addr)
+                               delete(knownPeers, addr)
                                state.terminate <- struct{}{}
+                               state.peer.Zero()
                                break
                        }
                        addr = peerReady.peer.Addr.String()
@@ -160,6 +175,8 @@ MainCycle:
                                continue
                        }
                        peers[addr] = state
+                       knownPeers[addr] = &peerReady.peer
+                       states[addr].Zero()
                        delete(states, addr)
                        log.Println("Registered interface", peerReady.iface, "with peer", peer)
                        go func(state *PeerState) {
@@ -177,16 +194,30 @@ MainCycle:
                        }
                        ethEvent.peer.EthProcess(ethEvent.data, conn, ethEvent.ready)
                case udpPkt = <-udpSink:
-                       if udpPkt == nil {
+                       if udpPkt.Addr == nil {
                                udpReady <- struct{}{}
                                continue
                        }
                        udpPktData = udpBuf[:udpPkt.Size]
                        addr = udpPkt.Addr.String()
-                       if govpn.IsValidHandshakePkt(udpPktData) {
+                       handshakeProcessForce = false
+               HandshakeProcess:
+                       if _, exists = peers[addr]; handshakeProcessForce || !exists {
+                               peerId = govpn.IDsCache.Find(udpPktData)
+                               if peerId == nil {
+                                       log.Println("Unknown identity from", addr)
+                                       udpReady <- struct{}{}
+                                       continue
+                               }
+                               peerConf = peerId.Conf()
+                               if peerConf == nil {
+                                       log.Println("Can not get peer configuration", peerId.String())
+                                       udpReady <- struct{}{}
+                                       continue
+                               }
                                state, exists = states[addr]
                                if !exists {
-                                       state = govpn.HandshakeNew(udpPkt.Addr)
+                                       state = govpn.HandshakeNew(udpPkt.Addr, peerConf)
                                        states[addr] = state
                                }
                                peer = state.Server(conn, udpPktData)
@@ -212,7 +243,9 @@ MainCycle:
                                                }()
                                        }
                                }
-                               udpReady <- struct{}{}
+                               if !handshakeProcessForce {
+                                       udpReady <- struct{}{}
+                               }
                                continue
                        }
                        peerState, exists = peers[addr]
@@ -220,7 +253,12 @@ MainCycle:
                                udpReady <- struct{}{}
                                continue
                        }
-                       peerState.peer.UDPProcess(udpPktData, peerState.tap, udpReady)
+                       // If it fails during processing, then try to work with it
+                       // as with handshake packet
+                       if !peerState.peer.UDPProcess(udpPktData, peerState.tap, udpReady) {
+                               handshakeProcessForce = true
+                               goto HandshakeProcess
+                       }
                }
        }
 }