mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-23 12:13:50 +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:
|
||||
// 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 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)
|
||||
addresses, err := ReadAddresses(r)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read addresses: %w", err)
|
||||
}
|
||||
|
||||
*e = addresses
|
||||
@@ -949,3 +784,180 @@ func ReadElements(r io.Reader, elements ...interface{}) error {
|
||||
}
|
||||
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