Skip to content

Commit 6c9ab43

Browse files
myleshortonclaude
andcommitted
Add HTTPClient and STUNServers to unbounded options
Allow callers to inject an http.Client and a static list of STUN servers into UnboundedOutboundOptions. When HTTPClient is set, it is used directly instead of building one from the sing-box dialer. When STUNServers is set (and STUNBatch is not), a batch function is created that returns from the provided list. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 30145c2 commit 6c9ab43

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

option/unbounded.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package option
22

33
import (
4+
"net/http"
5+
46
"github.com/sagernet/sing-box/option"
57
)
68

@@ -20,12 +22,14 @@ type UnboundedOutboundOptions struct {
2022
BusBufferSz int `json:"bus_buffer_sz,omitempty"`
2123
Netstated string `json:"netstated,omitempty"`
2224
// WebRTCOptions
23-
DiscoverySrv string `json:"discovery_srv,omitempty"`
24-
DiscoveryEndpoint string `json:"discovery_endpoint,omitempty"`
25-
GenesisAddr string `json:"genesis_addr,omitempty"`
26-
NATFailTimeout int `json:"nat_fail_timeout,omitempty"`
27-
STUNBatchSize int `json:"stun_batch_size,omitempty"`
25+
DiscoverySrv string `json:"discovery_srv,omitempty"`
26+
DiscoveryEndpoint string `json:"discovery_endpoint,omitempty"`
27+
GenesisAddr string `json:"genesis_addr,omitempty"`
28+
NATFailTimeout int `json:"nat_fail_timeout,omitempty"`
29+
STUNBatchSize int `json:"stun_batch_size,omitempty"`
30+
STUNServers []string `json:"stun_servers,omitempty"`
2831
STUNBatch func(size uint32) (batch []string, err error)
32+
HTTPClient *http.Client
2933
Tag string `json:"tag,omitempty"`
3034
Patience int `json:"patience,omitempty"`
3135
ErrorBackoff int `json:"error_backoff,omitempty"`

protocol/unbounded/outbound.go

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ func NewOutbound(
102102

103103
if options.STUNBatch != nil {
104104
rtcOpt.STUNBatch = options.STUNBatch
105+
} else if len(options.STUNServers) > 0 {
106+
servers := make([]string, len(options.STUNServers))
107+
copy(servers, options.STUNServers)
108+
rtcOpt.STUNBatch = func(size uint32) ([]string, error) {
109+
if int(size) >= len(servers) {
110+
return servers, nil
111+
}
112+
return servers[:size], nil
113+
}
105114
}
106115

107116
if options.Tag != "" {
@@ -156,16 +165,20 @@ func NewOutbound(
156165
return nil, err
157166
}
158167
rtcOpt.Net = rtcNet
159-
dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) {
160-
return outboundDialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
161-
}
162-
rtcOpt.HTTPClient = &http.Client{
163-
Transport: &http.Transport{
164-
Dial: func(network, addr string) (net.Conn, error) {
165-
return dialContext(ctx, network, addr)
168+
if options.HTTPClient != nil {
169+
rtcOpt.HTTPClient = options.HTTPClient
170+
} else {
171+
dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) {
172+
return outboundDialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
173+
}
174+
rtcOpt.HTTPClient = &http.Client{
175+
Transport: &http.Transport{
176+
Dial: func(network, addr string) (net.Conn, error) {
177+
return dialContext(ctx, network, addr)
178+
},
179+
DialContext: dialContext,
166180
},
167-
DialContext: dialContext,
168-
},
181+
}
169182
}
170183

171184
o := &Outbound{

0 commit comments

Comments
 (0)