]> Sergey Matveev's repositories - btrtrc.git/blob - handshake.go
sortimports
[btrtrc.git] / handshake.go
1 package torrent
2
3 import (
4         "bytes"
5         "fmt"
6         "io"
7         "net"
8         "time"
9
10         "github.com/anacrolix/torrent/mse"
11         pp "github.com/anacrolix/torrent/peer_protocol"
12 )
13
14 // Wraps a raw connection and provides the interface we want for using the
15 // connection in the message loop.
16 type deadlineReader struct {
17         nc net.Conn
18         r  io.Reader
19 }
20
21 func (r deadlineReader) Read(b []byte) (int, error) {
22         // Keep-alives should be received every 2 mins. Give a bit of gracetime.
23         err := r.nc.SetReadDeadline(time.Now().Add(150 * time.Second))
24         if err != nil {
25                 return 0, fmt.Errorf("error setting read deadline: %s", err)
26         }
27         return r.r.Read(b)
28 }
29
30 func handleEncryption(
31         rw io.ReadWriter,
32         skeys mse.SecretKeyIter,
33         policy EncryptionPolicy,
34 ) (
35         ret io.ReadWriter,
36         headerEncrypted bool,
37         cryptoMethod mse.CryptoMethod,
38         err error,
39 ) {
40         if !policy.ForceEncryption {
41                 var protocol [len(pp.Protocol)]byte
42                 _, err = io.ReadFull(rw, protocol[:])
43                 if err != nil {
44                         return
45                 }
46                 rw = struct {
47                         io.Reader
48                         io.Writer
49                 }{
50                         io.MultiReader(bytes.NewReader(protocol[:]), rw),
51                         rw,
52                 }
53                 if string(protocol[:]) == pp.Protocol {
54                         ret = rw
55                         return
56                 }
57         }
58         headerEncrypted = true
59         ret, cryptoMethod, err = mse.ReceiveHandshake(rw, skeys, func(provides mse.CryptoMethod) mse.CryptoMethod {
60                 switch {
61                 case policy.ForceEncryption:
62                         return mse.CryptoMethodRC4
63                 case policy.DisableEncryption:
64                         return mse.CryptoMethodPlaintext
65                 case policy.PreferNoEncryption && provides&mse.CryptoMethodPlaintext != 0:
66                         return mse.CryptoMethodPlaintext
67                 default:
68                         return mse.DefaultCryptoSelector(provides)
69                 }
70         })
71         return
72 }
73
74 type PeerExtensionBits = pp.PeerExtensionBits