lnwire: implement serialization of onion addresses
Co-Authored-By: Eugene <crypt-iq@users.noreply.github.com>
This commit is contained in:
parent
a07397465b
commit
850f9fbbe9
114
lnwire/lnwire.go
114
lnwire/lnwire.go
@ -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}
|
||||
|
Loading…
Reference in New Issue
Block a user