1package handshake 2 3import ( 4 "crypto/rand" 5 "encoding/asn1" 6 "net" 7 "time" 8 9 "github.com/lucas-clemente/quic-go/internal/protocol" 10 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13) 14 15var _ = Describe("Token Generator", func() { 16 var tokenGen *TokenGenerator 17 18 BeforeEach(func() { 19 var err error 20 tokenGen, err = NewTokenGenerator(rand.Reader) 21 Expect(err).ToNot(HaveOccurred()) 22 }) 23 24 It("generates a token", func() { 25 ip := net.IPv4(127, 0, 0, 1) 26 token, err := tokenGen.NewRetryToken(&net.UDPAddr{IP: ip, Port: 1337}, nil, nil) 27 Expect(err).ToNot(HaveOccurred()) 28 Expect(token).ToNot(BeEmpty()) 29 }) 30 31 It("works with nil tokens", func() { 32 token, err := tokenGen.DecodeToken(nil) 33 Expect(err).ToNot(HaveOccurred()) 34 Expect(token).To(BeNil()) 35 }) 36 37 It("accepts a valid token", func() { 38 ip := net.IPv4(192, 168, 0, 1) 39 tokenEnc, err := tokenGen.NewRetryToken( 40 &net.UDPAddr{IP: ip, Port: 1337}, 41 nil, 42 nil, 43 ) 44 Expect(err).ToNot(HaveOccurred()) 45 token, err := tokenGen.DecodeToken(tokenEnc) 46 Expect(err).ToNot(HaveOccurred()) 47 Expect(token.RemoteAddr).To(Equal("192.168.0.1")) 48 Expect(token.SentTime).To(BeTemporally("~", time.Now(), 100*time.Millisecond)) 49 Expect(token.OriginalDestConnectionID.Len()).To(BeZero()) 50 Expect(token.RetrySrcConnectionID.Len()).To(BeZero()) 51 }) 52 53 It("saves the connection ID", func() { 54 tokenEnc, err := tokenGen.NewRetryToken( 55 &net.UDPAddr{}, 56 protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}, 57 protocol.ConnectionID{0xde, 0xad, 0xc0, 0xde}, 58 ) 59 Expect(err).ToNot(HaveOccurred()) 60 token, err := tokenGen.DecodeToken(tokenEnc) 61 Expect(err).ToNot(HaveOccurred()) 62 Expect(token.OriginalDestConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef})) 63 Expect(token.RetrySrcConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xc0, 0xde})) 64 }) 65 66 It("rejects invalid tokens", func() { 67 _, err := tokenGen.DecodeToken([]byte("invalid token")) 68 Expect(err).To(HaveOccurred()) 69 }) 70 71 It("rejects tokens that cannot be decoded", func() { 72 token, err := tokenGen.tokenProtector.NewToken([]byte("foobar")) 73 Expect(err).ToNot(HaveOccurred()) 74 _, err = tokenGen.DecodeToken(token) 75 Expect(err).To(HaveOccurred()) 76 }) 77 78 It("rejects tokens that can be decoded, but have additional payload", func() { 79 t, err := asn1.Marshal(token{RemoteAddr: []byte("foobar")}) 80 Expect(err).ToNot(HaveOccurred()) 81 t = append(t, []byte("rest")...) 82 enc, err := tokenGen.tokenProtector.NewToken(t) 83 Expect(err).ToNot(HaveOccurred()) 84 _, err = tokenGen.DecodeToken(enc) 85 Expect(err).To(MatchError("rest when unpacking token: 4")) 86 }) 87 88 // we don't generate tokens that have no data, but we should be able to handle them if we receive one for whatever reason 89 It("doesn't panic if a tokens has no data", func() { 90 t, err := asn1.Marshal(token{RemoteAddr: []byte("")}) 91 Expect(err).ToNot(HaveOccurred()) 92 enc, err := tokenGen.tokenProtector.NewToken(t) 93 Expect(err).ToNot(HaveOccurred()) 94 _, err = tokenGen.DecodeToken(enc) 95 Expect(err).ToNot(HaveOccurred()) 96 }) 97 98 It("works with an IPv6 addresses ", func() { 99 addresses := []string{ 100 "2001:db8::68", 101 "2001:0000:4136:e378:8000:63bf:3fff:fdd2", 102 "2001::1", 103 "ff01:0:0:0:0:0:0:2", 104 } 105 for _, addr := range addresses { 106 ip := net.ParseIP(addr) 107 Expect(ip).ToNot(BeNil()) 108 raddr := &net.UDPAddr{IP: ip, Port: 1337} 109 tokenEnc, err := tokenGen.NewRetryToken(raddr, nil, nil) 110 Expect(err).ToNot(HaveOccurred()) 111 token, err := tokenGen.DecodeToken(tokenEnc) 112 Expect(err).ToNot(HaveOccurred()) 113 Expect(token.RemoteAddr).To(Equal(ip.String())) 114 Expect(token.SentTime).To(BeTemporally("~", time.Now(), 100*time.Millisecond)) 115 } 116 }) 117 118 It("uses the string representation an address that is not a UDP address", func() { 119 raddr := &net.TCPAddr{IP: net.IPv4(192, 168, 13, 37), Port: 1337} 120 tokenEnc, err := tokenGen.NewRetryToken(raddr, nil, nil) 121 Expect(err).ToNot(HaveOccurred()) 122 token, err := tokenGen.DecodeToken(tokenEnc) 123 Expect(err).ToNot(HaveOccurred()) 124 Expect(token.RemoteAddr).To(Equal("192.168.13.37:1337")) 125 Expect(token.SentTime).To(BeTemporally("~", time.Now(), 100*time.Millisecond)) 126 }) 127}) 128