lnwire: implement serialization of onion addresses
Co-Authored-By: Eugene <crypt-iq@users.noreply.github.com>
This commit is contained in:
1 file changed
+92
-22
+92
-22
@@ -11,6 +11,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
|
"github.com/lightningnetwork/lnd/tor"
|
||||||
"github.com/roasbeef/btcd/btcec"
|
"github.com/roasbeef/btcd/btcec"
|
||||||
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
||||||
"github.com/roasbeef/btcd/wire"
|
"github.com/roasbeef/btcd/wire"
|
||||||
@@ -43,8 +44,7 @@ const (
|
|||||||
// v2OnionAddr denotes a version 2 Tor onion service address.
|
// v2OnionAddr denotes a version 2 Tor onion service address.
|
||||||
v2OnionAddr addressType = 3
|
v2OnionAddr addressType = 3
|
||||||
|
|
||||||
// v3OnionAddr denotes a version 3 Tor (prop224) onion service
|
// v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
|
||||||
// addresses
|
|
||||||
v3OnionAddr addressType = 4
|
v3OnionAddr addressType = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -56,16 +56,12 @@ func (a addressType) AddrLen() uint16 {
|
|||||||
return 0
|
return 0
|
||||||
case tcp4Addr:
|
case tcp4Addr:
|
||||||
return 6
|
return 6
|
||||||
|
|
||||||
case tcp6Addr:
|
case tcp6Addr:
|
||||||
return 18
|
return 18
|
||||||
|
|
||||||
case v2OnionAddr:
|
case v2OnionAddr:
|
||||||
return 12
|
return 12
|
||||||
|
|
||||||
case v3OnionAddr:
|
case v3OnionAddr:
|
||||||
return 37
|
return 37
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -300,7 +296,6 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
return fmt.Errorf("cannot write nil TCPAddr")
|
return fmt.Errorf("cannot write nil TCPAddr")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): account for onion types too
|
|
||||||
if e.IP.To4() != nil {
|
if e.IP.To4() != nil {
|
||||||
var descriptor [1]byte
|
var descriptor [1]byte
|
||||||
descriptor[0] = uint8(tcp4Addr)
|
descriptor[0] = uint8(tcp4Addr)
|
||||||
@@ -331,6 +326,45 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
return err
|
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:
|
case []net.Addr:
|
||||||
// First, we'll encode all the addresses into an intermediate
|
// First, we'll encode all the addresses into an intermediate
|
||||||
// buffer. We need to do this in order to compute the total
|
// 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
|
addresses []net.Addr
|
||||||
addrBytesRead uint16
|
addrBytesRead uint16
|
||||||
)
|
)
|
||||||
|
|
||||||
for addrBytesRead < addrsLen {
|
for addrBytesRead < addrsLen {
|
||||||
var descriptor [1]byte
|
var descriptor [1]byte
|
||||||
if _, err = io.ReadFull(addrBuf, descriptor[:]); err != nil {
|
if _, err = io.ReadFull(addrBuf, descriptor[:]); err != nil {
|
||||||
@@ -640,52 +675,87 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
|
|
||||||
addrBytesRead++
|
addrBytesRead++
|
||||||
|
|
||||||
address := &net.TCPAddr{}
|
var address net.Addr
|
||||||
aType := addressType(descriptor[0])
|
switch aType := addressType(descriptor[0]); aType {
|
||||||
switch aType {
|
|
||||||
|
|
||||||
case noAddr:
|
case noAddr:
|
||||||
addrBytesRead += aType.AddrLen()
|
addrBytesRead += aType.AddrLen()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case tcp4Addr:
|
case tcp4Addr:
|
||||||
var ip [4]byte
|
var ip [4]byte
|
||||||
if _, err = io.ReadFull(addrBuf, ip[:]); err != nil {
|
if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
address.IP = (net.IP)(ip[:])
|
|
||||||
|
|
||||||
var port [2]byte
|
var port [2]byte
|
||||||
if _, err = io.ReadFull(addrBuf, port[:]); err != nil {
|
if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
|
||||||
return err
|
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()
|
addrBytesRead += aType.AddrLen()
|
||||||
|
|
||||||
case tcp6Addr:
|
case tcp6Addr:
|
||||||
var ip [16]byte
|
var ip [16]byte
|
||||||
if _, err = io.ReadFull(addrBuf, ip[:]); err != nil {
|
if _, err := io.ReadFull(addrBuf, ip[:]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
address.IP = (net.IP)(ip[:])
|
|
||||||
|
|
||||||
var port [2]byte
|
var port [2]byte
|
||||||
if _, err = io.ReadFull(addrBuf, port[:]); err != nil {
|
if _, err := io.ReadFull(addrBuf, port[:]); err != nil {
|
||||||
return err
|
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()
|
addrBytesRead += aType.AddrLen()
|
||||||
|
|
||||||
case v2OnionAddr:
|
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()
|
addrBytesRead += aType.AddrLen()
|
||||||
continue
|
|
||||||
|
|
||||||
case v3OnionAddr:
|
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()
|
addrBytesRead += aType.AddrLen()
|
||||||
continue
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return &ErrUnknownAddrType{aType}
|
return &ErrUnknownAddrType{aType}
|
||||||
|
|||||||
Reference in new issue
Block a user