]> Cypherpunks.ru repositories - govpn.git/blob - src/cypherpunks.ru/govpn/server/udp.go
turn `udpBufs` as a local variable instead of global
[govpn.git] / src / cypherpunks.ru / govpn / server / udp.go
1 /*
2 GoVPN -- simple secure free software virtual private network daemon
3 Copyright (C) 2014-2017 Sergey Matveev <stargrave@stargrave.org>
4
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.
9
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.
14
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/>.
17 */
18
19 package server
20
21 import (
22         "net"
23
24         "github.com/Sirupsen/logrus"
25         "github.com/pkg/errors"
26
27         "cypherpunks.ru/govpn"
28 )
29
30 type udpSender struct {
31         conn *net.UDPConn
32         addr *net.UDPAddr
33 }
34
35 func (c udpSender) Write(data []byte) (int, error) {
36         return c.conn.WriteToUDP(data, c.addr)
37 }
38
39 func (s *Server) startUDP() {
40         bind, err := net.ResolveUDPAddr("udp", s.configuration.BindAddress)
41         if err != nil {
42                 s.Error <- errors.Wrap(err, "net.ResolveUDPAddr")
43                 return
44         }
45         conn, err := net.ListenUDP("udp", bind)
46         if err != nil {
47                 s.Error <- errors.Wrapf(err, "net.ListenUDP %q", bind.String())
48                 return
49         }
50
51         fields := logrus.Fields{
52                 "func": logFuncPrefix + "Server.startUDP",
53                 "bind": bind.String(),
54         }
55         s.logger.WithFields(
56                 fields,
57         ).WithFields(
58                 s.LogFields(),
59         ).WithFields(
60                 s.configuration.LogFields(),
61         ).Info("Listen")
62
63         udpBufs := make(chan []byte, 1<<8)
64         udpBufs <- make([]byte, govpn.MTUMax)
65         go func() {
66                 var buf []byte
67                 var raddr *net.UDPAddr
68                 var addr string
69                 var n int
70                 var err error
71                 var ps *PeerState
72                 var hs *govpn.Handshake
73                 var addrPrev string
74                 var exists bool
75                 var peerID *govpn.PeerID
76                 var conf *govpn.PeerConf
77                 for {
78                         s.logger.WithFields(fields).Debug("Wait for UDP buffer")
79                         buf = <-udpBufs
80                         n, raddr, err = conn.ReadFromUDP(buf)
81                         if err != nil {
82                                 s.logger.WithFields(
83                                         fields,
84                                 ).WithFields(
85                                         s.LogFields(),
86                                 ).WithError(err).Debug("Receive failure")
87                                 break
88                         }
89                         addr = raddr.String()
90                         loopFields := logrus.Fields{"addr": addr}
91
92                         s.logger.WithFields(
93                                 fields,
94                         ).WithFields(
95                                 loopFields,
96                         ).Debug("Got UDP buffer, check if peer exists")
97                         s.peersLock.RLock()
98                         ps, exists = s.peers[addr]
99                         s.peersLock.RUnlock()
100                         if exists {
101                                 s.logger.WithFields(
102                                         fields,
103                                 ).WithFields(
104                                         loopFields,
105                                 ).Debug("Already known peer, PktProcess")
106                                 go func(peer *govpn.Peer, tap *govpn.TAP, buf []byte, n int) {
107                                         peer.PktProcess(buf[:n], tap, true)
108                                         udpBufs <- buf
109                                 }(ps.peer, ps.tap, buf, n)
110                                 continue
111                         }
112
113                         logrus.WithFields(fields).WithFields(loopFields).Debug("New peer")
114                         s.hsLock.RLock()
115                         hs, exists = s.handshakes[addr]
116                         s.hsLock.RUnlock()
117                         if !exists {
118                                 logrus.WithFields(
119                                         fields,
120                                 ).WithFields(
121                                         loopFields,
122                                 ).Debug("No handshake yet, try to figure peer ID")
123                                 peerID, err = s.idsCache.Find(buf[:n])
124                                 if err != nil {
125                                         s.logger.WithFields(
126                                                 fields,
127                                         ).WithFields(
128                                                 loopFields,
129                                         ).WithFields(
130                                                 s.LogFields(),
131                                         ).WithError(err).Debug("Couldn't lookup for peer in ids")
132                                         udpBufs <- buf
133                                         continue
134                                 }
135                                 if peerID == nil {
136                                         s.logger.WithFields(
137                                                 fields,
138                                         ).WithFields(
139                                                 loopFields,
140                                         ).WithFields(
141                                                 s.LogFields(),
142                                         ).Debug("Identity unknown")
143                                         udpBufs <- buf
144                                         continue
145                                 }
146
147                                 loopFields["peer_id"] = peerID.String()
148                                 s.logger.WithFields(fields).WithFields(loopFields).Debug("Found peer ID")
149                                 conf = s.confs.Get(*peerID)
150                                 if conf == nil {
151                                         s.logger.WithFields(
152                                                 loopFields,
153                                         ).WithFields(
154                                                 fields,
155                                         ).WithFields(
156                                                 s.LogFields(),
157                                         ).WithFields(
158                                                 s.configuration.LogFields(),
159                                         ).Error("Peer try to connect, but not configured")
160                                         udpBufs <- buf
161                                         continue
162                                 }
163
164                                 s.logger.WithFields(
165                                         loopFields,
166                                 ).WithFields(
167                                         fields,
168                                 ).Debug("Got configuration, perform handshake")
169                                 hs = govpn.NewHandshake(
170                                         addr,
171                                         udpSender{conn: conn, addr: raddr},
172                                         conf,
173                                 )
174                                 _, err := hs.Server(buf[:n])
175                                 udpBufs <- buf
176                                 if err != nil {
177                                         s.logger.WithFields(
178                                                 loopFields,
179                                         ).WithFields(
180                                                 fields,
181                                         ).WithError(err).WithFields(
182                                                 s.LogFields(),
183                                         ).Error("Can't create new peer: handshake failed")
184                                         continue
185                                 }
186                                 s.logger.WithFields(
187                                         loopFields,
188                                 ).WithFields(
189                                         fields,
190                                 ).WithFields(
191                                         s.LogFields(),
192                                 ).Info("Hashshake started, continue next packet")
193
194                                 s.hsLock.Lock()
195                                 s.handshakes[addr] = hs
196                                 s.hsLock.Unlock()
197                                 continue
198                         }
199
200                         logrus.WithFields(
201                                 fields,
202                         ).WithFields(
203                                 loopFields,
204                         ).Debug("Already go handshake, finish it")
205                         peer, err := hs.Server(buf[:n])
206                         if err != nil {
207                                 s.logger.WithFields(
208                                         fields,
209                                 ).WithFields(
210                                         loopFields,
211                                 ).WithError(err).WithFields(
212                                         s.LogFields(),
213                                 ).Error("Can't create new peer: handshake failed")
214                                 udpBufs <- buf
215                                 continue
216                         }
217                         if peer == nil {
218                                 s.logger.WithFields(
219                                         fields,
220                                 ).WithFields(
221                                         loopFields,
222                                 ).WithFields(
223                                         s.LogFields(),
224                                 ).Error("Couldn't continue handshake")
225                                 udpBufs <- buf
226                                 continue
227                         }
228
229                         s.logger.WithFields(
230                                 fields,
231                         ).WithFields(
232                                 s.LogFields(),
233                         ).WithFields(
234                                 loopFields,
235                         ).WithFields(
236                                 peer.LogFields(),
237                         ).Info("Handshake completed")
238
239                         hs.Zero()
240                         s.hsLock.Lock()
241                         delete(s.handshakes, addr)
242                         s.hsLock.Unlock()
243
244                         go func() {
245                                 udpBufs <- make([]byte, govpn.MTUMax)
246                                 udpBufs <- make([]byte, govpn.MTUMax)
247                         }()
248                         s.peersByIDLock.RLock()
249                         addrPrev, exists = s.peersByID[*peer.ID]
250                         s.peersByIDLock.RUnlock()
251
252                         if exists {
253                                 s.logger.WithFields(
254                                         fields,
255                                 ).WithFields(
256                                         loopFields,
257                                 ).Debug("Peer already exists")
258                                 s.peersLock.Lock()
259                                 s.peers[addrPrev].terminator <- struct{}{}
260                                 psNew := &PeerState{
261                                         peer:       peer,
262                                         tap:        s.peers[addrPrev].tap,
263                                         terminator: make(chan struct{}),
264                                 }
265                                 peer.Protocol = govpn.ProtocolUDP
266
267                                 go func(peer *govpn.Peer, tap *govpn.TAP, terminator chan struct{}) {
268                                         govpn.PeerTapProcessor(peer, tap, terminator)
269                                         <-udpBufs
270                                         <-udpBufs
271                                 }(psNew.peer, psNew.tap, psNew.terminator)
272
273                                 s.peersByIDLock.Lock()
274                                 s.kpLock.Lock()
275                                 delete(s.peers, addrPrev)
276                                 delete(s.knownPeers, addrPrev)
277                                 s.peers[addr] = psNew
278                                 s.knownPeers[addr] = &peer
279                                 s.peersByID[*peer.ID] = addr
280                                 s.peersLock.Unlock()
281                                 s.peersByIDLock.Unlock()
282                                 s.kpLock.Unlock()
283
284                                 s.logger.WithFields(
285                                         fields,
286                                 ).WithFields(
287                                         loopFields,
288                                 ).WithFields(
289                                         s.LogFields(),
290                                 ).WithFields(
291                                         peer.LogFields(),
292                                 ).Debug("Rehandshake completed")
293                         } else {
294                                 go func(addr string, peer *govpn.Peer) {
295                                         s.logger.WithFields(
296                                                 fields,
297                                         ).WithFields(
298                                                 loopFields,
299                                         ).Debug("Peer do not already exists")
300                                         tap, err := s.callUp(peer, govpn.ProtocolUDP)
301                                         if err != nil {
302                                                 s.logger.WithFields(
303                                                         loopFields,
304                                                 ).WithFields(
305                                                         fields,
306                                                 ).WithFields(
307                                                         s.LogFields(),
308                                                 ).WithFields(
309                                                         peer.LogFields(),
310                                                 ).WithError(err).Error("TAP failed")
311                                                 return
312                                         }
313                                         psNew := &PeerState{
314                                                 peer:       peer,
315                                                 tap:        tap,
316                                                 terminator: make(chan struct{}),
317                                         }
318                                         peer.Protocol = govpn.ProtocolUDP
319                                         go func(peer *govpn.Peer, tap *govpn.TAP, terminator chan struct{}) {
320                                                 govpn.PeerTapProcessor(peer, tap, terminator)
321                                                 <-udpBufs
322                                                 <-udpBufs
323                                         }(psNew.peer, psNew.tap, psNew.terminator)
324                                         s.peersLock.Lock()
325                                         s.peersByIDLock.Lock()
326                                         s.kpLock.Lock()
327                                         s.peers[addr] = psNew
328                                         s.knownPeers[addr] = &peer
329                                         s.peersByID[*peer.ID] = addr
330                                         s.peersLock.Unlock()
331                                         s.peersByIDLock.Unlock()
332                                         s.kpLock.Unlock()
333                                         s.logger.WithFields(
334                                                 loopFields,
335                                         ).WithFields(
336                                                 fields,
337                                         ).WithFields(
338                                                 s.LogFields(),
339                                         ).WithFields(
340                                                 peer.LogFields(),
341                                         ).Info("Peer initialized")
342                                 }(addr, peer)
343                         }
344                         udpBufs <- buf
345                 }
346         }()
347 }