2 GoVPN -- simple secure free software virtual private network daemon
3 Copyright (C) 2014-2020 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, version 3 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 "go.cypherpunks.ru/govpn/v7"
30 bind, err := net.ResolveTCPAddr("tcp", *bindAddr)
32 log.Fatalln("Can not resolve bind address:", err)
34 listener, err := net.ListenTCP("tcp", bind)
36 log.Fatalln("Can not listen on TCP:", err)
38 govpn.BothPrintf(`[tcp-listen bind="%s"]`, *bindAddr)
41 conn, err := listener.AcceptTCP()
43 govpn.Printf(`[tcp-accept-failed bind="%s" err="%s"]`, *bindAddr, err)
51 func handleTCP(conn net.Conn) {
52 addr := conn.RemoteAddr().String()
53 buf := make([]byte, govpn.EnclessEnlargeSize+2*govpn.MTUMax)
57 var hs *govpn.Handshake
61 var conf *govpn.PeerConf
63 var peerPrevI interface{}
64 var peerPrev *PeerState
69 conn.SetReadDeadline(time.Now().Add(time.Duration(govpn.TimeoutDefault) * time.Second))
70 n, err = conn.Read(buf[prev:])
72 // Either EOFed or timeouted
76 peerID := idsCache.Find(buf[:prev])
84 `[conf-get-failed bind="%s" peer="%s"]`,
85 *bindAddr, peerID.String(),
89 hs = govpn.NewHandshake(addr, conn, conf)
91 peer = hs.Server(buf[:prev])
98 `[handshake-completed bind="%s" addr="%s" peer="%s"]`,
99 *bindAddr, addr, peerID.String(),
101 addrPrevI, exists := peersByID.Load(*peer.ID)
103 addrPrev = addrPrevI.(string)
104 peerPrevI, exists = peers.Load(addrPrev)
106 peerPrev = peerPrevI.(*PeerState)
107 exists = peerPrev == nil
111 peerPrev.terminator <- struct{}{}
116 terminator: make(chan struct{}),
118 go govpn.PeerTapProcessor(ps.peer, ps.tap, ps.terminator)
119 peers.Delete(addrPrev)
120 peers.Store(addr, ps)
121 knownPeers.Delete(addrPrev)
122 knownPeers.Store(addr, &peer)
123 peersByID.Store(*peer.ID, addr)
125 `[rehandshake-completed bind="%s" peer="%s"]`,
126 *bindAddr, peerID.String(),
129 ifaceName, err := callUp(peer.ID, peer.Addr)
134 tap, err = govpn.TAPListen(ifaceName, peer.MTU)
137 `[tap-failed bind="%s" peer="%s" err="%s"]`,
138 *bindAddr, peerID.String(), err,
146 terminator: make(chan struct{}, 1),
148 go govpn.PeerTapProcessor(ps.peer, ps.tap, ps.terminator)
149 peers.Store(addr, ps)
150 peersByID.Store(*peer.ID, addr)
151 knownPeers.Store(addr, &peer)
152 govpn.Printf(`[peer-created bind="%s" peer="%s"]`, *bindAddr, peerID.String())
166 if prev == len(buf) {
169 conn.SetReadDeadline(time.Now().Add(conf.Timeout))
170 n, err = conn.Read(buf[prev:])
172 // Either EOFed or timeouted
177 if prev < govpn.MinPktLength {
180 i = bytes.Index(buf[:prev], peer.NonceExpect)
184 if !peer.PktProcess(buf[:i+govpn.NonceSize], tap, false) {
186 `[packet-unauthenticated bind="%s" addr="%s" peer="%s"]`,
187 *bindAddr, addr, peer.ID.String(),
191 copy(buf, buf[i+govpn.NonceSize:prev])
192 prev = prev - i - govpn.NonceSize