mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	support socks proxy in peer url and decouple explicit tor/i2p routing
This commit is contained in:
		
							parent
							
								
									769b058004
								
							
						
					
					
						commit
						7756891510
					
				
					 5 changed files with 74 additions and 61 deletions
				
			
		| 
						 | 
				
			
			@ -19,7 +19,6 @@ type Core struct {
 | 
			
		|||
	tun         tunDevice
 | 
			
		||||
	admin       admin
 | 
			
		||||
	searches    searches
 | 
			
		||||
	Dialer      Dialer
 | 
			
		||||
	tcp         *tcpInterface
 | 
			
		||||
	udp         *udpInterface
 | 
			
		||||
	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/proxy"
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
import "net"
 | 
			
		||||
import "net/url"
 | 
			
		||||
import "log"
 | 
			
		||||
import "strings"
 | 
			
		||||
import "regexp"
 | 
			
		||||
 | 
			
		||||
// 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) {
 | 
			
		||||
	iface := tcpInterface{}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,23 +1,10 @@
 | 
			
		|||
package yggdrasil
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"golang.org/x/net/proxy"
 | 
			
		||||
	"net"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"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
 | 
			
		||||
type wrappedConn struct {
 | 
			
		||||
	c     net.Conn
 | 
			
		||||
| 
						 | 
				
			
			@ -69,39 +56,3 @@ func (c *wrappedConn) LocalAddr() net.Addr {
 | 
			
		|||
func (c *wrappedConn) RemoteAddr() net.Addr {
 | 
			
		||||
	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) {
 | 
			
		||||
	go func() {
 | 
			
		||||
		quit := false
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +102,7 @@ func (iface *tcpInterface) call(saddr string) {
 | 
			
		|||
		}
 | 
			
		||||
		iface.mutex.Unlock()
 | 
			
		||||
		if !quit {
 | 
			
		||||
			conn, err := iface.core.Dialer.Dial("tcp", saddr)
 | 
			
		||||
			conn, err := net.Dial("tcp", saddr)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue