Modify code to use proxy aware NetAddresses.

This paves the way for support with proxied connections.
This commit is contained in:
Dave Collins 2013-08-07 13:17:29 -05:00
parent 0d7bff2444
commit 9a9f41a2f3

60
peer.go
View file

@ -10,8 +10,10 @@ import (
"github.com/conformal/btcdb"
"github.com/conformal/btcutil"
"github.com/conformal/btcwire"
"github.com/conformal/go-socks"
"github.com/davecgh/go-spew/spew"
"net"
"strconv"
"sync"
"time"
)
@ -30,6 +32,45 @@ func minUint32(a, b uint32) uint32 {
return b
}
// newNetAddress attempts to extract the IP address and port from the passed
// net.Addr interface and create a bitcoin NetAddress structure using that
// information.
func newNetAddress(addr net.Addr, services btcwire.ServiceFlag) (*btcwire.NetAddress, error) {
// addr will be a net.TCPAddr when not using a proxy.
if tcpAddr, ok := addr.(*net.TCPAddr); ok {
ip := tcpAddr.IP
port := uint16(tcpAddr.Port)
na := btcwire.NewNetAddressIPPort(ip, port, services)
return na, nil
}
// addr will be a socks.ProxiedAddr when using a proxy.
if proxiedAddr, ok := addr.(*socks.ProxiedAddr); ok {
ip := net.ParseIP(proxiedAddr.Host)
if ip == nil {
ip = net.ParseIP("0.0.0.0")
}
port := uint16(proxiedAddr.Port)
na := btcwire.NewNetAddressIPPort(ip, port, services)
return na, nil
}
// For the most part, addr should be one of the two above cases, but
// to be safe, fall back to trying to parse the information from the
// address string as a last resort.
host, portStr, err := net.SplitHostPort(addr.String())
if err != nil {
return nil, err
}
ip := net.ParseIP(host)
port, err := strconv.ParseUint(portStr, 10, 16)
if err != nil {
return nil, err
}
na := btcwire.NewNetAddressIPPort(ip, uint16(port), services)
return na, nil
}
// peer provides a bitcoin peer for handling bitcoin communications.
type peer struct {
server *server
@ -58,12 +99,24 @@ func (p *peer) pushVersionMsg() error {
return err
}
msg, err := btcwire.NewMsgVersionFromConn(p.conn, p.server.nonce,
userAgent, int32(blockNum))
// Create a NetAddress for the local IP. Don't assume any services
// until we know otherwise.
naMe, err := newNetAddress(p.conn.LocalAddr(), 0)
if err != nil {
return err
}
// Create a NetAddress for the remote IP. Don't assume any services
// until we know otherwise.
naYou, err := newNetAddress(p.conn.RemoteAddr(), 0)
if err != nil {
return err
}
// Version message.
msg := btcwire.NewMsgVersion(naMe, naYou, p.server.nonce, userAgent,
int32(blockNum))
// XXX: bitcoind appears to always enable the full node services flag
// of the remote peer netaddress field in the version message regardless
// of whether it knows it supports it or not. Also, bitcoind sets
@ -152,14 +205,13 @@ func (p *peer) handleVersionMsg(msg *btcwire.MsgVersion) {
// TODO: Only do this if we're listening, not doing the initial
// block download, and are routable.
// Advertise the local address.
na, err := btcwire.NewNetAddress(p.conn.LocalAddr(), p.services)
na, err := newNetAddress(p.conn.LocalAddr(), p.services)
if err != nil {
log.Errorf("[PEER] %v", err)
p.disconnect = true
p.conn.Close()
return
}
na.Services = p.services
addresses := map[string]*btcwire.NetAddress{
NetAddressKey(na): na,
}