Replace protobuf crate with prost! (#1390)

* Replace protobuf crate with prost!

* Add copyright headers to build.rs files.

* kad: Fix error when mapping connection types.

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Fix more mapping mistakes.

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
This commit is contained in:
Toralf Wittner
2020-01-15 12:02:02 +01:00
committed by Pierre Krieger
parent 9d2df148cd
commit 680c467f7e
52 changed files with 600 additions and 5836 deletions

View File

@ -24,7 +24,7 @@ multihash = { package = "parity-multihash", version = "0.2.1", path = "../misc/m
multistream-select = { version = "0.7.0", path = "../misc/multistream-select" }
parking_lot = "0.10.0"
pin-project = "0.4.6"
protobuf = "=2.8.1" # note: see https://github.com/libp2p/rust-libp2p/issues/1363
prost = "0.6"
rand = "0.7"
rw-stream-sink = { version = "0.2.0", path = "../misc/rw-stream-sink" }
sha2 = "0.8.0"
@ -48,6 +48,9 @@ libp2p-tcp = { version = "0.14.0-alpha.1", path = "../transports/tcp" }
quickcheck = "0.9.0"
wasm-timer = "0.2"
[build-dependencies]
prost-build = "0.6"
[features]
default = ["secp256k1"]
secp256k1 = ["libsecp256k1"]

23
core/build.rs Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
fn main() {
prost_build::compile_protos(&["src/keys.proto"], &["src"]).unwrap();
}

View File

@ -1,3 +0,0 @@
#!/bin/sh
../scripts/protobuf/gen.sh src/keys.proto

View File

@ -149,62 +149,67 @@ impl PublicKey {
/// Encode the public key into a protobuf structure for storage or
/// exchange with other nodes.
pub fn into_protobuf_encoding(self) -> Vec<u8> {
use protobuf::Message;
let mut public_key = keys_proto::PublicKey::new();
match self {
PublicKey::Ed25519(key) => {
public_key.set_Type(keys_proto::KeyType::Ed25519);
public_key.set_Data(key.encode().to_vec());
use prost::Message;
let public_key = match self {
PublicKey::Ed25519(key) =>
keys_proto::PublicKey {
r#type: keys_proto::KeyType::Ed25519 as i32,
data: key.encode().to_vec()
},
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
PublicKey::Rsa(key) => {
public_key.set_Type(keys_proto::KeyType::RSA);
public_key.set_Data(key.encode_x509());
PublicKey::Rsa(key) =>
keys_proto::PublicKey {
r#type: keys_proto::KeyType::Rsa as i32,
data: key.encode_x509()
},
#[cfg(feature = "secp256k1")]
PublicKey::Secp256k1(key) => {
public_key.set_Type(keys_proto::KeyType::Secp256k1);
public_key.set_Data(key.encode().to_vec());
},
PublicKey::Secp256k1(key) =>
keys_proto::PublicKey {
r#type: keys_proto::KeyType::Secp256k1 as i32,
data: key.encode().to_vec()
}
};
public_key
.write_to_bytes()
.expect("Encoding public key into protobuf failed.")
let mut buf = Vec::with_capacity(public_key.encoded_len());
public_key.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
buf
}
/// Decode a public key from a protobuf structure, e.g. read from storage
/// or received from another node.
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
use prost::Message;
#[allow(unused_mut)] // Due to conditional compilation.
let mut pubkey = protobuf::parse_from_bytes::<keys_proto::PublicKey>(bytes)
let mut pubkey = keys_proto::PublicKey::decode(bytes)
.map_err(|e| DecodingError::new("Protobuf").source(e))?;
match pubkey.get_Type() {
let key_type = keys_proto::KeyType::from_i32(pubkey.r#type)
.ok_or_else(|| DecodingError::new(format!("unknown key type: {}", pubkey.r#type)))?;
match key_type {
keys_proto::KeyType::Ed25519 => {
ed25519::PublicKey::decode(pubkey.get_Data())
.map(PublicKey::Ed25519)
ed25519::PublicKey::decode(&pubkey.data).map(PublicKey::Ed25519)
},
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
keys_proto::KeyType::RSA => {
rsa::PublicKey::decode_x509(&pubkey.take_Data())
.map(PublicKey::Rsa)
keys_proto::KeyType::Rsa => {
rsa::PublicKey::decode_x509(&pubkey.data).map(PublicKey::Rsa)
}
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
keys_proto::KeyType::RSA => {
keys_proto::KeyType::Rsa => {
log::debug!("support for RSA was disabled at compile-time");
Err(DecodingError::new("Unsupported"))
},
#[cfg(feature = "secp256k1")]
keys_proto::KeyType::Secp256k1 => {
secp256k1::PublicKey::decode(pubkey.get_Data())
.map(PublicKey::Secp256k1)
secp256k1::PublicKey::decode(&pubkey.data).map(PublicKey::Secp256k1)
}
#[cfg(not(feature = "secp256k1"))]
keys_proto::KeyType::Secp256k1 => {
log::debug!("support for secp256k1 was disabled at compile-time");
Err("Unsupported".to_string().into())
},
}
}
}

View File

@ -1,5 +1,7 @@
syntax = "proto2";
package keys_proto;
enum KeyType {
RSA = 0;
Ed25519 = 1;

View File

@ -1,574 +0,0 @@
// This file is generated by rust-protobuf 2.8.1. Do not edit
// @generated
// https://github.com/Manishearth/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy::all)]
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(box_pointers)]
#![allow(dead_code)]
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(trivial_casts)]
#![allow(unsafe_code)]
#![allow(unused_imports)]
#![allow(unused_results)]
//! Generated file from `src/keys.proto`
use protobuf::Message as Message_imported_for_functions;
use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
/// Generated files are compatible only with the same version
/// of protobuf runtime.
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_8_1;
#[derive(PartialEq,Clone,Default)]
pub struct PublicKey {
// message fields
Type: ::std::option::Option<KeyType>,
Data: ::protobuf::SingularField<::std::vec::Vec<u8>>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a PublicKey {
fn default() -> &'a PublicKey {
<PublicKey as ::protobuf::Message>::default_instance()
}
}
impl PublicKey {
pub fn new() -> PublicKey {
::std::default::Default::default()
}
// required .KeyType Type = 1;
pub fn get_Type(&self) -> KeyType {
self.Type.unwrap_or(KeyType::RSA)
}
pub fn clear_Type(&mut self) {
self.Type = ::std::option::Option::None;
}
pub fn has_Type(&self) -> bool {
self.Type.is_some()
}
// Param is passed by value, moved
pub fn set_Type(&mut self, v: KeyType) {
self.Type = ::std::option::Option::Some(v);
}
// required bytes Data = 2;
pub fn get_Data(&self) -> &[u8] {
match self.Data.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_Data(&mut self) {
self.Data.clear();
}
pub fn has_Data(&self) -> bool {
self.Data.is_some()
}
// Param is passed by value, moved
pub fn set_Data(&mut self, v: ::std::vec::Vec<u8>) {
self.Data = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_Data(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.Data.is_none() {
self.Data.set_default();
}
self.Data.as_mut().unwrap()
}
// Take field
pub fn take_Data(&mut self) -> ::std::vec::Vec<u8> {
self.Data.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
}
impl ::protobuf::Message for PublicKey {
fn is_initialized(&self) -> bool {
if self.Type.is_none() {
return false;
}
if self.Data.is_none() {
return false;
}
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
while !is.eof()? {
let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number {
1 => {
::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.Type, 1, &mut self.unknown_fields)?
},
2 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.Data)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
if let Some(v) = self.Type {
my_size += ::protobuf::rt::enum_size(1, v);
}
if let Some(ref v) = self.Data.as_ref() {
my_size += ::protobuf::rt::bytes_size(2, &v);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
if let Some(v) = self.Type {
os.write_enum(1, v.value())?;
}
if let Some(ref v) = self.Data.as_ref() {
os.write_bytes(2, &v)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn as_any(&self) -> &dyn (::std::any::Any) {
self as &dyn (::std::any::Any)
}
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
self as &mut dyn (::std::any::Any)
}
fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
self
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
Self::descriptor_static()
}
fn new() -> PublicKey {
PublicKey::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum<KeyType>>(
"Type",
|m: &PublicKey| { &m.Type },
|m: &mut PublicKey| { &mut m.Type },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"Data",
|m: &PublicKey| { &m.Data },
|m: &mut PublicKey| { &mut m.Data },
));
::protobuf::reflect::MessageDescriptor::new::<PublicKey>(
"PublicKey",
fields,
file_descriptor_proto()
)
})
}
}
fn default_instance() -> &'static PublicKey {
static mut instance: ::protobuf::lazy::Lazy<PublicKey> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const PublicKey,
};
unsafe {
instance.get(PublicKey::new)
}
}
}
impl ::protobuf::Clear for PublicKey {
fn clear(&mut self) {
self.Type = ::std::option::Option::None;
self.Data.clear();
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for PublicKey {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for PublicKey {
fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
::protobuf::reflect::ProtobufValueRef::Message(self)
}
}
#[derive(PartialEq,Clone,Default)]
pub struct PrivateKey {
// message fields
Type: ::std::option::Option<KeyType>,
Data: ::protobuf::SingularField<::std::vec::Vec<u8>>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a PrivateKey {
fn default() -> &'a PrivateKey {
<PrivateKey as ::protobuf::Message>::default_instance()
}
}
impl PrivateKey {
pub fn new() -> PrivateKey {
::std::default::Default::default()
}
// required .KeyType Type = 1;
pub fn get_Type(&self) -> KeyType {
self.Type.unwrap_or(KeyType::RSA)
}
pub fn clear_Type(&mut self) {
self.Type = ::std::option::Option::None;
}
pub fn has_Type(&self) -> bool {
self.Type.is_some()
}
// Param is passed by value, moved
pub fn set_Type(&mut self, v: KeyType) {
self.Type = ::std::option::Option::Some(v);
}
// required bytes Data = 2;
pub fn get_Data(&self) -> &[u8] {
match self.Data.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_Data(&mut self) {
self.Data.clear();
}
pub fn has_Data(&self) -> bool {
self.Data.is_some()
}
// Param is passed by value, moved
pub fn set_Data(&mut self, v: ::std::vec::Vec<u8>) {
self.Data = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_Data(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.Data.is_none() {
self.Data.set_default();
}
self.Data.as_mut().unwrap()
}
// Take field
pub fn take_Data(&mut self) -> ::std::vec::Vec<u8> {
self.Data.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
}
impl ::protobuf::Message for PrivateKey {
fn is_initialized(&self) -> bool {
if self.Type.is_none() {
return false;
}
if self.Data.is_none() {
return false;
}
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
while !is.eof()? {
let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number {
1 => {
::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.Type, 1, &mut self.unknown_fields)?
},
2 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.Data)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
if let Some(v) = self.Type {
my_size += ::protobuf::rt::enum_size(1, v);
}
if let Some(ref v) = self.Data.as_ref() {
my_size += ::protobuf::rt::bytes_size(2, &v);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
if let Some(v) = self.Type {
os.write_enum(1, v.value())?;
}
if let Some(ref v) = self.Data.as_ref() {
os.write_bytes(2, &v)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn as_any(&self) -> &dyn (::std::any::Any) {
self as &dyn (::std::any::Any)
}
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
self as &mut dyn (::std::any::Any)
}
fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
self
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
Self::descriptor_static()
}
fn new() -> PrivateKey {
PrivateKey::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum<KeyType>>(
"Type",
|m: &PrivateKey| { &m.Type },
|m: &mut PrivateKey| { &mut m.Type },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"Data",
|m: &PrivateKey| { &m.Data },
|m: &mut PrivateKey| { &mut m.Data },
));
::protobuf::reflect::MessageDescriptor::new::<PrivateKey>(
"PrivateKey",
fields,
file_descriptor_proto()
)
})
}
}
fn default_instance() -> &'static PrivateKey {
static mut instance: ::protobuf::lazy::Lazy<PrivateKey> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const PrivateKey,
};
unsafe {
instance.get(PrivateKey::new)
}
}
}
impl ::protobuf::Clear for PrivateKey {
fn clear(&mut self) {
self.Type = ::std::option::Option::None;
self.Data.clear();
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for PrivateKey {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for PrivateKey {
fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
::protobuf::reflect::ProtobufValueRef::Message(self)
}
}
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub enum KeyType {
RSA = 0,
Ed25519 = 1,
Secp256k1 = 2,
}
impl ::protobuf::ProtobufEnum for KeyType {
fn value(&self) -> i32 {
*self as i32
}
fn from_i32(value: i32) -> ::std::option::Option<KeyType> {
match value {
0 => ::std::option::Option::Some(KeyType::RSA),
1 => ::std::option::Option::Some(KeyType::Ed25519),
2 => ::std::option::Option::Some(KeyType::Secp256k1),
_ => ::std::option::Option::None
}
}
fn values() -> &'static [Self] {
static values: &'static [KeyType] = &[
KeyType::RSA,
KeyType::Ed25519,
KeyType::Secp256k1,
];
values
}
fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
};
unsafe {
descriptor.get(|| {
::protobuf::reflect::EnumDescriptor::new("KeyType", file_descriptor_proto())
})
}
}
}
impl ::std::marker::Copy for KeyType {
}
impl ::std::default::Default for KeyType {
fn default() -> Self {
KeyType::RSA
}
}
impl ::protobuf::reflect::ProtobufValue for KeyType {
fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
}
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0esrc/keys.proto\"=\n\tPublicKey\x12\x1c\n\x04Type\x18\x01\x20\x02(\
\x0e2\x08.KeyTypeR\x04Type\x12\x12\n\x04Data\x18\x02\x20\x02(\x0cR\x04Da\
ta\">\n\nPrivateKey\x12\x1c\n\x04Type\x18\x01\x20\x02(\x0e2\x08.KeyTypeR\
\x04Type\x12\x12\n\x04Data\x18\x02\x20\x02(\x0cR\x04Data*.\n\x07KeyType\
\x12\x07\n\x03RSA\x10\0\x12\x0b\n\x07Ed25519\x10\x01\x12\r\n\tSecp256k1\
\x10\x02J\xe9\x03\n\x06\x12\x04\0\0\x10\x01\n\x08\n\x01\x0c\x12\x03\0\0\
\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x06\x01\n\n\n\x03\x05\0\x01\x12\x03\
\x02\x05\x0c\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x02\n\n\x0c\n\x05\x05\0\
\x02\0\x01\x12\x03\x03\x02\x05\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\
\x08\t\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x02\x0e\n\x0c\n\x05\x05\0\
\x02\x01\x01\x12\x03\x04\x02\t\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x04\
\x0c\r\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x02\x10\n\x0c\n\x05\x05\0\
\x02\x02\x01\x12\x03\x05\x02\x0b\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\
\x05\x0e\x0f\n\n\n\x02\x04\0\x12\x04\x08\0\x0b\x01\n\n\n\x03\x04\0\x01\
\x12\x03\x08\x08\x11\n\x0b\n\x04\x04\0\x02\0\x12\x03\t\x02\x1c\n\x0c\n\
\x05\x04\0\x02\0\x04\x12\x03\t\x02\n\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\
\t\x0b\x12\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\t\x13\x17\n\x0c\n\x05\x04\
\0\x02\0\x03\x12\x03\t\x1a\x1b\n\x0b\n\x04\x04\0\x02\x01\x12\x03\n\x02\
\x1a\n\x0c\n\x05\x04\0\x02\x01\x04\x12\x03\n\x02\n\n\x0c\n\x05\x04\0\x02\
\x01\x05\x12\x03\n\x0b\x10\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\n\x11\
\x15\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\n\x18\x19\n\n\n\x02\x04\x01\
\x12\x04\r\0\x10\x01\n\n\n\x03\x04\x01\x01\x12\x03\r\x08\x12\n\x0b\n\x04\
\x04\x01\x02\0\x12\x03\x0e\x02\x1c\n\x0c\n\x05\x04\x01\x02\0\x04\x12\x03\
\x0e\x02\n\n\x0c\n\x05\x04\x01\x02\0\x06\x12\x03\x0e\x0b\x12\n\x0c\n\x05\
\x04\x01\x02\0\x01\x12\x03\x0e\x13\x17\n\x0c\n\x05\x04\x01\x02\0\x03\x12\
\x03\x0e\x1a\x1b\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x0f\x02\x1a\n\x0c\n\
\x05\x04\x01\x02\x01\x04\x12\x03\x0f\x02\n\n\x0c\n\x05\x04\x01\x02\x01\
\x05\x12\x03\x0f\x0b\x10\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x0f\x11\
\x15\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x0f\x18\x19\
";
static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
};
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
}
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
unsafe {
file_descriptor_proto_lazy.get(|| {
parse_descriptor_proto()
})
}
}

View File

@ -35,11 +35,14 @@
//! define how to upgrade each individual substream to use a protocol.
//! See the `upgrade` module.
mod keys_proto {
include!(concat!(env!("OUT_DIR"), "/keys_proto.rs"));
}
/// Multi-address re-export.
pub use multiaddr;
pub type Negotiated<T> = futures::compat::Compat01As03<multistream_select::Negotiated<futures::compat::Compat<T>>>;
mod keys_proto;
mod peer_id;
mod translation;

View File

@ -16,6 +16,10 @@ fnv = "1.0"
futures = "0.3.1"
libp2p-core = { version = "0.14.0-alpha.1", path = "../../core" }
libp2p-swarm = { version = "0.4.0-alpha.1", path = "../../swarm" }
protobuf = "=2.8.1" # note: see https://github.com/libp2p/rust-libp2p/issues/1363
prost = "0.6"
rand = "0.7"
smallvec = "1.0"
[build-dependencies]
prost-build = "0.6"

View File

@ -0,0 +1,24 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
fn main() {
prost_build::compile_protos(&["src/rpc.proto"], &["src"]).unwrap();
}

View File

@ -1,3 +0,0 @@
#!/bin/sh
../../scripts/protobuf/gen.sh src/rpc.proto

View File

@ -24,9 +24,12 @@
pub mod protocol;
mod layer;
mod rpc_proto;
mod topic;
mod rpc_proto {
include!(concat!(env!("OUT_DIR"), "/floodsub.pb.rs"));
}
pub use self::layer::{Floodsub, FloodsubEvent};
pub use self::protocol::{FloodsubMessage, FloodsubRpc};
pub use self::topic::{Topic, TopicBuilder, TopicHash};

View File

@ -22,7 +22,7 @@ use crate::rpc_proto;
use crate::topic::TopicHash;
use futures::prelude::*;
use libp2p_core::{InboundUpgrade, OutboundUpgrade, UpgradeInfo, PeerId, upgrade};
use protobuf::{ProtobufError, Message as ProtobufMessage};
use prost::Message;
use std::{error, fmt, io, iter, pin::Pin};
/// Implementation of `ConnectionUpgrade` for the floodsub protocol.
@ -31,7 +31,6 @@ pub struct FloodsubConfig {}
impl FloodsubConfig {
/// Builds a new `FloodsubConfig`.
#[inline]
pub fn new() -> FloodsubConfig {
FloodsubConfig {}
}
@ -41,7 +40,6 @@ impl UpgradeInfo for FloodsubConfig {
type Info = &'static [u8];
type InfoIter = iter::Once<Self::Info>;
#[inline]
fn protocol_info(&self) -> Self::InfoIter {
iter::once(b"/floodsub/1.0.0")
}
@ -58,18 +56,17 @@ where
fn upgrade_inbound(self, mut socket: TSocket, _: Self::Info) -> Self::Future {
Box::pin(async move {
let packet = upgrade::read_one(&mut socket, 2048).await?;
let mut rpc: rpc_proto::RPC = protobuf::parse_from_bytes(&packet)?;
let rpc = rpc_proto::Rpc::decode(&packet[..])?;
let mut messages = Vec::with_capacity(rpc.get_publish().len());
for mut publish in rpc.take_publish().into_iter() {
let mut messages = Vec::with_capacity(rpc.publish.len());
for publish in rpc.publish.into_iter() {
messages.push(FloodsubMessage {
source: PeerId::from_bytes(publish.take_from()).map_err(|_| {
source: PeerId::from_bytes(publish.from.unwrap_or_default()).map_err(|_| {
FloodsubDecodeError::InvalidPeerId
})?,
data: publish.take_data(),
sequence_number: publish.take_seqno(),
topics: publish
.take_topicIDs()
data: publish.data.unwrap_or_default(),
sequence_number: publish.seqno.unwrap_or_default(),
topics: publish.topic_ids
.into_iter()
.map(TopicHash::from_raw)
.collect(),
@ -78,16 +75,15 @@ where
Ok(FloodsubRpc {
messages,
subscriptions: rpc
.take_subscriptions()
subscriptions: rpc.subscriptions
.into_iter()
.map(|mut sub| FloodsubSubscription {
action: if sub.get_subscribe() {
.map(|sub| FloodsubSubscription {
action: if Some(true) == sub.subscribe {
FloodsubSubscriptionAction::Subscribe
} else {
FloodsubSubscriptionAction::Unsubscribe
},
topic: TopicHash::from_raw(sub.take_topicid()),
topic: TopicHash::from_raw(sub.topic_id.unwrap_or_default()),
})
.collect(),
})
@ -101,21 +97,19 @@ pub enum FloodsubDecodeError {
/// Error when reading the packet from the socket.
ReadError(upgrade::ReadOneError),
/// Error when decoding the raw buffer into a protobuf.
ProtobufError(ProtobufError),
ProtobufError(prost::DecodeError),
/// Error when parsing the `PeerId` in the message.
InvalidPeerId,
}
impl From<upgrade::ReadOneError> for FloodsubDecodeError {
#[inline]
fn from(err: upgrade::ReadOneError) -> Self {
FloodsubDecodeError::ReadError(err)
}
}
impl From<ProtobufError> for FloodsubDecodeError {
#[inline]
fn from(err: ProtobufError) -> Self {
impl From<prost::DecodeError> for FloodsubDecodeError {
fn from(err: prost::DecodeError) -> Self {
FloodsubDecodeError::ProtobufError(err)
}
}
@ -156,7 +150,6 @@ impl UpgradeInfo for FloodsubRpc {
type Info = &'static [u8];
type InfoIter = iter::Once<Self::Info>;
#[inline]
fn protocol_info(&self) -> Self::InfoIter {
iter::once(b"/floodsub/1.0.0")
}
@ -170,7 +163,6 @@ where
type Error = io::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Output, Self::Error>> + Send>>;
#[inline]
fn upgrade_outbound(self, mut socket: TSocket, _: Self::Info) -> Self::Future {
Box::pin(async move {
let bytes = self.into_bytes();
@ -183,33 +175,34 @@ where
impl FloodsubRpc {
/// Turns this `FloodsubRpc` into a message that can be sent to a substream.
fn into_bytes(self) -> Vec<u8> {
let mut proto = rpc_proto::RPC::new();
for message in self.messages {
let mut msg = rpc_proto::Message::new();
msg.set_from(message.source.into_bytes());
msg.set_data(message.data);
msg.set_seqno(message.sequence_number);
msg.set_topicIDs(
message
.topics
let rpc = rpc_proto::Rpc {
publish: self.messages.into_iter()
.map(|msg| {
rpc_proto::Message {
from: Some(msg.source.into_bytes()),
data: Some(msg.data),
seqno: Some(msg.sequence_number),
topic_ids: msg.topics
.into_iter()
.map(TopicHash::into_string)
.collect()
}
})
.collect(),
);
proto.mut_publish().push(msg);
}
for topic in self.subscriptions {
let mut subscription = rpc_proto::RPC_SubOpts::new();
subscription.set_subscribe(topic.action == FloodsubSubscriptionAction::Subscribe);
subscription.set_topicid(topic.topic.into_string());
proto.mut_subscriptions().push(subscription);
subscriptions: self.subscriptions.into_iter()
.map(|topic| {
rpc_proto::rpc::SubOpts {
subscribe: Some(topic.action == FloodsubSubscriptionAction::Subscribe),
topic_id: Some(topic.topic.into_string())
}
})
.collect()
};
proto
.write_to_bytes()
.expect("there is no situation in which the protobuf message can be invalid")
let mut buf = Vec::with_capacity(rpc.encoded_len());
rpc.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
buf
}
}

View File

@ -8,7 +8,7 @@ message RPC {
message SubOpts {
optional bool subscribe = 1; // subscribe or unsubcribe
optional string topicid = 2;
optional string topic_id = 2;
}
}
@ -16,7 +16,7 @@ message Message {
optional bytes from = 1;
optional bytes data = 2;
optional bytes seqno = 3;
repeated string topicIDs = 4;
repeated string topic_ids = 4;
}
// topicID = hash(topicDescriptor); (not the topic.name)
@ -38,7 +38,7 @@ message TopicDescriptor {
message EncOpts {
optional EncMode mode = 1;
repeated bytes keyHashes = 2; // the hashes of the shared keys used (salted)
repeated bytes key_hashes = 2; // the hashes of the shared keys used (salted)
enum EncMode {
NONE = 0; // no encryption, anyone can read

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@
use bs58;
use crate::rpc_proto;
use protobuf::Message;
use prost::Message;
/// Represents the hash of a topic.
///
@ -33,12 +33,10 @@ pub struct TopicHash {
impl TopicHash {
/// Builds a new `TopicHash` from the given hash.
#[inline]
pub fn from_raw(hash: String) -> TopicHash {
TopicHash { hash }
}
#[inline]
pub fn into_string(self) -> String {
self.hash
}
@ -53,28 +51,24 @@ pub struct Topic {
impl Topic {
/// Returns the hash of the topic.
#[inline]
pub fn hash(&self) -> &TopicHash {
&self.hash
}
}
impl AsRef<TopicHash> for Topic {
#[inline]
fn as_ref(&self) -> &TopicHash {
&self.hash
}
}
impl From<Topic> for TopicHash {
#[inline]
fn from(topic: Topic) -> TopicHash {
topic.hash
}
}
impl<'a> From<&'a Topic> for TopicHash {
#[inline]
fn from(topic: &'a Topic) -> TopicHash {
topic.hash.clone()
}
@ -91,21 +85,22 @@ impl TopicBuilder {
where
S: Into<String>,
{
let mut builder = rpc_proto::TopicDescriptor::new();
builder.set_name(name.into());
TopicBuilder { builder }
TopicBuilder {
builder: rpc_proto::TopicDescriptor {
name: Some(name.into()),
auth: None,
enc: None
}
}
}
/// Turns the builder into an actual `Topic`.
pub fn build(self) -> Topic {
let bytes = self
.builder
.write_to_bytes()
.expect("protobuf message is always valid");
let mut buf = Vec::with_capacity(self.builder.encoded_len());
self.builder.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
// TODO: https://github.com/libp2p/rust-libp2p/issues/473
let hash = TopicHash {
hash: bs58::encode(&bytes).into_string(),
hash: bs58::encode(&buf).into_string(),
};
Topic {
descriptor: self.builder,

View File

@ -14,7 +14,7 @@ futures = "0.3.1"
libp2p-core = { version = "0.14.0-alpha.1", path = "../../core" }
libp2p-swarm = { version = "0.4.0-alpha.1", path = "../../swarm" }
log = "0.4.1"
protobuf = "=2.8.1" # note: see https://github.com/libp2p/rust-libp2p/issues/1363
prost = "0.6"
smallvec = "1.0"
wasm-timer = "0.2"
@ -23,3 +23,7 @@ async-std = "1.0"
libp2p-mplex = { version = "0.14.0-alpha.1", path = "../../muxers/mplex" }
libp2p-secio = { version = "0.14.0-alpha.1", path = "../../protocols/secio" }
libp2p-tcp = { version = "0.14.0-alpha.1", path = "../../transports/tcp" }
[build-dependencies]
prost-build = "0.6"

View File

@ -0,0 +1,24 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
fn main() {
prost_build::compile_protos(&["src/structs.proto"], &["src"]).unwrap();
}

View File

@ -1,3 +0,0 @@
#!/bin/sh
../../scripts/protobuf/gen.sh src/structs.proto

View File

@ -43,4 +43,8 @@ pub use self::protocol::IdentifyInfo;
mod handler;
mod identify;
mod protocol;
mod structs_proto;
mod structs_proto {
include!(concat!(env!("OUT_DIR"), "/structs.rs"));
}

View File

@ -26,9 +26,7 @@ use libp2p_core::{
upgrade::{self, InboundUpgrade, OutboundUpgrade, UpgradeInfo}
};
use log::{debug, trace};
use protobuf::Message as ProtobufMessage;
use protobuf::parse_from_bytes as protobuf_parse_from_bytes;
use protobuf::RepeatedField;
use prost::Message;
use std::convert::TryFrom;
use std::{fmt, io, iter, pin::Pin};
@ -78,18 +76,18 @@ where
let pubkey_bytes = info.public_key.into_protobuf_encoding();
let mut message = structs_proto::Identify::new();
message.set_agentVersion(info.agent_version);
message.set_protocolVersion(info.protocol_version);
message.set_publicKey(pubkey_bytes);
message.set_listenAddrs(listen_addrs);
message.set_observedAddr(observed_addr.to_vec());
message.set_protocols(RepeatedField::from_vec(info.protocols));
let message = structs_proto::Identify {
agent_version: Some(info.agent_version),
protocol_version: Some(info.protocol_version),
public_key: Some(pubkey_bytes),
listen_addrs: listen_addrs,
observed_addr: Some(observed_addr.to_vec()),
protocols: info.protocols
};
async move {
let bytes = message
.write_to_bytes()
.expect("writing protobuf failed; should never happen");
let mut bytes = Vec::with_capacity(message.encoded_len());
message.encode(&mut bytes).expect("Vec<u8> provides capacity as needed");
upgrade::write_one(&mut self.inner, &bytes).await
}
}
@ -170,8 +168,8 @@ where
// Turns a protobuf message into an `IdentifyInfo` and an observed address. If something bad
// happens, turn it into an `io::Error`.
fn parse_proto_msg(msg: impl AsRef<[u8]>) -> Result<(IdentifyInfo, Multiaddr), io::Error> {
match protobuf_parse_from_bytes::<structs_proto::Identify>(msg.as_ref()) {
Ok(mut msg) => {
match structs_proto::Identify::decode(msg.as_ref()) {
Ok(msg) => {
// Turn a `Vec<u8>` into a `Multiaddr`. If something bad happens, turn it into
// an `io::Error`.
fn bytes_to_multiaddr(bytes: Vec<u8>) -> Result<Multiaddr, io::Error> {
@ -181,22 +179,22 @@ fn parse_proto_msg(msg: impl AsRef<[u8]>) -> Result<(IdentifyInfo, Multiaddr), i
let listen_addrs = {
let mut addrs = Vec::new();
for addr in msg.take_listenAddrs().into_iter() {
for addr in msg.listen_addrs.into_iter() {
addrs.push(bytes_to_multiaddr(addr)?);
}
addrs
};
let public_key = PublicKey::from_protobuf_encoding(msg.get_publicKey())
let public_key = PublicKey::from_protobuf_encoding(&msg.public_key.unwrap_or_default())
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
let observed_addr = bytes_to_multiaddr(msg.take_observedAddr())?;
let observed_addr = bytes_to_multiaddr(msg.observed_addr.unwrap_or_default())?;
let info = IdentifyInfo {
public_key,
protocol_version: msg.take_protocolVersion(),
agent_version: msg.take_agentVersion(),
protocol_version: msg.protocol_version.unwrap_or_default(),
agent_version: msg.agent_version.unwrap_or_default(),
listen_addrs,
protocols: msg.take_protocols().into_vec(),
protocols: msg.protocols
};
Ok((info, observed_addr))

View File

@ -1,5 +1,7 @@
syntax = "proto2";
package structs;
message Identify {
// protocolVersion determines compatibility between peers
optional string protocolVersion = 5; // e.g. ipfs/1.0.0

View File

@ -1,509 +0,0 @@
// This file is generated by rust-protobuf 2.8.1. Do not edit
// @generated
// https://github.com/Manishearth/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy::all)]
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(box_pointers)]
#![allow(dead_code)]
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(trivial_casts)]
#![allow(unsafe_code)]
#![allow(unused_imports)]
#![allow(unused_results)]
//! Generated file from `src/structs.proto`
use protobuf::Message as Message_imported_for_functions;
use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
/// Generated files are compatible only with the same version
/// of protobuf runtime.
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_8_1;
#[derive(PartialEq,Clone,Default)]
pub struct Identify {
// message fields
protocolVersion: ::protobuf::SingularField<::std::string::String>,
agentVersion: ::protobuf::SingularField<::std::string::String>,
publicKey: ::protobuf::SingularField<::std::vec::Vec<u8>>,
listenAddrs: ::protobuf::RepeatedField<::std::vec::Vec<u8>>,
observedAddr: ::protobuf::SingularField<::std::vec::Vec<u8>>,
protocols: ::protobuf::RepeatedField<::std::string::String>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a Identify {
fn default() -> &'a Identify {
<Identify as ::protobuf::Message>::default_instance()
}
}
impl Identify {
pub fn new() -> Identify {
::std::default::Default::default()
}
// optional string protocolVersion = 5;
pub fn get_protocolVersion(&self) -> &str {
match self.protocolVersion.as_ref() {
Some(v) => &v,
None => "",
}
}
pub fn clear_protocolVersion(&mut self) {
self.protocolVersion.clear();
}
pub fn has_protocolVersion(&self) -> bool {
self.protocolVersion.is_some()
}
// Param is passed by value, moved
pub fn set_protocolVersion(&mut self, v: ::std::string::String) {
self.protocolVersion = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_protocolVersion(&mut self) -> &mut ::std::string::String {
if self.protocolVersion.is_none() {
self.protocolVersion.set_default();
}
self.protocolVersion.as_mut().unwrap()
}
// Take field
pub fn take_protocolVersion(&mut self) -> ::std::string::String {
self.protocolVersion.take().unwrap_or_else(|| ::std::string::String::new())
}
// optional string agentVersion = 6;
pub fn get_agentVersion(&self) -> &str {
match self.agentVersion.as_ref() {
Some(v) => &v,
None => "",
}
}
pub fn clear_agentVersion(&mut self) {
self.agentVersion.clear();
}
pub fn has_agentVersion(&self) -> bool {
self.agentVersion.is_some()
}
// Param is passed by value, moved
pub fn set_agentVersion(&mut self, v: ::std::string::String) {
self.agentVersion = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_agentVersion(&mut self) -> &mut ::std::string::String {
if self.agentVersion.is_none() {
self.agentVersion.set_default();
}
self.agentVersion.as_mut().unwrap()
}
// Take field
pub fn take_agentVersion(&mut self) -> ::std::string::String {
self.agentVersion.take().unwrap_or_else(|| ::std::string::String::new())
}
// optional bytes publicKey = 1;
pub fn get_publicKey(&self) -> &[u8] {
match self.publicKey.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_publicKey(&mut self) {
self.publicKey.clear();
}
pub fn has_publicKey(&self) -> bool {
self.publicKey.is_some()
}
// Param is passed by value, moved
pub fn set_publicKey(&mut self, v: ::std::vec::Vec<u8>) {
self.publicKey = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_publicKey(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.publicKey.is_none() {
self.publicKey.set_default();
}
self.publicKey.as_mut().unwrap()
}
// Take field
pub fn take_publicKey(&mut self) -> ::std::vec::Vec<u8> {
self.publicKey.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
// repeated bytes listenAddrs = 2;
pub fn get_listenAddrs(&self) -> &[::std::vec::Vec<u8>] {
&self.listenAddrs
}
pub fn clear_listenAddrs(&mut self) {
self.listenAddrs.clear();
}
// Param is passed by value, moved
pub fn set_listenAddrs(&mut self, v: ::protobuf::RepeatedField<::std::vec::Vec<u8>>) {
self.listenAddrs = v;
}
// Mutable pointer to the field.
pub fn mut_listenAddrs(&mut self) -> &mut ::protobuf::RepeatedField<::std::vec::Vec<u8>> {
&mut self.listenAddrs
}
// Take field
pub fn take_listenAddrs(&mut self) -> ::protobuf::RepeatedField<::std::vec::Vec<u8>> {
::std::mem::replace(&mut self.listenAddrs, ::protobuf::RepeatedField::new())
}
// optional bytes observedAddr = 4;
pub fn get_observedAddr(&self) -> &[u8] {
match self.observedAddr.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_observedAddr(&mut self) {
self.observedAddr.clear();
}
pub fn has_observedAddr(&self) -> bool {
self.observedAddr.is_some()
}
// Param is passed by value, moved
pub fn set_observedAddr(&mut self, v: ::std::vec::Vec<u8>) {
self.observedAddr = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_observedAddr(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.observedAddr.is_none() {
self.observedAddr.set_default();
}
self.observedAddr.as_mut().unwrap()
}
// Take field
pub fn take_observedAddr(&mut self) -> ::std::vec::Vec<u8> {
self.observedAddr.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
// repeated string protocols = 3;
pub fn get_protocols(&self) -> &[::std::string::String] {
&self.protocols
}
pub fn clear_protocols(&mut self) {
self.protocols.clear();
}
// Param is passed by value, moved
pub fn set_protocols(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) {
self.protocols = v;
}
// Mutable pointer to the field.
pub fn mut_protocols(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> {
&mut self.protocols
}
// Take field
pub fn take_protocols(&mut self) -> ::protobuf::RepeatedField<::std::string::String> {
::std::mem::replace(&mut self.protocols, ::protobuf::RepeatedField::new())
}
}
impl ::protobuf::Message for Identify {
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
while !is.eof()? {
let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number {
5 => {
::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.protocolVersion)?;
},
6 => {
::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.agentVersion)?;
},
1 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.publicKey)?;
},
2 => {
::protobuf::rt::read_repeated_bytes_into(wire_type, is, &mut self.listenAddrs)?;
},
4 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.observedAddr)?;
},
3 => {
::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.protocols)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
if let Some(ref v) = self.protocolVersion.as_ref() {
my_size += ::protobuf::rt::string_size(5, &v);
}
if let Some(ref v) = self.agentVersion.as_ref() {
my_size += ::protobuf::rt::string_size(6, &v);
}
if let Some(ref v) = self.publicKey.as_ref() {
my_size += ::protobuf::rt::bytes_size(1, &v);
}
for value in &self.listenAddrs {
my_size += ::protobuf::rt::bytes_size(2, &value);
};
if let Some(ref v) = self.observedAddr.as_ref() {
my_size += ::protobuf::rt::bytes_size(4, &v);
}
for value in &self.protocols {
my_size += ::protobuf::rt::string_size(3, &value);
};
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
if let Some(ref v) = self.protocolVersion.as_ref() {
os.write_string(5, &v)?;
}
if let Some(ref v) = self.agentVersion.as_ref() {
os.write_string(6, &v)?;
}
if let Some(ref v) = self.publicKey.as_ref() {
os.write_bytes(1, &v)?;
}
for v in &self.listenAddrs {
os.write_bytes(2, &v)?;
};
if let Some(ref v) = self.observedAddr.as_ref() {
os.write_bytes(4, &v)?;
}
for v in &self.protocols {
os.write_string(3, &v)?;
};
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn as_any(&self) -> &dyn (::std::any::Any) {
self as &dyn (::std::any::Any)
}
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
self as &mut dyn (::std::any::Any)
}
fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
self
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
Self::descriptor_static()
}
fn new() -> Identify {
Identify::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"protocolVersion",
|m: &Identify| { &m.protocolVersion },
|m: &mut Identify| { &mut m.protocolVersion },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"agentVersion",
|m: &Identify| { &m.agentVersion },
|m: &mut Identify| { &mut m.agentVersion },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"publicKey",
|m: &Identify| { &m.publicKey },
|m: &mut Identify| { &mut m.publicKey },
));
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"listenAddrs",
|m: &Identify| { &m.listenAddrs },
|m: &mut Identify| { &mut m.listenAddrs },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"observedAddr",
|m: &Identify| { &m.observedAddr },
|m: &mut Identify| { &mut m.observedAddr },
));
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"protocols",
|m: &Identify| { &m.protocols },
|m: &mut Identify| { &mut m.protocols },
));
::protobuf::reflect::MessageDescriptor::new::<Identify>(
"Identify",
fields,
file_descriptor_proto()
)
})
}
}
fn default_instance() -> &'static Identify {
static mut instance: ::protobuf::lazy::Lazy<Identify> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const Identify,
};
unsafe {
instance.get(Identify::new)
}
}
}
impl ::protobuf::Clear for Identify {
fn clear(&mut self) {
self.protocolVersion.clear();
self.agentVersion.clear();
self.publicKey.clear();
self.listenAddrs.clear();
self.observedAddr.clear();
self.protocols.clear();
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for Identify {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for Identify {
fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
::protobuf::reflect::ProtobufValueRef::Message(self)
}
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x11src/structs.proto\"\xda\x01\n\x08Identify\x12(\n\x0fprotocolVersio\
n\x18\x05\x20\x01(\tR\x0fprotocolVersion\x12\"\n\x0cagentVersion\x18\x06\
\x20\x01(\tR\x0cagentVersion\x12\x1c\n\tpublicKey\x18\x01\x20\x01(\x0cR\
\tpublicKey\x12\x20\n\x0blistenAddrs\x18\x02\x20\x03(\x0cR\x0blistenAddr\
s\x12\"\n\x0cobservedAddr\x18\x04\x20\x01(\x0cR\x0cobservedAddr\x12\x1c\
\n\tprotocols\x18\x03\x20\x03(\tR\tprotocolsJ\xcc\t\n\x06\x12\x04\0\0\
\x18\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\
\x18\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x10\nX\n\x04\x04\0\x02\0\
\x12\x03\x04\x02&\x1a8\x20protocolVersion\x20determines\x20compatibility\
\x20between\x20peers\n\"\x11\x20e.g.\x20ipfs/1.0.0\n\n\x0c\n\x05\x04\0\
\x02\0\x04\x12\x03\x04\x02\n\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x04\x0b\
\x11\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x04\x12!\n\x0c\n\x05\x04\0\x02\
\0\x03\x12\x03\x04$%\n\x9f\x01\n\x04\x04\0\x02\x01\x12\x03\x08\x02#\x1a|\
\x20agentVersion\x20is\x20like\x20a\x20UserAgent\x20string\x20in\x20brow\
sers,\x20or\x20client\x20version\x20in\x20bittorrent\n\x20includes\x20th\
e\x20client\x20name\x20and\x20client.\n\"\x14\x20e.g.\x20go-ipfs/0.1.0\n\
\n\x0c\n\x05\x04\0\x02\x01\x04\x12\x03\x08\x02\n\n\x0c\n\x05\x04\0\x02\
\x01\x05\x12\x03\x08\x0b\x11\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x08\
\x12\x1e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x08!\"\n\xe3\x01\n\x04\
\x04\0\x02\x02\x12\x03\r\x02\x1f\x1a\xd5\x01\x20publicKey\x20is\x20this\
\x20node's\x20public\x20key\x20(which\x20also\x20gives\x20its\x20node.ID\
)\n\x20-\x20may\x20not\x20need\x20to\x20be\x20sent,\x20as\x20secure\x20c\
hannel\x20implies\x20it\x20has\x20been\x20sent.\n\x20-\x20then\x20again,\
\x20if\x20we\x20change\x20/\x20disable\x20secure\x20channel,\x20may\x20s\
till\x20want\x20it.\n\n\x0c\n\x05\x04\0\x02\x02\x04\x12\x03\r\x02\n\n\
\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\r\x0b\x10\n\x0c\n\x05\x04\0\x02\x02\
\x01\x12\x03\r\x11\x1a\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\r\x1d\x1e\n\
]\n\x04\x04\0\x02\x03\x12\x03\x10\x02!\x1aP\x20listenAddrs\x20are\x20the\
\x20multiaddrs\x20the\x20sender\x20node\x20listens\x20for\x20open\x20con\
nections\x20on\n\n\x0c\n\x05\x04\0\x02\x03\x04\x12\x03\x10\x02\n\n\x0c\n\
\x05\x04\0\x02\x03\x05\x12\x03\x10\x0b\x10\n\x0c\n\x05\x04\0\x02\x03\x01\
\x12\x03\x10\x11\x1c\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x10\x1f\x20\n\
\x81\x02\n\x04\x04\0\x02\x04\x12\x03\x15\x02\"\x1a\xf3\x01\x20oservedAdd\
r\x20is\x20the\x20multiaddr\x20of\x20the\x20remote\x20endpoint\x20that\
\x20the\x20sender\x20node\x20perceives\n\x20this\x20is\x20useful\x20info\
rmation\x20to\x20convey\x20to\x20the\x20other\x20side,\x20as\x20it\x20he\
lps\x20the\x20remote\x20endpoint\n\x20determine\x20whether\x20its\x20con\
nection\x20to\x20the\x20local\x20peer\x20goes\x20through\x20NAT.\n\n\x0c\
\n\x05\x04\0\x02\x04\x04\x12\x03\x15\x02\n\n\x0c\n\x05\x04\0\x02\x04\x05\
\x12\x03\x15\x0b\x10\n\x0c\n\x05\x04\0\x02\x04\x01\x12\x03\x15\x11\x1d\n\
\x0c\n\x05\x04\0\x02\x04\x03\x12\x03\x15\x20!\n\x0b\n\x04\x04\0\x02\x05\
\x12\x03\x17\x02\x20\n\x0c\n\x05\x04\0\x02\x05\x04\x12\x03\x17\x02\n\n\
\x0c\n\x05\x04\0\x02\x05\x05\x12\x03\x17\x0b\x11\n\x0c\n\x05\x04\0\x02\
\x05\x01\x12\x03\x17\x12\x1b\n\x0c\n\x05\x04\0\x02\x05\x03\x12\x03\x17\
\x1e\x1f\
";
static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
};
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
}
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
unsafe {
file_descriptor_proto_lazy.get(|| {
parse_descriptor_proto()
})
}
}

View File

@ -20,7 +20,7 @@ log = "0.4"
libp2p-core = { version = "0.14.0-alpha.1", path = "../../core" }
libp2p-swarm = { version = "0.4.0-alpha.1", path = "../../swarm" }
multihash = { package = "parity-multihash", version = "0.2.1", path = "../../misc/multihash" }
protobuf = "=2.8.1" # note: see https://github.com/libp2p/rust-libp2p/issues/1363
prost = "0.6"
rand = "0.7.2"
sha2 = "0.8.0"
smallvec = "1.0"
@ -33,3 +33,7 @@ void = "1.0"
libp2p-secio = { version = "0.14.0-alpha.1", path = "../secio" }
libp2p-yamux = { version = "0.14.0-alpha.1", path = "../../muxers/yamux" }
quickcheck = "0.9.0"
[build-dependencies]
prost-build = "0.6"

24
protocols/kad/build.rs Normal file
View File

@ -0,0 +1,24 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
fn main() {
prost_build::compile_protos(&["src/dht.proto"], &["src"]).unwrap();
}

View File

@ -1,3 +0,0 @@
#!/bin/sh
../../scripts/protobuf/gen.sh src/dht.proto

File diff suppressed because it is too large Load Diff

View File

@ -32,9 +32,12 @@ pub mod record;
mod addresses;
mod behaviour;
mod jobs;
mod dht_proto;
mod query;
mod dht_proto {
include!(concat!(env!("OUT_DIR"), "/dht.pb.rs"));
}
pub use addresses::Addresses;
pub use behaviour::{Kademlia, KademliaConfig, KademliaEvent, Quorum};
pub use behaviour::{

View File

@ -38,7 +38,7 @@ use futures::prelude::*;
use futures_codec::Framed;
use libp2p_core::{Multiaddr, PeerId};
use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo};
use protobuf::{self, Message};
use prost::Message;
use std::{borrow::Cow, convert::TryFrom, time::Duration};
use std::{io, iter};
use unsigned_varint::codec;
@ -57,30 +57,26 @@ pub enum KadConnectionType {
CannotConnect = 3,
}
impl From<proto::Message_ConnectionType> for KadConnectionType {
fn from(raw: proto::Message_ConnectionType) -> KadConnectionType {
use proto::Message_ConnectionType::{
CAN_CONNECT, CANNOT_CONNECT, CONNECTED, NOT_CONNECTED
};
impl From<proto::message::ConnectionType> for KadConnectionType {
fn from(raw: proto::message::ConnectionType) -> KadConnectionType {
use proto::message::ConnectionType::*;
match raw {
NOT_CONNECTED => KadConnectionType::NotConnected,
CONNECTED => KadConnectionType::Connected,
CAN_CONNECT => KadConnectionType::CanConnect,
CANNOT_CONNECT => KadConnectionType::CannotConnect,
NotConnected => KadConnectionType::NotConnected,
Connected => KadConnectionType::Connected,
CanConnect => KadConnectionType::CanConnect,
CannotConnect => KadConnectionType::CannotConnect,
}
}
}
impl Into<proto::Message_ConnectionType> for KadConnectionType {
fn into(self) -> proto::Message_ConnectionType {
use proto::Message_ConnectionType::{
CAN_CONNECT, CANNOT_CONNECT, CONNECTED, NOT_CONNECTED
};
impl Into<proto::message::ConnectionType> for KadConnectionType {
fn into(self) -> proto::message::ConnectionType {
use proto::message::ConnectionType::*;
match self {
KadConnectionType::NotConnected => NOT_CONNECTED,
KadConnectionType::Connected => CONNECTED,
KadConnectionType::CanConnect => CAN_CONNECT,
KadConnectionType::CannotConnect => CANNOT_CONNECT,
KadConnectionType::NotConnected => NotConnected,
KadConnectionType::Connected => Connected,
KadConnectionType::CanConnect => CanConnect,
KadConnectionType::CannotConnect => CannotConnect,
}
}
}
@ -97,23 +93,25 @@ pub struct KadPeer {
}
// Builds a `KadPeer` from a corresponding protobuf message.
impl TryFrom<&mut proto::Message_Peer> for KadPeer {
impl TryFrom<proto::message::Peer> for KadPeer {
type Error = io::Error;
fn try_from(peer: &mut proto::Message_Peer) -> Result<KadPeer, Self::Error> {
fn try_from(peer: proto::message::Peer) -> Result<KadPeer, Self::Error> {
// TODO: this is in fact a CID; not sure if this should be handled in `from_bytes` or
// as a special case here
let node_id = PeerId::from_bytes(peer.get_id().to_vec())
let node_id = PeerId::from_bytes(peer.id)
.map_err(|_| invalid_data("invalid peer id"))?;
let mut addrs = Vec::with_capacity(peer.get_addrs().len());
for addr in peer.take_addrs().into_iter() {
let mut addrs = Vec::with_capacity(peer.addrs.len());
for addr in peer.addrs.into_iter() {
let as_ma = Multiaddr::try_from(addr).map_err(invalid_data)?;
addrs.push(as_ma);
}
debug_assert_eq!(addrs.len(), addrs.capacity());
let connection_ty = peer.get_connection().into();
let connection_ty = proto::message::ConnectionType::from_i32(peer.connection)
.ok_or_else(|| invalid_data("unknown connection type"))?
.into();
Ok(KadPeer {
node_id,
@ -123,15 +121,16 @@ impl TryFrom<&mut proto::Message_Peer> for KadPeer {
}
}
impl Into<proto::Message_Peer> for KadPeer {
fn into(self) -> proto::Message_Peer {
let mut out = proto::Message_Peer::new();
out.set_id(self.node_id.into_bytes());
for addr in self.multiaddrs {
out.mut_addrs().push(addr.to_vec());
impl Into<proto::message::Peer> for KadPeer {
fn into(self) -> proto::message::Peer {
proto::message::Peer {
id: self.node_id.into_bytes(),
addrs: self.multiaddrs.into_iter().map(|a| a.to_vec()).collect(),
connection: {
let ct: proto::message::ConnectionType = self.connection_ty.into();
ct as i32
}
}
out.set_connection(self.connection_ty.into());
out
}
}
@ -188,12 +187,12 @@ where
.err_into()
.with::<_, _, fn(_) -> _, _>(|response| {
let proto_struct = resp_msg_to_proto(response);
future::ready(proto_struct.write_to_bytes()
.map(io::Cursor::new)
.map_err(invalid_data))
let mut buf = Vec::with_capacity(proto_struct.encoded_len());
proto_struct.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
future::ready(Ok(io::Cursor::new(buf)))
})
.and_then::<_, fn(_) -> _>(|bytes| {
let request = match protobuf::parse_from_bytes(&bytes) {
let request = match proto::Message::decode(bytes) {
Ok(r) => r,
Err(err) => return future::ready(Err(err.into()))
};
@ -220,12 +219,12 @@ where
.err_into()
.with::<_, _, fn(_) -> _, _>(|request| {
let proto_struct = req_msg_to_proto(request);
future::ready(proto_struct.write_to_bytes()
.map(io::Cursor::new)
.map_err(invalid_data))
let mut buf = Vec::with_capacity(proto_struct.encoded_len());
proto_struct.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
future::ready(Ok(io::Cursor::new(buf)))
})
.and_then::<_, fn(_) -> _>(|bytes| {
let response = match protobuf::parse_from_bytes(&bytes) {
let response = match proto::Message::decode(bytes) {
Ok(r) => r,
Err(err) => return future::ready(Err(err.into()))
};
@ -333,46 +332,39 @@ pub enum KadResponseMsg {
/// Converts a `KadRequestMsg` into the corresponding protobuf message for sending.
fn req_msg_to_proto(kad_msg: KadRequestMsg) -> proto::Message {
match kad_msg {
KadRequestMsg::Ping => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::PING);
msg
}
KadRequestMsg::FindNode { key } => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::FIND_NODE);
msg.set_key(key);
msg.set_clusterLevelRaw(10);
msg
}
KadRequestMsg::GetProviders { key } => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::GET_PROVIDERS);
msg.set_key(key.to_vec());
msg.set_clusterLevelRaw(10);
msg
}
KadRequestMsg::AddProvider { key, provider } => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::ADD_PROVIDER);
msg.set_clusterLevelRaw(10);
msg.set_key(key.to_vec());
msg.mut_providerPeers().push(provider.into());
msg
}
KadRequestMsg::GetValue { key } => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::GET_VALUE);
msg.set_clusterLevelRaw(10);
msg.set_key(key.to_vec());
msg
}
KadRequestMsg::PutValue { record } => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::PUT_VALUE);
msg.set_record(record_to_proto(record));
msg
KadRequestMsg::Ping => proto::Message {
r#type: proto::message::MessageType::Ping as i32,
.. proto::Message::default()
},
KadRequestMsg::FindNode { key } => proto::Message {
r#type: proto::message::MessageType::FindNode as i32,
key,
cluster_level_raw: 10,
.. proto::Message::default()
},
KadRequestMsg::GetProviders { key } => proto::Message {
r#type: proto::message::MessageType::GetProviders as i32,
key: key.to_vec(),
cluster_level_raw: 10,
.. proto::Message::default()
},
KadRequestMsg::AddProvider { key, provider } => proto::Message {
r#type: proto::message::MessageType::AddProvider as i32,
cluster_level_raw: 10,
key: key.to_vec(),
provider_peers: vec![provider.into()],
.. proto::Message::default()
},
KadRequestMsg::GetValue { key } => proto::Message {
r#type: proto::message::MessageType::GetValue as i32,
cluster_level_raw: 10,
key: key.to_vec(),
.. proto::Message::default()
},
KadRequestMsg::PutValue { record } => proto::Message {
r#type: proto::message::MessageType::PutValue as i32,
record: Some(record_to_proto(record)),
.. proto::Message::default()
}
}
}
@ -380,65 +372,39 @@ fn req_msg_to_proto(kad_msg: KadRequestMsg) -> proto::Message {
/// Converts a `KadResponseMsg` into the corresponding protobuf message for sending.
fn resp_msg_to_proto(kad_msg: KadResponseMsg) -> proto::Message {
match kad_msg {
KadResponseMsg::Pong => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::PING);
msg
}
KadResponseMsg::FindNode { closer_peers } => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::FIND_NODE);
msg.set_clusterLevelRaw(9);
for peer in closer_peers {
msg.mut_closerPeers().push(peer.into());
}
msg
}
KadResponseMsg::GetProviders {
closer_peers,
provider_peers,
} => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::GET_PROVIDERS);
msg.set_clusterLevelRaw(9);
for peer in closer_peers {
msg.mut_closerPeers().push(peer.into());
}
for peer in provider_peers {
msg.mut_providerPeers().push(peer.into());
}
msg
}
KadResponseMsg::GetValue {
record,
closer_peers,
} => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::GET_VALUE);
msg.set_clusterLevelRaw(9);
for peer in closer_peers {
msg.mut_closerPeers().push(peer.into());
}
if let Some(record) = record {
msg.set_record(record_to_proto(record));
}
msg
}
KadResponseMsg::PutValue {
key,
KadResponseMsg::Pong => proto::Message {
r#type: proto::message::MessageType::Ping as i32,
.. proto::Message::default()
},
KadResponseMsg::FindNode { closer_peers } => proto::Message {
r#type: proto::message::MessageType::FindNode as i32,
cluster_level_raw: 9,
closer_peers: closer_peers.into_iter().map(KadPeer::into).collect(),
.. proto::Message::default()
},
KadResponseMsg::GetProviders { closer_peers, provider_peers } => proto::Message {
r#type: proto::message::MessageType::GetProviders as i32,
cluster_level_raw: 9,
closer_peers: closer_peers.into_iter().map(KadPeer::into).collect(),
provider_peers: provider_peers.into_iter().map(KadPeer::into).collect(),
.. proto::Message::default()
},
KadResponseMsg::GetValue { record, closer_peers } => proto::Message {
r#type: proto::message::MessageType::GetValue as i32,
cluster_level_raw: 9,
closer_peers: closer_peers.into_iter().map(KadPeer::into).collect(),
record: record.map(record_to_proto),
.. proto::Message::default()
},
KadResponseMsg::PutValue { key, value } => proto::Message {
r#type: proto::message::MessageType::PutValue as i32,
key: key.to_vec(),
record: Some(proto::Record {
key: key.to_vec(),
value,
} => {
let mut msg = proto::Message::new();
msg.set_field_type(proto::Message_MessageType::PUT_VALUE);
msg.set_key(key.to_vec());
let mut record = proto::Record::new();
record.set_key(key.to_vec());
record.set_value(value);
msg.set_record(record);
msg
.. proto::Record::default()
}),
.. proto::Message::default()
}
}
}
@ -446,44 +412,38 @@ fn resp_msg_to_proto(kad_msg: KadResponseMsg) -> proto::Message {
/// Converts a received protobuf message into a corresponding `KadRequestMsg`.
///
/// Fails if the protobuf message is not a valid and supported Kademlia request message.
fn proto_to_req_msg(mut message: proto::Message) -> Result<KadRequestMsg, io::Error> {
match message.get_field_type() {
proto::Message_MessageType::PING => Ok(KadRequestMsg::Ping),
fn proto_to_req_msg(message: proto::Message) -> Result<KadRequestMsg, io::Error> {
let msg_type = proto::message::MessageType::from_i32(message.r#type)
.ok_or_else(|| invalid_data(format!("unknown message type: {}", message.r#type)))?;
proto::Message_MessageType::PUT_VALUE => {
let record = record_from_proto(message.take_record())?;
match msg_type {
proto::message::MessageType::Ping => Ok(KadRequestMsg::Ping),
proto::message::MessageType::PutValue => {
let record = record_from_proto(message.record.unwrap_or_default())?;
Ok(KadRequestMsg::PutValue { record })
}
proto::Message_MessageType::GET_VALUE => {
let key = record::Key::from(message.take_key());
Ok(KadRequestMsg::GetValue { key })
proto::message::MessageType::GetValue => {
Ok(KadRequestMsg::GetValue { key: record::Key::from(message.key) })
}
proto::Message_MessageType::FIND_NODE => {
let key = message.take_key();
Ok(KadRequestMsg::FindNode { key })
proto::message::MessageType::FindNode => {
Ok(KadRequestMsg::FindNode { key: message.key })
}
proto::Message_MessageType::GET_PROVIDERS => {
let key = record::Key::from(message.take_key());
Ok(KadRequestMsg::GetProviders { key })
proto::message::MessageType::GetProviders => {
Ok(KadRequestMsg::GetProviders { key: record::Key::from(message.key)})
}
proto::Message_MessageType::ADD_PROVIDER => {
proto::message::MessageType::AddProvider => {
// TODO: for now we don't parse the peer properly, so it is possible that we get
// parsing errors for peers even when they are valid; we ignore these
// errors for now, but ultimately we should just error altogether
let provider = message
.mut_providerPeers()
.iter_mut()
let provider = message.provider_peers
.into_iter()
.find_map(|peer| KadPeer::try_from(peer).ok());
if let Some(provider) = provider {
let key = record::Key::from(message.take_key());
let key = record::Key::from(message.key);
Ok(KadRequestMsg::AddProvider { key, provider })
} else {
Err(invalid_data("ADD_PROVIDER message with no valid peer."))
Err(invalid_data("AddProvider message with no valid peer."))
}
}
}
@ -492,49 +452,43 @@ fn proto_to_req_msg(mut message: proto::Message) -> Result<KadRequestMsg, io::Er
/// Converts a received protobuf message into a corresponding `KadResponseMessage`.
///
/// Fails if the protobuf message is not a valid and supported Kademlia response message.
fn proto_to_resp_msg(mut message: proto::Message) -> Result<KadResponseMsg, io::Error> {
match message.get_field_type() {
proto::Message_MessageType::PING => Ok(KadResponseMsg::Pong),
fn proto_to_resp_msg(message: proto::Message) -> Result<KadResponseMsg, io::Error> {
let msg_type = proto::message::MessageType::from_i32(message.r#type)
.ok_or_else(|| invalid_data(format!("unknown message type: {}", message.r#type)))?;
proto::Message_MessageType::GET_VALUE => {
match msg_type {
proto::message::MessageType::Ping => Ok(KadResponseMsg::Pong),
proto::message::MessageType::GetValue => {
let record =
if message.has_record() {
Some(record_from_proto(message.take_record())?)
if let Some(r) = message.record {
Some(record_from_proto(r)?)
} else {
None
};
let closer_peers = message
.mut_closerPeers()
.iter_mut()
let closer_peers = message.closer_peers.into_iter()
.filter_map(|peer| KadPeer::try_from(peer).ok())
.collect::<Vec<_>>();
.collect();
Ok(KadResponseMsg::GetValue { record, closer_peers })
},
}
proto::Message_MessageType::FIND_NODE => {
let closer_peers = message
.mut_closerPeers()
.iter_mut()
proto::message::MessageType::FindNode => {
let closer_peers = message.closer_peers.into_iter()
.filter_map(|peer| KadPeer::try_from(peer).ok())
.collect::<Vec<_>>();
.collect();
Ok(KadResponseMsg::FindNode { closer_peers })
}
proto::Message_MessageType::GET_PROVIDERS => {
let closer_peers = message
.mut_closerPeers()
.iter_mut()
proto::message::MessageType::GetProviders => {
let closer_peers = message.closer_peers.into_iter()
.filter_map(|peer| KadPeer::try_from(peer).ok())
.collect::<Vec<_>>();
.collect();
let provider_peers = message
.mut_providerPeers()
.iter_mut()
let provider_peers = message.provider_peers.into_iter()
.filter_map(|peer| KadPeer::try_from(peer).ok())
.collect::<Vec<_>>();
.collect();
Ok(KadResponseMsg::GetProviders {
closer_peers,
@ -542,31 +496,30 @@ fn proto_to_resp_msg(mut message: proto::Message) -> Result<KadResponseMsg, io::
})
}
proto::Message_MessageType::PUT_VALUE => {
let key = record::Key::from(message.take_key());
if !message.has_record() {
return Err(invalid_data("received PUT_VALUE message with no record"));
}
proto::message::MessageType::PutValue => {
let key = record::Key::from(message.key);
let rec = message.record.ok_or_else(|| {
invalid_data("received PutValue message with no record")
})?;
let mut record = message.take_record();
Ok(KadResponseMsg::PutValue {
key,
value: record.take_value(),
value: rec.value
})
}
proto::Message_MessageType::ADD_PROVIDER =>
Err(invalid_data("received an unexpected ADD_PROVIDER message"))
proto::message::MessageType::AddProvider =>
Err(invalid_data("received an unexpected AddProvider message"))
}
}
fn record_from_proto(mut record: proto::Record) -> Result<Record, io::Error> {
let key = record::Key::from(record.take_key());
let value = record.take_value();
fn record_from_proto(record: proto::Record) -> Result<Record, io::Error> {
let key = record::Key::from(record.key);
let value = record.value;
let publisher =
if record.publisher.len() > 0 {
PeerId::from_bytes(record.take_publisher())
if !record.publisher.is_empty() {
PeerId::from_bytes(record.publisher)
.map(Some)
.map_err(|_| invalid_data("Invalid publisher peer ID."))?
} else {
@ -584,22 +537,22 @@ fn record_from_proto(mut record: proto::Record) -> Result<Record, io::Error> {
}
fn record_to_proto(record: Record) -> proto::Record {
let mut pb_record = proto::Record::new();
pb_record.key = record.key.to_vec();
pb_record.value = record.value;
if let Some(p) = record.publisher {
pb_record.publisher = p.into_bytes();
}
if let Some(t) = record.expires {
proto::Record {
key: record.key.to_vec(),
value: record.value,
publisher: record.publisher.map(PeerId::into_bytes).unwrap_or_default(),
ttl: record.expires
.map(|t| {
let now = Instant::now();
if t > now {
pb_record.ttl = (t - now).as_secs() as u32;
(t - now).as_secs() as u32
} else {
pb_record.ttl = 1; // because 0 means "does not expire"
1 // because 0 means "does not expire"
}
})
.unwrap_or(0),
time_received: String::new()
}
pb_record
}
/// Creates an `io::Error` with `io::ErrorKind::InvalidData`.

View File

@ -13,7 +13,7 @@ futures = "0.3.1"
lazy_static = "1.2"
libp2p-core = { version = "0.14.0-alpha.1", path = "../../core" }
log = "0.4"
protobuf = "=2.8.1" # note: see https://github.com/libp2p/rust-libp2p/issues/1363
prost = "0.6"
rand = "0.7.2"
ring = { version = "0.16.9", features = ["alloc"], default-features = false }
snow = { version = "0.6.1", features = ["ring-resolver"], default-features = false }
@ -25,3 +25,7 @@ env_logger = "0.7.1"
libp2p-tcp = { version = "0.14.0-alpha.1", path = "../../transports/tcp" }
quickcheck = "0.9.0"
sodiumoxide = "^0.2.5"
[build-dependencies]
prost-build = "0.6"

23
protocols/noise/build.rs Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
fn main() {
prost_build::compile_protos(&["src/io/handshake/payload.proto"], &["src"]).unwrap();
}

View File

@ -1,3 +0,0 @@
#!/bin/sh
../../scripts/protobuf/gen.sh ./src/io/handshake/payload.proto

View File

@ -35,7 +35,7 @@ pub enum NoiseError {
/// upgrade failed.
AuthenticationFailed,
/// A handshake payload is invalid.
InvalidPayload(protobuf::ProtobufError),
InvalidPayload(prost::DecodeError),
/// A signature was required and could not be created.
SigningError(identity::error::SigningError),
#[doc(hidden)]
@ -82,8 +82,8 @@ impl From<SnowError> for NoiseError {
}
}
impl From<protobuf::ProtobufError> for NoiseError {
fn from(e: protobuf::ProtobufError) -> Self {
impl From<prost::DecodeError> for NoiseError {
fn from(e: prost::DecodeError) -> Self {
NoiseError::InvalidPayload(e)
}
}

View File

@ -20,7 +20,9 @@
//! Noise protocol handshake I/O.
mod payload_proto;
mod payload_proto {
include!(concat!(env!("OUT_DIR"), "/payload.proto.rs"));
}
use crate::error::NoiseError;
use crate::protocol::{Protocol, PublicKey, KeypairIdentity};
@ -29,7 +31,7 @@ use libp2p_core::identity;
use futures::prelude::*;
use futures::task;
use futures::io::AsyncReadExt;
use protobuf::Message;
use prost::Message;
use std::{pin::Pin, task::Context};
use super::NoiseOutput;
@ -363,10 +365,10 @@ where
let mut payload_buf = vec![0; len];
state.io.read_exact(&mut payload_buf).await?;
let pb: payload_proto::Identity = protobuf::parse_from_bytes(&payload_buf)?;
let pb = payload_proto::Identity::decode(&payload_buf[..])?;
if !pb.pubkey.is_empty() {
let pk = identity::PublicKey::from_protobuf_encoding(pb.get_pubkey())
let pk = identity::PublicKey::from_protobuf_encoding(&pb.pubkey)
.map_err(|_| NoiseError::InvalidKey)?;
if let Some(ref k) = state.id_remote_pubkey {
if k != &pk {
@ -387,17 +389,18 @@ async fn send_identity<T>(state: &mut State<T>) -> Result<(), NoiseError>
where
T: AsyncWrite + Unpin,
{
let mut pb = payload_proto::Identity::new();
let mut pb = payload_proto::Identity::default();
if state.send_identity {
pb.set_pubkey(state.identity.public.clone().into_protobuf_encoding());
pb.pubkey = state.identity.public.clone().into_protobuf_encoding()
}
if let Some(ref sig) = state.identity.signature {
pb.set_signature(sig.clone());
pb.signature = sig.clone()
}
let pb_bytes = pb.write_to_bytes()?;
let len = (pb_bytes.len() as u16).to_be_bytes();
let mut buf = Vec::with_capacity(pb.encoded_len());
pb.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
let len = (buf.len() as u16).to_be_bytes();
state.io.write_all(&len).await?;
state.io.write_all(&pb_bytes).await?;
state.io.write_all(&buf).await?;
state.io.flush().await?;
Ok(())
}

View File

@ -1,5 +1,7 @@
syntax = "proto3";
package payload.proto;
// Payloads for Noise handshake messages.
message Identity {

View File

@ -1,271 +0,0 @@
// This file is generated by rust-protobuf 2.8.1. Do not edit
// @generated
// https://github.com/Manishearth/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy::all)]
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(box_pointers)]
#![allow(dead_code)]
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(trivial_casts)]
#![allow(unsafe_code)]
#![allow(unused_imports)]
#![allow(unused_results)]
//! Generated file from `src/io/handshake/payload.proto`
use protobuf::Message as Message_imported_for_functions;
use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
/// Generated files are compatible only with the same version
/// of protobuf runtime.
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_8_1;
#[derive(PartialEq,Clone,Default)]
pub struct Identity {
// message fields
pub pubkey: ::std::vec::Vec<u8>,
pub signature: ::std::vec::Vec<u8>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a Identity {
fn default() -> &'a Identity {
<Identity as ::protobuf::Message>::default_instance()
}
}
impl Identity {
pub fn new() -> Identity {
::std::default::Default::default()
}
// bytes pubkey = 1;
pub fn get_pubkey(&self) -> &[u8] {
&self.pubkey
}
pub fn clear_pubkey(&mut self) {
self.pubkey.clear();
}
// Param is passed by value, moved
pub fn set_pubkey(&mut self, v: ::std::vec::Vec<u8>) {
self.pubkey = v;
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_pubkey(&mut self) -> &mut ::std::vec::Vec<u8> {
&mut self.pubkey
}
// Take field
pub fn take_pubkey(&mut self) -> ::std::vec::Vec<u8> {
::std::mem::replace(&mut self.pubkey, ::std::vec::Vec::new())
}
// bytes signature = 2;
pub fn get_signature(&self) -> &[u8] {
&self.signature
}
pub fn clear_signature(&mut self) {
self.signature.clear();
}
// Param is passed by value, moved
pub fn set_signature(&mut self, v: ::std::vec::Vec<u8>) {
self.signature = v;
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_signature(&mut self) -> &mut ::std::vec::Vec<u8> {
&mut self.signature
}
// Take field
pub fn take_signature(&mut self) -> ::std::vec::Vec<u8> {
::std::mem::replace(&mut self.signature, ::std::vec::Vec::new())
}
}
impl ::protobuf::Message for Identity {
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
while !is.eof()? {
let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number {
1 => {
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.pubkey)?;
},
2 => {
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.signature)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
if !self.pubkey.is_empty() {
my_size += ::protobuf::rt::bytes_size(1, &self.pubkey);
}
if !self.signature.is_empty() {
my_size += ::protobuf::rt::bytes_size(2, &self.signature);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
if !self.pubkey.is_empty() {
os.write_bytes(1, &self.pubkey)?;
}
if !self.signature.is_empty() {
os.write_bytes(2, &self.signature)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn as_any(&self) -> &dyn (::std::any::Any) {
self as &dyn (::std::any::Any)
}
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
self as &mut dyn (::std::any::Any)
}
fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
self
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
Self::descriptor_static()
}
fn new() -> Identity {
Identity::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"pubkey",
|m: &Identity| { &m.pubkey },
|m: &mut Identity| { &mut m.pubkey },
));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"signature",
|m: &Identity| { &m.signature },
|m: &mut Identity| { &mut m.signature },
));
::protobuf::reflect::MessageDescriptor::new::<Identity>(
"Identity",
fields,
file_descriptor_proto()
)
})
}
}
fn default_instance() -> &'static Identity {
static mut instance: ::protobuf::lazy::Lazy<Identity> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const Identity,
};
unsafe {
instance.get(Identity::new)
}
}
}
impl ::protobuf::Clear for Identity {
fn clear(&mut self) {
self.pubkey.clear();
self.signature.clear();
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for Identity {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for Identity {
fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
::protobuf::reflect::ProtobufValueRef::Message(self)
}
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x1esrc/io/handshake/payload.proto\"@\n\x08Identity\x12\x16\n\x06pubke\
y\x18\x01\x20\x01(\x0cR\x06pubkey\x12\x1c\n\tsignature\x18\x02\x20\x01(\
\x0cR\tsignatureJ\xe0\x01\n\x06\x12\x04\0\0\x07\x01\n\x08\n\x01\x0c\x12\
\x03\0\0\x12\n4\n\x02\x04\0\x12\x04\x04\0\x07\x012(\x20Payloads\x20for\
\x20Noise\x20handshake\x20messages.\n\n\n\n\x03\x04\0\x01\x12\x03\x04\
\x08\x10\n\x0b\n\x04\x04\0\x02\0\x12\x03\x05\x08\x19\n\r\n\x05\x04\0\x02\
\0\x04\x12\x04\x05\x08\x04\x12\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x05\
\x08\r\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x05\x0e\x14\n\x0c\n\x05\x04\0\
\x02\0\x03\x12\x03\x05\x17\x18\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x06\x08\
\x1c\n\r\n\x05\x04\0\x02\x01\x04\x12\x04\x06\x08\x05\x19\n\x0c\n\x05\x04\
\0\x02\x01\x05\x12\x03\x06\x08\r\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\
\x06\x0e\x17\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x06\x1a\x1bb\x06proto\
3\
";
static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
};
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
}
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
unsafe {
file_descriptor_proto_lazy.get(|| {
parse_descriptor_proto()
})
}
}

View File

@ -15,7 +15,7 @@ futures = "0.3.1"
futures_codec = "0.3.4"
libp2p-core = { version = "0.14.0-alpha.1", path = "../../core" }
log = "0.4.8"
protobuf = "=2.8.1" # note: see https://github.com/libp2p/rust-libp2p/issues/1363
prost = "0.6"
rw-stream-sink = { version = "0.2.0", path = "../../misc/rw-stream-sink" }
unsigned-varint = { version = "0.3", features = ["futures-codec"] }
void = "1.0.2"
@ -24,3 +24,7 @@ void = "1.0.2"
env_logger = "0.7.1"
quickcheck = "0.9.0"
rand = "0.7"
[build-dependencies]
prost-build = "0.6"

View File

@ -0,0 +1,24 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
fn main() {
prost_build::compile_protos(&["src/structs.proto"], &["src"]).unwrap();
}

View File

@ -1,4 +0,0 @@
#!/bin/sh
../../scripts/protobuf/gen.sh ./src/structs.proto

View File

@ -21,7 +21,6 @@
use std::error;
use std::fmt;
use std::io::Error as IoError;
use protobuf::error::ProtobufError;
#[derive(Debug)]
pub enum PlainTextError {
@ -29,7 +28,7 @@ pub enum PlainTextError {
IoError(IoError),
/// Failed to parse the handshake protobuf message.
InvalidPayload(Option<ProtobufError>),
InvalidPayload(Option<prost::DecodeError>),
/// The peer id of the exchange isn't consistent with the remote public key.
InvalidPeerId,
@ -68,8 +67,8 @@ impl From<IoError> for PlainTextError {
}
}
impl From<ProtobufError> for PlainTextError {
fn from(err: ProtobufError) -> PlainTextError {
impl From<prost::DecodeError> for PlainTextError {
fn from(err: prost::DecodeError) -> PlainTextError {
PlainTextError::InvalidPayload(Some(err))
}
}

View File

@ -27,7 +27,7 @@ use futures::prelude::*;
use futures_codec::Framed;
use libp2p_core::{PublicKey, PeerId};
use log::{debug, trace};
use protobuf::Message;
use prost::Message;
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
use unsigned_varint::codec::UviBytes;
@ -52,15 +52,17 @@ pub struct Remote {
impl HandshakeContext<Local> {
fn new(config: PlainText2Config) -> Result<Self, PlainTextError> {
let mut exchange = Exchange::new();
exchange.set_id(config.local_public_key.clone().into_peer_id().into_bytes());
exchange.set_pubkey(config.local_public_key.clone().into_protobuf_encoding());
let exchange_bytes = exchange.write_to_bytes()?;
let exchange = Exchange {
id: Some(config.local_public_key.clone().into_peer_id().into_bytes()),
pubkey: Some(config.local_public_key.clone().into_protobuf_encoding())
};
let mut buf = Vec::with_capacity(exchange.encoded_len());
exchange.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
Ok(Self {
config,
state: Local {
exchange_bytes
exchange_bytes: buf
}
})
}
@ -68,7 +70,7 @@ impl HandshakeContext<Local> {
fn with_remote(self, exchange_bytes: BytesMut)
-> Result<HandshakeContext<Remote>, PlainTextError>
{
let mut prop = match protobuf::parse_from_bytes::<Exchange>(&exchange_bytes) {
let prop = match Exchange::decode(exchange_bytes) {
Ok(prop) => prop,
Err(e) => {
debug!("failed to parse remote's exchange protobuf message");
@ -76,7 +78,7 @@ impl HandshakeContext<Local> {
},
};
let pb_pubkey = prop.take_pubkey();
let pb_pubkey = prop.pubkey.unwrap_or_default();
let public_key = match PublicKey::from_protobuf_encoding(pb_pubkey.as_slice()) {
Ok(p) => p,
Err(_) => {
@ -84,7 +86,7 @@ impl HandshakeContext<Local> {
return Err(PlainTextError::InvalidPayload(None));
},
};
let peer_id = match PeerId::from_bytes(prop.take_id()) {
let peer_id = match PeerId::from_bytes(prop.id.unwrap_or_default()) {
Ok(p) => p,
Err(_) => {
debug!("failed to parse remote's exchange's id protobuf");

View File

@ -42,7 +42,10 @@ use void::Void;
mod error;
mod handshake;
mod structs_proto;
mod structs_proto {
include!(concat!(env!("OUT_DIR"), "/structs.rs"));
}
/// `PlainText1Config` is an insecure connection handshake for testing purposes only.
///

View File

@ -1,5 +1,7 @@
syntax = "proto2";
package structs;
message Exchange {
optional bytes id = 1;
optional bytes pubkey = 2;

View File

@ -1,289 +0,0 @@
// This file is generated by rust-protobuf 2.8.1. Do not edit
// @generated
// https://github.com/Manishearth/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy::all)]
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(box_pointers)]
#![allow(dead_code)]
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(trivial_casts)]
#![allow(unsafe_code)]
#![allow(unused_imports)]
#![allow(unused_results)]
//! Generated file from `src/structs.proto`
use protobuf::Message as Message_imported_for_functions;
use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
/// Generated files are compatible only with the same version
/// of protobuf runtime.
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_8_1;
#[derive(PartialEq,Clone,Default)]
pub struct Exchange {
// message fields
id: ::protobuf::SingularField<::std::vec::Vec<u8>>,
pubkey: ::protobuf::SingularField<::std::vec::Vec<u8>>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a Exchange {
fn default() -> &'a Exchange {
<Exchange as ::protobuf::Message>::default_instance()
}
}
impl Exchange {
pub fn new() -> Exchange {
::std::default::Default::default()
}
// optional bytes id = 1;
pub fn get_id(&self) -> &[u8] {
match self.id.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_id(&mut self) {
self.id.clear();
}
pub fn has_id(&self) -> bool {
self.id.is_some()
}
// Param is passed by value, moved
pub fn set_id(&mut self, v: ::std::vec::Vec<u8>) {
self.id = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_id(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.id.is_none() {
self.id.set_default();
}
self.id.as_mut().unwrap()
}
// Take field
pub fn take_id(&mut self) -> ::std::vec::Vec<u8> {
self.id.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
// optional bytes pubkey = 2;
pub fn get_pubkey(&self) -> &[u8] {
match self.pubkey.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_pubkey(&mut self) {
self.pubkey.clear();
}
pub fn has_pubkey(&self) -> bool {
self.pubkey.is_some()
}
// Param is passed by value, moved
pub fn set_pubkey(&mut self, v: ::std::vec::Vec<u8>) {
self.pubkey = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_pubkey(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.pubkey.is_none() {
self.pubkey.set_default();
}
self.pubkey.as_mut().unwrap()
}
// Take field
pub fn take_pubkey(&mut self) -> ::std::vec::Vec<u8> {
self.pubkey.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
}
impl ::protobuf::Message for Exchange {
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
while !is.eof()? {
let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number {
1 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.id)?;
},
2 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.pubkey)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
if let Some(ref v) = self.id.as_ref() {
my_size += ::protobuf::rt::bytes_size(1, &v);
}
if let Some(ref v) = self.pubkey.as_ref() {
my_size += ::protobuf::rt::bytes_size(2, &v);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
if let Some(ref v) = self.id.as_ref() {
os.write_bytes(1, &v)?;
}
if let Some(ref v) = self.pubkey.as_ref() {
os.write_bytes(2, &v)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn as_any(&self) -> &dyn (::std::any::Any) {
self as &dyn (::std::any::Any)
}
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
self as &mut dyn (::std::any::Any)
}
fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
self
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
Self::descriptor_static()
}
fn new() -> Exchange {
Exchange::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"id",
|m: &Exchange| { &m.id },
|m: &mut Exchange| { &mut m.id },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"pubkey",
|m: &Exchange| { &m.pubkey },
|m: &mut Exchange| { &mut m.pubkey },
));
::protobuf::reflect::MessageDescriptor::new::<Exchange>(
"Exchange",
fields,
file_descriptor_proto()
)
})
}
}
fn default_instance() -> &'static Exchange {
static mut instance: ::protobuf::lazy::Lazy<Exchange> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const Exchange,
};
unsafe {
instance.get(Exchange::new)
}
}
}
impl ::protobuf::Clear for Exchange {
fn clear(&mut self) {
self.id.clear();
self.pubkey.clear();
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for Exchange {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for Exchange {
fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
::protobuf::reflect::ProtobufValueRef::Message(self)
}
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x11src/structs.proto\"2\n\x08Exchange\x12\x0e\n\x02id\x18\x01\x20\x01\
(\x0cR\x02id\x12\x16\n\x06pubkey\x18\x02\x20\x01(\x0cR\x06pubkeyJ\xb4\
\x01\n\x06\x12\x04\0\0\x05\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x10\n\
\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x02\x18\n\x0c\n\x05\x04\0\x02\0\x04\
\x12\x03\x03\x02\n\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x0b\x10\n\x0c\
\n\x05\x04\0\x02\0\x01\x12\x03\x03\x11\x13\n\x0c\n\x05\x04\0\x02\0\x03\
\x12\x03\x03\x16\x17\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x02\x1c\n\x0c\
\n\x05\x04\0\x02\x01\x04\x12\x03\x04\x02\n\n\x0c\n\x05\x04\0\x02\x01\x05\
\x12\x03\x04\x0b\x10\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x11\x17\n\
\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x1a\x1b\
";
static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
};
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
}
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
unsafe {
file_descriptor_proto_lazy.get(|| {
parse_descriptor_proto()
})
}
}

View File

@ -18,8 +18,8 @@ hmac = "0.7.0"
lazy_static = "1.2.0"
libp2p-core = { version = "0.14.0-alpha.1", path = "../../core" }
log = "0.4.6"
prost = "0.6"
pin-project = "0.4.6"
protobuf = "=2.8.1" # note: see https://github.com/libp2p/rust-libp2p/issues/1363
quicksink = "0.1"
rand = "0.7"
rw-stream-sink = { version = "0.2.0", path = "../../misc/rw-stream-sink" }
@ -37,6 +37,9 @@ wasm-bindgen = "0.2.33"
wasm-bindgen-futures = "0.4.5"
web-sys = { version = "0.3.10", features = ["Crypto", "CryptoKey", "SubtleCrypto", "Window"] }
[build-dependencies]
prost-build = "0.6"
[features]
default = ["secp256k1"]
secp256k1 = []

24
protocols/secio/build.rs Normal file
View File

@ -0,0 +1,24 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
fn main() {
prost_build::compile_protos(&["src/structs.proto"], &["src"]).unwrap();
}

View File

@ -1,3 +0,0 @@
#!/bin/sh
../../scripts/protobuf/gen.sh src/structs.proto

View File

@ -21,7 +21,6 @@
//! Defines the `SecioError` enum that groups all possible errors in SECIO.
use aes_ctr::stream_cipher::LoopError;
use protobuf::error::ProtobufError;
use std::error;
use std::fmt;
use std::io::Error as IoError;
@ -33,7 +32,7 @@ pub enum SecioError {
IoError(IoError),
/// Protocol buffer error.
ProtobufError(ProtobufError),
ProtobufError(prost::DecodeError),
/// Failed to parse one of the handshake protobuf messages.
HandshakeParsingFailure,
@ -90,7 +89,6 @@ impl error::Error for SecioError {
}
impl fmt::Display for SecioError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self {
SecioError::IoError(e) =>
@ -128,22 +126,19 @@ impl fmt::Display for SecioError {
}
impl From<LoopError> for SecioError {
#[inline]
fn from(err: LoopError) -> SecioError {
SecioError::CipherError(err)
}
}
impl From<IoError> for SecioError {
#[inline]
fn from(err: IoError) -> SecioError {
SecioError::IoError(err)
}
}
impl From<ProtobufError> for SecioError {
#[inline]
fn from(err: ProtobufError) -> SecioError {
impl From<prost::DecodeError> for SecioError {
fn from(err: prost::DecodeError) -> SecioError {
SecioError::ProtobufError(err)
}
}

View File

@ -28,8 +28,7 @@ use crate::structs_proto::{Exchange, Propose};
use futures::prelude::*;
use libp2p_core::PublicKey;
use log::{debug, trace};
use protobuf::Message as ProtobufMessage;
use protobuf::parse_from_bytes as protobuf_parse_from_bytes;
use prost::Message;
use rand::{self, RngCore};
use sha2::{Digest as ShaDigestTrait, Sha256};
use std::cmp::{self, Ordering};
@ -63,35 +62,36 @@ where
let local_public_key_encoded = config.key.public().into_protobuf_encoding();
// Send our proposition with our nonce, public key and supported protocols.
let mut local_proposition = Propose::new();
local_proposition.set_rand(local_nonce.to_vec());
local_proposition.set_pubkey(local_public_key_encoded.clone());
if let Some(ref p) = config.agreements_prop {
let local_proposition = Propose {
rand: Some(local_nonce.to_vec()),
pubkey: Some(local_public_key_encoded.clone()),
exchanges: if let Some(ref p) = config.agreements_prop {
trace!("agreements proposition: {}", p);
local_proposition.set_exchanges(p.clone())
Some(p.clone())
} else {
trace!("agreements proposition: {}", algo_support::DEFAULT_AGREEMENTS_PROPOSITION);
local_proposition.set_exchanges(algo_support::DEFAULT_AGREEMENTS_PROPOSITION.into())
}
if let Some(ref p) = config.ciphers_prop {
Some(algo_support::DEFAULT_AGREEMENTS_PROPOSITION.into())
},
ciphers: if let Some(ref p) = config.ciphers_prop {
trace!("ciphers proposition: {}", p);
local_proposition.set_ciphers(p.clone())
Some(p.clone())
} else {
trace!("ciphers proposition: {}", algo_support::DEFAULT_CIPHERS_PROPOSITION);
local_proposition.set_ciphers(algo_support::DEFAULT_CIPHERS_PROPOSITION.into())
}
if let Some(ref p) = config.digests_prop {
Some(algo_support::DEFAULT_CIPHERS_PROPOSITION.into())
},
hashes: if let Some(ref p) = config.digests_prop {
trace!("digests proposition: {}", p);
local_proposition.set_hashes(p.clone())
Some(p.clone())
} else {
trace!("digests proposition: {}", algo_support::DEFAULT_DIGESTS_PROPOSITION);
local_proposition.set_hashes(algo_support::DEFAULT_DIGESTS_PROPOSITION.into())
Some(algo_support::DEFAULT_DIGESTS_PROPOSITION.into())
}
};
let local_proposition_bytes = local_proposition.write_to_bytes()?;
let local_proposition_bytes = {
let mut buf = Vec::with_capacity(local_proposition.encoded_len());
local_proposition.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
buf
};
trace!("starting handshake; local nonce = {:?}", local_nonce);
trace!("sending proposition to remote");
@ -107,7 +107,7 @@ where
},
};
let mut remote_proposition = match protobuf_parse_from_bytes::<Propose>(&remote_proposition_bytes) {
let remote_proposition = match Propose::decode(&remote_proposition_bytes[..]) {
Ok(prop) => prop,
Err(_) => {
debug!("failed to parse remote's proposition protobuf message");
@ -115,8 +115,8 @@ where
}
};
let remote_public_key_encoded = remote_proposition.take_pubkey();
let remote_nonce = remote_proposition.take_rand();
let remote_public_key_encoded = remote_proposition.pubkey.unwrap_or_default();
let remote_nonce = remote_proposition.rand.unwrap_or_default();
let remote_public_key = match PublicKey::from_protobuf_encoding(&remote_public_key_encoded) {
Ok(p) => p,
@ -152,7 +152,7 @@ where
let ours = config.agreements_prop.as_ref()
.map(|s| s.as_ref())
.unwrap_or(algo_support::DEFAULT_AGREEMENTS_PROPOSITION);
let theirs = &remote_proposition.get_exchanges();
let theirs = &remote_proposition.exchanges.unwrap_or_default();
match algo_support::select_agreement(hashes_ordering, ours, theirs) {
Ok(a) => a,
Err(err) => {
@ -166,7 +166,7 @@ where
let ours = config.ciphers_prop.as_ref()
.map(|s| s.as_ref())
.unwrap_or(algo_support::DEFAULT_CIPHERS_PROPOSITION);
let theirs = &remote_proposition.get_ciphers();
let theirs = &remote_proposition.ciphers.unwrap_or_default();
match algo_support::select_cipher(hashes_ordering, ours, theirs) {
Ok(a) => {
debug!("selected cipher: {:?}", a);
@ -183,7 +183,7 @@ where
let ours = config.digests_prop.as_ref()
.map(|s| s.as_ref())
.unwrap_or(algo_support::DEFAULT_DIGESTS_PROPOSITION);
let theirs = &remote_proposition.get_hashes();
let theirs = &remote_proposition.hashes.unwrap_or_default();
match algo_support::select_digest(hashes_ordering, ours, theirs) {
Ok(a) => {
debug!("selected hash: {:?}", a);
@ -206,15 +206,19 @@ where
data_to_sign.extend_from_slice(&remote_proposition_bytes);
data_to_sign.extend_from_slice(&tmp_pub_key);
let mut exchange = Exchange::new();
exchange.set_epubkey(tmp_pub_key.clone());
match config.key.sign(&data_to_sign) {
Ok(sig) => exchange.set_signature(sig),
Exchange {
epubkey: Some(tmp_pub_key.clone()),
signature: match config.key.sign(&data_to_sign) {
Ok(sig) => Some(sig),
Err(_) => return Err(SecioError::SigningFailure)
}
exchange
}
};
let local_exch = {
let mut buf = Vec::with_capacity(local_exchange.encoded_len());
local_exchange.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
buf
};
let local_exch = local_exchange.write_to_bytes()?;
// Send our local `Exchange`.
trace!("sending exchange to remote");
@ -231,7 +235,7 @@ where
},
};
match protobuf_parse_from_bytes::<Exchange>(&raw) {
match Exchange::decode(&raw[..]) {
Ok(e) => {
trace!("received and decoded the remote's exchange");
e
@ -249,9 +253,9 @@ where
{
let mut data_to_verify = remote_proposition_bytes.clone();
data_to_verify.extend_from_slice(&local_proposition_bytes);
data_to_verify.extend_from_slice(remote_exch.get_epubkey());
data_to_verify.extend_from_slice(remote_exch.epubkey.as_deref().unwrap_or_default());
if !remote_public_key.verify(&data_to_verify, remote_exch.get_signature()) {
if !remote_public_key.verify(&data_to_verify, &remote_exch.signature.unwrap_or_default()) {
return Err(SecioError::SignatureVerificationFailed)
}
@ -260,7 +264,12 @@ where
// Generate a key from the local ephemeral private key and the remote ephemeral public key,
// derive from it a cipher key, an iv, and a hmac key, and build the encoder/decoder.
let key_material = exchange::agree(chosen_exchange, tmp_priv_key, remote_exch.get_epubkey(), chosen_hash.num_bytes()).await?;
let key_material = exchange::agree(
chosen_exchange,
tmp_priv_key,
&remote_exch.epubkey.unwrap_or_default(),
chosen_hash.num_bytes()
).await?;
// Generate a key from the local ephemeral private key and the remote ephemeral public key,
// derive from it a cipher key, an iv, and a hmac key, and build the encoder/decoder.

View File

@ -69,8 +69,9 @@ mod codec;
mod error;
mod exchange;
mod handshake;
// #[allow(rust_2018_idioms)]
mod structs_proto;
mod structs_proto {
include!(concat!(env!("OUT_DIR"), "/spipe.pb.rs"));
}
mod stream_cipher;
pub use crate::algo_support::Digest;

View File

@ -1,699 +0,0 @@
// This file is generated by rust-protobuf 2.8.1. Do not edit
// @generated
// https://github.com/Manishearth/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy::all)]
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(box_pointers)]
#![allow(dead_code)]
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(trivial_casts)]
#![allow(unsafe_code)]
#![allow(unused_imports)]
#![allow(unused_results)]
//! Generated file from `src/structs.proto`
use protobuf::Message as Message_imported_for_functions;
use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
/// Generated files are compatible only with the same version
/// of protobuf runtime.
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_8_1;
#[derive(PartialEq,Clone,Default)]
pub struct Propose {
// message fields
rand: ::protobuf::SingularField<::std::vec::Vec<u8>>,
pubkey: ::protobuf::SingularField<::std::vec::Vec<u8>>,
exchanges: ::protobuf::SingularField<::std::string::String>,
ciphers: ::protobuf::SingularField<::std::string::String>,
hashes: ::protobuf::SingularField<::std::string::String>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a Propose {
fn default() -> &'a Propose {
<Propose as ::protobuf::Message>::default_instance()
}
}
impl Propose {
pub fn new() -> Propose {
::std::default::Default::default()
}
// optional bytes rand = 1;
pub fn get_rand(&self) -> &[u8] {
match self.rand.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_rand(&mut self) {
self.rand.clear();
}
pub fn has_rand(&self) -> bool {
self.rand.is_some()
}
// Param is passed by value, moved
pub fn set_rand(&mut self, v: ::std::vec::Vec<u8>) {
self.rand = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_rand(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.rand.is_none() {
self.rand.set_default();
}
self.rand.as_mut().unwrap()
}
// Take field
pub fn take_rand(&mut self) -> ::std::vec::Vec<u8> {
self.rand.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
// optional bytes pubkey = 2;
pub fn get_pubkey(&self) -> &[u8] {
match self.pubkey.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_pubkey(&mut self) {
self.pubkey.clear();
}
pub fn has_pubkey(&self) -> bool {
self.pubkey.is_some()
}
// Param is passed by value, moved
pub fn set_pubkey(&mut self, v: ::std::vec::Vec<u8>) {
self.pubkey = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_pubkey(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.pubkey.is_none() {
self.pubkey.set_default();
}
self.pubkey.as_mut().unwrap()
}
// Take field
pub fn take_pubkey(&mut self) -> ::std::vec::Vec<u8> {
self.pubkey.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
// optional string exchanges = 3;
pub fn get_exchanges(&self) -> &str {
match self.exchanges.as_ref() {
Some(v) => &v,
None => "",
}
}
pub fn clear_exchanges(&mut self) {
self.exchanges.clear();
}
pub fn has_exchanges(&self) -> bool {
self.exchanges.is_some()
}
// Param is passed by value, moved
pub fn set_exchanges(&mut self, v: ::std::string::String) {
self.exchanges = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_exchanges(&mut self) -> &mut ::std::string::String {
if self.exchanges.is_none() {
self.exchanges.set_default();
}
self.exchanges.as_mut().unwrap()
}
// Take field
pub fn take_exchanges(&mut self) -> ::std::string::String {
self.exchanges.take().unwrap_or_else(|| ::std::string::String::new())
}
// optional string ciphers = 4;
pub fn get_ciphers(&self) -> &str {
match self.ciphers.as_ref() {
Some(v) => &v,
None => "",
}
}
pub fn clear_ciphers(&mut self) {
self.ciphers.clear();
}
pub fn has_ciphers(&self) -> bool {
self.ciphers.is_some()
}
// Param is passed by value, moved
pub fn set_ciphers(&mut self, v: ::std::string::String) {
self.ciphers = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_ciphers(&mut self) -> &mut ::std::string::String {
if self.ciphers.is_none() {
self.ciphers.set_default();
}
self.ciphers.as_mut().unwrap()
}
// Take field
pub fn take_ciphers(&mut self) -> ::std::string::String {
self.ciphers.take().unwrap_or_else(|| ::std::string::String::new())
}
// optional string hashes = 5;
pub fn get_hashes(&self) -> &str {
match self.hashes.as_ref() {
Some(v) => &v,
None => "",
}
}
pub fn clear_hashes(&mut self) {
self.hashes.clear();
}
pub fn has_hashes(&self) -> bool {
self.hashes.is_some()
}
// Param is passed by value, moved
pub fn set_hashes(&mut self, v: ::std::string::String) {
self.hashes = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_hashes(&mut self) -> &mut ::std::string::String {
if self.hashes.is_none() {
self.hashes.set_default();
}
self.hashes.as_mut().unwrap()
}
// Take field
pub fn take_hashes(&mut self) -> ::std::string::String {
self.hashes.take().unwrap_or_else(|| ::std::string::String::new())
}
}
impl ::protobuf::Message for Propose {
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
while !is.eof()? {
let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number {
1 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.rand)?;
},
2 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.pubkey)?;
},
3 => {
::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.exchanges)?;
},
4 => {
::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.ciphers)?;
},
5 => {
::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.hashes)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
if let Some(ref v) = self.rand.as_ref() {
my_size += ::protobuf::rt::bytes_size(1, &v);
}
if let Some(ref v) = self.pubkey.as_ref() {
my_size += ::protobuf::rt::bytes_size(2, &v);
}
if let Some(ref v) = self.exchanges.as_ref() {
my_size += ::protobuf::rt::string_size(3, &v);
}
if let Some(ref v) = self.ciphers.as_ref() {
my_size += ::protobuf::rt::string_size(4, &v);
}
if let Some(ref v) = self.hashes.as_ref() {
my_size += ::protobuf::rt::string_size(5, &v);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
if let Some(ref v) = self.rand.as_ref() {
os.write_bytes(1, &v)?;
}
if let Some(ref v) = self.pubkey.as_ref() {
os.write_bytes(2, &v)?;
}
if let Some(ref v) = self.exchanges.as_ref() {
os.write_string(3, &v)?;
}
if let Some(ref v) = self.ciphers.as_ref() {
os.write_string(4, &v)?;
}
if let Some(ref v) = self.hashes.as_ref() {
os.write_string(5, &v)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn as_any(&self) -> &dyn (::std::any::Any) {
self as &dyn (::std::any::Any)
}
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
self as &mut dyn (::std::any::Any)
}
fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
self
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
Self::descriptor_static()
}
fn new() -> Propose {
Propose::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"rand",
|m: &Propose| { &m.rand },
|m: &mut Propose| { &mut m.rand },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"pubkey",
|m: &Propose| { &m.pubkey },
|m: &mut Propose| { &mut m.pubkey },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"exchanges",
|m: &Propose| { &m.exchanges },
|m: &mut Propose| { &mut m.exchanges },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"ciphers",
|m: &Propose| { &m.ciphers },
|m: &mut Propose| { &mut m.ciphers },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"hashes",
|m: &Propose| { &m.hashes },
|m: &mut Propose| { &mut m.hashes },
));
::protobuf::reflect::MessageDescriptor::new::<Propose>(
"Propose",
fields,
file_descriptor_proto()
)
})
}
}
fn default_instance() -> &'static Propose {
static mut instance: ::protobuf::lazy::Lazy<Propose> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const Propose,
};
unsafe {
instance.get(Propose::new)
}
}
}
impl ::protobuf::Clear for Propose {
fn clear(&mut self) {
self.rand.clear();
self.pubkey.clear();
self.exchanges.clear();
self.ciphers.clear();
self.hashes.clear();
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for Propose {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for Propose {
fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
::protobuf::reflect::ProtobufValueRef::Message(self)
}
}
#[derive(PartialEq,Clone,Default)]
pub struct Exchange {
// message fields
epubkey: ::protobuf::SingularField<::std::vec::Vec<u8>>,
signature: ::protobuf::SingularField<::std::vec::Vec<u8>>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a Exchange {
fn default() -> &'a Exchange {
<Exchange as ::protobuf::Message>::default_instance()
}
}
impl Exchange {
pub fn new() -> Exchange {
::std::default::Default::default()
}
// optional bytes epubkey = 1;
pub fn get_epubkey(&self) -> &[u8] {
match self.epubkey.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_epubkey(&mut self) {
self.epubkey.clear();
}
pub fn has_epubkey(&self) -> bool {
self.epubkey.is_some()
}
// Param is passed by value, moved
pub fn set_epubkey(&mut self, v: ::std::vec::Vec<u8>) {
self.epubkey = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_epubkey(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.epubkey.is_none() {
self.epubkey.set_default();
}
self.epubkey.as_mut().unwrap()
}
// Take field
pub fn take_epubkey(&mut self) -> ::std::vec::Vec<u8> {
self.epubkey.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
// optional bytes signature = 2;
pub fn get_signature(&self) -> &[u8] {
match self.signature.as_ref() {
Some(v) => &v,
None => &[],
}
}
pub fn clear_signature(&mut self) {
self.signature.clear();
}
pub fn has_signature(&self) -> bool {
self.signature.is_some()
}
// Param is passed by value, moved
pub fn set_signature(&mut self, v: ::std::vec::Vec<u8>) {
self.signature = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_signature(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.signature.is_none() {
self.signature.set_default();
}
self.signature.as_mut().unwrap()
}
// Take field
pub fn take_signature(&mut self) -> ::std::vec::Vec<u8> {
self.signature.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
}
impl ::protobuf::Message for Exchange {
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
while !is.eof()? {
let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number {
1 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.epubkey)?;
},
2 => {
::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.signature)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
if let Some(ref v) = self.epubkey.as_ref() {
my_size += ::protobuf::rt::bytes_size(1, &v);
}
if let Some(ref v) = self.signature.as_ref() {
my_size += ::protobuf::rt::bytes_size(2, &v);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
if let Some(ref v) = self.epubkey.as_ref() {
os.write_bytes(1, &v)?;
}
if let Some(ref v) = self.signature.as_ref() {
os.write_bytes(2, &v)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn as_any(&self) -> &dyn (::std::any::Any) {
self as &dyn (::std::any::Any)
}
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
self as &mut dyn (::std::any::Any)
}
fn into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
self
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
Self::descriptor_static()
}
fn new() -> Exchange {
Exchange::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"epubkey",
|m: &Exchange| { &m.epubkey },
|m: &mut Exchange| { &mut m.epubkey },
));
fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"signature",
|m: &Exchange| { &m.signature },
|m: &mut Exchange| { &mut m.signature },
));
::protobuf::reflect::MessageDescriptor::new::<Exchange>(
"Exchange",
fields,
file_descriptor_proto()
)
})
}
}
fn default_instance() -> &'static Exchange {
static mut instance: ::protobuf::lazy::Lazy<Exchange> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const Exchange,
};
unsafe {
instance.get(Exchange::new)
}
}
}
impl ::protobuf::Clear for Exchange {
fn clear(&mut self) {
self.epubkey.clear();
self.signature.clear();
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for Exchange {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for Exchange {
fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
::protobuf::reflect::ProtobufValueRef::Message(self)
}
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x11src/structs.proto\x12\x08spipe.pb\"\x85\x01\n\x07Propose\x12\x12\n\
\x04rand\x18\x01\x20\x01(\x0cR\x04rand\x12\x16\n\x06pubkey\x18\x02\x20\
\x01(\x0cR\x06pubkey\x12\x1c\n\texchanges\x18\x03\x20\x01(\tR\texchanges\
\x12\x18\n\x07ciphers\x18\x04\x20\x01(\tR\x07ciphers\x12\x16\n\x06hashes\
\x18\x05\x20\x01(\tR\x06hashes\"B\n\x08Exchange\x12\x18\n\x07epubkey\x18\
\x01\x20\x01(\x0cR\x07epubkey\x12\x1c\n\tsignature\x18\x02\x20\x01(\x0cR\
\tsignatureJ\xaf\x04\n\x06\x12\x04\0\0\x0f\x01\n\x08\n\x01\x0c\x12\x03\0\
\0\x12\n\x08\n\x01\x02\x12\x03\x02\x08\x10\n\n\n\x02\x04\0\x12\x04\x04\0\
\n\x01\n\n\n\x03\x04\0\x01\x12\x03\x04\x08\x0f\n\x0b\n\x04\x04\0\x02\0\
\x12\x03\x05\x08\x20\n\x0c\n\x05\x04\0\x02\0\x04\x12\x03\x05\x08\x10\n\
\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x05\x11\x16\n\x0c\n\x05\x04\0\x02\0\
\x01\x12\x03\x05\x17\x1b\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x05\x1e\x1f\
\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x06\x08\"\n\x0c\n\x05\x04\0\x02\x01\
\x04\x12\x03\x06\x08\x10\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x06\x11\
\x16\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x06\x17\x1d\n\x0c\n\x05\x04\0\
\x02\x01\x03\x12\x03\x06\x20!\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x07\x08&\
\n\x0c\n\x05\x04\0\x02\x02\x04\x12\x03\x07\x08\x10\n\x0c\n\x05\x04\0\x02\
\x02\x05\x12\x03\x07\x11\x17\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x07\
\x18!\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x07$%\n\x0b\n\x04\x04\0\x02\
\x03\x12\x03\x08\x08$\n\x0c\n\x05\x04\0\x02\x03\x04\x12\x03\x08\x08\x10\
\n\x0c\n\x05\x04\0\x02\x03\x05\x12\x03\x08\x11\x17\n\x0c\n\x05\x04\0\x02\
\x03\x01\x12\x03\x08\x18\x1f\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x08\"\
#\n\x0b\n\x04\x04\0\x02\x04\x12\x03\t\x08#\n\x0c\n\x05\x04\0\x02\x04\x04\
\x12\x03\t\x08\x10\n\x0c\n\x05\x04\0\x02\x04\x05\x12\x03\t\x11\x17\n\x0c\
\n\x05\x04\0\x02\x04\x01\x12\x03\t\x18\x1e\n\x0c\n\x05\x04\0\x02\x04\x03\
\x12\x03\t!\"\n\n\n\x02\x04\x01\x12\x04\x0c\0\x0f\x01\n\n\n\x03\x04\x01\
\x01\x12\x03\x0c\x08\x10\n\x0b\n\x04\x04\x01\x02\0\x12\x03\r\x08#\n\x0c\
\n\x05\x04\x01\x02\0\x04\x12\x03\r\x08\x10\n\x0c\n\x05\x04\x01\x02\0\x05\
\x12\x03\r\x11\x16\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\r\x17\x1e\n\x0c\
\n\x05\x04\x01\x02\0\x03\x12\x03\r!\"\n\x0b\n\x04\x04\x01\x02\x01\x12\
\x03\x0e\x08%\n\x0c\n\x05\x04\x01\x02\x01\x04\x12\x03\x0e\x08\x10\n\x0c\
\n\x05\x04\x01\x02\x01\x05\x12\x03\x0e\x11\x16\n\x0c\n\x05\x04\x01\x02\
\x01\x01\x12\x03\x0e\x17\x20\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x0e\
#$\
";
static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
};
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
}
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
unsafe {
file_descriptor_proto_lazy.get(|| {
parse_descriptor_proto()
})
}
}

View File

@ -1,5 +0,0 @@
FROM rust:1.38
RUN apt-get update && apt-get install -y protobuf-compiler
RUN cargo install --version 2.8.1 protobuf-codegen

View File

@ -1,35 +0,0 @@
#!/usr/bin/env bash
# exit immediately when a command fails
set -e
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
# error on unset variables
set -u
# print each command before executing it
set -x
# The source .proto file.
SOURCE_PROTO_FILE=$1
DEST_FOLDER=$(dirname "$SOURCE_PROTO_FILE")
# The .rs file generated via protoc.
TMP_GEN_RUST_FILE=${SOURCE_PROTO_FILE/proto/rs}
# The above with `_proto` injected.
FINAL_GEN_RUST_FILE=${TMP_GEN_RUST_FILE/.rs/_proto.rs}
sudo docker build -t rust-libp2p-protobuf-builder $(dirname "$0")
sudo docker run --rm \
-v `pwd`:/usr/code:z \
-u="$(id -u):$(id -g)" \
-w /usr/code \
rust-libp2p-protobuf-builder \
/bin/bash -c " \
protoc --rust_out $DEST_FOLDER $SOURCE_PROTO_FILE"
mv $TMP_GEN_RUST_FILE $FINAL_GEN_RUST_FILE