mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2024-11-23 18:15:24 +00:00
tor auto config
This commit is contained in:
parent
48ced483d6
commit
3c4fee0492
29
src/yggdrasil/config/config.go
Normal file
29
src/yggdrasil/config/config.go
Normal file
@ -0,0 +1,29 @@
|
||||
package config
|
||||
|
||||
/**
|
||||
* This is a very crude wrapper around src/yggdrasil
|
||||
* It can generate a new config (--genconf)
|
||||
* It can read a config from stdin (--useconf)
|
||||
* It can run with an automatic config (--autoconf)
|
||||
*/
|
||||
|
||||
type NodeConfig struct {
|
||||
Listen string
|
||||
AdminListen string
|
||||
Peers []string
|
||||
BoxPub string
|
||||
BoxPriv string
|
||||
SigPub string
|
||||
SigPriv string
|
||||
Multicast bool
|
||||
LinkLocal string
|
||||
IfName string
|
||||
IfTAPMode bool
|
||||
IfMTU int
|
||||
Net NetConfig
|
||||
}
|
||||
|
||||
type NetConfig struct {
|
||||
Tor TorConfig
|
||||
I2P I2PConfig
|
||||
}
|
7
src/yggdrasil/config/i2p.go
Normal file
7
src/yggdrasil/config/i2p.go
Normal file
@ -0,0 +1,7 @@
|
||||
package config
|
||||
|
||||
type I2PConfig struct {
|
||||
Keyfile string
|
||||
Addr string
|
||||
Enabled bool
|
||||
}
|
11
src/yggdrasil/config/tor.go
Normal file
11
src/yggdrasil/config/tor.go
Normal file
@ -0,0 +1,11 @@
|
||||
package config
|
||||
|
||||
/**
|
||||
*tor specific configuration
|
||||
*/
|
||||
type TorConfig struct {
|
||||
OnionKeyfile string
|
||||
SocksAddr string
|
||||
UseForAll bool
|
||||
Enabled bool
|
||||
}
|
@ -19,6 +19,7 @@ type Core struct {
|
||||
tun tunDevice
|
||||
admin admin
|
||||
searches searches
|
||||
Dialer Dialer
|
||||
tcp *tcpInterface
|
||||
udp *udpInterface
|
||||
log *log.Logger
|
||||
|
99
src/yggdrasil/dial.go
Normal file
99
src/yggdrasil/dial.go
Normal file
@ -0,0 +1,99 @@
|
||||
package yggdrasil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"golang.org/x/net/proxy"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
"yggdrasil/config"
|
||||
)
|
||||
|
||||
type Dialer = proxy.Dialer
|
||||
|
||||
type muxedDialer struct {
|
||||
conf config.NetConfig
|
||||
tor Dialer
|
||||
direct Dialer
|
||||
}
|
||||
|
||||
type wrappedConn struct {
|
||||
c net.Conn
|
||||
raddr net.Addr
|
||||
}
|
||||
|
||||
type wrappedAddr struct {
|
||||
network string
|
||||
addr string
|
||||
}
|
||||
|
||||
func (a *wrappedAddr) Network() string {
|
||||
return a.network
|
||||
}
|
||||
|
||||
func (a *wrappedAddr) String() string {
|
||||
return a.addr
|
||||
}
|
||||
|
||||
func (c *wrappedConn) Write(data []byte) (int, error) {
|
||||
return c.c.Write(data)
|
||||
}
|
||||
|
||||
func (c *wrappedConn) Read(data []byte) (int, error) {
|
||||
return c.c.Read(data)
|
||||
}
|
||||
|
||||
func (c *wrappedConn) SetDeadline(t time.Time) error {
|
||||
return c.c.SetDeadline(t)
|
||||
}
|
||||
|
||||
func (c *wrappedConn) SetReadDeadline(t time.Time) error {
|
||||
return c.c.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
func (c *wrappedConn) SetWriteDeadline(t time.Time) error {
|
||||
return c.c.SetWriteDeadline(t)
|
||||
}
|
||||
|
||||
func (c *wrappedConn) Close() error {
|
||||
return c.c.Close()
|
||||
}
|
||||
|
||||
func (c *wrappedConn) LocalAddr() net.Addr {
|
||||
return c.c.LocalAddr()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
func NewDialer(c config.NetConfig) Dialer {
|
||||
tor, _ := proxy.SOCKS5("tcp", c.Tor.SocksAddr, nil, proxy.Direct)
|
||||
return &muxedDialer{
|
||||
conf: c,
|
||||
tor: tor,
|
||||
direct: proxy.Direct,
|
||||
}
|
||||
}
|
@ -19,9 +19,17 @@ import "bufio"
|
||||
|
||||
const tcp_msgSize = 2048 + 65535 // TODO figure out what makes sense
|
||||
|
||||
// wrapper function for non tcp/ip connections
|
||||
func setNoDelay(c net.Conn, delay bool) {
|
||||
tcp, ok := c.(*net.TCPConn)
|
||||
if ok {
|
||||
tcp.SetNoDelay(delay)
|
||||
}
|
||||
}
|
||||
|
||||
type tcpInterface struct {
|
||||
core *Core
|
||||
serv *net.TCPListener
|
||||
serv net.Listener
|
||||
mutex sync.Mutex // Protecting the below
|
||||
calls map[string]struct{}
|
||||
conns map[tcpInfo](chan struct{})
|
||||
@ -30,30 +38,27 @@ type tcpInterface struct {
|
||||
type tcpInfo struct {
|
||||
box boxPubKey
|
||||
sig sigPubKey
|
||||
localAddr string // net.IPAddr.String(), not TCPAddr, don't care about port
|
||||
remoteAddr string
|
||||
localAddr net.Addr
|
||||
remoteAddr net.Addr
|
||||
}
|
||||
|
||||
func (iface *tcpInterface) init(core *Core, addr string) {
|
||||
func (iface *tcpInterface) init(core *Core, addr string) (err error) {
|
||||
iface.core = core
|
||||
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
iface.serv, err = net.ListenTCP("tcp", tcpAddr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
iface.serv, err = net.Listen("tcp", addr)
|
||||
if err == nil {
|
||||
iface.calls = make(map[string]struct{})
|
||||
iface.conns = make(map[tcpInfo](chan struct{}))
|
||||
go iface.listener()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (iface *tcpInterface) listener() {
|
||||
defer iface.serv.Close()
|
||||
iface.core.log.Println("Listening for TCP on:", iface.serv.Addr().String())
|
||||
for {
|
||||
sock, err := iface.serv.AcceptTCP()
|
||||
sock, err := iface.serv.Accept()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -77,17 +82,16 @@ func (iface *tcpInterface) call(saddr string) {
|
||||
}
|
||||
iface.mutex.Unlock()
|
||||
if !quit {
|
||||
conn, err := net.DialTimeout("tcp", saddr, 6*time.Second)
|
||||
conn, err := iface.core.Dialer.Dial("tcp", saddr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sock := conn.(*net.TCPConn)
|
||||
iface.handler(sock)
|
||||
iface.handler(conn)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
func (iface *tcpInterface) handler(sock net.Conn) {
|
||||
defer sock.Close()
|
||||
// Get our keys
|
||||
keys := []byte{}
|
||||
@ -127,18 +131,8 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
return
|
||||
}
|
||||
// Check if we already have a connection to this node, close and block if yes
|
||||
local := sock.LocalAddr().(*net.TCPAddr)
|
||||
laddr := net.IPAddr{
|
||||
IP: local.IP,
|
||||
Zone: local.Zone,
|
||||
}
|
||||
info.localAddr = laddr.String()
|
||||
remote := sock.RemoteAddr().(*net.TCPAddr)
|
||||
raddr := net.IPAddr{
|
||||
IP: remote.IP,
|
||||
Zone: remote.Zone,
|
||||
}
|
||||
info.remoteAddr = raddr.String()
|
||||
info.localAddr = sock.LocalAddr()
|
||||
info.remoteAddr = sock.RemoteAddr()
|
||||
iface.mutex.Lock()
|
||||
if blockChan, isIn := iface.conns[info]; isIn {
|
||||
iface.mutex.Unlock()
|
||||
@ -224,7 +218,7 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
util_putBytes(msg)
|
||||
}
|
||||
}
|
||||
sock.SetNoDelay(true)
|
||||
setNoDelay(sock, true)
|
||||
go p.linkLoop(linkIn)
|
||||
defer func() {
|
||||
// Put all of our cleanup here...
|
||||
@ -239,7 +233,7 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
p.core.peers.mutex.Unlock()
|
||||
close(linkIn)
|
||||
}()
|
||||
them := sock.RemoteAddr().(*net.TCPAddr)
|
||||
them := sock.RemoteAddr()
|
||||
themNodeID := getNodeID(&info.box)
|
||||
themAddr := address_addrForNodeID(themNodeID)
|
||||
themAddrString := net.IP(themAddr[:]).String()
|
||||
@ -250,7 +244,7 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
return
|
||||
}
|
||||
|
||||
func (iface *tcpInterface) reader(sock *net.TCPConn, in func([]byte)) {
|
||||
func (iface *tcpInterface) reader(sock net.Conn, in func([]byte)) {
|
||||
bs := make([]byte, 2*tcp_msgSize)
|
||||
frag := bs[:0]
|
||||
for {
|
||||
|
33
yggdrasil.go
33
yggdrasil.go
@ -21,31 +21,13 @@ import "runtime"
|
||||
|
||||
import "golang.org/x/net/ipv6"
|
||||
|
||||
import . "yggdrasil"
|
||||
import "yggdrasil"
|
||||
import "yggdrasil/config"
|
||||
|
||||
import "github.com/kardianos/minwinsvc"
|
||||
|
||||
/**
|
||||
* This is a very crude wrapper around src/yggdrasil
|
||||
* It can generate a new config (--genconf)
|
||||
* It can read a config from stdin (--useconf)
|
||||
* It can run with an automatic config (--autoconf)
|
||||
*/
|
||||
|
||||
type nodeConfig struct {
|
||||
Listen string
|
||||
AdminListen string
|
||||
Peers []string
|
||||
BoxPub string
|
||||
BoxPriv string
|
||||
SigPub string
|
||||
SigPriv string
|
||||
Multicast bool
|
||||
LinkLocal string
|
||||
IfName string
|
||||
IfTAPMode bool
|
||||
IfMTU int
|
||||
}
|
||||
type nodeConfig = config.NodeConfig
|
||||
type Core = yggdrasil.Core
|
||||
|
||||
type node struct {
|
||||
core Core
|
||||
@ -76,6 +58,9 @@ func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
|
||||
panic(err)
|
||||
}
|
||||
n.core.DEBUG_setIfceExpr(ifceExpr)
|
||||
|
||||
n.core.Dialer = yggdrasil.NewDialer(cfg.Net)
|
||||
|
||||
logger.Println("Starting interface...")
|
||||
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
|
||||
@ -126,6 +111,10 @@ func generateConfig(isAutoconf bool) *nodeConfig {
|
||||
cfg.IfName = core.DEBUG_GetTUNDefaultIfName()
|
||||
cfg.IfMTU = core.DEBUG_GetTUNDefaultIfMTU()
|
||||
cfg.IfTAPMode = core.DEBUG_GetTUNDefaultIfTAPMode()
|
||||
|
||||
cfg.Net.Tor.SocksAddr = "127.0.0.1:9050"
|
||||
cfg.Net.Tor.UseForAll = false
|
||||
cfg.Net.Tor.Enabled = true
|
||||
return &cfg
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user