mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-08-24 02:53:20 +03:00
Add call protocol, Rmux. Update AmneziaWG. Fixes and improvements
This commit is contained in:
139
transport/call/dion/connect.go
Normal file
139
transport/call/dion/connect.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package dion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/transport/call/common"
|
||||
"github.com/sagernet/sing-box/transport/call/tunnel"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
func ConnectCreator(ctx context.Context, cookieStr, roomID, email, password string, readBuf int, dialer N.Dialer, logger logger.ContextLogger) (*tunnel.RelayBridge, string, error) {
|
||||
auth, err := NewSession(dialer)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("dion: new session: %w", err)
|
||||
}
|
||||
if err := auth.LoadCookieString(cookieStr); err != nil {
|
||||
return nil, "", fmt.Errorf("dion: load cookies: %w", err)
|
||||
}
|
||||
auth.SetCredentials(email, password)
|
||||
if err := auth.EnsureValidToken(); err != nil {
|
||||
return nil, "", fmt.Errorf("dion: ensure valid token: %w", err)
|
||||
}
|
||||
requestedRoom := ParseRoom(roomID)
|
||||
var event *EventInfo
|
||||
if requestedRoom != "" {
|
||||
event, err = auth.GetEventBySlug(requestedRoom)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("dion: get event by slug: %w", err)
|
||||
}
|
||||
} else {
|
||||
event, err = auth.CreateRoom()
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("dion: create room: %w", err)
|
||||
}
|
||||
}
|
||||
joinLink := WebBase + "/event/" + event.Slug
|
||||
if readBuf <= 0 {
|
||||
readBuf = 32768
|
||||
}
|
||||
obf, err := tunnel.NewTunnelObfuscator(tunnel.DeriveSecretFromJoinLink(event.Slug))
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("dion: obfuscator init: %w", err)
|
||||
}
|
||||
relayCh := make(chan *tunnel.RelayBridge, 1)
|
||||
var activeRelay *tunnel.RelayBridge
|
||||
call := NewCall(CallConfig{
|
||||
Auth: auth,
|
||||
Event: event,
|
||||
Obfuscator: obf,
|
||||
DisplayName: "Creator",
|
||||
Logger: logger,
|
||||
Dialer: dialer,
|
||||
Role: RoleCreator,
|
||||
})
|
||||
call.OnConnected = func(tun tunnel.DataTunnel) {
|
||||
if activeRelay != nil {
|
||||
activeRelay.Reset()
|
||||
}
|
||||
bridgeReadBuf := common.VP8BufSize
|
||||
if _, ok := tun.(*tunnel.DCTunnel); ok {
|
||||
bridgeReadBuf = readBuf
|
||||
}
|
||||
activeRelay = tunnel.NewRelayBridge(tun, "creator", bridgeReadBuf, dialer, logger)
|
||||
activeRelay.MarkReady()
|
||||
select {
|
||||
case relayCh <- activeRelay:
|
||||
default:
|
||||
}
|
||||
}
|
||||
call.OnPeerRestart = func() {
|
||||
if activeRelay != nil {
|
||||
activeRelay.Reset()
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
if err := call.Start(); err != nil {
|
||||
logger.Error(fmt.Sprintf("dion: call start failed: %v", err))
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case relay := <-relayCh:
|
||||
return relay, joinLink, nil
|
||||
case <-ctx.Done():
|
||||
call.Close()
|
||||
return nil, "", ctx.Err()
|
||||
case <-time.After(60 * time.Second):
|
||||
call.Close()
|
||||
return nil, "", fmt.Errorf("dion: creator tunnel timed out")
|
||||
}
|
||||
}
|
||||
|
||||
func ConnectJoiner(ctx context.Context, roomID, displayName string, readBuf int, dialer N.Dialer, logger logger.ContextLogger) (tunnel.DataTunnel, error) {
|
||||
if displayName == "" {
|
||||
displayName = "Joiner"
|
||||
}
|
||||
slug := ParseRoom(roomID)
|
||||
if slug == "" {
|
||||
return nil, fmt.Errorf("dion: missing room")
|
||||
}
|
||||
auth, event, err := JoinAsGuest(dialer, slug, displayName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("dion: join as guest: %w", err)
|
||||
}
|
||||
obf, err := tunnel.NewTunnelObfuscator(tunnel.DeriveSecretFromJoinLink(event.Slug))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("dion: obfuscator init: %w", err)
|
||||
}
|
||||
call := NewCall(CallConfig{
|
||||
Auth: auth,
|
||||
Event: event,
|
||||
Obfuscator: obf,
|
||||
DisplayName: displayName,
|
||||
Logger: logger,
|
||||
Dialer: dialer,
|
||||
Role: RoleJoiner,
|
||||
})
|
||||
tunCh := make(chan tunnel.DataTunnel, 1)
|
||||
call.OnConnected = func(tun tunnel.DataTunnel) {
|
||||
select {
|
||||
case tunCh <- tun:
|
||||
default:
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
if err := call.Start(); err != nil {
|
||||
logger.Error(fmt.Sprintf("dion: call start failed: %v", err))
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case tun := <-tunCh:
|
||||
return tun, nil
|
||||
case <-ctx.Done():
|
||||
call.Close()
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user