Merge pull request #2 from i2p/2018ification

2018ification
This commit is contained in:
str4d
2019-04-21 08:17:16 +01:00
committed by GitHub
14 changed files with 180 additions and 145 deletions

View File

@ -8,3 +8,11 @@ rust:
matrix:
allow_failures:
- nightly
before_script:
- rustup component add rustfmt
script:
- cargo fmt -- --check
- cargo build --verbose
- cargo test --verbose

View File

@ -9,6 +9,7 @@ readme = "README.md"
categories = ["network-programming"]
keywords = ["i2p", "net", "network", "sam"]
license = "MIT"
edition = "2018"
[badges]
travis-ci = { repository = "i2p/i2p-rs" }

View File

@ -1,8 +1,6 @@
extern crate i2p;
use i2p::net::I2pStream;
use std::env;
use std::io::{BufReader, Read, Write};
use i2p::net::I2pStream;
fn help() {
println!("Usage: eepget <host.i2p> [port]")

View File

@ -1,7 +0,0 @@
array_layout = "Block"
generics_indent = "Block"
fn_args_layout = "Block"
fn_call_style = "Block"
max_width = 115
where_style = "Rfc"
write_mode = "overwrite"

View File

@ -3,8 +3,6 @@ extern crate nom;
#[macro_use]
extern crate log;
extern crate rand;
pub mod net;
pub mod sam;

View File

@ -6,7 +6,7 @@ use std::option;
use std::slice;
use std::vec;
use net::i2p::I2pAddr;
use crate::net::i2p::I2pAddr;
pub struct I2pSocketAddr {
port: u16,
@ -92,13 +92,13 @@ impl I2pSocketAddr {
}
impl fmt::Display for I2pSocketAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.dest(), self.port())
}
}
impl fmt::Debug for I2pSocketAddr {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, fmt)
}
}
@ -223,13 +223,12 @@ impl ToI2pSocketAddrs for str {
type Iter = vec::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<I2pSocketAddr>> {
macro_rules! try_opt {
($e:expr, $msg:expr) => (
($e:expr, $msg:expr) => {
match $e {
Some(r) => r,
None => return Err(io::Error::new(io::ErrorKind::InvalidInput,
$msg)),
None => return Err(io::Error::new(io::ErrorKind::InvalidInput, $msg)),
}
)
};
}
// split the string by ':' and convert the second part to u16
@ -265,8 +264,8 @@ impl ToI2pSocketAddrs for String {
#[cfg(test)]
mod tests {
use net::*;
use net::test::{tsa, isa};
use crate::net::test::{isa, tsa};
use crate::net::*;
#[test]
fn to_socket_addr_i2paddr_u16() {

View File

@ -1,8 +1,8 @@
use std::io::{self, Error, ErrorKind};
use std::net::{SocketAddr, ToSocketAddrs};
use net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
use sam::DEFAULT_API;
use crate::net::{I2pSocketAddr, ToI2pSocketAddrs};
use crate::sam::DEFAULT_API;
/// Unimplemented
///
@ -53,11 +53,14 @@ impl I2pDatagramSocket {
I2pDatagramSocket::bind_via(DEFAULT_API, addr)
}
pub fn bind_via<A: ToSocketAddrs, B: ToI2pSocketAddrs>(sam_addr: A, addr: B) -> io::Result<I2pDatagramSocket> {
pub fn bind_via<A: ToSocketAddrs, B: ToI2pSocketAddrs>(
sam_addr: A,
addr: B,
) -> io::Result<I2pDatagramSocket> {
super::each_addr(sam_addr, addr, I2pDatagramSocket::bind_addr)
}
fn bind_addr(sam_addr: &SocketAddr, addr: &I2pSocketAddr) -> io::Result<I2pDatagramSocket> {
fn bind_addr(_sam_addr: &SocketAddr, _addr: &I2pSocketAddr) -> io::Result<I2pDatagramSocket> {
unimplemented!();
}
@ -74,7 +77,7 @@ impl I2pDatagramSocket {
/// let (number_of_bytes, src_addr) = socket.recv_from(&mut buf)
/// .expect("Didn't receive data");
/// ```
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, I2pSocketAddr)> {
pub fn recv_from(&self, _buf: &mut [u8]) -> io::Result<(usize, I2pSocketAddr)> {
unimplemented!()
}
@ -95,7 +98,7 @@ impl I2pDatagramSocket {
/// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf)
/// .expect("Didn't receive data");
/// ```
pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, I2pSocketAddr)> {
pub fn peek_from(&self, _buf: &mut [u8]) -> io::Result<(usize, I2pSocketAddr)> {
unimplemented!()
}
@ -115,12 +118,13 @@ impl I2pDatagramSocket {
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.send_to(&[0; 10], "127.0.0.1:4242").expect("couldn't send data");
/// ```
pub fn send_to<A: ToI2pSocketAddrs>(&self, buf: &[u8], addr: A)
-> io::Result<usize> {
pub fn send_to<A: ToI2pSocketAddrs>(&self, _buf: &[u8], addr: A) -> io::Result<usize> {
match addr.to_socket_addrs()?.next() {
Some(addr) => unimplemented!(),
None => Err(Error::new(ErrorKind::InvalidInput,
"no addresses to send data to")),
Some(_addr) => unimplemented!(),
None => Err(Error::new(
ErrorKind::InvalidInput,
"no addresses to send data to",
)),
}
}
@ -173,8 +177,12 @@ impl I2pDatagramSocket {
self.connect_via(DEFAULT_API, addr)
}
pub fn connect_via<A: ToSocketAddrs, B: ToI2pSocketAddrs>(&self, sam_addr: A, addr: B) -> io::Result<()> {
super::each_addr(sam_addr, addr, |sam_addr, addr| unimplemented!())
pub fn connect_via<A: ToSocketAddrs, B: ToI2pSocketAddrs>(
&self,
sam_addr: A,
addr: B,
) -> io::Result<()> {
super::each_addr(sam_addr, addr, |_sam_addr, _addr| unimplemented!())
}
/// Sends data on the socket to the remote address to which it is connected.
@ -193,7 +201,7 @@ impl I2pDatagramSocket {
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
/// socket.send(&[0, 1, 2]).expect("couldn't send message");
/// ```
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
pub fn send(&self, _buf: &[u8]) -> io::Result<usize> {
unimplemented!()
}
@ -216,7 +224,7 @@ impl I2pDatagramSocket {
/// Err(e) => println!("recv function failed: {:?}", e),
/// }
/// ```
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
pub fn recv(&self, _buf: &mut [u8]) -> io::Result<usize> {
unimplemented!()
}
@ -244,7 +252,7 @@ impl I2pDatagramSocket {
/// Err(e) => println!("peek function failed: {:?}", e),
/// }
/// ```
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
pub fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {
unimplemented!()
}
}
}

View File

@ -36,7 +36,9 @@ impl I2pAddr {
/// let addr = I2pAddr::new("example.i2p");
/// ```
pub fn new(dest: &str) -> I2pAddr {
I2pAddr { inner: dest.to_string() }
I2pAddr {
inner: dest.to_string(),
}
}
/// Returns the String that makes up this address.
@ -55,13 +57,13 @@ impl I2pAddr {
}
impl fmt::Display for I2pAddr {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}", self.inner)
}
}
impl fmt::Debug for I2pAddr {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, fmt)
}
}

View File

@ -2,9 +2,9 @@ use std::io;
use std::net::{SocketAddr, ToSocketAddrs};
pub use self::addr::{I2pSocketAddr, ToI2pSocketAddrs};
pub use self::i2p::I2pAddr;
pub use self::streaming::{I2pStream, I2pListener};
pub use self::datagram::I2pDatagramSocket;
pub use self::i2p::I2pAddr;
pub use self::streaming::{I2pListener, I2pStream};
mod addr;
mod datagram;
@ -13,7 +13,11 @@ mod streaming;
#[cfg(test)]
mod test;
fn each_addr<A: ToSocketAddrs, B: ToI2pSocketAddrs, F, T>(sam_addr: A, addr: B, mut f: F) -> io::Result<T>
fn each_addr<A: ToSocketAddrs, B: ToI2pSocketAddrs, F, T>(
sam_addr: A,
addr: B,
mut f: F,
) -> io::Result<T>
where
F: FnMut(&SocketAddr, &I2pSocketAddr) -> io::Result<T>,
{
@ -26,14 +30,10 @@ where
}
}
}
Err(
last_err.unwrap_or_else(
|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"could not resolve to any addresses",
)
},
),
)
Err(last_err.unwrap_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"could not resolve to any addresses",
)
}))
}

View File

@ -7,8 +7,8 @@ use std::net::{Shutdown, SocketAddr, ToSocketAddrs};
use rand;
use rand::Rng;
use net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
use sam::{DEFAULT_API, StreamConnect};
use crate::net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
use crate::sam::{StreamConnect, DEFAULT_API};
/// A structure which represents an I2P stream between a local socket and a
/// remote socket.
@ -71,7 +71,9 @@ pub struct I2pListener {}
/// [`incoming`]: struct.I2pListener.html#method.incoming
/// [`I2pListener`]: struct.I2pListener.html
#[derive(Debug)]
pub struct Incoming<'a> { listener: &'a I2pListener }
pub struct Incoming<'a> {
listener: &'a I2pListener,
}
impl I2pStream {
/// Opens a TCP-like connection to a remote host.
@ -98,7 +100,10 @@ impl I2pStream {
I2pStream::connect_via(DEFAULT_API, addr)
}
pub fn connect_via<A: ToSocketAddrs, B: ToI2pSocketAddrs>(sam_addr: A, addr: B) -> io::Result<I2pStream> {
pub fn connect_via<A: ToSocketAddrs, B: ToI2pSocketAddrs>(
sam_addr: A,
addr: B,
) -> io::Result<I2pStream> {
super::each_addr(sam_addr, addr, I2pStream::connect_addr)
}
@ -124,7 +129,9 @@ impl I2pStream {
/// I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080));
/// ```
pub fn peer_addr(&self) -> io::Result<I2pSocketAddr> {
self.inner.peer_addr().map(|(d, p)| I2pSocketAddr::new(I2pAddr::new(&d), p))
self.inner
.peer_addr()
.map(|(d, p)| I2pSocketAddr::new(I2pAddr::new(&d), p))
}
/// Returns the socket address of the local half of this I2P connection.
@ -140,7 +147,9 @@ impl I2pStream {
/// I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080));
/// ```
pub fn local_addr(&self) -> io::Result<I2pSocketAddr> {
self.inner.local_addr().map(|(d, p)| I2pSocketAddr::new(I2pAddr::new(&d), p))
self.inner
.local_addr()
.map(|(d, p)| I2pSocketAddr::new(I2pAddr::new(&d), p))
}
/// Shuts down the read, write, or both halves of this connection.
@ -202,7 +211,7 @@ impl Write for I2pStream {
}
impl fmt::Debug for I2pStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut res = f.debug_struct("I2pStream");
if let Ok(addr) = self.local_addr() {
@ -239,11 +248,14 @@ impl I2pListener {
I2pListener::bind_via(DEFAULT_API, addr)
}
pub fn bind_via<A: ToSocketAddrs, B: ToI2pSocketAddrs>(sam_addr: A, addr: B) -> io::Result<I2pListener> {
pub fn bind_via<A: ToSocketAddrs, B: ToI2pSocketAddrs>(
sam_addr: A,
addr: B,
) -> io::Result<I2pListener> {
super::each_addr(sam_addr, addr, I2pListener::bind_addr)
}
fn bind_addr(sam_addr: &SocketAddr, addr: &I2pSocketAddr) -> io::Result<I2pListener> {
fn bind_addr(_sam_addr: &SocketAddr, _addr: &I2pSocketAddr) -> io::Result<I2pListener> {
unimplemented!();
}
@ -326,7 +338,7 @@ impl I2pListener {
/// }
/// }
/// ```
pub fn incoming(&self) -> Incoming {
pub fn incoming(&self) -> Incoming<'_> {
Incoming { listener: self }
}
}
@ -339,7 +351,7 @@ impl<'a> Iterator for Incoming<'a> {
}
impl fmt::Debug for I2pListener {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
unimplemented!()
}
}

View File

@ -1,4 +1,4 @@
use net::{I2pSocketAddr, I2pAddr, ToI2pSocketAddrs};
use crate::net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
pub fn isa(a: I2pAddr, p: u16) -> I2pSocketAddr {
I2pSocketAddr::new(a, p)

View File

@ -1,4 +1,4 @@
use nom::{space, alphanumeric};
use nom::{alphanumeric, space};
fn is_space(chr: char) -> bool {
chr == ' ' || chr == '\t'
@ -85,74 +85,100 @@ named!(pub sam_dest_reply <&str, Vec<(&str, &str)> >,
#[cfg(test)]
mod tests {
use nom::ErrorKind;
use nom::IResult::Done;
use nom::IResult::Error;
use nom::ErrorKind;
#[test]
fn hello() {
use parsers::sam_hello;
use crate::parsers::sam_hello;
assert_eq!(
sam_hello("HELLO REPLY RESULT=OK VERSION=3.1\n"),
Done("", vec![("RESULT", "OK"), ("VERSION", "3.1")]));
Done("", vec![("RESULT", "OK"), ("VERSION", "3.1")])
);
assert_eq!(
sam_hello("HELLO REPLY RESULT=NOVERSION\n"),
Done("", vec![("RESULT", "NOVERSION")]));
Done("", vec![("RESULT", "NOVERSION")])
);
assert_eq!(
sam_hello("HELLO REPLY RESULT=I2P_ERROR MESSAGE=\"Something failed\"\n"),
Done("", vec![("RESULT", "I2P_ERROR"), ("MESSAGE", "Something failed")]));
Done(
"",
vec![("RESULT", "I2P_ERROR"), ("MESSAGE", "Something failed")]
)
);
}
#[test]
fn session_status() {
use parsers::sam_session_status;
use crate::parsers::sam_session_status;
assert_eq!(
sam_session_status("SESSION STATUS RESULT=OK DESTINATION=privkey\n"),
Done("", vec![("RESULT", "OK"), ("DESTINATION", "privkey")]));
Done("", vec![("RESULT", "OK"), ("DESTINATION", "privkey")])
);
assert_eq!(
sam_session_status("SESSION STATUS RESULT=DUPLICATED_ID\n"),
Done("", vec![("RESULT", "DUPLICATED_ID")]));
Done("", vec![("RESULT", "DUPLICATED_ID")])
);
}
#[test]
fn stream_status() {
use parsers::sam_stream_status;
use crate::parsers::sam_stream_status;
assert_eq!(
sam_stream_status("STREAM STATUS RESULT=OK\n"),
Done("", vec![("RESULT", "OK")]));
Done("", vec![("RESULT", "OK")])
);
assert_eq!(
sam_stream_status("STREAM STATUS RESULT=CANT_REACH_PEER MESSAGE=\"Can't reach peer\"\n"),
Done("", vec![("RESULT", "CANT_REACH_PEER"), ("MESSAGE", "Can't reach peer")]));
sam_stream_status(
"STREAM STATUS RESULT=CANT_REACH_PEER MESSAGE=\"Can't reach peer\"\n"
),
Done(
"",
vec![
("RESULT", "CANT_REACH_PEER"),
("MESSAGE", "Can't reach peer")
]
)
);
}
#[test]
fn naming_reply() {
use parsers::sam_naming_reply;
use crate::parsers::sam_naming_reply;
assert_eq!(
sam_naming_reply("NAMING REPLY RESULT=OK NAME=name VALUE=dest\n"),
Done("", vec![("RESULT", "OK"), ("NAME", "name"), ("VALUE", "dest")]));
Done(
"",
vec![("RESULT", "OK"), ("NAME", "name"), ("VALUE", "dest")]
)
);
assert_eq!(
sam_naming_reply("NAMING REPLY RESULT=KEY_NOT_FOUND\n"),
Done("", vec![("RESULT", "KEY_NOT_FOUND")]));
Done("", vec![("RESULT", "KEY_NOT_FOUND")])
);
assert_eq!(
sam_naming_reply("NAMINGREPLY RESULT=KEY_NOT_FOUND\n"),
Error(ErrorKind::Tag));
Error(ErrorKind::Tag)
);
assert_eq!(
sam_naming_reply("NAMING REPLY RESULT=KEY_NOT_FOUND\n"),
Error(ErrorKind::Tag));
Error(ErrorKind::Tag)
);
}
#[test]
fn dest_reply() {
use parsers::sam_dest_reply;
use crate::parsers::sam_dest_reply;
assert_eq!(
sam_dest_reply("DEST REPLY PUB=foo PRIV=foobar\n"),
Done("", vec![("PUB", "foo"), ("PRIV", "foobar")]));
Done("", vec![("PUB", "foo"), ("PRIV", "foobar")])
);
}
}

