diff --git a/.travis.yml b/.travis.yml index dba2873..f13b2cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ os: language: go go: - - 1.12.x + - 1.13.x env: global: diff --git a/README.md b/README.md index 81c319d..5f90d39 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ > Home to the interfaces and abstractions that make up go-libp2p. +Minimum go version: 1.13 + ## Install ```sh diff --git a/crypto/ed25519.go b/crypto/ed25519.go index ceb3483..1707e75 100644 --- a/crypto/ed25519.go +++ b/crypto/ed25519.go @@ -2,14 +2,13 @@ package crypto import ( "bytes" + "crypto/ed25519" "crypto/subtle" "errors" "fmt" "io" pb "github.com/libp2p/go-libp2p-core/crypto/pb" - - "golang.org/x/crypto/ed25519" ) // Ed25519PrivateKey is an ed25519 private key. diff --git a/crypto/ed25519_test.go b/crypto/ed25519_test.go index 222b515..ae1bebe 100644 --- a/crypto/ed25519_test.go +++ b/crypto/ed25519_test.go @@ -1,12 +1,11 @@ package crypto import ( + "crypto/ed25519" "crypto/rand" "testing" pb "github.com/libp2p/go-libp2p-core/crypto/pb" - - "golang.org/x/crypto/ed25519" ) func TestBasicSignAndVerify(t *testing.T) { diff --git a/crypto/key.go b/crypto/key.go index bdb6f08..3a52636 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -351,12 +351,12 @@ func MarshalPrivateKey(k PrivKey) ([]byte, error) { return proto.Marshal(pbmes) } -// ConfigDecodeKey decodes from b64 (for config file), and unmarshals. +// ConfigDecodeKey decodes from b64 (for config file) to a byte array that can be unmarshalled. func ConfigDecodeKey(b string) ([]byte, error) { return base64.StdEncoding.DecodeString(b) } -// ConfigEncodeKey encodes to b64 (for config file), and marshals. +// ConfigEncodeKey encodes a marshalled key to b64 (for config file). func ConfigEncodeKey(b []byte) string { return base64.StdEncoding.EncodeToString(b) } diff --git a/crypto/key_not_openssl.go b/crypto/key_not_openssl.go index ae8b01f..6b5b6fc 100644 --- a/crypto/key_not_openssl.go +++ b/crypto/key_not_openssl.go @@ -5,10 +5,10 @@ package crypto import ( "crypto" "crypto/ecdsa" + "crypto/ed25519" "crypto/rsa" btcec "github.com/btcsuite/btcd/btcec" - "golang.org/x/crypto/ed25519" ) // KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p-core/crypto keys diff --git a/crypto/key_openssl.go b/crypto/key_openssl.go index 4545492..b948f3d 100644 --- a/crypto/key_openssl.go +++ b/crypto/key_openssl.go @@ -5,12 +5,12 @@ package crypto import ( "crypto" "crypto/ecdsa" + "crypto/ed25519" "crypto/rsa" "crypto/x509" btcec "github.com/btcsuite/btcd/btcec" openssl "github.com/libp2p/go-openssl" - "golang.org/x/crypto/ed25519" ) // KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p-core/crypto keys diff --git a/crypto/key_test.go b/crypto/key_test.go index aff2bad..984eaa1 100644 --- a/crypto/key_test.go +++ b/crypto/key_test.go @@ -4,6 +4,7 @@ import ( "bytes" "crypto" "crypto/ecdsa" + "crypto/ed25519" "crypto/elliptic" "crypto/rand" "crypto/rsa" @@ -15,7 +16,6 @@ import ( pb "github.com/libp2p/go-libp2p-core/crypto/pb" "github.com/libp2p/go-libp2p-core/test" sha256 "github.com/minio/sha256-simd" - "golang.org/x/crypto/ed25519" ) func TestKeys(t *testing.T) { diff --git a/crypto/pb/crypto.pb.go b/crypto/pb/crypto.pb.go index 5fa7aec..072fad9 100644 --- a/crypto/pb/crypto.pb.go +++ b/crypto/pb/crypto.pb.go @@ -9,6 +9,7 @@ import ( proto "github.com/gogo/protobuf/proto" io "io" math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. @@ -20,7 +21,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type KeyType int32 @@ -87,7 +88,7 @@ func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PublicKey.Marshal(b, m, deterministic) } else { b = b[:cap(b)] - n, err := m.MarshalTo(b) + n, err := m.MarshalToSizedBuffer(b) if err != nil { return nil, err } @@ -139,7 +140,7 @@ func (m *PrivateKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PrivateKey.Marshal(b, m, deterministic) } else { b = b[:cap(b)] - n, err := m.MarshalTo(b) + n, err := m.MarshalToSizedBuffer(b) if err != nil { return nil, err } @@ -200,7 +201,7 @@ var fileDescriptor_527278fb02d03321 = []byte{ func (m *PublicKey) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) if err != nil { return nil, err } @@ -208,26 +209,32 @@ func (m *PublicKey) Marshal() (dAtA []byte, err error) { } func (m *PublicKey) MarshalTo(dAtA []byte) (int, error) { - var i int + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PublicKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) _ = i var l int _ = l - dAtA[i] = 0x8 - i++ - i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) if m.Data != nil { - dAtA[i] = 0x12 - i++ + i -= len(m.Data) + copy(dAtA[i:], m.Data) i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data))) - i += copy(dAtA[i:], m.Data) + i-- + dAtA[i] = 0x12 } - return i, nil + i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil } func (m *PrivateKey) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) if err != nil { return nil, err } @@ -235,30 +242,38 @@ func (m *PrivateKey) Marshal() (dAtA []byte, err error) { } func (m *PrivateKey) MarshalTo(dAtA []byte) (int, error) { - var i int + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PrivateKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) _ = i var l int _ = l - dAtA[i] = 0x8 - i++ - i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) if m.Data != nil { - dAtA[i] = 0x12 - i++ + i -= len(m.Data) + copy(dAtA[i:], m.Data) i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data))) - i += copy(dAtA[i:], m.Data) + i-- + dAtA[i] = 0x12 } - return i, nil + i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil } func encodeVarintCrypto(dAtA []byte, offset int, v uint64) int { + offset -= sovCrypto(v) + base := offset for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } dAtA[offset] = uint8(v) - return offset + 1 + return base } func (m *PublicKey) Size() (n int) { if m == nil { @@ -289,14 +304,7 @@ func (m *PrivateKey) Size() (n int) { } func sovCrypto(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n + return (math_bits.Len64(x|1) + 6) / 7 } func sozCrypto(x uint64) (n int) { return sovCrypto(uint64((x << 1) ^ uint64((int64(x) >> 63)))) @@ -534,6 +542,7 @@ func (m *PrivateKey) Unmarshal(dAtA []byte) error { func skipCrypto(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 + depth := 0 for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { @@ -565,10 +574,8 @@ func skipCrypto(dAtA []byte) (n int, err error) { break } } - return iNdEx, nil case 1: iNdEx += 8 - return iNdEx, nil case 2: var length int for shift := uint(0); ; shift += 7 { @@ -589,55 +596,30 @@ func skipCrypto(dAtA []byte) (n int, err error) { return 0, ErrInvalidLengthCrypto } iNdEx += length - if iNdEx < 0 { - return 0, ErrInvalidLengthCrypto - } - return iNdEx, nil case 3: - for { - var innerWire uint64 - var start int = iNdEx - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowCrypto - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := skipCrypto(dAtA[start:]) - if err != nil { - return 0, err - } - iNdEx = start + next - if iNdEx < 0 { - return 0, ErrInvalidLengthCrypto - } - } - return iNdEx, nil + depth++ case 4: - return iNdEx, nil + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupCrypto + } + depth-- case 5: iNdEx += 4 - return iNdEx, nil default: return 0, fmt.Errorf("proto: illegal wireType %d", wireType) } + if iNdEx < 0 { + return 0, ErrInvalidLengthCrypto + } + if depth == 0 { + return iNdEx, nil + } } - panic("unreachable") + return 0, io.ErrUnexpectedEOF } var ( - ErrInvalidLengthCrypto = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowCrypto = fmt.Errorf("proto: integer overflow") + ErrInvalidLengthCrypto = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowCrypto = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupCrypto = fmt.Errorf("proto: unexpected end of group") ) diff --git a/crypto/rsa_openssl.go b/crypto/rsa_openssl.go index fd9d451..9b7a342 100644 --- a/crypto/rsa_openssl.go +++ b/crypto/rsa_openssl.go @@ -43,6 +43,9 @@ func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) { if err != nil { return nil, err } + if 8*key.key.Size() < MinRsaKeyBits { + return nil, ErrRsaKeyTooSmall + } if key.Type() != RSA { return nil, errors.New("not actually an rsa public key") } @@ -55,6 +58,9 @@ func UnmarshalRsaPublicKey(b []byte) (PubKey, error) { if err != nil { return nil, err } + if 8*key.key.Size() < MinRsaKeyBits { + return nil, ErrRsaKeyTooSmall + } if key.Type() != RSA { return nil, errors.New("not actually an rsa public key") } diff --git a/crypto/rsa_test.go b/crypto/rsa_test.go index 08db136..9de03a1 100644 --- a/crypto/rsa_test.go +++ b/crypto/rsa_test.go @@ -40,10 +40,32 @@ func TestRSABasicSignAndVerify(t *testing.T) { } func TestRSASmallKey(t *testing.T) { - _, _, err := GenerateRSAKeyPair(384, rand.Reader) + _, _, err := GenerateRSAKeyPair(MinRsaKeyBits/2, rand.Reader) if err != ErrRsaKeyTooSmall { t.Fatal("should have refused to create small RSA key") } + MinRsaKeyBits /= 2 + badPriv, badPub, err := GenerateRSAKeyPair(MinRsaKeyBits, rand.Reader) + if err != nil { + t.Fatalf("should have succeeded, got: %s", err) + } + pubBytes, err := MarshalPublicKey(badPub) + if err != nil { + t.Fatal(err) + } + privBytes, err := MarshalPrivateKey(badPriv) + if err != nil { + t.Fatal(err) + } + MinRsaKeyBits *= 2 + _, err = UnmarshalPublicKey(pubBytes) + if err != ErrRsaKeyTooSmall { + t.Fatal("should have refused to unmarshal a weak key") + } + _, err = UnmarshalPrivateKey(privBytes) + if err != ErrRsaKeyTooSmall { + t.Fatal("should have refused to unmarshal a weak key") + } } func TestRSASignZero(t *testing.T) { diff --git a/go.mod b/go.mod index a0476ea..19c559d 100644 --- a/go.mod +++ b/go.mod @@ -1,21 +1,19 @@ module github.com/libp2p/go-libp2p-core require ( - github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 + github.com/btcsuite/btcd v0.20.1-beta github.com/coreos/go-semver v0.3.0 - github.com/gogo/protobuf v1.3.0 + github.com/gogo/protobuf v1.3.1 github.com/ipfs/go-cid v0.0.3 github.com/jbenet/goprocess v0.1.3 - github.com/libp2p/go-flow-metrics v0.0.1 - github.com/libp2p/go-msgio v0.0.4 - github.com/libp2p/go-openssl v0.0.2 + github.com/libp2p/go-flow-metrics v0.0.3 + github.com/libp2p/go-openssl v0.0.4 github.com/minio/sha256-simd v0.1.1 - github.com/mr-tron/base58 v1.1.2 - github.com/multiformats/go-multiaddr v0.1.1 - github.com/multiformats/go-multihash v0.0.8 + github.com/mr-tron/base58 v1.1.3 + github.com/multiformats/go-multiaddr v0.1.2 + github.com/multiformats/go-multihash v0.0.10 github.com/smola/gocompat v0.2.0 - go.opencensus.io v0.22.1 - golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 + go.opencensus.io v0.22.2 ) -go 1.12 +go 1.13 diff --git a/go.sum b/go.sum index 748f03f..1193092 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0= -github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng= @@ -23,11 +23,12 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -64,16 +65,12 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= -github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= -github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= -github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= -github.com/libp2p/go-msgio v0.0.4 h1:agEFehY3zWJFUHK6SEMR7UYmk2z6kC3oeCM7ybLhguA= -github.com/libp2p/go-msgio v0.0.4 h1:agEFehY3zWJFUHK6SEMR7UYmk2z6kC3oeCM7ybLhguA= -github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= -github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= -github.com/libp2p/go-openssl v0.0.2 h1:9pP2d3Ubaxkv7ZisLjx9BFwgOGnQdQYnfcH29HNY3ls= -github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= +github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM= +github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= +github.com/libp2p/go-openssl v0.0.4 h1:d27YZvLoTyMhIN4njrkr8zMDOM4lfpHIp6A+TK9fovg= +github.com/libp2p/go-openssl v0.0.4 h1:d27YZvLoTyMhIN4njrkr8zMDOM4lfpHIp6A+TK9fovg= +github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= @@ -92,16 +89,22 @@ github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= -github.com/multiformats/go-multiaddr v0.1.1 h1:rVAztJYMhCQ7vEFr8FvxW3mS+HF2eY/oPbOMeS0ZDnE= -github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= +github.com/multiformats/go-multiaddr v0.1.2 h1:HWYHNSyyllbQopmVIF5K7JKJugiah+L9/kuZKHbmNdQ= +github.com/multiformats/go-multiaddr v0.1.2/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.10 h1:lMoNbh2Ssd9PUF74Nz008KGzGPlfeV6wH3rit5IIGCM= +github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-varint v0.0.1 h1:TR/0rdQtnNxuN2IhiB639xC3tWM4IUi7DkTBVTdGW/M= +github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -117,22 +120,24 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/src-d/envconfig v1.0.0 h1:/AJi6DtjFhZKNx3OB2qMsq7y4yT5//AeSZIe7rk+PX8= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50= -go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= +go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -161,8 +166,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -191,4 +194,6 @@ gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFab gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/metrics/bandwidth.go b/metrics/bandwidth.go index e2c8acf..2d94b05 100644 --- a/metrics/bandwidth.go +++ b/metrics/bandwidth.go @@ -2,6 +2,8 @@ package metrics import ( + "time" + "github.com/libp2p/go-flow-metrics" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/protocol" @@ -151,3 +153,23 @@ func (bwc *BandwidthCounter) GetBandwidthByProtocol() map[protocol.ID]Stats { return protocols } + +// Reset clears all stats. +func (bwc *BandwidthCounter) Reset() { + bwc.totalIn.Reset() + bwc.totalOut.Reset() + + bwc.protocolIn.Clear() + bwc.protocolOut.Clear() + + bwc.peerIn.Clear() + bwc.peerOut.Clear() +} + +// TrimIdle trims all timers idle since the given time. +func (bwc *BandwidthCounter) TrimIdle(since time.Time) { + bwc.peerIn.TrimIdle(since) + bwc.peerOut.TrimIdle(since) + bwc.protocolIn.TrimIdle(since) + bwc.protocolOut.TrimIdle(since) +} diff --git a/metrics/bandwidth_test.go b/metrics/bandwidth_test.go index de7b0fd..a3232e1 100644 --- a/metrics/bandwidth_test.go +++ b/metrics/bandwidth_test.go @@ -48,8 +48,8 @@ func round(bwc *BandwidthCounter, b *testing.B) { b.StopTimer() } -// Allow 7% errors for bw calculations. -const acceptableError = 0.07 +// Allow 1% errors for bw calculations. +const acceptableError = 0.01 func TestBandwidthCounter(t *testing.T) { bwc := NewBandwidthCounter() @@ -62,12 +62,19 @@ func TestBandwidthCounter(t *testing.T) { proto := protocol.ID(fmt.Sprintf("proto-%d", j)) go func() { defer wg.Done() + + // make sure the bandwidth counters are active + bwc.LogSentMessage(100) + bwc.LogRecvMessage(50) + bwc.LogSentMessageStream(100, proto, p) + bwc.LogRecvMessageStream(50, proto, p) + <-start t := time.NewTicker(100 * time.Millisecond) defer t.Stop() - for i := 0; i < 40; i++ { + for i := 0; i < 39; i++ { bwc.LogSentMessage(100) bwc.LogRecvMessage(50) bwc.LogSentMessageStream(100, proto, p) @@ -104,6 +111,7 @@ func TestBandwidthCounter(t *testing.T) { } } + time.Sleep(time.Second) close(start) time.Sleep(2*time.Second + 100*time.Millisecond) @@ -143,6 +151,71 @@ func TestBandwidthCounter(t *testing.T) { } } +func TestResetBandwidthCounter(t *testing.T) { + bwc := NewBandwidthCounter() + + p := peer.ID("peer-0") + proto := protocol.ID("proto-0") + + // We don't calculate bandwidth till we've been active for a second. + bwc.LogSentMessage(42) + bwc.LogRecvMessage(24) + bwc.LogSentMessageStream(100, proto, p) + bwc.LogRecvMessageStream(50, proto, p) + + time.Sleep(1*time.Second + time.Millisecond) + + bwc.LogSentMessage(42) + bwc.LogRecvMessage(24) + bwc.LogSentMessageStream(100, proto, p) + bwc.LogRecvMessageStream(50, proto, p) + + time.Sleep(1*time.Second + time.Millisecond) + + { + stats := bwc.GetBandwidthTotals() + assertEq(t, 84, stats.TotalOut) + assertEq(t, 48, stats.TotalIn) + } + + { + stats := bwc.GetBandwidthByProtocol() + assertApproxEq(t, 1, float64(len(stats))) + stat := stats[proto] + assertApproxEq(t, 100, stat.RateOut) + assertApproxEq(t, 50, stat.RateIn) + } + + { + stats := bwc.GetBandwidthByPeer() + assertApproxEq(t, 1, float64(len(stats))) + stat := stats[p] + assertApproxEq(t, 100, stat.RateOut) + assertApproxEq(t, 50, stat.RateIn) + } + + bwc.Reset() + { + stats := bwc.GetBandwidthTotals() + assertEq(t, 0, stats.TotalOut) + assertEq(t, 0, stats.TotalIn) + } + + { + byProtocol := bwc.GetBandwidthByProtocol() + if len(byProtocol) != 0 { + t.Errorf("expected 0 protocols, got %d", len(byProtocol)) + } + } + + { + byPeer := bwc.GetBandwidthByPeer() + if len(byPeer) != 0 { + t.Errorf("expected 0 peers, got %d", len(byPeer)) + } + } +} + func assertEq(t *testing.T, expected, actual int64) { if expected != actual { t.Errorf("expected %d, got %d", expected, actual) diff --git a/routing/query.go b/routing/query.go index 3769d1c..42acdb1 100644 --- a/routing/query.go +++ b/routing/query.go @@ -7,22 +7,32 @@ import ( "github.com/libp2p/go-libp2p-core/peer" ) +// QueryEventType indicates the query event's type. type QueryEventType int // Number of events to buffer. var QueryEventBufferSize = 16 const ( + // Sending a query to a peer. SendingQuery QueryEventType = iota + // Got a response from a peer. PeerResponse + // Found a "closest" peer (not currently used). FinalPeer + // Got an error when querying. QueryError + // Found a provider. Provider + // Found a value. Value + // Adding a peer to the query. AddingPeer + // Dialing a peer. DialingPeer ) +// QueryEvent is emitted for every notable event that happens during a DHT query. type QueryEvent struct { ID peer.ID Type QueryEventType @@ -67,6 +77,12 @@ func (e *eventChannel) send(ctx context.Context, ev *QueryEvent) { e.mu.Unlock() } +// RegisterForQueryEvents registers a query event channel with the given +// context. The returned context can be passed to DHT queries to receive query +// events on the returned channels. +// +// The passed context MUST be canceled when the caller is no longer interested +// in query events. func RegisterForQueryEvents(ctx context.Context) (context.Context, <-chan *QueryEvent) { ch := make(chan *QueryEvent, QueryEventBufferSize) ech := &eventChannel{ch: ch, ctx: ctx} @@ -74,6 +90,8 @@ func RegisterForQueryEvents(ctx context.Context) (context.Context, <-chan *Query return context.WithValue(ctx, routingQueryKey{}, ech), ch } +// PublishQueryEvent publishes a query event to the query event channel +// associated with the given context, if any. func PublishQueryEvent(ctx context.Context, ev *QueryEvent) { ich := ctx.Value(routingQueryKey{}) if ich == nil { diff --git a/sec/insecure/insecure.go b/sec/insecure/insecure.go index e3670c2..259b4f2 100644 --- a/sec/insecure/insecure.go +++ b/sec/insecure/insecure.go @@ -6,11 +6,13 @@ package insecure import ( "context" "fmt" + "io" "net" + gogoio "github.com/gogo/protobuf/io" + "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-msgio" ci "github.com/libp2p/go-libp2p-core/crypto" pb "github.com/libp2p/go-libp2p-core/sec/insecure/pb" @@ -143,7 +145,6 @@ func (ic *Conn) runHandshakeSync() error { return nil } - rw := msgio.NewReadWriter(ic.Conn) // Generate an Exchange message msg, err := makeExchangeMessage(ic.localPrivKey.GetPublic()) if err != nil { @@ -151,7 +152,7 @@ func (ic *Conn) runHandshakeSync() error { } // Send our Exchange and read theirs - remoteMsg, err := readWriteMsg(rw, msg) + remoteMsg, err := readWriteMsg(ic.Conn, msg) if err != nil { return err } @@ -181,31 +182,28 @@ func (ic *Conn) runHandshakeSync() error { } // read and write a message at the same time. -func readWriteMsg(c msgio.ReadWriter, out *pb.Exchange) (*pb.Exchange, error) { - outBytes, err := out.Marshal() +func readWriteMsg(rw io.ReadWriter, out *pb.Exchange) (*pb.Exchange, error) { + const maxMsgSize = 1 << 16 + r := gogoio.NewDelimitedReader(rw, maxMsgSize) + w := gogoio.NewDelimitedWriter(rw) + wresult := make(chan error) + go func() { + wresult <- w.WriteMsg(out) + }() + + inMsg := pb.Exchange{} + err := r.ReadMsg(&inMsg) + + // Always wait for the write to finish. + err2 := <-wresult + if err != nil { return nil, err } - wresult := make(chan error) - go func() { - wresult <- c.WriteMsg(outBytes) - }() - - msg, err1 := c.ReadMsg() - - // Always wait for the read to finish. - err2 := <-wresult - - if err1 != nil { - return nil, err1 - } if err2 != nil { - c.ReleaseMsg(msg) return nil, err2 } - inMsg := new(pb.Exchange) - err = inMsg.Unmarshal(msg) - return inMsg, err + return &inMsg, err } // LocalPeer returns the local peer ID. diff --git a/sec/insecure/pb/plaintext.pb.go b/sec/insecure/pb/plaintext.pb.go index 68b12f0..4c5af18 100644 --- a/sec/insecure/pb/plaintext.pb.go +++ b/sec/insecure/pb/plaintext.pb.go @@ -9,6 +9,7 @@ import ( pb "github.com/libp2p/go-libp2p-core/crypto/pb" io "io" math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. @@ -20,7 +21,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Exchange struct { Id []byte `protobuf:"bytes,1,opt,name=id" json:"id"` @@ -41,7 +42,7 @@ func (m *Exchange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Exchange.Marshal(b, m, deterministic) } else { b = b[:cap(b)] - n, err := m.MarshalTo(b) + n, err := m.MarshalToSizedBuffer(b) if err != nil { return nil, err } @@ -99,7 +100,7 @@ var fileDescriptor_aba144f73931b711 = []byte{ func (m *Exchange) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) if err != nil { return nil, err } @@ -107,37 +108,47 @@ func (m *Exchange) Marshal() (dAtA []byte, err error) { } func (m *Exchange) MarshalTo(dAtA []byte) (int, error) { - var i int + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Exchange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) _ = i var l int _ = l - if m.Id != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintPlaintext(dAtA, i, uint64(len(m.Id))) - i += copy(dAtA[i:], m.Id) - } if m.Pubkey != nil { - dAtA[i] = 0x12 - i++ - i = encodeVarintPlaintext(dAtA, i, uint64(m.Pubkey.Size())) - n1, err := m.Pubkey.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err + { + size, err := m.Pubkey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPlaintext(dAtA, i, uint64(size)) } - i += n1 + i-- + dAtA[i] = 0x12 } - return i, nil + if m.Id != nil { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintPlaintext(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } func encodeVarintPlaintext(dAtA []byte, offset int, v uint64) int { + offset -= sovPlaintext(v) + base := offset for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } dAtA[offset] = uint8(v) - return offset + 1 + return base } func (m *Exchange) Size() (n int) { if m == nil { @@ -157,14 +168,7 @@ func (m *Exchange) Size() (n int) { } func sovPlaintext(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n + return (math_bits.Len64(x|1) + 6) / 7 } func sozPlaintext(x uint64) (n int) { return sovPlaintext(uint64((x << 1) ^ uint64((int64(x) >> 63)))) @@ -295,6 +299,7 @@ func (m *Exchange) Unmarshal(dAtA []byte) error { func skipPlaintext(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 + depth := 0 for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { @@ -326,10 +331,8 @@ func skipPlaintext(dAtA []byte) (n int, err error) { break } } - return iNdEx, nil case 1: iNdEx += 8 - return iNdEx, nil case 2: var length int for shift := uint(0); ; shift += 7 { @@ -350,55 +353,30 @@ func skipPlaintext(dAtA []byte) (n int, err error) { return 0, ErrInvalidLengthPlaintext } iNdEx += length - if iNdEx < 0 { - return 0, ErrInvalidLengthPlaintext - } - return iNdEx, nil case 3: - for { - var innerWire uint64 - var start int = iNdEx - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPlaintext - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := skipPlaintext(dAtA[start:]) - if err != nil { - return 0, err - } - iNdEx = start + next - if iNdEx < 0 { - return 0, ErrInvalidLengthPlaintext - } - } - return iNdEx, nil + depth++ case 4: - return iNdEx, nil + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupPlaintext + } + depth-- case 5: iNdEx += 4 - return iNdEx, nil default: return 0, fmt.Errorf("proto: illegal wireType %d", wireType) } + if iNdEx < 0 { + return 0, ErrInvalidLengthPlaintext + } + if depth == 0 { + return iNdEx, nil + } } - panic("unreachable") + return 0, io.ErrUnexpectedEOF } var ( - ErrInvalidLengthPlaintext = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowPlaintext = fmt.Errorf("proto: integer overflow") + ErrInvalidLengthPlaintext = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPlaintext = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupPlaintext = fmt.Errorf("proto: unexpected end of group") )