@@ -744,146 +744,19 @@ func ReadElement(r io.Reader, element interface{}) error {
744744 )
745745
746746 for addrBytesRead < addrsLen {
747- var descriptor [1 ]byte
748- if _ , err = io .ReadFull (addrBuf , descriptor [:]); err != nil {
749- return err
747+ bytesRead , address , err := ReadAddress (
748+ addrBuf , addrsLen - addrBytesRead ,
749+ )
750+ if err != nil {
751+ return fmt .Errorf ("unable to read address: %w" ,
752+ err )
750753 }
754+ addrBytesRead += bytesRead
751755
752- addrBytesRead ++
753-
754- var address net.Addr
755- switch aType := addressType (descriptor [0 ]); aType {
756- case noAddr :
756+ // If we encounter a noAddr descriptor, then we'll move
757+ // on to the next address.
758+ if address == nil {
757759 continue
758-
759- case tcp4Addr :
760- var ip [4 ]byte
761- if _ , err := io .ReadFull (addrBuf , ip [:]); err != nil {
762- return err
763- }
764-
765- var port [2 ]byte
766- if _ , err := io .ReadFull (addrBuf , port [:]); err != nil {
767- return err
768- }
769-
770- address = & net.TCPAddr {
771- IP : net .IP (ip [:]),
772- Port : int (binary .BigEndian .Uint16 (port [:])),
773- }
774- addrBytesRead += tcp4AddrLen
775-
776- case tcp6Addr :
777- var ip [16 ]byte
778- if _ , err := io .ReadFull (addrBuf , ip [:]); err != nil {
779- return err
780- }
781-
782- var port [2 ]byte
783- if _ , err := io .ReadFull (addrBuf , port [:]); err != nil {
784- return err
785- }
786-
787- address = & net.TCPAddr {
788- IP : net .IP (ip [:]),
789- Port : int (binary .BigEndian .Uint16 (port [:])),
790- }
791- addrBytesRead += tcp6AddrLen
792-
793- case v2OnionAddr :
794- var h [tor .V2DecodedLen ]byte
795- if _ , err := io .ReadFull (addrBuf , h [:]); err != nil {
796- return err
797- }
798-
799- var p [2 ]byte
800- if _ , err := io .ReadFull (addrBuf , p [:]); err != nil {
801- return err
802- }
803-
804- onionService := tor .Base32Encoding .EncodeToString (h [:])
805- onionService += tor .OnionSuffix
806- port := int (binary .BigEndian .Uint16 (p [:]))
807-
808- address = & tor.OnionAddr {
809- OnionService : onionService ,
810- Port : port ,
811- }
812- addrBytesRead += v2OnionAddrLen
813-
814- case v3OnionAddr :
815- var h [tor .V3DecodedLen ]byte
816- if _ , err := io .ReadFull (addrBuf , h [:]); err != nil {
817- return err
818- }
819-
820- var p [2 ]byte
821- if _ , err := io .ReadFull (addrBuf , p [:]); err != nil {
822- return err
823- }
824-
825- onionService := tor .Base32Encoding .EncodeToString (h [:])
826- onionService += tor .OnionSuffix
827- port := int (binary .BigEndian .Uint16 (p [:]))
828-
829- address = & tor.OnionAddr {
830- OnionService : onionService ,
831- Port : port ,
832- }
833- addrBytesRead += v3OnionAddrLen
834-
835- case dnsAddr :
836- var hostnameLen [1 ]byte
837- _ , err := io .ReadFull (addrBuf , hostnameLen [:])
838- if err != nil {
839- return err
840- }
841-
842- hostname := make ([]byte , hostnameLen [0 ])
843- _ , err = io .ReadFull (addrBuf , hostname )
844- if err != nil {
845- return err
846- }
847-
848- var port [2 ]byte
849- _ , err = io .ReadFull (addrBuf , port [:])
850- if err != nil {
851- return err
852- }
853-
854- address = & DNSAddress {
855- Hostname : string (hostname ),
856- Port : binary .BigEndian .Uint16 (
857- port [:],
858- ),
859- }
860- addrBytesRead += dnsAddrOverhead +
861- uint16 (len (hostname ))
862-
863- default :
864- // If we don't understand this address type,
865- // we just store it along with the remaining
866- // address bytes as type OpaqueAddrs. We need
867- // to hold onto the bytes so that we can still
868- // write them back to the wire when we
869- // propagate this message.
870- payloadLen := 1 + addrsLen - addrBytesRead
871- payload := make ([]byte , payloadLen )
872-
873- // First write a byte for the address type that
874- // we already read.
875- payload [0 ] = byte (aType )
876-
877- // Now append the rest of the address bytes.
878- _ , err := io .ReadFull (addrBuf , payload [1 :])
879- if err != nil {
880- return err
881- }
882-
883- address = & OpaqueAddrs {
884- Payload : payload ,
885- }
886- addrBytesRead = addrsLen
887760 }
888761
889762 addresses = append (addresses , address )
@@ -949,3 +822,147 @@ func ReadElements(r io.Reader, elements ...interface{}) error {
949822 }
950823 return nil
951824}
825+
826+ // ReadAddress attempts to read a single address descriptor (as defined in
827+ // Bolt 7) from the passed io.Reader. The total length of the address section
828+ // (in bytes) must be provided so that we can ensure we don't read beyond the
829+ // end of the address section. The number of bytes read from the reader and the
830+ // parsed net.Addr are returned.
831+ //
832+ // NOTE: it is possible for the number of bytes read to be 1 even if a nil
833+ // address is returned.
834+ func ReadAddress (addrBuf io.Reader , addrsLen uint16 ) (uint16 , net.Addr , error ) {
835+ var descriptor [1 ]byte
836+ if _ , err := io .ReadFull (addrBuf , descriptor [:]); err != nil {
837+ return 0 , nil , err
838+ }
839+
840+ addrBytesRead := uint16 (1 )
841+
842+ var address net.Addr
843+ switch aType := addressType (descriptor [0 ]); aType {
844+ case noAddr :
845+ return addrBytesRead , nil , nil
846+
847+ case tcp4Addr :
848+ var ip [4 ]byte
849+ if _ , err := io .ReadFull (addrBuf , ip [:]); err != nil {
850+ return 0 , nil , err
851+ }
852+
853+ var port [2 ]byte
854+ if _ , err := io .ReadFull (addrBuf , port [:]); err != nil {
855+ return 0 , nil , err
856+ }
857+
858+ address = & net.TCPAddr {
859+ IP : net .IP (ip [:]),
860+ Port : int (binary .BigEndian .Uint16 (port [:])),
861+ }
862+ addrBytesRead += tcp4AddrLen
863+
864+ case tcp6Addr :
865+ var ip [16 ]byte
866+ if _ , err := io .ReadFull (addrBuf , ip [:]); err != nil {
867+ return 0 , nil , err
868+ }
869+
870+ var port [2 ]byte
871+ if _ , err := io .ReadFull (addrBuf , port [:]); err != nil {
872+ return 0 , nil , err
873+ }
874+
875+ address = & net.TCPAddr {
876+ IP : net .IP (ip [:]),
877+ Port : int (binary .BigEndian .Uint16 (port [:])),
878+ }
879+ addrBytesRead += tcp6AddrLen
880+
881+ case v2OnionAddr :
882+ var h [tor .V2DecodedLen ]byte
883+ if _ , err := io .ReadFull (addrBuf , h [:]); err != nil {
884+ return 0 , nil , err
885+ }
886+
887+ var p [2 ]byte
888+ if _ , err := io .ReadFull (addrBuf , p [:]); err != nil {
889+ return 0 , nil , err
890+ }
891+
892+ onionService := tor .Base32Encoding .EncodeToString (h [:])
893+ onionService += tor .OnionSuffix
894+ port := int (binary .BigEndian .Uint16 (p [:]))
895+
896+ address = & tor.OnionAddr {
897+ OnionService : onionService ,
898+ Port : port ,
899+ }
900+ addrBytesRead += v2OnionAddrLen
901+
902+ case v3OnionAddr :
903+ var h [tor .V3DecodedLen ]byte
904+ if _ , err := io .ReadFull (addrBuf , h [:]); err != nil {
905+ return 0 , nil , err
906+ }
907+
908+ var p [2 ]byte
909+ if _ , err := io .ReadFull (addrBuf , p [:]); err != nil {
910+ return 0 , nil , err
911+ }
912+
913+ onionService := tor .Base32Encoding .EncodeToString (h [:])
914+ onionService += tor .OnionSuffix
915+ port := int (binary .BigEndian .Uint16 (p [:]))
916+
917+ address = & tor.OnionAddr {
918+ OnionService : onionService ,
919+ Port : port ,
920+ }
921+ addrBytesRead += v3OnionAddrLen
922+
923+ case dnsAddr :
924+ var hostnameLen [1 ]byte
925+ if _ , err := io .ReadFull (addrBuf , hostnameLen [:]); err != nil {
926+ return 0 , nil , err
927+ }
928+
929+ hostname := make ([]byte , hostnameLen [0 ])
930+ if _ , err := io .ReadFull (addrBuf , hostname ); err != nil {
931+ return 0 , nil , err
932+ }
933+
934+ var port [2 ]byte
935+ if _ , err := io .ReadFull (addrBuf , port [:]); err != nil {
936+ return 0 , nil , err
937+ }
938+
939+ address = & DNSAddress {
940+ Hostname : string (hostname ),
941+ Port : binary .BigEndian .Uint16 (port [:]),
942+ }
943+ addrBytesRead += dnsAddrOverhead + uint16 (len (hostname ))
944+
945+ default :
946+ // If we don't understand this address type, we just store it
947+ // along with the remaining address bytes as type OpaqueAddrs.
948+ // We need to hold onto the bytes so that we can still write
949+ // them back to the wire when we propagate this message.
950+ payloadLen := 1 + addrsLen - addrBytesRead
951+ payload := make ([]byte , payloadLen )
952+
953+ // First write a byte for the address type that we already read.
954+ payload [0 ] = byte (aType )
955+
956+ // Now append the rest of the address bytes.
957+ if _ , err := io .ReadFull (addrBuf , payload [1 :]); err != nil {
958+ return 0 , nil , err
959+ }
960+
961+ address = & OpaqueAddrs {
962+ Payload : payload ,
963+ }
964+ addrBytesRead = addrsLen
965+ }
966+
967+ return addrBytesRead , address , nil
968+ }
0 commit comments