View File

@ -3,12 +3,12 @@ use std::io::prelude::*;
use std::clone::Clone;
use std::collections::HashMap;
use std::io;
use std::io::{Error, ErrorKind, BufReader};
use std::io::{BufReader, Error, ErrorKind};
use std::net::{Shutdown, SocketAddr, TcpStream, ToSocketAddrs};
use nom::IResult;
use parsers::{sam_hello, sam_naming_reply, sam_session_status, sam_stream_status};
use crate::parsers::{sam_hello, sam_naming_reply, sam_session_status, sam_stream_status};
pub static DEFAULT_API: &'static str = "127.0.0.1:7656";
@ -55,9 +55,9 @@ fn verify_response<'a>(vec: &'a [(&str, &str)]) -> Result<HashMap<&'a str, &'a s
let msg = map.get("MESSAGE").unwrap_or(&"").clone();
match res {
"OK" => Ok(map),
"CANT_REACH_PEER" |
"KEY_NOT_FOUND" |
"PEER_NOT_FOUND" => Err(Error::new(ErrorKind::NotFound, msg)),
"CANT_REACH_PEER" | "KEY_NOT_FOUND" | "PEER_NOT_FOUND" => {
Err(Error::new(ErrorKind::NotFound, msg))
}
"DUPLICATED_DEST" => Err(Error::new(ErrorKind::AddrInUse, msg)),
"INVALID_KEY" | "INVALID_ID" => Err(Error::new(ErrorKind::InvalidInput, msg)),
"TIMEOUT" => Err(Error::new(ErrorKind::TimedOut, msg)),
@ -81,19 +81,19 @@ impl SamConnection {
let response = reply_parser(&buffer);
let vec_opts = response.unwrap().1;
verify_response(&vec_opts).map(
|m| {
m.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect()
},
)
verify_response(&vec_opts).map(|m| {
m.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect()
})
}
fn handshake(&mut self) -> Result<HashMap<String, String>, Error> {
let hello_msg = format!("HELLO VERSION MIN={min} MAX={max} \n",
min = SAM_MIN,
max = SAM_MAX);
let hello_msg = format!(
"HELLO VERSION MIN={min} MAX={max} \n",
min = SAM_MIN,
max = SAM_MAX
);
self.send(hello_msg, sam_hello)
}
@ -127,21 +127,21 @@ impl Session {
style: SessionStyle,
) -> Result<Session, Error> {
let mut sam = SamConnection::connect(sam_addr).unwrap();
let create_session_msg = format!("SESSION CREATE STYLE={style} ID={nickname} DESTINATION={destination} \n",
style = style.string(),
nickname = nickname,
destination = destination);
let create_session_msg = format!(
"SESSION CREATE STYLE={style} ID={nickname} DESTINATION={destination} \n",
style = style.string(),
nickname = nickname,
destination = destination
);
sam.send(create_session_msg, sam_session_status)?;
let local_dest = sam.naming_lookup("ME")?;
Ok(
Session {
sam: sam,
local_dest: local_dest,
},
)
Ok(Session {
sam: sam,
local_dest: local_dest,
})
}
pub fn sam_api(&self) -> io::Result<SocketAddr> {
@ -153,16 +153,10 @@ impl Session {
}
pub fn duplicate(&self) -> io::Result<Session> {
self.sam
.duplicate()
.map(
|s| {
Session {
sam: s,
local_dest: self.local_dest.clone(),
}
},
)
self.sam.duplicate().map(|s| Session {
sam: s,
local_dest: self.local_dest.clone(),
})
}
}
@ -176,24 +170,24 @@ impl StreamConnect {
let mut session = Session::create(sam_addr, "TRANSIENT", nickname, SessionStyle::Stream)?;
let mut sam = SamConnection::connect(session.sam_api()?).unwrap();
let create_stream_msg = format!("STREAM CONNECT ID={nickname} DESTINATION={destination} SILENT=false TO_PORT={port}\n",
nickname = nickname,
destination = destination,
port = port);
let create_stream_msg = format!(
"STREAM CONNECT ID={nickname} DESTINATION={destination} SILENT=false TO_PORT={port}\n",
nickname = nickname,
destination = destination,
port = port
);
sam.send(create_stream_msg, sam_stream_status)?;
let peer_dest = session.naming_lookup(destination)?;
Ok(
StreamConnect {
sam: sam,
session: session,
peer_dest: peer_dest,
peer_port: port,
local_port: 0,
},
)
Ok(StreamConnect {
sam: sam,
session: session,
peer_dest: peer_dest,
peer_port: port,
local_port: 0,
})
}
pub fn peer_addr(&self) -> io::Result<(String, u16)> {
@ -209,15 +203,13 @@ impl StreamConnect {
}
pub fn duplicate(&self) -> io::Result<StreamConnect> {
Ok(
StreamConnect {
sam: self.sam.duplicate()?,
session: self.session.duplicate()?,
peer_dest: self.peer_dest.clone(),
peer_port: self.peer_port,
local_port: self.local_port,
},
)
Ok(StreamConnect {
sam: self.sam.duplicate()?,
session: self.session.duplicate()?,
peer_dest: self.peer_dest.clone(),
peer_port: self.peer_port,
local_port: self.local_port,
})
}
}

View File

@ -1,5 +1,3 @@
extern crate i2p;
#[test]
#[ignore]
fn naming_lookup() {