name the quic.Cookie to quic.Token

This commit is contained in:
Marten Seemann 2019-05-30 22:13:06 +08:00
parent 06da72ae4e
commit 1d6707325f
12 changed files with 234 additions and 232 deletions

View file

@ -3,6 +3,7 @@
## v0.12.0 (unreleased)
- Implement HTTP/3.
- Rename `quic.Cookie` to `quic.Token` and `quic.Config.AcceptCookie` to `quic.Config.AcceptToken`.
## v0.11.0 (2019-04-05)

View file

@ -113,8 +113,8 @@ var _ = Describe("Handshake RTT tests", func() {
expectDurationInRTTs(2)
})
It("establishes a connection in 1 RTT when the server doesn't require a Cookie", func() {
serverConfig.AcceptCookie = func(_ net.Addr, _ *quic.Cookie) bool {
It("establishes a connection in 1 RTT when the server doesn't require a token", func() {
serverConfig.AcceptToken = func(_ net.Addr, _ *quic.Token) bool {
return true
}
runServerAndProxy()
@ -128,7 +128,7 @@ var _ = Describe("Handshake RTT tests", func() {
})
It("establishes a connection in 2 RTTs if a HelloRetryRequest is performed", func() {
serverConfig.AcceptCookie = func(_ net.Addr, _ *quic.Cookie) bool {
serverConfig.AcceptToken = func(_ net.Addr, _ *quic.Token) bool {
return true
}
serverTLSConfig.CurvePreferences = []tls.CurveID{tls.CurveP384}
@ -142,8 +142,8 @@ var _ = Describe("Handshake RTT tests", func() {
expectDurationInRTTs(2)
})
It("doesn't complete the handshake when the server never accepts the Cookie", func() {
serverConfig.AcceptCookie = func(_ net.Addr, _ *quic.Cookie) bool {
It("doesn't complete the handshake when the server never accepts the token", func() {
serverConfig.AcceptToken = func(_ net.Addr, _ *quic.Token) bool {
return false
}
clientConfig.HandshakeTimeout = 500 * time.Millisecond

View file

@ -196,7 +196,7 @@ var _ = Describe("Handshake tests", func() {
}
BeforeEach(func() {
serverConfig.AcceptCookie = func(net.Addr, *quic.Cookie) bool { return true }
serverConfig.AcceptToken = func(net.Addr, *quic.Token) bool { return true }
var err error
// start the server, but don't call Accept
server, err = quic.ListenAddr("localhost:0", testdata.GetTLSConfig(), serverConfig)

View file

@ -16,8 +16,8 @@ type StreamID = protocol.StreamID
// A VersionNumber is a QUIC version number.
type VersionNumber = protocol.VersionNumber
// A Cookie can be used to verify the ownership of the client address.
type Cookie struct {
// A Token can be used to verify the ownership of the client address.
type Token struct {
RemoteAddr string
SentTime time.Time
}
@ -187,11 +187,11 @@ type Config struct {
// If the timeout is exceeded, the connection is closed.
// If this value is zero, the timeout is set to 30 seconds.
IdleTimeout time.Duration
// AcceptCookie determines if a Cookie is accepted.
// It is called with cookie = nil if the client didn't send an Cookie.
// If not set, it verifies that the address matches, and that the Cookie was issued within the last 24 hours.
// AcceptToken determines if a Token is accepted.
// It is called with token = nil if the client didn't send a token.
// If not set, it verifies that the address matches, and that the token was issued within the last 24 hours.
// This option is only valid for the server.
AcceptCookie func(clientAddr net.Addr, cookie *Cookie) bool
AcceptToken func(clientAddr net.Addr, token *Token) bool
// MaxReceiveStreamFlowControlWindow is the maximum stream-level flow control window for receiving data.
// If this value is zero, it will default to 1 MB for the server and 6 MB for the client.
MaxReceiveStreamFlowControlWindow uint64

View file

@ -1,109 +0,0 @@
package handshake
import (
"encoding/asn1"
"fmt"
"net"
"time"
"github.com/lucas-clemente/quic-go/internal/protocol"
)
const (
cookiePrefixIP byte = iota
cookiePrefixString
)
// A Cookie is derived from the client address and can be used to verify the ownership of this address.
type Cookie struct {
RemoteAddr string
OriginalDestConnectionID protocol.ConnectionID
// The time that the Cookie was issued (resolution 1 second)
SentTime time.Time
}
// token is the struct that is used for ASN1 serialization and deserialization
type token struct {
RemoteAddr []byte
OriginalDestConnectionID []byte
Timestamp int64
}
// A CookieGenerator generates Cookies
type CookieGenerator struct {
cookieProtector cookieProtector
}
// NewCookieGenerator initializes a new CookieGenerator
func NewCookieGenerator() (*CookieGenerator, error) {
cookieProtector, err := newCookieProtector()
if err != nil {
return nil, err
}
return &CookieGenerator{
cookieProtector: cookieProtector,
}, nil
}
// NewToken generates a new Cookie for a given source address
func (g *CookieGenerator) NewToken(raddr net.Addr, origConnID protocol.ConnectionID) ([]byte, error) {
data, err := asn1.Marshal(token{
RemoteAddr: encodeRemoteAddr(raddr),
OriginalDestConnectionID: origConnID,
Timestamp: time.Now().Unix(),
})
if err != nil {
return nil, err
}
return g.cookieProtector.NewToken(data)
}
// DecodeToken decodes a Cookie
func (g *CookieGenerator) DecodeToken(encrypted []byte) (*Cookie, error) {
// if the client didn't send any Cookie, DecodeToken will be called with a nil-slice
if len(encrypted) == 0 {
return nil, nil
}
data, err := g.cookieProtector.DecodeToken(encrypted)
if err != nil {
return nil, err
}
t := &token{}
rest, err := asn1.Unmarshal(data, t)
if err != nil {
return nil, err
}
if len(rest) != 0 {
return nil, fmt.Errorf("rest when unpacking token: %d", len(rest))
}
cookie := &Cookie{
RemoteAddr: decodeRemoteAddr(t.RemoteAddr),
SentTime: time.Unix(t.Timestamp, 0),
}
if len(t.OriginalDestConnectionID) > 0 {
cookie.OriginalDestConnectionID = protocol.ConnectionID(t.OriginalDestConnectionID)
}
return cookie, nil
}
// encodeRemoteAddr encodes a remote address such that it can be saved in the Cookie
func encodeRemoteAddr(remoteAddr net.Addr) []byte {
if udpAddr, ok := remoteAddr.(*net.UDPAddr); ok {
return append([]byte{cookiePrefixIP}, udpAddr.IP...)
}
return append([]byte{cookiePrefixString}, []byte(remoteAddr.String())...)
}
// decodeRemoteAddr decodes the remote address saved in the Cookie
func decodeRemoteAddr(data []byte) string {
// data will never be empty for a Cookie that we generated. Check it to be on the safe side
if len(data) == 0 {
return ""
}
if data[0] == cookiePrefixIP {
return net.IP(data[1:]).String()
}
return string(data[1:])
}

View file

@ -0,0 +1,110 @@
package handshake
import (
"encoding/asn1"
"fmt"
"net"
"time"
"github.com/lucas-clemente/quic-go/internal/protocol"
)
const (
tokenPrefixIP byte = iota
tokenPrefixString
)
// A Token is derived from the client address and can be used to verify the ownership of this address.
type Token struct {
RemoteAddr string
OriginalDestConnectionID protocol.ConnectionID
// The time that the Token was issued (resolution 1 second)
SentTime time.Time
}
// token is the struct that is used for ASN1 serialization and deserialization
type token struct {
RemoteAddr []byte
OriginalDestConnectionID []byte
Timestamp int64
}
// A TokenGenerator generates tokens
type TokenGenerator struct {
tokenProtector tokenProtector
}
// NewTokenGenerator initializes a new TookenGenerator
func NewTokenGenerator() (*TokenGenerator, error) {
tokenProtector, err := newTokenProtector()
if err != nil {
return nil, err
}
return &TokenGenerator{
tokenProtector: tokenProtector,
}, nil
}
// NewToken generates a new token for a given source address
func (g *TokenGenerator) NewToken(raddr net.Addr, origConnID protocol.ConnectionID) ([]byte, error) {
data, err := asn1.Marshal(token{
RemoteAddr: encodeRemoteAddr(raddr),
OriginalDestConnectionID: origConnID,
Timestamp: time.Now().Unix(),
})
if err != nil {
return nil, err
}
return g.tokenProtector.NewToken(data)
}
// DecodeToken decodes a token
func (g *TokenGenerator) DecodeToken(encrypted []byte) (*Token, error) {
// if the client didn't send any token, DecodeToken will be called with a nil-slice
if len(encrypted) == 0 {
return nil, nil
}
data, err := g.tokenProtector.DecodeToken(encrypted)
if err != nil {
return nil, err
}
t := &token{}
rest, err := asn1.Unmarshal(data, t)
if err != nil {
return nil, err
}
if len(rest) != 0 {
return nil, fmt.Errorf("rest when unpacking token: %d", len(rest))
}
token := &Token{
RemoteAddr: decodeRemoteAddr(t.RemoteAddr),
SentTime: time.Unix(t.Timestamp, 0),
}
if len(t.OriginalDestConnectionID) > 0 {
token.OriginalDestConnectionID = protocol.ConnectionID(t.OriginalDestConnectionID)
}
return token, nil
}
// encodeRemoteAddr encodes a remote address such that it can be saved in the token
func encodeRemoteAddr(remoteAddr net.Addr) []byte {
if udpAddr, ok := remoteAddr.(*net.UDPAddr); ok {
return append([]byte{tokenPrefixIP}, udpAddr.IP...)
}
return append([]byte{tokenPrefixString}, []byte(remoteAddr.String())...)
}
// decodeRemoteAddr decodes the remote address saved in the token
func decodeRemoteAddr(data []byte) string {
// data will never be empty for a token that we generated.
// Check it to be on the safe side
if len(data) == 0 {
return ""
}
if data[0] == tokenPrefixIP {
return net.IP(data[1:]).String()
}
return string(data[1:])
}

View file

@ -11,64 +11,64 @@ import (
. "github.com/onsi/gomega"
)
var _ = Describe("Cookie Generator", func() {
var cookieGen *CookieGenerator
var _ = Describe("Token Generator", func() {
var tokenGen *TokenGenerator
BeforeEach(func() {
var err error
cookieGen, err = NewCookieGenerator()
tokenGen, err = NewTokenGenerator()
Expect(err).ToNot(HaveOccurred())
})
It("generates a Cookie", func() {
It("generates a token", func() {
ip := net.IPv4(127, 0, 0, 1)
token, err := cookieGen.NewToken(&net.UDPAddr{IP: ip, Port: 1337}, nil)
token, err := tokenGen.NewToken(&net.UDPAddr{IP: ip, Port: 1337}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(token).ToNot(BeEmpty())
})
It("works with nil tokens", func() {
cookie, err := cookieGen.DecodeToken(nil)
token, err := tokenGen.DecodeToken(nil)
Expect(err).ToNot(HaveOccurred())
Expect(cookie).To(BeNil())
Expect(token).To(BeNil())
})
It("accepts a valid cookie", func() {
It("accepts a valid token", func() {
ip := net.IPv4(192, 168, 0, 1)
token, err := cookieGen.NewToken(
tokenEnc, err := tokenGen.NewToken(
&net.UDPAddr{IP: ip, Port: 1337},
nil,
)
Expect(err).ToNot(HaveOccurred())
cookie, err := cookieGen.DecodeToken(token)
token, err := tokenGen.DecodeToken(tokenEnc)
Expect(err).ToNot(HaveOccurred())
Expect(cookie.RemoteAddr).To(Equal("192.168.0.1"))
// the time resolution of the Cookie is just 1 second
// if Cookie generation and this check happen in "different seconds", the difference will be between 1 and 2 seconds
Expect(cookie.SentTime).To(BeTemporally("~", time.Now(), 2*time.Second))
Expect(cookie.OriginalDestConnectionID).To(BeNil())
Expect(token.RemoteAddr).To(Equal("192.168.0.1"))
// the time resolution of the token is just 1 second
// if token generation and this check happen in "different seconds", the difference will be between 1 and 2 seconds
Expect(token.SentTime).To(BeTemporally("~", time.Now(), 2*time.Second))
Expect(token.OriginalDestConnectionID).To(BeNil())
})
It("saves the connection ID", func() {
token, err := cookieGen.NewToken(
tokenEnc, err := tokenGen.NewToken(
&net.UDPAddr{},
protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
)
Expect(err).ToNot(HaveOccurred())
cookie, err := cookieGen.DecodeToken(token)
token, err := tokenGen.DecodeToken(tokenEnc)
Expect(err).ToNot(HaveOccurred())
Expect(cookie.OriginalDestConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}))
Expect(token.OriginalDestConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}))
})
It("rejects invalid tokens", func() {
_, err := cookieGen.DecodeToken([]byte("invalid token"))
_, err := tokenGen.DecodeToken([]byte("invalid token"))
Expect(err).To(HaveOccurred())
})
It("rejects tokens that cannot be decoded", func() {
token, err := cookieGen.cookieProtector.NewToken([]byte("foobar"))
token, err := tokenGen.tokenProtector.NewToken([]byte("foobar"))
Expect(err).ToNot(HaveOccurred())
_, err = cookieGen.DecodeToken(token)
_, err = tokenGen.DecodeToken(token)
Expect(err).To(HaveOccurred())
})
@ -76,9 +76,9 @@ var _ = Describe("Cookie Generator", func() {
t, err := asn1.Marshal(token{RemoteAddr: []byte("foobar")})
Expect(err).ToNot(HaveOccurred())
t = append(t, []byte("rest")...)
enc, err := cookieGen.cookieProtector.NewToken(t)
enc, err := tokenGen.tokenProtector.NewToken(t)
Expect(err).ToNot(HaveOccurred())
_, err = cookieGen.DecodeToken(enc)
_, err = tokenGen.DecodeToken(enc)
Expect(err).To(MatchError("rest when unpacking token: 4"))
})
@ -86,9 +86,9 @@ var _ = Describe("Cookie Generator", func() {
It("doesn't panic if a tokens has no data", func() {
t, err := asn1.Marshal(token{RemoteAddr: []byte("")})
Expect(err).ToNot(HaveOccurred())
enc, err := cookieGen.cookieProtector.NewToken(t)
enc, err := tokenGen.tokenProtector.NewToken(t)
Expect(err).ToNot(HaveOccurred())
_, err = cookieGen.DecodeToken(enc)
_, err = tokenGen.DecodeToken(enc)
Expect(err).ToNot(HaveOccurred())
})
@ -103,26 +103,26 @@ var _ = Describe("Cookie Generator", func() {
ip := net.ParseIP(addr)
Expect(ip).ToNot(BeNil())
raddr := &net.UDPAddr{IP: ip, Port: 1337}
token, err := cookieGen.NewToken(raddr, nil)
tokenEnc, err := tokenGen.NewToken(raddr, nil)
Expect(err).ToNot(HaveOccurred())
cookie, err := cookieGen.DecodeToken(token)
token, err := tokenGen.DecodeToken(tokenEnc)
Expect(err).ToNot(HaveOccurred())
Expect(cookie.RemoteAddr).To(Equal(ip.String()))
// the time resolution of the Cookie is just 1 second
// if Cookie generation and this check happen in "different seconds", the difference will be between 1 and 2 seconds
Expect(cookie.SentTime).To(BeTemporally("~", time.Now(), 2*time.Second))
Expect(token.RemoteAddr).To(Equal(ip.String()))
// the time resolution of the token is just 1 second
// if token generation and this check happen in "different seconds", the difference will be between 1 and 2 seconds
Expect(token.SentTime).To(BeTemporally("~", time.Now(), 2*time.Second))
}
})
It("uses the string representation an address that is not a UDP address", func() {
raddr := &net.TCPAddr{IP: net.IPv4(192, 168, 13, 37), Port: 1337}
token, err := cookieGen.NewToken(raddr, nil)
tokenEnc, err := tokenGen.NewToken(raddr, nil)
Expect(err).ToNot(HaveOccurred())
cookie, err := cookieGen.DecodeToken(token)
token, err := tokenGen.DecodeToken(tokenEnc)
Expect(err).ToNot(HaveOccurred())
Expect(cookie.RemoteAddr).To(Equal("192.168.13.37:1337"))
// the time resolution of the Cookie is just 1 second
// if Cookie generation and this check happen in "different seconds", the difference will be between 1 and 2 seconds
Expect(cookie.SentTime).To(BeTemporally("~", time.Now(), 2*time.Second))
Expect(token.RemoteAddr).To(Equal("192.168.13.37:1337"))
// the time resolution of the token is just 1 second
// if token generation and this check happen in "different seconds", the difference will be between 1 and 2 seconds
Expect(token.SentTime).To(BeTemporally("~", time.Now(), 2*time.Second))
})
})

View file

@ -11,8 +11,8 @@ import (
"golang.org/x/crypto/hkdf"
)
// CookieProtector is used to create and verify a cookie
type cookieProtector interface {
// TokenProtector is used to create and verify a token
type tokenProtector interface {
// NewToken creates a new token
NewToken([]byte) ([]byte, error)
// DecodeToken decodes a token
@ -20,27 +20,27 @@ type cookieProtector interface {
}
const (
cookieSecretSize = 32
cookieNonceSize = 32
tokenSecretSize = 32
tokenNonceSize = 32
)
// cookieProtector is used to create and verify a cookie
type cookieProtectorImpl struct {
// tokenProtector is used to create and verify a token
type tokenProtectorImpl struct {
secret []byte
}
// newCookieProtector creates a source for source address tokens
func newCookieProtector() (cookieProtector, error) {
secret := make([]byte, cookieSecretSize)
// newTokenProtector creates a source for source address tokens
func newTokenProtector() (tokenProtector, error) {
secret := make([]byte, tokenSecretSize)
if _, err := rand.Read(secret); err != nil {
return nil, err
}
return &cookieProtectorImpl{secret: secret}, nil
return &tokenProtectorImpl{secret: secret}, nil
}
// NewToken encodes data into a new token.
func (s *cookieProtectorImpl) NewToken(data []byte) ([]byte, error) {
nonce := make([]byte, cookieNonceSize)
func (s *tokenProtectorImpl) NewToken(data []byte) ([]byte, error) {
nonce := make([]byte, tokenNonceSize)
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
@ -52,20 +52,20 @@ func (s *cookieProtectorImpl) NewToken(data []byte) ([]byte, error) {
}
// DecodeToken decodes a token.
func (s *cookieProtectorImpl) DecodeToken(p []byte) ([]byte, error) {
if len(p) < cookieNonceSize {
func (s *tokenProtectorImpl) DecodeToken(p []byte) ([]byte, error) {
if len(p) < tokenNonceSize {
return nil, fmt.Errorf("Token too short: %d", len(p))
}
nonce := p[:cookieNonceSize]
nonce := p[:tokenNonceSize]
aead, aeadNonce, err := s.createAEAD(nonce)
if err != nil {
return nil, err
}
return aead.Open(nil, aeadNonce, p[cookieNonceSize:], nil)
return aead.Open(nil, aeadNonce, p[tokenNonceSize:], nil)
}
func (s *cookieProtectorImpl) createAEAD(nonce []byte) (cipher.AEAD, []byte, error) {
h := hkdf.New(sha256.New, s.secret, nonce, []byte("quic-go cookie source"))
func (s *tokenProtectorImpl) createAEAD(nonce []byte) (cipher.AEAD, []byte, error) {
h := hkdf.New(sha256.New, s.secret, nonce, []byte("quic-go token source"))
key := make([]byte, 32) // use a 32 byte key, in order to select AES-256
if _, err := io.ReadFull(h, key); err != nil {
return nil, nil, err

View file

@ -5,35 +5,35 @@ import (
. "github.com/onsi/gomega"
)
var _ = Describe("Cookie Protector", func() {
var cp cookieProtector
var _ = Describe("Token Protector", func() {
var tp tokenProtector
BeforeEach(func() {
var err error
cp, err = newCookieProtector()
tp, err = newTokenProtector()
Expect(err).ToNot(HaveOccurred())
})
It("encodes and decodes tokens", func() {
token, err := cp.NewToken([]byte("foobar"))
token, err := tp.NewToken([]byte("foobar"))
Expect(err).ToNot(HaveOccurred())
Expect(token).ToNot(ContainSubstring("foobar"))
decoded, err := cp.DecodeToken(token)
decoded, err := tp.DecodeToken(token)
Expect(err).ToNot(HaveOccurred())
Expect(decoded).To(Equal([]byte("foobar")))
})
It("fails deconding invalid tokens", func() {
token, err := cp.NewToken([]byte("foobar"))
token, err := tp.NewToken([]byte("foobar"))
Expect(err).ToNot(HaveOccurred())
token = token[1:] // remove the first byte
_, err = cp.DecodeToken(token)
_, err = tp.DecodeToken(token)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("message authentication failed"))
})
It("errors when decoding too short tokens", func() {
_, err := cp.DecodeToken([]byte("foobar"))
_, err := tp.DecodeToken([]byte("foobar"))
Expect(err).To(MatchError("Token too short: 6"))
})
})

View file

@ -57,8 +57,8 @@ const MaxTrackedSkippedPackets = 10
// If the queue is full, new connection attempts will be rejected.
const MaxAcceptQueueSize = 32
// CookieExpiryTime is the valid time of a cookie
const CookieExpiryTime = 24 * time.Hour
// TokenExpiryTime is the valid time of a token
const TokenExpiryTime = 24 * time.Hour
// MaxOutstandingSentPackets is maximum number of packets saved for retransmission.
// When reached, it imposes a soft limit on sending new packets:

View file

@ -84,7 +84,7 @@ type server struct {
// If it is started with Listen, we take a packet conn as a parameter.
createdPacketConn bool
cookieGenerator *handshake.CookieGenerator
tokenGenerator *handshake.TokenGenerator
sessionHandler packetHandlerManager
@ -186,19 +186,19 @@ func (s *server) setup() error {
}()
},
}
cookieGenerator, err := handshake.NewCookieGenerator()
tokenGenerator, err := handshake.NewTokenGenerator()
if err != nil {
return err
}
s.cookieGenerator = cookieGenerator
s.tokenGenerator = tokenGenerator
return nil
}
var defaultAcceptCookie = func(clientAddr net.Addr, cookie *Cookie) bool {
if cookie == nil {
var defaultAcceptToken = func(clientAddr net.Addr, token *Token) bool {
if token == nil {
return false
}
if time.Now().After(cookie.SentTime.Add(protocol.CookieExpiryTime)) {
if time.Now().After(token.SentTime.Add(protocol.TokenExpiryTime)) {
return false
}
var sourceAddr string
@ -207,7 +207,7 @@ var defaultAcceptCookie = func(clientAddr net.Addr, cookie *Cookie) bool {
} else {
sourceAddr = clientAddr.String()
}
return sourceAddr == cookie.RemoteAddr
return sourceAddr == token.RemoteAddr
}
// populateServerConfig populates fields in the quic.Config with their default values, if none are set
@ -221,9 +221,9 @@ func populateServerConfig(config *Config) *Config {
versions = protocol.SupportedVersions
}
vsa := defaultAcceptCookie
if config.AcceptCookie != nil {
vsa = config.AcceptCookie
verifyToken := defaultAcceptToken
if config.AcceptToken != nil {
verifyToken = config.AcceptToken
}
handshakeTimeout := protocol.DefaultHandshakeTimeout
@ -264,7 +264,7 @@ func populateServerConfig(config *Config) *Config {
Versions: versions,
HandshakeTimeout: handshakeTimeout,
IdleTimeout: idleTimeout,
AcceptCookie: vsa,
AcceptToken: verifyToken,
KeepAlive: config.KeepAlive,
MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow,
MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow,
@ -381,19 +381,19 @@ func (s *server) handleInitialImpl(p *receivedPacket, hdr *wire.Header) (quicSes
return nil, nil, errors.New("too short connection ID")
}
var cookie *Cookie
var token *Token
var origDestConnectionID protocol.ConnectionID
if len(hdr.Token) > 0 {
c, err := s.cookieGenerator.DecodeToken(hdr.Token)
c, err := s.tokenGenerator.DecodeToken(hdr.Token)
if err == nil {
cookie = &Cookie{
token = &Token{
RemoteAddr: c.RemoteAddr,
SentTime: c.SentTime,
}
origDestConnectionID = c.OriginalDestConnectionID
}
}
if !s.config.AcceptCookie(p.remoteAddr, cookie) {
if !s.config.AcceptToken(p.remoteAddr, token) {
// Log the Initial packet now.
// If no Retry is sent, the packet will be logged by the session.
(&wire.ExtendedHeader{Header: *hdr}).Log(s.logger)
@ -468,7 +468,7 @@ func (s *server) createNewSession(
}
func (s *server) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error {
token, err := s.cookieGenerator.NewToken(remoteAddr, hdr.DestConnectionID)
token, err := s.tokenGenerator.NewToken(remoteAddr, hdr.DestConnectionID)
if err != nil {
return err
}

View file

@ -69,7 +69,7 @@ var _ = Describe("Server", func() {
Expect(server.config.Versions).To(Equal(protocol.SupportedVersions))
Expect(server.config.HandshakeTimeout).To(Equal(protocol.DefaultHandshakeTimeout))
Expect(server.config.IdleTimeout).To(Equal(protocol.DefaultIdleTimeout))
Expect(reflect.ValueOf(server.config.AcceptCookie)).To(Equal(reflect.ValueOf(defaultAcceptCookie)))
Expect(reflect.ValueOf(server.config.AcceptToken)).To(Equal(reflect.ValueOf(defaultAcceptToken)))
Expect(server.config.KeepAlive).To(BeFalse())
// stop the listener
Expect(ln.Close()).To(Succeed())
@ -77,10 +77,10 @@ var _ = Describe("Server", func() {
It("setups with the right values", func() {
supportedVersions := []protocol.VersionNumber{protocol.VersionTLS}
acceptCookie := func(_ net.Addr, _ *Cookie) bool { return true }
acceptToken := func(_ net.Addr, _ *Token) bool { return true }
config := Config{
Versions: supportedVersions,
AcceptCookie: acceptCookie,
AcceptToken: acceptToken,
HandshakeTimeout: 1337 * time.Hour,
IdleTimeout: 42 * time.Minute,
KeepAlive: true,
@ -93,7 +93,7 @@ var _ = Describe("Server", func() {
Expect(server.config.Versions).To(Equal(supportedVersions))
Expect(server.config.HandshakeTimeout).To(Equal(1337 * time.Hour))
Expect(server.config.IdleTimeout).To(Equal(42 * time.Minute))
Expect(reflect.ValueOf(server.config.AcceptCookie)).To(Equal(reflect.ValueOf(acceptCookie)))
Expect(reflect.ValueOf(server.config.AcceptToken)).To(Equal(reflect.ValueOf(acceptToken)))
Expect(server.config.KeepAlive).To(BeTrue())
Expect(server.config.StatelessResetKey).To(Equal([]byte("foobar")))
// stop the listener
@ -179,19 +179,19 @@ var _ = Describe("Server", func() {
))
})
It("decodes the cookie from the Token field", func() {
It("decodes the token from the Token field", func() {
raddr := &net.UDPAddr{
IP: net.IPv4(192, 168, 13, 37),
Port: 1337,
}
done := make(chan struct{})
serv.config.AcceptCookie = func(addr net.Addr, cookie *Cookie) bool {
serv.config.AcceptToken = func(addr net.Addr, token *Token) bool {
Expect(addr).To(Equal(raddr))
Expect(cookie).ToNot(BeNil())
Expect(token).ToNot(BeNil())
close(done)
return false
}
token, err := serv.cookieGenerator.NewToken(raddr, nil)
token, err := serv.tokenGenerator.NewToken(raddr, nil)
Expect(err).ToNot(HaveOccurred())
packet := getPacket(&wire.Header{
IsLongHeader: true,
@ -204,15 +204,15 @@ var _ = Describe("Server", func() {
Eventually(done).Should(BeClosed())
})
It("passes an empty cookie to the callback, if decoding fails", func() {
It("passes an empty token to the callback, if decoding fails", func() {
raddr := &net.UDPAddr{
IP: net.IPv4(192, 168, 13, 37),
Port: 1337,
}
done := make(chan struct{})
serv.config.AcceptCookie = func(addr net.Addr, cookie *Cookie) bool {
serv.config.AcceptToken = func(addr net.Addr, token *Token) bool {
Expect(addr).To(Equal(raddr))
Expect(cookie).To(BeNil())
Expect(token).To(BeNil())
close(done)
return false
}
@ -249,8 +249,8 @@ var _ = Describe("Server", func() {
Expect(hdr.SupportedVersions).ToNot(ContainElement(protocol.VersionNumber(0x42)))
})
It("replies with a Retry packet, if a Cookie is required", func() {
serv.config.AcceptCookie = func(_ net.Addr, _ *Cookie) bool { return false }
It("replies with a Retry packet, if a Token is required", func() {
serv.config.AcceptToken = func(_ net.Addr, _ *Token) bool { return false }
hdr := &wire.Header{
IsLongHeader: true,
Type: protocol.PacketTypeInitial,
@ -272,8 +272,8 @@ var _ = Describe("Server", func() {
Expect(replyHdr.Token).ToNot(BeEmpty())
})
It("creates a session, if no Cookie is required", func() {
serv.config.AcceptCookie = func(_ net.Addr, _ *Cookie) bool { return true }
It("creates a session, if no Token is required", func() {
serv.config.AcceptToken = func(_ net.Addr, _ *Token) bool { return true }
hdr := &wire.Header{
IsLongHeader: true,
Type: protocol.PacketTypeInitial,
@ -320,7 +320,7 @@ var _ = Describe("Server", func() {
})
It("rejects new connection attempts if the accept queue is full", func() {
serv.config.AcceptCookie = func(_ net.Addr, _ *Cookie) bool { return true }
serv.config.AcceptToken = func(_ net.Addr, _ *Token) bool { return true }
senderAddr := &net.UDPAddr{IP: net.IPv4(1, 2, 3, 4), Port: 42}
hdr := &wire.Header{
@ -375,7 +375,7 @@ var _ = Describe("Server", func() {
})
It("doesn't accept new sessions if they were closed in the mean time", func() {
serv.config.AcceptCookie = func(_ net.Addr, _ *Cookie) bool { return true }
serv.config.AcceptToken = func(_ net.Addr, _ *Token) bool { return true }
senderAddr := &net.UDPAddr{IP: net.IPv4(1, 2, 3, 4), Port: 42}
hdr := &wire.Header{
@ -543,51 +543,51 @@ var _ = Describe("Server", func() {
var _ = Describe("default source address verification", func() {
It("accepts a token", func() {
remoteAddr := &net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}
cookie := &Cookie{
token := &Token{
RemoteAddr: "192.168.0.1",
SentTime: time.Now().Add(-protocol.CookieExpiryTime).Add(time.Second), // will expire in 1 second
SentTime: time.Now().Add(-protocol.TokenExpiryTime).Add(time.Second), // will expire in 1 second
}
Expect(defaultAcceptCookie(remoteAddr, cookie)).To(BeTrue())
Expect(defaultAcceptToken(remoteAddr, token)).To(BeTrue())
})
It("requests verification if no token is provided", func() {
remoteAddr := &net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}
Expect(defaultAcceptCookie(remoteAddr, nil)).To(BeFalse())
Expect(defaultAcceptToken(remoteAddr, nil)).To(BeFalse())
})
It("rejects a token if the address doesn't match", func() {
remoteAddr := &net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}
cookie := &Cookie{
token := &Token{
RemoteAddr: "127.0.0.1",
SentTime: time.Now(),
}
Expect(defaultAcceptCookie(remoteAddr, cookie)).To(BeFalse())
Expect(defaultAcceptToken(remoteAddr, token)).To(BeFalse())
})
It("accepts a token for a remote address is not a UDP address", func() {
remoteAddr := &net.TCPAddr{IP: net.IPv4(192, 168, 0, 1), Port: 1337}
cookie := &Cookie{
token := &Token{
RemoteAddr: "192.168.0.1:1337",
SentTime: time.Now(),
}
Expect(defaultAcceptCookie(remoteAddr, cookie)).To(BeTrue())
Expect(defaultAcceptToken(remoteAddr, token)).To(BeTrue())
})
It("rejects an invalid token for a remote address is not a UDP address", func() {
remoteAddr := &net.TCPAddr{IP: net.IPv4(192, 168, 0, 1), Port: 1337}
cookie := &Cookie{
token := &Token{
RemoteAddr: "192.168.0.1:7331", // mismatching port
SentTime: time.Now(),
}
Expect(defaultAcceptCookie(remoteAddr, cookie)).To(BeFalse())
Expect(defaultAcceptToken(remoteAddr, token)).To(BeFalse())
})
It("rejects an expired token", func() {
remoteAddr := &net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}
cookie := &Cookie{
token := &Token{
RemoteAddr: "192.168.0.1",
SentTime: time.Now().Add(-protocol.CookieExpiryTime).Add(-time.Second), // expired 1 second ago
SentTime: time.Now().Add(-protocol.TokenExpiryTime).Add(-time.Second), // expired 1 second ago
}
Expect(defaultAcceptCookie(remoteAddr, cookie)).To(BeFalse())
Expect(defaultAcceptToken(remoteAddr, token)).To(BeFalse())
})
})