1package handshake
2
3import (
4	"github.com/lucas-clemente/quic-go/internal/protocol"
5	"github.com/lucas-clemente/quic-go/internal/qtls"
6)
7
8const (
9	quicTLSExtensionTypeOldDrafts = 0xffa5
10	quicTLSExtensionType          = 0x39
11)
12
13type extensionHandler struct {
14	ourParams  []byte
15	paramsChan chan []byte
16
17	extensionType uint16
18
19	perspective protocol.Perspective
20}
21
22var _ tlsExtensionHandler = &extensionHandler{}
23
24// newExtensionHandler creates a new extension handler
25func newExtensionHandler(params []byte, pers protocol.Perspective, v protocol.VersionNumber) tlsExtensionHandler {
26	et := uint16(quicTLSExtensionType)
27	if v != protocol.Version1 {
28		et = quicTLSExtensionTypeOldDrafts
29	}
30	return &extensionHandler{
31		ourParams:     params,
32		paramsChan:    make(chan []byte),
33		perspective:   pers,
34		extensionType: et,
35	}
36}
37
38func (h *extensionHandler) GetExtensions(msgType uint8) []qtls.Extension {
39	if (h.perspective == protocol.PerspectiveClient && messageType(msgType) != typeClientHello) ||
40		(h.perspective == protocol.PerspectiveServer && messageType(msgType) != typeEncryptedExtensions) {
41		return nil
42	}
43	return []qtls.Extension{{
44		Type: h.extensionType,
45		Data: h.ourParams,
46	}}
47}
48
49func (h *extensionHandler) ReceivedExtensions(msgType uint8, exts []qtls.Extension) {
50	if (h.perspective == protocol.PerspectiveClient && messageType(msgType) != typeEncryptedExtensions) ||
51		(h.perspective == protocol.PerspectiveServer && messageType(msgType) != typeClientHello) {
52		return
53	}
54
55	var data []byte
56	for _, ext := range exts {
57		if ext.Type == h.extensionType {
58			data = ext.Data
59			break
60		}
61	}
62
63	h.paramsChan <- data
64}
65
66func (h *extensionHandler) TransportParameters() <-chan []byte {
67	return h.paramsChan
68}
69