multi: apply roasbeef diff to support incoming socks.ProxiedAddr

This commit is contained in:
MeshCollider 2018-02-03 19:24:43 +13:00 committed by Olaoluwa Osuntokun
parent 36219427ad
commit 4b1cc98808
7 changed files with 86 additions and 43 deletions

View File

@ -3,6 +3,8 @@ package channeldb
import (
"io"
"net"
"github.com/btcsuite/go-socks/socks"
)
// addressType specifies the network protocol and version that should be used
@ -23,6 +25,40 @@ const (
v3OnionAddr addressType = 3
)
func encodeTCPAddr(w io.Writer, addr *net.TCPAddr) error {
var scratch [16]byte
if addr.IP.To4() != nil {
scratch[0] = uint8(tcp4Addr)
if _, err := w.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:4], addr.IP.To4())
if _, err := w.Write(scratch[:4]); err != nil {
return err
}
} else {
scratch[0] = uint8(tcp6Addr)
if _, err := w.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:], addr.IP.To16())
if _, err := w.Write(scratch[:]); err != nil {
return err
}
}
byteOrder.PutUint16(scratch[:2], uint16(addr.Port))
if _, err := w.Write(scratch[:2]); err != nil {
return err
}
return nil
}
// deserializeAddr reads the serialized raw representation of an address and
// deserializes it into the actual address, to avoid performing address
// resolution in the database module
@ -70,33 +106,31 @@ func deserializeAddr(r io.Reader) (net.Addr, error) {
// serializeAddr serializes an address into a raw byte representation so it
// can be deserialized without requiring address resolution
func serializeAddr(w io.Writer, address net.Addr) error {
var scratch [16]byte
if address.Network() == "tcp" {
if address.(*net.TCPAddr).IP.To4() != nil {
scratch[0] = uint8(tcp4Addr)
if _, err := w.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:4], address.(*net.TCPAddr).IP.To4())
if _, err := w.Write(scratch[:4]); err != nil {
return err
}
} else {
scratch[0] = uint8(tcp6Addr)
if _, err := w.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:], address.(*net.TCPAddr).IP.To16())
if _, err := w.Write(scratch[:]); err != nil {
return err
}
switch addr := address.(type) {
case *net.TCPAddr:
return encodeTCPAddr(w, addr)
// If this is a proxied address (due to the connection being
// established over a SOCKs proxy, then we'll convert it into its
// corresponding TCP address.
case *socks.ProxiedAddr:
// If we can't parse the host as an IP (though we should be
// able to at this point), then we'll skip this address all
// together.
//
// TODO(roasbeef): would be nice to be able to store hosts
// though...
ip := net.ParseIP(addr.Host)
if ip == nil {
return nil
}
byteOrder.PutUint16(scratch[:2],
uint16(address.(*net.TCPAddr).Port))
if _, err := w.Write(scratch[:2]); err != nil {
return err
tcpAddr := &net.TCPAddr{
IP: ip,
Port: addr.Port,
}
return encodeTCPAddr(w, tcpAddr)
}
return nil

View File

@ -623,7 +623,7 @@ func fetchOpenChannel(chanBucket *bolt.Bucket,
//
// TODO(roasbeef): addr param should eventually be a lnwire.NetAddress type
// that includes service bits.
func (c *OpenChannel) SyncPending(addr *net.TCPAddr, pendingHeight uint32) error {
func (c *OpenChannel) SyncPending(addr net.Addr, pendingHeight uint32) error {
c.Lock()
defer c.Unlock()

View File

@ -56,7 +56,7 @@ type LinkNode struct {
// authenticated connection for the stored identity public key.
//
// TODO(roasbeef): also need to support hidden service addrs
Addresses []*net.TCPAddr
Addresses []net.Addr
db *DB
}
@ -64,13 +64,13 @@ type LinkNode struct {
// NewLinkNode creates a new LinkNode from the provided parameters, which is
// backed by an instance of channeldb.
func (db *DB) NewLinkNode(bitNet wire.BitcoinNet, pub *btcec.PublicKey,
addr *net.TCPAddr) *LinkNode {
addr net.Addr) *LinkNode {
return &LinkNode{
Network: bitNet,
IdentityPub: pub,
LastSeen: time.Now(),
Addresses: []*net.TCPAddr{addr},
Addresses: []net.Addr{addr},
db: db,
}
}
@ -267,13 +267,13 @@ func deserializeLinkNode(r io.Reader) (*LinkNode, error) {
}
numAddrs := byteOrder.Uint32(buf[:4])
node.Addresses = make([]*net.TCPAddr, numAddrs)
node.Addresses = make([]net.Addr, numAddrs)
for i := uint32(0); i < numAddrs; i++ {
addr, err := deserializeAddr(r)
if err != nil {
return nil, err
}
node.Addresses[i] = addr.(*net.TCPAddr)
node.Addresses[i] = addr
}
return node, nil

View File

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"fmt"
"net"
"sync"
"sync/atomic"
"time"
@ -26,7 +27,6 @@ import (
"github.com/roasbeef/btcd/chaincfg/chainhash"
"github.com/roasbeef/btcd/wire"
"github.com/roasbeef/btcutil"
"net"
)
const (
@ -847,7 +847,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
chainHash := chainhash.Hash(msg.ChainHash)
reservation, err := f.cfg.Wallet.InitChannelReservation(amt, 0,
msg.PushAmount, btcutil.Amount(msg.FeePerKiloWeight), 0,
fmsg.peerAddress.IdentityKey, fmsg.peerAddress.Address.(*net.TCPAddr),
fmsg.peerAddress.IdentityKey, fmsg.peerAddress.Address,
&chainHash, msg.ChannelFlags)
if err != nil {
fndgLog.Errorf("Unable to initialize reservation: %v", err)

View File

@ -110,7 +110,7 @@ type ChannelReservation struct {
theirContribution *ChannelContribution
partialState *channeldb.OpenChannel
nodeAddr *net.TCPAddr
nodeAddr net.Addr
// The ID of this reservation, used to uniquely track the reservation
// throughout its lifetime.

View File

@ -82,10 +82,10 @@ type initFundingReserveMsg struct {
// with.
nodeID *btcec.PublicKey
// nodeAddr is the IP address plus port that we used to either
// establish or accept the connection which led to the negotiation of
// this funding workflow.
nodeAddr *net.TCPAddr
// nodeAddr is the address port that we used to either establish or
// accept the connection which led to the negotiation of this funding
// workflow.
nodeAddr net.Addr
// fundingAmount is the amount of funds requested for this channel.
fundingAmount btcutil.Amount
@ -452,7 +452,7 @@ out:
func (l *LightningWallet) InitChannelReservation(
capacity, ourFundAmt btcutil.Amount, pushMSat lnwire.MilliSatoshi,
commitFeePerKw, fundingFeePerWeight btcutil.Amount,
theirID *btcec.PublicKey, theirAddr *net.TCPAddr,
theirID *btcec.PublicKey, theirAddr net.Addr,
chainHash *chainhash.Hash, flags lnwire.FundingFlag) (*ChannelReservation, error) {
errChan := make(chan error, 1)

View File

@ -815,7 +815,7 @@ func (s *server) genNodeAnnouncement(
type nodeAddresses struct {
pubKey *btcec.PublicKey
addresses []*net.TCPAddr
addresses []net.Addr
}
// establishPersistentConnections attempts to establish persistent connections
@ -838,9 +838,13 @@ func (s *server) establishPersistentConnections() error {
}
for _, node := range linkNodes {
for _, address := range node.Addresses {
if address.Port == 0 {
address.Port = defaultPeerPort
switch addr := address.(type) {
case *net.TCPAddr:
if addr.Port == 0 {
addr.Port = defaultPeerPort
}
}
}
pubStr := string(node.IdentityPub.SerializeCompressed())
@ -872,14 +876,19 @@ func (s *server) establishPersistentConnections() error {
// list of addresses we'll connect to. If there are duplicates
// that have different ports specified, the port from the
// channel graph should supersede the port from the link node.
var addrs []*net.TCPAddr
var addrs []net.Addr
linkNodeAddrs, ok := nodeAddrsMap[pubStr]
if ok {
for _, lnAddress := range linkNodeAddrs.addresses {
lnAddrTCP, ok := lnAddress.(*net.TCPAddr)
if !ok {
continue
}
var addrMatched bool
for _, polAddress := range policy.Node.Addresses {
polTCPAddr, ok := polAddress.(*net.TCPAddr)
if ok && polTCPAddr.IP.Equal(lnAddress.IP) {
if ok && polTCPAddr.IP.Equal(lnAddrTCP.IP) {
addrMatched = true
addrs = append(addrs, polTCPAddr)
}