Repository: libp2p/go-libp2p
Pull request #2946 (2024-08-30 15:12:01)

Release v0.36.3
Same as master except

- Make BlackHoleState type public 99433a2f99459244b8671d1e2d7d01af8d5888a5


Patch:
diff --git a/.github/workflows/go-check.yml b/.github/workflows/go-check.yml
index a1cc205f..617f59e4 100644
--- a/.github/workflows/go-check.yml
+++ b/.github/workflows/go-check.yml
@@ -17,4 +17,5 @@ jobs:
   go-check:
     uses: ipdxco/unified-github-workflows/.github/workflows/go-check.yml@v1.0
     with:
+      go-version: "1.22.x"
       go-generate-ignore-protoc-version-comments: true
diff --git a/core/crypto/key.go b/core/crypto/key.go
index 6725188d..ef697ad6 100644
--- a/core/crypto/key.go
+++ b/core/crypto/key.go
@@ -15,8 +15,6 @@ import (
 	"google.golang.org/protobuf/proto"
 )
 
-//go:generate protoc --go_out=. --go_opt=Mpb/crypto.proto=./pb pb/crypto.proto
-
 const (
 	// RSA is an enum for the supported RSA key type
 	RSA = iota
diff --git a/core/crypto/pb/crypto.pb.go b/core/crypto/pb/crypto.pb.go
index 8f48c7bb..4c83183e 100644
--- a/core/crypto/pb/crypto.pb.go
+++ b/core/crypto/pb/crypto.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/crypto.proto
+// 	protoc        v5.27.3
+// source: core/crypto/pb/crypto.proto
 
 package pb
 
@@ -56,11 +56,11 @@ func (x KeyType) String() string {
 }
 
 func (KeyType) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_crypto_proto_enumTypes[0].Descriptor()
+	return file_core_crypto_pb_crypto_proto_enumTypes[0].Descriptor()
 }
 
 func (KeyType) Type() protoreflect.EnumType {
-	return &file_pb_crypto_proto_enumTypes[0]
+	return &file_core_crypto_pb_crypto_proto_enumTypes[0]
 }
 
 func (x KeyType) Number() protoreflect.EnumNumber {
@@ -79,7 +79,7 @@ func (x *KeyType) UnmarshalJSON(b []byte) error {
 
 // Deprecated: Use KeyType.Descriptor instead.
 func (KeyType) EnumDescriptor() ([]byte, []int) {
-	return file_pb_crypto_proto_rawDescGZIP(), []int{0}
+	return file_core_crypto_pb_crypto_proto_rawDescGZIP(), []int{0}
 }
 
 type PublicKey struct {
@@ -94,7 +94,7 @@ type PublicKey struct {
 func (x *PublicKey) Reset() {
 	*x = PublicKey{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_crypto_proto_msgTypes[0]
+		mi := &file_core_crypto_pb_crypto_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -107,7 +107,7 @@ func (x *PublicKey) String() string {
 func (*PublicKey) ProtoMessage() {}
 
 func (x *PublicKey) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_crypto_proto_msgTypes[0]
+	mi := &file_core_crypto_pb_crypto_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -120,7 +120,7 @@ func (x *PublicKey) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PublicKey.ProtoReflect.Descriptor instead.
 func (*PublicKey) Descriptor() ([]byte, []int) {
-	return file_pb_crypto_proto_rawDescGZIP(), []int{0}
+	return file_core_crypto_pb_crypto_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *PublicKey) GetType() KeyType {
@@ -149,7 +149,7 @@ type PrivateKey struct {
 func (x *PrivateKey) Reset() {
 	*x = PrivateKey{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_crypto_proto_msgTypes[1]
+		mi := &file_core_crypto_pb_crypto_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -162,7 +162,7 @@ func (x *PrivateKey) String() string {
 func (*PrivateKey) ProtoMessage() {}
 
 func (x *PrivateKey) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_crypto_proto_msgTypes[1]
+	mi := &file_core_crypto_pb_crypto_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -175,7 +175,7 @@ func (x *PrivateKey) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PrivateKey.ProtoReflect.Descriptor instead.
 func (*PrivateKey) Descriptor() ([]byte, []int) {
-	return file_pb_crypto_proto_rawDescGZIP(), []int{1}
+	return file_core_crypto_pb_crypto_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *PrivateKey) GetType() KeyType {
@@ -192,49 +192,50 @@ func (x *PrivateKey) GetData() []byte {
 	return nil
 }
 
-var File_pb_crypto_proto protoreflect.FileDescriptor
-
-var file_pb_crypto_proto_rawDesc = []byte{
-	0x0a, 0x0f, 0x70, 0x62, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x12, 0x09, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x22, 0x47, 0x0a, 0x09,
-	0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70,
-	0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f,
-	0x2e, 0x70, 0x62, 0x2e, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70,
-	0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52,
-	0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x48, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
-	0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28,
-	0x0e, 0x32, 0x12, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x2e, 0x4b, 0x65,
-	0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44,
-	0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x2a,
-	0x39, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x53,
-	0x41, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01,
-	0x12, 0x0d, 0x0a, 0x09, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x10, 0x02, 0x12,
-	0x09, 0x0a, 0x05, 0x45, 0x43, 0x44, 0x53, 0x41, 0x10, 0x03, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69,
-	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f,
-	0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63,
-	0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f, 0x70, 0x62,
+var File_core_crypto_pb_crypto_proto protoreflect.FileDescriptor
+
+var file_core_crypto_pb_crypto_proto_rawDesc = []byte{
+	0x0a, 0x1b, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f, 0x70, 0x62,
+	0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x63,
+	0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x22, 0x47, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c,
+	0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20,
+	0x02, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x2e,
+	0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a,
+	0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74,
+	0x61, 0x22, 0x48, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12,
+	0x26, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x12, 0x2e,
+	0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x2e, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70,
+	0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18,
+	0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x2a, 0x39, 0x0a, 0x07, 0x4b,
+	0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x53, 0x41, 0x10, 0x00, 0x12,
+	0x0b, 0x0a, 0x07, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09,
+	0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45,
+	0x43, 0x44, 0x53, 0x41, 0x10, 0x03, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d, 0x6c,
+	0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74,
+	0x6f, 0x2f, 0x70, 0x62,
 }
 
 var (
-	file_pb_crypto_proto_rawDescOnce sync.Once
-	file_pb_crypto_proto_rawDescData = file_pb_crypto_proto_rawDesc
+	file_core_crypto_pb_crypto_proto_rawDescOnce sync.Once
+	file_core_crypto_pb_crypto_proto_rawDescData = file_core_crypto_pb_crypto_proto_rawDesc
 )
 
-func file_pb_crypto_proto_rawDescGZIP() []byte {
-	file_pb_crypto_proto_rawDescOnce.Do(func() {
-		file_pb_crypto_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_crypto_proto_rawDescData)
+func file_core_crypto_pb_crypto_proto_rawDescGZIP() []byte {
+	file_core_crypto_pb_crypto_proto_rawDescOnce.Do(func() {
+		file_core_crypto_pb_crypto_proto_rawDescData = protoimpl.X.CompressGZIP(file_core_crypto_pb_crypto_proto_rawDescData)
 	})
-	return file_pb_crypto_proto_rawDescData
+	return file_core_crypto_pb_crypto_proto_rawDescData
 }
 
-var file_pb_crypto_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_pb_crypto_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
-var file_pb_crypto_proto_goTypes = []any{
+var file_core_crypto_pb_crypto_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_core_crypto_pb_crypto_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_core_crypto_pb_crypto_proto_goTypes = []any{
 	(KeyType)(0),       // 0: crypto.pb.KeyType
 	(*PublicKey)(nil),  // 1: crypto.pb.PublicKey
 	(*PrivateKey)(nil), // 2: crypto.pb.PrivateKey
 }
-var file_pb_crypto_proto_depIdxs = []int32{
+var file_core_crypto_pb_crypto_proto_depIdxs = []int32{
 	0, // 0: crypto.pb.PublicKey.Type:type_name -> crypto.pb.KeyType
 	0, // 1: crypto.pb.PrivateKey.Type:type_name -> crypto.pb.KeyType
 	2, // [2:2] is the sub-list for method output_type
@@ -244,13 +245,13 @@ var file_pb_crypto_proto_depIdxs = []int32{
 	0, // [0:2] is the sub-list for field type_name
 }
 
-func init() { file_pb_crypto_proto_init() }
-func file_pb_crypto_proto_init() {
-	if File_pb_crypto_proto != nil {
+func init() { file_core_crypto_pb_crypto_proto_init() }
+func file_core_crypto_pb_crypto_proto_init() {
+	if File_core_crypto_pb_crypto_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_crypto_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_core_crypto_pb_crypto_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*PublicKey); i {
 			case 0:
 				return &v.state
@@ -262,7 +263,7 @@ func file_pb_crypto_proto_init() {
 				return nil
 			}
 		}
-		file_pb_crypto_proto_msgTypes[1].Exporter = func(v any, i int) any {
+		file_core_crypto_pb_crypto_proto_msgTypes[1].Exporter = func(v any, i int) any {
 			switch v := v.(*PrivateKey); i {
 			case 0:
 				return &v.state
@@ -279,19 +280,19 @@ func file_pb_crypto_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_crypto_proto_rawDesc,
+			RawDescriptor: file_core_crypto_pb_crypto_proto_rawDesc,
 			NumEnums:      1,
 			NumMessages:   2,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_crypto_proto_goTypes,
-		DependencyIndexes: file_pb_crypto_proto_depIdxs,
-		EnumInfos:         file_pb_crypto_proto_enumTypes,
-		MessageInfos:      file_pb_crypto_proto_msgTypes,
+		GoTypes:           file_core_crypto_pb_crypto_proto_goTypes,
+		DependencyIndexes: file_core_crypto_pb_crypto_proto_depIdxs,
+		EnumInfos:         file_core_crypto_pb_crypto_proto_enumTypes,
+		MessageInfos:      file_core_crypto_pb_crypto_proto_msgTypes,
 	}.Build()
-	File_pb_crypto_proto = out.File
-	file_pb_crypto_proto_rawDesc = nil
-	file_pb_crypto_proto_goTypes = nil
-	file_pb_crypto_proto_depIdxs = nil
+	File_core_crypto_pb_crypto_proto = out.File
+	file_core_crypto_pb_crypto_proto_rawDesc = nil
+	file_core_crypto_pb_crypto_proto_goTypes = nil
+	file_core_crypto_pb_crypto_proto_depIdxs = nil
 }
diff --git a/core/peer/pb/peer_record.pb.go b/core/peer/pb/peer_record.pb.go
index 9b37df65..ef9e2aea 100644
--- a/core/peer/pb/peer_record.pb.go
+++ b/core/peer/pb/peer_record.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/peer_record.proto
+// 	protoc        v5.27.3
+// source: core/peer/pb/peer_record.proto
 
 package pb
 
@@ -44,7 +44,7 @@ type PeerRecord struct {
 func (x *PeerRecord) Reset() {
 	*x = PeerRecord{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_peer_record_proto_msgTypes[0]
+		mi := &file_core_peer_pb_peer_record_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -57,7 +57,7 @@ func (x *PeerRecord) String() string {
 func (*PeerRecord) ProtoMessage() {}
 
 func (x *PeerRecord) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_peer_record_proto_msgTypes[0]
+	mi := &file_core_peer_pb_peer_record_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -70,7 +70,7 @@ func (x *PeerRecord) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeerRecord.ProtoReflect.Descriptor instead.
 func (*PeerRecord) Descriptor() ([]byte, []int) {
-	return file_pb_peer_record_proto_rawDescGZIP(), []int{0}
+	return file_core_peer_pb_peer_record_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *PeerRecord) GetPeerId() []byte {
@@ -107,7 +107,7 @@ type PeerRecord_AddressInfo struct {
 func (x *PeerRecord_AddressInfo) Reset() {
 	*x = PeerRecord_AddressInfo{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_peer_record_proto_msgTypes[1]
+		mi := &file_core_peer_pb_peer_record_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -120,7 +120,7 @@ func (x *PeerRecord_AddressInfo) String() string {
 func (*PeerRecord_AddressInfo) ProtoMessage() {}
 
 func (x *PeerRecord_AddressInfo) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_peer_record_proto_msgTypes[1]
+	mi := &file_core_peer_pb_peer_record_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -133,7 +133,7 @@ func (x *PeerRecord_AddressInfo) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PeerRecord_AddressInfo.ProtoReflect.Descriptor instead.
 func (*PeerRecord_AddressInfo) Descriptor() ([]byte, []int) {
-	return file_pb_peer_record_proto_rawDescGZIP(), []int{0, 0}
+	return file_core_peer_pb_peer_record_proto_rawDescGZIP(), []int{0, 0}
 }
 
 func (x *PeerRecord_AddressInfo) GetMultiaddr() []byte {
@@ -143,42 +143,46 @@ func (x *PeerRecord_AddressInfo) GetMultiaddr() []byte {
 	return nil
 }
 
-var File_pb_peer_record_proto protoreflect.FileDescriptor
-
-var file_pb_peer_record_proto_rawDesc = []byte{
-	0x0a, 0x14, 0x70, 0x62, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x70, 0x65, 0x65, 0x72, 0x2e, 0x70, 0x62, 0x22,
-	0xa3, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x17,
-	0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
-	0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x3d, 0x0a, 0x09, 0x61, 0x64, 0x64,
-	0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70,
-	0x65, 0x65, 0x72, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72,
-	0x64, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x61,
-	0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x1a, 0x2b, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x72,
-	0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69,
-	0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74,
-	0x69, 0x61, 0x64, 0x64, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+var File_core_peer_pb_peer_record_proto protoreflect.FileDescriptor
+
+var file_core_peer_pb_peer_record_proto_rawDesc = []byte{
+	0x0a, 0x1e, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x2f, 0x70, 0x62, 0x2f, 0x70,
+	0x65, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x12, 0x07, 0x70, 0x65, 0x65, 0x72, 0x2e, 0x70, 0x62, 0x22, 0xa3, 0x01, 0x0a, 0x0a, 0x50, 0x65,
+	0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49,
+	0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03,
+	0x73, 0x65, 0x71, 0x12, 0x3d, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73,
+	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x2e, 0x70, 0x62,
+	0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x72,
+	0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
+	0x65, 0x73, 0x1a, 0x2b, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66,
+	0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x42,
+	0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69,
+	0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x63,
+	0x6f, 0x72, 0x65, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x33,
 }
 
 var (
-	file_pb_peer_record_proto_rawDescOnce sync.Once
-	file_pb_peer_record_proto_rawDescData = file_pb_peer_record_proto_rawDesc
+	file_core_peer_pb_peer_record_proto_rawDescOnce sync.Once
+	file_core_peer_pb_peer_record_proto_rawDescData = file_core_peer_pb_peer_record_proto_rawDesc
 )
 
-func file_pb_peer_record_proto_rawDescGZIP() []byte {
-	file_pb_peer_record_proto_rawDescOnce.Do(func() {
-		file_pb_peer_record_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_peer_record_proto_rawDescData)
+func file_core_peer_pb_peer_record_proto_rawDescGZIP() []byte {
+	file_core_peer_pb_peer_record_proto_rawDescOnce.Do(func() {
+		file_core_peer_pb_peer_record_proto_rawDescData = protoimpl.X.CompressGZIP(file_core_peer_pb_peer_record_proto_rawDescData)
 	})
-	return file_pb_peer_record_proto_rawDescData
+	return file_core_peer_pb_peer_record_proto_rawDescData
 }
 
-var file_pb_peer_record_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
-var file_pb_peer_record_proto_goTypes = []any{
+var file_core_peer_pb_peer_record_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_core_peer_pb_peer_record_proto_goTypes = []any{
 	(*PeerRecord)(nil),             // 0: peer.pb.PeerRecord
 	(*PeerRecord_AddressInfo)(nil), // 1: peer.pb.PeerRecord.AddressInfo
 }
-var file_pb_peer_record_proto_depIdxs = []int32{
+var file_core_peer_pb_peer_record_proto_depIdxs = []int32{
 	1, // 0: peer.pb.PeerRecord.addresses:type_name -> peer.pb.PeerRecord.AddressInfo
 	1, // [1:1] is the sub-list for method output_type
 	1, // [1:1] is the sub-list for method input_type
@@ -187,13 +191,13 @@ var file_pb_peer_record_proto_depIdxs = []int32{
 	0, // [0:1] is the sub-list for field type_name
 }
 
-func init() { file_pb_peer_record_proto_init() }
-func file_pb_peer_record_proto_init() {
-	if File_pb_peer_record_proto != nil {
+func init() { file_core_peer_pb_peer_record_proto_init() }
+func file_core_peer_pb_peer_record_proto_init() {
+	if File_core_peer_pb_peer_record_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_peer_record_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_core_peer_pb_peer_record_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*PeerRecord); i {
 			case 0:
 				return &v.state
@@ -205,7 +209,7 @@ func file_pb_peer_record_proto_init() {
 				return nil
 			}
 		}
-		file_pb_peer_record_proto_msgTypes[1].Exporter = func(v any, i int) any {
+		file_core_peer_pb_peer_record_proto_msgTypes[1].Exporter = func(v any, i int) any {
 			switch v := v.(*PeerRecord_AddressInfo); i {
 			case 0:
 				return &v.state
@@ -222,18 +226,18 @@ func file_pb_peer_record_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_peer_record_proto_rawDesc,
+			RawDescriptor: file_core_peer_pb_peer_record_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   2,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_peer_record_proto_goTypes,
-		DependencyIndexes: file_pb_peer_record_proto_depIdxs,
-		MessageInfos:      file_pb_peer_record_proto_msgTypes,
+		GoTypes:           file_core_peer_pb_peer_record_proto_goTypes,
+		DependencyIndexes: file_core_peer_pb_peer_record_proto_depIdxs,
+		MessageInfos:      file_core_peer_pb_peer_record_proto_msgTypes,
 	}.Build()
-	File_pb_peer_record_proto = out.File
-	file_pb_peer_record_proto_rawDesc = nil
-	file_pb_peer_record_proto_goTypes = nil
-	file_pb_peer_record_proto_depIdxs = nil
+	File_core_peer_pb_peer_record_proto = out.File
+	file_core_peer_pb_peer_record_proto_rawDesc = nil
+	file_core_peer_pb_peer_record_proto_goTypes = nil
+	file_core_peer_pb_peer_record_proto_depIdxs = nil
 }
diff --git a/core/peer/pb/peer_record.proto b/core/peer/pb/peer_record.proto
index 55dd43a2..3a97e1a4 100644
--- a/core/peer/pb/peer_record.proto
+++ b/core/peer/pb/peer_record.proto
@@ -2,6 +2,8 @@ syntax = "proto3";
 
 package peer.pb;
 
+option go_package = "github.com/libp2p/go-libp2p/core/peer/pb";
+
 // PeerRecord messages contain information that is useful to share with other peers.
 // Currently, a PeerRecord contains the public listen addresses for a peer, but this
 // is expected to expand to include other information in the future.
diff --git a/core/peer/record.go b/core/peer/record.go
index 49d89e14..fce69ce0 100644
--- a/core/peer/record.go
+++ b/core/peer/record.go
@@ -14,8 +14,6 @@ import (
 	"google.golang.org/protobuf/proto"
 )
 
-//go:generate protoc --proto_path=$PWD:$PWD/../.. --go_out=. --go_opt=Mpb/peer_record.proto=./pb pb/peer_record.proto
-
 var _ record.Record = (*PeerRecord)(nil)
 
 func init() {
diff --git a/core/record/envelope.go b/core/record/envelope.go
index 2ad01718..413a55c9 100644
--- a/core/record/envelope.go
+++ b/core/record/envelope.go
@@ -16,8 +16,6 @@ import (
 	"google.golang.org/protobuf/proto"
 )
 
-//go:generate protoc --proto_path=$PWD:$PWD/../.. --go_out=. --go_opt=Mpb/envelope.proto=./pb pb/envelope.proto
-
 // Envelope contains an arbitrary []byte payload, signed by a libp2p peer.
 //
 // Envelopes are signed in the context of a particular "domain", which is a
diff --git a/core/record/pb/envelope.pb.go b/core/record/pb/envelope.pb.go
index 58a1be1d..9be1a5ff 100644
--- a/core/record/pb/envelope.pb.go
+++ b/core/record/pb/envelope.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/envelope.proto
+// 	protoc        v5.27.3
+// source: core/record/pb/envelope.proto
 
 package pb
 
@@ -50,7 +50,7 @@ type Envelope struct {
 func (x *Envelope) Reset() {
 	*x = Envelope{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_envelope_proto_msgTypes[0]
+		mi := &file_core_record_pb_envelope_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -63,7 +63,7 @@ func (x *Envelope) String() string {
 func (*Envelope) ProtoMessage() {}
 
 func (x *Envelope) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_envelope_proto_msgTypes[0]
+	mi := &file_core_record_pb_envelope_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -76,7 +76,7 @@ func (x *Envelope) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Envelope.ProtoReflect.Descriptor instead.
 func (*Envelope) Descriptor() ([]byte, []int) {
-	return file_pb_envelope_proto_rawDescGZIP(), []int{0}
+	return file_core_record_pb_envelope_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *Envelope) GetPublicKey() *pb.PublicKey {
@@ -107,43 +107,47 @@ func (x *Envelope) GetSignature() []byte {
 	return nil
 }
 
-var File_pb_envelope_proto protoreflect.FileDescriptor
-
-var file_pb_envelope_proto_rawDesc = []byte{
-	0x0a, 0x11, 0x70, 0x62, 0x2f, 0x65, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x12, 0x09, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x70, 0x62, 0x1a, 0x1b,
-	0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x63,
-	0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9a, 0x01, 0x0a, 0x08,
-	0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c,
-	0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63,
-	0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
-	0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a,
-	0x0c, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65,
-	0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69,
-	0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73,
-	0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+var File_core_record_pb_envelope_proto protoreflect.FileDescriptor
+
+var file_core_record_pb_envelope_proto_rawDesc = []byte{
+	0x0a, 0x1d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2f, 0x70, 0x62,
+	0x2f, 0x65, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+	0x09, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x70, 0x62, 0x1a, 0x1b, 0x63, 0x6f, 0x72, 0x65,
+	0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74,
+	0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9a, 0x01, 0x0a, 0x08, 0x45, 0x6e, 0x76, 0x65,
+	0x6c, 0x6f, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b,
+	0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74,
+	0x6f, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09,
+	0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x79,
+	0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
+	0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07,
+	0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70,
+	0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
+	0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61,
+	0x74, 0x75, 0x72, 0x65, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62,
+	0x70, 0x32, 0x70, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2f,
+	0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_pb_envelope_proto_rawDescOnce sync.Once
-	file_pb_envelope_proto_rawDescData = file_pb_envelope_proto_rawDesc
+	file_core_record_pb_envelope_proto_rawDescOnce sync.Once
+	file_core_record_pb_envelope_proto_rawDescData = file_core_record_pb_envelope_proto_rawDesc
 )
 
-func file_pb_envelope_proto_rawDescGZIP() []byte {
-	file_pb_envelope_proto_rawDescOnce.Do(func() {
-		file_pb_envelope_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_envelope_proto_rawDescData)
+func file_core_record_pb_envelope_proto_rawDescGZIP() []byte {
+	file_core_record_pb_envelope_proto_rawDescOnce.Do(func() {
+		file_core_record_pb_envelope_proto_rawDescData = protoimpl.X.CompressGZIP(file_core_record_pb_envelope_proto_rawDescData)
 	})
-	return file_pb_envelope_proto_rawDescData
+	return file_core_record_pb_envelope_proto_rawDescData
 }
 
-var file_pb_envelope_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
-var file_pb_envelope_proto_goTypes = []any{
+var file_core_record_pb_envelope_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_core_record_pb_envelope_proto_goTypes = []any{
 	(*Envelope)(nil),     // 0: record.pb.Envelope
 	(*pb.PublicKey)(nil), // 1: crypto.pb.PublicKey
 }
-var file_pb_envelope_proto_depIdxs = []int32{
+var file_core_record_pb_envelope_proto_depIdxs = []int32{
 	1, // 0: record.pb.Envelope.public_key:type_name -> crypto.pb.PublicKey
 	1, // [1:1] is the sub-list for method output_type
 	1, // [1:1] is the sub-list for method input_type
@@ -152,13 +156,13 @@ var file_pb_envelope_proto_depIdxs = []int32{
 	0, // [0:1] is the sub-list for field type_name
 }
 
-func init() { file_pb_envelope_proto_init() }
-func file_pb_envelope_proto_init() {
-	if File_pb_envelope_proto != nil {
+func init() { file_core_record_pb_envelope_proto_init() }
+func file_core_record_pb_envelope_proto_init() {
+	if File_core_record_pb_envelope_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_envelope_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_core_record_pb_envelope_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*Envelope); i {
 			case 0:
 				return &v.state
@@ -175,18 +179,18 @@ func file_pb_envelope_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_envelope_proto_rawDesc,
+			RawDescriptor: file_core_record_pb_envelope_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   1,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_envelope_proto_goTypes,
-		DependencyIndexes: file_pb_envelope_proto_depIdxs,
-		MessageInfos:      file_pb_envelope_proto_msgTypes,
+		GoTypes:           file_core_record_pb_envelope_proto_goTypes,
+		DependencyIndexes: file_core_record_pb_envelope_proto_depIdxs,
+		MessageInfos:      file_core_record_pb_envelope_proto_msgTypes,
 	}.Build()
-	File_pb_envelope_proto = out.File
-	file_pb_envelope_proto_rawDesc = nil
-	file_pb_envelope_proto_goTypes = nil
-	file_pb_envelope_proto_depIdxs = nil
+	File_core_record_pb_envelope_proto = out.File
+	file_core_record_pb_envelope_proto_rawDesc = nil
+	file_core_record_pb_envelope_proto_goTypes = nil
+	file_core_record_pb_envelope_proto_depIdxs = nil
 }
diff --git a/core/record/pb/envelope.proto b/core/record/pb/envelope.proto
index 05071ccd..ff192844 100644
--- a/core/record/pb/envelope.proto
+++ b/core/record/pb/envelope.proto
@@ -4,6 +4,8 @@ package record.pb;
 
 import "core/crypto/pb/crypto.proto";
 
+option go_package = "github.com/libp2p/go-libp2p/core/record/pb";
+
 // Envelope encloses a signed payload produced by a peer, along with the public
 // key of the keypair it was signed with so that it can be statelessly validated
 // by the receiver.
diff --git a/core/sec/insecure/insecure.go b/core/sec/insecure/insecure.go
index 9d4fe117..3377b320 100644
--- a/core/sec/insecure/insecure.go
+++ b/core/sec/insecure/insecure.go
@@ -21,8 +21,6 @@ import (
 	"google.golang.org/protobuf/proto"
 )
 
-//go:generate protoc --proto_path=$PWD:$PWD/../../.. --go_out=. --go_opt=Mpb/plaintext.proto=./pb pb/plaintext.proto
-
 // ID is the multistream-select protocol ID that should be used when identifying
 // this security transport.
 const ID = "/plaintext/2.0.0"
diff --git a/core/sec/insecure/pb/plaintext.pb.go b/core/sec/insecure/pb/plaintext.pb.go
index 35d46a0b..44844641 100644
--- a/core/sec/insecure/pb/plaintext.pb.go
+++ b/core/sec/insecure/pb/plaintext.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/plaintext.proto
+// 	protoc        v5.27.3
+// source: core/sec/insecure/pb/plaintext.proto
 
 package pb
 
@@ -33,7 +33,7 @@ type Exchange struct {
 func (x *Exchange) Reset() {
 	*x = Exchange{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_plaintext_proto_msgTypes[0]
+		mi := &file_core_sec_insecure_pb_plaintext_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -46,7 +46,7 @@ func (x *Exchange) String() string {
 func (*Exchange) ProtoMessage() {}
 
 func (x *Exchange) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_plaintext_proto_msgTypes[0]
+	mi := &file_core_sec_insecure_pb_plaintext_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -59,7 +59,7 @@ func (x *Exchange) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Exchange.ProtoReflect.Descriptor instead.
 func (*Exchange) Descriptor() ([]byte, []int) {
-	return file_pb_plaintext_proto_rawDescGZIP(), []int{0}
+	return file_core_sec_insecure_pb_plaintext_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *Exchange) GetId() []byte {
@@ -76,38 +76,42 @@ func (x *Exchange) GetPubkey() *pb.PublicKey {
 	return nil
 }
 
-var File_pb_plaintext_proto protoreflect.FileDescriptor
-
-var file_pb_plaintext_proto_rawDesc = []byte{
-	0x0a, 0x12, 0x70, 0x62, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e,
-	0x70, 0x62, 0x1a, 0x1b, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f,
-	0x70, 0x62, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
-	0x48, 0x0a, 0x08, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x06, 0x70,
-	0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x72,
-	0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
-	0x79, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79,
+var File_core_sec_insecure_pb_plaintext_proto protoreflect.FileDescriptor
+
+var file_core_sec_insecure_pb_plaintext_proto_rawDesc = []byte{
+	0x0a, 0x24, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x63, 0x2f, 0x69, 0x6e, 0x73, 0x65, 0x63,
+	0x75, 0x72, 0x65, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78,
+	0x74, 0x2e, 0x70, 0x62, 0x1a, 0x1b, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74,
+	0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x22, 0x48, 0x0a, 0x08, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x0e, 0x0a,
+	0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2c, 0x0a,
+	0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
+	0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
+	0x4b, 0x65, 0x79, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x42, 0x32, 0x5a, 0x30, 0x67,
+	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70,
+	0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f,
+	0x73, 0x65, 0x63, 0x2f, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2f, 0x70, 0x62,
 }
 
 var (
-	file_pb_plaintext_proto_rawDescOnce sync.Once
-	file_pb_plaintext_proto_rawDescData = file_pb_plaintext_proto_rawDesc
+	file_core_sec_insecure_pb_plaintext_proto_rawDescOnce sync.Once
+	file_core_sec_insecure_pb_plaintext_proto_rawDescData = file_core_sec_insecure_pb_plaintext_proto_rawDesc
 )
 
-func file_pb_plaintext_proto_rawDescGZIP() []byte {
-	file_pb_plaintext_proto_rawDescOnce.Do(func() {
-		file_pb_plaintext_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_plaintext_proto_rawDescData)
+func file_core_sec_insecure_pb_plaintext_proto_rawDescGZIP() []byte {
+	file_core_sec_insecure_pb_plaintext_proto_rawDescOnce.Do(func() {
+		file_core_sec_insecure_pb_plaintext_proto_rawDescData = protoimpl.X.CompressGZIP(file_core_sec_insecure_pb_plaintext_proto_rawDescData)
 	})
-	return file_pb_plaintext_proto_rawDescData
+	return file_core_sec_insecure_pb_plaintext_proto_rawDescData
 }
 
-var file_pb_plaintext_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
-var file_pb_plaintext_proto_goTypes = []any{
+var file_core_sec_insecure_pb_plaintext_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_core_sec_insecure_pb_plaintext_proto_goTypes = []any{
 	(*Exchange)(nil),     // 0: plaintext.pb.Exchange
 	(*pb.PublicKey)(nil), // 1: crypto.pb.PublicKey
 }
-var file_pb_plaintext_proto_depIdxs = []int32{
+var file_core_sec_insecure_pb_plaintext_proto_depIdxs = []int32{
 	1, // 0: plaintext.pb.Exchange.pubkey:type_name -> crypto.pb.PublicKey
 	1, // [1:1] is the sub-list for method output_type
 	1, // [1:1] is the sub-list for method input_type
@@ -116,13 +120,13 @@ var file_pb_plaintext_proto_depIdxs = []int32{
 	0, // [0:1] is the sub-list for field type_name
 }
 
-func init() { file_pb_plaintext_proto_init() }
-func file_pb_plaintext_proto_init() {
-	if File_pb_plaintext_proto != nil {
+func init() { file_core_sec_insecure_pb_plaintext_proto_init() }
+func file_core_sec_insecure_pb_plaintext_proto_init() {
+	if File_core_sec_insecure_pb_plaintext_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_plaintext_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_core_sec_insecure_pb_plaintext_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*Exchange); i {
 			case 0:
 				return &v.state
@@ -139,18 +143,18 @@ func file_pb_plaintext_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_plaintext_proto_rawDesc,
+			RawDescriptor: file_core_sec_insecure_pb_plaintext_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   1,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_plaintext_proto_goTypes,
-		DependencyIndexes: file_pb_plaintext_proto_depIdxs,
-		MessageInfos:      file_pb_plaintext_proto_msgTypes,
+		GoTypes:           file_core_sec_insecure_pb_plaintext_proto_goTypes,
+		DependencyIndexes: file_core_sec_insecure_pb_plaintext_proto_depIdxs,
+		MessageInfos:      file_core_sec_insecure_pb_plaintext_proto_msgTypes,
 	}.Build()
-	File_pb_plaintext_proto = out.File
-	file_pb_plaintext_proto_rawDesc = nil
-	file_pb_plaintext_proto_goTypes = nil
-	file_pb_plaintext_proto_depIdxs = nil
+	File_core_sec_insecure_pb_plaintext_proto = out.File
+	file_core_sec_insecure_pb_plaintext_proto_rawDesc = nil
+	file_core_sec_insecure_pb_plaintext_proto_goTypes = nil
+	file_core_sec_insecure_pb_plaintext_proto_depIdxs = nil
 }
diff --git a/core/sec/insecure/pb/plaintext.proto b/core/sec/insecure/pb/plaintext.proto
index 634100bd..6b14764b 100644
--- a/core/sec/insecure/pb/plaintext.proto
+++ b/core/sec/insecure/pb/plaintext.proto
@@ -4,6 +4,8 @@ package plaintext.pb;
 
 import "core/crypto/pb/crypto.proto";
 
+option go_package = "github.com/libp2p/go-libp2p/core/sec/insecure/pb";
+
 message Exchange {
     optional bytes id = 1;
     optional crypto.pb.PublicKey pubkey = 2;
diff --git a/examples/go.mod b/examples/go.mod
index 578546a8..e4ba4983 100644
--- a/examples/go.mod
+++ b/examples/go.mod
@@ -1,6 +1,6 @@
 module github.com/libp2p/go-libp2p/examples
 
-go 1.21
+go 1.22
 
 require (
 	github.com/gogo/protobuf v1.3.2
diff --git a/examples/ipfs-camp-2019/go.mod b/examples/ipfs-camp-2019/go.mod
index 0d0b29c0..268135ab 100644
--- a/examples/ipfs-camp-2019/go.mod
+++ b/examples/ipfs-camp-2019/go.mod
@@ -1,6 +1,6 @@
 module github.com/libp2p/go-libp2p/examples/ipfs-camp-2019
 
-go 1.21
+go 1.22
 
 require (
 	github.com/gogo/protobuf v1.3.2
diff --git a/examples/pubsub/basic-chat-with-rendezvous/go.mod b/examples/pubsub/basic-chat-with-rendezvous/go.mod
index cd90b4d5..c45d1986 100644
--- a/examples/pubsub/basic-chat-with-rendezvous/go.mod
+++ b/examples/pubsub/basic-chat-with-rendezvous/go.mod
@@ -1,6 +1,6 @@
 module github.com/libp2p/go-libp2p/examples/pubsub/chat
 
-go 1.21
+go 1.22
 
 require (
 	github.com/libp2p/go-libp2p v0.33.0
diff --git a/examples/pubsub/chat/go.mod b/examples/pubsub/chat/go.mod
index 6c53916b..3f1e6c2f 100644
--- a/examples/pubsub/chat/go.mod
+++ b/examples/pubsub/chat/go.mod
@@ -1,6 +1,6 @@
 module github.com/libp2p/go-libp2p/examples/pubsub/chat
 
-go 1.21
+go 1.22
 
 require (
 	github.com/gdamore/tcell/v2 v2.5.2
diff --git a/go.mod b/go.mod
index 6359d180..684f3544 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/libp2p/go-libp2p
 
-go 1.21
+go 1.22
 
 retract v0.26.1 // Tag was applied incorrectly due to a bug in the release workflow.
 
diff --git a/p2p/host/autonat/pb/autonat.pb.go b/p2p/host/autonat/pb/autonat.pb.go
index 41df2cb7..26944fcb 100644
--- a/p2p/host/autonat/pb/autonat.pb.go
+++ b/p2p/host/autonat/pb/autonat.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/autonat.proto
+// 	protoc        v5.27.3
+// source: p2p/host/autonat/pb/autonat.proto
 
 package pb
 
@@ -50,11 +50,11 @@ func (x Message_MessageType) String() string {
 }
 
 func (Message_MessageType) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_autonat_proto_enumTypes[0].Descriptor()
+	return file_p2p_host_autonat_pb_autonat_proto_enumTypes[0].Descriptor()
 }
 
 func (Message_MessageType) Type() protoreflect.EnumType {
-	return &file_pb_autonat_proto_enumTypes[0]
+	return &file_p2p_host_autonat_pb_autonat_proto_enumTypes[0]
 }
 
 func (x Message_MessageType) Number() protoreflect.EnumNumber {
@@ -73,7 +73,7 @@ func (x *Message_MessageType) UnmarshalJSON(b []byte) error {
 
 // Deprecated: Use Message_MessageType.Descriptor instead.
 func (Message_MessageType) EnumDescriptor() ([]byte, []int) {
-	return file_pb_autonat_proto_rawDescGZIP(), []int{0, 0}
+	return file_p2p_host_autonat_pb_autonat_proto_rawDescGZIP(), []int{0, 0}
 }
 
 type Message_ResponseStatus int32
@@ -115,11 +115,11 @@ func (x Message_ResponseStatus) String() string {
 }
 
 func (Message_ResponseStatus) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_autonat_proto_enumTypes[1].Descriptor()
+	return file_p2p_host_autonat_pb_autonat_proto_enumTypes[1].Descriptor()
 }
 
 func (Message_ResponseStatus) Type() protoreflect.EnumType {
-	return &file_pb_autonat_proto_enumTypes[1]
+	return &file_p2p_host_autonat_pb_autonat_proto_enumTypes[1]
 }
 
 func (x Message_ResponseStatus) Number() protoreflect.EnumNumber {
@@ -138,7 +138,7 @@ func (x *Message_ResponseStatus) UnmarshalJSON(b []byte) error {
 
 // Deprecated: Use Message_ResponseStatus.Descriptor instead.
 func (Message_ResponseStatus) EnumDescriptor() ([]byte, []int) {
-	return file_pb_autonat_proto_rawDescGZIP(), []int{0, 1}
+	return file_p2p_host_autonat_pb_autonat_proto_rawDescGZIP(), []int{0, 1}
 }
 
 type Message struct {
@@ -154,7 +154,7 @@ type Message struct {
 func (x *Message) Reset() {
 	*x = Message{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonat_proto_msgTypes[0]
+		mi := &file_p2p_host_autonat_pb_autonat_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -167,7 +167,7 @@ func (x *Message) String() string {
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonat_proto_msgTypes[0]
+	mi := &file_p2p_host_autonat_pb_autonat_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -180,7 +180,7 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Message.ProtoReflect.Descriptor instead.
 func (*Message) Descriptor() ([]byte, []int) {
-	return file_pb_autonat_proto_rawDescGZIP(), []int{0}
+	return file_p2p_host_autonat_pb_autonat_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *Message) GetType() Message_MessageType {
@@ -216,7 +216,7 @@ type Message_PeerInfo struct {
 func (x *Message_PeerInfo) Reset() {
 	*x = Message_PeerInfo{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonat_proto_msgTypes[1]
+		mi := &file_p2p_host_autonat_pb_autonat_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -229,7 +229,7 @@ func (x *Message_PeerInfo) String() string {
 func (*Message_PeerInfo) ProtoMessage() {}
 
 func (x *Message_PeerInfo) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonat_proto_msgTypes[1]
+	mi := &file_p2p_host_autonat_pb_autonat_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -242,7 +242,7 @@ func (x *Message_PeerInfo) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Message_PeerInfo.ProtoReflect.Descriptor instead.
 func (*Message_PeerInfo) Descriptor() ([]byte, []int) {
-	return file_pb_autonat_proto_rawDescGZIP(), []int{0, 0}
+	return file_p2p_host_autonat_pb_autonat_proto_rawDescGZIP(), []int{0, 0}
 }
 
 func (x *Message_PeerInfo) GetId() []byte {
@@ -270,7 +270,7 @@ type Message_Dial struct {
 func (x *Message_Dial) Reset() {
 	*x = Message_Dial{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonat_proto_msgTypes[2]
+		mi := &file_p2p_host_autonat_pb_autonat_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -283,7 +283,7 @@ func (x *Message_Dial) String() string {
 func (*Message_Dial) ProtoMessage() {}
 
 func (x *Message_Dial) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonat_proto_msgTypes[2]
+	mi := &file_p2p_host_autonat_pb_autonat_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -296,7 +296,7 @@ func (x *Message_Dial) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Message_Dial.ProtoReflect.Descriptor instead.
 func (*Message_Dial) Descriptor() ([]byte, []int) {
-	return file_pb_autonat_proto_rawDescGZIP(), []int{0, 1}
+	return file_p2p_host_autonat_pb_autonat_proto_rawDescGZIP(), []int{0, 1}
 }
 
 func (x *Message_Dial) GetPeer() *Message_PeerInfo {
@@ -319,7 +319,7 @@ type Message_DialResponse struct {
 func (x *Message_DialResponse) Reset() {
 	*x = Message_DialResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonat_proto_msgTypes[3]
+		mi := &file_p2p_host_autonat_pb_autonat_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -332,7 +332,7 @@ func (x *Message_DialResponse) String() string {
 func (*Message_DialResponse) ProtoMessage() {}
 
 func (x *Message_DialResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonat_proto_msgTypes[3]
+	mi := &file_p2p_host_autonat_pb_autonat_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -345,7 +345,7 @@ func (x *Message_DialResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Message_DialResponse.ProtoReflect.Descriptor instead.
 func (*Message_DialResponse) Descriptor() ([]byte, []int) {
-	return file_pb_autonat_proto_rawDescGZIP(), []int{0, 2}
+	return file_p2p_host_autonat_pb_autonat_proto_rawDescGZIP(), []int{0, 2}
 }
 
 func (x *Message_DialResponse) GetStatus() Message_ResponseStatus {
@@ -369,64 +369,68 @@ func (x *Message_DialResponse) GetAddr() []byte {
 	return nil
 }
 
-var File_pb_autonat_proto protoreflect.FileDescriptor
-
-var file_pb_autonat_proto_rawDesc = []byte{
-	0x0a, 0x10, 0x70, 0x62, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x12, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x22, 0xb5,
-	0x04, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x74, 0x79,
-	0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e,
-	0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
-	0x2c, 0x0a, 0x04, 0x64, 0x69, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e,
-	0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x04, 0x64, 0x69, 0x61, 0x6c, 0x12, 0x44, 0x0a,
-	0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62,
-	0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x1a, 0x30, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12,
-	0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12,
-	0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05,
-	0x61, 0x64, 0x64, 0x72, 0x73, 0x1a, 0x38, 0x0a, 0x04, 0x44, 0x69, 0x61, 0x6c, 0x12, 0x30, 0x0a,
-	0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x75,
-	0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x2e, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x1a,
-	0x7e, 0x0a, 0x0c, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
-	0x22, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73,
-	0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61,
-	0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x22,
-	0x2a, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08,
-	0x0a, 0x04, 0x44, 0x49, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x49, 0x41, 0x4c,
-	0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x10, 0x01, 0x22, 0x69, 0x0a, 0x0e, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a,
-	0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x5f, 0x44, 0x49, 0x41, 0x4c, 0x5f,
-	0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x64, 0x12, 0x12, 0x0a, 0x0e, 0x45, 0x5f, 0x44, 0x49, 0x41,
-	0x4c, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x53, 0x45, 0x44, 0x10, 0x65, 0x12, 0x12, 0x0a, 0x0d, 0x45,
-	0x5f, 0x42, 0x41, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0xc8, 0x01, 0x12,
-	0x15, 0x0a, 0x10, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52,
-	0x52, 0x4f, 0x52, 0x10, 0xac, 0x02,
+var File_p2p_host_autonat_pb_autonat_proto protoreflect.FileDescriptor
+
+var file_p2p_host_autonat_pb_autonat_proto_rawDesc = []byte{
+	0x0a, 0x21, 0x70, 0x32, 0x70, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x6e,
+	0x61, 0x74, 0x2f, 0x70, 0x62, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x22,
+	0xb5, 0x04, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x74,
+	0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x6f,
+	0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
+	0x12, 0x2c, 0x0a, 0x04, 0x64, 0x69, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18,
+	0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x04, 0x64, 0x69, 0x61, 0x6c, 0x12, 0x44,
+	0x0a, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70,
+	0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x30, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f,
+	0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64,
+	0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52,
+	0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x1a, 0x38, 0x0a, 0x04, 0x44, 0x69, 0x61, 0x6c, 0x12, 0x30,
+	0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61,
+	0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72,
+	0x1a, 0x7e, 0x0a, 0x0c, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+	0x32, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a,
+	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04,
+	0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72,
+	0x22, 0x2a, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12,
+	0x08, 0x0a, 0x04, 0x44, 0x49, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x49, 0x41,
+	0x4c, 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x10, 0x01, 0x22, 0x69, 0x0a, 0x0e,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06,
+	0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x5f, 0x44, 0x49, 0x41, 0x4c,
+	0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x64, 0x12, 0x12, 0x0a, 0x0e, 0x45, 0x5f, 0x44, 0x49,
+	0x41, 0x4c, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x53, 0x45, 0x44, 0x10, 0x65, 0x12, 0x12, 0x0a, 0x0d,
+	0x45, 0x5f, 0x42, 0x41, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0xc8, 0x01,
+	0x12, 0x15, 0x0a, 0x10, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45,
+	0x52, 0x52, 0x4f, 0x52, 0x10, 0xac, 0x02, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75,
+	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d,
+	0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x2f,
+	0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2f, 0x70, 0x62,
 }
 
 var (
-	file_pb_autonat_proto_rawDescOnce sync.Once
-	file_pb_autonat_proto_rawDescData = file_pb_autonat_proto_rawDesc
+	file_p2p_host_autonat_pb_autonat_proto_rawDescOnce sync.Once
+	file_p2p_host_autonat_pb_autonat_proto_rawDescData = file_p2p_host_autonat_pb_autonat_proto_rawDesc
 )
 
-func file_pb_autonat_proto_rawDescGZIP() []byte {
-	file_pb_autonat_proto_rawDescOnce.Do(func() {
-		file_pb_autonat_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_autonat_proto_rawDescData)
+func file_p2p_host_autonat_pb_autonat_proto_rawDescGZIP() []byte {
+	file_p2p_host_autonat_pb_autonat_proto_rawDescOnce.Do(func() {
+		file_p2p_host_autonat_pb_autonat_proto_rawDescData = protoimpl.X.CompressGZIP(file_p2p_host_autonat_pb_autonat_proto_rawDescData)
 	})
-	return file_pb_autonat_proto_rawDescData
+	return file_p2p_host_autonat_pb_autonat_proto_rawDescData
 }
 
-var file_pb_autonat_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
-var file_pb_autonat_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
-var file_pb_autonat_proto_goTypes = []any{
+var file_p2p_host_autonat_pb_autonat_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_p2p_host_autonat_pb_autonat_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_p2p_host_autonat_pb_autonat_proto_goTypes = []any{
 	(Message_MessageType)(0),     // 0: autonat.pb.Message.MessageType
 	(Message_ResponseStatus)(0),  // 1: autonat.pb.Message.ResponseStatus
 	(*Message)(nil),              // 2: autonat.pb.Message
@@ -434,7 +438,7 @@ var file_pb_autonat_proto_goTypes = []any{
 	(*Message_Dial)(nil),         // 4: autonat.pb.Message.Dial
 	(*Message_DialResponse)(nil), // 5: autonat.pb.Message.DialResponse
 }
-var file_pb_autonat_proto_depIdxs = []int32{
+var file_p2p_host_autonat_pb_autonat_proto_depIdxs = []int32{
 	0, // 0: autonat.pb.Message.type:type_name -> autonat.pb.Message.MessageType
 	4, // 1: autonat.pb.Message.dial:type_name -> autonat.pb.Message.Dial
 	5, // 2: autonat.pb.Message.dialResponse:type_name -> autonat.pb.Message.DialResponse
@@ -447,13 +451,13 @@ var file_pb_autonat_proto_depIdxs = []int32{
 	0, // [0:5] is the sub-list for field type_name
 }
 
-func init() { file_pb_autonat_proto_init() }
-func file_pb_autonat_proto_init() {
-	if File_pb_autonat_proto != nil {
+func init() { file_p2p_host_autonat_pb_autonat_proto_init() }
+func file_p2p_host_autonat_pb_autonat_proto_init() {
+	if File_p2p_host_autonat_pb_autonat_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_autonat_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_p2p_host_autonat_pb_autonat_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*Message); i {
 			case 0:
 				return &v.state
@@ -465,7 +469,7 @@ func file_pb_autonat_proto_init() {
 				return nil
 			}
 		}
-		file_pb_autonat_proto_msgTypes[1].Exporter = func(v any, i int) any {
+		file_p2p_host_autonat_pb_autonat_proto_msgTypes[1].Exporter = func(v any, i int) any {
 			switch v := v.(*Message_PeerInfo); i {
 			case 0:
 				return &v.state
@@ -477,7 +481,7 @@ func file_pb_autonat_proto_init() {
 				return nil
 			}
 		}
-		file_pb_autonat_proto_msgTypes[2].Exporter = func(v any, i int) any {
+		file_p2p_host_autonat_pb_autonat_proto_msgTypes[2].Exporter = func(v any, i int) any {
 			switch v := v.(*Message_Dial); i {
 			case 0:
 				return &v.state
@@ -489,7 +493,7 @@ func file_pb_autonat_proto_init() {
 				return nil
 			}
 		}
-		file_pb_autonat_proto_msgTypes[3].Exporter = func(v any, i int) any {
+		file_p2p_host_autonat_pb_autonat_proto_msgTypes[3].Exporter = func(v any, i int) any {
 			switch v := v.(*Message_DialResponse); i {
 			case 0:
 				return &v.state
@@ -506,19 +510,19 @@ func file_pb_autonat_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_autonat_proto_rawDesc,
+			RawDescriptor: file_p2p_host_autonat_pb_autonat_proto_rawDesc,
 			NumEnums:      2,
 			NumMessages:   4,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_autonat_proto_goTypes,
-		DependencyIndexes: file_pb_autonat_proto_depIdxs,
-		EnumInfos:         file_pb_autonat_proto_enumTypes,
-		MessageInfos:      file_pb_autonat_proto_msgTypes,
+		GoTypes:           file_p2p_host_autonat_pb_autonat_proto_goTypes,
+		DependencyIndexes: file_p2p_host_autonat_pb_autonat_proto_depIdxs,
+		EnumInfos:         file_p2p_host_autonat_pb_autonat_proto_enumTypes,
+		MessageInfos:      file_p2p_host_autonat_pb_autonat_proto_msgTypes,
 	}.Build()
-	File_pb_autonat_proto = out.File
-	file_pb_autonat_proto_rawDesc = nil
-	file_pb_autonat_proto_goTypes = nil
-	file_pb_autonat_proto_depIdxs = nil
+	File_p2p_host_autonat_pb_autonat_proto = out.File
+	file_p2p_host_autonat_pb_autonat_proto_rawDesc = nil
+	file_p2p_host_autonat_pb_autonat_proto_goTypes = nil
+	file_p2p_host_autonat_pb_autonat_proto_depIdxs = nil
 }
diff --git a/p2p/host/autonat/pb/autonat.proto b/p2p/host/autonat/pb/autonat.proto
index 777270a1..60ab15e8 100644
--- a/p2p/host/autonat/pb/autonat.proto
+++ b/p2p/host/autonat/pb/autonat.proto
@@ -2,6 +2,8 @@ syntax = "proto2";
 
 package autonat.pb;
 
+option go_package = "github.com/libp2p/go-libp2p/p2p/host/autonat/pb";
+
 message Message {
   enum MessageType {
     DIAL          = 0;
diff --git a/p2p/host/autonat/proto.go b/p2p/host/autonat/proto.go
index 5bb2de06..e8f97c53 100644
--- a/p2p/host/autonat/proto.go
+++ b/p2p/host/autonat/proto.go
@@ -7,8 +7,6 @@ import (
 	ma "github.com/multiformats/go-multiaddr"
 )
 
-//go:generate protoc --proto_path=$PWD:$PWD/../../.. --go_out=. --go_opt=Mpb/autonat.proto=./pb pb/autonat.proto
-
 // AutoNATProto identifies the autonat service protocol
 const AutoNATProto = "/libp2p/autonat/1.0.0"
 
diff --git a/p2p/host/peerstore/pstoreds/pb/pstore.pb.go b/p2p/host/peerstore/pstoreds/pb/pstore.pb.go
index aacbb367..5ac20406 100644
--- a/p2p/host/peerstore/pstoreds/pb/pstore.pb.go
+++ b/p2p/host/peerstore/pstoreds/pb/pstore.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/pstore.proto
+// 	protoc        v5.27.3
+// source: p2p/host/peerstore/pstoreds/pb/pstore.proto
 
 package pb
 
@@ -37,7 +37,7 @@ type AddrBookRecord struct {
 func (x *AddrBookRecord) Reset() {
 	*x = AddrBookRecord{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_pstore_proto_msgTypes[0]
+		mi := &file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -50,7 +50,7 @@ func (x *AddrBookRecord) String() string {
 func (*AddrBookRecord) ProtoMessage() {}
 
 func (x *AddrBookRecord) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_pstore_proto_msgTypes[0]
+	mi := &file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -63,7 +63,7 @@ func (x *AddrBookRecord) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AddrBookRecord.ProtoReflect.Descriptor instead.
 func (*AddrBookRecord) Descriptor() ([]byte, []int) {
-	return file_pb_pstore_proto_rawDescGZIP(), []int{0}
+	return file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *AddrBookRecord) GetId() []byte {
@@ -103,7 +103,7 @@ type AddrBookRecord_AddrEntry struct {
 func (x *AddrBookRecord_AddrEntry) Reset() {
 	*x = AddrBookRecord_AddrEntry{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_pstore_proto_msgTypes[1]
+		mi := &file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -116,7 +116,7 @@ func (x *AddrBookRecord_AddrEntry) String() string {
 func (*AddrBookRecord_AddrEntry) ProtoMessage() {}
 
 func (x *AddrBookRecord_AddrEntry) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_pstore_proto_msgTypes[1]
+	mi := &file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -129,7 +129,7 @@ func (x *AddrBookRecord_AddrEntry) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AddrBookRecord_AddrEntry.ProtoReflect.Descriptor instead.
 func (*AddrBookRecord_AddrEntry) Descriptor() ([]byte, []int) {
-	return file_pb_pstore_proto_rawDescGZIP(), []int{0, 0}
+	return file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescGZIP(), []int{0, 0}
 }
 
 func (x *AddrBookRecord_AddrEntry) GetAddr() []byte {
@@ -169,7 +169,7 @@ type AddrBookRecord_CertifiedRecord struct {
 func (x *AddrBookRecord_CertifiedRecord) Reset() {
 	*x = AddrBookRecord_CertifiedRecord{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_pstore_proto_msgTypes[2]
+		mi := &file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -182,7 +182,7 @@ func (x *AddrBookRecord_CertifiedRecord) String() string {
 func (*AddrBookRecord_CertifiedRecord) ProtoMessage() {}
 
 func (x *AddrBookRecord_CertifiedRecord) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_pstore_proto_msgTypes[2]
+	mi := &file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -195,7 +195,7 @@ func (x *AddrBookRecord_CertifiedRecord) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AddrBookRecord_CertifiedRecord.ProtoReflect.Descriptor instead.
 func (*AddrBookRecord_CertifiedRecord) Descriptor() ([]byte, []int) {
-	return file_pb_pstore_proto_rawDescGZIP(), []int{0, 1}
+	return file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescGZIP(), []int{0, 1}
 }
 
 func (x *AddrBookRecord_CertifiedRecord) GetSeq() uint64 {
@@ -212,52 +212,58 @@ func (x *AddrBookRecord_CertifiedRecord) GetRaw() []byte {
 	return nil
 }
 
-var File_pb_pstore_proto protoreflect.FileDescriptor
-
-var file_pb_pstore_proto_rawDesc = []byte{
-	0x0a, 0x0f, 0x70, 0x62, 0x2f, 0x70, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x12, 0x09, 0x70, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x62, 0x22, 0xb3, 0x02, 0x0a,
-	0x0e, 0x41, 0x64, 0x64, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12,
-	0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12,
-	0x39, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23,
-	0x2e, 0x70, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x42,
-	0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x45, 0x6e,
-	0x74, 0x72, 0x79, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x12, 0x54, 0x0a, 0x10, 0x63, 0x65,
-	0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x62,
-	0x2e, 0x41, 0x64, 0x64, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e,
-	0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52,
-	0x0f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
-	0x1a, 0x49, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a,
-	0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x61, 0x64, 0x64,
-	0x72, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x03, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x1a, 0x35, 0x0a, 0x0f, 0x43,
-	0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x10,
-	0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x73, 0x65, 0x71,
-	0x12, 0x10, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72,
-	0x61, 0x77, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+var File_p2p_host_peerstore_pstoreds_pb_pstore_proto protoreflect.FileDescriptor
+
+var file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDesc = []byte{
+	0x0a, 0x2b, 0x70, 0x32, 0x70, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x73,
+	0x74, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x70, 0x62,
+	0x2f, 0x70, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x70,
+	0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x62, 0x22, 0xb3, 0x02, 0x0a, 0x0e, 0x41, 0x64, 0x64,
+	0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x05, 0x61,
+	0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x73, 0x74,
+	0x6f, 0x72, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x52,
+	0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
+	0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x12, 0x54, 0x0a, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+	0x69, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x29, 0x2e, 0x70, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64,
+	0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x43, 0x65, 0x72, 0x74,
+	0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x0f, 0x63, 0x65, 0x72,
+	0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x1a, 0x49, 0x0a, 0x09,
+	0x41, 0x64, 0x64, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64,
+	0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x16, 0x0a,
+	0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65,
+	0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x1a, 0x35, 0x0a, 0x0f, 0x43, 0x65, 0x72, 0x74, 0x69,
+	0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65,
+	0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03,
+	0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x3c,
+	0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62,
+	0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32,
+	0x70, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x74, 0x6f, 0x72, 0x65,
+	0x2f, 0x70, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_pb_pstore_proto_rawDescOnce sync.Once
-	file_pb_pstore_proto_rawDescData = file_pb_pstore_proto_rawDesc
+	file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescOnce sync.Once
+	file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescData = file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDesc
 )
 
-func file_pb_pstore_proto_rawDescGZIP() []byte {
-	file_pb_pstore_proto_rawDescOnce.Do(func() {
-		file_pb_pstore_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_pstore_proto_rawDescData)
+func file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescGZIP() []byte {
+	file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescOnce.Do(func() {
+		file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescData = protoimpl.X.CompressGZIP(file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescData)
 	})
-	return file_pb_pstore_proto_rawDescData
+	return file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDescData
 }
 
-var file_pb_pstore_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_pb_pstore_proto_goTypes = []any{
+var file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_p2p_host_peerstore_pstoreds_pb_pstore_proto_goTypes = []any{
 	(*AddrBookRecord)(nil),                 // 0: pstore.pb.AddrBookRecord
 	(*AddrBookRecord_AddrEntry)(nil),       // 1: pstore.pb.AddrBookRecord.AddrEntry
 	(*AddrBookRecord_CertifiedRecord)(nil), // 2: pstore.pb.AddrBookRecord.CertifiedRecord
 }
-var file_pb_pstore_proto_depIdxs = []int32{
+var file_p2p_host_peerstore_pstoreds_pb_pstore_proto_depIdxs = []int32{
 	1, // 0: pstore.pb.AddrBookRecord.addrs:type_name -> pstore.pb.AddrBookRecord.AddrEntry
 	2, // 1: pstore.pb.AddrBookRecord.certified_record:type_name -> pstore.pb.AddrBookRecord.CertifiedRecord
 	2, // [2:2] is the sub-list for method output_type
@@ -267,13 +273,13 @@ var file_pb_pstore_proto_depIdxs = []int32{
 	0, // [0:2] is the sub-list for field type_name
 }
 
-func init() { file_pb_pstore_proto_init() }
-func file_pb_pstore_proto_init() {
-	if File_pb_pstore_proto != nil {
+func init() { file_p2p_host_peerstore_pstoreds_pb_pstore_proto_init() }
+func file_p2p_host_peerstore_pstoreds_pb_pstore_proto_init() {
+	if File_p2p_host_peerstore_pstoreds_pb_pstore_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_pstore_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*AddrBookRecord); i {
 			case 0:
 				return &v.state
@@ -285,7 +291,7 @@ func file_pb_pstore_proto_init() {
 				return nil
 			}
 		}
-		file_pb_pstore_proto_msgTypes[1].Exporter = func(v any, i int) any {
+		file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes[1].Exporter = func(v any, i int) any {
 			switch v := v.(*AddrBookRecord_AddrEntry); i {
 			case 0:
 				return &v.state
@@ -297,7 +303,7 @@ func file_pb_pstore_proto_init() {
 				return nil
 			}
 		}
-		file_pb_pstore_proto_msgTypes[2].Exporter = func(v any, i int) any {
+		file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes[2].Exporter = func(v any, i int) any {
 			switch v := v.(*AddrBookRecord_CertifiedRecord); i {
 			case 0:
 				return &v.state
@@ -314,18 +320,18 @@ func file_pb_pstore_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_pstore_proto_rawDesc,
+			RawDescriptor: file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   3,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_pstore_proto_goTypes,
-		DependencyIndexes: file_pb_pstore_proto_depIdxs,
-		MessageInfos:      file_pb_pstore_proto_msgTypes,
+		GoTypes:           file_p2p_host_peerstore_pstoreds_pb_pstore_proto_goTypes,
+		DependencyIndexes: file_p2p_host_peerstore_pstoreds_pb_pstore_proto_depIdxs,
+		MessageInfos:      file_p2p_host_peerstore_pstoreds_pb_pstore_proto_msgTypes,
 	}.Build()
-	File_pb_pstore_proto = out.File
-	file_pb_pstore_proto_rawDesc = nil
-	file_pb_pstore_proto_goTypes = nil
-	file_pb_pstore_proto_depIdxs = nil
+	File_p2p_host_peerstore_pstoreds_pb_pstore_proto = out.File
+	file_p2p_host_peerstore_pstoreds_pb_pstore_proto_rawDesc = nil
+	file_p2p_host_peerstore_pstoreds_pb_pstore_proto_goTypes = nil
+	file_p2p_host_peerstore_pstoreds_pb_pstore_proto_depIdxs = nil
 }
diff --git a/p2p/host/peerstore/pstoreds/pb/pstore.proto b/p2p/host/peerstore/pstoreds/pb/pstore.proto
index 5922b254..22236681 100644
--- a/p2p/host/peerstore/pstoreds/pb/pstore.proto
+++ b/p2p/host/peerstore/pstoreds/pb/pstore.proto
@@ -1,6 +1,8 @@
 syntax = "proto3";
 package pstore.pb;
 
+option go_package = "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds/pb";
+
 // AddrBookRecord represents a record for a peer in the address book.
 message AddrBookRecord {
 	// The peer ID.
diff --git a/p2p/host/peerstore/pstoreds/peerstore.go b/p2p/host/peerstore/pstoreds/peerstore.go
index be053597..bd547681 100644
--- a/p2p/host/peerstore/pstoreds/peerstore.go
+++ b/p2p/host/peerstore/pstoreds/peerstore.go
@@ -15,8 +15,6 @@ import (
 	"github.com/multiformats/go-base32"
 )
 
-//go:generate protoc --proto_path=$PWD:$PWD/../../../.. --go_out=. --go_opt=Mpb/pstore.proto=./pb pb/pstore.proto
-
 // Configuration object for the peerstore.
 type Options struct {
 	// The size of the in-memory cache. A value of 0 or lower disables the cache.
diff --git a/p2p/net/swarm/dial_error.go b/p2p/net/swarm/dial_error.go
index 4de68220..faa1047d 100644
--- a/p2p/net/swarm/dial_error.go
+++ b/p2p/net/swarm/dial_error.go
@@ -53,7 +53,7 @@ func (e *DialError) Unwrap() []error {
 		return nil
 	}
 
-	errs := make([]error, len(e.DialErrors)+1)
+	errs := make([]error, 0, len(e.DialErrors)+1)
 	if e.Cause != nil {
 		errs = append(errs, e.Cause)
 	}
diff --git a/p2p/protocol/autonatv2/autonat.go b/p2p/protocol/autonatv2/autonat.go
index 1ae11edb..3dc3bc16 100644
--- a/p2p/protocol/autonatv2/autonat.go
+++ b/p2p/protocol/autonatv2/autonat.go
@@ -19,8 +19,6 @@ import (
 	"golang.org/x/exp/slices"
 )
 
-//go:generate protoc --go_out=. --go_opt=Mpb/autonatv2.proto=./pb pb/autonatv2.proto
-
 const (
 	ServiceName      = "libp2p.autonatv2"
 	DialBackProtocol = "/libp2p/autonat/2/dial-back"
diff --git a/p2p/protocol/autonatv2/client.go b/p2p/protocol/autonatv2/client.go
index f93cc313..c1d82b7f 100644
--- a/p2p/protocol/autonatv2/client.go
+++ b/p2p/protocol/autonatv2/client.go
@@ -15,8 +15,6 @@ import (
 	"golang.org/x/exp/rand"
 )
 
-//go:generate protoc --go_out=. --go_opt=Mpb/autonatv2.proto=./pb pb/autonatv2.proto
-
 // client implements the client for making dial requests for AutoNAT v2. It verifies successful
 // dials and provides an option to send data for dial requests.
 type client struct {
diff --git a/p2p/protocol/autonatv2/pb/autonatv2.pb.go b/p2p/protocol/autonatv2/pb/autonatv2.pb.go
index b4cb7959..2138374c 100644
--- a/p2p/protocol/autonatv2/pb/autonatv2.pb.go
+++ b/p2p/protocol/autonatv2/pb/autonatv2.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/autonatv2.proto
+// 	protoc        v5.27.3
+// source: p2p/protocol/autonatv2/pb/autonatv2.proto
 
 package pb
 
@@ -56,11 +56,11 @@ func (x DialStatus) String() string {
 }
 
 func (DialStatus) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_autonatv2_proto_enumTypes[0].Descriptor()
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_enumTypes[0].Descriptor()
 }
 
 func (DialStatus) Type() protoreflect.EnumType {
-	return &file_pb_autonatv2_proto_enumTypes[0]
+	return &file_p2p_protocol_autonatv2_pb_autonatv2_proto_enumTypes[0]
 }
 
 func (x DialStatus) Number() protoreflect.EnumNumber {
@@ -69,7 +69,7 @@ func (x DialStatus) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use DialStatus.Descriptor instead.
 func (DialStatus) EnumDescriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{0}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{0}
 }
 
 type DialResponse_ResponseStatus int32
@@ -108,11 +108,11 @@ func (x DialResponse_ResponseStatus) String() string {
 }
 
 func (DialResponse_ResponseStatus) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_autonatv2_proto_enumTypes[1].Descriptor()
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_enumTypes[1].Descriptor()
 }
 
 func (DialResponse_ResponseStatus) Type() protoreflect.EnumType {
-	return &file_pb_autonatv2_proto_enumTypes[1]
+	return &file_p2p_protocol_autonatv2_pb_autonatv2_proto_enumTypes[1]
 }
 
 func (x DialResponse_ResponseStatus) Number() protoreflect.EnumNumber {
@@ -121,7 +121,7 @@ func (x DialResponse_ResponseStatus) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use DialResponse_ResponseStatus.Descriptor instead.
 func (DialResponse_ResponseStatus) EnumDescriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{3, 0}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{3, 0}
 }
 
 type DialBackResponse_DialBackStatus int32
@@ -151,11 +151,11 @@ func (x DialBackResponse_DialBackStatus) String() string {
 }
 
 func (DialBackResponse_DialBackStatus) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_autonatv2_proto_enumTypes[2].Descriptor()
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_enumTypes[2].Descriptor()
 }
 
 func (DialBackResponse_DialBackStatus) Type() protoreflect.EnumType {
-	return &file_pb_autonatv2_proto_enumTypes[2]
+	return &file_p2p_protocol_autonatv2_pb_autonatv2_proto_enumTypes[2]
 }
 
 func (x DialBackResponse_DialBackStatus) Number() protoreflect.EnumNumber {
@@ -164,7 +164,7 @@ func (x DialBackResponse_DialBackStatus) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use DialBackResponse_DialBackStatus.Descriptor instead.
 func (DialBackResponse_DialBackStatus) EnumDescriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{6, 0}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{6, 0}
 }
 
 type Message struct {
@@ -184,7 +184,7 @@ type Message struct {
 func (x *Message) Reset() {
 	*x = Message{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonatv2_proto_msgTypes[0]
+		mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -197,7 +197,7 @@ func (x *Message) String() string {
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonatv2_proto_msgTypes[0]
+	mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -210,7 +210,7 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Message.ProtoReflect.Descriptor instead.
 func (*Message) Descriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{0}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{0}
 }
 
 func (m *Message) GetMsg() isMessage_Msg {
@@ -288,7 +288,7 @@ type DialRequest struct {
 func (x *DialRequest) Reset() {
 	*x = DialRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonatv2_proto_msgTypes[1]
+		mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -301,7 +301,7 @@ func (x *DialRequest) String() string {
 func (*DialRequest) ProtoMessage() {}
 
 func (x *DialRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonatv2_proto_msgTypes[1]
+	mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -314,7 +314,7 @@ func (x *DialRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DialRequest.ProtoReflect.Descriptor instead.
 func (*DialRequest) Descriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{1}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *DialRequest) GetAddrs() [][]byte {
@@ -343,7 +343,7 @@ type DialDataRequest struct {
 func (x *DialDataRequest) Reset() {
 	*x = DialDataRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonatv2_proto_msgTypes[2]
+		mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -356,7 +356,7 @@ func (x *DialDataRequest) String() string {
 func (*DialDataRequest) ProtoMessage() {}
 
 func (x *DialDataRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonatv2_proto_msgTypes[2]
+	mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -369,7 +369,7 @@ func (x *DialDataRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DialDataRequest.ProtoReflect.Descriptor instead.
 func (*DialDataRequest) Descriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{2}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *DialDataRequest) GetAddrIdx() uint32 {
@@ -399,7 +399,7 @@ type DialResponse struct {
 func (x *DialResponse) Reset() {
 	*x = DialResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonatv2_proto_msgTypes[3]
+		mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -412,7 +412,7 @@ func (x *DialResponse) String() string {
 func (*DialResponse) ProtoMessage() {}
 
 func (x *DialResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonatv2_proto_msgTypes[3]
+	mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -425,7 +425,7 @@ func (x *DialResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DialResponse.ProtoReflect.Descriptor instead.
 func (*DialResponse) Descriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{3}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *DialResponse) GetStatus() DialResponse_ResponseStatus {
@@ -460,7 +460,7 @@ type DialDataResponse struct {
 func (x *DialDataResponse) Reset() {
 	*x = DialDataResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonatv2_proto_msgTypes[4]
+		mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[4]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -473,7 +473,7 @@ func (x *DialDataResponse) String() string {
 func (*DialDataResponse) ProtoMessage() {}
 
 func (x *DialDataResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonatv2_proto_msgTypes[4]
+	mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[4]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -486,7 +486,7 @@ func (x *DialDataResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DialDataResponse.ProtoReflect.Descriptor instead.
 func (*DialDataResponse) Descriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{4}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{4}
 }
 
 func (x *DialDataResponse) GetData() []byte {
@@ -507,7 +507,7 @@ type DialBack struct {
 func (x *DialBack) Reset() {
 	*x = DialBack{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonatv2_proto_msgTypes[5]
+		mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[5]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -520,7 +520,7 @@ func (x *DialBack) String() string {
 func (*DialBack) ProtoMessage() {}
 
 func (x *DialBack) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonatv2_proto_msgTypes[5]
+	mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[5]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -533,7 +533,7 @@ func (x *DialBack) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DialBack.ProtoReflect.Descriptor instead.
 func (*DialBack) Descriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{5}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *DialBack) GetNonce() uint64 {
@@ -554,7 +554,7 @@ type DialBackResponse struct {
 func (x *DialBackResponse) Reset() {
 	*x = DialBackResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_autonatv2_proto_msgTypes[6]
+		mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[6]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -567,7 +567,7 @@ func (x *DialBackResponse) String() string {
 func (*DialBackResponse) ProtoMessage() {}
 
 func (x *DialBackResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_autonatv2_proto_msgTypes[6]
+	mi := &file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[6]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -580,7 +580,7 @@ func (x *DialBackResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DialBackResponse.ProtoReflect.Descriptor instead.
 func (*DialBackResponse) Descriptor() ([]byte, []int) {
-	return file_pb_autonatv2_proto_rawDescGZIP(), []int{6}
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP(), []int{6}
 }
 
 func (x *DialBackResponse) GetStatus() DialBackResponse_DialBackStatus {
@@ -590,89 +590,94 @@ func (x *DialBackResponse) GetStatus() DialBackResponse_DialBackStatus {
 	return DialBackResponse_OK
 }
 
-var File_pb_autonatv2_proto protoreflect.FileDescriptor
-
-var file_pb_autonatv2_proto_rawDesc = []byte{
-	0x0a, 0x12, 0x70, 0x62, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e,
-	0x70, 0x62, 0x22, 0xaa, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d,
-	0x0a, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e,
-	0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00,
-	0x52, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a,
-	0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e,
-	0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48,
-	0x00, 0x52, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x49, 0x0a, 0x0f, 0x64, 0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e,
-	0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x69, 0x61, 0x6c, 0x44,
-	0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x10, 0x64, 0x69,
-	0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32,
-	0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x10, 0x64, 0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x22,
-	0x39, 0x0a, 0x0b, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14,
-	0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x61,
-	0x64, 0x64, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x06, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x47, 0x0a, 0x0f, 0x44, 0x69,
-	0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
-	0x07, 0x61, 0x64, 0x64, 0x72, 0x49, 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
-	0x61, 0x64, 0x64, 0x72, 0x49, 0x64, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x75, 0x6d, 0x42, 0x79,
-	0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x42, 0x79,
-	0x74, 0x65, 0x73, 0x22, 0x82, 0x02, 0x0a, 0x0c, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32,
-	0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
-	0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x49,
-	0x64, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x49, 0x64,
-	0x78, 0x12, 0x38, 0x0a, 0x0a, 0x64, 0x69, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76,
-	0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
-	0x0a, 0x64, 0x69, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x5b, 0x0a, 0x0e, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a,
-	0x10, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f,
-	0x52, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54,
-	0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x64, 0x12, 0x12, 0x0a, 0x0e, 0x45,
-	0x5f, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x53, 0x45, 0x44, 0x10, 0x65, 0x12,
-	0x07, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0xc8, 0x01, 0x22, 0x26, 0x0a, 0x10, 0x44, 0x69, 0x61, 0x6c,
-	0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04,
-	0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61,
-	0x22, 0x20, 0x0a, 0x08, 0x44, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05,
-	0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x06, 0x52, 0x05, 0x6e, 0x6f, 0x6e,
-	0x63, 0x65, 0x22, 0x73, 0x0a, 0x10, 0x44, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74,
-	0x76, 0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x53,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x18, 0x0a,
-	0x0e, 0x44, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
-	0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x2a, 0x4a, 0x0a, 0x0a, 0x44, 0x69, 0x61, 0x6c, 0x53,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x10,
-	0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x5f, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f,
-	0x52, 0x10, 0x64, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x5f, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x42, 0x41,
-	0x43, 0x4b, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x65, 0x12, 0x07, 0x0a, 0x02, 0x4f, 0x4b,
-	0x10, 0xc8, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+var File_p2p_protocol_autonatv2_pb_autonatv2_proto protoreflect.FileDescriptor
+
+var file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDesc = []byte{
+	0x0a, 0x29, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x61,
+	0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2f, 0x70, 0x62, 0x2f, 0x61, 0x75, 0x74, 0x6f,
+	0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x61, 0x75, 0x74,
+	0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x62, 0x22, 0xaa, 0x02, 0x0a, 0x07, 0x4d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x75, 0x74,
+	0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x74,
+	0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0f, 0x64, 0x69, 0x61, 0x6c, 0x44, 0x61,
+	0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x1d, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44,
+	0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00,
+	0x52, 0x0f, 0x64, 0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x4c, 0x0a, 0x10, 0x64, 0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x75,
+	0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x44,
+	0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x10, 0x64,
+	0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42,
+	0x05, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x39, 0x0a, 0x0b, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x01,
+	0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e,
+	0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63,
+	0x65, 0x22, 0x47, 0x0a, 0x0f, 0x44, 0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x49, 0x64, 0x78, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x49, 0x64, 0x78, 0x12, 0x1a,
+	0x0a, 0x08, 0x6e, 0x75, 0x6d, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x08, 0x6e, 0x75, 0x6d, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x82, 0x02, 0x0a, 0x0c, 0x44,
+	0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x73,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x61, 0x75,
+	0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18,
+	0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x49, 0x64, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
+	0x07, 0x61, 0x64, 0x64, 0x72, 0x49, 0x64, 0x78, 0x12, 0x38, 0x0a, 0x0a, 0x64, 0x69, 0x61, 0x6c,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x61,
+	0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61, 0x6c,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x64, 0x69, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x22, 0x5b, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e,
+	0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x5f,
+	0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44,
+	0x10, 0x64, 0x12, 0x12, 0x0a, 0x0e, 0x45, 0x5f, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x46,
+	0x55, 0x53, 0x45, 0x44, 0x10, 0x65, 0x12, 0x07, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0xc8, 0x01, 0x22,
+	0x26, 0x0a, 0x10, 0x44, 0x69, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x20, 0x0a, 0x08, 0x44, 0x69, 0x61, 0x6c, 0x42,
+	0x61, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x06, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x73, 0x0a, 0x10, 0x44, 0x69, 0x61,
+	0x6c, 0x42, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a,
+	0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e,
+	0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x61,
+	0x6c, 0x42, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x69,
+	0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x22, 0x18, 0x0a, 0x0e, 0x44, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x2a, 0x4a,
+	0x0a, 0x0a, 0x44, 0x69, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06,
+	0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x5f, 0x44, 0x49,
+	0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x64, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x5f,
+	0x44, 0x49, 0x41, 0x4c, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10,
+	0x65, 0x12, 0x07, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0xc8, 0x01, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69,
+	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f,
+	0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x76, 0x32,
+	0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_pb_autonatv2_proto_rawDescOnce sync.Once
-	file_pb_autonatv2_proto_rawDescData = file_pb_autonatv2_proto_rawDesc
+	file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescOnce sync.Once
+	file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescData = file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDesc
 )
 
-func file_pb_autonatv2_proto_rawDescGZIP() []byte {
-	file_pb_autonatv2_proto_rawDescOnce.Do(func() {
-		file_pb_autonatv2_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_autonatv2_proto_rawDescData)
+func file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescGZIP() []byte {
+	file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescOnce.Do(func() {
+		file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescData = protoimpl.X.CompressGZIP(file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescData)
 	})
-	return file_pb_autonatv2_proto_rawDescData
+	return file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDescData
 }
 
-var file_pb_autonatv2_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
-var file_pb_autonatv2_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
-var file_pb_autonatv2_proto_goTypes = []any{
+var file_p2p_protocol_autonatv2_pb_autonatv2_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
+var file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_p2p_protocol_autonatv2_pb_autonatv2_proto_goTypes = []any{
 	(DialStatus)(0),                      // 0: autonatv2.pb.DialStatus
 	(DialResponse_ResponseStatus)(0),     // 1: autonatv2.pb.DialResponse.ResponseStatus
 	(DialBackResponse_DialBackStatus)(0), // 2: autonatv2.pb.DialBackResponse.DialBackStatus
@@ -684,7 +689,7 @@ var file_pb_autonatv2_proto_goTypes = []any{
 	(*DialBack)(nil),                     // 8: autonatv2.pb.DialBack
 	(*DialBackResponse)(nil),             // 9: autonatv2.pb.DialBackResponse
 }
-var file_pb_autonatv2_proto_depIdxs = []int32{
+var file_p2p_protocol_autonatv2_pb_autonatv2_proto_depIdxs = []int32{
 	4, // 0: autonatv2.pb.Message.dialRequest:type_name -> autonatv2.pb.DialRequest
 	6, // 1: autonatv2.pb.Message.dialResponse:type_name -> autonatv2.pb.DialResponse
 	5, // 2: autonatv2.pb.Message.dialDataRequest:type_name -> autonatv2.pb.DialDataRequest
@@ -699,13 +704,13 @@ var file_pb_autonatv2_proto_depIdxs = []int32{
 	0, // [0:7] is the sub-list for field type_name
 }
 
-func init() { file_pb_autonatv2_proto_init() }
-func file_pb_autonatv2_proto_init() {
-	if File_pb_autonatv2_proto != nil {
+func init() { file_p2p_protocol_autonatv2_pb_autonatv2_proto_init() }
+func file_p2p_protocol_autonatv2_pb_autonatv2_proto_init() {
+	if File_p2p_protocol_autonatv2_pb_autonatv2_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_autonatv2_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*Message); i {
 			case 0:
 				return &v.state
@@ -717,7 +722,7 @@ func file_pb_autonatv2_proto_init() {
 				return nil
 			}
 		}
-		file_pb_autonatv2_proto_msgTypes[1].Exporter = func(v any, i int) any {
+		file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[1].Exporter = func(v any, i int) any {
 			switch v := v.(*DialRequest); i {
 			case 0:
 				return &v.state
@@ -729,7 +734,7 @@ func file_pb_autonatv2_proto_init() {
 				return nil
 			}
 		}
-		file_pb_autonatv2_proto_msgTypes[2].Exporter = func(v any, i int) any {
+		file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[2].Exporter = func(v any, i int) any {
 			switch v := v.(*DialDataRequest); i {
 			case 0:
 				return &v.state
@@ -741,7 +746,7 @@ func file_pb_autonatv2_proto_init() {
 				return nil
 			}
 		}
-		file_pb_autonatv2_proto_msgTypes[3].Exporter = func(v any, i int) any {
+		file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[3].Exporter = func(v any, i int) any {
 			switch v := v.(*DialResponse); i {
 			case 0:
 				return &v.state
@@ -753,7 +758,7 @@ func file_pb_autonatv2_proto_init() {
 				return nil
 			}
 		}
-		file_pb_autonatv2_proto_msgTypes[4].Exporter = func(v any, i int) any {
+		file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[4].Exporter = func(v any, i int) any {
 			switch v := v.(*DialDataResponse); i {
 			case 0:
 				return &v.state
@@ -765,7 +770,7 @@ func file_pb_autonatv2_proto_init() {
 				return nil
 			}
 		}
-		file_pb_autonatv2_proto_msgTypes[5].Exporter = func(v any, i int) any {
+		file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[5].Exporter = func(v any, i int) any {
 			switch v := v.(*DialBack); i {
 			case 0:
 				return &v.state
@@ -777,7 +782,7 @@ func file_pb_autonatv2_proto_init() {
 				return nil
 			}
 		}
-		file_pb_autonatv2_proto_msgTypes[6].Exporter = func(v any, i int) any {
+		file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[6].Exporter = func(v any, i int) any {
 			switch v := v.(*DialBackResponse); i {
 			case 0:
 				return &v.state
@@ -790,7 +795,7 @@ func file_pb_autonatv2_proto_init() {
 			}
 		}
 	}
-	file_pb_autonatv2_proto_msgTypes[0].OneofWrappers = []any{
+	file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes[0].OneofWrappers = []any{
 		(*Message_DialRequest)(nil),
 		(*Message_DialResponse)(nil),
 		(*Message_DialDataRequest)(nil),
@@ -800,19 +805,19 @@ func file_pb_autonatv2_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_autonatv2_proto_rawDesc,
+			RawDescriptor: file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDesc,
 			NumEnums:      3,
 			NumMessages:   7,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_autonatv2_proto_goTypes,
-		DependencyIndexes: file_pb_autonatv2_proto_depIdxs,
-		EnumInfos:         file_pb_autonatv2_proto_enumTypes,
-		MessageInfos:      file_pb_autonatv2_proto_msgTypes,
+		GoTypes:           file_p2p_protocol_autonatv2_pb_autonatv2_proto_goTypes,
+		DependencyIndexes: file_p2p_protocol_autonatv2_pb_autonatv2_proto_depIdxs,
+		EnumInfos:         file_p2p_protocol_autonatv2_pb_autonatv2_proto_enumTypes,
+		MessageInfos:      file_p2p_protocol_autonatv2_pb_autonatv2_proto_msgTypes,
 	}.Build()
-	File_pb_autonatv2_proto = out.File
-	file_pb_autonatv2_proto_rawDesc = nil
-	file_pb_autonatv2_proto_goTypes = nil
-	file_pb_autonatv2_proto_depIdxs = nil
+	File_p2p_protocol_autonatv2_pb_autonatv2_proto = out.File
+	file_p2p_protocol_autonatv2_pb_autonatv2_proto_rawDesc = nil
+	file_p2p_protocol_autonatv2_pb_autonatv2_proto_goTypes = nil
+	file_p2p_protocol_autonatv2_pb_autonatv2_proto_depIdxs = nil
 }
diff --git a/p2p/protocol/autonatv2/pb/autonatv2.proto b/p2p/protocol/autonatv2/pb/autonatv2.proto
index 64dca113..0d7ad063 100644
--- a/p2p/protocol/autonatv2/pb/autonatv2.proto
+++ b/p2p/protocol/autonatv2/pb/autonatv2.proto
@@ -2,6 +2,8 @@ syntax = "proto3";
 
 package autonatv2.pb;
 
+option go_package = "github.com/libp2p/go-libp2p/p2p/protocol/autonatv2/pb";
+
 message Message {
     oneof msg {
         DialRequest dialRequest   = 1;
@@ -61,4 +63,4 @@ message DialBackResponse {
     }
 
     DialBackStatus status = 1;
-}
\ No newline at end of file
+}
diff --git a/p2p/protocol/circuitv2/pb/circuit.pb.go b/p2p/protocol/circuitv2/pb/circuit.pb.go
index afe93577..f9cc2036 100644
--- a/p2p/protocol/circuitv2/pb/circuit.pb.go
+++ b/p2p/protocol/circuitv2/pb/circuit.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/circuit.proto
+// 	protoc        v5.27.3
+// source: p2p/protocol/circuitv2/pb/circuit.proto
 
 package pb
 
@@ -72,11 +72,11 @@ func (x Status) String() string {
 }
 
 func (Status) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_circuit_proto_enumTypes[0].Descriptor()
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_enumTypes[0].Descriptor()
 }
 
 func (Status) Type() protoreflect.EnumType {
-	return &file_pb_circuit_proto_enumTypes[0]
+	return &file_p2p_protocol_circuitv2_pb_circuit_proto_enumTypes[0]
 }
 
 func (x Status) Number() protoreflect.EnumNumber {
@@ -85,7 +85,7 @@ func (x Status) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use Status.Descriptor instead.
 func (Status) EnumDescriptor() ([]byte, []int) {
-	return file_pb_circuit_proto_rawDescGZIP(), []int{0}
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescGZIP(), []int{0}
 }
 
 type HopMessage_Type int32
@@ -121,11 +121,11 @@ func (x HopMessage_Type) String() string {
 }
 
 func (HopMessage_Type) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_circuit_proto_enumTypes[1].Descriptor()
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_enumTypes[1].Descriptor()
 }
 
 func (HopMessage_Type) Type() protoreflect.EnumType {
-	return &file_pb_circuit_proto_enumTypes[1]
+	return &file_p2p_protocol_circuitv2_pb_circuit_proto_enumTypes[1]
 }
 
 func (x HopMessage_Type) Number() protoreflect.EnumNumber {
@@ -134,7 +134,7 @@ func (x HopMessage_Type) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use HopMessage_Type.Descriptor instead.
 func (HopMessage_Type) EnumDescriptor() ([]byte, []int) {
-	return file_pb_circuit_proto_rawDescGZIP(), []int{0, 0}
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescGZIP(), []int{0, 0}
 }
 
 type StopMessage_Type int32
@@ -167,11 +167,11 @@ func (x StopMessage_Type) String() string {
 }
 
 func (StopMessage_Type) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_circuit_proto_enumTypes[2].Descriptor()
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_enumTypes[2].Descriptor()
 }
 
 func (StopMessage_Type) Type() protoreflect.EnumType {
-	return &file_pb_circuit_proto_enumTypes[2]
+	return &file_p2p_protocol_circuitv2_pb_circuit_proto_enumTypes[2]
 }
 
 func (x StopMessage_Type) Number() protoreflect.EnumNumber {
@@ -180,7 +180,7 @@ func (x StopMessage_Type) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use StopMessage_Type.Descriptor instead.
 func (StopMessage_Type) EnumDescriptor() ([]byte, []int) {
-	return file_pb_circuit_proto_rawDescGZIP(), []int{1, 0}
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescGZIP(), []int{1, 0}
 }
 
 type HopMessage struct {
@@ -200,7 +200,7 @@ type HopMessage struct {
 func (x *HopMessage) Reset() {
 	*x = HopMessage{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_circuit_proto_msgTypes[0]
+		mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -213,7 +213,7 @@ func (x *HopMessage) String() string {
 func (*HopMessage) ProtoMessage() {}
 
 func (x *HopMessage) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_circuit_proto_msgTypes[0]
+	mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -226,7 +226,7 @@ func (x *HopMessage) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use HopMessage.ProtoReflect.Descriptor instead.
 func (*HopMessage) Descriptor() ([]byte, []int) {
-	return file_pb_circuit_proto_rawDescGZIP(), []int{0}
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *HopMessage) GetType() HopMessage_Type {
@@ -280,7 +280,7 @@ type StopMessage struct {
 func (x *StopMessage) Reset() {
 	*x = StopMessage{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_circuit_proto_msgTypes[1]
+		mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -293,7 +293,7 @@ func (x *StopMessage) String() string {
 func (*StopMessage) ProtoMessage() {}
 
 func (x *StopMessage) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_circuit_proto_msgTypes[1]
+	mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -306,7 +306,7 @@ func (x *StopMessage) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use StopMessage.ProtoReflect.Descriptor instead.
 func (*StopMessage) Descriptor() ([]byte, []int) {
-	return file_pb_circuit_proto_rawDescGZIP(), []int{1}
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *StopMessage) GetType() StopMessage_Type {
@@ -351,7 +351,7 @@ type Peer struct {
 func (x *Peer) Reset() {
 	*x = Peer{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_circuit_proto_msgTypes[2]
+		mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -364,7 +364,7 @@ func (x *Peer) String() string {
 func (*Peer) ProtoMessage() {}
 
 func (x *Peer) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_circuit_proto_msgTypes[2]
+	mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -377,7 +377,7 @@ func (x *Peer) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Peer.ProtoReflect.Descriptor instead.
 func (*Peer) Descriptor() ([]byte, []int) {
-	return file_pb_circuit_proto_rawDescGZIP(), []int{2}
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *Peer) GetId() []byte {
@@ -409,7 +409,7 @@ type Reservation struct {
 func (x *Reservation) Reset() {
 	*x = Reservation{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_circuit_proto_msgTypes[3]
+		mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -422,7 +422,7 @@ func (x *Reservation) String() string {
 func (*Reservation) ProtoMessage() {}
 
 func (x *Reservation) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_circuit_proto_msgTypes[3]
+	mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -435,7 +435,7 @@ func (x *Reservation) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Reservation.ProtoReflect.Descriptor instead.
 func (*Reservation) Descriptor() ([]byte, []int) {
-	return file_pb_circuit_proto_rawDescGZIP(), []int{3}
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *Reservation) GetExpire() uint64 {
@@ -471,7 +471,7 @@ type Limit struct {
 func (x *Limit) Reset() {
 	*x = Limit{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_circuit_proto_msgTypes[4]
+		mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[4]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -484,7 +484,7 @@ func (x *Limit) String() string {
 func (*Limit) ProtoMessage() {}
 
 func (x *Limit) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_circuit_proto_msgTypes[4]
+	mi := &file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[4]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -497,7 +497,7 @@ func (x *Limit) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Limit.ProtoReflect.Descriptor instead.
 func (*Limit) Descriptor() ([]byte, []int) {
-	return file_pb_circuit_proto_rawDescGZIP(), []int{4}
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescGZIP(), []int{4}
 }
 
 func (x *Limit) GetDuration() uint32 {
@@ -514,99 +514,104 @@ func (x *Limit) GetData() uint64 {
 	return 0
 }
 
-var File_pb_circuit_proto protoreflect.FileDescriptor
-
-var file_pb_circuit_proto_rawDesc = []byte{
-	0x0a, 0x10, 0x70, 0x62, 0x2f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x12, 0x0a, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x22, 0xf1,
-	0x02, 0x0a, 0x0a, 0x48, 0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a,
-	0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x63, 0x69,
-	0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
-	0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x10, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x50,
-	0x65, 0x65, 0x72, 0x48, 0x01, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x3e,
-	0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62,
-	0x2e, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x02, 0x52, 0x0b,
-	0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x2c,
-	0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
-	0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74,
-	0x48, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x06,
-	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63,
-	0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
-	0x48, 0x04, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x22, 0x2c, 0x0a,
-	0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x53, 0x45, 0x52, 0x56, 0x45,
-	0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x01, 0x12,
-	0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x02, 0x42, 0x07, 0x0a, 0x05, 0x5f,
-	0x74, 0x79, 0x70, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x42, 0x0e, 0x0a,
-	0x0c, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0x0a,
+var File_p2p_protocol_circuitv2_pb_circuit_proto protoreflect.FileDescriptor
+
+var file_p2p_protocol_circuitv2_pb_circuit_proto_rawDesc = []byte{
+	0x0a, 0x27, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x63,
+	0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x76, 0x32, 0x2f, 0x70, 0x62, 0x2f, 0x63, 0x69, 0x72, 0x63,
+	0x75, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x63, 0x69, 0x72, 0x63, 0x75,
+	0x69, 0x74, 0x2e, 0x70, 0x62, 0x22, 0xf1, 0x02, 0x0a, 0x0a, 0x48, 0x6f, 0x70, 0x4d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e,
+	0x48, 0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x48,
+	0x00, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x04, 0x70, 0x65,
+	0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75,
+	0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x48, 0x01, 0x52, 0x04, 0x70, 0x65,
+	0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x69, 0x72,
+	0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x48, 0x02, 0x52, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x2c, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70,
+	0x62, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x48, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74,
+	0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62,
+	0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x04, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x88, 0x01, 0x01, 0x22, 0x2c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07,
+	0x52, 0x45, 0x53, 0x45, 0x52, 0x56, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4e,
+	0x4e, 0x45, 0x43, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53,
+	0x10, 0x02, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f,
+	0x70, 0x65, 0x65, 0x72, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x09,
+	0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x96, 0x02, 0x0a, 0x0b, 0x53, 0x74,
+	0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x79, 0x70,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69,
+	0x74, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x2e, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01,
+	0x12, 0x29, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
+	0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x65, 0x65, 0x72,
+	0x48, 0x01, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x2c, 0x0a, 0x05, 0x6c,
+	0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x69, 0x72,
+	0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x48, 0x02, 0x52,
+	0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x69, 0x72, 0x63,
+	0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x03, 0x52,
+	0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x22, 0x1f, 0x0a, 0x04, 0x54, 0x79,
+	0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x00, 0x12,
+	0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f,
+	0x74, 0x79, 0x70, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x42, 0x08, 0x0a,
 	0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x22, 0x96, 0x02, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
-	0x32, 0x1c, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74,
-	0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00,
-	0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x04, 0x70, 0x65, 0x65,
-	0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69,
-	0x74, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x48, 0x01, 0x52, 0x04, 0x70, 0x65, 0x65,
-	0x72, 0x88, 0x01, 0x01, 0x12, 0x2c, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62,
-	0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x48, 0x02, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88,
-	0x01, 0x01, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x2e,
-	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x03, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
-	0x88, 0x01, 0x01, 0x22, 0x1f, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43,
-	0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54,
-	0x55, 0x53, 0x10, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x42, 0x07, 0x0a,
-	0x05, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74,
-	0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x38, 0x0a, 0x04, 0x50,
-	0x65, 0x65, 0x72, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48,
-	0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72,
-	0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x42, 0x05,
-	0x0a, 0x03, 0x5f, 0x69, 0x64, 0x22, 0x76, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x88, 0x01,
-	0x01, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c,
-	0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x07, 0x76, 0x6f, 0x75, 0x63, 0x68,
-	0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x01, 0x52, 0x07, 0x76, 0x6f, 0x75, 0x63,
-	0x68, 0x65, 0x72, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72,
-	0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x22, 0x57, 0x0a,
-	0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1f, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x04, 0x48, 0x01, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01,
-	0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x07, 0x0a,
-	0x05, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x2a, 0xca, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a,
-	0x02, 0x4f, 0x4b, 0x10, 0x64, 0x12, 0x18, 0x0a, 0x13, 0x52, 0x45, 0x53, 0x45, 0x52, 0x56, 0x41,
-	0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x53, 0x45, 0x44, 0x10, 0xc8, 0x01, 0x12,
-	0x1c, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49,
-	0x54, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0xc9, 0x01, 0x12, 0x16, 0x0a,
-	0x11, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x49,
-	0x45, 0x44, 0x10, 0xca, 0x01, 0x12, 0x16, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54,
-	0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0xcb, 0x01, 0x12, 0x13, 0x0a,
-	0x0e, 0x4e, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x52, 0x56, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10,
-	0xcc, 0x01, 0x12, 0x16, 0x0a, 0x11, 0x4d, 0x41, 0x4c, 0x46, 0x4f, 0x52, 0x4d, 0x45, 0x44, 0x5f,
-	0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x90, 0x03, 0x12, 0x17, 0x0a, 0x12, 0x55, 0x4e,
-	0x45, 0x58, 0x50, 0x45, 0x43, 0x54, 0x45, 0x44, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45,
-	0x10, 0x91, 0x03, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x75, 0x73, 0x22, 0x38, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12,
+	0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05,
+	0x61, 0x64, 0x64, 0x72, 0x73, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x22, 0x76, 0x0a, 0x0b,
+	0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x06, 0x65,
+	0x78, 0x70, 0x69, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x06, 0x65,
+	0x78, 0x70, 0x69, 0x72, 0x65, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72,
+	0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x12, 0x1d,
+	0x0a, 0x07, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48,
+	0x01, 0x52, 0x07, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a,
+	0x07, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x76, 0x6f, 0x75,
+	0x63, 0x68, 0x65, 0x72, 0x22, 0x57, 0x0a, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1f, 0x0a,
+	0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48,
+	0x00, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x17,
+	0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x48, 0x01, 0x52, 0x04,
+	0x64, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x75, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x2a, 0xca, 0x01,
+	0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x4e, 0x55, 0x53,
+	0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x64, 0x12, 0x18, 0x0a, 0x13,
+	0x52, 0x45, 0x53, 0x45, 0x52, 0x56, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x46, 0x55,
+	0x53, 0x45, 0x44, 0x10, 0xc8, 0x01, 0x12, 0x1c, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52,
+	0x43, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45,
+	0x44, 0x10, 0xc9, 0x01, 0x12, 0x16, 0x0a, 0x11, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49,
+	0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0xca, 0x01, 0x12, 0x16, 0x0a, 0x11,
+	0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45,
+	0x44, 0x10, 0xcb, 0x01, 0x12, 0x13, 0x0a, 0x0e, 0x4e, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x52,
+	0x56, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0xcc, 0x01, 0x12, 0x16, 0x0a, 0x11, 0x4d, 0x41, 0x4c,
+	0x46, 0x4f, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x90,
+	0x03, 0x12, 0x17, 0x0a, 0x12, 0x55, 0x4e, 0x45, 0x58, 0x50, 0x45, 0x43, 0x54, 0x45, 0x44, 0x5f,
+	0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x91, 0x03, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69,
+	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f,
+	0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x76, 0x32,
+	0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_pb_circuit_proto_rawDescOnce sync.Once
-	file_pb_circuit_proto_rawDescData = file_pb_circuit_proto_rawDesc
+	file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescOnce sync.Once
+	file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescData = file_p2p_protocol_circuitv2_pb_circuit_proto_rawDesc
 )
 
-func file_pb_circuit_proto_rawDescGZIP() []byte {
-	file_pb_circuit_proto_rawDescOnce.Do(func() {
-		file_pb_circuit_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_circuit_proto_rawDescData)
+func file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescGZIP() []byte {
+	file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescOnce.Do(func() {
+		file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescData = protoimpl.X.CompressGZIP(file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescData)
 	})
-	return file_pb_circuit_proto_rawDescData
+	return file_p2p_protocol_circuitv2_pb_circuit_proto_rawDescData
 }
 
-var file_pb_circuit_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
-var file_pb_circuit_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
-var file_pb_circuit_proto_goTypes = []any{
+var file_p2p_protocol_circuitv2_pb_circuit_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
+var file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_p2p_protocol_circuitv2_pb_circuit_proto_goTypes = []any{
 	(Status)(0),           // 0: circuit.pb.Status
 	(HopMessage_Type)(0),  // 1: circuit.pb.HopMessage.Type
 	(StopMessage_Type)(0), // 2: circuit.pb.StopMessage.Type
@@ -616,7 +621,7 @@ var file_pb_circuit_proto_goTypes = []any{
 	(*Reservation)(nil),   // 6: circuit.pb.Reservation
 	(*Limit)(nil),         // 7: circuit.pb.Limit
 }
-var file_pb_circuit_proto_depIdxs = []int32{
+var file_p2p_protocol_circuitv2_pb_circuit_proto_depIdxs = []int32{
 	1, // 0: circuit.pb.HopMessage.type:type_name -> circuit.pb.HopMessage.Type
 	5, // 1: circuit.pb.HopMessage.peer:type_name -> circuit.pb.Peer
 	6, // 2: circuit.pb.HopMessage.reservation:type_name -> circuit.pb.Reservation
@@ -633,13 +638,13 @@ var file_pb_circuit_proto_depIdxs = []int32{
 	0, // [0:9] is the sub-list for field type_name
 }
 
-func init() { file_pb_circuit_proto_init() }
-func file_pb_circuit_proto_init() {
-	if File_pb_circuit_proto != nil {
+func init() { file_p2p_protocol_circuitv2_pb_circuit_proto_init() }
+func file_p2p_protocol_circuitv2_pb_circuit_proto_init() {
+	if File_p2p_protocol_circuitv2_pb_circuit_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_circuit_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*HopMessage); i {
 			case 0:
 				return &v.state
@@ -651,7 +656,7 @@ func file_pb_circuit_proto_init() {
 				return nil
 			}
 		}
-		file_pb_circuit_proto_msgTypes[1].Exporter = func(v any, i int) any {
+		file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[1].Exporter = func(v any, i int) any {
 			switch v := v.(*StopMessage); i {
 			case 0:
 				return &v.state
@@ -663,7 +668,7 @@ func file_pb_circuit_proto_init() {
 				return nil
 			}
 		}
-		file_pb_circuit_proto_msgTypes[2].Exporter = func(v any, i int) any {
+		file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[2].Exporter = func(v any, i int) any {
 			switch v := v.(*Peer); i {
 			case 0:
 				return &v.state
@@ -675,7 +680,7 @@ func file_pb_circuit_proto_init() {
 				return nil
 			}
 		}
-		file_pb_circuit_proto_msgTypes[3].Exporter = func(v any, i int) any {
+		file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[3].Exporter = func(v any, i int) any {
 			switch v := v.(*Reservation); i {
 			case 0:
 				return &v.state
@@ -687,7 +692,7 @@ func file_pb_circuit_proto_init() {
 				return nil
 			}
 		}
-		file_pb_circuit_proto_msgTypes[4].Exporter = func(v any, i int) any {
+		file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[4].Exporter = func(v any, i int) any {
 			switch v := v.(*Limit); i {
 			case 0:
 				return &v.state
@@ -700,28 +705,28 @@ func file_pb_circuit_proto_init() {
 			}
 		}
 	}
-	file_pb_circuit_proto_msgTypes[0].OneofWrappers = []any{}
-	file_pb_circuit_proto_msgTypes[1].OneofWrappers = []any{}
-	file_pb_circuit_proto_msgTypes[2].OneofWrappers = []any{}
-	file_pb_circuit_proto_msgTypes[3].OneofWrappers = []any{}
-	file_pb_circuit_proto_msgTypes[4].OneofWrappers = []any{}
+	file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[0].OneofWrappers = []any{}
+	file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[1].OneofWrappers = []any{}
+	file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[2].OneofWrappers = []any{}
+	file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[3].OneofWrappers = []any{}
+	file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes[4].OneofWrappers = []any{}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_circuit_proto_rawDesc,
+			RawDescriptor: file_p2p_protocol_circuitv2_pb_circuit_proto_rawDesc,
 			NumEnums:      3,
 			NumMessages:   5,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_circuit_proto_goTypes,
-		DependencyIndexes: file_pb_circuit_proto_depIdxs,
-		EnumInfos:         file_pb_circuit_proto_enumTypes,
-		MessageInfos:      file_pb_circuit_proto_msgTypes,
+		GoTypes:           file_p2p_protocol_circuitv2_pb_circuit_proto_goTypes,
+		DependencyIndexes: file_p2p_protocol_circuitv2_pb_circuit_proto_depIdxs,
+		EnumInfos:         file_p2p_protocol_circuitv2_pb_circuit_proto_enumTypes,
+		MessageInfos:      file_p2p_protocol_circuitv2_pb_circuit_proto_msgTypes,
 	}.Build()
-	File_pb_circuit_proto = out.File
-	file_pb_circuit_proto_rawDesc = nil
-	file_pb_circuit_proto_goTypes = nil
-	file_pb_circuit_proto_depIdxs = nil
+	File_p2p_protocol_circuitv2_pb_circuit_proto = out.File
+	file_p2p_protocol_circuitv2_pb_circuit_proto_rawDesc = nil
+	file_p2p_protocol_circuitv2_pb_circuit_proto_goTypes = nil
+	file_p2p_protocol_circuitv2_pb_circuit_proto_depIdxs = nil
 }
diff --git a/p2p/protocol/circuitv2/pb/circuit.proto b/p2p/protocol/circuitv2/pb/circuit.proto
index b9b65fa0..43af7e89 100644
--- a/p2p/protocol/circuitv2/pb/circuit.proto
+++ b/p2p/protocol/circuitv2/pb/circuit.proto
@@ -2,6 +2,8 @@ syntax = "proto3";
 
 package circuit.pb;
 
+option go_package = "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb";
+
 message HopMessage {
   enum Type {
     RESERVE = 0;
@@ -67,4 +69,4 @@ enum Status {
   NO_RESERVATION          = 204;
   MALFORMED_MESSAGE       = 400;
   UNEXPECTED_MESSAGE      = 401;
-}
\ No newline at end of file
+}
diff --git a/p2p/protocol/circuitv2/pb/voucher.pb.go b/p2p/protocol/circuitv2/pb/voucher.pb.go
index 6b02cdac..02d8f212 100644
--- a/p2p/protocol/circuitv2/pb/voucher.pb.go
+++ b/p2p/protocol/circuitv2/pb/voucher.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/voucher.proto
+// 	protoc        v5.27.3
+// source: p2p/protocol/circuitv2/pb/voucher.proto
 
 package pb
 
@@ -35,7 +35,7 @@ type ReservationVoucher struct {
 func (x *ReservationVoucher) Reset() {
 	*x = ReservationVoucher{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_voucher_proto_msgTypes[0]
+		mi := &file_p2p_protocol_circuitv2_pb_voucher_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -48,7 +48,7 @@ func (x *ReservationVoucher) String() string {
 func (*ReservationVoucher) ProtoMessage() {}
 
 func (x *ReservationVoucher) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_voucher_proto_msgTypes[0]
+	mi := &file_p2p_protocol_circuitv2_pb_voucher_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -61,7 +61,7 @@ func (x *ReservationVoucher) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ReservationVoucher.ProtoReflect.Descriptor instead.
 func (*ReservationVoucher) Descriptor() ([]byte, []int) {
-	return file_pb_voucher_proto_rawDescGZIP(), []int{0}
+	return file_p2p_protocol_circuitv2_pb_voucher_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *ReservationVoucher) GetRelay() []byte {
@@ -85,40 +85,45 @@ func (x *ReservationVoucher) GetExpiration() uint64 {
 	return 0
 }
 
-var File_pb_voucher_proto protoreflect.FileDescriptor
-
-var file_pb_voucher_proto_rawDesc = []byte{
-	0x0a, 0x10, 0x70, 0x62, 0x2f, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x12, 0x0a, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x62, 0x22, 0x8f,
-	0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x6f,
-	0x75, 0x63, 0x68, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x88, 0x01, 0x01,
-	0x12, 0x17, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x01,
-	0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x0a, 0x65, 0x78, 0x70,
-	0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x48, 0x02, 0x52,
-	0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x08,
-	0x0a, 0x06, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x65, 0x65,
-	0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+var File_p2p_protocol_circuitv2_pb_voucher_proto protoreflect.FileDescriptor
+
+var file_p2p_protocol_circuitv2_pb_voucher_proto_rawDesc = []byte{
+	0x0a, 0x27, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x63,
+	0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x76, 0x32, 0x2f, 0x70, 0x62, 0x2f, 0x76, 0x6f, 0x75, 0x63,
+	0x68, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x63, 0x69, 0x72, 0x63, 0x75,
+	0x69, 0x74, 0x2e, 0x70, 0x62, 0x22, 0x8f, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x05,
+	0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x72,
+	0x65, 0x6c, 0x61, 0x79, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x01, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x88, 0x01, 0x01,
+	0x12, 0x23, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x04, 0x48, 0x02, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x42,
+	0x07, 0x0a, 0x05, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70,
+	0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75,
+	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d,
+	0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x63, 0x6f, 0x6c, 0x2f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x76, 0x32, 0x2f, 0x70, 0x62,
 	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_pb_voucher_proto_rawDescOnce sync.Once
-	file_pb_voucher_proto_rawDescData = file_pb_voucher_proto_rawDesc
+	file_p2p_protocol_circuitv2_pb_voucher_proto_rawDescOnce sync.Once
+	file_p2p_protocol_circuitv2_pb_voucher_proto_rawDescData = file_p2p_protocol_circuitv2_pb_voucher_proto_rawDesc
 )
 
-func file_pb_voucher_proto_rawDescGZIP() []byte {
-	file_pb_voucher_proto_rawDescOnce.Do(func() {
-		file_pb_voucher_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_voucher_proto_rawDescData)
+func file_p2p_protocol_circuitv2_pb_voucher_proto_rawDescGZIP() []byte {
+	file_p2p_protocol_circuitv2_pb_voucher_proto_rawDescOnce.Do(func() {
+		file_p2p_protocol_circuitv2_pb_voucher_proto_rawDescData = protoimpl.X.CompressGZIP(file_p2p_protocol_circuitv2_pb_voucher_proto_rawDescData)
 	})
-	return file_pb_voucher_proto_rawDescData
+	return file_p2p_protocol_circuitv2_pb_voucher_proto_rawDescData
 }
 
-var file_pb_voucher_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
-var file_pb_voucher_proto_goTypes = []any{
+var file_p2p_protocol_circuitv2_pb_voucher_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_p2p_protocol_circuitv2_pb_voucher_proto_goTypes = []any{
 	(*ReservationVoucher)(nil), // 0: circuit.pb.ReservationVoucher
 }
-var file_pb_voucher_proto_depIdxs = []int32{
+var file_p2p_protocol_circuitv2_pb_voucher_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for method output_type
 	0, // [0:0] is the sub-list for method input_type
 	0, // [0:0] is the sub-list for extension type_name
@@ -126,13 +131,13 @@ var file_pb_voucher_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for field type_name
 }
 
-func init() { file_pb_voucher_proto_init() }
-func file_pb_voucher_proto_init() {
-	if File_pb_voucher_proto != nil {
+func init() { file_p2p_protocol_circuitv2_pb_voucher_proto_init() }
+func file_p2p_protocol_circuitv2_pb_voucher_proto_init() {
+	if File_p2p_protocol_circuitv2_pb_voucher_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_voucher_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_p2p_protocol_circuitv2_pb_voucher_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*ReservationVoucher); i {
 			case 0:
 				return &v.state
@@ -145,23 +150,23 @@ func file_pb_voucher_proto_init() {
 			}
 		}
 	}
-	file_pb_voucher_proto_msgTypes[0].OneofWrappers = []any{}
+	file_p2p_protocol_circuitv2_pb_voucher_proto_msgTypes[0].OneofWrappers = []any{}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_voucher_proto_rawDesc,
+			RawDescriptor: file_p2p_protocol_circuitv2_pb_voucher_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   1,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_voucher_proto_goTypes,
-		DependencyIndexes: file_pb_voucher_proto_depIdxs,
-		MessageInfos:      file_pb_voucher_proto_msgTypes,
+		GoTypes:           file_p2p_protocol_circuitv2_pb_voucher_proto_goTypes,
+		DependencyIndexes: file_p2p_protocol_circuitv2_pb_voucher_proto_depIdxs,
+		MessageInfos:      file_p2p_protocol_circuitv2_pb_voucher_proto_msgTypes,
 	}.Build()
-	File_pb_voucher_proto = out.File
-	file_pb_voucher_proto_rawDesc = nil
-	file_pb_voucher_proto_goTypes = nil
-	file_pb_voucher_proto_depIdxs = nil
+	File_p2p_protocol_circuitv2_pb_voucher_proto = out.File
+	file_p2p_protocol_circuitv2_pb_voucher_proto_rawDesc = nil
+	file_p2p_protocol_circuitv2_pb_voucher_proto_goTypes = nil
+	file_p2p_protocol_circuitv2_pb_voucher_proto_depIdxs = nil
 }
diff --git a/p2p/protocol/circuitv2/pb/voucher.proto b/p2p/protocol/circuitv2/pb/voucher.proto
index 1e2e7963..b723c78a 100644
--- a/p2p/protocol/circuitv2/pb/voucher.proto
+++ b/p2p/protocol/circuitv2/pb/voucher.proto
@@ -2,10 +2,12 @@ syntax = "proto3";
 
 package circuit.pb;
 
+option go_package = "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb";
+
 message ReservationVoucher {
   // These fields are marked optional for backwards compatibility with proto2.
   // Users should make sure to always set these.
   optional bytes relay = 1;
   optional bytes peer = 2;
   optional uint64 expiration = 3;
-}
\ No newline at end of file
+}
diff --git a/p2p/protocol/circuitv2/proto.go b/p2p/protocol/circuitv2/proto.go
deleted file mode 100644
index d0e0436c..00000000
--- a/p2p/protocol/circuitv2/proto.go
+++ /dev/null
@@ -1,4 +0,0 @@
-package circuitv2
-
-//go:generate protoc --proto_path=$PWD:$PWD/../../.. --go_out=. --go_opt=Mpb/circuit.proto=./pb pb/circuit.proto
-//go:generate protoc --proto_path=$PWD:$PWD/../../.. --go_out=. --go_opt=Mpb/voucher.proto=./pb pb/voucher.proto
diff --git a/p2p/protocol/holepunch/holepuncher.go b/p2p/protocol/holepunch/holepuncher.go
index 479376ef..a30e6537 100644
--- a/p2p/protocol/holepunch/holepuncher.go
+++ b/p2p/protocol/holepunch/holepuncher.go
@@ -17,8 +17,6 @@ import (
 	manet "github.com/multiformats/go-multiaddr/net"
 )
 
-//go:generate protoc --proto_path=$PWD:$PWD/../../.. --go_out=. --go_opt=Mpb/holepunch.proto=./pb pb/holepunch.proto
-
 // ErrHolePunchActive is returned from DirectConnect when another hole punching attempt is currently running
 var ErrHolePunchActive = errors.New("another hole punching attempt to this peer is active")
 
diff --git a/p2p/protocol/holepunch/pb/holepunch.pb.go b/p2p/protocol/holepunch/pb/holepunch.pb.go
index 8478ab69..dde534a7 100644
--- a/p2p/protocol/holepunch/pb/holepunch.pb.go
+++ b/p2p/protocol/holepunch/pb/holepunch.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/holepunch.proto
+// 	protoc        v5.27.3
+// source: p2p/protocol/holepunch/pb/holepunch.proto
 
 package pb
 
@@ -50,11 +50,11 @@ func (x HolePunch_Type) String() string {
 }
 
 func (HolePunch_Type) Descriptor() protoreflect.EnumDescriptor {
-	return file_pb_holepunch_proto_enumTypes[0].Descriptor()
+	return file_p2p_protocol_holepunch_pb_holepunch_proto_enumTypes[0].Descriptor()
 }
 
 func (HolePunch_Type) Type() protoreflect.EnumType {
-	return &file_pb_holepunch_proto_enumTypes[0]
+	return &file_p2p_protocol_holepunch_pb_holepunch_proto_enumTypes[0]
 }
 
 func (x HolePunch_Type) Number() protoreflect.EnumNumber {
@@ -73,7 +73,7 @@ func (x *HolePunch_Type) UnmarshalJSON(b []byte) error {
 
 // Deprecated: Use HolePunch_Type.Descriptor instead.
 func (HolePunch_Type) EnumDescriptor() ([]byte, []int) {
-	return file_pb_holepunch_proto_rawDescGZIP(), []int{0, 0}
+	return file_p2p_protocol_holepunch_pb_holepunch_proto_rawDescGZIP(), []int{0, 0}
 }
 
 // spec: https://github.com/libp2p/specs/blob/master/relay/DCUtR.md
@@ -89,7 +89,7 @@ type HolePunch struct {
 func (x *HolePunch) Reset() {
 	*x = HolePunch{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_holepunch_proto_msgTypes[0]
+		mi := &file_p2p_protocol_holepunch_pb_holepunch_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -102,7 +102,7 @@ func (x *HolePunch) String() string {
 func (*HolePunch) ProtoMessage() {}
 
 func (x *HolePunch) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_holepunch_proto_msgTypes[0]
+	mi := &file_p2p_protocol_holepunch_pb_holepunch_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -115,7 +115,7 @@ func (x *HolePunch) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use HolePunch.ProtoReflect.Descriptor instead.
 func (*HolePunch) Descriptor() ([]byte, []int) {
-	return file_pb_holepunch_proto_rawDescGZIP(), []int{0}
+	return file_p2p_protocol_holepunch_pb_holepunch_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *HolePunch) GetType() HolePunch_Type {
@@ -132,40 +132,45 @@ func (x *HolePunch) GetObsAddrs() [][]byte {
 	return nil
 }
 
-var File_pb_holepunch_proto protoreflect.FileDescriptor
+var File_p2p_protocol_holepunch_pb_holepunch_proto protoreflect.FileDescriptor
 
-var file_pb_holepunch_proto_rawDesc = []byte{
-	0x0a, 0x12, 0x70, 0x62, 0x2f, 0x68, 0x6f, 0x6c, 0x65, 0x70, 0x75, 0x6e, 0x63, 0x68, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x68, 0x6f, 0x6c, 0x65, 0x70, 0x75, 0x6e, 0x63, 0x68, 0x2e,
-	0x70, 0x62, 0x22, 0x79, 0x0a, 0x09, 0x48, 0x6f, 0x6c, 0x65, 0x50, 0x75, 0x6e, 0x63, 0x68, 0x12,
-	0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x1c, 0x2e,
-	0x68, 0x6f, 0x6c, 0x65, 0x70, 0x75, 0x6e, 0x63, 0x68, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x6c,
-	0x65, 0x50, 0x75, 0x6e, 0x63, 0x68, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70,
-	0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4f, 0x62, 0x73, 0x41, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20,
-	0x03, 0x28, 0x0c, 0x52, 0x08, 0x4f, 0x62, 0x73, 0x41, 0x64, 0x64, 0x72, 0x73, 0x22, 0x1e, 0x0a,
-	0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54,
-	0x10, 0x64, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x59, 0x4e, 0x43, 0x10, 0xac, 0x02,
+var file_p2p_protocol_holepunch_pb_holepunch_proto_rawDesc = []byte{
+	0x0a, 0x29, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68,
+	0x6f, 0x6c, 0x65, 0x70, 0x75, 0x6e, 0x63, 0x68, 0x2f, 0x70, 0x62, 0x2f, 0x68, 0x6f, 0x6c, 0x65,
+	0x70, 0x75, 0x6e, 0x63, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x68, 0x6f, 0x6c,
+	0x65, 0x70, 0x75, 0x6e, 0x63, 0x68, 0x2e, 0x70, 0x62, 0x22, 0x79, 0x0a, 0x09, 0x48, 0x6f, 0x6c,
+	0x65, 0x50, 0x75, 0x6e, 0x63, 0x68, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,
+	0x20, 0x02, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x68, 0x6f, 0x6c, 0x65, 0x70, 0x75, 0x6e, 0x63, 0x68,
+	0x2e, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x6c, 0x65, 0x50, 0x75, 0x6e, 0x63, 0x68, 0x2e, 0x54, 0x79,
+	0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4f, 0x62, 0x73, 0x41,
+	0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x4f, 0x62, 0x73, 0x41,
+	0x64, 0x64, 0x72, 0x73, 0x22, 0x1e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07,
+	0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x64, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x59, 0x4e,
+	0x43, 0x10, 0xac, 0x02, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62,
+	0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
+	0x2f, 0x68, 0x6f, 0x6c, 0x65, 0x70, 0x75, 0x6e, 0x63, 0x68, 0x2f, 0x70, 0x62,
 }
 
 var (
-	file_pb_holepunch_proto_rawDescOnce sync.Once
-	file_pb_holepunch_proto_rawDescData = file_pb_holepunch_proto_rawDesc
+	file_p2p_protocol_holepunch_pb_holepunch_proto_rawDescOnce sync.Once
+	file_p2p_protocol_holepunch_pb_holepunch_proto_rawDescData = file_p2p_protocol_holepunch_pb_holepunch_proto_rawDesc
 )
 
-func file_pb_holepunch_proto_rawDescGZIP() []byte {
-	file_pb_holepunch_proto_rawDescOnce.Do(func() {
-		file_pb_holepunch_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_holepunch_proto_rawDescData)
+func file_p2p_protocol_holepunch_pb_holepunch_proto_rawDescGZIP() []byte {
+	file_p2p_protocol_holepunch_pb_holepunch_proto_rawDescOnce.Do(func() {
+		file_p2p_protocol_holepunch_pb_holepunch_proto_rawDescData = protoimpl.X.CompressGZIP(file_p2p_protocol_holepunch_pb_holepunch_proto_rawDescData)
 	})
-	return file_pb_holepunch_proto_rawDescData
+	return file_p2p_protocol_holepunch_pb_holepunch_proto_rawDescData
 }
 
-var file_pb_holepunch_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_pb_holepunch_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
-var file_pb_holepunch_proto_goTypes = []any{
+var file_p2p_protocol_holepunch_pb_holepunch_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_p2p_protocol_holepunch_pb_holepunch_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_p2p_protocol_holepunch_pb_holepunch_proto_goTypes = []any{
 	(HolePunch_Type)(0), // 0: holepunch.pb.HolePunch.Type
 	(*HolePunch)(nil),   // 1: holepunch.pb.HolePunch
 }
-var file_pb_holepunch_proto_depIdxs = []int32{
+var file_p2p_protocol_holepunch_pb_holepunch_proto_depIdxs = []int32{
 	0, // 0: holepunch.pb.HolePunch.type:type_name -> holepunch.pb.HolePunch.Type
 	1, // [1:1] is the sub-list for method output_type
 	1, // [1:1] is the sub-list for method input_type
@@ -174,13 +179,13 @@ var file_pb_holepunch_proto_depIdxs = []int32{
 	0, // [0:1] is the sub-list for field type_name
 }
 
-func init() { file_pb_holepunch_proto_init() }
-func file_pb_holepunch_proto_init() {
-	if File_pb_holepunch_proto != nil {
+func init() { file_p2p_protocol_holepunch_pb_holepunch_proto_init() }
+func file_p2p_protocol_holepunch_pb_holepunch_proto_init() {
+	if File_p2p_protocol_holepunch_pb_holepunch_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_holepunch_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_p2p_protocol_holepunch_pb_holepunch_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*HolePunch); i {
 			case 0:
 				return &v.state
@@ -197,19 +202,19 @@ func file_pb_holepunch_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_holepunch_proto_rawDesc,
+			RawDescriptor: file_p2p_protocol_holepunch_pb_holepunch_proto_rawDesc,
 			NumEnums:      1,
 			NumMessages:   1,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_holepunch_proto_goTypes,
-		DependencyIndexes: file_pb_holepunch_proto_depIdxs,
-		EnumInfos:         file_pb_holepunch_proto_enumTypes,
-		MessageInfos:      file_pb_holepunch_proto_msgTypes,
+		GoTypes:           file_p2p_protocol_holepunch_pb_holepunch_proto_goTypes,
+		DependencyIndexes: file_p2p_protocol_holepunch_pb_holepunch_proto_depIdxs,
+		EnumInfos:         file_p2p_protocol_holepunch_pb_holepunch_proto_enumTypes,
+		MessageInfos:      file_p2p_protocol_holepunch_pb_holepunch_proto_msgTypes,
 	}.Build()
-	File_pb_holepunch_proto = out.File
-	file_pb_holepunch_proto_rawDesc = nil
-	file_pb_holepunch_proto_goTypes = nil
-	file_pb_holepunch_proto_depIdxs = nil
+	File_p2p_protocol_holepunch_pb_holepunch_proto = out.File
+	file_p2p_protocol_holepunch_pb_holepunch_proto_rawDesc = nil
+	file_p2p_protocol_holepunch_pb_holepunch_proto_goTypes = nil
+	file_p2p_protocol_holepunch_pb_holepunch_proto_depIdxs = nil
 }
diff --git a/p2p/protocol/holepunch/pb/holepunch.proto b/p2p/protocol/holepunch/pb/holepunch.proto
index e5c4562e..cf697f94 100644
--- a/p2p/protocol/holepunch/pb/holepunch.proto
+++ b/p2p/protocol/holepunch/pb/holepunch.proto
@@ -2,6 +2,8 @@ syntax = "proto2";
 
 package holepunch.pb;
 
+option go_package = "github.com/libp2p/go-libp2p/p2p/protocol/holepunch/pb";
+
 // spec: https://github.com/libp2p/specs/blob/master/relay/DCUtR.md
 message HolePunch {
   enum Type {
diff --git a/p2p/protocol/holepunch/svc.go b/p2p/protocol/holepunch/svc.go
index 9de0a11e..eb8ad9fd 100644
--- a/p2p/protocol/holepunch/svc.go
+++ b/p2p/protocol/holepunch/svc.go
@@ -19,6 +19,7 @@ import (
 	"github.com/libp2p/go-msgio/pbio"
 
 	ma "github.com/multiformats/go-multiaddr"
+	manet "github.com/multiformats/go-multiaddr/net"
 )
 
 // Protocol is the libp2p protocol for Hole Punching.
@@ -106,7 +107,7 @@ func (s *Service) watchForPublicAddr() {
 	t := time.NewTimer(duration)
 	defer t.Stop()
 	for {
-		if containsPublicAddr(s.ids.OwnObservedAddrs()) {
+		if len(s.getPublicAddrs()) > 0 {
 			log.Debug("Host now has a public address. Starting holepunch protocol.")
 			s.host.SetStreamHandler(Protocol, s.handleNewStream)
 			break
@@ -171,7 +172,7 @@ func (s *Service) incomingHolePunch(str network.Stream) (rtt time.Duration, remo
 	if !isRelayAddress(str.Conn().RemoteMultiaddr()) {
 		return 0, nil, nil, fmt.Errorf("received hole punch stream: %s", str.Conn().RemoteMultiaddr())
 	}
-	ownAddrs = removeRelayAddrs(s.ids.OwnObservedAddrs())
+	ownAddrs = s.getPublicAddrs()
 	if s.filter != nil {
 		ownAddrs = s.filter.FilterLocal(str.Conn().RemotePeer(), ownAddrs)
 	}
@@ -274,6 +275,29 @@ func (s *Service) handleNewStream(str network.Stream) {
 	s.tracer.HolePunchFinished("receiver", 1, addrs, ownAddrs, getDirectConnection(s.host, rp))
 }
 
+// getPublicAddrs returns public observed and interface addresses
+func (s *Service) getPublicAddrs() []ma.Multiaddr {
+	addrs := removeRelayAddrs(s.ids.OwnObservedAddrs())
+
+	interfaceListenAddrs, err := s.host.Network().InterfaceListenAddresses()
+	if err != nil {
+		log.Debugf("failed to get to get InterfaceListenAddresses: %s", err)
+	} else {
+		addrs = append(addrs, interfaceListenAddrs...)
+	}
+
+	addrs = ma.Unique(addrs)
+
+	publicAddrs := make([]ma.Multiaddr, 0, len(addrs))
+
+	for _, addr := range addrs {
+		if manet.IsPublicAddr(addr) {
+			publicAddrs = append(publicAddrs, addr)
+		}
+	}
+	return publicAddrs
+}
+
 // DirectConnect is only exposed for testing purposes.
 // TODO: find a solution for this.
 func (s *Service) DirectConnect(p peer.ID) error {
diff --git a/p2p/protocol/holepunch/util.go b/p2p/protocol/holepunch/util.go
index 13013568..947b1ffd 100644
--- a/p2p/protocol/holepunch/util.go
+++ b/p2p/protocol/holepunch/util.go
@@ -8,19 +8,8 @@ import (
 	"github.com/libp2p/go-libp2p/core/peer"
 
 	ma "github.com/multiformats/go-multiaddr"
-	manet "github.com/multiformats/go-multiaddr/net"
 )
 
-func containsPublicAddr(addrs []ma.Multiaddr) bool {
-	for _, addr := range addrs {
-		if isRelayAddress(addr) || !manet.IsPublicAddr(addr) {
-			continue
-		}
-		return true
-	}
-	return false
-}
-
 func removeRelayAddrs(addrs []ma.Multiaddr) []ma.Multiaddr {
 	result := make([]ma.Multiaddr, 0, len(addrs))
 	for _, addr := range addrs {
diff --git a/p2p/protocol/identify/id.go b/p2p/protocol/identify/id.go
index e91fdee7..acaa40ac 100644
--- a/p2p/protocol/identify/id.go
+++ b/p2p/protocol/identify/id.go
@@ -30,8 +30,6 @@ import (
 	"google.golang.org/protobuf/proto"
 )
 
-//go:generate protoc --proto_path=$PWD:$PWD/../../.. --go_out=. --go_opt=Mpb/identify.proto=./pb pb/identify.proto
-
 var log = logging.Logger("net/identify")
 
 var Timeout = 30 * time.Second // timeout on all incoming Identify interactions
@@ -997,7 +995,7 @@ func (ids *idService) addConnWithLock(c network.Conn) {
 }
 
 func signedPeerRecordFromMessage(msg *pb.Identify) (*record.Envelope, error) {
-	if msg.SignedPeerRecord == nil || len(msg.SignedPeerRecord) == 0 {
+	if len(msg.SignedPeerRecord) == 0 {
 		return nil, nil
 	}
 	env, _, err := record.ConsumeEnvelope(msg.SignedPeerRecord, peer.PeerRecordEnvelopeDomain)
diff --git a/p2p/protocol/identify/pb/identify.pb.go b/p2p/protocol/identify/pb/identify.pb.go
index 078a7e17..a63ae000 100644
--- a/p2p/protocol/identify/pb/identify.pb.go
+++ b/p2p/protocol/identify/pb/identify.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/identify.proto
+// 	protoc        v5.27.3
+// source: p2p/protocol/identify/pb/identify.proto
 
 package pb
 
@@ -53,7 +53,7 @@ type Identify struct {
 func (x *Identify) Reset() {
 	*x = Identify{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_identify_proto_msgTypes[0]
+		mi := &file_p2p_protocol_identify_pb_identify_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -66,7 +66,7 @@ func (x *Identify) String() string {
 func (*Identify) ProtoMessage() {}
 
 func (x *Identify) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_identify_proto_msgTypes[0]
+	mi := &file_p2p_protocol_identify_pb_identify_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -79,7 +79,7 @@ func (x *Identify) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Identify.ProtoReflect.Descriptor instead.
 func (*Identify) Descriptor() ([]byte, []int) {
-	return file_pb_identify_proto_rawDescGZIP(), []int{0}
+	return file_p2p_protocol_identify_pb_identify_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *Identify) GetProtocolVersion() string {
@@ -131,47 +131,52 @@ func (x *Identify) GetSignedPeerRecord() []byte {
 	return nil
 }
 
-var File_pb_identify_proto protoreflect.FileDescriptor
-
-var file_pb_identify_proto_rawDesc = []byte{
-	0x0a, 0x11, 0x70, 0x62, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x62,
-	0x22, 0x86, 0x02, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x28, 0x0a,
-	0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
-	0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
-	0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74,
-	0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61,
-	0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x70,
-	0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
-	0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x6c, 0x69, 0x73,
-	0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b,
-	0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6f,
-	0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28,
-	0x0c, 0x52, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12,
-	0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03,
-	0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x2a, 0x0a,
-	0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72,
-	0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50,
-	0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
+var File_p2p_protocol_identify_pb_identify_proto protoreflect.FileDescriptor
+
+var file_p2p_protocol_identify_pb_identify_proto_rawDesc = []byte{
+	0x0a, 0x27, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x69,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x62, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74,
+	0x69, 0x66, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74,
+	0x69, 0x66, 0x79, 0x2e, 0x70, 0x62, 0x22, 0x86, 0x02, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74,
+	0x69, 0x66, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a,
+	0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12,
+	0x20, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02,
+	0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72,
+	0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x64, 0x64,
+	0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65,
+	0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
+	0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
+	0x6f, 0x6c, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65,
+	0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x73,
+	0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x42,
+	0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69,
+	0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x70,
+	0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x69, 0x64, 0x65, 0x6e,
+	0x74, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x62,
 }
 
 var (
-	file_pb_identify_proto_rawDescOnce sync.Once
-	file_pb_identify_proto_rawDescData = file_pb_identify_proto_rawDesc
+	file_p2p_protocol_identify_pb_identify_proto_rawDescOnce sync.Once
+	file_p2p_protocol_identify_pb_identify_proto_rawDescData = file_p2p_protocol_identify_pb_identify_proto_rawDesc
 )
 
-func file_pb_identify_proto_rawDescGZIP() []byte {
-	file_pb_identify_proto_rawDescOnce.Do(func() {
-		file_pb_identify_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_identify_proto_rawDescData)
+func file_p2p_protocol_identify_pb_identify_proto_rawDescGZIP() []byte {
+	file_p2p_protocol_identify_pb_identify_proto_rawDescOnce.Do(func() {
+		file_p2p_protocol_identify_pb_identify_proto_rawDescData = protoimpl.X.CompressGZIP(file_p2p_protocol_identify_pb_identify_proto_rawDescData)
 	})
-	return file_pb_identify_proto_rawDescData
+	return file_p2p_protocol_identify_pb_identify_proto_rawDescData
 }
 
-var file_pb_identify_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
-var file_pb_identify_proto_goTypes = []any{
+var file_p2p_protocol_identify_pb_identify_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_p2p_protocol_identify_pb_identify_proto_goTypes = []any{
 	(*Identify)(nil), // 0: identify.pb.Identify
 }
-var file_pb_identify_proto_depIdxs = []int32{
+var file_p2p_protocol_identify_pb_identify_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for method output_type
 	0, // [0:0] is the sub-list for method input_type
 	0, // [0:0] is the sub-list for extension type_name
@@ -179,13 +184,13 @@ var file_pb_identify_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for field type_name
 }
 
-func init() { file_pb_identify_proto_init() }
-func file_pb_identify_proto_init() {
-	if File_pb_identify_proto != nil {
+func init() { file_p2p_protocol_identify_pb_identify_proto_init() }
+func file_p2p_protocol_identify_pb_identify_proto_init() {
+	if File_p2p_protocol_identify_pb_identify_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_identify_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_p2p_protocol_identify_pb_identify_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*Identify); i {
 			case 0:
 				return &v.state
@@ -202,18 +207,18 @@ func file_pb_identify_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_identify_proto_rawDesc,
+			RawDescriptor: file_p2p_protocol_identify_pb_identify_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   1,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_identify_proto_goTypes,
-		DependencyIndexes: file_pb_identify_proto_depIdxs,
-		MessageInfos:      file_pb_identify_proto_msgTypes,
+		GoTypes:           file_p2p_protocol_identify_pb_identify_proto_goTypes,
+		DependencyIndexes: file_p2p_protocol_identify_pb_identify_proto_depIdxs,
+		MessageInfos:      file_p2p_protocol_identify_pb_identify_proto_msgTypes,
 	}.Build()
-	File_pb_identify_proto = out.File
-	file_pb_identify_proto_rawDesc = nil
-	file_pb_identify_proto_goTypes = nil
-	file_pb_identify_proto_depIdxs = nil
+	File_p2p_protocol_identify_pb_identify_proto = out.File
+	file_p2p_protocol_identify_pb_identify_proto_rawDesc = nil
+	file_p2p_protocol_identify_pb_identify_proto_goTypes = nil
+	file_p2p_protocol_identify_pb_identify_proto_depIdxs = nil
 }
diff --git a/p2p/protocol/identify/pb/identify.proto b/p2p/protocol/identify/pb/identify.proto
index cda102d4..11343870 100644
--- a/p2p/protocol/identify/pb/identify.proto
+++ b/p2p/protocol/identify/pb/identify.proto
@@ -2,6 +2,8 @@ syntax = "proto2";
 
 package identify.pb;
 
+option go_package = "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb";
+
 message Identify {
 
   // protocolVersion determines compatibility between peers
diff --git a/p2p/security/noise/handshake.go b/p2p/security/noise/handshake.go
index 47607684..d81aa72f 100644
--- a/p2p/security/noise/handshake.go
+++ b/p2p/security/noise/handshake.go
@@ -19,8 +19,6 @@ import (
 	"google.golang.org/protobuf/proto"
 )
 
-//go:generate protoc --go_out=. --go_opt=Mpb/payload.proto=./pb pb/payload.proto
-
 // payloadSigPrefix is prepended to our Noise static key before signing with
 // our libp2p identity key.
 const payloadSigPrefix = "noise-libp2p-static-key:"
diff --git a/p2p/security/noise/pb/payload.pb.go b/p2p/security/noise/pb/payload.pb.go
index dc980dd1..3572d128 100644
--- a/p2p/security/noise/pb/payload.pb.go
+++ b/p2p/security/noise/pb/payload.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: pb/payload.proto
+// 	protoc        v5.27.3
+// source: p2p/security/noise/pb/payload.proto
 
 package pb
 
@@ -32,7 +32,7 @@ type NoiseExtensions struct {
 func (x *NoiseExtensions) Reset() {
 	*x = NoiseExtensions{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_payload_proto_msgTypes[0]
+		mi := &file_p2p_security_noise_pb_payload_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -45,7 +45,7 @@ func (x *NoiseExtensions) String() string {
 func (*NoiseExtensions) ProtoMessage() {}
 
 func (x *NoiseExtensions) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_payload_proto_msgTypes[0]
+	mi := &file_p2p_security_noise_pb_payload_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -58,7 +58,7 @@ func (x *NoiseExtensions) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use NoiseExtensions.ProtoReflect.Descriptor instead.
 func (*NoiseExtensions) Descriptor() ([]byte, []int) {
-	return file_pb_payload_proto_rawDescGZIP(), []int{0}
+	return file_p2p_security_noise_pb_payload_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *NoiseExtensions) GetWebtransportCerthashes() [][]byte {
@@ -88,7 +88,7 @@ type NoiseHandshakePayload struct {
 func (x *NoiseHandshakePayload) Reset() {
 	*x = NoiseHandshakePayload{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_pb_payload_proto_msgTypes[1]
+		mi := &file_p2p_security_noise_pb_payload_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -101,7 +101,7 @@ func (x *NoiseHandshakePayload) String() string {
 func (*NoiseHandshakePayload) ProtoMessage() {}
 
 func (x *NoiseHandshakePayload) ProtoReflect() protoreflect.Message {
-	mi := &file_pb_payload_proto_msgTypes[1]
+	mi := &file_p2p_security_noise_pb_payload_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -114,7 +114,7 @@ func (x *NoiseHandshakePayload) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use NoiseHandshakePayload.ProtoReflect.Descriptor instead.
 func (*NoiseHandshakePayload) Descriptor() ([]byte, []int) {
-	return file_pb_payload_proto_rawDescGZIP(), []int{1}
+	return file_p2p_security_noise_pb_payload_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *NoiseHandshakePayload) GetIdentityKey() []byte {
@@ -138,47 +138,52 @@ func (x *NoiseHandshakePayload) GetExtensions() *NoiseExtensions {
 	return nil
 }
 
-var File_pb_payload_proto protoreflect.FileDescriptor
-
-var file_pb_payload_proto_rawDesc = []byte{
-	0x0a, 0x10, 0x70, 0x62, 0x2f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x6f, 0x0a, 0x0f, 0x4e, 0x6f, 0x69, 0x73, 0x65, 0x45,
-	0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x17, 0x77, 0x65, 0x62,
-	0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x68, 0x61,
-	0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x16, 0x77, 0x65, 0x62, 0x74,
-	0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x65, 0x72, 0x74, 0x68, 0x61, 0x73, 0x68,
-	0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x6d, 0x75, 0x78,
-	0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x74, 0x72, 0x65, 0x61,
-	0x6d, 0x4d, 0x75, 0x78, 0x65, 0x72, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x15, 0x4e, 0x6f, 0x69, 0x73,
-	0x65, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
-	0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6b, 0x65,
-	0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
-	0x79, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
-	0x5f, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x64, 0x65, 0x6e,
-	0x74, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x12, 0x33, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e,
-	0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x62,
-	0x2e, 0x4e, 0x6f, 0x69, 0x73, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73,
-	0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73,
+var File_p2p_security_noise_pb_payload_proto protoreflect.FileDescriptor
+
+var file_p2p_security_noise_pb_payload_proto_rawDesc = []byte{
+	0x0a, 0x23, 0x70, 0x32, 0x70, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x6e,
+	0x6f, 0x69, 0x73, 0x65, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x6f, 0x0a, 0x0f, 0x4e, 0x6f, 0x69,
+	0x73, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x17,
+	0x77, 0x65, 0x62, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x65, 0x72,
+	0x74, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x16, 0x77,
+	0x65, 0x62, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x65, 0x72, 0x74, 0x68,
+	0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f,
+	0x6d, 0x75, 0x78, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x74,
+	0x72, 0x65, 0x61, 0x6d, 0x4d, 0x75, 0x78, 0x65, 0x72, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x15, 0x4e,
+	0x6f, 0x69, 0x73, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x79,
+	0x6c, 0x6f, 0x61, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
+	0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x64, 0x65, 0x6e,
+	0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74,
+	0x69, 0x74, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x12, 0x33, 0x0a, 0x0a, 0x65, 0x78,
+	0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,
+	0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x69, 0x73, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
+	0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42,
+	0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69,
+	0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x70,
+	0x32, 0x70, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x6e, 0x6f, 0x69, 0x73,
+	0x65, 0x2f, 0x70, 0x62,
 }
 
 var (
-	file_pb_payload_proto_rawDescOnce sync.Once
-	file_pb_payload_proto_rawDescData = file_pb_payload_proto_rawDesc
+	file_p2p_security_noise_pb_payload_proto_rawDescOnce sync.Once
+	file_p2p_security_noise_pb_payload_proto_rawDescData = file_p2p_security_noise_pb_payload_proto_rawDesc
 )
 
-func file_pb_payload_proto_rawDescGZIP() []byte {
-	file_pb_payload_proto_rawDescOnce.Do(func() {
-		file_pb_payload_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_payload_proto_rawDescData)
+func file_p2p_security_noise_pb_payload_proto_rawDescGZIP() []byte {
+	file_p2p_security_noise_pb_payload_proto_rawDescOnce.Do(func() {
+		file_p2p_security_noise_pb_payload_proto_rawDescData = protoimpl.X.CompressGZIP(file_p2p_security_noise_pb_payload_proto_rawDescData)
 	})
-	return file_pb_payload_proto_rawDescData
+	return file_p2p_security_noise_pb_payload_proto_rawDescData
 }
 
-var file_pb_payload_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
-var file_pb_payload_proto_goTypes = []any{
+var file_p2p_security_noise_pb_payload_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_p2p_security_noise_pb_payload_proto_goTypes = []any{
 	(*NoiseExtensions)(nil),       // 0: pb.NoiseExtensions
 	(*NoiseHandshakePayload)(nil), // 1: pb.NoiseHandshakePayload
 }
-var file_pb_payload_proto_depIdxs = []int32{
+var file_p2p_security_noise_pb_payload_proto_depIdxs = []int32{
 	0, // 0: pb.NoiseHandshakePayload.extensions:type_name -> pb.NoiseExtensions
 	1, // [1:1] is the sub-list for method output_type
 	1, // [1:1] is the sub-list for method input_type
@@ -187,13 +192,13 @@ var file_pb_payload_proto_depIdxs = []int32{
 	0, // [0:1] is the sub-list for field type_name
 }
 
-func init() { file_pb_payload_proto_init() }
-func file_pb_payload_proto_init() {
-	if File_pb_payload_proto != nil {
+func init() { file_p2p_security_noise_pb_payload_proto_init() }
+func file_p2p_security_noise_pb_payload_proto_init() {
+	if File_p2p_security_noise_pb_payload_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_pb_payload_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_p2p_security_noise_pb_payload_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*NoiseExtensions); i {
 			case 0:
 				return &v.state
@@ -205,7 +210,7 @@ func file_pb_payload_proto_init() {
 				return nil
 			}
 		}
-		file_pb_payload_proto_msgTypes[1].Exporter = func(v any, i int) any {
+		file_p2p_security_noise_pb_payload_proto_msgTypes[1].Exporter = func(v any, i int) any {
 			switch v := v.(*NoiseHandshakePayload); i {
 			case 0:
 				return &v.state
@@ -222,18 +227,18 @@ func file_pb_payload_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_pb_payload_proto_rawDesc,
+			RawDescriptor: file_p2p_security_noise_pb_payload_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   2,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_pb_payload_proto_goTypes,
-		DependencyIndexes: file_pb_payload_proto_depIdxs,
-		MessageInfos:      file_pb_payload_proto_msgTypes,
+		GoTypes:           file_p2p_security_noise_pb_payload_proto_goTypes,
+		DependencyIndexes: file_p2p_security_noise_pb_payload_proto_depIdxs,
+		MessageInfos:      file_p2p_security_noise_pb_payload_proto_msgTypes,
 	}.Build()
-	File_pb_payload_proto = out.File
-	file_pb_payload_proto_rawDesc = nil
-	file_pb_payload_proto_goTypes = nil
-	file_pb_payload_proto_depIdxs = nil
+	File_p2p_security_noise_pb_payload_proto = out.File
+	file_p2p_security_noise_pb_payload_proto_rawDesc = nil
+	file_p2p_security_noise_pb_payload_proto_goTypes = nil
+	file_p2p_security_noise_pb_payload_proto_depIdxs = nil
 }
diff --git a/p2p/security/noise/pb/payload.proto b/p2p/security/noise/pb/payload.proto
index ff303b0d..edcacd3b 100644
--- a/p2p/security/noise/pb/payload.proto
+++ b/p2p/security/noise/pb/payload.proto
@@ -1,6 +1,8 @@
 syntax = "proto2";
 package pb;
 
+option go_package = "github.com/libp2p/go-libp2p/p2p/security/noise/pb";
+
 message NoiseExtensions {
 	repeated bytes webtransport_certhashes = 1;
 	repeated string stream_muxers = 2;
diff --git a/p2p/transport/quic/cmd/client/main.go b/p2p/transport/quic/cmd/client/main.go
index 5736d895..e9883d2a 100644
--- a/p2p/transport/quic/cmd/client/main.go
+++ b/p2p/transport/quic/cmd/client/main.go
@@ -14,6 +14,6 @@ func main() {
 		return
 	}
 	if err := cmdlib.RunClient(os.Args[1], os.Args[2]); err != nil {
-		log.Fatalf(err.Error())
+		log.Fatal(err.Error())
 	}
 }
diff --git a/p2p/transport/quic/cmd/server/main.go b/p2p/transport/quic/cmd/server/main.go
index ef3f90a4..c478d34b 100644
--- a/p2p/transport/quic/cmd/server/main.go
+++ b/p2p/transport/quic/cmd/server/main.go
@@ -14,6 +14,6 @@ func main() {
 		return
 	}
 	if err := cmdlib.RunServer(os.Args[1], nil); err != nil {
-		log.Fatalf(err.Error())
+		log.Fatal(err.Error())
 	}
 }
diff --git a/p2p/transport/quic/transport.go b/p2p/transport/quic/transport.go
index 04b5e4d6..f0862d22 100644
--- a/p2p/transport/quic/transport.go
+++ b/p2p/transport/quic/transport.go
@@ -136,6 +136,7 @@ func (t *transport) dialWithScope(ctx context.Context, raddr ma.Multiaddr, p pee
 	}
 
 	tlsConf, keyCh := t.identity.ConfigForPeer(p)
+	ctx = quicreuse.WithAssociation(ctx, t)
 	pconn, err := t.connManager.DialQUIC(ctx, raddr, tlsConf, t.allowWindowIncrease)
 	if err != nil {
 		return nil, err
@@ -196,7 +197,7 @@ func (t *transport) holePunch(ctx context.Context, raddr ma.Multiaddr, p peer.ID
 	if err != nil {
 		return nil, err
 	}
-	tr, err := t.connManager.TransportForDial(network, addr)
+	tr, err := t.connManager.TransportWithAssociationForDial(t, network, addr)
 	if err != nil {
 		return nil, err
 	}
@@ -313,7 +314,7 @@ func (t *transport) Listen(addr ma.Multiaddr) (tpt.Listener, error) {
 			return nil, fmt.Errorf("can't listen on quic version %v, underlying listener doesn't support it", version)
 		}
 	} else {
-		ln, err := t.connManager.ListenQUIC(addr, &tlsConf, t.allowWindowIncrease)
+		ln, err := t.connManager.ListenQUICAndAssociate(t, addr, &tlsConf, t.allowWindowIncrease)
 		if err != nil {
 			return nil, err
 		}
diff --git a/p2p/transport/quicreuse/connmgr.go b/p2p/transport/quicreuse/connmgr.go
index 01e1bcda..8e4c61b0 100644
--- a/p2p/transport/quicreuse/connmgr.go
+++ b/p2p/transport/quicreuse/connmgr.go
@@ -102,6 +102,11 @@ func (c *ConnManager) getReuse(network string) (*reuse, error) {
 }
 
 func (c *ConnManager) ListenQUIC(addr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool) (Listener, error) {
+	return c.ListenQUICAndAssociate(nil, addr, tlsConf, allowWindowIncrease)
+}
+
+// ListenQUICAndAssociate returns a QUIC listener and associates the underlying transport with the given association.
+func (c *ConnManager) ListenQUICAndAssociate(association any, addr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool) (Listener, error) {
 	netw, host, err := manet.DialArgs(addr)
 	if err != nil {
 		return nil, err
@@ -117,7 +122,7 @@ func (c *ConnManager) ListenQUIC(addr ma.Multiaddr, tlsConf *tls.Config, allowWi
 	key := laddr.String()
 	entry, ok := c.quicListeners[key]
 	if !ok {
-		tr, err := c.transportForListen(netw, laddr)
+		tr, err := c.transportForListen(association, netw, laddr)
 		if err != nil {
 			return nil, err
 		}
@@ -176,13 +181,18 @@ func (c *ConnManager) SharedNonQUICPacketConn(network string, laddr *net.UDPAddr
 	return nil, errors.New("expected to be able to share with a QUIC listener, but the QUIC listener is not using a refcountedTransport. `DisableReuseport` should not be set")
 }
 
-func (c *ConnManager) transportForListen(network string, laddr *net.UDPAddr) (refCountedQuicTransport, error) {
+func (c *ConnManager) transportForListen(association any, network string, laddr *net.UDPAddr) (refCountedQuicTransport, error) {
 	if c.enableReuseport {
 		reuse, err := c.getReuse(network)
 		if err != nil {
 			return nil, err
 		}
-		return reuse.TransportForListen(network, laddr)
+		tr, err := reuse.TransportForListen(network, laddr)
+		if err != nil {
+			return nil, err
+		}
+		tr.associate(association)
+		return tr, nil
 	}
 
 	conn, err := net.ListenUDP(network, laddr)
@@ -199,6 +209,14 @@ func (c *ConnManager) transportForListen(network string, laddr *net.UDPAddr) (re
 	}, nil
 }
 
+type associationKey struct{}
+
+// WithAssociation returns a new context with the given association. Used in
+// DialQUIC to prefer a transport that has the given association.
+func WithAssociation(ctx context.Context, association any) context.Context {
+	return context.WithValue(ctx, associationKey{}, association)
+}
+
 func (c *ConnManager) DialQUIC(ctx context.Context, raddr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool) (quic.Connection, error) {
 	naddr, v, err := FromQuicMultiaddr(raddr)
 	if err != nil {
@@ -219,7 +237,12 @@ func (c *ConnManager) DialQUIC(ctx context.Context, raddr ma.Multiaddr, tlsConf
 		return nil, errors.New("unknown QUIC version")
 	}
 
-	tr, err := c.TransportForDial(netw, naddr)
+	var tr refCountedQuicTransport
+	if association := ctx.Value(associationKey{}); association != nil {
+		tr, err = c.TransportWithAssociationForDial(association, netw, naddr)
+	} else {
+		tr, err = c.TransportForDial(netw, naddr)
+	}
 	if err != nil {
 		return nil, err
 	}
@@ -232,12 +255,17 @@ func (c *ConnManager) DialQUIC(ctx context.Context, raddr ma.Multiaddr, tlsConf
 }
 
 func (c *ConnManager) TransportForDial(network string, raddr *net.UDPAddr) (refCountedQuicTransport, error) {
+	return c.TransportWithAssociationForDial(nil, network, raddr)
+}
+
+// TransportWithAssociationForDial returns a QUIC transport for dialing, preferring a transport with the given association.
+func (c *ConnManager) TransportWithAssociationForDial(association any, network string, raddr *net.UDPAddr) (refCountedQuicTransport, error) {
 	if c.enableReuseport {
 		reuse, err := c.getReuse(network)
 		if err != nil {
 			return nil, err
 		}
-		return reuse.TransportForDial(network, raddr)
+		return reuse.transportWithAssociationForDial(association, network, raddr)
 	}
 
 	var laddr *net.UDPAddr
diff --git a/p2p/transport/quicreuse/reuse.go b/p2p/transport/quicreuse/reuse.go
index dc2b33b8..c6fc6113 100644
--- a/p2p/transport/quicreuse/reuse.go
+++ b/p2p/transport/quicreuse/reuse.go
@@ -69,6 +69,36 @@ type refcountedTransport struct {
 	mutex       sync.Mutex
 	refCount    int
 	unusedSince time.Time
+
+	assocations map[any]struct{}
+}
+
+// associate an arbitrary value with this transport.
+// This lets us "tag" the refcountedTransport when listening so we can use it
+// later for dialing. Necessary for holepunching and learning about our own
+// observed listening address.
+func (c *refcountedTransport) associate(a any) {
+	if a == nil {
+		return
+	}
+	c.mutex.Lock()
+	defer c.mutex.Unlock()
+	if c.assocations == nil {
+		c.assocations = make(map[any]struct{})
+	}
+	c.assocations[a] = struct{}{}
+}
+
+// hasAssociation returns true if the transport has the given association.
+// If it is a nil association, it will always return true.
+func (c *refcountedTransport) hasAssociation(a any) bool {
+	if a == nil {
+		return true
+	}
+	c.mutex.Lock()
+	defer c.mutex.Unlock()
+	_, ok := c.assocations[a]
+	return ok
 }
 
 func (c *refcountedTransport) IncreaseCount() {
@@ -204,7 +234,7 @@ func (r *reuse) gc() {
 	}
 }
 
-func (r *reuse) TransportForDial(network string, raddr *net.UDPAddr) (*refcountedTransport, error) {
+func (r *reuse) transportWithAssociationForDial(association any, network string, raddr *net.UDPAddr) (*refcountedTransport, error) {
 	var ip *net.IP
 
 	// Only bother looking up the source address if we actually _have_ non 0.0.0.0 listeners.
@@ -224,7 +254,7 @@ func (r *reuse) TransportForDial(network string, raddr *net.UDPAddr) (*refcounte
 	r.mutex.Lock()
 	defer r.mutex.Unlock()
 
-	tr, err := r.transportForDialLocked(network, ip)
+	tr, err := r.transportForDialLocked(association, network, ip)
 	if err != nil {
 		return nil, err
 	}
@@ -232,21 +262,26 @@ func (r *reuse) TransportForDial(network string, raddr *net.UDPAddr) (*refcounte
 	return tr, nil
 }
 
-func (r *reuse) transportForDialLocked(network string, source *net.IP) (*refcountedTransport, error) {
+func (r *reuse) transportForDialLocked(association any, network string, source *net.IP) (*refcountedTransport, error) {
 	if source != nil {
 		// We already have at least one suitable transport...
 		if trs, ok := r.unicast[source.String()]; ok {
-			// ... we don't care which port we're dialing from. Just use the first.
+			// Prefer a transport that has the given association. We want to
+			// reuse the transport the association used for listening.
 			for _, tr := range trs {
-				return tr, nil
+				if tr.hasAssociation(association) {
+					return tr, nil
+				}
 			}
 		}
 	}
 
 	// Use a transport listening on 0.0.0.0 (or ::).
-	// Again, we don't care about the port number.
+	// Again, prefer a transport that has the given association.
 	for _, tr := range r.globalListeners {
-		return tr, nil
+		if tr.hasAssociation(association) {
+			return tr, nil
+		}
 	}
 
 	// Use a transport we've previously dialed from
diff --git a/p2p/transport/webrtc/listener.go b/p2p/transport/webrtc/listener.go
index 96174f34..d4ba3c05 100644
--- a/p2p/transport/webrtc/listener.go
+++ b/p2p/transport/webrtc/listener.go
@@ -137,8 +137,8 @@ func (l *listener) listen() {
 			}
 
 			select {
-			case <-ctx.Done():
-				log.Warn("could not push connection: ctx done")
+			case <-l.ctx.Done():
+				log.Debug("dropping connection, listener closed")
 				conn.Close()
 			case l.acceptQueue <- conn:
 				// acceptQueue is an unbuffered channel, so this blocks until the connection is accepted.
diff --git a/p2p/transport/webrtc/message.go b/p2p/transport/webrtc/message.go
deleted file mode 100644
index 8b57fc80..00000000
--- a/p2p/transport/webrtc/message.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package libp2pwebrtc
-
-//go:generate protoc --go_out=. --go_opt=Mpb/message.proto=./pb pb/message.proto
diff --git a/p2p/transport/webrtc/pb/generate.go b/p2p/transport/webrtc/pb/generate.go
deleted file mode 100644
index 5785a952..00000000
--- a/p2p/transport/webrtc/pb/generate.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package pb
-
-//go:generate protoc --go_out=. --go_opt=paths=source_relative -I . message.proto
diff --git a/p2p/transport/webrtc/pb/message.pb.go b/p2p/transport/webrtc/pb/message.pb.go
index 44e787cd..d8e68a1a 100644
--- a/p2p/transport/webrtc/pb/message.pb.go
+++ b/p2p/transport/webrtc/pb/message.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.34.2
-// 	protoc        v5.27.2
-// source: message.proto
+// 	protoc        v5.27.3
+// source: p2p/transport/webrtc/pb/message.proto
 
 package pb
 
@@ -64,11 +64,11 @@ func (x Message_Flag) String() string {
 }
 
 func (Message_Flag) Descriptor() protoreflect.EnumDescriptor {
-	return file_message_proto_enumTypes[0].Descriptor()
+	return file_p2p_transport_webrtc_pb_message_proto_enumTypes[0].Descriptor()
 }
 
 func (Message_Flag) Type() protoreflect.EnumType {
-	return &file_message_proto_enumTypes[0]
+	return &file_p2p_transport_webrtc_pb_message_proto_enumTypes[0]
 }
 
 func (x Message_Flag) Number() protoreflect.EnumNumber {
@@ -87,7 +87,7 @@ func (x *Message_Flag) UnmarshalJSON(b []byte) error {
 
 // Deprecated: Use Message_Flag.Descriptor instead.
 func (Message_Flag) EnumDescriptor() ([]byte, []int) {
-	return file_message_proto_rawDescGZIP(), []int{0, 0}
+	return file_p2p_transport_webrtc_pb_message_proto_rawDescGZIP(), []int{0, 0}
 }
 
 type Message struct {
@@ -102,7 +102,7 @@ type Message struct {
 func (x *Message) Reset() {
 	*x = Message{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_message_proto_msgTypes[0]
+		mi := &file_p2p_transport_webrtc_pb_message_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -115,7 +115,7 @@ func (x *Message) String() string {
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	mi := &file_message_proto_msgTypes[0]
+	mi := &file_p2p_transport_webrtc_pb_message_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -128,7 +128,7 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Message.ProtoReflect.Descriptor instead.
 func (*Message) Descriptor() ([]byte, []int) {
-	return file_message_proto_rawDescGZIP(), []int{0}
+	return file_p2p_transport_webrtc_pb_message_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *Message) GetFlag() Message_Flag {
@@ -145,43 +145,45 @@ func (x *Message) GetMessage() []byte {
 	return nil
 }
 
-var File_message_proto protoreflect.FileDescriptor
+var File_p2p_transport_webrtc_pb_message_proto protoreflect.FileDescriptor
 
-var file_message_proto_rawDesc = []byte{
-	0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
-	0x81, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x04, 0x66,
-	0x6c, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x4d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x04, 0x66, 0x6c, 0x61, 0x67, 0x12, 0x18,
-	0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
-	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x39, 0x0a, 0x04, 0x46, 0x6c, 0x61, 0x67,
-	0x12, 0x07, 0x0a, 0x03, 0x46, 0x49, 0x4e, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x4f,
-	0x50, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x52,
-	0x45, 0x53, 0x45, 0x54, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x49, 0x4e, 0x5f, 0x41, 0x43,
-	0x4b, 0x10, 0x03, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
-	0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70,
-	0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74,
-	0x2f, 0x77, 0x65, 0x62, 0x72, 0x74, 0x63, 0x2f, 0x70, 0x62,
+var file_p2p_transport_webrtc_pb_message_proto_rawDesc = []byte{
+	0x0a, 0x25, 0x70, 0x32, 0x70, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f,
+	0x77, 0x65, 0x62, 0x72, 0x74, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x81, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x04, 0x66, 0x6c, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x0d, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x6c, 0x61, 0x67,
+	0x52, 0x04, 0x66, 0x6c, 0x61, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x22, 0x39, 0x0a, 0x04, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x07, 0x0a, 0x03, 0x46, 0x49, 0x4e, 0x10,
+	0x00, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x49, 0x4e,
+	0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x53, 0x45, 0x54, 0x10, 0x02, 0x12, 0x0b,
+	0x0a, 0x07, 0x46, 0x49, 0x4e, 0x5f, 0x41, 0x43, 0x4b, 0x10, 0x03, 0x42, 0x35, 0x5a, 0x33, 0x67,
+	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70,
+	0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x74,
+	0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x77, 0x65, 0x62, 0x72, 0x74, 0x63, 0x2f,
+	0x70, 0x62,
 }
 
 var (
-	file_message_proto_rawDescOnce sync.Once
-	file_message_proto_rawDescData = file_message_proto_rawDesc
+	file_p2p_transport_webrtc_pb_message_proto_rawDescOnce sync.Once
+	file_p2p_transport_webrtc_pb_message_proto_rawDescData = file_p2p_transport_webrtc_pb_message_proto_rawDesc
 )
 
-func file_message_proto_rawDescGZIP() []byte {
-	file_message_proto_rawDescOnce.Do(func() {
-		file_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_message_proto_rawDescData)
+func file_p2p_transport_webrtc_pb_message_proto_rawDescGZIP() []byte {
+	file_p2p_transport_webrtc_pb_message_proto_rawDescOnce.Do(func() {
+		file_p2p_transport_webrtc_pb_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_p2p_transport_webrtc_pb_message_proto_rawDescData)
 	})
-	return file_message_proto_rawDescData
+	return file_p2p_transport_webrtc_pb_message_proto_rawDescData
 }
 
-var file_message_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_message_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
-var file_message_proto_goTypes = []any{
+var file_p2p_transport_webrtc_pb_message_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_p2p_transport_webrtc_pb_message_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_p2p_transport_webrtc_pb_message_proto_goTypes = []any{
 	(Message_Flag)(0), // 0: Message.Flag
 	(*Message)(nil),   // 1: Message
 }
-var file_message_proto_depIdxs = []int32{
+var file_p2p_transport_webrtc_pb_message_proto_depIdxs = []int32{
 	0, // 0: Message.flag:type_name -> Message.Flag
 	1, // [1:1] is the sub-list for method output_type
 	1, // [1:1] is the sub-list for method input_type
@@ -190,13 +192,13 @@ var file_message_proto_depIdxs = []int32{
 	0, // [0:1] is the sub-list for field type_name
 }
 
-func init() { file_message_proto_init() }
-func file_message_proto_init() {
-	if File_message_proto != nil {
+func init() { file_p2p_transport_webrtc_pb_message_proto_init() }
+func file_p2p_transport_webrtc_pb_message_proto_init() {
+	if File_p2p_transport_webrtc_pb_message_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_message_proto_msgTypes[0].Exporter = func(v any, i int) any {
+		file_p2p_transport_webrtc_pb_message_proto_msgTypes[0].Exporter = func(v any, i int) any {
 			switch v := v.(*Message); i {
 			case 0:
 				return &v.state
@@ -213,19 +215,19 @@ func file_message_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_message_proto_rawDesc,
+			RawDescriptor: file_p2p_transport_webrtc_pb_message_proto_rawDesc,
 			NumEnums:      1,
 			NumMessages:   1,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_message_proto_goTypes,
-		DependencyIndexes: file_message_proto_depIdxs,
-		EnumInfos:         file_message_proto_enumTypes,
-		MessageInfos:      file_message_proto_msgTypes,
+		GoTypes:           file_p2p_transport_webrtc_pb_message_proto_goTypes,
+		DependencyIndexes: file_p2p_transport_webrtc_pb_message_proto_depIdxs,
+		EnumInfos:         file_p2p_transport_webrtc_pb_message_proto_enumTypes,
+		MessageInfos:      file_p2p_transport_webrtc_pb_message_proto_msgTypes,
 	}.Build()
-	File_message_proto = out.File
-	file_message_proto_rawDesc = nil
-	file_message_proto_goTypes = nil
-	file_message_proto_depIdxs = nil
+	File_p2p_transport_webrtc_pb_message_proto = out.File
+	file_p2p_transport_webrtc_pb_message_proto_rawDesc = nil
+	file_p2p_transport_webrtc_pb_message_proto_goTypes = nil
+	file_p2p_transport_webrtc_pb_message_proto_depIdxs = nil
 }
diff --git a/p2p/transport/websocket/websocket.go b/p2p/transport/websocket/websocket.go
index 5142ca97..36818dec 100644
--- a/p2p/transport/websocket/websocket.go
+++ b/p2p/transport/websocket/websocket.go
@@ -229,7 +229,11 @@ func (t *WebsocketTransport) maDial(ctx context.Context, raddr ma.Multiaddr) (ma
 }
 
 func (t *WebsocketTransport) maListen(a ma.Multiaddr) (manet.Listener, error) {
-	l, err := newListener(a, t.tlsConf)
+	var tlsConf *tls.Config
+	if t.tlsConf != nil {
+		tlsConf = t.tlsConf.Clone()
+	}
+	l, err := newListener(a, tlsConf)
 	if err != nil {
 		return nil, err
 	}
diff --git a/p2p/transport/webtransport/transport.go b/p2p/transport/webtransport/transport.go
index ef8551d6..acb40f0b 100644
--- a/p2p/transport/webtransport/transport.go
+++ b/p2p/transport/webtransport/transport.go
@@ -207,6 +207,7 @@ func (t *transport) dial(ctx context.Context, addr ma.Multiaddr, url, sni string
 			return verifyRawCerts(rawCerts, certHashes)
 		}
 	}
+	ctx = quicreuse.WithAssociation(ctx, t)
 	conn, err := t.connManager.DialQUIC(ctx, addr, tlsConf, t.allowWindowIncrease)
 	if err != nil {
 		return nil, nil, err
@@ -331,7 +332,7 @@ func (t *transport) Listen(laddr ma.Multiaddr) (tpt.Listener, error) {
 	}
 	tlsConf.NextProtos = append(tlsConf.NextProtos, http3.NextProtoH3)
 
-	ln, err := t.connManager.ListenQUIC(laddr, tlsConf, t.allowWindowIncrease)
+	ln, err := t.connManager.ListenQUICAndAssociate(t, laddr, tlsConf, t.allowWindowIncrease)
 	if err != nil {
 		return nil, err
 	}
diff --git a/scripts/gen-proto.sh b/scripts/gen-proto.sh
new file mode 100755
index 00000000..32c4274e
--- /dev/null
+++ b/scripts/gen-proto.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+set -eou pipefail
+
+root=$1
+
+proto_array=(
+    core/crypto/pb/crypto.proto
+    core/record/pb/envelope.proto
+    core/peer/pb/peer_record.proto
+    core/sec/insecure/pb/plaintext.proto
+    p2p/host/autonat/pb/autonat.proto
+    p2p/security/noise/pb/payload.proto
+    p2p/transport/webrtc/pb/message.proto
+    p2p/protocol/identify/pb/identify.proto
+    p2p/protocol/circuitv2/pb/circuit.proto
+    p2p/protocol/circuitv2/pb/voucher.proto
+    p2p/protocol/autonatv2/pb/autonatv2.proto
+    p2p/protocol/holepunch/pb/holepunch.proto
+    p2p/host/peerstore/pstoreds/pb/pstore.proto
+)
+
+proto_paths=""
+for path in "${proto_array[@]}"; do
+    proto_paths+="$path "
+done
+
+protoc --proto_path=$root --go_out=$root --go_opt=paths=source_relative $proto_paths
diff --git a/version.json b/version.json
index 53072426..844c2c12 100644
--- a/version.json
+++ b/version.json
@@ -1,3 +1,3 @@
 {
-  "version": "v0.36.2"
+  "version": "v0.36.3"
 }


Test patch:
diff --git a/.github/actions/go-test-setup/action.yml b/.github/actions/go-test-setup/action.yml
index c7e4d11a..2667db4c 100644
--- a/.github/actions/go-test-setup/action.yml
+++ b/.github/actions/go-test-setup/action.yml
@@ -9,3 +9,9 @@ runs:
       shell: bash
       # This matches only tests with "NoCover" in their test name to avoid running all tests again.
       run: go test -tags nocover -run NoCover -v ./...
+    - name: Install testing tools
+      shell: bash
+      run: cd scripts/test_analysis && go install ./cmd/gotest2sql
+    - name: Install test_analysis
+      shell: bash
+      run: cd scripts/test_analysis && go install .
diff --git a/.github/workflows/go-test-config.json b/.github/workflows/go-test-config.json
new file mode 100644
index 00000000..699fa72e
--- /dev/null
+++ b/.github/workflows/go-test-config.json
@@ -0,0 +1,3 @@
+{
+    "skip32bit": true
+}
diff --git a/.github/workflows/go-test-template.yml b/.github/workflows/go-test-template.yml
new file mode 100644
index 00000000..fa7c974e
--- /dev/null
+++ b/.github/workflows/go-test-template.yml
@@ -0,0 +1,154 @@
+name: Go Test
+on:
+  workflow_call:
+    inputs:
+      go-versions:
+        required: false
+        type: string
+        default: '["this", "next"]'
+    secrets:
+      CODECOV_TOKEN:
+        required: false
+
+defaults:
+  run:
+    shell: bash
+
+jobs:
+  unit:
+    strategy:
+      fail-fast: false
+      matrix:
+        os: ["ubuntu", "macos", "windows"]
+        go: ${{ fromJSON(inputs.go-versions) }}
+    env:
+      GOTESTFLAGS: -cover -coverprofile=module-coverage.txt -coverpkg=./...
+      GO386FLAGS: ""
+      GORACEFLAGS: ""
+    runs-on: ${{ fromJSON(vars[format('UCI_GO_TEST_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }}
+    name: ${{ matrix.os }} (go ${{ matrix.go }})
+    steps:
+      - name: Use msys2 on windows
+        if: matrix.os == 'windows'
+        # The executable for msys2 is also called bash.cmd
+        #   https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md#shells
+        # If we prepend its location to the PATH
+        #   subsequent 'shell: bash' steps will use msys2 instead of gitbash
+        run: echo "C:/msys64/usr/bin" >> $GITHUB_PATH
+      - name: Check out the repository
+        uses: actions/checkout@v4
+        with:
+          submodules: recursive
+      - name: Check out the latest stable version of Go
+        uses: actions/setup-go@v5
+        with:
+          go-version: stable
+          cache: ${{ matrix.os != 'windows' }} # Windows VMs are slow to use caching. Can add ~15m to the job
+      - name: Read the Unified GitHub Workflows configuration
+        id: config
+        uses: ipdxco/unified-github-workflows/.github/actions/read-config@main
+      - name: Read the go.mod file
+        id: go-mod
+        uses: ipdxco/unified-github-workflows/.github/actions/read-go-mod@main
+      - name: Determine the Go version to use based on the go.mod file
+        id: go
+        env:
+          MATRIX_GO: ${{ matrix.go }}
+          GO_MOD_VERSION: ${{ fromJSON(steps.go-mod.outputs.json).Go }}
+        run: |
+          if [[ "$MATRIX_GO" == "this" ]]; then
+            echo "version=$GO_MOD_VERSION.x" >> $GITHUB_OUTPUT
+          elif [[ "$MATRIX_GO" == "next" ]]; then
+            MAJOR="${GO_MOD_VERSION%.[0-9]*}"
+            MINOR="${GO_MOD_VERSION#[0-9]*.}"
+            echo "version=$MAJOR.$(($MINOR+1)).x" >> $GITHUB_OUTPUT
+          elif [[ "$MATRIX_GO" == "prev" ]]; then
+            MAJOR="${GO_MOD_VERSION%.[0-9]*}"
+            MINOR="${GO_MOD_VERSION#[0-9]*.}"
+            echo "version=$MAJOR.$(($MINOR-1)).x" >> $GITHUB_OUTPUT
+          else
+            echo "version=$MATRIX_GO" >> $GITHUB_OUTPUT
+          fi
+      - name: Enable shuffle flag for go test command
+        if: toJSON(fromJSON(steps.config.outputs.json).shuffle) != 'false'
+        run: |
+          echo "GOTESTFLAGS=-shuffle=on $GOTESTFLAGS" >> $GITHUB_ENV
+          echo "GO386FLAGS=-shuffle=on $GO386FLAGS" >> $GITHUB_ENV
+          echo "GORACEFLAGS=-shuffle=on $GORACEFLAGS" >> $GITHUB_ENV
+      - name: Enable verbose flag for go test command
+        if: toJSON(fromJSON(steps.config.outputs.json).verbose) != 'false'
+        run: |
+          echo "GOTESTFLAGS=-v $GOTESTFLAGS" >> $GITHUB_ENV
+          echo "GO386FLAGS=-v $GO386FLAGS" >> $GITHUB_ENV
+          echo "GORACEFLAGS=-v $GORACEFLAGS" >> $GITHUB_ENV
+      - name: Set extra flags for go test command
+        if: fromJSON(steps.config.outputs.json).gotestflags != ''
+        run: |
+          echo "GOTESTFLAGS=${{ fromJSON(steps.config.outputs.json).gotestflags }} $GOTESTFLAGS" >> $GITHUB_ENV
+      - name: Set extra flags for go test race command
+        if: fromJSON(steps.config.outputs.json).goraceflags != ''
+        run: |
+          echo "GORACEFLAGS=${{ fromJSON(steps.config.outputs.json).goraceflags }} $GORACEFLAGS" >> $GITHUB_ENV
+      - name: Set up the Go version read from the go.mod file
+        uses: actions/setup-go@v5
+        with:
+          go-version: ${{ steps.go.outputs.version }}
+          cache: ${{ matrix.os != 'windows' }} # Windows VMs are slow to use caching. Can add ~15m to the job
+      - name: Display the Go version and environment
+        run: |
+          go version
+          go env
+      - name: Run repo-specific setup
+        uses: ./.github/actions/go-test-setup
+        if: hashFiles('./.github/actions/go-test-setup') != ''
+      - name: Run tests
+        id: test
+        if: contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false
+        uses: protocol/multiple-go-modules@v1.4
+        with:
+          run: test_analysis ${{ env.GOTESTFLAGS }}
+      - name: Upload test results
+        if: always()
+        uses: actions/upload-artifact@v3
+        with:
+          name: ${{ matrix.os }}_${{ matrix.go }}_test_results.db
+          path: ./test_results.db
+      - name: Add failure summary
+        if: always()
+        run: |
+          echo "### Failure Summary" >> $GITHUB_STEP_SUMMARY
+          test_analysis summarize >> $GITHUB_STEP_SUMMARY
+      - name: Remove test results
+        run: rm ./test_results.db
+      - name: Run tests with race detector
+        # speed things up. Windows and OSX VMs are slow
+        if: matrix.os == 'ubuntu' &&
+          fromJSON(steps.config.outputs.json).skipRace != true &&
+          contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false
+        uses: protocol/multiple-go-modules@v1.4
+        id: race
+        with:
+          run: test_analysis -race ${{ env.GORACEFLAGS }} ./...
+      - name: Upload test results (Race)
+        if: (steps.race.conclusion == 'success' || steps.race.conclusion == 'failure')
+        uses: actions/upload-artifact@v3
+        with:
+          name: ${{ matrix.os }}_${{ matrix.go }}_test_results_race.db
+          path: ./test_results.db
+      - name: Add failure summary
+        if: (steps.race.conclusion == 'success' || steps.race.conclusion == 'failure')
+        run: |
+          echo "# Tests with race detector failure summary" >> $GITHUB_STEP_SUMMARY
+          test_analysis summarize >> $GITHUB_STEP_SUMMARY
+      - name: Adding Link to Run Analysis
+        run: echo "### [Test flakiness analysis](https://observablehq.com/d/d74435ea5bbf24c7?run-id=$GITHUB_RUN_ID)" >> $GITHUB_STEP_SUMMARY
+      - name: Collect coverage files
+        id: coverages
+        run: echo "files=$(find . -type f -name 'module-coverage.txt' | tr -s '\n' ',' | sed 's/,$//')" >> $GITHUB_OUTPUT
+      - name: Upload coverage to Codecov
+        uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0
+        with:
+          files: ${{ steps.coverages.outputs.files }}
+          env_vars: OS=${{ matrix.os }}, GO=${{ steps.go.outputs.version }}
+          token: ${{ secrets.CODECOV_TOKEN }}
+          fail_ci_if_error: false
diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml
index e33480c0..66cacd99 100644
--- a/.github/workflows/go-test.yml
+++ b/.github/workflows/go-test.yml
@@ -15,8 +15,8 @@ concurrency:
 
 jobs:
   go-test:
-    uses: libp2p/uci/.github/workflows/go-test.yml@v1.0
+    uses: ./.github/workflows/go-test-template.yml
     with:
-      go-versions: '["1.21.x", "1.22.x"]'
+      go-versions: '["1.22.x", "1.23.x"]'
     secrets:
       CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/libp2p_test.go b/libp2p_test.go
index b479ff2b..a5803add 100644
--- a/libp2p_test.go
+++ b/libp2p_test.go
@@ -5,6 +5,9 @@ import (
 	"crypto/rand"
 	"errors"
 	"fmt"
+	"io"
+	"net"
+	"net/netip"
 	"regexp"
 	"strconv"
 	"strings"
@@ -488,10 +491,23 @@ func TestHostAddrsFactoryAddsCerthashes(t *testing.T) {
 	h.Close()
 }
 
+func newRandomPort(t *testing.T) string {
+	t.Helper()
+	// Find an available port
+	c, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})
+	require.NoError(t, err)
+	c.LocalAddr().Network()
+	ipPort := netip.MustParseAddrPort(c.LocalAddr().String())
+	port := strconv.Itoa(int(ipPort.Port()))
+	require.NoError(t, c.Close())
+	return port
+}
+
 func TestWebRTCReuseAddrWithQUIC(t *testing.T) {
+	port := newRandomPort(t)
 	order := [][]string{
-		{"/ip4/127.0.0.1/udp/54322/quic-v1", "/ip4/127.0.0.1/udp/54322/webrtc-direct"},
-		{"/ip4/127.0.0.1/udp/54322/webrtc-direct", "/ip4/127.0.0.1/udp/54322/quic-v1"},
+		{"/ip4/127.0.0.1/udp/" + port + "/quic-v1", "/ip4/127.0.0.1/udp/" + port + "/webrtc-direct"},
+		{"/ip4/127.0.0.1/udp/" + port + "/webrtc-direct", "/ip4/127.0.0.1/udp/" + port + "/quic-v1"},
 		// We do not support WebRTC automatically reusing QUIC addresses if port is not specified, yet.
 		// {"/ip4/127.0.0.1/udp/0/webrtc-direct", "/ip4/127.0.0.1/udp/0/quic-v1"},
 	}
@@ -542,16 +558,18 @@ func TestWebRTCReuseAddrWithQUIC(t *testing.T) {
 		})
 	}
 
-	swapPort := func(addrStrs []string, newPort string) []string {
+	swapPort := func(addrStrs []string, oldPort, newPort string) []string {
 		out := make([]string, 0, len(addrStrs))
 		for _, addrStr := range addrStrs {
-			out = append(out, strings.Replace(addrStr, "54322", newPort, 1))
+			out = append(out, strings.Replace(addrStr, oldPort, newPort, 1))
 		}
 		return out
 	}
 
 	t.Run("setup with no reuseport. Should fail", func(t *testing.T) {
-		h1, err := New(ListenAddrStrings(swapPort(order[0], "54323")...), Transport(quic.NewTransport), Transport(libp2pwebrtc.New), QUICReuse(quicreuse.NewConnManager, quicreuse.DisableReuseport()))
+		oldPort := port
+		newPort := newRandomPort(t)
+		h1, err := New(ListenAddrStrings(swapPort(order[0], oldPort, newPort)...), Transport(quic.NewTransport), Transport(libp2pwebrtc.New), QUICReuse(quicreuse.NewConnManager, quicreuse.DisableReuseport()))
 		require.NoError(t, err) // It's a bug/feature that swarm.Listen does not error if at least one transport succeeds in listening.
 		defer h1.Close()
 		// Check that webrtc did fail to listen
@@ -560,7 +578,9 @@ func TestWebRTCReuseAddrWithQUIC(t *testing.T) {
 	})
 
 	t.Run("setup with autonat", func(t *testing.T) {
-		h1, err := New(EnableAutoNATv2(), ListenAddrStrings(swapPort(order[0], "54324")...), Transport(quic.NewTransport), Transport(libp2pwebrtc.New), QUICReuse(quicreuse.NewConnManager, quicreuse.DisableReuseport()))
+		oldPort := port
+		newPort := newRandomPort(t)
+		h1, err := New(EnableAutoNATv2(), ListenAddrStrings(swapPort(order[0], oldPort, newPort)...), Transport(quic.NewTransport), Transport(libp2pwebrtc.New), QUICReuse(quicreuse.NewConnManager, quicreuse.DisableReuseport()))
 		require.NoError(t, err) // It's a bug/feature that swarm.Listen does not error if at least one transport succeeds in listening.
 		defer h1.Close()
 		// Check that webrtc did fail to listen
@@ -568,3 +588,70 @@ func TestWebRTCReuseAddrWithQUIC(t *testing.T) {
 		require.Contains(t, h1.Addrs()[0].String(), "quic-v1")
 	})
 }
+
+func TestUseCorrectTransportForDialOut(t *testing.T) {
+	listAddrOrder := [][]string{
+		{"/ip4/127.0.0.1/udp/0/quic-v1", "/ip4/127.0.0.1/udp/0/quic-v1/webtransport"},
+		{"/ip4/127.0.0.1/udp/0/quic-v1/webtransport", "/ip4/127.0.0.1/udp/0/quic-v1"},
+		{"/ip4/0.0.0.0/udp/0/quic-v1", "/ip4/0.0.0.0/udp/0/quic-v1/webtransport"},
+		{"/ip4/0.0.0.0/udp/0/quic-v1/webtransport", "/ip4/0.0.0.0/udp/0/quic-v1"},
+	}
+	for _, order := range listAddrOrder {
+		h1, err := New(ListenAddrStrings(order...), Transport(quic.NewTransport), Transport(webtransport.New))
+		require.NoError(t, err)
+		t.Cleanup(func() {
+			h1.Close()
+		})
+
+		go func() {
+			h1.SetStreamHandler("/echo-port", func(s network.Stream) {
+				m := s.Conn().RemoteMultiaddr()
+				v, err := m.ValueForProtocol(ma.P_UDP)
+				if err != nil {
+					s.Reset()
+					return
+				}
+				s.Write([]byte(v))
+				s.Close()
+			})
+		}()
+
+		for _, addr := range h1.Addrs() {
+			t.Run("order "+strings.Join(order, ",")+" Dial to "+addr.String(), func(t *testing.T) {
+				h2, err := New(ListenAddrStrings(
+					"/ip4/0.0.0.0/udp/0/quic-v1",
+					"/ip4/0.0.0.0/udp/0/quic-v1/webtransport",
+				), Transport(quic.NewTransport), Transport(webtransport.New))
+				require.NoError(t, err)
+				defer h2.Close()
+				t.Log("H2 Addrs", h2.Addrs())
+				var myExpectedDialOutAddr ma.Multiaddr
+				addrIsWT, _ := webtransport.IsWebtransportMultiaddr(addr)
+				isLocal := func(a ma.Multiaddr) bool {
+					return strings.Contains(a.String(), "127.0.0.1")
+				}
+				addrIsLocal := isLocal(addr)
+				for _, a := range h2.Addrs() {
+					aIsWT, _ := webtransport.IsWebtransportMultiaddr(a)
+					if addrIsWT == aIsWT && isLocal(a) == addrIsLocal {
+						myExpectedDialOutAddr = a
+						break
+					}
+				}
+
+				err = h2.Connect(context.Background(), peer.AddrInfo{ID: h1.ID(), Addrs: []ma.Multiaddr{addr}})
+				require.NoError(t, err)
+
+				s, err := h2.NewStream(context.Background(), h1.ID(), "/echo-port")
+				require.NoError(t, err)
+
+				port, err := io.ReadAll(s)
+				require.NoError(t, err)
+
+				myExpectedPort, err := myExpectedDialOutAddr.ValueForProtocol(ma.P_UDP)
+				require.NoError(t, err)
+				require.Equal(t, myExpectedPort, string(port))
+			})
+		}
+	}
+}
diff --git a/p2p/net/nat/nat_test.go b/p2p/net/nat/nat_test.go
index 50e1eb3a..772c876c 100644
--- a/p2p/net/nat/nat_test.go
+++ b/p2p/net/nat/nat_test.go
@@ -45,7 +45,8 @@ func TestAddMapping(t *testing.T) {
 	require.False(t, found, "didn't expect a port mapping for unmapped protocol")
 	mapped, found := nat.GetMapping("tcp", 10000)
 	require.True(t, found, "expected port mapping")
-	require.Equal(t, netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 1234), mapped)
+	addr, _ := netip.AddrFromSlice(net.IPv4(1, 2, 3, 4))
+	require.Equal(t, netip.AddrPortFrom(addr, 1234), mapped)
 }
 
 func TestRemoveMapping(t *testing.T) {
diff --git a/p2p/protocol/identify/id_test.go b/p2p/protocol/identify/id_test.go
index 904e47ce..06ea0119 100644
--- a/p2p/protocol/identify/id_test.go
+++ b/p2p/protocol/identify/id_test.go
@@ -960,7 +960,7 @@ func waitForAddrInStream(t *testing.T, s <-chan ma.Multiaddr, expected ma.Multia
 			}
 			continue
 		case <-time.After(timeout):
-			t.Fatalf(failMsg)
+			t.Fatal(failMsg)
 		}
 	}
 }
diff --git a/p2p/transport/quicreuse/connmgr_test.go b/p2p/transport/quicreuse/connmgr_test.go
index f3576a39..8e7da2cd 100644
--- a/p2p/transport/quicreuse/connmgr_test.go
+++ b/p2p/transport/quicreuse/connmgr_test.go
@@ -61,8 +61,6 @@ func testListenOnSameProto(t *testing.T, enableReuseport bool) {
 
 	const alpn = "proto"
 
-	var tlsConf tls.Config
-	tlsConf.NextProtos = []string{alpn}
 	ln1, err := cm.ListenQUIC(ma.StringCast("/ip4/127.0.0.1/udp/0/quic-v1"), &tls.Config{NextProtos: []string{alpn}}, nil)
 	require.NoError(t, err)
 	defer ln1.Close()
@@ -96,7 +94,7 @@ func TestConnectionPassedToQUICForListening(t *testing.T) {
 
 	_, err = cm.ListenQUIC(raddr, &tls.Config{NextProtos: []string{"proto"}}, nil)
 	require.NoError(t, err)
-	quicTr, err := cm.transportForListen(netw, naddr)
+	quicTr, err := cm.transportForListen(nil, netw, naddr)
 	require.NoError(t, err)
 	defer quicTr.Close()
 	if _, ok := quicTr.(*singleOwnerTransport).Transport.Conn.(quic.OOBCapablePacketConn); !ok {
diff --git a/p2p/transport/quicreuse/reuse_test.go b/p2p/transport/quicreuse/reuse_test.go
index b4630947..1da32b5e 100644
--- a/p2p/transport/quicreuse/reuse_test.go
+++ b/p2p/transport/quicreuse/reuse_test.go
@@ -91,7 +91,7 @@ func TestReuseCreateNewGlobalConnOnDial(t *testing.T) {
 
 	addr, err := net.ResolveUDPAddr("udp4", "1.1.1.1:1234")
 	require.NoError(t, err)
-	conn, err := reuse.TransportForDial("udp4", addr)
+	conn, err := reuse.transportWithAssociationForDial(nil, "udp4", addr)
 	require.NoError(t, err)
 	require.Equal(t, 1, conn.GetCount())
 	laddr := conn.LocalAddr().(*net.UDPAddr)
@@ -111,7 +111,7 @@ func TestReuseConnectionWhenDialing(t *testing.T) {
 	// dial
 	raddr, err := net.ResolveUDPAddr("udp4", "1.1.1.1:1234")
 	require.NoError(t, err)
-	conn, err := reuse.TransportForDial("udp4", raddr)
+	conn, err := reuse.transportWithAssociationForDial(nil, "udp4", raddr)
 	require.NoError(t, err)
 	require.Equal(t, 2, conn.GetCount())
 }
@@ -122,7 +122,7 @@ func TestReuseConnectionWhenListening(t *testing.T) {
 
 	raddr, err := net.ResolveUDPAddr("udp4", "1.1.1.1:1234")
 	require.NoError(t, err)
-	tr, err := reuse.TransportForDial("udp4", raddr)
+	tr, err := reuse.transportWithAssociationForDial(nil, "udp4", raddr)
 	require.NoError(t, err)
 	laddr := &net.UDPAddr{IP: net.IPv4zero, Port: tr.LocalAddr().(*net.UDPAddr).Port}
 	lconn, err := reuse.TransportForListen("udp4", laddr)
@@ -138,7 +138,7 @@ func TestReuseConnectionWhenDialBeforeListen(t *testing.T) {
 	// dial any address
 	raddr, err := net.ResolveUDPAddr("udp4", "1.1.1.1:1234")
 	require.NoError(t, err)
-	rTr, err := reuse.TransportForDial("udp4", raddr)
+	rTr, err := reuse.transportWithAssociationForDial(nil, "udp4", raddr)
 	require.NoError(t, err)
 
 	// open a listener
@@ -149,7 +149,7 @@ func TestReuseConnectionWhenDialBeforeListen(t *testing.T) {
 	// new dials should go via the listener connection
 	raddr, err = net.ResolveUDPAddr("udp4", "1.1.1.1:1235")
 	require.NoError(t, err)
-	tr, err := reuse.TransportForDial("udp4", raddr)
+	tr, err := reuse.transportWithAssociationForDial(nil, "udp4", raddr)
 	require.NoError(t, err)
 	require.Equal(t, lTr, tr)
 	require.Equal(t, 2, tr.GetCount())
@@ -183,7 +183,7 @@ func TestReuseListenOnSpecificInterface(t *testing.T) {
 	require.NoError(t, err)
 	require.Equal(t, 1, lconn.GetCount())
 	// dial
-	conn, err := reuse.TransportForDial("udp4", raddr)
+	conn, err := reuse.transportWithAssociationForDial(nil, "udp4", raddr)
 	require.NoError(t, err)
 	require.Equal(t, 1, conn.GetCount())
 }
@@ -214,7 +214,7 @@ func TestReuseGarbageCollect(t *testing.T) {
 
 	raddr, err := net.ResolveUDPAddr("udp4", "1.2.3.4:1234")
 	require.NoError(t, err)
-	dTr, err := reuse.TransportForDial("udp4", raddr)
+	dTr, err := reuse.transportWithAssociationForDial(nil, "udp4", raddr)
 	require.NoError(t, err)
 	require.Equal(t, 1, dTr.GetCount())
 
diff --git a/p2p/transport/webrtc/transport_test.go b/p2p/transport/webrtc/transport_test.go
index d603d610..b2c06d33 100644
--- a/p2p/transport/webrtc/transport_test.go
+++ b/p2p/transport/webrtc/transport_test.go
@@ -1014,13 +1014,16 @@ func TestConnectionClosedWhenRemoteCloses(t *testing.T) {
 	listenT, p := getTransport(t)
 	listener, err := listenT.Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/webrtc-direct"))
 	require.NoError(t, err)
+	defer listener.Close()
 
+	accepted := make(chan struct{})
 	dialer, _ := getTransport(t)
 	var wg sync.WaitGroup
 	wg.Add(1)
 	go func() {
 		defer wg.Done()
 		c, err := listener.Accept()
+		close(accepted)
 		if !assert.NoError(t, err) {
 			return
 		}
@@ -1031,6 +1034,7 @@ func TestConnectionClosedWhenRemoteCloses(t *testing.T) {
 
 	c, err := dialer.Dial(context.Background(), listener.Multiaddr(), p)
 	require.NoError(t, err)
+	<-accepted
 	c.Close()
 	wg.Wait()
 }
diff --git a/proto_test.go b/proto_test.go
new file mode 100644
index 00000000..4c81749b
--- /dev/null
+++ b/proto_test.go
@@ -0,0 +1,38 @@
+package libp2p_test
+
+import (
+	"testing"
+
+	// Import all protobuf packages to ensure their `init` functions run.
+	// This may not be strictly necessary if they are imported in the `libp2p` package, but
+	// we do it here in case the imports in non-test files change.
+	_ "github.com/libp2p/go-libp2p/core/crypto/pb"
+	_ "github.com/libp2p/go-libp2p/core/peer/pb"
+	_ "github.com/libp2p/go-libp2p/core/record/pb"
+	_ "github.com/libp2p/go-libp2p/core/sec/insecure/pb"
+	_ "github.com/libp2p/go-libp2p/p2p/host/autonat/pb"
+	_ "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds/pb"
+	_ "github.com/libp2p/go-libp2p/p2p/protocol/autonatv2/pb"
+	_ "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb"
+	_ "github.com/libp2p/go-libp2p/p2p/protocol/holepunch/pb"
+	_ "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb"
+	_ "github.com/libp2p/go-libp2p/p2p/security/noise/pb"
+	_ "github.com/libp2p/go-libp2p/p2p/transport/webrtc/pb"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+//go:generate scripts/gen-proto.sh .
+
+func TestProtoImportsAndPathsAreConsistent(t *testing.T) {
+	protoregistry.GlobalFiles.RangeFiles(func(fd protoreflect.FileDescriptor) bool {
+		imports := fd.Imports()
+		for i := 0; i < imports.Len(); i++ {
+			path := imports.Get(i).Path()
+			if _, err := protoregistry.GlobalFiles.FindFileByPath(path); err != nil {
+				t.Fatalf("find dependency %s: %v", path, err)
+			}
+		}
+		return true
+	})
+}
diff --git a/scripts/test_analysis/cmd/gotest2sql/main.go b/scripts/test_analysis/cmd/gotest2sql/main.go
new file mode 100644
index 00000000..05a247e2
--- /dev/null
+++ b/scripts/test_analysis/cmd/gotest2sql/main.go
@@ -0,0 +1,100 @@
+// gotest2sql inserts the output of go test -json ./... into a sqlite database
+package main
+
+import (
+	"bufio"
+	"database/sql"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"log"
+	"os"
+	"time"
+
+	_ "github.com/glebarez/go-sqlite"
+)
+
+type TestEvent struct {
+	Time    time.Time // encodes as an RFC3339-format string
+	Action  string
+	Package string
+	Test    string
+	Elapsed float64 // seconds
+	Output  string
+}
+
+func main() {
+	outputPath := flag.String("output", "", "output db file")
+	verbose := flag.Bool("v", false, "Print test output to stdout")
+	flag.Parse()
+
+	if *outputPath == "" {
+		log.Fatal("-output path is required")
+	}
+
+	db, err := sql.Open("sqlite", *outputPath)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Create a table to store test results.
+	_, err = db.Exec(`
+		CREATE TABLE IF NOT EXISTS test_results (
+			Time TEXT,
+			Action TEXT,
+			Package TEXT,
+			Test TEXT,
+			Elapsed REAL,
+			Output TEXT,
+			BatchInsertTime TEXT
+	)`)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	tx, err := db.Begin()
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Prepare the insert statement once
+	insertTime := time.Now().Format(time.RFC3339Nano)
+	stmt, err := tx.Prepare(`
+    INSERT INTO test_results (Time, Action, Package, Test, Elapsed, Output, BatchInsertTime)
+    VALUES (?, ?, ?, ?, ?, ?, ?)`)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer stmt.Close() // Ensure the statement is closed after use
+
+	s := bufio.NewScanner(os.Stdin)
+	for s.Scan() {
+		line := s.Bytes()
+		var ev TestEvent
+		err = json.Unmarshal(line, &ev)
+		if err != nil {
+			log.Fatal(err)
+		}
+		if *verbose && ev.Action == "output" {
+			fmt.Print(ev.Output)
+		}
+
+		_, err = stmt.Exec(
+			ev.Time.Format(time.RFC3339Nano),
+			ev.Action,
+			ev.Package,
+			ev.Test,
+			ev.Elapsed,
+			ev.Output,
+			insertTime,
+		)
+		if err != nil {
+			log.Fatal(err)
+		}
+	}
+
+	// Commit the transaction
+	if err := tx.Commit(); err != nil {
+		log.Fatal(err)
+	}
+}
diff --git a/scripts/test_analysis/go.mod b/scripts/test_analysis/go.mod
new file mode 100644
index 00000000..84ffc92b
--- /dev/null
+++ b/scripts/test_analysis/go.mod
@@ -0,0 +1,17 @@
+module github.com/libp2p/go-libp2p/scripts/test_analysis
+
+go 1.22
+
+require github.com/glebarez/go-sqlite v1.22.0
+
+require (
+	github.com/dustin/go-humanize v1.0.1 // indirect
+	github.com/google/uuid v1.5.0 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
+	golang.org/x/sys v0.15.0 // indirect
+	modernc.org/libc v1.37.6 // indirect
+	modernc.org/mathutil v1.6.0 // indirect
+	modernc.org/memory v1.7.2 // indirect
+	modernc.org/sqlite v1.28.0 // indirect
+)
diff --git a/scripts/test_analysis/go.sum b/scripts/test_analysis/go.sum
new file mode 100644
index 00000000..e635754c
--- /dev/null
+++ b/scripts/test_analysis/go.sum
@@ -0,0 +1,23 @@
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
+github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
+github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
+github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
+github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
+github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw=
+modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE=
+modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
+modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
+modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
+modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
+modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ=
+modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0=
diff --git a/scripts/test_analysis/main.go b/scripts/test_analysis/main.go
new file mode 100644
index 00000000..e96a09cd
--- /dev/null
+++ b/scripts/test_analysis/main.go
@@ -0,0 +1,311 @@
+package main
+
+import (
+	"context"
+	"database/sql"
+	"errors"
+	"fmt"
+	"log"
+	"os"
+	"os/exec"
+	"regexp"
+	"strings"
+
+	_ "github.com/glebarez/go-sqlite"
+)
+
+const dbPath = "./test_results.db"
+const retryCount = 4 // For a total of 5 runs
+
+var coverRegex = regexp.MustCompile(`-cover`)
+
+func main() {
+	var t tester
+	if len(os.Args) >= 2 {
+		if os.Args[1] == "summarize" {
+			md, err := t.summarize()
+			if err != nil {
+				log.Fatal(err)
+			}
+			fmt.Print(md)
+			return
+		}
+	}
+
+	passThruFlags := os.Args[1:]
+	err := t.runTests(passThruFlags)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+type tester struct {
+	Dir string
+}
+
+func (t *tester) runTests(passThruFlags []string) error {
+	err := t.goTestAll(passThruFlags)
+	if err == nil {
+		// No failed tests, nothing to do
+		return nil
+	}
+	log.Printf("Not all tests passed: %v", err)
+
+	timedOutPackages, err := t.findTimedoutTests(context.Background())
+	if err != nil {
+		return err
+	}
+	if len(timedOutPackages) > 0 {
+		// Fail immediately if we find any timeouts. We'd have to run all tests
+		// in the package, and this could take a long time.
+		log.Printf("Found %d timed out packages. Failing", len(timedOutPackages))
+		return errors.New("one or more tests timed out")
+	}
+
+	failedTests, err := t.findFailedTests(context.Background())
+	if err != nil {
+		return err
+	}
+
+	log.Printf("Found %d failed tests. Retrying them %d times", len(failedTests), retryCount)
+	hasOneNonFlakyFailure := false
+	loggedFlaky := map[string]struct{}{}
+
+	for _, ft := range failedTests {
+		isFlaky := false
+		for i := 0; i < retryCount; i++ {
+			log.Printf("Retrying %s.%s", ft.Package, ft.Test)
+			if err := t.goTestPkgTest(ft.Package, ft.Test, filterOutFlags(passThruFlags, coverRegex)); err != nil {
+				log.Printf("Failed to run %s.%s: %v", ft.Package, ft.Test, err)
+			} else {
+				isFlaky = true
+				flakyName := ft.Package + "." + ft.Test
+				if _, ok := loggedFlaky[flakyName]; !ok {
+					loggedFlaky[flakyName] = struct{}{}
+					log.Printf("Test %s.%s is flaky.", ft.Package, ft.Test)
+				}
+			}
+		}
+		if !isFlaky {
+			hasOneNonFlakyFailure = true
+		}
+	}
+
+	// A test consistently failed, so we should exit with a non-zero exit code.
+	if hasOneNonFlakyFailure {
+		return errors.New("one or more tests consistently failed")
+	}
+	return nil
+}
+
+func (t *tester) goTestAll(extraFlags []string) error {
+	flags := []string{"./..."}
+	flags = append(flags, extraFlags...)
+	return t.goTest(flags)
+}
+
+func (t *tester) goTestPkgTest(pkg, testname string, extraFlags []string) error {
+	flags := []string{
+		pkg, "-run", "^" + testname + "$", "-count", "1",
+	}
+	flags = append(flags, extraFlags...)
+	return t.goTest(flags)
+}
+
+func (t *tester) goTest(extraFlags []string) error {
+	flags := []string{
+		"test", "-json",
+	}
+	flags = append(flags, extraFlags...)
+	cmd := exec.Command("go", flags...)
+	cmd.Dir = t.Dir
+	cmd.Stderr = os.Stderr
+
+	gotest2sql := exec.Command("gotest2sql", "-v", "-output", dbPath)
+	gotest2sql.Dir = t.Dir
+	gotest2sql.Stdin, _ = cmd.StdoutPipe()
+	gotest2sql.Stdout = os.Stdout
+	gotest2sql.Stderr = os.Stderr
+	err := gotest2sql.Start()
+	if err != nil {
+		return err
+	}
+
+	err = cmd.Run()
+	return errors.Join(err, gotest2sql.Wait())
+}
+
+type failedTest struct {
+	Package string
+	Test    string
+}
+
+type timedOutPackage struct {
+	Package string
+	Outputs string
+}
+
+func (t *tester) findFailedTests(ctx context.Context) ([]failedTest, error) {
+	db, err := sql.Open("sqlite", t.Dir+dbPath)
+	if err != nil {
+		return nil, err
+	}
+	defer db.Close()
+
+	rows, err := db.QueryContext(ctx, "SELECT DISTINCT Package, Test FROM test_results where Action='fail' and Test != ''")
+	if err != nil {
+		return nil, err
+	}
+	var out []failedTest
+	for rows.Next() {
+		var pkg, test string
+		if err := rows.Scan(&pkg, &test); err != nil {
+			return nil, err
+		}
+		out = append(out, failedTest{pkg, test})
+	}
+	return out, nil
+}
+
+func (t *tester) findTimedoutTests(ctx context.Context) ([]timedOutPackage, error) {
+	db, err := sql.Open("sqlite", t.Dir+dbPath)
+	if err != nil {
+		return nil, err
+	}
+	defer db.Close()
+
+	rows, err := db.QueryContext(ctx, `WITH failed_packages AS (
+    SELECT
+        Package
+    FROM
+        test_results
+    WHERE
+        Action = 'fail'
+        AND Elapsed > 300
+)
+SELECT
+	test_results.Package, GROUP_CONCAT(Output, "") as Outputs
+FROM
+    test_results
+INNER JOIN
+    failed_packages
+ON
+    test_results.Package = failed_packages.Package
+GROUP BY
+    test_results.Package
+HAVING
+    Outputs LIKE '%timed out%'
+ORDER BY Time;`)
+	if err != nil {
+		return nil, err
+	}
+	var out []timedOutPackage
+	for rows.Next() {
+		var pkg, outputs string
+		if err := rows.Scan(&pkg, &outputs); err != nil {
+			return nil, err
+		}
+		out = append(out, timedOutPackage{pkg, outputs})
+	}
+	return out, nil
+}
+
+func filterOutFlags(flags []string, exclude *regexp.Regexp) []string {
+	out := make([]string, 0, len(flags))
+	for _, f := range flags {
+		if !exclude.MatchString(f) {
+			out = append(out, f)
+		}
+	}
+	return out
+}
+
+// summarize returns a markdown string of the test results.
+func (t *tester) summarize() (string, error) {
+	ctx := context.Background()
+	var out strings.Builder
+
+	testFailures, err := t.findFailedTests(ctx)
+	if err != nil {
+		return "", err
+	}
+	timeouts, err := t.findTimedoutTests(ctx)
+	if err != nil {
+		return "", err
+	}
+
+	testFailureCount := len(testFailures) + len(timeouts)
+
+	plural := "s"
+	if testFailureCount == 1 {
+		plural = ""
+	}
+	out.WriteString(fmt.Sprintf("## %d Test Failure%s\n\n", testFailureCount, plural))
+
+	if len(timeouts) > 0 {
+		out.WriteString("### Timed Out Tests\n\n")
+		for _, timeout := range timeouts {
+			_, err = out.WriteString(fmt.Sprintf(`<details>
+<summary>%s</summary>
+<pre>
+%s
+</pre>
+</details>`, timeout.Package, timeout.Outputs))
+			if err != nil {
+				return "", err
+			}
+		}
+		out.WriteString("\n")
+	}
+
+	if len(testFailures) > 0 {
+		out.WriteString("### Failed Tests\n\n")
+
+		db, err := sql.Open("sqlite", t.Dir+dbPath)
+		if err != nil {
+			return "", err
+		}
+		defer db.Close()
+
+		rows, err := db.QueryContext(ctx, `SELECT
+    tr_output.Package,
+    tr_output.Test,
+    GROUP_CONCAT(tr_output.Output,  "") AS Outputs
+FROM
+    test_results tr_fail
+JOIN
+    test_results tr_output
+ON
+    tr_fail.Test = tr_output.Test
+    AND tr_fail.BatchInsertTime = tr_output.BatchInsertTime
+    AND tr_fail.Package = tr_output.Package
+WHERE
+    tr_fail.Action = 'fail'
+    AND tr_output.Test != ''
+GROUP BY
+    tr_output.BatchInsertTime,
+    tr_output.Package,
+    tr_output.Test
+ORDER BY
+    MIN(tr_output.Time);`)
+		if err != nil {
+			return "", err
+		}
+		for rows.Next() {
+			var pkg, test, outputs string
+			if err := rows.Scan(&pkg, &test, &outputs); err != nil {
+				return "", err
+			}
+			_, err = out.WriteString(fmt.Sprintf(`<details>
+<summary>%s.%s</summary>
+<pre>
+%s
+</pre>
+</details>`, pkg, test, outputs))
+			if err != nil {
+				return "", err
+			}
+		}
+	}
+	return out.String(), nil
+}
diff --git a/scripts/test_analysis/main_test.go b/scripts/test_analysis/main_test.go
new file mode 100644
index 00000000..b8a5dae1
--- /dev/null
+++ b/scripts/test_analysis/main_test.go
@@ -0,0 +1,56 @@
+package main
+
+import (
+	"os"
+	"testing"
+)
+
+func TestFailsOnConsistentFailure(t *testing.T) {
+	tmpDir := t.TempDir() + "/"
+	os.WriteFile(tmpDir+"/main.go", []byte(`package main
+func main() {}`), 0644)
+	// Add a test that fails consistently.
+	os.WriteFile(tmpDir+"/main_test.go", []byte(`package main
+
+import (
+	"testing"
+)
+func TestConsistentFailure(t *testing.T) {
+	t.Fatal("consistent failure")
+}`), 0644)
+	os.WriteFile(tmpDir+"/go.mod", []byte(`module example.com/test`), 0644)
+
+	tstr := tester{Dir: tmpDir}
+	err := tstr.runTests(nil)
+	if err == nil {
+		t.Fatal("Should have failed with a consistent failure")
+	}
+}
+
+func TestPassesOnFlakyFailure(t *testing.T) {
+	tmpDir := t.TempDir() + "/"
+	os.WriteFile(tmpDir+"/main.go", []byte(`package main
+func main() {
+}`), 0644)
+	// Add a test that fails the first time.
+	os.WriteFile(tmpDir+"/main_test.go", []byte(`package main
+import (
+	"os"
+	"testing"
+)
+func TestFlakyFailure(t *testing.T) {
+	_, err := os.Stat("foo")
+	if err != nil {
+		os.WriteFile("foo", []byte("hello"), 0644)
+		t.Fatal("flaky failure")
+	}
+}`), 0644)
+	os.WriteFile(tmpDir+"/go.mod", []byte(`module example.com/test`), 0644)
+
+	// Run the test.
+	tstr := tester{Dir: tmpDir}
+	err := tstr.runTests(nil)
+	if err != nil {
+		t.Fatal("Should have passed with a flaky test")
+	}
+}
diff --git a/test-plans/PingDockerfile b/test-plans/PingDockerfile
index 5c413aa4..4c5ffe9c 100644
--- a/test-plans/PingDockerfile
+++ b/test-plans/PingDockerfile
@@ -1,7 +1,7 @@
 # syntax=docker/dockerfile:1
 # This is run from the parent directory to copy the whole go-libp2p codebase
 
-FROM golang:1.21-alpine AS builder
+FROM golang:1.23-alpine AS builder
 
 WORKDIR /app/
 
diff --git a/test-plans/go.mod b/test-plans/go.mod
index e963be7b..466a55e9 100644
--- a/test-plans/go.mod
+++ b/test-plans/go.mod
@@ -1,6 +1,6 @@
 module github.com/libp2p/go-libp2p/test-plans/m/v2
 
-go 1.21
+go 1.22
 
 require (
 	github.com/go-redis/redis/v8 v8.11.5