Finish ICE implementation

This commit is contained in:
Sean DuBois
2018-05-30 22:49:59 -07:00
parent 6d30c80c51
commit 1a1db71e99
3 changed files with 79 additions and 3 deletions

60
ice_helper.go Normal file
View File

@@ -0,0 +1,60 @@
package main
import (
"fmt"
"net"
"github.com/pions/pkg/stun"
"golang.org/x/net/ipv4"
)
func packetHandler(relaySocket *ipv4.PacketConn, remoteKey [16]byte) {
const MTU = 1500
buffer := make([]byte, MTU)
for {
n, _, srcAddr, _ := relaySocket.ReadFrom(buffer)
if packetType, err := stun.GetPacketType(buffer[:n]); err == nil && packetType == stun.PacketTypeSTUN {
if m, err := stun.NewMessage(buffer[:n]); err == nil && m.Class == stun.ClassRequest && m.Method == stun.MethodBinding {
dstAddr := &stun.TransportAddr{IP: srcAddr.(*net.UDPAddr).IP, Port: srcAddr.(*net.UDPAddr).Port}
err := stun.BuildAndSend(relaySocket, dstAddr, stun.ClassSuccessResponse, stun.MethodBinding, m.TransactionID,
&stun.XorMappedAddress{
XorAddress: stun.XorAddress{
IP: dstAddr.IP,
Port: dstAddr.Port,
},
},
&stun.MessageIntegrity{
Key: remoteKey,
},
&stun.Fingerprint{},
)
if err != nil {
fmt.Println(err)
}
}
}
}
}
func udpListener(ip string, remoteKey [16]byte) (int, error) {
listener, err := net.ListenPacket("udp4", ip+":0")
if err != nil {
return 0, err
}
relaySocket := ipv4.NewPacketConn(listener)
err = relaySocket.SetControlMessage(ipv4.FlagDst, true)
if err != nil {
return 0, err
}
addr, err := stun.NewTransportAddr(listener.LocalAddr())
go packetHandler(relaySocket, remoteKey)
return addr.Port, err
}

View File

@@ -1,12 +1,19 @@
package main
import (
"bufio"
"encoding/base64"
"fmt"
"os"
)
func main() {
fmt.Print("base64 encoded Session Description: ")
text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
fmt.Println(text)
a := generateVP8OnlyAnswer().Marshal()
fmt.Println(a)
fmt.Println(base64.StdEncoding.EncodeToString([]byte(a)))
select {}
}

View File

@@ -1,6 +1,7 @@
package main
import (
"crypto/md5"
"fmt"
"math/rand"
"net"
@@ -13,6 +14,9 @@ import (
// TODO RTCPeerConnection.localDescription()
func generateVP8OnlyAnswer() *sdp.SessionDescription {
iceUsername := randSeq(16)
icePassword := randSeq(32)
videoMediaDescription := &sdp.MediaDescription{
MediaName: "video 7 RTP/SAVPF 96 97",
ConnectionData: "IN IP4 127.0.0.1",
@@ -30,8 +34,8 @@ func generateVP8OnlyAnswer() *sdp.SessionDescription {
"setup:active",
"mid:video",
"recvonly",
"ice-ufrag:" + randSeq(16),
"ice-pwd:" + randSeq(32),
"ice-ufrag:" + iceUsername,
"ice-pwd:" + icePassword,
"ice-options:renomination",
"rtcp-mux",
"rtcp-rsize",
@@ -40,8 +44,13 @@ func generateVP8OnlyAnswer() *sdp.SessionDescription {
// Generate only UDP host candidates for ICE
basePriority := uint16(rand.Uint32() & (1<<16 - 1))
dstPort := 1816
remoteKey := md5.Sum([]byte(iceUsername + ":" + icePassword))
for id, c := range hostCandidates() {
dstPort, err := udpListener(c, remoteKey)
if err != nil {
panic(err)
}
videoMediaDescription.Attributes = append(videoMediaDescription.Attributes, fmt.Sprintf("candidate:udpcandidate %d udp %d %s %d typ host", id, basePriority, c, dstPort))
basePriority = basePriority + 1