3
3
4
4
package dtls
5
5
6
- import "crypto/rand"
6
+ import (
7
+ "crypto/rand"
8
+
9
+ "github.com/pion/dtls/v2/pkg/protocol"
10
+ "github.com/pion/dtls/v2/pkg/protocol/extension"
11
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
12
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
13
+ )
7
14
8
15
// RandomCIDGenerator is a random Connection ID generator where CID is the
9
16
// specified size. Specifying a size of 0 will indicate to peers that sending a
@@ -26,3 +33,69 @@ func OnlySendCIDGenerator() func() []byte {
26
33
return nil
27
34
}
28
35
}
36
+
37
+ // cidDatagramRouter extracts connection IDs from incoming datagram payloads and
38
+ // uses them to route to the proper connection.
39
+ // NOTE: properly routing datagrams based on connection IDs requires using
40
+ // constant size connection IDs.
41
+ func cidDatagramRouter (size int ) func ([]byte ) (string , bool ) {
42
+ return func (packet []byte ) (string , bool ) {
43
+ pkts , err := recordlayer .ContentAwareUnpackDatagram (packet , size )
44
+ if err != nil || len (pkts ) < 1 {
45
+ return "" , false
46
+ }
47
+ for _ , pkt := range pkts {
48
+ h := & recordlayer.Header {
49
+ ConnectionID : make ([]byte , size ),
50
+ }
51
+ if err := h .Unmarshal (pkt ); err != nil {
52
+ continue
53
+ }
54
+ if h .ContentType != protocol .ContentTypeConnectionID {
55
+ continue
56
+ }
57
+ return string (h .ConnectionID ), true
58
+ }
59
+ return "" , false
60
+ }
61
+ }
62
+
63
+ // cidConnIdentifier extracts connection IDs from outgoing ServerHello records
64
+ // and associates them with the associated connection.
65
+ // NOTE: a ServerHello should always be the first record in a datagram if
66
+ // multiple are present, so we avoid iterating through all packets if the first
67
+ // is not a ServerHello.
68
+ func cidConnIdentifier () func ([]byte ) (string , bool ) {
69
+ return func (packet []byte ) (string , bool ) {
70
+ pkts , err := recordlayer .UnpackDatagram (packet )
71
+ if err != nil || len (pkts ) < 1 {
72
+ return "" , false
73
+ }
74
+ var h recordlayer.Header
75
+ if hErr := h .Unmarshal (pkts [0 ]); hErr != nil {
76
+ return "" , false
77
+ }
78
+ if h .ContentType != protocol .ContentTypeHandshake {
79
+ return "" , false
80
+ }
81
+ var hh handshake.Header
82
+ var sh handshake.MessageServerHello
83
+ for _ , pkt := range pkts {
84
+ if hhErr := hh .Unmarshal (pkt [recordlayer .FixedHeaderSize :]); hhErr != nil {
85
+ continue
86
+ }
87
+ if err = sh .Unmarshal (pkt [recordlayer .FixedHeaderSize + handshake .HeaderLength :]); err == nil {
88
+ break
89
+ }
90
+ }
91
+ if err != nil {
92
+ return "" , false
93
+ }
94
+ for _ , ext := range sh .Extensions {
95
+ if e , ok := ext .(* extension.ConnectionID ); ok {
96
+ return string (e .CID ), true
97
+ }
98
+ }
99
+ return "" , false
100
+ }
101
+ }
0 commit comments