Skip to content
This repository was archived by the owner on Oct 5, 2021. It is now read-only.

Tor integration: TorDialer and OnionListener #6

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions convert.go
Original file line number Diff line number Diff line change
@@ -3,8 +3,10 @@ package manet
import (
"fmt"
"net"
"strconv"
"strings"

tor "github.com/david415/oniondialer"
utp "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/h2so5/utp"
ma "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
)
@@ -97,6 +99,23 @@ func FromNetAddr(a net.Addr) (ma.Multiaddr, error) {
}
return FromIP(ac.IP)

case "onion":
onionAddr, ok := a.(*tor.OnionAddr)
if !ok {
return nil, errIncorrectNetAddr
}

fields := strings.Split(onionAddr.String(), ":")
if len(fields) != 2 {
return nil, fmt.Errorf("invalid onion addr doesn't contain a port %v", onionAddr)
}
// Get Tor Onion Addr
onionm, err := ma.NewMultiaddr(fmt.Sprintf("/onion/%s:%s", fields[0], fields[1]))
if err != nil {
return nil, errIncorrectNetAddr
}
return onionm, nil

default:
return nil, fmt.Errorf("unknown network %v", a.Network())
}
@@ -139,13 +158,23 @@ func FromIP(ip net.IP) (ma.Multiaddr, error) {

// DialArgs is a convenience function returning arguments for use in net.Dial
func DialArgs(m ma.Multiaddr) (string, string, error) {
if !IsThinWaist(m) {
return "", "", fmt.Errorf("%s is not a 'thin waist' address", m)
}

str := m.String()
parts := strings.Split(str, "/")[1:]

switch parts[0] {
case "onion":
addr := strings.Split(parts[1], ":")
if len(addr) != 2 {
return "", "", fmt.Errorf("failed to parse addr %s: does not contain a port number.", str)
}
onionHost := addr[0] + ".onion"
onionPort, err := strconv.Atoi(addr[1])
if err != nil {
return "", "", fmt.Errorf("failed to parse addr %s: invalid port number", str)
}
return "onion", fmt.Sprintf("%s:%s", onionHost, onionPort), nil
}

if len(parts) == 2 { // only IP
return parts[0], parts[1], nil
}
36 changes: 26 additions & 10 deletions net.go
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import (
"net"

// utp "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/h2so5/utp"
tor "github.com/david415/oniondialer"
ma "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
)

@@ -88,18 +89,18 @@ type Dialer struct {
// remote Multiaddrs).
func (d *Dialer) Dial(remote ma.Multiaddr) (Conn, error) {

// if a LocalAddr is specified, use it on the embedded dialer.
if d.LocalAddr != nil {
// convert our multiaddr to net.Addr friendly
naddr, err := ToNetAddr(d.LocalAddr)
if err != nil {
return nil, err
if IsThinWaist(remote) {
// if a LocalAddr is specified, use it on the embedded dialer.
if d.LocalAddr != nil {
// convert our multiaddr to net.Addr friendly
naddr, err := ToNetAddr(d.LocalAddr)
if err != nil {
return nil, err
}
// set the dialer's LocalAddr as naddr
d.Dialer.LocalAddr = naddr
}

// set the dialer's LocalAddr as naddr
d.Dialer.LocalAddr = naddr
}

// get the net.Dial friendly arguments from the remote addr
rnet, rnaddr, err := DialArgs(remote)
if err != nil {
@@ -127,6 +128,21 @@ func (d *Dialer) Dial(remote ma.Multiaddr) (Conn, error) {
// if err != nil {
// return nil, err
// }
case "onion":
// XXX fix me. do not want hard coded values. needs user specified parameters.
torDialer, err := tor.NewTorDialer("tcp", "127.0.0.1:9050", nil)
if err != nil {
return nil, err
}
nconn, err = torDialer.Dial(rnet, rnaddr)
if err != nil {
return nil, err
}
return &maConn{
Conn: nconn,
laddr: d.LocalAddr,
raddr: remote,
}, nil
}

// get local address (pre-specified or assigned within net.Conn)