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