mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-23 20:23:54 +02:00
lnwire: extract addr descriptor reading logic
cause we will need to be able to deserialise any persisted OpaqueAddrs which will have a Payload that we should be able to decode with this lnwire method to extract any new addresses that we now support. Co-authored-by: Elle Mouton <elle.mouton@gmail.com>
This commit is contained in:
committed by
Mohamed Awnallah
parent
5844bb0477
commit
0a064d531c
348
lnwire/lnwire.go
348
lnwire/lnwire.go
@@ -719,174 +719,9 @@ func ReadElement(r io.Reader, element interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case *[]net.Addr:
|
case *[]net.Addr:
|
||||||
// First, we'll read the number of total bytes that have been
|
addresses, err := ReadAddresses(r)
|
||||||
// used to encode the set of addresses.
|
if err != nil {
|
||||||
var numAddrsBytes [2]byte
|
return fmt.Errorf("unable to read addresses: %w", err)
|
||||||
if _, err = io.ReadFull(r, numAddrsBytes[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
addrsLen := binary.BigEndian.Uint16(numAddrsBytes[:])
|
|
||||||
|
|
||||||
// With the number of addresses, read, we'll now pull in the
|
|
||||||
// buffer of the encoded addresses into memory.
|
|
||||||
addrs := make([]byte, addrsLen)
|
|
||||||
if _, err := io.ReadFull(r, addrs[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
addrBuf := bytes.NewReader(addrs)
|
|
||||||
|
|
||||||
// Finally, we'll parse the remaining address payload in
|
|
||||||
// series, using the first byte to denote how to decode the
|
|
||||||
// address itself.
|
|
||||||
var (
|
|
||||||
addresses []net.Addr
|
|
||||||
addrBytesRead uint16
|
|
||||||
)
|
|
||||||
|
|
||||||
for addrBytesRead < addrsLen {
|
|
||||||
var descriptor [1]byte
|
|
||||||
if _, err = io.ReadFull(addrBuf, descriptor[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
addrBytesRead++
|
|
||||||
|
|
||||||
var address net.Addr
|
|
||||||
switch aType := addressType(descriptor[0]); aType {
|
|
||||||
case noAddr:
|
|
||||||
continue
|
|
||||||
|
|
||||||
case tcp4Addr:
|
|
||||||
var ip [4]byte
|
|
||||||
if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var port [2]byte
|
|
||||||
if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
address = &net.TCPAddr{
|
|
||||||
IP: net.IP(ip[:]),
|
|
||||||
Port: int(binary.BigEndian.Uint16(port[:])),
|
|
||||||
}
|
|
||||||
addrBytesRead += tcp4AddrLen
|
|
||||||
|
|
||||||
case tcp6Addr:
|
|
||||||
var ip [16]byte
|
|
||||||
if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var port [2]byte
|
|
||||||
if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
address = &net.TCPAddr{
|
|
||||||
IP: net.IP(ip[:]),
|
|
||||||
Port: int(binary.BigEndian.Uint16(port[:])),
|
|
||||||
}
|
|
||||||
addrBytesRead += tcp6AddrLen
|
|
||||||
|
|
||||||
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 += v2OnionAddrLen
|
|
||||||
|
|
||||||
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 += v3OnionAddrLen
|
|
||||||
|
|
||||||
case dnsAddr:
|
|
||||||
var hostnameLen [1]byte
|
|
||||||
_, err := io.ReadFull(addrBuf, hostnameLen[:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
hostname := make([]byte, hostnameLen[0])
|
|
||||||
_, err = io.ReadFull(addrBuf, hostname)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var port [2]byte
|
|
||||||
_, err = io.ReadFull(addrBuf, port[:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
address = &DNSAddress{
|
|
||||||
Hostname: string(hostname),
|
|
||||||
Port: binary.BigEndian.Uint16(
|
|
||||||
port[:],
|
|
||||||
),
|
|
||||||
}
|
|
||||||
addrBytesRead += dnsAddrOverhead +
|
|
||||||
uint16(len(hostname))
|
|
||||||
|
|
||||||
default:
|
|
||||||
// If we don't understand this address type,
|
|
||||||
// we just store it along with the remaining
|
|
||||||
// address bytes as type OpaqueAddrs. We need
|
|
||||||
// to hold onto the bytes so that we can still
|
|
||||||
// write them back to the wire when we
|
|
||||||
// propagate this message.
|
|
||||||
payloadLen := 1 + addrsLen - addrBytesRead
|
|
||||||
payload := make([]byte, payloadLen)
|
|
||||||
|
|
||||||
// First write a byte for the address type that
|
|
||||||
// we already read.
|
|
||||||
payload[0] = byte(aType)
|
|
||||||
|
|
||||||
// Now append the rest of the address bytes.
|
|
||||||
_, err := io.ReadFull(addrBuf, payload[1:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
address = &OpaqueAddrs{
|
|
||||||
Payload: payload,
|
|
||||||
}
|
|
||||||
addrBytesRead = addrsLen
|
|
||||||
}
|
|
||||||
|
|
||||||
addresses = append(addresses, address)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*e = addresses
|
*e = addresses
|
||||||
@@ -949,3 +784,180 @@ func ReadElements(r io.Reader, elements ...interface{}) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadAddresses reads encoded network addresses.
|
||||||
|
//
|
||||||
|
//nolint:funlen
|
||||||
|
func ReadAddresses(r io.Reader) ([]net.Addr, error) {
|
||||||
|
// First, we'll read the number of total bytes that have been
|
||||||
|
// used to encode the set of addresses.
|
||||||
|
var numAddrsBytes [2]byte
|
||||||
|
if _, err := io.ReadFull(r, numAddrsBytes[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
addrsLen := binary.BigEndian.Uint16(numAddrsBytes[:])
|
||||||
|
|
||||||
|
// With the number of addresses, read, we'll now pull in the
|
||||||
|
// buffer of the encoded addresses into memory.
|
||||||
|
addrs := make([]byte, addrsLen)
|
||||||
|
if _, err := io.ReadFull(r, addrs); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
addrBuf := bytes.NewReader(addrs)
|
||||||
|
|
||||||
|
// Finally, we'll parse the remaining address payload in
|
||||||
|
// series, using the first byte to denote how to decode the
|
||||||
|
// address itself.
|
||||||
|
var (
|
||||||
|
addresses []net.Addr
|
||||||
|
addrBytesRead uint16
|
||||||
|
)
|
||||||
|
|
||||||
|
for addrBytesRead < addrsLen {
|
||||||
|
var descriptor [1]byte
|
||||||
|
if _, err := io.ReadFull(addrBuf, descriptor[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
addrBytesRead++
|
||||||
|
|
||||||
|
var address net.Addr
|
||||||
|
switch aType := addressType(descriptor[0]); aType {
|
||||||
|
case noAddr:
|
||||||
|
continue
|
||||||
|
|
||||||
|
case tcp4Addr:
|
||||||
|
var ip [4]byte
|
||||||
|
if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var port [2]byte
|
||||||
|
if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
address = &net.TCPAddr{
|
||||||
|
IP: net.IP(ip[:]),
|
||||||
|
Port: int(binary.BigEndian.Uint16(port[:])),
|
||||||
|
}
|
||||||
|
addrBytesRead += tcp4AddrLen
|
||||||
|
|
||||||
|
case tcp6Addr:
|
||||||
|
var ip [16]byte
|
||||||
|
if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var port [2]byte
|
||||||
|
if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
address = &net.TCPAddr{
|
||||||
|
IP: net.IP(ip[:]),
|
||||||
|
Port: int(binary.BigEndian.Uint16(port[:])),
|
||||||
|
}
|
||||||
|
addrBytesRead += tcp6AddrLen
|
||||||
|
|
||||||
|
case v2OnionAddr:
|
||||||
|
var h [tor.V2DecodedLen]byte
|
||||||
|
if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var p [2]byte
|
||||||
|
if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
onionService := tor.Base32Encoding.EncodeToString(h[:])
|
||||||
|
onionService += tor.OnionSuffix
|
||||||
|
port := int(binary.BigEndian.Uint16(p[:]))
|
||||||
|
|
||||||
|
address = &tor.OnionAddr{
|
||||||
|
OnionService: onionService,
|
||||||
|
Port: port,
|
||||||
|
}
|
||||||
|
addrBytesRead += v2OnionAddrLen
|
||||||
|
|
||||||
|
case v3OnionAddr:
|
||||||
|
var h [tor.V3DecodedLen]byte
|
||||||
|
if _, err := io.ReadFull(addrBuf, h[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var p [2]byte
|
||||||
|
if _, err := io.ReadFull(addrBuf, p[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
onionService := tor.Base32Encoding.EncodeToString(h[:])
|
||||||
|
onionService += tor.OnionSuffix
|
||||||
|
port := int(binary.BigEndian.Uint16(p[:]))
|
||||||
|
|
||||||
|
address = &tor.OnionAddr{
|
||||||
|
OnionService: onionService,
|
||||||
|
Port: port,
|
||||||
|
}
|
||||||
|
addrBytesRead += v3OnionAddrLen
|
||||||
|
|
||||||
|
case dnsAddr:
|
||||||
|
var hostnameLen [1]byte
|
||||||
|
_, err := io.ReadFull(addrBuf, hostnameLen[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname := make([]byte, hostnameLen[0])
|
||||||
|
_, err = io.ReadFull(addrBuf, hostname)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var port [2]byte
|
||||||
|
_, err = io.ReadFull(addrBuf, port[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
address = &DNSAddress{
|
||||||
|
Hostname: string(hostname),
|
||||||
|
Port: binary.BigEndian.Uint16(
|
||||||
|
port[:],
|
||||||
|
),
|
||||||
|
}
|
||||||
|
addrBytesRead += dnsAddrOverhead +
|
||||||
|
uint16(len(hostname))
|
||||||
|
|
||||||
|
default:
|
||||||
|
// If we don't understand this address type,
|
||||||
|
// we just store it along with the remaining
|
||||||
|
// address bytes as type OpaqueAddrs. We need
|
||||||
|
// to hold onto the bytes so that we can still
|
||||||
|
// write them back to the wire when we
|
||||||
|
// propagate this message.
|
||||||
|
payloadLen := 1 + addrsLen - addrBytesRead
|
||||||
|
payload := make([]byte, payloadLen)
|
||||||
|
|
||||||
|
// First write a byte for the address type that
|
||||||
|
// we already read.
|
||||||
|
payload[0] = byte(aType)
|
||||||
|
|
||||||
|
// Now append the rest of the address bytes.
|
||||||
|
_, err := io.ReadFull(addrBuf, payload[1:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
address = &OpaqueAddrs{
|
||||||
|
Payload: payload,
|
||||||
|
}
|
||||||
|
addrBytesRead = addrsLen
|
||||||
|
}
|
||||||
|
|
||||||
|
addresses = append(addresses, address)
|
||||||
|
}
|
||||||
|
|
||||||
|
return addresses, nil
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user