forked from libp2p/go-libp2p
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sdp.go
143 lines (130 loc) · 3.29 KB
/
sdp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package libp2pwebrtc
import (
"crypto"
"fmt"
"net"
"strings"
"github.com/multiformats/go-multihash"
)
// clientSDP describes an SDP format string which can be used
// to infer a client's SDP offer from the incoming STUN message.
// The fingerprint used to render a client SDP is arbitrary since
// it fingerprint verification is disabled in favour of a noise
// handshake. The max message size is fixed to 16384 bytes.
const clientSDP = `v=0
o=- 0 0 IN %[1]s %[2]s
s=-
c=IN %[1]s %[2]s
t=0 0
m=application %[3]d UDP/DTLS/SCTP webrtc-datachannel
a=mid:0
a=ice-options:ice2
a=ice-ufrag:%[4]s
a=ice-pwd:%[4]s
a=fingerprint:sha-256 ba:78:16:bf:8f:01:cf:ea:41:41:40:de:5d:ae:22:23:b0:03:61:a3:96:17:7a:9c:b4:10:ff:61:f2:00:15:ad
a=setup:actpass
a=sctp-port:5000
a=max-message-size:16384
`
func createClientSDP(addr *net.UDPAddr, ufrag string) string {
ipVersion := "IP4"
if addr.IP.To4() == nil {
ipVersion = "IP6"
}
return fmt.Sprintf(
clientSDP,
ipVersion,
addr.IP,
addr.Port,
ufrag,
)
}
// serverSDP defines an SDP format string used by a dialer
// to infer the SDP answer of a server based on the provided
// multiaddr, and the locally set ICE credentials. The max
// message size is fixed to 16384 bytes.
const serverSDP = `v=0
o=- 0 0 IN %[1]s %[2]s
s=-
t=0 0
a=ice-lite
m=application %[3]d UDP/DTLS/SCTP webrtc-datachannel
c=IN %[1]s %[2]s
a=mid:0
a=ice-options:ice2
a=ice-ufrag:%[4]s
a=ice-pwd:%[4]s
a=fingerprint:%[5]s
a=setup:passive
a=sctp-port:5000
a=max-message-size:16384
a=candidate:1 1 UDP 1 %[2]s %[3]d typ host
a=end-of-candidates
`
func createServerSDP(addr *net.UDPAddr, ufrag string, fingerprint multihash.DecodedMultihash) (string, error) {
ipVersion := "IP4"
if addr.IP.To4() == nil {
ipVersion = "IP6"
}
sdpString, err := getSupportedSDPString(fingerprint.Code)
if err != nil {
return "", err
}
var builder strings.Builder
builder.Grow(len(fingerprint.Digest)*3 + 8)
builder.WriteString(sdpString)
builder.WriteByte(' ')
builder.WriteString(encodeInterspersedHex(fingerprint.Digest))
fp := builder.String()
return fmt.Sprintf(
serverSDP,
ipVersion,
addr.IP,
addr.Port,
ufrag,
fp,
), nil
}
// getSupportedSDPHash converts a multihash code to the
// corresponding crypto.Hash for supported protocols. If a
// crypto.Hash cannot be found, it returns `(0, false)`
func getSupportedSDPHash(code uint64) (crypto.Hash, bool) {
switch code {
case multihash.MD5:
return crypto.MD5, true
case multihash.SHA1:
return crypto.SHA1, true
case multihash.SHA3_224:
return crypto.SHA3_224, true
case multihash.SHA2_256:
return crypto.SHA256, true
case multihash.SHA3_384:
return crypto.SHA3_384, true
case multihash.SHA2_512:
return crypto.SHA512, true
default:
return 0, false
}
}
// getSupportedSDPString converts a multihash code
// to a string format recognised by pion for fingerprint
// algorithms
func getSupportedSDPString(code uint64) (string, error) {
// values based on (cryto.Hash).String()
switch code {
case multihash.MD5:
return "md5", nil
case multihash.SHA1:
return "sha-1", nil
case multihash.SHA3_224:
return "sha3-224", nil
case multihash.SHA2_256:
return "sha-256", nil
case multihash.SHA3_384:
return "sha3-384", nil
case multihash.SHA2_512:
return "sha-512", nil
default:
return "", fmt.Errorf("unsupported hash code (%d)", code)
}
}