/*
GoVPN -- simple secure free software virtual private network daemon
-Copyright (C) 2014-2015 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2014-2016 Sergey Matveev <stargrave@stargrave.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
if err != nil {
log.Fatalln("Can not listen on UDP:", err)
}
- log.Println("Listening on UDP", *bindAddr)
- udpBufs <- make([]byte, govpn.MTU)
+ log.Println("Listening on UDP:" + *bindAddr)
+
+ udpBufs <- make([]byte, govpn.MTUMax)
go func() {
var buf []byte
var raddr *net.UDPAddr
var conf *govpn.PeerConf
for {
buf = <-udpBufs
-
n, raddr, err = conn.ReadFromUDP(buf)
if err != nil {
+ log.Println("Unexpected error when receiving", err)
break
}
addr = raddr.String()
goto Finished
}
- log.Println("Peer handshake finished:", addr)
+ log.Println("Peer handshake finished:", addr, peer.Id.String())
hs.Zero()
hsLock.Lock()
delete(handshakes, addr)
hsLock.Unlock()
go func() {
- udpBufs <- make([]byte, govpn.MTU)
- udpBufs <- make([]byte, govpn.MTU)
+ udpBufs <- make([]byte, govpn.MTUMax)
+ udpBufs <- make([]byte, govpn.MTUMax)
}()
peersByIdLock.RLock()
addrPrev, exists = peersById[*peer.Id]
peersByIdLock.RUnlock()
if exists {
- peersLock.RLock()
+ peersLock.Lock()
+ peers[addrPrev].terminator <- struct{}{}
ps = &PeerState{
peer: peer,
tap: peers[addrPrev].tap,
- terminator: peers[addrPrev].terminator,
+ terminator: make(chan struct{}),
}
- peersLock.RUnlock()
- ps.terminator <- struct{}{}
- peersLock.Lock()
+ go func(ps PeerState) {
+ peerReady(ps)
+ <-udpBufs
+ <-udpBufs
+ }(*ps)
peersByIdLock.Lock()
kpLock.Lock()
delete(peers, addrPrev)
delete(knownPeers, addrPrev)
- delete(peersById, *peer.Id)
peers[addr] = ps
knownPeers[addr] = &peer
peersById[*peer.Id] = addr
peersLock.Unlock()
peersByIdLock.Unlock()
kpLock.Unlock()
- go func(ps PeerState) {
- peerReady(ps)
- <-udpBufs
- <-udpBufs
- }(*ps)
- log.Println("Rehandshake finished:", peer.Id.String())
+ log.Println("Rehandshake processed:", peer.Id.String())
} else {
go func(addr string, peer *govpn.Peer) {
ifaceName, err := callUp(peer.Id)
if err != nil {
return
}
- tap, err := govpn.TAPListen(ifaceName)
+ tap, err := govpn.TAPListen(ifaceName, peer.MTU)
if err != nil {
log.Println("Unable to create TAP:", err)
return
ps = &PeerState{
peer: peer,
tap: tap,
- terminator: make(chan struct{}, 1),
+ terminator: make(chan struct{}),
}
go func(ps PeerState) {
peerReady(ps)
peersLock.Unlock()
peersByIdLock.Unlock()
kpLock.Unlock()
- log.Println("New peer:", peer.Id.String())
+ log.Println("Peer created:", peer.Id.String())
}(addr, peer)
}
goto Finished
CheckID:
- peerId = govpn.IDsCache.Find(buf[:n])
+ peerId = idsCache.Find(buf[:n])
if peerId == nil {
log.Println("Unknown identity from:", addr)
goto Finished
}
- conf = peerId.Conf()
+ conf = confs[*peerId]
if conf == nil {
- log.Println("Can not get peer configuration:", peerId.String())
+ log.Println("Unable to get peer configuration:", peerId.String())
goto Finished
}
hs = govpn.NewHandshake(