]> Cypherpunks.ru repositories - govpn.git/blob - src/cypherpunks.ru/govpn/server/udp.go
Refactor server
[govpn.git] / src / cypherpunks.ru / govpn / server / udp.go
1 /*
2 GoVPN -- simple secure free software virtual private network daemon
3 Copyright (C) 2014-2016 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(fields).WithFields(s.LogFields()).WithFields(s.configuration.LogFields()).Info("Listen")
60         udpBufs <- make([]byte, govpn.MTUMax)
61         go func() {
62                 var buf []byte
63                 var raddr *net.UDPAddr
64                 var addr string
65                 var n int
66                 var err error
67                 var ps *PeerState
68                 var hs *govpn.Handshake
69                 var addrPrev string
70                 var exists bool
71                 var peerID *govpn.PeerID
72                 var conf *govpn.PeerConf
73                 for {
74                         s.logger.WithFields(fields).Debug("Wait for UDP buffer")
75                         buf = <-udpBufs
76                         n, raddr, err = conn.ReadFromUDP(buf)
77                         if err != nil {
78                                 s.logger.WithFields(fields).WithFields(s.LogFields()).WithError(err).Debug("Receive failure")
79                                 break
80                         }
81                         addr = raddr.String()
82                         loopFields := logrus.Fields{"addr": addr}
83
84                         s.logger.WithFields(fields).WithFields(loopFields).Debug("Got UDP buffer, check if peer exists")
85                         s.peersLock.RLock()
86                         ps, exists = s.peers[addr]
87                         s.peersLock.RUnlock()
88                         if exists {
89                                 s.logger.WithFields(fields).WithFields(loopFields).Debug("Already known peer, PktProcess")
90                                 go func(peer *govpn.Peer, tap *govpn.TAP, buf []byte, n int) {
91                                         peer.PktProcess(buf[:n], tap, true)
92                                         udpBufs <- buf
93                                 }(ps.peer, ps.tap, buf, n)
94                                 continue
95                         }
96
97                         logrus.WithFields(fields).WithFields(loopFields).Debug("New peer")
98                         s.hsLock.RLock()
99                         hs, exists = s.handshakes[addr]
100                         s.hsLock.RUnlock()
101                         if !exists {
102                                 logrus.WithFields(fields).WithFields(loopFields).Debug("No handshake yet, try to figure peer ID")
103                                 peerID, err = s.idsCache.Find(buf[:n])
104                                 if err != nil {
105                                         s.logger.WithFields(fields).WithFields(loopFields).WithFields(s.LogFields()).WithError(err).Debug("Couldn't lookup for peer in ids")
106                                         udpBufs <- buf
107                                         continue
108                                 }
109                                 if peerID == nil {
110                                         s.logger.WithFields(fields).WithFields(loopFields).WithFields(s.LogFields()).Debug("Identity unknown")
111                                         udpBufs <- buf
112                                         continue
113                                 }
114
115                                 loopFields["peer_id"] = peerID.String()
116                                 s.logger.WithFields(fields).WithFields(loopFields).Debug("Found peer ID")
117                                 conf = s.confs.Get(*peerID)
118                                 if conf == nil {
119                                         s.logger.WithFields(loopFields).WithFields(fields).WithFields(s.LogFields()).WithFields(s.configuration.LogFields()).Error("Peer try to connect, but not configured")
120                                         udpBufs <- buf
121                                         continue
122                                 }
123
124                                 s.logger.WithFields(loopFields).WithFields(fields).Debug("Got configuration, perform handshake")
125                                 hs = govpn.NewHandshake(
126                                         addr,
127                                         udpSender{conn: conn, addr: raddr},
128                                         conf,
129                                 )
130                                 _, err := hs.Server(buf[:n])
131                                 udpBufs <- buf
132                                 if err != nil {
133                                         s.logger.WithFields(loopFields).WithFields(fields).WithError(err).WithFields(s.LogFields()).Error("Can't create new peer: handshake failed")
134                                         continue
135                                 }
136                                 s.logger.WithFields(loopFields).WithFields(fields).WithFields(s.LogFields()).Info("Hashshake started, continue next packet")
137
138                                 s.hsLock.Lock()
139                                 s.handshakes[addr] = hs
140                                 s.hsLock.Unlock()
141                                 continue
142                         }
143
144                         logrus.WithFields(fields).WithFields(loopFields).Debug("Already go handshake, finish it")
145                         peer, err := hs.Server(buf[:n])
146                         if err != nil {
147                                 s.logger.WithFields(fields).WithFields(loopFields).WithError(err).WithFields(s.LogFields()).Error("Can't create new peer: handshake failed")
148                                 udpBufs <- buf
149                                 continue
150                         }
151                         if peer == nil {
152                                 s.logger.WithFields(fields).WithFields(loopFields).WithFields(s.LogFields()).Error("Couldn't continue handshake")
153                                 udpBufs <- buf
154                                 continue
155                         }
156
157                         s.logger.WithFields(fields).WithFields(s.LogFields()).WithFields(loopFields).WithFields(peer.LogFields()).Info("Handshake completed")
158
159                         hs.Zero()
160                         s.hsLock.Lock()
161                         delete(s.handshakes, addr)
162                         s.hsLock.Unlock()
163
164                         go func() {
165                                 udpBufs <- make([]byte, govpn.MTUMax)
166                                 udpBufs <- make([]byte, govpn.MTUMax)
167                         }()
168                         s.peersByIDLock.RLock()
169                         addrPrev, exists = s.peersByID[*peer.ID]
170                         s.peersByIDLock.RUnlock()
171
172                         if exists {
173                                 s.logger.WithFields(fields).WithFields(loopFields).Debug("Peer already exists")
174                                 s.peersLock.Lock()
175                                 s.peers[addrPrev].terminator <- struct{}{}
176                                 psNew := &PeerState{
177                                         peer:       peer,
178                                         tap:        s.peers[addrPrev].tap,
179                                         terminator: make(chan struct{}),
180                                 }
181                                 peer.Protocol = govpn.ProtocolUDP
182
183                                 go func(peer *govpn.Peer, tap *govpn.TAP, terminator chan struct{}) {
184                                         govpn.PeerTapProcessor(peer, tap, terminator)
185                                         <-udpBufs
186                                         <-udpBufs
187                                 }(psNew.peer, psNew.tap, psNew.terminator)
188
189                                 s.peersByIDLock.Lock()
190                                 s.kpLock.Lock()
191                                 delete(s.peers, addrPrev)
192                                 delete(s.knownPeers, addrPrev)
193                                 s.peers[addr] = psNew
194                                 s.knownPeers[addr] = &peer
195                                 s.peersByID[*peer.ID] = addr
196                                 s.peersLock.Unlock()
197                                 s.peersByIDLock.Unlock()
198                                 s.kpLock.Unlock()
199
200                                 s.logger.WithFields(fields).WithFields(loopFields).WithFields(s.LogFields()).WithFields(peer.LogFields()).Debug("Rehandshake completed")
201                         } else {
202                                 go func(addr string, peer *govpn.Peer) {
203                                         s.logger.WithFields(fields).WithFields(loopFields).Debug("Peer do not already exists")
204                                         tap, err := s.callUp(peer, govpn.ProtocolUDP)
205                                         if err != nil {
206                                                 s.logger.WithFields(loopFields).WithFields(fields).WithFields(s.LogFields()).WithFields(peer.LogFields()).WithError(err).Error("TAP failed")
207                                                 return
208                                         }
209                                         psNew := &PeerState{
210                                                 peer:       peer,
211                                                 tap:        tap,
212                                                 terminator: make(chan struct{}),
213                                         }
214                                         peer.Protocol = govpn.ProtocolUDP
215                                         go func(peer *govpn.Peer, tap *govpn.TAP, terminator chan struct{}) {
216                                                 govpn.PeerTapProcessor(peer, tap, terminator)
217                                                 <-udpBufs
218                                                 <-udpBufs
219                                         }(psNew.peer, psNew.tap, psNew.terminator)
220                                         s.peersLock.Lock()
221                                         s.peersByIDLock.Lock()
222                                         s.kpLock.Lock()
223                                         s.peers[addr] = psNew
224                                         s.knownPeers[addr] = &peer
225                                         s.peersByID[*peer.ID] = addr
226                                         s.peersLock.Unlock()
227                                         s.peersByIDLock.Unlock()
228                                         s.kpLock.Unlock()
229                                         s.logger.WithFields(loopFields).WithFields(fields).WithFields(s.LogFields()).WithFields(peer.LogFields()).Info("Peer initialized")
230                                 }(addr, peer)
231                         }
232                         udpBufs <- buf
233                 }
234         }()
235 }