mirror of
https://github.com/pion/webrtc.git
synced 2025-09-26 19:21:12 +08:00
Finish ICE implementation
This commit is contained in:
60
ice_helper.go
Normal file
60
ice_helper.go
Normal 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
|
||||
}
|
7
main.go
7
main.go
@@ -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 {}
|
||||
}
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user