X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcypherpunks.ru%2Fgovpn%2Fcmd%2Fgovpn-server%2Fmain.go;fp=src%2Fcypherpunks.ru%2Fgovpn%2Fcmd%2Fgovpn-server%2Fmain.go;h=886b8a812b365dae21960e36232e4d18b0e6618f;hb=cecb63f12f4a9f523276a0c19c7feb7437c7f53a;hp=0000000000000000000000000000000000000000;hpb=5123d4cd2b5cfbbba1112710ce29d3d85a3b3ef9;p=govpn.git diff --git a/src/cypherpunks.ru/govpn/cmd/govpn-server/main.go b/src/cypherpunks.ru/govpn/cmd/govpn-server/main.go new file mode 100644 index 0000000..886b8a8 --- /dev/null +++ b/src/cypherpunks.ru/govpn/cmd/govpn-server/main.go @@ -0,0 +1,128 @@ +/* +GoVPN -- simple secure free software virtual private network daemon +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 +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 . +*/ + +// Simple secure, DPI/censorship-resistant free software VPN daemon. +package main + +import ( + "flag" + "log" + "net" + "os" + "os/signal" + "time" + + "cypherpunks.ru/govpn" +) + +var ( + bindAddr = flag.String("bind", "[::]:1194", "Bind to address") + proto = flag.String("proto", "udp", "Protocol to use: udp, tcp or all") + confPath = flag.String("conf", "peers.yaml", "Path to configuration YAML") + stats = flag.String("stats", "", "Enable stats retrieving on host:port") + proxy = flag.String("proxy", "", "Enable HTTP proxy on host:port") + egdPath = flag.String("egd", "", "Optional path to EGD socket") +) + +func main() { + flag.Parse() + timeout := time.Second * time.Duration(govpn.TimeoutDefault) + log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile) + log.Println(govpn.VersionGet()) + + confInit() + knownPeers = govpn.KnownPeers(make(map[string]**govpn.Peer)) + + if *egdPath != "" { + log.Println("Using", *egdPath, "EGD") + govpn.EGDInit(*egdPath) + } + + switch *proto { + case "udp": + startUDP() + case "tcp": + startTCP() + case "all": + startUDP() + startTCP() + default: + log.Fatalln("Unknown protocol specified") + } + + termSignal := make(chan os.Signal, 1) + signal.Notify(termSignal, os.Interrupt, os.Kill) + + hsHeartbeat := time.Tick(timeout) + go func() { <-hsHeartbeat }() + + if *stats != "" { + log.Println("Stats are going to listen on", *stats) + statsPort, err := net.Listen("tcp", *stats) + if err != nil { + log.Fatalln("Can not listen on stats port:", err) + } + go govpn.StatsProcessor(statsPort, &knownPeers) + } + if *proxy != "" { + go proxyStart() + } + log.Println("Server started") + + var needsDeletion bool +MainCycle: + for { + select { + case <-termSignal: + break MainCycle + case <-hsHeartbeat: + now := time.Now() + hsLock.Lock() + for addr, hs := range handshakes { + if hs.LastPing.Add(timeout).Before(now) { + log.Println("Deleting handshake state", addr) + hs.Zero() + delete(handshakes, addr) + } + } + peersLock.Lock() + peersByIdLock.Lock() + kpLock.Lock() + for addr, ps := range peers { + ps.peer.BusyR.Lock() + needsDeletion = ps.peer.LastPing.Add(timeout).Before(now) + ps.peer.BusyR.Unlock() + if needsDeletion { + log.Println("Deleting peer", ps.peer) + delete(peers, addr) + delete(knownPeers, addr) + delete(peersById, *ps.peer.Id) + go govpn.ScriptCall( + confs[*ps.peer.Id].Down, + ps.tap.Name, + ) + ps.terminator <- struct{}{} + } + } + hsLock.Unlock() + peersLock.Unlock() + peersByIdLock.Unlock() + kpLock.Unlock() + } + } +}