diff --git a/vnt/proto/message.proto b/vnt/proto/message.proto index ba59438..cd251fd 100644 --- a/vnt/proto/message.proto +++ b/vnt/proto/message.proto @@ -1,66 +1,78 @@ syntax = "proto3"; -message HandshakeRequest{ - string version = 1; - bool secret = 2; + +message HandshakeRequest { + string version = 1; + bool secret = 2; } -message HandshakeResponse{ - string version = 1; - bool secret = 2; - bytes public_key = 3; - string key_finger = 4; +message HandshakeResponse { + string version = 1; + bool secret = 2; + bytes public_key = 3; + string key_finger = 4; } -message SecretHandshakeRequest{ - string token = 1; - bytes key = 2; +message SecretHandshakeRequest { + string token = 1; + bytes key = 2; } -message RegistrationRequest{ - string token = 1; - string device_id = 2; - string name = 3; - bool is_fast = 4; - string version = 5; - fixed32 virtual_ip = 6; - bool allow_ip_change = 7; - bool client_secret = 8; +message RegistrationRequest { + string token = 1; + string device_id = 2; + string name = 3; + bool is_fast = 4; + string version = 5; + fixed32 virtual_ip = 6; + bool allow_ip_change = 7; + bool client_secret = 8; } -message RegistrationResponse{ - fixed32 virtual_ip = 1; - fixed32 virtual_gateway = 2; - fixed32 virtual_netmask = 3; - uint32 epoch = 4; - repeated DeviceInfo device_info_list = 5; - fixed32 public_ip = 6; - uint32 public_port = 7; - bytes public_ipv6 = 8; +message RegistrationResponse { + fixed32 virtual_ip = 1; + fixed32 virtual_gateway = 2; + fixed32 virtual_netmask = 3; + uint32 epoch = 4; + repeated DeviceInfo device_info_list = 5; + fixed32 public_ip = 6; + uint32 public_port = 7; + bytes public_ipv6 = 8; } -message DeviceInfo{ - string name = 1; - fixed32 virtual_ip = 2; - uint32 device_status = 3; - bool client_secret = 4; +message DeviceInfo { + string name = 1; + fixed32 virtual_ip = 2; + uint32 device_status = 3; + bool client_secret = 4; } -message DeviceList{ - uint32 epoch = 1; - repeated DeviceInfo device_info_list = 2; +message DeviceList { + uint32 epoch = 1; + repeated DeviceInfo device_info_list = 2; } -message PunchInfo{ - repeated fixed32 public_ip_list = 2; - uint32 public_port = 3; - uint32 public_port_range = 4; - PunchNatType nat_type = 5; - bool reply = 6; - fixed32 local_ip = 7; - uint32 local_port = 8; - bytes ipv6 = 9; - uint32 ipv6_port = 10; - uint32 tcp_port = 11; - repeated uint32 udp_ports = 12; - repeated uint32 public_ports = 13; +message PunchInfo { + repeated fixed32 public_ip_list = 2; + uint32 public_port = 3; + uint32 public_port_range = 4; + PunchNatType nat_type = 5; + bool reply = 6; + fixed32 local_ip = 7; + uint32 local_port = 8; + bytes ipv6 = 9; + uint32 ipv6_port = 10; + uint32 tcp_port = 11; + repeated uint32 udp_ports = 12; + repeated uint32 public_ports = 13; } -enum PunchNatType{ - Symmetric = 0; - Cone = 1; +enum PunchNatType { + Symmetric = 0; + Cone = 1; +} +/// 向服务器上报客户端状态信息 +message ClientStatusInfo { + fixed32 source = 1; + repeated RouteItem p2p_list = 2; + uint64 up_stream = 3; + uint64 down_stream = 4; + PunchNatType nat_type = 5; +} +message RouteItem { + fixed32 next_ip = 1; } \ No newline at end of file diff --git a/vnt/src/channel/context.rs b/vnt/src/channel/context.rs index acb6049..3a038b3 100644 --- a/vnt/src/channel/context.rs +++ b/vnt/src/channel/context.rs @@ -482,9 +482,10 @@ impl RouteTable { let table = self.route_table.read(); let mut list = Vec::with_capacity(8); for (ip, (_, routes)) in table.iter() { - if let Some((route, _)) = routes.first() { + for (route, _) in routes.iter() { if route.is_p2p() { list.push((*ip, *route)); + break; } } } diff --git a/vnt/src/channel/udp_channel.rs b/vnt/src/channel/udp_channel.rs index c462aee..542a7b0 100644 --- a/vnt/src/channel/udp_channel.rs +++ b/vnt/src/channel/udp_channel.rs @@ -188,8 +188,14 @@ where NOTIFY => return Ok(()), Token(index) => index - 1, }; + let udp = if let Some(udp) = udps.get(index) { + udp + } else { + log::error!("{:?}", x); + continue; + }; loop { - match udps[index].recv_from(&mut buf) { + match udp.recv_from(&mut buf) { Ok((len, addr)) => { recv_handler.handle( &mut buf[..len], diff --git a/vnt/src/core/conn.rs b/vnt/src/core/conn.rs index 00806b6..42a13e5 100644 --- a/vnt/src/core/conn.rs +++ b/vnt/src/core/conn.rs @@ -205,6 +205,8 @@ impl Vnt { let context = context.clone(); let nat_test = nat_test.clone(); let device_list = device_list.clone(); + let down_count_watcher = down_count_watcher.clone(); + let up_count_watcher = up_count_watcher.clone(); let current_device = current_device.clone(); if !config.use_channel_type.is_only_relay() { // 定时nat探测 @@ -229,6 +231,8 @@ impl Vnt { config_info, punch, callback, + down_count_watcher, + up_count_watcher, ); }); } @@ -259,6 +263,8 @@ pub fn start( config_info: BaseConfigInfo, punch: Punch, callback: Call, + down_count_watcher: WatchU64Adder, + up_count_watcher: WatchSingleU64Adder, ) { // 定时心跳 maintain::heartbeat( @@ -310,6 +316,13 @@ pub fn start( punch, ); } + maintain::up_status( + scheduler, + context.clone(), + current_device.clone(), + down_count_watcher, + up_count_watcher, + ) } impl Vnt { diff --git a/vnt/src/handle/maintain/mod.rs b/vnt/src/handle/maintain/mod.rs index 62f2aab..1055835 100644 --- a/vnt/src/handle/maintain/mod.rs +++ b/vnt/src/handle/maintain/mod.rs @@ -14,3 +14,6 @@ pub use punch::*; mod idle; pub use idle::idle_gateway; pub use idle::idle_route; + +mod up_status; +pub use up_status::*; diff --git a/vnt/src/handle/maintain/punch.rs b/vnt/src/handle/maintain/punch.rs index 9200c33..aa915e1 100644 --- a/vnt/src/handle/maintain/punch.rs +++ b/vnt/src/handle/maintain/punch.rs @@ -1,4 +1,3 @@ -use std::cmp::Ordering; use std::net::Ipv4Addr; use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::sync::Arc; diff --git a/vnt/src/handle/maintain/up_status.rs b/vnt/src/handle/maintain/up_status.rs new file mode 100644 index 0000000..54fd621 --- /dev/null +++ b/vnt/src/handle/maintain/up_status.rs @@ -0,0 +1,104 @@ +use crate::channel::context::Context; +use crate::handle::CurrentDeviceInfo; +use crate::proto::message::{ClientStatusInfo, PunchNatType, RouteItem}; +use crate::protocol::body::ENCRYPTION_RESERVED; +use crate::protocol::{service_packet, NetPacket, Protocol, Version, HEAD_LEN, MAX_TTL}; +use crate::util::{Scheduler, WatchSingleU64Adder, WatchU64Adder}; +use crossbeam_utils::atomic::AtomicCell; +use protobuf::Message; +use std::io; +use std::sync::Arc; +use std::time::Duration; + +/// 上报状态给服务器 +pub fn up_status( + scheduler: &Scheduler, + context: Context, + current_device_info: Arc>, + down_count_watcher: WatchU64Adder, + up_count_watcher: WatchSingleU64Adder, +) { + let _ = scheduler.timeout(Duration::from_secs(60), move |x| { + up_status0( + x, + context, + current_device_info, + down_count_watcher, + up_count_watcher, + ) + }); +} + +fn up_status0( + scheduler: &Scheduler, + context: Context, + current_device_info: Arc>, + down_count_watcher: WatchU64Adder, + up_count_watcher: WatchSingleU64Adder, +) { + if let Err(e) = send_up_status_packet( + &context, + ¤t_device_info, + &down_count_watcher, + &up_count_watcher, + ) { + log::warn!("{:?}", e) + } + let rs = scheduler.timeout(Duration::from_secs(10 * 60), move |x| { + up_status0( + x, + context, + current_device_info, + down_count_watcher, + up_count_watcher, + ) + }); + if !rs { + log::info!("定时任务停止"); + } +} + +fn send_up_status_packet( + context: &Context, + current_device_info: &AtomicCell, + down_count_watcher: &WatchU64Adder, + up_count_watcher: &WatchSingleU64Adder, +) -> io::Result<()> { + let device_info = current_device_info.load(); + if device_info.status.offline() { + return Ok(()); + } + let routes = context.route_table.route_table_p2p(); + if routes.is_empty() { + return Ok(()); + } + let mut message = ClientStatusInfo::new(); + message.source = device_info.virtual_ip.into(); + for (ip, _) in routes { + let mut item = RouteItem::new(); + item.next_ip = ip.into(); + message.p2p_list.push(item); + } + message.up_stream = up_count_watcher.get(); + message.down_stream = down_count_watcher.get(); + message.nat_type = protobuf::EnumOrUnknown::new(if context.is_cone() { + PunchNatType::Cone + } else { + PunchNatType::Symmetric + }); + let buf = message + .write_to_bytes() + .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("up_status_packet {:?}", e)))?; + let mut net_packet = + NetPacket::new_encrypt(vec![0; HEAD_LEN + buf.len() + ENCRYPTION_RESERVED])?; + net_packet.set_version(Version::V1); + net_packet.set_gateway_flag(true); + net_packet.set_protocol(Protocol::Service); + net_packet.set_transport_protocol_into(service_packet::Protocol::ClientStatusInfo); + net_packet.first_set_ttl(MAX_TTL); + net_packet.set_source(device_info.virtual_ip); + net_packet.set_destination(device_info.virtual_gateway); + net_packet.set_payload(&buf)?; + context.send_default(net_packet.buffer(), device_info.connect_server)?; + Ok(()) +} diff --git a/vnt/src/proto/message.rs b/vnt/src/proto/message.rs index 1cea963..aa5fc5f 100644 --- a/vnt/src/proto/message.rs +++ b/vnt/src/proto/message.rs @@ -1622,6 +1622,323 @@ impl ::protobuf::reflect::ProtobufValue for PunchInfo { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +#[derive(PartialEq,Clone,Default,Debug)] +// @@protoc_insertion_point(message:ClientStatusInfo) +pub struct ClientStatusInfo { + // message fields + // @@protoc_insertion_point(field:ClientStatusInfo.source) + pub source: u32, + // @@protoc_insertion_point(field:ClientStatusInfo.p2p_list) + pub p2p_list: ::std::vec::Vec, + // @@protoc_insertion_point(field:ClientStatusInfo.up_stream) + pub up_stream: u64, + // @@protoc_insertion_point(field:ClientStatusInfo.down_stream) + pub down_stream: u64, + // @@protoc_insertion_point(field:ClientStatusInfo.nat_type) + pub nat_type: ::protobuf::EnumOrUnknown, + // special fields + // @@protoc_insertion_point(special_field:ClientStatusInfo.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ClientStatusInfo { + fn default() -> &'a ClientStatusInfo { + ::default_instance() + } +} + +impl ClientStatusInfo { + pub fn new() -> ClientStatusInfo { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(5); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "source", + |m: &ClientStatusInfo| { &m.source }, + |m: &mut ClientStatusInfo| { &mut m.source }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "p2p_list", + |m: &ClientStatusInfo| { &m.p2p_list }, + |m: &mut ClientStatusInfo| { &mut m.p2p_list }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "up_stream", + |m: &ClientStatusInfo| { &m.up_stream }, + |m: &mut ClientStatusInfo| { &mut m.up_stream }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "down_stream", + |m: &ClientStatusInfo| { &m.down_stream }, + |m: &mut ClientStatusInfo| { &mut m.down_stream }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "nat_type", + |m: &ClientStatusInfo| { &m.nat_type }, + |m: &mut ClientStatusInfo| { &mut m.nat_type }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "ClientStatusInfo", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ClientStatusInfo { + const NAME: &'static str = "ClientStatusInfo"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 13 => { + self.source = is.read_fixed32()?; + }, + 18 => { + self.p2p_list.push(is.read_message()?); + }, + 24 => { + self.up_stream = is.read_uint64()?; + }, + 32 => { + self.down_stream = is.read_uint64()?; + }, + 40 => { + self.nat_type = is.read_enum_or_unknown()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if self.source != 0 { + my_size += 1 + 4; + } + for value in &self.p2p_list { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + if self.up_stream != 0 { + my_size += ::protobuf::rt::uint64_size(3, self.up_stream); + } + if self.down_stream != 0 { + my_size += ::protobuf::rt::uint64_size(4, self.down_stream); + } + if self.nat_type != ::protobuf::EnumOrUnknown::new(PunchNatType::Symmetric) { + my_size += ::protobuf::rt::int32_size(5, self.nat_type.value()); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if self.source != 0 { + os.write_fixed32(1, self.source)?; + } + for v in &self.p2p_list { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + }; + if self.up_stream != 0 { + os.write_uint64(3, self.up_stream)?; + } + if self.down_stream != 0 { + os.write_uint64(4, self.down_stream)?; + } + if self.nat_type != ::protobuf::EnumOrUnknown::new(PunchNatType::Symmetric) { + os.write_enum(5, ::protobuf::EnumOrUnknown::value(&self.nat_type))?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ClientStatusInfo { + ClientStatusInfo::new() + } + + fn clear(&mut self) { + self.source = 0; + self.p2p_list.clear(); + self.up_stream = 0; + self.down_stream = 0; + self.nat_type = ::protobuf::EnumOrUnknown::new(PunchNatType::Symmetric); + self.special_fields.clear(); + } + + fn default_instance() -> &'static ClientStatusInfo { + static instance: ClientStatusInfo = ClientStatusInfo { + source: 0, + p2p_list: ::std::vec::Vec::new(), + up_stream: 0, + down_stream: 0, + nat_type: ::protobuf::EnumOrUnknown::from_i32(0), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ClientStatusInfo { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ClientStatusInfo").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ClientStatusInfo { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ClientStatusInfo { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +#[derive(PartialEq,Clone,Default,Debug)] +// @@protoc_insertion_point(message:RouteItem) +pub struct RouteItem { + // message fields + // @@protoc_insertion_point(field:RouteItem.next_ip) + pub next_ip: u32, + // special fields + // @@protoc_insertion_point(special_field:RouteItem.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a RouteItem { + fn default() -> &'a RouteItem { + ::default_instance() + } +} + +impl RouteItem { + pub fn new() -> RouteItem { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "next_ip", + |m: &RouteItem| { &m.next_ip }, + |m: &mut RouteItem| { &mut m.next_ip }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "RouteItem", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for RouteItem { + const NAME: &'static str = "RouteItem"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 13 => { + self.next_ip = is.read_fixed32()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if self.next_ip != 0 { + my_size += 1 + 4; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if self.next_ip != 0 { + os.write_fixed32(1, self.next_ip)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> RouteItem { + RouteItem::new() + } + + fn clear(&mut self) { + self.next_ip = 0; + self.special_fields.clear(); + } + + fn default_instance() -> &'static RouteItem { + static instance: RouteItem = RouteItem { + next_ip: 0, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for RouteItem { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("RouteItem").unwrap()).clone() + } +} + +impl ::std::fmt::Display for RouteItem { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RouteItem { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + #[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)] // @@protoc_insertion_point(enum:PunchNatType) pub enum PunchNatType { @@ -1713,8 +2030,14 @@ static file_descriptor_proto_data: &'static [u8] = b"\ 6\x18\t\x20\x01(\x0cR\x04ipv6\x12\x1b\n\tipv6_port\x18\n\x20\x01(\rR\x08\ ipv6Port\x12\x19\n\x08tcp_port\x18\x0b\x20\x01(\rR\x07tcpPort\x12\x1b\n\ \tudp_ports\x18\x0c\x20\x03(\rR\x08udpPorts\x12!\n\x0cpublic_ports\x18\r\ - \x20\x03(\rR\x0bpublicPorts*'\n\x0cPunchNatType\x12\r\n\tSymmetric\x10\0\ - \x12\x08\n\x04Cone\x10\x01b\x06proto3\ + \x20\x03(\rR\x0bpublicPorts\"\xb9\x01\n\x10ClientStatusInfo\x12\x16\n\ + \x06source\x18\x01\x20\x01(\x07R\x06source\x12%\n\x08p2p_list\x18\x02\ + \x20\x03(\x0b2\n.RouteItemR\x07p2pList\x12\x1b\n\tup_stream\x18\x03\x20\ + \x01(\x04R\x08upStream\x12\x1f\n\x0bdown_stream\x18\x04\x20\x01(\x04R\nd\ + ownStream\x12(\n\x08nat_type\x18\x05\x20\x01(\x0e2\r.PunchNatTypeR\x07na\ + tType\"$\n\tRouteItem\x12\x17\n\x07next_ip\x18\x01\x20\x01(\x07R\x06next\ + Ip*'\n\x0cPunchNatType\x12\r\n\tSymmetric\x10\0\x12\x08\n\x04Cone\x10\ + \x01b\x06proto3\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -1732,7 +2055,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { file_descriptor.get(|| { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let mut deps = ::std::vec::Vec::with_capacity(0); - let mut messages = ::std::vec::Vec::with_capacity(8); + let mut messages = ::std::vec::Vec::with_capacity(10); messages.push(HandshakeRequest::generated_message_descriptor_data()); messages.push(HandshakeResponse::generated_message_descriptor_data()); messages.push(SecretHandshakeRequest::generated_message_descriptor_data()); @@ -1741,6 +2064,8 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { messages.push(DeviceInfo::generated_message_descriptor_data()); messages.push(DeviceList::generated_message_descriptor_data()); messages.push(PunchInfo::generated_message_descriptor_data()); + messages.push(ClientStatusInfo::generated_message_descriptor_data()); + messages.push(RouteItem::generated_message_descriptor_data()); let mut enums = ::std::vec::Vec::with_capacity(1); enums.push(PunchNatType::generated_enum_descriptor_data()); ::protobuf::reflect::GeneratedFileDescriptor::new_generated( diff --git a/vnt/src/protocol/mod.rs b/vnt/src/protocol/mod.rs index 8cc187d..8e44afc 100644 --- a/vnt/src/protocol/mod.rs +++ b/vnt/src/protocol/mod.rs @@ -183,6 +183,9 @@ impl> NetPacket { pub fn payload(&self) -> &[u8] { &self.buffer.as_ref()[12..self.data_len] } + pub fn head(&self) -> &[u8] { + &self.buffer.as_ref()[..12] + } } impl + AsMut<[u8]>> NetPacket { @@ -214,6 +217,9 @@ impl + AsMut<[u8]>> NetPacket { pub fn set_transport_protocol(&mut self, transport_protocol: u8) { self.buffer.as_mut()[2] = transport_protocol; } + pub fn set_transport_protocol_into>(&mut self, transport_protocol: P) { + self.buffer.as_mut()[2] = transport_protocol.into(); + } pub fn first_set_ttl(&mut self, ttl: u8) { self.buffer.as_mut()[3] = ttl << 4 | ttl; } diff --git a/vnt/src/protocol/service_packet.rs b/vnt/src/protocol/service_packet.rs index 0b34699..cb21bd1 100644 --- a/vnt/src/protocol/service_packet.rs +++ b/vnt/src/protocol/service_packet.rs @@ -13,6 +13,8 @@ pub enum Protocol { HandshakeResponse, SecretHandshakeRequest, SecretHandshakeResponse, + /// 客户端上报状态 + ClientStatusInfo, Unknown(u8), } @@ -27,6 +29,7 @@ impl From for Protocol { 6 => Self::HandshakeResponse, 7 => Self::SecretHandshakeRequest, 8 => Self::SecretHandshakeResponse, + 9 => Self::ClientStatusInfo, val => Self::Unknown(val), } } @@ -43,6 +46,7 @@ impl Into for Protocol { Self::HandshakeResponse => 6, Self::SecretHandshakeRequest => 7, Self::SecretHandshakeResponse => 8, + Self::ClientStatusInfo => 9, Self::Unknown(val) => val, } }