Merge pull request #1943 from lucas-clemente/new-tokens

send NEW_TOKEN frames
This commit is contained in:
Marten Seemann
2019-06-02 14:42:25 +08:00
committed by GitHub
10 changed files with 105 additions and 37 deletions

View File

@@ -16,13 +16,16 @@ const (
// A Token is derived from the client address and can be used to verify the ownership of this address.
type Token struct {
RemoteAddr string
SentTime time.Time
IsRetryToken bool
RemoteAddr string
SentTime time.Time
// only set for retry tokens
OriginalDestConnectionID protocol.ConnectionID
}
// token is the struct that is used for ASN1 serialization and deserialization
type token struct {
IsRetryToken bool
RemoteAddr []byte
Timestamp int64
OriginalDestConnectionID []byte
@@ -44,9 +47,10 @@ func NewTokenGenerator() (*TokenGenerator, error) {
}, nil
}
// NewToken generates a new token for a given source address
func (g *TokenGenerator) NewToken(raddr net.Addr, origConnID protocol.ConnectionID) ([]byte, error) {
// NewRetryToken generates a new token for a Retry for a given source address
func (g *TokenGenerator) NewRetryToken(raddr net.Addr, origConnID protocol.ConnectionID) ([]byte, error) {
data, err := asn1.Marshal(token{
IsRetryToken: true,
RemoteAddr: encodeRemoteAddr(raddr),
OriginalDestConnectionID: origConnID,
Timestamp: time.Now().UnixNano(),
@@ -57,6 +61,18 @@ func (g *TokenGenerator) NewToken(raddr net.Addr, origConnID protocol.Connection
return g.tokenProtector.NewToken(data)
}
// NewToken generates a new token to be sent in a NEW_TOKEN frame
func (g *TokenGenerator) NewToken(raddr net.Addr) ([]byte, error) {
data, err := asn1.Marshal(token{
RemoteAddr: encodeRemoteAddr(raddr),
Timestamp: time.Now().UnixNano(),
})
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
@@ -77,8 +93,9 @@ func (g *TokenGenerator) DecodeToken(encrypted []byte) (*Token, error) {
return nil, fmt.Errorf("rest when unpacking token: %d", len(rest))
}
token := &Token{
RemoteAddr: decodeRemoteAddr(t.RemoteAddr),
SentTime: time.Unix(0, t.Timestamp),
IsRetryToken: t.IsRetryToken,
RemoteAddr: decodeRemoteAddr(t.RemoteAddr),
SentTime: time.Unix(0, t.Timestamp),
}
if len(t.OriginalDestConnectionID) > 0 {
token.OriginalDestConnectionID = protocol.ConnectionID(t.OriginalDestConnectionID)

View File

@@ -22,7 +22,7 @@ var _ = Describe("Token Generator", func() {
It("generates a token", func() {
ip := net.IPv4(127, 0, 0, 1)
token, err := tokenGen.NewToken(&net.UDPAddr{IP: ip, Port: 1337}, nil)
token, err := tokenGen.NewRetryToken(&net.UDPAddr{IP: ip, Port: 1337}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(token).ToNot(BeEmpty())
})
@@ -35,7 +35,7 @@ var _ = Describe("Token Generator", func() {
It("accepts a valid token", func() {
ip := net.IPv4(192, 168, 0, 1)
tokenEnc, err := tokenGen.NewToken(
tokenEnc, err := tokenGen.NewRetryToken(
&net.UDPAddr{IP: ip, Port: 1337},
nil,
)
@@ -48,7 +48,7 @@ var _ = Describe("Token Generator", func() {
})
It("saves the connection ID", func() {
tokenEnc, err := tokenGen.NewToken(
tokenEnc, err := tokenGen.NewRetryToken(
&net.UDPAddr{},
protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
)
@@ -101,7 +101,7 @@ var _ = Describe("Token Generator", func() {
ip := net.ParseIP(addr)
Expect(ip).ToNot(BeNil())
raddr := &net.UDPAddr{IP: ip, Port: 1337}
tokenEnc, err := tokenGen.NewToken(raddr, nil)
tokenEnc, err := tokenGen.NewRetryToken(raddr, nil)
Expect(err).ToNot(HaveOccurred())
token, err := tokenGen.DecodeToken(tokenEnc)
Expect(err).ToNot(HaveOccurred())
@@ -112,7 +112,7 @@ var _ = Describe("Token Generator", func() {
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}
tokenEnc, err := tokenGen.NewToken(raddr, nil)
tokenEnc, err := tokenGen.NewRetryToken(raddr, nil)
Expect(err).ToNot(HaveOccurred())
token, err := tokenGen.DecodeToken(tokenEnc)
Expect(err).ToNot(HaveOccurred())

View File

@@ -57,6 +57,9 @@ const MaxTrackedSkippedPackets = 10
// If the queue is full, new connection attempts will be rejected.
const MaxAcceptQueueSize = 32
// TokenValidity is the duration that a (non-retry) token is considered valid
const TokenValidity = 24 * time.Hour
// RetryTokenValidity is the duration that a retry token is considered valid
const RetryTokenValidity = 10 * time.Second