mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2024-11-27 12:05:23 +00:00
support socks proxy in peer url and decouple explicit tor/i2p routing
This commit is contained in:
parent
769b058004
commit
7756891510
@ -19,7 +19,6 @@ type Core struct {
|
|||||||
tun tunDevice
|
tun tunDevice
|
||||||
admin admin
|
admin admin
|
||||||
searches searches
|
searches searches
|
||||||
Dialer Dialer
|
|
||||||
tcp *tcpInterface
|
tcp *tcpInterface
|
||||||
udp *udpInterface
|
udp *udpInterface
|
||||||
log *log.Logger
|
log *log.Logger
|
||||||
|
@ -8,9 +8,13 @@ package yggdrasil
|
|||||||
|
|
||||||
import _ "golang.org/x/net/ipv6" // TODO put this somewhere better
|
import _ "golang.org/x/net/ipv6" // TODO put this somewhere better
|
||||||
|
|
||||||
|
import "golang.org/x/net/proxy"
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "net"
|
import "net"
|
||||||
|
import "net/url"
|
||||||
import "log"
|
import "log"
|
||||||
|
import "strings"
|
||||||
import "regexp"
|
import "regexp"
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
@ -307,6 +311,54 @@ func (c *Core) DEBUG_maybeSendUDPKeys(saddr string) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
func (c *Core) DEBUG_addPeer(addr string) {
|
||||||
|
u, err := url.Parse(addr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(u.Opaque) == 0 {
|
||||||
|
switch strings.ToLower(u.Scheme) {
|
||||||
|
case "tcp":
|
||||||
|
c.DEBUG_addTCPConn(u.Host)
|
||||||
|
case "udp":
|
||||||
|
c.DEBUG_maybeSendUDPKeys(u.Host)
|
||||||
|
case "socks":
|
||||||
|
c.DEBUG_addSOCKSConn(u.Host, u.Path[1:])
|
||||||
|
default:
|
||||||
|
panic("invalid peer: " + addr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no url scheme provided
|
||||||
|
addr = strings.ToLower(addr)
|
||||||
|
if strings.HasPrefix(addr, "udp:") {
|
||||||
|
c.DEBUG_maybeSendUDPKeys(addr[4:])
|
||||||
|
} else {
|
||||||
|
if strings.HasPrefix(addr, "tcp:") {
|
||||||
|
addr = addr[4:]
|
||||||
|
}
|
||||||
|
c.DEBUG_addTCPConn(addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Core) DEBUG_addSOCKSConn(socksaddr, peeraddr string) {
|
||||||
|
go func() {
|
||||||
|
dialer, err := proxy.SOCKS5("tcp", socksaddr, nil, proxy.Direct)
|
||||||
|
if err == nil {
|
||||||
|
conn, err := dialer.Dial("tcp", peeraddr)
|
||||||
|
if err == nil {
|
||||||
|
c.tcp.callWithConn(&wrappedConn{
|
||||||
|
c: conn,
|
||||||
|
raddr: &wrappedAddr{
|
||||||
|
network: "tcp",
|
||||||
|
addr: peeraddr,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
//*
|
//*
|
||||||
func (c *Core) DEBUG_setupAndStartGlobalTCPInterface(addrport string) {
|
func (c *Core) DEBUG_setupAndStartGlobalTCPInterface(addrport string) {
|
||||||
iface := tcpInterface{}
|
iface := tcpInterface{}
|
||||||
|
@ -1,23 +1,10 @@
|
|||||||
package yggdrasil
|
package yggdrasil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"golang.org/x/net/proxy"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
"yggdrasil/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Dialer = proxy.Dialer
|
|
||||||
|
|
||||||
// muxedDialer implements proxy.Dialer (aka Dialer)
|
|
||||||
type muxedDialer struct {
|
|
||||||
conf config.NetConfig
|
|
||||||
tor Dialer
|
|
||||||
direct Dialer
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrappedConn implements net.Conn
|
// wrappedConn implements net.Conn
|
||||||
type wrappedConn struct {
|
type wrappedConn struct {
|
||||||
c net.Conn
|
c net.Conn
|
||||||
@ -69,39 +56,3 @@ func (c *wrappedConn) LocalAddr() net.Addr {
|
|||||||
func (c *wrappedConn) RemoteAddr() net.Addr {
|
func (c *wrappedConn) RemoteAddr() net.Addr {
|
||||||
return c.raddr
|
return c.raddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *muxedDialer) Dial(network, addr string) (net.Conn, error) {
|
|
||||||
host, _, _ := net.SplitHostPort(addr)
|
|
||||||
if d.conf.Tor.UseForAll || strings.HasSuffix(host, ".onion") {
|
|
||||||
if !d.conf.Tor.Enabled {
|
|
||||||
return nil, errors.New("tor not enabled")
|
|
||||||
}
|
|
||||||
c, err := d.tor.Dial(network, addr)
|
|
||||||
if err == nil {
|
|
||||||
c = &wrappedConn{
|
|
||||||
c: c,
|
|
||||||
raddr: &wrappedAddr{
|
|
||||||
network: network,
|
|
||||||
addr: addr,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c, err
|
|
||||||
} else {
|
|
||||||
return d.direct.Dial(network, addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDialer creates a Dialer from a NetConfig
|
|
||||||
func NewDialer(c config.NetConfig) Dialer {
|
|
||||||
if c.Tor.Enabled {
|
|
||||||
tor, _ := proxy.SOCKS5("tcp", c.Tor.SocksAddr, nil, proxy.Direct)
|
|
||||||
return &muxedDialer{
|
|
||||||
conf: c,
|
|
||||||
tor: tor,
|
|
||||||
direct: proxy.Direct,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return proxy.Direct
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -66,6 +66,26 @@ func (iface *tcpInterface) listener() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (iface *tcpInterface) callWithConn(conn net.Conn) {
|
||||||
|
go func() {
|
||||||
|
raddr := conn.RemoteAddr().String()
|
||||||
|
iface.mutex.Lock()
|
||||||
|
_, isIn := iface.calls[raddr]
|
||||||
|
iface.mutex.Unlock()
|
||||||
|
if !isIn {
|
||||||
|
iface.mutex.Lock()
|
||||||
|
iface.calls[raddr] = struct{}{}
|
||||||
|
iface.mutex.Unlock()
|
||||||
|
defer func() {
|
||||||
|
iface.mutex.Lock()
|
||||||
|
delete(iface.calls, raddr)
|
||||||
|
iface.mutex.Unlock()
|
||||||
|
}()
|
||||||
|
iface.handler(conn)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
func (iface *tcpInterface) call(saddr string) {
|
func (iface *tcpInterface) call(saddr string) {
|
||||||
go func() {
|
go func() {
|
||||||
quit := false
|
quit := false
|
||||||
@ -82,7 +102,7 @@ func (iface *tcpInterface) call(saddr string) {
|
|||||||
}
|
}
|
||||||
iface.mutex.Unlock()
|
iface.mutex.Unlock()
|
||||||
if !quit {
|
if !quit {
|
||||||
conn, err := iface.core.Dialer.Dial("tcp", saddr)
|
conn, err := net.Dial("tcp", saddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
11
yggdrasil.go
11
yggdrasil.go
@ -59,8 +59,6 @@ func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
|
|||||||
}
|
}
|
||||||
n.core.DEBUG_setIfceExpr(ifceExpr)
|
n.core.DEBUG_setIfceExpr(ifceExpr)
|
||||||
|
|
||||||
n.core.Dialer = yggdrasil.NewDialer(cfg.Net)
|
|
||||||
|
|
||||||
logger.Println("Starting interface...")
|
logger.Println("Starting interface...")
|
||||||
n.core.DEBUG_setupAndStartGlobalTCPInterface(cfg.Listen) // Listen for peers on TCP
|
n.core.DEBUG_setupAndStartGlobalTCPInterface(cfg.Listen) // Listen for peers on TCP
|
||||||
n.core.DEBUG_setupAndStartGlobalUDPInterface(cfg.Listen) // Also listen on UDP, TODO allow separate configuration for ip/port to listen on each of these
|
n.core.DEBUG_setupAndStartGlobalUDPInterface(cfg.Listen) // Also listen on UDP, TODO allow separate configuration for ip/port to listen on each of these
|
||||||
@ -74,14 +72,7 @@ func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
|
|||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
for _, p := range cfg.Peers {
|
for _, p := range cfg.Peers {
|
||||||
switch {
|
n.core.DEBUG_addPeer(p)
|
||||||
case len(p) >= 4 && p[:4] == "udp:":
|
|
||||||
n.core.DEBUG_maybeSendUDPKeys(p[4:])
|
|
||||||
case len(p) >= 4 && p[:4] == "tcp:":
|
|
||||||
n.core.DEBUG_addTCPConn(p[4:])
|
|
||||||
default:
|
|
||||||
n.core.DEBUG_addTCPConn(p)
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
time.Sleep(time.Minute)
|
time.Sleep(time.Minute)
|
||||||
|
Loading…
Reference in New Issue
Block a user