lnd.xprv/channeldb/addr.go

104 lines
2.5 KiB
Go

package channeldb
import (
"io"
"net"
)
// addressType specifies the network protocol and version that should be used
// when connecting to a node at a particular address.
type addressType uint8
const (
// tcp4Addr denotes an IPv4 TCP address.
tcp4Addr addressType = 0
// tcp6Addr denotes an IPv6 TCP address.
tcp6Addr addressType = 1
// v2OnionAddr denotes a version 2 Tor onion service address.
v2OnionAddr addressType = 2
// v3OnionAddr denotes a version 3 Tor (prop224) onion service addresses.
v3OnionAddr addressType = 3
)
// 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
func deserializeAddr(r io.Reader) (net.Addr, error) {
var scratch [8]byte
var address net.Addr
if _, err := r.Read(scratch[:1]); err != nil {
return nil, err
}
// TODO(roasbeef): also add onion addrs
switch addressType(scratch[0]) {
case tcp4Addr:
addr := &net.TCPAddr{}
var ip [4]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
addr.IP = (net.IP)(ip[:])
if _, err := r.Read(scratch[:2]); err != nil {
return nil, err
}
addr.Port = int(byteOrder.Uint16(scratch[:2]))
address = addr
case tcp6Addr:
addr := &net.TCPAddr{}
var ip [16]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
addr.IP = (net.IP)(ip[:])
if _, err := r.Read(scratch[:2]); err != nil {
return nil, err
}
addr.Port = int(byteOrder.Uint16(scratch[:2]))
address = addr
default:
return nil, ErrUnknownAddressType
}
return address, nil
}
// 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
}
}
byteOrder.PutUint16(scratch[:2],
uint16(address.(*net.TCPAddr).Port))
if _, err := w.Write(scratch[:2]); err != nil {
return err
}
}
return nil
}