Merge pull request #1159 from wpaulino/onion-service-support

multi: add onion services support
This commit is contained in:
Olaoluwa Osuntokun authored and GitHub committed 2018-06-04 21:46:51 -07:00
commit d98d4523e1
22 files changed
+1694 -623

No files matched your search

+92 -22
View File
@@ -11,6 +11,7 @@ import (
"net"
"github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/tor"
"github.com/roasbeef/btcd/btcec"
"github.com/roasbeef/btcd/chaincfg/chainhash"
"github.com/roasbeef/btcd/wire"
@@ -43,8 +44,7 @@ const (
// v2OnionAddr denotes a version 2 Tor onion service address.
v2OnionAddr addressType = 3
// v3OnionAddr denotes a version 3 Tor (prop224) onion service
// addresses
// v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
v3OnionAddr addressType = 4
)
@@ -56,16 +56,12 @@ func (a addressType) AddrLen() uint16 {
return 0
case tcp4Addr:
return 6
case tcp6Addr:
return 18
case v2OnionAddr:
return 12
case v3OnionAddr:
return 37
default:
return 0
}
@@ -300,7 +296,6 @@ func writeElement(w io.Writer, element interface{}) error {
return fmt.Errorf("cannot write nil TCPAddr")
}
// TODO(roasbeef): account for onion types too
if e.IP.To4() != nil {
var descriptor [1]byte
descriptor[0] = uint8(tcp4Addr)
@@ -331,6 +326,45 @@ func writeElement(w io.Writer, element interface{}) error {
return err
}
case *tor.OnionAddr:
if e == nil {
return errors.New("cannot write nil onion address")
}
var suffixIndex int
switch len(e.OnionService) {
case tor.V2Len:
descriptor := []byte{byte(v2OnionAddr)}
if _, err := w.Write(descriptor); err != nil {
return err
}
suffixIndex = tor.V2Len - tor.OnionSuffixLen
case tor.V3Len:
descriptor := []byte{byte(v3OnionAddr)}
if _, err := w.Write(descriptor); err != nil {
return err
}
suffixIndex = tor.V3Len - tor.OnionSuffixLen
default:
return errors.New("unknown onion service length")
}
host, err := tor.Base32Encoding.DecodeString(
e.OnionService[:suffixIndex],
)
if err != nil {
return err
}
if _, err := w.Write(host); err != nil {
return err
}
var port [2]byte
binary.BigEndian.PutUint16(port[:], uint16(e.Port))
if _, err := w.Write(port[:]); err != nil {
return err
}
case []net.Addr:
// First, we'll encode all the addresses into an intermediate
// buffer. We need to do this in order to compute the total
@@ -632,6 +666,7 @@ func readElement(r io.Reader, element interface{}) error {
addresses []net.Addr
addrBytesRead uint16
)
for addrBytesRead < addrsLen {
var descriptor [1]byte
if _, err = io.ReadFull(addrBuf, descriptor[:]); err != nil {
@@ -640,52 +675,87 @@ func readElement(r io.Reader, element interface{}) error {
addrBytesRead++
address := &net.TCPAddr{}
aType := addressType(descriptor[0])
switch aType {
var address net.Addr
switch aType := addressType(descriptor[0]); aType {
case noAddr:
addrBytesRead += aType.AddrLen()
continue
case tcp4Addr:
var ip [4]byte
if _, err = io.ReadFull(addrBuf, ip[:]); err != nil {
if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
return err
}
address.IP = (net.IP)(ip[:])
var port [2]byte
if _, err = io.ReadFull(addrBuf, port[:]); err != nil {
if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
return err
}
address.Port = int(binary.BigEndian.Uint16(port[:]))
address = &net.TCPAddr{
IP: net.IP(ip[:]),
Port: int(binary.BigEndian.Uint16(port[:])),
}
addrBytesRead += aType.AddrLen()
case tcp6Addr:
var ip [16]byte
if _, err = io.ReadFull(addrBuf, ip[:]); err != nil {
if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
return err
}
address.IP = (net.IP)(ip[:])
var port [2]byte
if _, err = io.ReadFull(addrBuf, port[:]); err != nil {
if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
return err
}
address.Port = int(binary.BigEndian.Uint16(port[:]))
address = &net.TCPAddr{
IP: net.IP(ip[:]),
Port: int(binary.BigEndian.Uint16(port[:])),
}
addrBytesRead += aType.AddrLen()
case v2OnionAddr:
var h [tor.V2DecodedLen]byte
if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
return err
}
var p [2]byte
if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
return err
}
onionService := tor.Base32Encoding.EncodeToString(h[:])
onionService += tor.OnionSuffix
port := int(binary.BigEndian.Uint16(p[:]))
address = &tor.OnionAddr{
OnionService: onionService,
Port: port,
}
addrBytesRead += aType.AddrLen()
continue
case v3OnionAddr:
var h [tor.V3DecodedLen]byte
if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
return err
}
var p [2]byte
if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
return err
}
onionService := tor.Base32Encoding.EncodeToString(h[:])
onionService += tor.OnionSuffix
port := int(binary.BigEndian.Uint16(p[:]))
address = &tor.OnionAddr{
OnionService: onionService,
Port: port,
}
addrBytesRead += aType.AddrLen()
continue
default:
return &ErrUnknownAddrType{aType}
+101 -7
View File
@@ -2,6 +2,7 @@ package lnwire
import (
"bytes"
"encoding/binary"
"encoding/hex"
"image/color"
"math"
@@ -14,6 +15,7 @@ import (
"time"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/tor"
"github.com/roasbeef/btcd/btcec"
"github.com/roasbeef/btcd/chaincfg/chainhash"
"github.com/roasbeef/btcd/wire"
@@ -37,11 +39,6 @@ var (
}
_, _ = testSig.R.SetString("63724406601629180062774974542967536251589935445068131219452686511677818569431", 10)
_, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10)
// TODO(roasbeef): randomly generate from three types of addrs
a1 = &net.TCPAddr{IP: (net.IP)([]byte{0x7f, 0x0, 0x0, 0x1}), Port: 8333}
a2, _ = net.ResolveTCPAddr("tcp", "[2001:db8:85a3:0:0:8a2e:370:7334]:80")
testAddrs = []net.Addr{a1, a2}
)
func randPubKey() (*btcec.PublicKey, error) {
@@ -76,6 +73,100 @@ func randRawFeatureVector(r *rand.Rand) *RawFeatureVector {
return featureVec
}
func randTCP4Addr(r *rand.Rand) (*net.TCPAddr, error) {
var ip [4]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
var port [2]byte
if _, err := r.Read(port[:]); err != nil {
return nil, err
}
addrIP := net.IP(ip[:])
addrPort := int(binary.BigEndian.Uint16(port[:]))
return &net.TCPAddr{IP: addrIP, Port: addrPort}, nil
}
func randTCP6Addr(r *rand.Rand) (*net.TCPAddr, error) {
var ip [16]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
var port [2]byte
if _, err := r.Read(port[:]); err != nil {
return nil, err
}
addrIP := net.IP(ip[:])
addrPort := int(binary.BigEndian.Uint16(port[:]))
return &net.TCPAddr{IP: addrIP, Port: addrPort}, nil
}
func randV2OnionAddr(r *rand.Rand) (*tor.OnionAddr, error) {
var serviceID [tor.V2DecodedLen]byte
if _, err := r.Read(serviceID[:]); err != nil {
return nil, err
}
var port [2]byte
if _, err := r.Read(port[:]); err != nil {
return nil, err
}
onionService := tor.Base32Encoding.EncodeToString(serviceID[:])
onionService += tor.OnionSuffix
addrPort := int(binary.BigEndian.Uint16(port[:]))
return &tor.OnionAddr{OnionService: onionService, Port: addrPort}, nil
}
func randV3OnionAddr(r *rand.Rand) (*tor.OnionAddr, error) {
var serviceID [tor.V3DecodedLen]byte
if _, err := r.Read(serviceID[:]); err != nil {
return nil, err
}
var port [2]byte
if _, err := r.Read(port[:]); err != nil {
return nil, err
}
onionService := tor.Base32Encoding.EncodeToString(serviceID[:])
onionService += tor.OnionSuffix
addrPort := int(binary.BigEndian.Uint16(port[:]))
return &tor.OnionAddr{OnionService: onionService, Port: addrPort}, nil
}
func randAddrs(r *rand.Rand) ([]net.Addr, error) {
tcp4Addr, err := randTCP4Addr(r)
if err != nil {
return nil, err
}
tcp6Addr, err := randTCP6Addr(r)
if err != nil {
return nil, err
}
v2OnionAddr, err := randV2OnionAddr(r)
if err != nil {
return nil, err
}
v3OnionAddr, err := randV3OnionAddr(r)
if err != nil {
return nil, err
}
return []net.Addr{tcp4Addr, tcp6Addr, v2OnionAddr, v3OnionAddr}, nil
}
func TestMaxOutPointIndex(t *testing.T) {
t.Parallel()
@@ -465,8 +556,6 @@ func TestLightningWireProtocol(t *testing.T) {
G: uint8(r.Int31()),
B: uint8(r.Int31()),
},
// TODO(roasbeef): proper gen rand addrs
Addresses: testAddrs,
}
req.Signature, err = NewSigFromSignature(testSig)
if err != nil {
@@ -480,6 +569,11 @@ func TestLightningWireProtocol(t *testing.T) {
return
}
req.Addresses, err = randAddrs(r)
if err != nil {
t.Fatalf("unable to generate addresses: %v", err)
}
v[0] = reflect.ValueOf(req)
},
MsgChannelUpdate: func(v []reflect.Value, r *rand.Rand) {