Skip to content

Commit 9db84b5

Browse files
committedAug 27, 2023
Add CID based datagram routing
Adds functions to route datagrams and identify connections by DTLS 1.2 Connection IDs. Signed-off-by: Daniel Mangum <[email protected]>
1 parent a8998af commit 9db84b5

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed
 

‎connection_id.go

+74-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33

44
package dtls
55

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+
)
714

815
// RandomCIDGenerator is a random Connection ID generator where CID is the
916
// specified size. Specifying a size of 0 will indicate to peers that sending a
@@ -26,3 +33,69 @@ func OnlySendCIDGenerator() func() []byte {
2633
return nil
2734
}
2835
}
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+
}

‎go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/pion/dtls/v2
33
require (
44
github.com/pion/logging v0.2.2
55
github.com/pion/transport/v2 v2.2.2-0.20230802201558-f2dffd80896b
6+
github.com/stretchr/testify v1.8.4
67
golang.org/x/crypto v0.12.0
78
golang.org/x/net v0.13.0
89
)

0 commit comments

Comments
 (0)
Please sign in to comment.