2 GoVPN -- simple secure free software virtual private network daemon
3 Copyright (C) 2014-2015 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/>.
28 "golang.org/x/crypto/poly1305"
29 "golang.org/x/crypto/salsa20"
30 "golang.org/x/crypto/xtea"
36 // S20BS is Salsa20's internal blocksize in bytes
38 // Maximal amount of bytes transfered with single key (4 GiB)
39 MaxBytesPerKey int64 = 1 << 32
40 // Size of packet's size mark in bytes
42 // Heartbeat rate, relative to Timeout
58 CPRCycle time.Duration `json:"-"`
60 // Cryptography related
61 Key *[KeySize]byte `json:"-"`
63 NonceOur uint64 `json:"-"`
64 NonceRecv uint64 `json:"-"`
65 NonceCipher *xtea.Cipher `json:"-"`
68 Timeout time.Duration `json:"-"`
72 willSentCycle time.Time
74 // This variables are initialized only once to relief GC
76 tag *[poly1305.TagSize]byte
77 keyAuth *[KeySize]byte
96 func (p *Peer) String() string {
97 return p.Id.String() + ":" + p.Addr.String()
100 // Zero peer's memory state
101 func (p *Peer) Zero() {
104 sliceZero(p.keyAuth[:])
111 Emptiness = make([]byte, 1<<14)
112 taps = make(map[string]*TAP)
115 // Create TAP listening goroutine.
116 // This function takes required TAP interface name, opens it and allocates
117 // a buffer where all frame data will be written, channel where information
118 // about number of read bytes is sent to, synchronization channel (external
119 // processes tell that read buffer can be used again) and possible channel
121 func TAPListen(ifaceName string, timeout time.Duration, cpr int) (*TAP, chan []byte, chan struct{}, chan struct{}, error) {
124 tap, exists := taps[ifaceName]
126 tap, err = NewTAP(ifaceName)
128 return nil, nil, nil, nil, err
130 taps[ifaceName] = tap
132 sink := make(chan []byte)
133 sinkReady := make(chan struct{})
134 sinkTerminate := make(chan struct{})
135 sinkSkip := make(chan struct{})
138 cprCycle := cprCycleCalculate(cpr)
139 if cprCycle != time.Duration(0) {
142 timeout = timeout / TimeoutHeartbeat
144 heartbeat := time.Tick(timeout)
149 case <-sinkTerminate:
152 go func() { sink <- make([]byte, 0) }()
156 tap.ready <- struct{}{}
162 go func() { sink <- make([]byte, 0) }()
163 goto HeartbeatCatched
164 case <-sinkTerminate:
166 case pkt = <-tap.sink:
175 if exists && tap.synced {
176 sinkSkip <- struct{}{}
178 sinkReady <- struct{}{}
180 return tap, sink, sinkReady, sinkTerminate, nil
183 // Create UDP listening goroutine.
184 // This function takes already listening UDP socket and a buffer where
185 // all UDP packet data will be saved, channel where information about
186 // remote address and number of written bytes are stored, and a channel
187 // used to tell that buffer is ready to be overwritten.
188 func ConnListen(conn *net.UDPConn) (chan UDPPkt, []byte, chan struct{}) {
189 buf := make([]byte, MTU)
190 sink := make(chan UDPPkt)
191 sinkReady := make(chan struct{})
192 go func(conn *net.UDPConn) {
194 var addr *net.UDPAddr
198 conn.SetReadDeadline(time.Now().Add(time.Second))
199 n, addr, err = conn.ReadFromUDP(buf)
201 // This is needed for ticking the timeouts counter outside
202 sink <- UDPPkt{nil, 0}
205 sink <- UDPPkt{addr, n}
208 sinkReady <- struct{}{}
209 return sink, buf, sinkReady
212 func newNonceCipher(key *[KeySize]byte) *xtea.Cipher {
213 nonceKey := make([]byte, 16)
214 salsa20.XORKeyStream(
216 make([]byte, KeySize),
217 make([]byte, xtea.BlockSize),
220 ciph, err := xtea.NewCipher(nonceKey)
227 func cprCycleCalculate(rate int) time.Duration {
229 return time.Duration(0)
231 return time.Second / time.Duration(rate*(1<<10)/MTU)
234 func newPeer(addr *net.UDPAddr, id PeerId, nonce int, key *[KeySize]byte) *Peer {
237 timeout := conf.Timeout
238 cprCycle := cprCycleCalculate(conf.CPR)
239 noiseEnable := conf.NoiseEnable
244 timeout = timeout / TimeoutHeartbeat
252 NoiseEnable: noiseEnable,
255 Noncediff: conf.Noncediff,
256 NonceOur: uint64(conf.Noncediff + nonce),
257 NonceRecv: uint64(conf.Noncediff + 0),
259 NonceCipher: newNonceCipher(key),
260 buf: make([]byte, MTU+S20BS),
261 tag: new([poly1305.TagSize]byte),
262 keyAuth: new([KeySize]byte),
263 nonce: make([]byte, NonceSize),
268 // Process incoming UDP packet.
269 // udpPkt is received data, related to the peer tap interface and
270 // ConnListen'es synchronization channel used to tell him that he is
271 // free to receive new packets. Authenticated and decrypted packets
272 // will be written to the interface immediately (except heartbeat ones).
273 func (p *Peer) UDPProcess(udpPkt []byte, tap io.Writer, ready chan struct{}) bool {
275 copy(p.buf, Emptiness)
276 copy(p.tag[:], udpPkt[size-poly1305.TagSize:])
277 copy(p.buf[S20BS:], udpPkt[NonceSize:size-poly1305.TagSize])
278 salsa20.XORKeyStream(
279 p.buf[:S20BS+size-poly1305.TagSize],
280 p.buf[:S20BS+size-poly1305.TagSize],
284 copy(p.keyAuth[:], p.buf[:KeySize])
285 if !poly1305.Verify(p.tag, udpPkt[:size-poly1305.TagSize], p.keyAuth) {
290 p.NonceCipher.Decrypt(p.buf, udpPkt[:NonceSize])
291 p.nonceRecv, _ = binary.Uvarint(p.buf[:NonceSize])
292 if int(p.NonceRecv)-p.Noncediff >= 0 && int(p.nonceRecv) < int(p.NonceRecv)-p.Noncediff {
299 p.BytesIn += int64(size)
300 p.LastPing = time.Now()
301 p.NonceRecv = p.nonceRecv
302 p.pktSize, _ = binary.Uvarint(p.buf[S20BS : S20BS+PktSizeSize])
307 p.frame = p.buf[S20BS+PktSizeSize : S20BS+PktSizeSize+p.pktSize]
308 p.BytesPayloadIn += int64(p.pktSize)
313 type WriteToer interface {
314 WriteTo([]byte, net.Addr) (int, error)
317 // Process incoming Ethernet packet.
318 // ethPkt is received data, conn is our outgoing connection.
319 // ready channel is TAPListen's synchronization channel used to tell him
320 // that he is free to receive new packets. Encrypted and authenticated
321 // packets will be sent to remote Peer side immediately.
322 func (p *Peer) EthProcess(ethPkt []byte, conn WriteToer, ready chan struct{}) {
325 // If this heartbeat is necessary
326 if size == 0 && !p.LastSent.Add(p.Timeout).Before(now) {
329 copy(p.buf, Emptiness)
331 copy(p.buf[S20BS+PktSizeSize:], ethPkt)
333 binary.PutUvarint(p.buf[S20BS:S20BS+PktSizeSize], uint64(size))
334 p.BytesPayloadOut += int64(size)
340 copy(p.nonce, Emptiness)
341 binary.PutUvarint(p.nonce, p.NonceOur)
342 p.NonceCipher.Encrypt(p.nonce, p.nonce)
344 salsa20.XORKeyStream(p.buf, p.buf, p.nonce, p.Key)
345 copy(p.buf[S20BS-NonceSize:S20BS], p.nonce)
346 copy(p.keyAuth[:], p.buf[:KeySize])
348 p.frame = p.buf[S20BS-NonceSize : S20BS+MTU-NonceSize-poly1305.TagSize]
350 p.frame = p.buf[S20BS-NonceSize : S20BS+PktSizeSize+size]
352 poly1305.Sum(p.tag, p.frame, p.keyAuth)
354 p.BytesOut += int64(len(p.frame) + poly1305.TagSize)
357 if p.CPRCycle != time.Duration(0) {
358 p.willSentCycle = p.LastSent.Add(p.CPRCycle)
359 if p.willSentCycle.After(now) {
360 time.Sleep(p.willSentCycle.Sub(now))
361 now = p.willSentCycle
365 if _, err := conn.WriteTo(append(p.frame, p.tag[:]...), p.Addr); err != nil {
366 log.Println("Error sending UDP", err)