X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcypherpunks.ru%2Fgovpn%2Fcmd%2Fgovpn-server%2Fudp.go;h=f074df47a6740ff390a665c3cfc94c3bfb1e0454;hb=c982ccb214ba8d0fd8a30dee7439ea2db1559f6f;hp=f654181fa1bc583a0f03e2196d5b9325c0955ca6;hpb=649e55e1ead338121ea76d6ae1187617ea9839d6;p=govpn.git diff --git a/src/cypherpunks.ru/govpn/cmd/govpn-server/udp.go b/src/cypherpunks.ru/govpn/cmd/govpn-server/udp.go index f654181..f074df4 100644 --- a/src/cypherpunks.ru/govpn/cmd/govpn-server/udp.go +++ b/src/cypherpunks.ru/govpn/cmd/govpn-server/udp.go @@ -1,6 +1,6 @@ /* GoVPN -- simple secure free software virtual private network daemon -Copyright (C) 2014-2016 Sergey Matveev +Copyright (C) 2014-2017 Sergey Matveev 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 @@ -36,7 +36,7 @@ func (c UDPSender) Write(data []byte) (int, error) { var ( // Buffers for UDP parallel processing - udpBufs chan []byte = make(chan []byte, 1<<8) + udpBufs = make(chan []byte, 1<<8) ) func startUDP() { @@ -48,8 +48,7 @@ func startUDP() { if err != nil { log.Fatalln("Can not listen on UDP:", err) } - log.Println("Listening on UDP:" + *bindAddr) - govpn.Println("Listening on UDP:" + *bindAddr) + govpn.BothPrintf(`[udp-listen bind="%s"]`, *bindAddr) udpBufs <- make([]byte, govpn.MTUMax) go func() { @@ -58,137 +57,145 @@ func startUDP() { var addr string var n int var err error + var exists bool + var psI interface{} var ps *PeerState + var hsI interface{} var hs *govpn.Handshake + var addrPrevI interface{} var addrPrev string - var exists bool - var peerId *govpn.PeerId - var peer *govpn.Peer + var peerPrevI interface{} + var peerPrev *PeerState + var peerID *govpn.PeerID var conf *govpn.PeerConf for { buf = <-udpBufs n, raddr, err = conn.ReadFromUDP(buf) if err != nil { - govpn.Println("Unexpected error when receiving", err) + govpn.Printf(`[receive-failed bind="%s" err="%s"]`, *bindAddr, err) break } addr = raddr.String() - peersLock.RLock() - ps, exists = peers[addr] - peersLock.RUnlock() - if !exists { - goto CheckHandshake + psI, exists = peers.Load(addr) + if exists { + ps = psI.(*PeerState) + go func(peer *govpn.Peer, tap *govpn.TAP, buf []byte, n int) { + peer.PktProcess(buf[:n], tap, true) + udpBufs <- buf + }(ps.peer, ps.tap, buf, n) + continue } - go func(ps *govpn.Peer, tap *govpn.TAP, buf []byte, n int) { - peer.PktProcess(buf[:n], tap, true) - udpBufs <- buf - }(ps.peer, ps.tap, buf, n) - continue - CheckHandshake: - hsLock.RLock() - hs, exists = handshakes[addr] - hsLock.RUnlock() + + hsI, exists = handshakes.Load(addr) if !exists { - goto CheckID + peerID = idsCache.Find(buf[:n]) + if peerID == nil { + govpn.Printf(`[identity-unknown bind="%s" addr="%s"]`, *bindAddr, addr) + udpBufs <- buf + continue + } + conf = confs[*peerID] + if conf == nil { + govpn.Printf( + `[conf-get-failed bind="%s" peer="%s"]`, + *bindAddr, peerID.String(), + ) + udpBufs <- buf + continue + } + hs := govpn.NewHandshake( + addr, + UDPSender{conn: conn, addr: raddr}, + conf, + ) + hs.Server(buf[:n]) + udpBufs <- buf + handshakes.Store(addr, hs) + continue } - peer = hs.Server(buf[:n]) + + hs = hsI.(*govpn.Handshake) + peer := hs.Server(buf[:n]) if peer == nil { - goto Finished + udpBufs <- buf + continue } - - govpn.Println("Peer handshake finished:", addr, peer.Id.String()) + govpn.Printf( + `[handshake-completed bind="%s" addr="%s" peer="%s"]`, + *bindAddr, addr, peerID.String(), + ) hs.Zero() - hsLock.Lock() - delete(handshakes, addr) - hsLock.Unlock() + handshakes.Delete(addr) go func() { udpBufs <- make([]byte, govpn.MTUMax) udpBufs <- make([]byte, govpn.MTUMax) }() - peersByIdLock.RLock() - addrPrev, exists = peersById[*peer.Id] - peersByIdLock.RUnlock() + addrPrevI, exists = peersByID.Load(*peer.ID) if exists { - peersLock.Lock() - peers[addrPrev].terminator <- struct{}{} - ps = &PeerState{ + addrPrev = addrPrevI.(string) + peerPrevI, exists = peers.Load(addrPrev) + if exists { + peerPrev = peerPrevI.(*PeerState) + exists = peerPrev == nil + } + } + if exists { + peerPrev.terminator <- struct{}{} + psNew := &PeerState{ peer: peer, - tap: peers[addrPrev].tap, + tap: peerPrev.tap, terminator: make(chan struct{}), } - go func(ps PeerState) { - peerReady(ps) + go func(peer *govpn.Peer, tap *govpn.TAP, terminator chan struct{}) { + govpn.PeerTapProcessor(peer, tap, terminator) <-udpBufs <-udpBufs - }(*ps) - peersByIdLock.Lock() - kpLock.Lock() - delete(peers, addrPrev) - delete(knownPeers, addrPrev) - peers[addr] = ps - knownPeers[addr] = &peer - peersById[*peer.Id] = addr - peersLock.Unlock() - peersByIdLock.Unlock() - kpLock.Unlock() - govpn.Println("Rehandshake processed:", peer.Id.String()) + }(psNew.peer, psNew.tap, psNew.terminator) + peers.Delete(addrPrev) + peers.Store(addr, psNew) + knownPeers.Delete(addrPrev) + knownPeers.Store(addr, &peer) + peersByID.Store(*peer.ID, addr) + govpn.Printf( + `[rehandshake-completed bind="%s" peer="%s"]`, + *bindAddr, peer.ID.String(), + ) } else { go func(addr string, peer *govpn.Peer) { - ifaceName, err := callUp(peer.Id, peer.Addr) + ifaceName, err := callUp(peer.ID, peer.Addr) if err != nil { return } tap, err := govpn.TAPListen(ifaceName, peer.MTU) if err != nil { - govpn.Println("Unable to create TAP:", err) + govpn.Printf( + `[tap-failed bind="%s" peer="%s" err="%s"]`, + *bindAddr, peer.ID.String(), err, + ) return } - ps = &PeerState{ + psNew := &PeerState{ peer: peer, tap: tap, terminator: make(chan struct{}), } - go func(ps PeerState) { - peerReady(ps) + go func(peer *govpn.Peer, tap *govpn.TAP, terminator chan struct{}) { + govpn.PeerTapProcessor(peer, tap, terminator) <-udpBufs <-udpBufs - }(*ps) - peersLock.Lock() - peersByIdLock.Lock() - kpLock.Lock() - peers[addr] = ps - knownPeers[addr] = &peer - peersById[*peer.Id] = addr - peersLock.Unlock() - peersByIdLock.Unlock() - kpLock.Unlock() - govpn.Println("Peer created:", peer.Id.String()) + }(psNew.peer, psNew.tap, psNew.terminator) + peers.Store(addr, psNew) + knownPeers.Store(addr, &peer) + peersByID.Store(*peer.ID, addr) + govpn.Printf( + `[peer-created bind="%s" peer="%s"]`, + *bindAddr, + peer.ID.String(), + ) }(addr, peer) } - goto Finished - CheckID: - peerId = idsCache.Find(buf[:n]) - if peerId == nil { - govpn.Println("Unknown identity from:", addr) - goto Finished - } - conf = confs[*peerId] - if conf == nil { - govpn.Println("Unable to get peer configuration:", peerId.String()) - goto Finished - } - hs = govpn.NewHandshake( - addr, - UDPSender{conn: conn, addr: raddr}, - conf, - ) - hs.Server(buf[:n]) - hsLock.Lock() - handshakes[addr] = hs - hsLock.Unlock() - Finished: udpBufs <- buf } }()