@ -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
|
||||
|
@ -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" }
|
||||
|
@ -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]")
|
||||
|
@ -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"
|
@ -3,8 +3,6 @@ extern crate nom;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
extern crate rand;
|
||||
|
||||
pub mod net;
|
||||
pub mod sam;
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
)
|
||||
}))
|
||||
}
|
||||
|
@ -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!()
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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")])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
106
src/sam.rs
106
src/sam.rs
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
extern crate i2p;
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn naming_lookup() {
|
||||
|
Reference in New Issue
Block a user