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) {
126 lowP := strings.ToLower(p)
127 for k, v = range protocolText {
128 if strings.ToLower(v) == lowP {
133 choices := make([]string, len(protocolText))
135 for k = range protocolText {
136 choices[index] = protocolText[k]
140 return Protocol(-1), errors.Errorf(
141 "Invalid protocol %q: %s", p, strings.Join(choices, ","),
145 // SliceZero zeros each byte.
146 func SliceZero(data []byte) {
147 for i := 0; i < len(data); i++ {
152 // VersionGet returns version of GoVPN
153 func VersionGet() string {
154 return "GoVPN version " + Version + " built with " + runtime.Version()
157 // CatchSignalShutdown returns a channel.
158 // that channel will get a SIG_INT or SIG_KILL signal is received
159 // this is intended to be used to stop a client/server
160 func CatchSignalShutdown() chan interface{} {
161 shutdownChan := make(chan interface{}, 1)
163 termSignal := make(chan os.Signal, 1)
164 signal.Notify(termSignal, os.Interrupt, os.Kill)
166 logger.WithFields(logrus.Fields{
167 "func": logFuncPrefix + "CatchSignalShutdown",
168 "signal": sig.String(),
169 }).Debug("Catch signal, shutting down")
175 // SetLogger set the Logger used by this library.
176 // by default logrus StdLogger is used.
177 func SetLogger(l *logrus.Logger) {
181 // CloseLog log an error if a io.Closer fail to Close
182 func CloseLog(c io.Closer, l *logrus.Logger, fields logrus.Fields) {
183 if err := c.Close(); err != nil {
184 logrus.WithFields(fields).WithError(err).Error("Can't close connection")