2 GoVPN -- simple secure free software virtual private network daemon
3 Copyright (C) 2014-2017 Sergey Matveev <stargrave@stargrave.org>
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.
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.
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/>.
31 "github.com/Sirupsen/logrus"
32 "github.com/pkg/errors"
36 // ProtocolUDP is UDP transport protocol
37 ProtocolUDP Protocol = iota
38 // ProtocolTCP is TCP transport protocol
40 // ProtocolALL is TCP+UDP transport protocol
44 // MTUMax is maximum MTU size of Ethernet packet
45 MTUMax = 9000 + etherSize + 1
46 // MTUDefault is default MTU size of Ethernet packet
47 MTUDefault = 1500 + etherSize + 1
49 environmentKeyInterface = "GOVPN_IFACE"
50 environmentKeyRemote = "GOVPN_REMOTE"
52 wrapIoReadFull = "io.ReadFull %q"
53 wrapBlake2bNew256 = "blake2b.New256"
54 wrapEnclessDecode = "EnclessDecode"
55 wrapEnclessEncode = "EnclessEncode"
56 wrapNewProtocolFromString = "NewProtocolFromString"
60 // Version holds release string set at build time
62 protocolText = map[Protocol]string{
67 logger = logrus.StandardLogger()
68 logFuncPrefix = "govpn."
69 // TimeoutDefault is default timeout value for various network operations
70 TimeoutDefault = 60 * time.Second
73 // Protocol is a GoVPN supported protocol: either UDP, TCP or both
76 // String converts a Protocol into a string
77 func (p Protocol) String() string {
78 return protocolText[p]
81 // MarshalJSON returns a JSON string from a protocol
82 func (p Protocol) MarshalJSON() ([]byte, error) {
84 output, err := json.Marshal(&str)
85 return output, errors.Wrap(err, "json.Marshal")
88 // UnmarshalJSON converts a JSON string into a Protocol
89 func (p *Protocol) UnmarshalJSON(encoded []byte) error {
91 if err := json.Unmarshal(encoded, &str); err != nil {
94 "Can't unmarshall to string %q",
95 hex.EncodeToString(encoded),
98 proto, err := NewProtocolFromString(str)
100 return errors.Wrap(err, wrapNewProtocolFromString)
106 // UnmarshalYAML converts a YAML string into a Protocol
107 func (p *Protocol) UnmarshalYAML(unmarshal func(interface{}) error) error {
109 err := unmarshal(&str)
111 return errors.Wrap(err, "unmarshall")
114 proto, err := NewProtocolFromString(str)
116 return errors.Wrap(err, wrapNewProtocolFromString)
122 // NewProtocolFromString converts a string into a govpn.Protocol
123 func NewProtocolFromString(p string) (Protocol, error) {
124 lowP := strings.ToLower(p)
125 for k, v := range protocolText {
126 if strings.ToLower(v) == lowP {
131 choices := make([]string, len(protocolText))
133 for k, v := range protocolText {
143 return Protocol(-1), errors.Errorf("Invalid protocol %q: %s", p, strings.Join(choices, ","))
146 // SliceZero zeros each byte.
147 func SliceZero(data []byte) {
148 for i := 0; i < len(data); i++ {
153 // VersionGet returns version of GoVPN
154 func VersionGet() string {
155 return "GoVPN version " + Version + " built with " + runtime.Version()
158 // CatchSignalShutdown returns a channel.
159 // that channel will get a SIG_INT or SIG_KILL signal is received
160 // this is intended to be used to stop a client/server
161 func CatchSignalShutdown() chan interface{} {
162 shutdownChan := make(chan interface{}, 1)
164 termSignal := make(chan os.Signal, 1)
165 signal.Notify(termSignal, os.Interrupt, os.Kill)
167 logger.WithFields(logrus.Fields{
168 "func": logFuncPrefix + "CatchSignalShutdown",
169 "signal": sig.String(),
170 }).Debug("Catch signal, shutting down")
176 // SetLogger set the Logger used by this library.
177 // by default logrus StdLogger is used.
178 func SetLogger(l *logrus.Logger) {
182 // CloseLog log an error if a io.Closer fail to Close
183 func CloseLog(c io.Closer, l *logrus.Logger, fields logrus.Fields) {
184 if err := c.Close(); err != nil {
185 logrus.WithFields(fields).WithError(err).Error("Couldn't close connection")