lnwire: implement serialization of onion addresses

Co-Authored-By: Eugene <crypt-iq@users.noreply.github.com>
This commit is contained in:
Wilmer PaulinoandEugene committed 2018-06-04 20:41:31 -07:00
1 parent a07397465b
commit 850f9fbbe9
1 file changed
+92 -22
+92 -22
View File
@@ -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}