]> Cypherpunks.ru repositories - govpn.git/blob - src/cypherpunks.ru/govpn/server/tcp.go
Split long lines
[govpn.git] / src / cypherpunks.ru / govpn / server / tcp.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         "bytes"
23         "net"
24         "time"
25
26         "github.com/Sirupsen/logrus"
27         "github.com/pkg/errors"
28
29         "cypherpunks.ru/govpn"
30 )
31
32 func (s *Server) startTCP() {
33         bind, err := net.ResolveTCPAddr("tcp", s.configuration.BindAddress)
34         if err != nil {
35                 s.Error <- errors.Wrap(err, "net.ResolveTCPAddr")
36                 return
37         }
38         listener, err := net.ListenTCP("tcp", bind)
39         if err != nil {
40                 s.Error <- errors.Wrapf(err, "net.ListenTCP %q", bind.String())
41                 return
42         }
43         fields := logrus.Fields{
44                 "func": logFuncPrefix + "Server.startTCP",
45                 "bind": bind.String(),
46         }
47         s.logger.WithFields(
48                 fields,
49         ).WithFields(
50                 s.LogFields(),
51         ).WithFields(
52                 s.configuration.LogFields(),
53         ).Info("Listen")
54         go func() {
55                 for {
56                         conn, err := listener.AcceptTCP()
57                         if err != nil {
58                                 s.logger.WithError(err).WithFields(
59                                         fields,
60                                 ).WithFields(
61                                         s.LogFields(),
62                                 ).Error("Failed to accept TCP connection")
63                                 continue
64                         }
65                         go s.handleTCP(conn)
66                 }
67         }()
68 }
69
70 func (s *Server) handleTCP(conn net.Conn) {
71         addr := conn.RemoteAddr().String()
72         buf := make([]byte, govpn.EnclessEnlargeSize+2*govpn.MTUMax)
73         var n int
74         var err error
75         var prev int
76         var hs *govpn.Handshake
77         var ps *PeerState
78         var peer *govpn.Peer
79         var deadLine time.Time
80         var tap *govpn.TAP
81         var conf *govpn.PeerConf
82         fields := logrus.Fields{
83                 "func":   logFuncPrefix + "Server.handleTCP",
84                 "remote": addr,
85         }
86         for {
87                 if prev == len(buf) {
88                         // TODO log why
89                         break
90                 }
91
92                 deadLine = time.Now().Add(govpn.TimeoutDefault)
93                 if err = conn.SetReadDeadline(deadLine); err != nil {
94                         s.Error <- errors.Wrapf(err, "conn.SetReadDeadline %s", deadLine.String())
95                         return
96                 }
97                 n, err = conn.Read(buf[prev:])
98                 if err != nil {
99                         s.logger.WithFields(
100                                 fields,
101                         ).WithFields(
102                                 s.LogFields(),
103                         ).WithError(
104                                 err,
105                         ).Debug("Can't read connection: either EOFed or timeouted")
106                         break
107                 }
108                 prev += n
109                 peerID, err := s.idsCache.Find(buf[:prev])
110                 if err != nil {
111                         s.logger.WithFields(
112                                 fields,
113                         ).WithFields(
114                                 s.LogFields(),
115                         ).WithError(err).Debug("Couldn't lookup for peer in ids")
116                         continue
117                 }
118                 if peerID == nil {
119                         s.logger.WithFields(fields).WithFields(s.LogFields()).Debug("Couldn't find peer")
120                         continue
121                 }
122                 if hs == nil {
123                         conf = s.confs.Get(*peerID)
124                         if conf == nil {
125                                 s.logger.WithFields(
126                                         fields,
127                                 ).WithFields(
128                                         s.LogFields(),
129                                 ).WithFields(
130                                         s.configuration.LogFields(),
131                                 ).Error("Configuration get failed")
132                                 break
133                         }
134                         hs = govpn.NewHandshake(addr, conn, conf)
135                 }
136                 peer, err = hs.Server(buf[:prev])
137                 if err != nil {
138                         s.logger.WithFields(
139                                 fields,
140                         ).WithError(err).WithFields(
141                                 s.LogFields(),
142                         ).Error("Can't create new peer")
143                         continue
144                 }
145                 prev = 0
146                 if peer == nil {
147                         continue
148                 }
149
150                 s.logger.WithFields(
151                         fields,
152                 ).WithFields(
153                         s.LogFields(),
154                 ).WithFields(
155                         peer.LogFields(),
156                 ).Info("Handshake completed")
157
158                 hs.Zero()
159                 s.peersByIDLock.RLock()
160                 addrPrev, exists := s.peersByID[*peer.ID]
161                 s.peersByIDLock.RUnlock()
162
163                 if exists {
164                         s.peersLock.Lock()
165                         s.peers[addrPrev].terminator <- struct{}{}
166                         tap = s.peers[addrPrev].tap
167                         ps = &PeerState{
168                                 peer:       peer,
169                                 tap:        tap,
170                                 terminator: make(chan struct{}),
171                         }
172                         peer.Protocol = govpn.ProtocolTCP
173                         go govpn.PeerTapProcessor(ps.peer, ps.tap, ps.terminator)
174                         s.peersByIDLock.Lock()
175                         s.kpLock.Lock()
176                         delete(s.peers, addrPrev)
177                         delete(s.knownPeers, addrPrev)
178                         s.peers[addr] = ps
179                         s.knownPeers[addr] = &peer
180                         s.peersByID[*peer.ID] = addr
181                         s.peersLock.Unlock()
182                         s.peersByIDLock.Unlock()
183                         s.kpLock.Unlock()
184                         s.logger.WithFields(
185                                 fields,
186                         ).WithFields(
187                                 s.LogFields(),
188                         ).WithFields(
189                                 peer.LogFields(),
190                         ).Debug("Rehandshake completed")
191                 } else {
192                         tap, err = s.callUp(peer, govpn.ProtocolTCP)
193                         if err != nil {
194                                 s.logger.WithFields(
195                                         fields,
196                                 ).WithFields(
197                                         s.LogFields(),
198                                 ).WithFields(
199                                         peer.LogFields(),
200                                 ).WithError(err).Error("TAP failed")
201                                 peer = nil
202                                 break
203                         }
204                         ps = &PeerState{
205                                 peer:       peer,
206                                 tap:        tap,
207                                 terminator: make(chan struct{}, 1),
208                         }
209                         peer.Protocol = govpn.ProtocolTCP
210                         go govpn.PeerTapProcessor(ps.peer, ps.tap, ps.terminator)
211                         s.peersLock.Lock()
212                         s.peersByIDLock.Lock()
213                         s.kpLock.Lock()
214                         s.peers[addr] = ps
215                         s.peersByID[*peer.ID] = addr
216                         s.knownPeers[addr] = &peer
217                         s.peersLock.Unlock()
218                         s.peersByIDLock.Unlock()
219                         s.kpLock.Unlock()
220                         s.logger.WithFields(
221                                 fields,
222                         ).WithFields(
223                                 s.LogFields(),
224                         ).WithFields(
225                                 peer.LogFields(),
226                         ).Info("Peer created")
227                 }
228                 break
229         }
230         if hs != nil {
231                 hs.Zero()
232         }
233         if peer == nil {
234                 return
235         }
236
237         prev = 0
238         var i int
239         for {
240                 if prev == len(buf) {
241                         break
242                 }
243                 deadLine = time.Now().Add(conf.Timeout)
244                 if err = conn.SetReadDeadline(deadLine); err != nil {
245                         s.Error <- errors.Wrapf(err, "conn.SetReadDeadline %s", deadLine.String())
246                         return
247                 }
248                 n, err = conn.Read(buf[prev:])
249                 if err != nil {
250                         s.logger.WithFields(
251                                 fields,
252                         ).WithFields(
253                                 s.LogFields(),
254                         ).WithError(
255                                 err,
256                         ).Debug("Can't read connection: either EOFed or timeouted")
257                         break
258                 }
259                 prev += n
260         CheckMore:
261                 if prev < govpn.MinPktLength {
262                         continue
263                 }
264                 i = bytes.Index(buf[:prev], peer.NonceExpect)
265                 if i == -1 {
266                         continue
267                 }
268                 if !peer.PktProcess(buf[:i+govpn.NonceSize], tap, false) {
269                         s.logger.WithFields(
270                                 fields,
271                         ).WithFields(
272                                 s.LogFields(),
273                         ).WithFields(
274                                 peer.LogFields(),
275                         ).Warn("Packet unauthenticated")
276                         break
277                 }
278                 copy(buf, buf[i+govpn.NonceSize:prev])
279                 prev = prev - i - govpn.NonceSize
280                 goto CheckMore
281         }
282         peer.Zero()
283 }