mirror of
https://github.com/openlibrecommunity/olcrtc.git
synced 2026-06-01 22:18:52 +02:00
Update olcRTC mobile bridge
This commit is contained in:
@@ -32,6 +32,10 @@ type Client struct {
|
||||
}
|
||||
|
||||
func Run(ctx context.Context, roomURL, keyHex string, socksPort int, duo bool, socksUser, socksPass string) error {
|
||||
return RunWithReady(ctx, roomURL, keyHex, socksPort, duo, socksUser, socksPass, nil)
|
||||
}
|
||||
|
||||
func RunWithReady(ctx context.Context, roomURL, keyHex string, socksPort int, duo bool, socksUser, socksPass string, onReady func()) error {
|
||||
runCtx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
@@ -159,7 +163,7 @@ func Run(ctx context.Context, roomURL, keyHex string, socksPort int, duo bool, s
|
||||
log.Printf("Sent reset signal to server (clientID=%d)", c.clientID)
|
||||
}
|
||||
|
||||
err = c.runSOCKS5(runCtx, socksPort, socksUser, socksPass)
|
||||
err = c.runSOCKS5(runCtx, socksPort, socksUser, socksPass, onReady)
|
||||
|
||||
log.Println("Waiting for client goroutines...")
|
||||
c.wg.Wait()
|
||||
@@ -178,13 +182,16 @@ func (c *Client) onData(data []byte) {
|
||||
c.mux.HandleFrame(plaintext)
|
||||
}
|
||||
|
||||
func (c *Client) runSOCKS5(ctx context.Context, port int, username, password string) error {
|
||||
func (c *Client) runSOCKS5(ctx context.Context, port int, username, password string, onReady func()) error {
|
||||
listener, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("SOCKS5 proxy listening on 127.0.0.1:%d (auth=%v)", port, username != "")
|
||||
if onReady != nil {
|
||||
onReady()
|
||||
}
|
||||
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
package mux
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseControlFrame(t *testing.T) {
|
||||
frame := BuildControlFrame(42, ControlResetClient)
|
||||
|
||||
control, ok := ParseControlFrame(frame)
|
||||
if !ok {
|
||||
t.Fatal("expected control frame")
|
||||
}
|
||||
if control.ClientID != 42 {
|
||||
t.Fatalf("ClientID = %d, want 42", control.ClientID)
|
||||
}
|
||||
if control.Type != ControlResetClient {
|
||||
t.Fatalf("Type = %d, want %d", control.Type, ControlResetClient)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleControlResetClient(t *testing.T) {
|
||||
m := New(0, func([]byte) error { return nil })
|
||||
|
||||
dataFrame := make([]byte, 13)
|
||||
binary.BigEndian.PutUint32(dataFrame[0:4], 42)
|
||||
binary.BigEndian.PutUint16(dataFrame[4:6], 7)
|
||||
binary.BigEndian.PutUint16(dataFrame[6:8], 1)
|
||||
binary.BigEndian.PutUint32(dataFrame[8:12], 0)
|
||||
dataFrame[12] = 0xAA
|
||||
|
||||
m.HandleFrame(dataFrame)
|
||||
if stream := m.GetStream(7); stream == nil {
|
||||
t.Fatal("expected data stream before reset")
|
||||
}
|
||||
|
||||
m.HandleFrame(BuildControlFrame(42, ControlResetClient))
|
||||
if stream := m.GetStream(7); stream != nil {
|
||||
t.Fatal("expected data stream to be removed by client reset")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendClientReset(t *testing.T) {
|
||||
var sent []byte
|
||||
m := New(99, func(frame []byte) error {
|
||||
sent = append([]byte(nil), frame...)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := m.SendClientReset(); err != nil {
|
||||
t.Fatalf("SendClientReset failed: %v", err)
|
||||
}
|
||||
control, ok := ParseControlFrame(sent)
|
||||
if !ok {
|
||||
t.Fatal("expected sent control frame")
|
||||
}
|
||||
if control.ClientID != 99 || control.Type != ControlResetClient {
|
||||
t.Fatalf("control = %#v", control)
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package names
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGenerateFallsBackWhenListsAreEmpty(t *testing.T) {
|
||||
oldFirst := firstNames
|
||||
oldLast := lastNames
|
||||
defer func() {
|
||||
firstNames = oldFirst
|
||||
lastNames = oldLast
|
||||
}()
|
||||
|
||||
firstNames = nil
|
||||
lastNames = nil
|
||||
|
||||
if got := Generate(); got == "" {
|
||||
t.Fatal("Generate returned an empty display name")
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package telemost
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestIsConferenceEndMessage(t *testing.T) {
|
||||
tests := []map[string]interface{}{
|
||||
{"conferenceEnded": map[string]interface{}{}},
|
||||
{"conference": map[string]interface{}{"state": "closed"}},
|
||||
{"conferenceState": map[string]interface{}{"state": "TERMINATED"}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
if !isConferenceEndMessage(tt) {
|
||||
t.Fatalf("expected end message for %#v", tt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsConferenceEndMessageIgnoresActiveState(t *testing.T) {
|
||||
msg := map[string]interface{}{
|
||||
"conference": map[string]interface{}{"state": "active"},
|
||||
}
|
||||
if isConferenceEndMessage(msg) {
|
||||
t.Fatal("active conference state must not be treated as ended")
|
||||
}
|
||||
}
|
||||
+65
-4
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/openlibrecommunity/olcrtc/internal/client"
|
||||
"github.com/openlibrecommunity/olcrtc/internal/logger"
|
||||
@@ -27,7 +28,9 @@ type LogWriter interface {
|
||||
var (
|
||||
mu sync.Mutex
|
||||
cancel context.CancelFunc
|
||||
done chan error
|
||||
done chan struct{}
|
||||
ready chan struct{}
|
||||
runErr error
|
||||
)
|
||||
|
||||
// SetProtector sets the Android VPN socket protector.
|
||||
@@ -84,19 +87,77 @@ func Start(roomID, keyHex string, socksPort int, duo bool, socksUser, socksPass
|
||||
|
||||
ctx, c := context.WithCancel(context.Background())
|
||||
cancel = c
|
||||
done = make(chan error, 1)
|
||||
done = make(chan struct{})
|
||||
ready = make(chan struct{})
|
||||
localReady := ready
|
||||
runErr = nil
|
||||
|
||||
var readyOnce sync.Once
|
||||
|
||||
go func() {
|
||||
err := client.Run(ctx, roomURL, keyHex, socksPort, duo, socksUser, socksPass)
|
||||
err := client.RunWithReady(ctx, roomURL, keyHex, socksPort, duo, socksUser, socksPass, func() {
|
||||
readyOnce.Do(func() {
|
||||
close(localReady)
|
||||
})
|
||||
})
|
||||
mu.Lock()
|
||||
cancel = nil
|
||||
runErr = err
|
||||
mu.Unlock()
|
||||
done <- err
|
||||
close(done)
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitReady blocks until the Telemost peers are connected and the local SOCKS5 listener is ready.
|
||||
func WaitReady(timeoutMillis int) error {
|
||||
mu.Lock()
|
||||
r := ready
|
||||
d := done
|
||||
err := runErr
|
||||
running := cancel != nil
|
||||
mu.Unlock()
|
||||
|
||||
if r == nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("olcRTC is not running")
|
||||
}
|
||||
|
||||
select {
|
||||
case <-r:
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
|
||||
if !running {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("olcRTC stopped before becoming ready")
|
||||
}
|
||||
|
||||
timer := time.NewTimer(time.Duration(timeoutMillis) * time.Millisecond)
|
||||
defer timer.Stop()
|
||||
|
||||
select {
|
||||
case <-r:
|
||||
return nil
|
||||
case <-d:
|
||||
mu.Lock()
|
||||
err := runErr
|
||||
mu.Unlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("olcRTC stopped before becoming ready")
|
||||
case <-timer.C:
|
||||
return fmt.Errorf("olcRTC start timed out")
|
||||
}
|
||||
}
|
||||
|
||||
// Stop gracefully stops the olcRTC client.
|
||||
func Stop() {
|
||||
mu.Lock()
|
||||
|
||||
Reference in New Issue
Block a user