Skip to content

Commit 01e1d0b

Browse files
committed
ipn,tun2socks: ControlledRouter api for connectivity checks
1 parent 0dfe46d commit 01e1d0b

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

intra/ipn/exit.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ package ipn
88

99
import (
1010
"context"
11+
"encoding/hex"
12+
"math/rand/v2"
13+
"net"
1114
"strconv"
1215

1316
x "github.com/celzero/firestack/intra/backend"
@@ -17,7 +20,14 @@ import (
1720
"github.com/celzero/firestack/intra/protect"
1821
)
1922

20-
const fakeExitAddr = "127.0.0.127:1337"
23+
const (
24+
fakeExitAddr = "127.0.0.127"
25+
fakeExitPort = "1337"
26+
)
27+
28+
var (
29+
fakeExitAddrPort = net.JoinHostPort(fakeExitAddr, fakeExitPort)
30+
)
2131

2232
// exit is a proxy that always dials out to the internet.
2333
type exit struct {
@@ -37,6 +47,16 @@ func NewExitProxy(ctx context.Context, c protect.Controller) *exit {
3747
return newExitProxy(Exit, fakeExitAddr, ctx, c)
3848
}
3949

50+
func NewExitProxyWithID(id, addr string, ctx context.Context, c protect.Controller) *exit {
51+
if len(id) <= 0 {
52+
id = hex8()
53+
}
54+
if len(addr) <= 0 {
55+
addr = net.JoinHostPort(fakeExitAddr, no65535())
56+
}
57+
return newExitProxy(id, addr, ctx, c)
58+
}
59+
4060
func newExitProxy(id, addr string, ctx context.Context, c protect.Controller) *exit {
4161
ctx, done := context.WithCancel(ctx)
4262
h := &exit{
@@ -179,3 +199,17 @@ func idstr(p x.Proxy) string {
179199
}
180200
return p.ID()
181201
}
202+
203+
// create a random hex character string of length 8
204+
func hex8() string {
205+
b := make([]byte, 4)
206+
if _, err := rand.Read(b); err != nil {
207+
return "deadbeef"
208+
}
209+
return hex.EncodeToString(b)
210+
}
211+
212+
func no65535() string {
213+
no := max(rand.IntN(65535), 1024)
214+
return strconv.Itoa(no)
215+
}

intra/tun2socks.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
package intra
2525

2626
import (
27+
"context"
2728
"os"
2829
"path/filepath"
2930
"runtime/debug"
3031

3132
x "github.com/celzero/firestack/intra/backend"
3233
"github.com/celzero/firestack/intra/core"
34+
"github.com/celzero/firestack/intra/ipn"
3335
"github.com/celzero/firestack/intra/rnet"
3436
"github.com/celzero/firestack/intra/settings"
3537

@@ -77,6 +79,14 @@ func Connect(fd, mtu int, fakedns string, dtr DefaultDNS, bdg Bridge) (t Tunnel,
7779
return NewTunnel(fd, mtu, fakedns, dtr, bdg)
7880
}
7981

82+
// ControlledRouter creates a [backend.Router] over a [backend.Internet] proxy (like [backend.Exit]),
83+
// but one that uses custom Controller c. id and addrport are used only for
84+
// diagnostics and logging, and could be left empty. Typical usage is to use
85+
// Router.Reaches() to check if a host:port is reachable over this Controller c.
86+
func ControlledRouter(c Controller, id, addrport string) x.Router {
87+
return ipn.NewExitProxyWithID(id, addrport, context.Background(), c).Router()
88+
}
89+
8090
// Change log level to very verbose (0), verbose (1), debug (2), info (3), warn (4), error (5),
8191
// stacktraces (6), user notifications (7), or no logs (8). gologLevel and consolelogLevel can
8292
// be set independently; ex: LogLevel(2, 6) or LogLevel(8, 0) etc.

0 commit comments

Comments
 (0)