|
|
|
@ -1,16 +1,17 @@
|
|
|
|
|
use alloc::borrow::ToOwned; |
|
|
|
|
use std::net; |
|
|
|
|
use std::thread; |
|
|
|
|
use alloc::string::{String, ToString}; |
|
|
|
|
use alloc::vec; |
|
|
|
|
use alloc::vec::Vec; |
|
|
|
|
use alloc::string::{String, ToString}; |
|
|
|
|
use core::ops::RangeInclusive; |
|
|
|
|
use core::time::Duration; |
|
|
|
|
use std::net; |
|
|
|
|
#[cfg(test)] |
|
|
|
|
use std::thread; |
|
|
|
|
|
|
|
|
|
use crate::interface::{Interface, InterfaceRequirements, TargetingData}; |
|
|
|
|
use crate::message::MessageBytes; |
|
|
|
|
use crate::res::{IFError, IFResult}; |
|
|
|
|
use crate::res::IFError::General; |
|
|
|
|
use crate::res::{IFError, IFResult}; |
|
|
|
|
use crate::std::io::{Read, Write}; |
|
|
|
|
use crate::std::println; |
|
|
|
|
|
|
|
|
@ -22,7 +23,7 @@ pub struct IPInterface {
|
|
|
|
|
connections: Vec<net::TcpStream>, |
|
|
|
|
listener: net::TcpListener, |
|
|
|
|
peers: Vec<net::IpAddr>, |
|
|
|
|
package_queue: Vec<IPPackage> |
|
|
|
|
package_queue: Vec<IPPackage>, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[derive(Debug)] |
|
|
|
@ -46,7 +47,7 @@ impl MessageType {
|
|
|
|
|
0 => Ok(MessageType::Service), |
|
|
|
|
1 => Ok(MessageType::PeerRequest), |
|
|
|
|
2 => Ok(MessageType::Common), |
|
|
|
|
_ => Err(IFError::General("Incorrect message type".to_string())) |
|
|
|
|
_ => Err(IFError::General("Incorrect message type".to_string())), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -54,7 +55,7 @@ impl MessageType {
|
|
|
|
|
match self { |
|
|
|
|
MessageType::Service => 0, |
|
|
|
|
MessageType::PeerRequest => 1, |
|
|
|
|
MessageType::Common => 2 |
|
|
|
|
MessageType::Common => 2, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -86,7 +87,12 @@ impl Interface for IPInterface {
|
|
|
|
|
let mut message: Vec<u8> = vec![]; |
|
|
|
|
message_take.read_to_end(&mut message)?; |
|
|
|
|
|
|
|
|
|
let package = IPPackage {version, package_type, size, message}; |
|
|
|
|
let package = IPPackage { |
|
|
|
|
version, |
|
|
|
|
package_type, |
|
|
|
|
size, |
|
|
|
|
message, |
|
|
|
|
}; |
|
|
|
|
self.package_queue.push(package); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -102,43 +108,53 @@ impl Interface for IPInterface {
|
|
|
|
|
fn send(&mut self, message: &[u8], interface_data: Option<TargetingData>) -> IFResult<()> { |
|
|
|
|
let addr: net::SocketAddr = match interface_data { |
|
|
|
|
Some(ip_string) => ip_string.parse().expect("Unable to parse address"), |
|
|
|
|
None => return Err(IFError::General(String::from("Not enough info to create connections"))) |
|
|
|
|
None => { |
|
|
|
|
return Err(IFError::General(String::from( |
|
|
|
|
"Not enough info to create connections", |
|
|
|
|
))) |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
println!("Connecting to {:?}", addr); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let index = match self.connections.iter().position(|connection| connection.peer_addr().ok() == Some(addr)) { |
|
|
|
|
let index = match self |
|
|
|
|
.connections |
|
|
|
|
.iter() |
|
|
|
|
.position(|connection| connection.peer_addr().ok() == Some(addr)) |
|
|
|
|
{ |
|
|
|
|
None => { |
|
|
|
|
let connection = match net::TcpStream::connect_timeout( |
|
|
|
|
&addr, |
|
|
|
|
Duration::new(1, 0), |
|
|
|
|
) { |
|
|
|
|
let connection = match net::TcpStream::connect_timeout(&addr, Duration::new(1, 0)) { |
|
|
|
|
Ok(connection) => connection, |
|
|
|
|
Err(_) => return Err(General(String::from("Can't connect to this port"))) |
|
|
|
|
Err(_) => return Err(General(String::from("Can't connect to this port"))), |
|
|
|
|
}; |
|
|
|
|
self.connections.push(connection); |
|
|
|
|
self.connections.len() - 1 |
|
|
|
|
} |
|
|
|
|
Some(i) => i |
|
|
|
|
Some(i) => i, |
|
|
|
|
}; |
|
|
|
|
println!("Sending message to {:?}", self.connections[index].peer_addr().unwrap()); |
|
|
|
|
println!( |
|
|
|
|
"Sending message to {:?}", |
|
|
|
|
self.connections[index].peer_addr().unwrap() |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
self.connections[index].set_write_timeout(Some(Duration::new(1, 0)))?; |
|
|
|
|
|
|
|
|
|
IPInterface::send_package(&mut self.connections[index], IPPackage { |
|
|
|
|
version: 0, |
|
|
|
|
package_type: MessageType::Common, |
|
|
|
|
size: message.len() as u32, |
|
|
|
|
message: Vec::from(message), |
|
|
|
|
})?; |
|
|
|
|
IPInterface::send_package( |
|
|
|
|
&mut self.connections[index], |
|
|
|
|
IPPackage { |
|
|
|
|
version: 0, |
|
|
|
|
package_type: MessageType::Common, |
|
|
|
|
size: message.len() as u32, |
|
|
|
|
message: Vec::from(message), |
|
|
|
|
}, |
|
|
|
|
)?; |
|
|
|
|
println!("Sent message"); |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
fn receive(&mut self) -> IFResult<Option<(MessageBytes, TargetingData)>> { |
|
|
|
|
match self.package_queue.pop() { |
|
|
|
|
Some(ip_package) => Ok(Some( (ip_package.message, "".to_string()) )), |
|
|
|
|
None => Ok(None) |
|
|
|
|
Some(ip_package) => Ok(Some((ip_package.message, "".to_string()))), |
|
|
|
|
None => Ok(None), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -148,7 +164,9 @@ impl IPInterface {
|
|
|
|
|
let listener = match create_tcp_listener() { |
|
|
|
|
Some(listener) => listener, |
|
|
|
|
None => { |
|
|
|
|
return Err(IFError::General(String::from("Unable to open TCP listener"))); |
|
|
|
|
return Err(IFError::General(String::from( |
|
|
|
|
"Unable to open TCP listener", |
|
|
|
|
))); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -156,10 +174,10 @@ impl IPInterface {
|
|
|
|
|
|
|
|
|
|
Ok(IPInterface { |
|
|
|
|
id: String::from("IP Interface"), |
|
|
|
|
connections: vec!(), |
|
|
|
|
connections: vec![], |
|
|
|
|
listener, |
|
|
|
|
peers: vec!(), |
|
|
|
|
package_queue: vec!() |
|
|
|
|
peers: vec![], |
|
|
|
|
package_queue: vec![], |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
pub fn dump(&self) -> IFResult<Vec<u8>> { |
|
|
|
@ -173,9 +191,7 @@ impl IPInterface {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn send_package(stream: &mut net::TcpStream, package: IPPackage) -> IFResult<()> { |
|
|
|
|
let mut header: Vec<u8> = vec![]; |
|
|
|
|
header.push(package.version); |
|
|
|
|
header.push(package.package_type.to_u8()); |
|
|
|
|
let mut header: Vec<u8> = vec![package.version, package.package_type.to_u8()]; |
|
|
|
|
for byte in size_to_bytes(package.size) { |
|
|
|
|
header.push(byte); |
|
|
|
|
} |
|
|
|
@ -186,14 +202,13 @@ impl IPInterface {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn create_tcp_listener() -> Option<net::TcpListener> { |
|
|
|
|
for port in SOCKET_RANGE { |
|
|
|
|
match net::TcpListener::bind("127.0.0.1:".to_owned() + &port.to_string()) { |
|
|
|
|
Ok(listener) => return Some(listener), |
|
|
|
|
Err(_e) => {} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
None |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -206,7 +221,6 @@ fn parse_header(data: Vec<u8>) -> IFResult<IPPackage> {
|
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn size_to_bytes(mut a: u32) -> [u8; 4] { |
|
|
|
|
let mut arr: [u8; 4] = [0, 0, 0, 0]; |
|
|
|
|
for i in [3, 2, 1, 0] { |
|
|
|
@ -232,7 +246,9 @@ fn test_creating_connection() -> IFResult<()> {
|
|
|
|
|
let mut interface2 = IPInterface::new()?; |
|
|
|
|
|
|
|
|
|
let t1 = std::thread::spawn(move || { |
|
|
|
|
interface1.send(&message, Some(String::from("127.0.0.1:50001"))).unwrap(); |
|
|
|
|
interface1 |
|
|
|
|
.send(&message, Some(String::from("127.0.0.1:50001"))) |
|
|
|
|
.unwrap(); |
|
|
|
|
interface1 |
|
|
|
|
}); |
|
|
|
|
thread::sleep(Duration::from_millis(10)); |
|
|
|
@ -244,9 +260,8 @@ fn test_creating_connection() -> IFResult<()> {
|
|
|
|
|
match res1 { |
|
|
|
|
Ok(_res) => { |
|
|
|
|
println!("Thread Ok"); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
Err(e) => println!("{:?}", e) |
|
|
|
|
Err(e) => println!("{:?}", e), |
|
|
|
|
} |
|
|
|
|
let res2 = t2.join(); |
|
|
|
|
match res2 { |
|
|
|
@ -255,18 +270,15 @@ fn test_creating_connection() -> IFResult<()> {
|
|
|
|
|
match res.receive() { |
|
|
|
|
Ok(tmp) => match tmp { |
|
|
|
|
Some((message, _metadata)) => println!("Received {:?}", message), |
|
|
|
|
None => println!("None") |
|
|
|
|
} |
|
|
|
|
Err(e) => println!("{:?}", e) |
|
|
|
|
None => println!("None"), |
|
|
|
|
}, |
|
|
|
|
Err(e) => println!("{:?}", e), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Err(e) => println!("{:?}", e) |
|
|
|
|
Err(e) => println!("{:?}", e), |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[cfg(test)] |
|
|
|
|
pub mod test_ip_interface {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|