mirror of
https://github.com/p1neappleXpress/OpenFlux.git
synced 2026-10-26 07:03:17 +08:00
Base is hotfix/oflx-encrypted-logging-context; in every place both trees touched the same code, the hotfix version wins (3-level logger, heard-first routing + MarkStalled, replay window, boards JSON API, robust SOCKS5 auth). Brought over from meepo161/openfluxfork@fork-main (the mobile/ Android bridge is intentionally left in the Android fork): - provision/ + node_wizard.go + --node-wizard: SSH VDS exit-node install. - deploy/node-install.sh + .github/workflows/node-release.yml: pinned, hash-verified node release. - netbind/ + tun_windows.go + --inbound=tun on Windows (Wintun): full tunnel with the core's own sockets bound to the real interface; dial sites in direct/boards/vyandex/cupsonline/mailru/yandex now dial bound. - transport/yandex/cookies.go + --yandex-cookies-file: Netscape cookie import into the shared vyandex jar (sessions and single-transport alike). - yandex: CheckVolgaDocument (doc suitability for the wizard) and the PoW captcha fix (a rejected challenge is a captcha, not a bad document). - --http-proxy: HTTP CONNECT proxy over the same tunnel as SOCKS5. - ipcStatusLoop: per-second IPC Status frame with the active carrier (Session.LiveTransports / ActiveTransport). Builds for darwin, windows and linux; go vet and the full test suite pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
78 lines
2.4 KiB
Go
78 lines
2.4 KiB
Go
// Package netbind keeps the core's own connections off its own tunnel.
|
|
//
|
|
// With the Windows full tunnel (--inbound=tun) the default route points at
|
|
// the OpenFlux adapter, but the carriers (Yandex, the node's direct port)
|
|
// must still leave through the real network, or they would loop into the
|
|
// tunnel they carry. Android gets this by excluding the app from its VPN;
|
|
// here every outbound socket of the core is bound to the physical
|
|
// interface instead (IP_UNICAST_IF), which holds whatever the routes say.
|
|
// Dial sites use Dialer or DialContext; Bind also covers the defaults
|
|
// (http.DefaultTransport, websocket.DefaultDialer, net.DefaultResolver).
|
|
package netbind
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"net/http"
|
|
"sync/atomic"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
type controlFunc = func(network, address string, c syscall.RawConn) error
|
|
|
|
var current atomic.Pointer[controlFunc]
|
|
|
|
// control applies the current binding, if any.
|
|
func control(network, address string, c syscall.RawConn) error {
|
|
if f := current.Load(); f != nil {
|
|
return (*f)(network, address, c)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Dialer is a net.Dialer that follows the binding.
|
|
func Dialer(timeout time.Duration) *net.Dialer {
|
|
return Wrap(&net.Dialer{Timeout: timeout, KeepAlive: 30 * time.Second})
|
|
}
|
|
|
|
// Wrap makes d follow the binding (keeping its own Control, if any).
|
|
func Wrap(d *net.Dialer) *net.Dialer {
|
|
own := d.Control
|
|
d.Control = func(network, address string, c syscall.RawConn) error {
|
|
if own != nil {
|
|
if err := own(network, address, c); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return control(network, address, c)
|
|
}
|
|
return d
|
|
}
|
|
|
|
// DialContext dials with a default Dialer (30 s timeout).
|
|
func DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
|
return Dialer(30*time.Second).DialContext(ctx, network, address)
|
|
}
|
|
|
|
// Bound reports whether sockets are bound to an interface now.
|
|
func Bound() bool { return current.Load() != nil }
|
|
|
|
// install sets the binding and points the standard library's defaults at
|
|
// bound dialers, so code that never names a dialer is covered too.
|
|
func install(f controlFunc) {
|
|
current.Store(&f)
|
|
if t, ok := http.DefaultTransport.(*http.Transport); ok {
|
|
t.DialContext = DialContext
|
|
}
|
|
websocket.DefaultDialer.NetDialContext = DialContext
|
|
net.DefaultResolver = &net.Resolver{
|
|
PreferGo: true,
|
|
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
|
return Dialer(10*time.Second).DialContext(ctx, network, address)
|
|
},
|
|
}
|
|
}
|