]> Cypherpunks.ru repositories - govpn.git/blob - src/cypherpunks.ru/govpn/cmd/govpn-server/conf.go
d357b2536c9d25158943a2f363b0113761a27ba6
[govpn.git] / src / cypherpunks.ru / govpn / cmd / govpn-server / conf.go
1 /*
2 GoVPN -- simple secure free software virtual private network daemon
3 Copyright (C) 2014-2017 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 package main
20
21 import (
22         "io/ioutil"
23         "time"
24
25         "github.com/Sirupsen/logrus"
26         "github.com/pkg/errors"
27         "gopkg.in/yaml.v2"
28
29         "cypherpunks.ru/govpn"
30 )
31
32 const refreshRate = time.Minute
33
34 var (
35         confs    peerConfigurations
36         idsCache *govpn.MACCache
37         logger   *logrus.Logger
38 )
39
40 type peerConfigurations map[govpn.PeerID]*govpn.PeerConf
41
42 func (peerConfs peerConfigurations) Get(peerID govpn.PeerID) *govpn.PeerConf {
43         pc, exists := peerConfs[peerID]
44         if !exists {
45                 return nil
46         }
47         return pc
48 }
49
50 type peerConf struct {
51         Name        string `yaml:"name"`
52         Iface       string `yaml:"iface"`
53         MTU         int    `yaml:"mtu"`
54         Up          string `yaml:"up"`
55         Down        string `yaml:"down"`
56         TimeoutInt  int    `yaml:"timeout"`
57         Noise       bool   `yaml:"noise"`
58         CPR         int    `yaml:"cpr"`
59         Encless     bool   `yaml:"encless"`
60         TimeSync    int    `yaml:"timesync"`
61         VerifierRaw string `yaml:"verifier"`
62 }
63
64 func confRead() (*map[govpn.PeerID]*govpn.PeerConf, error) {
65         data, err := ioutil.ReadFile(*confPath)
66         if err != nil {
67                 return nil, errors.Wrap(err, "ioutil.ReadFile")
68         }
69         confsRaw := new(map[string]peerConf)
70         err = yaml.Unmarshal(data, confsRaw)
71         if err != nil {
72                 return nil, errors.Wrap(err, "yaml.Unmarshal")
73         }
74
75         confs := make(map[govpn.PeerID]*govpn.PeerConf, len(*confsRaw))
76         for name, pc := range *confsRaw {
77                 verifier, err := govpn.VerifierFromString(pc.VerifierRaw)
78                 if err != nil {
79                         return nil, errors.Wrap(err, "govpn.VerifierFromString")
80                 }
81                 if pc.Encless {
82                         pc.Noise = true
83                 }
84                 if pc.MTU == 0 {
85                         pc.MTU = govpn.MTUDefault
86                 }
87                 if pc.MTU > govpn.MTUMax {
88                         logger.WithFields(logrus.Fields{
89                                 "bind":         *bindAddr,
90                                 "previous_mtu": pc.MTU,
91                                 "new_mtu":      govpn.MTUMax,
92                         }).Warning("Overriden MTU")
93                         pc.MTU = govpn.MTUMax
94                 }
95                 conf := govpn.PeerConf{
96                         Verifier: verifier,
97                         ID:       verifier.ID,
98                         Name:     name,
99                         Iface:    pc.Iface,
100                         MTU:      pc.MTU,
101                         PreUp:    preUpAction(pc.Up),
102                         Down:     govpn.RunScriptAction(&pc.Down),
103                         Noise:    pc.Noise,
104                         CPR:      pc.CPR,
105                         Encless:  pc.Encless,
106                         TimeSync: pc.TimeSync,
107                 }
108                 if pc.TimeoutInt <= 0 {
109                         conf.Timeout = govpn.TimeoutDefault
110                 } else {
111                         conf.Timeout = time.Second * time.Duration(pc.TimeoutInt)
112                 }
113                 confs[*verifier.ID] = &conf
114         }
115         return &confs, nil
116 }
117
118 func confRefresh() error {
119         fields := logrus.Fields{
120                 "func": "confRefresh",
121         }
122         logger.WithFields(fields).Debug("Check configuration file")
123         newConfs, err := confRead()
124         if err != nil {
125                 return errors.Wrap(err, "confRead")
126         }
127         confs = *newConfs
128         logger.WithFields(
129                 fields,
130         ).WithField(
131                 "newConfs",
132                 len(confs),
133         ).Debug("idsCache.Update")
134         if err = idsCache.Update(newConfs); err != nil {
135                 return errors.Wrap(err, "idsCache.Update")
136         }
137         logger.WithFields(fields).Debug("Done")
138         return nil
139 }
140
141 func confInit() {
142         idsCache = govpn.NewMACCache()
143         err := confRefresh()
144         fields := logrus.Fields{"func": "confInit"}
145         if err != nil {
146                 logger.WithError(err).WithFields(
147                         fields,
148                 ).Fatal("Couldn't perform initial configuration read")
149         }
150         go func() {
151                 for {
152                         time.Sleep(refreshRate)
153                         if err = confRefresh(); err != nil {
154                                 logger.WithError(err).WithFields(
155                                         fields,
156                                 ).Error("Couldn't refresh configuration")
157                         }
158                 }
159         }()
160 }