]> Cypherpunks.ru repositories - govpn.git/blob - src/govpn/cmd/govpn-server/main.go
dd338a2ce913dc596f3e29b98428aaf9bc1519f1
[govpn.git] / src / govpn / cmd / govpn-server / main.go
1 /*
2 GoVPN -- simple secure free software virtual private network daemon
3 Copyright (C) 2014-2015 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 // Simple secure, DPI/censorship-resistant free software VPN daemon.
20 package main
21
22 import (
23         "flag"
24         "log"
25         "net"
26         "os"
27         "os/signal"
28         "path"
29         "time"
30
31         "govpn"
32 )
33
34 var (
35         bindAddr  = flag.String("bind", "[::]:1194", "Bind to address")
36         proto     = flag.String("proto", "udp", "Protocol to use: udp, tcp or all")
37         peersPath = flag.String("peers", "peers", "Path to peers keys directory")
38         stats     = flag.String("stats", "", "Enable stats retrieving on host:port")
39         proxy     = flag.String("proxy", "", "Enable HTTP proxy on host:port")
40         mtu       = flag.Int("mtu", 1452, "MTU for outgoing packets")
41         egdPath   = flag.String("egd", "", "Optional path to EGD socket")
42 )
43
44 func main() {
45         flag.Parse()
46         timeout := time.Second * time.Duration(govpn.TimeoutDefault)
47         log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
48         log.Println(govpn.VersionGet())
49
50         govpn.MTU = *mtu
51         govpn.PeersInit(*peersPath)
52         knownPeers = govpn.KnownPeers(make(map[string]**govpn.Peer))
53
54         if *egdPath != "" {
55                 log.Println("Using", *egdPath, "EGD")
56                 govpn.EGDInit(*egdPath)
57         }
58
59         switch *proto {
60         case "udp":
61                 startUDP()
62         case "tcp":
63                 startTCP()
64         case "all":
65                 startUDP()
66                 startTCP()
67         default:
68                 log.Fatalln("Unknown protocol specified")
69         }
70
71         termSignal := make(chan os.Signal, 1)
72         signal.Notify(termSignal, os.Interrupt, os.Kill)
73
74         hsHeartbeat := time.Tick(timeout)
75         go func() { <-hsHeartbeat }()
76
77         log.Println("Max MTU on TAP interface:", govpn.TAPMaxMTU())
78         if *stats != "" {
79                 log.Println("Stats are going to listen on", *stats)
80                 statsPort, err := net.Listen("tcp", *stats)
81                 if err != nil {
82                         log.Fatalln("Can not listen on stats port:", err)
83                 }
84                 go govpn.StatsProcessor(statsPort, &knownPeers)
85         }
86         if *proxy != "" {
87                 go proxyStart()
88         }
89         log.Println("Server started")
90
91         var needsDeletion bool
92 MainCycle:
93         for {
94                 select {
95                 case <-termSignal:
96                         break MainCycle
97                 case <-hsHeartbeat:
98                         now := time.Now()
99                         hsLock.Lock()
100                         for addr, hs := range handshakes {
101                                 if hs.LastPing.Add(timeout).Before(now) {
102                                         log.Println("Deleting handshake state", addr)
103                                         hs.Zero()
104                                         delete(handshakes, addr)
105                                 }
106                         }
107                         peersLock.Lock()
108                         peersByIdLock.Lock()
109                         kpLock.Lock()
110                         for addr, ps := range peers {
111                                 ps.peer.BusyR.Lock()
112                                 needsDeletion = ps.peer.LastPing.Add(timeout).Before(now)
113                                 ps.peer.BusyR.Unlock()
114                                 if needsDeletion {
115                                         log.Println("Deleting peer", ps.peer)
116                                         delete(peers, addr)
117                                         delete(knownPeers, addr)
118                                         delete(peersById, *ps.peer.Id)
119                                         downPath := path.Join(
120                                                 govpn.PeersPath,
121                                                 ps.peer.Id.String(),
122                                                 "down.sh",
123                                         )
124                                         go govpn.ScriptCall(downPath, ps.tap.Name)
125                                         ps.terminator <- struct{}{}
126                                 }
127                         }
128                         hsLock.Unlock()
129                         peersLock.Unlock()
130                         peersByIdLock.Unlock()
131                         kpLock.Unlock()
132                 }
133         }
134 }