client,proxy: add a media channel

This commit is contained in:
KokaKiwi 2025-08-09 14:11:54 +02:00
parent 70974640ab
commit 0a7291e90f
No known key found for this signature in database
GPG key ID: FD333F84686EFE78
3 changed files with 70 additions and 0 deletions

View file

@ -1,7 +1,9 @@
package snowflake_client
import (
"crypto/rand"
"log"
"math/big"
"time"
)
@ -69,3 +71,12 @@ func (b *bytesSyncLogger) addOutbound(amount int64) {
func (b *bytesSyncLogger) addInbound(amount int64) {
b.inboundChan <- amount
}
func randomInt(min, max int) int {
nBig, err := rand.Int(rand.Reader, big.NewInt(int64(max-min)))
if err != nil {
panic(err)
}
return int(nBig.Int64()) + min
}

View file

@ -15,6 +15,7 @@ import (
"github.com/pion/transport/v3"
"github.com/pion/transport/v3/stdnet"
"github.com/pion/webrtc/v4"
"github.com/pion/webrtc/v4/pkg/media"
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/event"
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/proxy"
@ -296,6 +297,7 @@ func (c *WebRTCPeer) preparePeerConnection(
log.Printf("NewPeerConnection ERROR: %s", err)
return err
}
ordered := true
dataChannelOptions := &webrtc.DataChannelInit{
Ordered: &ordered,
@ -340,6 +342,8 @@ func (c *WebRTCPeer) preparePeerConnection(
c.open = make(chan struct{})
log.Println("WebRTC: DataChannel created")
c.openMediaTrack()
offer, err := c.pc.CreateOffer(nil)
// TODO: Potentially timeout and retry if ICE isn't working.
if err != nil {
@ -365,6 +369,48 @@ func (c *WebRTCPeer) preparePeerConnection(
return nil
}
func (c *WebRTCPeer) openMediaTrack() {
videoTrack, err := webrtc.NewTrackLocalStaticSample(
webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeAV1}, "video", "pion",
)
if err != nil {
log.Printf("webrtc.NewTrackLocalStaticSample ERROR: %s", err)
return
}
rtpSender, err := c.pc.AddTrack(videoTrack)
if err != nil {
log.Printf("webrtc.AddTrack ERROR: %s", err)
return
}
go func() {
rtcpBuf := make([]byte, 1500)
for {
if _, _, rtcpErr := rtpSender.Read(rtcpBuf); rtcpErr != nil {
return
}
}
}()
go func() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for ; true; <-ticker.C {
bufSize := randomInt(1000, 2500)
buf := make([]byte, bufSize)
err := videoTrack.WriteSample(media.Sample{Data: buf, Duration: time.Second})
if err != nil {
log.Printf("webrtc.WriteSample ERROR: %s", err)
}
}
}()
log.Println("WebRTC: Media track opened")
}
// cleanup closes all channels and transports
func (c *WebRTCPeer) cleanup() {
// Close this side of the SOCKS pipe.

View file

@ -451,6 +451,19 @@ func (sf *SnowflakeProxy) makePeerConnectionFromOffer(
return nil, fmt.Errorf("accept: NewPeerConnection: %s", err)
}
pc.OnTrack(func(remote *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {
log.Printf("Track has started streamId(%s) id(%s) rid(%s) \n", remote.StreamID(), remote.ID(), remote.RID())
for {
rtcpBuf := make([]byte, 1500)
for {
if _, _, err := receiver.Read(rtcpBuf); err != nil {
return
}
}
}
})
pc.OnDataChannel(func(dc *webrtc.DataChannel) {
log.Printf("New Data Channel %s-%d\n", dc.Label(), dc.ID())
close(dataChan)