]> Cypherpunks.ru repositories - govpn.git/blob - src/cypherpunks.ru/govpn/server/tcp.go
Language mistakes and stylistic fixes
[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 not 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("Can not lookup for peer in ids")
116                         continue
117                 }
118                 if peerID == nil {
119                         s.logger.WithFields(
120                                 fields,
121                         ).WithFields(
122                                 s.LogFields(),
123                         ).Debug("Can not find peer")
124                         continue
125                 }
126                 if hs == nil {
127                         conf = s.confs.Get(*peerID)
128                         if conf == nil {
129                                 s.logger.WithFields(
130                                         fields,
131                                 ).WithFields(
132                                         s.LogFields(),
133                                 ).WithFields(
134                                         s.configuration.LogFields(),
135                                 ).Error("Configuration get failed")
136                                 break
137                         }
138                         hs = govpn.NewHandshake(addr, conn, conf)
139                 }
140                 peer, err = hs.Server(buf[:prev])
141                 if err != nil {
142                         s.logger.WithFields(
143                                 fields,
144                         ).WithError(err).WithFields(
145                                 s.LogFields(),
146                         ).Error("Can not create new peer")
147                         continue
148                 }
149                 prev = 0
150                 if peer == nil {
151                         continue
152                 }
153
154                 s.logger.WithFields(
155                         fields,
156                 ).WithFields(
157                         s.LogFields(),
158                 ).WithFields(
159                         peer.LogFields(),
160                 ).Info("Handshake completed")
161
162                 hs.Zero()
163                 s.peersByIDLock.RLock()
164                 addrPrev, exists := s.peersByID[*peer.ID]
165                 s.peersByIDLock.RUnlock()
166
167                 if exists {
168                         s.peersLock.Lock()
169                         s.peers[addrPrev].terminator <- struct{}{}
170                         tap = s.peers[addrPrev].tap
171                         ps = &PeerState{
172                                 peer:       peer,
173                                 tap:        tap,
174                                 terminator: make(chan struct{}),
175                         }
176                         peer.Protocol = govpn.ProtocolTCP
177                         go govpn.PeerTapProcessor(ps.peer, ps.tap, ps.terminator)
178                         s.peersByIDLock.Lock()
179                         s.kpLock.Lock()
180                         delete(s.peers, addrPrev)
181                         delete(s.knownPeers, addrPrev)
182                         s.peers[addr] = ps
183                         s.knownPeers[addr] = &peer
184                         s.peersByID[*peer.ID] = addr
185                         s.peersLock.Unlock()
186                         s.peersByIDLock.Unlock()
187                         s.kpLock.Unlock()
188                         s.logger.WithFields(
189                                 fields,
190                         ).WithFields(
191                                 s.LogFields(),
192                         ).WithFields(
193                                 peer.LogFields(),
194                         ).Debug("Rehandshake completed")
195                 } else {
196                         tap, err = s.callUp(peer, govpn.ProtocolTCP)
197                         if err != nil {
198                                 s.logger.WithFields(
199                                         fields,
200                                 ).WithFields(
201                                         s.LogFields(),
202                                 ).WithFields(
203                                         peer.LogFields(),
204                                 ).WithError(err).Error("TAP failed")
205                                 peer = nil
206                                 break
207                         }
208                         ps = &PeerState{
209                                 peer:       peer,
210                                 tap:        tap,
211                                 terminator: make(chan struct{}, 1),
212                         }
213                         peer.Protocol = govpn.ProtocolTCP
214                         go govpn.PeerTapProcessor(ps.peer, ps.tap, ps.terminator)
215                         s.peersLock.Lock()
216                         s.peersByIDLock.Lock()
217                         s.kpLock.Lock()
218                         s.peers[addr] = ps
219                         s.peersByID[*peer.ID] = addr
220                         s.knownPeers[addr] = &peer
221                         s.peersLock.Unlock()
222                         s.peersByIDLock.Unlock()
223                         s.kpLock.Unlock()
224                         s.logger.WithFields(
225                                 fields,
226                         ).WithFields(
227                                 s.LogFields(),
228                         ).WithFields(
229                                 peer.LogFields(),
230                         ).Info("Peer created")
231                 }
232                 break
233         }
234         if hs != nil {
235                 hs.Zero()
236         }
237         if peer == nil {
238                 return
239         }
240
241         prev = 0
242         var i int
243         for {
244                 if prev == len(buf) {
245                         break
246                 }
247                 deadLine = time.Now().Add(conf.Timeout)
248                 if err = conn.SetReadDeadline(deadLine); err != nil {
249                         s.Error <- errors.Wrapf(err, "conn.SetReadDeadline %s", deadLine.String())
250                         return
251                 }
252                 n, err = conn.Read(buf[prev:])
253                 if err != nil {
254                         s.logger.WithFields(
255                                 fields,
256                         ).WithFields(
257                                 s.LogFields(),
258                         ).WithError(
259                                 err,
260                         ).Debug("Can not read connection: either EOFed or timeouted")
261                         break
262                 }
263                 prev += n
264         CheckMore:
265                 if prev < govpn.MinPktLength {
266                         continue
267                 }
268                 i = bytes.Index(buf[:prev], peer.NonceExpect)
269                 if i == -1 {
270                         continue
271                 }
272                 if !peer.PktProcess(buf[:i+govpn.NonceSize], tap, false) {
273                         s.logger.WithFields(
274                                 fields,
275                         ).WithFields(
276                                 s.LogFields(),
277                         ).WithFields(
278                                 peer.LogFields(),
279                         ).Warn("Packet unauthenticated")
280                         break
281                 }
282                 copy(buf, buf[i+govpn.NonceSize:prev])
283                 prev = prev - i - govpn.NonceSize
284                 goto CheckMore
285         }
286         peer.Zero()
287 }