Latest formatting from cargo fmt

This commit is contained in:
Ignotus Peverell
2019-03-06 23:16:06 +00:00
committed by bonedaddy
parent c23a90ca1c
commit 9f95a08e5f
11 changed files with 1025 additions and 1011 deletions

View File

@ -1,43 +1,44 @@
extern crate i2p;
extern crate env_logger;
extern crate i2p;
use i2p::net::I2pStream;
use std::env;
use std::io::{BufReader, Read, Write};
fn help() {
println!("Usage: eepget <host.i2p> [port]")
println!("Usage: eepget <host.i2p> [port]")
}
fn print_homepage(host: &str, port: u16) {
let mut stream = I2pStream::connect(format!("{}:{}", host, port)).unwrap();
let mut stream = I2pStream::connect(format!("{}:{}", host, port)).unwrap();
let msg = "GET / HTTP/1.1\r\n\r\n";
let _ = stream.write(msg.as_bytes());
let mut reader = BufReader::new(stream);
let mut buffer = String::new();
let _ = reader.read_to_string(&mut buffer);
let msg = "GET / HTTP/1.1\r\n\r\n";
let _ = stream.write(msg.as_bytes());
let mut reader = BufReader::new(stream);
let mut buffer = String::new();
let _ = reader.read_to_string(&mut buffer);
println!("{}", buffer);
println!("{}", buffer);
}
fn main() {
env_logger::init();
let args: Vec<String> = env::args().collect();
match args.len() {
2 => print_homepage(&args[1], 80),
3 => {
let host = &args[1];
let port = &args[2];
let port_num: u16 = match port.parse() {
Ok(n) => n,
Err(_) => {
println!("Port must be an integer");
help();
return;
}
};
print_homepage(host, port_num)
}
_ => help(),
}
env_logger::init();
let args: Vec<String> = env::args().collect();
match args.len() {
2 => print_homepage(&args[1], 80),
3 => {
let host = &args[1];
let port = &args[2];
let port_num: u16 = match port.parse() {
Ok(n) => n,
Err(_) => {
println!("Port must be an integer");
help();
return;
}
};
print_homepage(host, port_num)
}
_ => help(),
}
}

1
rustfmt.toml Normal file
View File

@ -0,0 +1 @@
hard_tabs = true

View File

@ -9,117 +9,117 @@ use std::vec;
use crate::net::i2p::I2pAddr;
pub struct I2pSocketAddr {
port: u16,
dest: I2pAddr,
port: u16,
dest: I2pAddr,
}
impl I2pSocketAddr {
/// Creates a new socket address from the (dest, port) pair.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// assert_eq!(socket.dest(), I2pAddr::new("example.i2p"));
/// assert_eq!(socket.port(), 8080);
/// ```
pub fn new(dest: I2pAddr, port: u16) -> I2pSocketAddr {
I2pSocketAddr {
port: port,
dest: dest,
}
}
/// Creates a new socket address from the (dest, port) pair.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// assert_eq!(socket.dest(), I2pAddr::new("example.i2p"));
/// assert_eq!(socket.port(), 8080);
/// ```
pub fn new(dest: I2pAddr, port: u16) -> I2pSocketAddr {
I2pSocketAddr {
port: port,
dest: dest,
}
}
/// Returns the I2P address associated with this socket address.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// assert_eq!(socket.dest(), I2pAddr::new("example.i2p"));
/// ```
pub fn dest(&self) -> I2pAddr {
self.dest.clone()
}
/// Returns the I2P address associated with this socket address.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// assert_eq!(socket.dest(), I2pAddr::new("example.i2p"));
/// ```
pub fn dest(&self) -> I2pAddr {
self.dest.clone()
}
/// Change the I2P address associated with this socket address.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let mut socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// socket.set_dest(I2pAddr::new("foobar.i2p"));
/// assert_eq!(socket.dest(), I2pAddr::new("foobar.i2p"));
/// ```
pub fn set_dest(&mut self, new_dest: I2pAddr) {
self.dest = new_dest;
}
/// Change the I2P address associated with this socket address.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let mut socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// socket.set_dest(I2pAddr::new("foobar.i2p"));
/// assert_eq!(socket.dest(), I2pAddr::new("foobar.i2p"));
/// ```
pub fn set_dest(&mut self, new_dest: I2pAddr) {
self.dest = new_dest;
}
/// Returns the port number associated with this socket address.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// assert_eq!(socket.port(), 8080);
/// ```
pub fn port(&self) -> u16 {
self.port
}
/// Returns the port number associated with this socket address.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// assert_eq!(socket.port(), 8080);
/// ```
pub fn port(&self) -> u16 {
self.port
}
/// Change the port number associated with this socket address.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let mut socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// socket.set_port(1025);
/// assert_eq!(socket.port(), 1025);
/// ```
pub fn set_port(&mut self, new_port: u16) {
self.port = new_port;
}
/// Change the port number associated with this socket address.
///
/// # Examples
///
/// ```
/// use i2p::net::{I2pAddr, I2pSocketAddr};
///
/// let mut socket = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080);
/// socket.set_port(1025);
/// assert_eq!(socket.port(), 1025);
/// ```
pub fn set_port(&mut self, new_port: u16) {
self.port = new_port;
}
}
impl fmt::Display for I2pSocketAddr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.dest(), self.port())
}
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 {
fmt::Display::fmt(self, fmt)
}
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, fmt)
}
}
impl Clone for I2pSocketAddr {
fn clone(&self) -> I2pSocketAddr {
I2pSocketAddr::new(self.dest.clone(), self.port)
}
fn clone(&self) -> I2pSocketAddr {
I2pSocketAddr::new(self.dest.clone(), self.port)
}
}
impl PartialEq for I2pSocketAddr {
fn eq(&self, other: &I2pSocketAddr) -> bool {
self.port == other.port && self.dest == other.dest
}
fn eq(&self, other: &I2pSocketAddr) -> bool {
self.port == other.port && self.dest == other.dest
}
}
impl Eq for I2pSocketAddr {}
impl hash::Hash for I2pSocketAddr {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
(self.port, &self.dest).hash(s)
}
fn hash<H: hash::Hasher>(&self, s: &mut H) {
(self.port, &self.dest).hash(s)
}
}
/// A trait for objects which can be converted or resolved to one or more
@ -176,161 +176,161 @@ impl hash::Hash for I2pSocketAddr {
/// }
/// ```
pub trait ToI2pSocketAddrs {
/// Returned iterator over socket addresses which this type may correspond
/// to.
type Iter: Iterator<Item = I2pSocketAddr>;
/// Returned iterator over socket addresses which this type may correspond
/// to.
type Iter: Iterator<Item = I2pSocketAddr>;
/// Converts this object to an iterator of resolved `I2pSocketAddr`s.
///
/// The returned iterator may not actually yield any values depending on the
/// outcome of any resolution performed.
///
/// Note that this function may block the current thread while resolution is
/// performed.
///
/// # Errors
///
/// Any errors encountered during resolution will be returned as an `Err`.
fn to_socket_addrs(&self) -> io::Result<Self::Iter>;
/// Converts this object to an iterator of resolved `I2pSocketAddr`s.
///
/// The returned iterator may not actually yield any values depending on the
/// outcome of any resolution performed.
///
/// Note that this function may block the current thread while resolution is
/// performed.
///
/// # Errors
///
/// Any errors encountered during resolution will be returned as an `Err`.
fn to_socket_addrs(&self) -> io::Result<Self::Iter>;
}
impl ToI2pSocketAddrs for I2pSocketAddr {
type Iter = option::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<option::IntoIter<I2pSocketAddr>> {
Ok(Some(self.clone()).into_iter())
}
type Iter = option::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<option::IntoIter<I2pSocketAddr>> {
Ok(Some(self.clone()).into_iter())
}
}
impl ToI2pSocketAddrs for (I2pAddr, u16) {
type Iter = option::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<option::IntoIter<I2pSocketAddr>> {
let (dest, port) = self.clone();
I2pSocketAddr::new(dest, port).to_socket_addrs()
}
type Iter = option::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<option::IntoIter<I2pSocketAddr>> {
let (dest, port) = self.clone();
I2pSocketAddr::new(dest, port).to_socket_addrs()
}
}
impl<'a> ToI2pSocketAddrs for (&'a str, u16) {
type Iter = vec::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<I2pSocketAddr>> {
let (host, port) = *self;
let addr = I2pSocketAddr::new(I2pAddr::new(host), port);
Ok(vec![addr].into_iter())
}
type Iter = vec::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<I2pSocketAddr>> {
let (host, port) = *self;
let addr = I2pSocketAddr::new(I2pAddr::new(host), port);
Ok(vec![addr].into_iter())
}
}
// accepts strings like 'example.i2p:12345'
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) => {
match $e {
Some(r) => r,
None => return Err(io::Error::new(io::ErrorKind::InvalidInput, $msg)),
}
};
}
type Iter = vec::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<I2pSocketAddr>> {
macro_rules! try_opt {
($e:expr, $msg:expr) => {
match $e {
Some(r) => r,
None => return Err(io::Error::new(io::ErrorKind::InvalidInput, $msg)),
}
};
}
// split the string by ':' and convert the second part to u16
let mut parts_iter = self.rsplitn(2, ':');
let port_str = try_opt!(parts_iter.next(), "invalid I2P socket address");
let host = try_opt!(parts_iter.next(), "invalid I2P socket address");
let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
(host, port).to_socket_addrs()
}
// split the string by ':' and convert the second part to u16
let mut parts_iter = self.rsplitn(2, ':');
let port_str = try_opt!(parts_iter.next(), "invalid I2P socket address");
let host = try_opt!(parts_iter.next(), "invalid I2P socket address");
let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
(host, port).to_socket_addrs()
}
}
impl<'a> ToI2pSocketAddrs for &'a [I2pSocketAddr] {
type Iter = iter::Cloned<slice::Iter<'a, I2pSocketAddr>>;
type Iter = iter::Cloned<slice::Iter<'a, I2pSocketAddr>>;
fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
Ok(self.iter().cloned())
}
fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
Ok(self.iter().cloned())
}
}
impl<'a, T: ToI2pSocketAddrs + ?Sized> ToI2pSocketAddrs for &'a T {
type Iter = T::Iter;
fn to_socket_addrs(&self) -> io::Result<T::Iter> {
(**self).to_socket_addrs()
}
type Iter = T::Iter;
fn to_socket_addrs(&self) -> io::Result<T::Iter> {
(**self).to_socket_addrs()
}
}
impl ToI2pSocketAddrs for String {
type Iter = vec::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<I2pSocketAddr>> {
(&**self).to_socket_addrs()
}
type Iter = vec::IntoIter<I2pSocketAddr>;
fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<I2pSocketAddr>> {
(&**self).to_socket_addrs()
}
}
#[cfg(test)]
mod tests {
use crate::net::test::{isa, tsa};
use crate::net::*;
use net::test::{isa, tsa};
use net::*;
#[test]
fn to_socket_addr_i2paddr_u16() {
let a = I2pAddr::new("example.i2p");
let p = 12345;
let e = I2pSocketAddr::new(a.clone(), p);
assert_eq!(Ok(vec![e]), tsa((a, p)));
}
#[test]
fn to_socket_addr_i2paddr_u16() {
let a = I2pAddr::new("example.i2p");
let p = 12345;
let e = I2pSocketAddr::new(a.clone(), p);
assert_eq!(Ok(vec![e]), tsa((a, p)));
}
#[test]
fn to_socket_addr_str_u16() {
let a = isa(I2pAddr::new("example.i2p"), 24352);
assert_eq!(Ok(vec![a]), tsa(("example.i2p", 24352)));
#[test]
fn to_socket_addr_str_u16() {
let a = isa(I2pAddr::new("example.i2p"), 24352);
assert_eq!(Ok(vec![a]), tsa(("example.i2p", 24352)));
let a = isa(I2pAddr::new("example.i2p"), 23924);
assert!(tsa(("example.i2p", 23924)).unwrap().contains(&a));
}
let a = isa(I2pAddr::new("example.i2p"), 23924);
assert!(tsa(("example.i2p", 23924)).unwrap().contains(&a));
}
#[test]
fn to_socket_addr_str() {
let a = isa(I2pAddr::new("example.i2p"), 24352);
assert_eq!(Ok(vec![a]), tsa("example.i2p:24352"));
#[test]
fn to_socket_addr_str() {
let a = isa(I2pAddr::new("example.i2p"), 24352);
assert_eq!(Ok(vec![a]), tsa("example.i2p:24352"));
let a = isa(I2pAddr::new("example.i2p"), 23924);
assert!(tsa("example.i2p:23924").unwrap().contains(&a));
}
let a = isa(I2pAddr::new("example.i2p"), 23924);
assert!(tsa("example.i2p:23924").unwrap().contains(&a));
}
#[test]
fn to_socket_addr_string() {
let a = isa(I2pAddr::new("example.i2p"), 24352);
assert_eq!(
Ok(vec![a.clone()]),
tsa(&*format!("{}:{}", "example.i2p", "24352"))
);
assert_eq!(
Ok(vec![a.clone()]),
tsa(&format!("{}:{}", "example.i2p", "24352"))
);
assert_eq!(
Ok(vec![a.clone()]),
tsa(format!("{}:{}", "example.i2p", "24352"))
);
#[test]
fn to_socket_addr_string() {
let a = isa(I2pAddr::new("example.i2p"), 24352);
assert_eq!(
Ok(vec![a.clone()]),
tsa(&*format!("{}:{}", "example.i2p", "24352"))
);
assert_eq!(
Ok(vec![a.clone()]),
tsa(&format!("{}:{}", "example.i2p", "24352"))
);
assert_eq!(
Ok(vec![a.clone()]),
tsa(format!("{}:{}", "example.i2p", "24352"))
);
let s = format!("{}:{}", "example.i2p", "24352");
assert_eq!(Ok(vec![a]), tsa(s));
// s has been moved into the tsa call
}
let s = format!("{}:{}", "example.i2p", "24352");
assert_eq!(Ok(vec![a]), tsa(s));
// s has been moved into the tsa call
}
#[test]
fn set_dest() {
fn i2p(low: u8) -> I2pAddr {
I2pAddr::new(&format!("example{}.i2p", low))
}
#[test]
fn set_dest() {
fn i2p(low: u8) -> I2pAddr {
I2pAddr::new(&format!("example{}.i2p", low))
}
let mut addr = I2pSocketAddr::new(i2p(12), 80);
assert_eq!(addr.dest(), i2p(12));
addr.set_dest(i2p(13));
assert_eq!(addr.dest(), i2p(13));
}
let mut addr = I2pSocketAddr::new(i2p(12), 80);
assert_eq!(addr.dest(), i2p(12));
addr.set_dest(i2p(13));
assert_eq!(addr.dest(), i2p(13));
}
#[test]
fn set_port() {
let mut addr = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 80);
assert_eq!(addr.port(), 80);
addr.set_port(8080);
assert_eq!(addr.port(), 8080);
}
#[test]
fn set_port() {
let mut addr = I2pSocketAddr::new(I2pAddr::new("example.i2p"), 80);
assert_eq!(addr.port(), 80);
addr.set_port(8080);
assert_eq!(addr.port(), 8080);
}
}

View File

@ -37,219 +37,224 @@ use crate::sam::DEFAULT_API;
pub struct I2pDatagramSocket {}
impl I2pDatagramSocket {
/// Creates an I2P datagram socket from the given address.
///
/// The address type can be any implementor of [`ToI2pSocketAddrs`] trait. See
/// its documentation for concrete examples.
///
/// [`ToI2pSocketAddrs`]: ../../i2p/net/trait.ToI2pSocketAddrs.html
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// ```
pub fn bind<A: ToI2pSocketAddrs>(addr: A) -> io::Result<I2pDatagramSocket> {
I2pDatagramSocket::bind_via(DEFAULT_API, addr)
}
/// Creates an I2P datagram socket from the given address.
///
/// The address type can be any implementor of [`ToI2pSocketAddrs`] trait. See
/// its documentation for concrete examples.
///
/// [`ToI2pSocketAddrs`]: ../../i2p/net/trait.ToI2pSocketAddrs.html
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// ```
pub fn bind<A: ToI2pSocketAddrs>(addr: A) -> io::Result<I2pDatagramSocket> {
I2pDatagramSocket::bind_via(DEFAULT_API, addr)
}
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)
}
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> {
unimplemented!();
}
fn bind_addr(_sam_addr: &SocketAddr, _addr: &I2pSocketAddr) -> io::Result<I2pDatagramSocket> {
unimplemented!();
}
/// Receives data from the socket. On success, returns the number of bytes
/// read and the address from whence the data came.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// let mut buf = [0; 10];
/// 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)> {
unimplemented!()
}
/// Receives data from the socket. On success, returns the number of bytes
/// read and the address from whence the data came.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// let mut buf = [0; 10];
/// 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)> {
unimplemented!()
}
/// Receives data from the socket, without removing it from the queue.
///
/// Successive calls return the same data.
///
/// On success, returns the number of bytes peeked and the address from
/// whence the data came.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// let mut buf = [0; 10];
/// 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)> {
unimplemented!()
}
/// Receives data from the socket, without removing it from the queue.
///
/// Successive calls return the same data.
///
/// On success, returns the number of bytes peeked and the address from
/// whence the data came.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// let mut buf = [0; 10];
/// 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)> {
unimplemented!()
}
/// Sends data on the socket to the given address. On success, returns the
/// number of bytes written.
///
/// Address type can be any implementor of [`ToI2pSocketAddrs`] trait. See
/// its documentation for concrete examples.
///
/// [`ToI2pSocketAddrs`]: ../../std/net/trait.ToI2pSocketAddrs.html
///
/// # Examples
///
/// ```no_run
/// use i2p::net::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> {
match addr.to_socket_addrs()?.next() {
Some(_addr) => unimplemented!(),
None => Err(Error::new(ErrorKind::InvalidInput,
"no addresses to send data to")),
}
}
/// Sends data on the socket to the given address. On success, returns the
/// number of bytes written.
///
/// Address type can be any implementor of [`ToI2pSocketAddrs`] trait. See
/// its documentation for concrete examples.
///
/// [`ToI2pSocketAddrs`]: ../../std/net/trait.ToI2pSocketAddrs.html
///
/// # Examples
///
/// ```no_run
/// use i2p::net::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> {
match addr.to_socket_addrs()?.next() {
Some(_addr) => unimplemented!(),
None => Err(Error::new(
ErrorKind::InvalidInput,
"no addresses to send data to",
)),
}
}
/// Returns the socket address that this socket was created from.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::{I2pAddr, I2pSocketAddr, I2pDatagramSocket};
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// assert_eq!(socket.local_addr().unwrap(),
/// I2pSocketAddr::new(I2pAddr::new("example.i2p"), 34254));
/// ```
pub fn local_addr(&self) -> io::Result<I2pSocketAddr> {
unimplemented!()
}
/// Returns the socket address that this socket was created from.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::{I2pAddr, I2pSocketAddr, I2pDatagramSocket};
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// assert_eq!(socket.local_addr().unwrap(),
/// I2pSocketAddr::new(I2pAddr::new("example.i2p"), 34254));
/// ```
pub fn local_addr(&self) -> io::Result<I2pSocketAddr> {
unimplemented!()
}
/// Creates a new independently owned handle to the underlying socket.
///
/// The returned `I2pDatagramSocket` is a reference to the same socket that this
/// object references. Both handles will read and write the same port, and
/// options set on one socket will be propagated to the other.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// let socket_clone = socket.try_clone().expect("couldn't clone the socket");
/// ```
pub fn try_clone(&self) -> io::Result<I2pDatagramSocket> {
unimplemented!()
}
/// Creates a new independently owned handle to the underlying socket.
///
/// The returned `I2pDatagramSocket` is a reference to the same socket that this
/// object references. Both handles will read and write the same port, and
/// options set on one socket will be propagated to the other.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// let socket_clone = socket.try_clone().expect("couldn't clone the socket");
/// ```
pub fn try_clone(&self) -> io::Result<I2pDatagramSocket> {
unimplemented!()
}
/// Connects this datagram socket to a remote address, allowing the `send` and
/// `recv` calls to be used to send data and also applies filters to only
/// receive data from the specified address.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
/// ```
pub fn connect<A: ToI2pSocketAddrs>(&self, addr: A) -> io::Result<()> {
self.connect_via(DEFAULT_API, addr)
}
/// Connects this datagram socket to a remote address, allowing the `send` and
/// `recv` calls to be used to send data and also applies filters to only
/// receive data from the specified address.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
/// ```
pub fn connect<A: ToI2pSocketAddrs>(&self, addr: A) -> io::Result<()> {
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.
///
/// The [`connect()`] method will connect this socket to a remote address. This
/// method will fail if the socket is not connected.
///
/// [`connect()`]: #method.connect
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// 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> {
unimplemented!()
}
/// Sends data on the socket to the remote address to which it is connected.
///
/// The [`connect()`] method will connect this socket to a remote address. This
/// method will fail if the socket is not connected.
///
/// [`connect()`]: #method.connect
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// 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> {
unimplemented!()
}
/// Receives data on the socket from the remote address to which it is
/// connected.
///
/// The `connect` method will connect this socket to a remote address. This
/// method will fail if the socket is not connected.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
/// let mut buf = [0; 10];
/// match socket.recv(&mut buf) {
/// Ok(received) => println!("received {} bytes", received),
/// Err(e) => println!("recv function failed: {:?}", e),
/// }
/// ```
pub fn recv(&self, _buf: &mut [u8]) -> io::Result<usize> {
unimplemented!()
}
/// Receives data on the socket from the remote address to which it is
/// connected.
///
/// The `connect` method will connect this socket to a remote address. This
/// method will fail if the socket is not connected.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
/// let mut buf = [0; 10];
/// match socket.recv(&mut buf) {
/// Ok(received) => println!("received {} bytes", received),
/// Err(e) => println!("recv function failed: {:?}", e),
/// }
/// ```
pub fn recv(&self, _buf: &mut [u8]) -> io::Result<usize> {
unimplemented!()
}
/// Receives data on the socket from the remote adress to which it is
/// connected, without removing that data from the queue. On success,
/// returns the number of bytes peeked.
///
/// Successive calls return the same data.
///
/// # Errors
///
/// This method will fail if the socket is not connected. The `connect` method
/// will connect this socket to a remote address.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
/// let mut buf = [0; 10];
/// match socket.peek(&mut buf) {
/// Ok(received) => println!("received {} bytes", received),
/// Err(e) => println!("peek function failed: {:?}", e),
/// }
/// ```
pub fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {
unimplemented!()
}
/// Receives data on the socket from the remote adress to which it is
/// connected, without removing that data from the queue. On success,
/// returns the number of bytes peeked.
///
/// Successive calls return the same data.
///
/// # Errors
///
/// This method will fail if the socket is not connected. The `connect` method
/// will connect this socket to a remote address.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pDatagramSocket;
///
/// let socket = I2pDatagramSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
/// let mut buf = [0; 10];
/// match socket.peek(&mut buf) {
/// Ok(received) => println!("received {} bytes", received),
/// Err(e) => println!("peek function failed: {:?}", e),
/// }
/// ```
pub fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {
unimplemented!()
}
}

View File

@ -22,80 +22,80 @@ use std::hash;
/// I2pAddr::new("abcdefghijklmnopqrstuvwxyz234567abcdefghijklmnopqrst.b32.i2p");
/// ```
pub struct I2pAddr {
inner: String,
inner: String,
}
impl I2pAddr {
/// Creates a new I2p address from a given string.
///
/// # Examples
///
/// ```
/// use i2p::net::I2pAddr;
///
/// let addr = I2pAddr::new("example.i2p");
/// ```
pub fn new(dest: &str) -> I2pAddr {
I2pAddr {
inner: dest.to_string(),
}
}
/// Creates a new I2p address from a given string.
///
/// # Examples
///
/// ```
/// use i2p::net::I2pAddr;
///
/// let addr = I2pAddr::new("example.i2p");
/// ```
pub fn new(dest: &str) -> I2pAddr {
I2pAddr {
inner: dest.to_string(),
}
}
/// Returns the String that makes up this address.
///
/// # Examples
///
/// ```
/// use i2p::net::I2pAddr;
///
/// let addr = I2pAddr::new("example.i2p");
/// assert_eq!(addr.string(), "example.i2p");
/// ```
pub fn string(&self) -> String {
self.inner.clone()
}
/// Returns the String that makes up this address.
///
/// # Examples
///
/// ```
/// use i2p::net::I2pAddr;
///
/// let addr = I2pAddr::new("example.i2p");
/// assert_eq!(addr.string(), "example.i2p");
/// ```
pub fn string(&self) -> String {
self.inner.clone()
}
}
impl fmt::Display for I2pAddr {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}", self.inner)
}
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 {
fmt::Display::fmt(self, fmt)
}
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, fmt)
}
}
impl Clone for I2pAddr {
fn clone(&self) -> I2pAddr {
I2pAddr::new(&self.inner)
}
fn clone(&self) -> I2pAddr {
I2pAddr::new(&self.inner)
}
}
impl PartialEq for I2pAddr {
fn eq(&self, other: &I2pAddr) -> bool {
self.inner == other.inner
}
fn eq(&self, other: &I2pAddr) -> bool {
self.inner == other.inner
}
}
impl Eq for I2pAddr {}
impl hash::Hash for I2pAddr {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
self.inner.hash(s)
}
fn hash<H: hash::Hasher>(&self, s: &mut H) {
self.inner.hash(s)
}
}
impl PartialOrd for I2pAddr {
fn partial_cmp(&self, other: &I2pAddr) -> Option<Ordering> {
Some(self.cmp(other))
}
fn partial_cmp(&self, other: &I2pAddr) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for I2pAddr {
fn cmp(&self, other: &I2pAddr) -> Ordering {
self.inner.cmp(&other.inner)
}
fn cmp(&self, other: &I2pAddr) -> Ordering {
self.inner.cmp(&other.inner)
}
}

View File

@ -14,26 +14,26 @@ mod streaming;
mod test;
fn each_addr<A: ToSocketAddrs, B: ToI2pSocketAddrs, F, T>(
sam_addr: A,
addr: B,
mut f: F,
sam_addr: A,
addr: B,
mut f: F,
) -> io::Result<T>
where
F: FnMut(&SocketAddr, &I2pSocketAddr) -> io::Result<T>,
F: FnMut(&SocketAddr, &I2pSocketAddr) -> io::Result<T>,
{
let mut last_err = None;
for addr in addr.to_socket_addrs()? {
for sam_addr in sam_addr.to_socket_addrs()? {
match f(&sam_addr, &addr) {
Ok(l) => return Ok(l),
Err(e) => last_err = Some(e),
}
}
}
Err(last_err.unwrap_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"could not resolve to any addresses",
)
}))
let mut last_err = None;
for addr in addr.to_socket_addrs()? {
for sam_addr in sam_addr.to_socket_addrs()? {
match f(&sam_addr, &addr) {
Ok(l) => return Ok(l),
Err(e) => last_err = Some(e),
}
}
}
Err(last_err.unwrap_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"could not resolve to any addresses",
)
}))
}

View File

@ -4,11 +4,11 @@ use std::fmt;
use std::io;
use std::net::{Shutdown, SocketAddr, ToSocketAddrs};
use rand::{self, Rng};
use rand::distributions::Alphanumeric;
use rand::{self, Rng};
use crate::net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
use crate::sam::{DEFAULT_API, StreamConnect};
use crate::sam::{StreamConnect, DEFAULT_API};
/// A structure which represents an I2P stream between a local socket and a
/// remote socket.
@ -30,7 +30,7 @@ use crate::sam::{DEFAULT_API, StreamConnect};
/// } // the stream is closed here
/// ```
pub struct I2pStream {
inner: StreamConnect,
inner: StreamConnect,
}
/// Unimplemented
@ -72,286 +72,289 @@ pub struct I2pListener {}
/// [`I2pListener`]: struct.I2pListener.html
#[derive(Debug)]
pub struct Incoming<'a> {
listener: &'a I2pListener,
listener: &'a I2pListener,
}
impl I2pStream {
/// Opens a TCP-like connection to a remote host.
///
/// `addr` is an address of the remote host. Anything which implements
/// `ToI2pSocketAddrs` trait can be supplied for the address; see this trait
/// documentation for concrete examples.
/// In case `ToI2pSocketAddrs::to_socket_addrs()` returns more than one
/// entry (which should never be the case), then the first valid and
/// reachable address is used.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pStream;
///
/// if let Ok(stream) = I2pStream::connect("example.i2p:8080") {
/// println!("Connected to the server!");
/// } else {
/// println!("Couldn't connect to server...");
/// }
/// ```
pub fn connect<A: ToI2pSocketAddrs>(addr: A) -> io::Result<I2pStream> {
I2pStream::connect_via(DEFAULT_API, addr)
}
/// Opens a TCP-like connection to a remote host.
///
/// `addr` is an address of the remote host. Anything which implements
/// `ToI2pSocketAddrs` trait can be supplied for the address; see this trait
/// documentation for concrete examples.
/// In case `ToI2pSocketAddrs::to_socket_addrs()` returns more than one
/// entry (which should never be the case), then the first valid and
/// reachable address is used.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pStream;
///
/// if let Ok(stream) = I2pStream::connect("example.i2p:8080") {
/// println!("Connected to the server!");
/// } else {
/// println!("Couldn't connect to server...");
/// }
/// ```
pub fn connect<A: ToI2pSocketAddrs>(addr: A) -> io::Result<I2pStream> {
I2pStream::connect_via(DEFAULT_API, addr)
}
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)
}
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)
}
fn connect_addr(sam_addr: &SocketAddr, addr: &I2pSocketAddr) -> io::Result<I2pStream> {
let suffix: String = rand::thread_rng().sample_iter(&Alphanumeric).take(8).collect();
let nickname = format!("i2prs-{}", suffix);
fn connect_addr(sam_addr: &SocketAddr, addr: &I2pSocketAddr) -> io::Result<I2pStream> {
let suffix: String = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(8)
.collect();
let nickname = format!("i2prs-{}", suffix);
let stream = StreamConnect::new(sam_addr, &addr.dest().string(), addr.port(), &nickname)?;
let stream = StreamConnect::new(sam_addr, &addr.dest().string(), addr.port(), &nickname)?;
Ok(I2pStream { inner: stream })
}
Ok(I2pStream { inner: stream })
}
/// Returns the socket address of the remote peer of this I2P connection.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::{I2pAddr, I2pSocketAddr, I2pStream};
///
/// let stream = I2pStream::connect("example.i2p:8080")
/// .expect("Couldn't connect to the server...");
/// assert_eq!(stream.peer_addr().unwrap(),
/// 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))
}
/// Returns the socket address of the remote peer of this I2P connection.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::{I2pAddr, I2pSocketAddr, I2pStream};
///
/// let stream = I2pStream::connect("example.i2p:8080")
/// .expect("Couldn't connect to the server...");
/// assert_eq!(stream.peer_addr().unwrap(),
/// 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))
}
/// Returns the socket address of the local half of this I2P connection.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::{I2pAddr, I2pSocketAddr, I2pStream};
///
/// let stream = I2pStream::connect("example.i2p:8080")
/// .expect("Couldn't connect to the server...");
/// assert_eq!(stream.local_addr().unwrap(),
/// 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))
}
/// Returns the socket address of the local half of this I2P connection.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::{I2pAddr, I2pSocketAddr, I2pStream};
///
/// let stream = I2pStream::connect("example.i2p:8080")
/// .expect("Couldn't connect to the server...");
/// assert_eq!(stream.local_addr().unwrap(),
/// 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))
}
/// Shuts down the read, write, or both halves of this connection.
///
/// This function will cause all pending and future I/O on the specified
/// portions to return immediately with an appropriate value (see the
/// documentation of [`Shutdown`]).
///
/// [`Shutdown`]: ../../std/net/enum.Shutdown.html
///
/// # Examples
///
/// ```no_run
/// use std::net::Shutdown;
/// use i2p::net::I2pStream;
///
/// let stream = I2pStream::connect("127.0.0.1:8080")
/// .expect("Couldn't connect to the server...");
/// stream.shutdown(Shutdown::Both).expect("shutdown call failed");
/// ```
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.inner.shutdown(how)
}
/// Shuts down the read, write, or both halves of this connection.
///
/// This function will cause all pending and future I/O on the specified
/// portions to return immediately with an appropriate value (see the
/// documentation of [`Shutdown`]).
///
/// [`Shutdown`]: ../../std/net/enum.Shutdown.html
///
/// # Examples
///
/// ```no_run
/// use std::net::Shutdown;
/// use i2p::net::I2pStream;
///
/// let stream = I2pStream::connect("127.0.0.1:8080")
/// .expect("Couldn't connect to the server...");
/// stream.shutdown(Shutdown::Both).expect("shutdown call failed");
/// ```
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.inner.shutdown(how)
}
/// Creates a new independently owned handle to the underlying socket.
///
/// The returned `I2pStream` is a reference to the same stream that this
/// object references. Both handles will read and write the same stream of
/// data, and options set on one stream will be propagated to the other
/// stream.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pStream;
///
/// let stream = I2pStream::connect("example.i2p:8080")
/// .expect("Couldn't connect to the server...");
/// let stream_clone = stream.try_clone().expect("clone failed...");
/// ```
pub fn try_clone(&self) -> io::Result<I2pStream> {
self.inner.duplicate().map(|s| I2pStream { inner: s })
}
/// Creates a new independently owned handle to the underlying socket.
///
/// The returned `I2pStream` is a reference to the same stream that this
/// object references. Both handles will read and write the same stream of
/// data, and options set on one stream will be propagated to the other
/// stream.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pStream;
///
/// let stream = I2pStream::connect("example.i2p:8080")
/// .expect("Couldn't connect to the server...");
/// let stream_clone = stream.try_clone().expect("clone failed...");
/// ```
pub fn try_clone(&self) -> io::Result<I2pStream> {
self.inner.duplicate().map(|s| I2pStream { inner: s })
}
}
impl Read for I2pStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl Write for I2pStream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl fmt::Debug for I2pStream {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut res = f.debug_struct("I2pStream");
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut res = f.debug_struct("I2pStream");
if let Ok(addr) = self.local_addr() {
res.field("addr", &addr);
}
if let Ok(addr) = self.local_addr() {
res.field("addr", &addr);
}
if let Ok(peer) = self.peer_addr() {
res.field("peer", &peer);
}
if let Ok(peer) = self.peer_addr() {
res.field("peer", &peer);
}
res.finish()
}
res.finish()
}
}
impl I2pListener {
/// Creates a new `I2pListener` which will be bound to the specified
/// address.
///
/// The returned listener is ready for accepting connections.
///
/// Binding with a port number of 0 is equivalent to binding on every port.
///
/// The address type can be any implementor of `ToI2pSocketAddrs` trait. See
/// its documentation for concrete examples.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pListener;
///
/// let listener = I2pListener::bind("127.0.0.1:80").unwrap();
/// ```
pub fn bind<A: ToI2pSocketAddrs>(addr: A) -> io::Result<I2pListener> {
I2pListener::bind_via(DEFAULT_API, addr)
}
/// Creates a new `I2pListener` which will be bound to the specified
/// address.
///
/// The returned listener is ready for accepting connections.
///
/// Binding with a port number of 0 is equivalent to binding on every port.
///
/// The address type can be any implementor of `ToI2pSocketAddrs` trait. See
/// its documentation for concrete examples.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pListener;
///
/// let listener = I2pListener::bind("127.0.0.1:80").unwrap();
/// ```
pub fn bind<A: ToI2pSocketAddrs>(addr: A) -> io::Result<I2pListener> {
I2pListener::bind_via(DEFAULT_API, addr)
}
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)
}
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> {
unimplemented!();
}
fn bind_addr(_sam_addr: &SocketAddr, _addr: &I2pSocketAddr) -> io::Result<I2pListener> {
unimplemented!();
}
/// Returns the local socket address of this listener.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::{I2pAddr, I2pSocketAddr, I2pListener};
///
/// let listener = I2pListener::bind("127.0.0.1:8080").unwrap();
/// assert_eq!(listener.local_addr().unwrap(),
/// I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080));
/// ```
pub fn local_addr(&self) -> io::Result<I2pSocketAddr> {
unimplemented!()
}
/// Returns the local socket address of this listener.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::{I2pAddr, I2pSocketAddr, I2pListener};
///
/// let listener = I2pListener::bind("127.0.0.1:8080").unwrap();
/// assert_eq!(listener.local_addr().unwrap(),
/// I2pSocketAddr::new(I2pAddr::new("example.i2p"), 8080));
/// ```
pub fn local_addr(&self) -> io::Result<I2pSocketAddr> {
unimplemented!()
}
/// Creates a new independently owned handle to the underlying socket.
///
/// The returned `TcpListener` is a reference to the same socket that this
/// object references. Both handles can be used to accept incoming
/// connections and options set on one listener will affect the other.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pListener;
///
/// let listener = I2pListener::bind("127.0.0.1:8080").unwrap();
/// let listener_clone = listener.try_clone().unwrap();
/// ```
pub fn try_clone(&self) -> io::Result<I2pListener> {
unimplemented!()
}
/// Creates a new independently owned handle to the underlying socket.
///
/// The returned `TcpListener` is a reference to the same socket that this
/// object references. Both handles can be used to accept incoming
/// connections and options set on one listener will affect the other.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pListener;
///
/// let listener = I2pListener::bind("127.0.0.1:8080").unwrap();
/// let listener_clone = listener.try_clone().unwrap();
/// ```
pub fn try_clone(&self) -> io::Result<I2pListener> {
unimplemented!()
}
/// Accept a new incoming connection from this listener.
///
/// This function will block the calling thread until a new TCP connection
/// is established. When established, the corresponding `TcpStream` and the
/// remote peer's address will be returned.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pListener;
///
/// let listener = I2pListener::bind("127.0.0.1:8080").unwrap();
/// match listener.accept() {
/// Ok((_socket, addr)) => println!("new client: {:?}", addr),
/// Err(e) => println!("couldn't get client: {:?}", e),
/// }
/// ```
pub fn accept(&self) -> io::Result<(I2pStream, I2pSocketAddr)> {
unimplemented!()
}
/// Accept a new incoming connection from this listener.
///
/// This function will block the calling thread until a new TCP connection
/// is established. When established, the corresponding `TcpStream` and the
/// remote peer's address will be returned.
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pListener;
///
/// let listener = I2pListener::bind("127.0.0.1:8080").unwrap();
/// match listener.accept() {
/// Ok((_socket, addr)) => println!("new client: {:?}", addr),
/// Err(e) => println!("couldn't get client: {:?}", e),
/// }
/// ```
pub fn accept(&self) -> io::Result<(I2pStream, I2pSocketAddr)> {
unimplemented!()
}
/// Returns an iterator over the connections being received on this
/// listener.
///
/// The returned iterator will never return [`None`] and will also not yield
/// the peer's [`I2pSocketAddr`] structure.
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
/// [`I2pSocketAddr`]: ../../std/net/struct.I2pSocketAddr.html
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pListener;
///
/// let listener = I2pListener::bind("127.0.0.1:80").unwrap();
///
/// for stream in listener.incoming() {
/// match stream {
/// Ok(stream) => {
/// println!("new client!");
/// }
/// Err(e) => { /* connection failed */ }
/// }
/// }
/// ```
pub fn incoming(&self) -> Incoming<'_> {
Incoming { listener: self }
}
/// Returns an iterator over the connections being received on this
/// listener.
///
/// The returned iterator will never return [`None`] and will also not yield
/// the peer's [`I2pSocketAddr`] structure.
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
/// [`I2pSocketAddr`]: ../../std/net/struct.I2pSocketAddr.html
///
/// # Examples
///
/// ```no_run
/// use i2p::net::I2pListener;
///
/// let listener = I2pListener::bind("127.0.0.1:80").unwrap();
///
/// for stream in listener.incoming() {
/// match stream {
/// Ok(stream) => {
/// println!("new client!");
/// }
/// Err(e) => { /* connection failed */ }
/// }
/// }
/// ```
pub fn incoming(&self) -> Incoming {
Incoming { listener: self }
}
}
impl<'a> Iterator for Incoming<'a> {
type Item = io::Result<I2pStream>;
fn next(&mut self) -> Option<io::Result<I2pStream>> {
Some(self.listener.accept().map(|p| p.0))
}
type Item = io::Result<I2pStream>;
fn next(&mut self) -> Option<io::Result<I2pStream>> {
Some(self.listener.accept().map(|p| p.0))
}
}
impl fmt::Debug for I2pListener {
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
unimplemented!()
}
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
unimplemented!()
}
}

View File

@ -1,12 +1,12 @@
use crate::net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
use net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
pub fn isa(a: I2pAddr, p: u16) -> I2pSocketAddr {
I2pSocketAddr::new(a, p)
I2pSocketAddr::new(a, p)
}
pub fn tsa<A: ToI2pSocketAddrs>(a: A) -> Result<Vec<I2pSocketAddr>, String> {
match a.to_socket_addrs() {
Ok(a) => Ok(a.collect()),
Err(e) => Err(e.to_string()),
}
match a.to_socket_addrs() {
Ok(a) => Ok(a.collect()),
Err(e) => Err(e.to_string()),
}
}

View File

@ -1,20 +1,22 @@
use nom::{space, alphanumeric, named, do_parse, separated_list, take_till_s,
tag_s, call, error_position, tag, alt, take_till};
use nom::{
alphanumeric, alt, call, do_parse, error_position, named, separated_list, space, tag, tag_s,
take_till, take_till_s,
};
fn is_space(chr: char) -> bool {
chr == ' ' || chr == '\t'
chr == ' ' || chr == '\t'
}
fn is_next_line(chr: char) -> bool {
chr == '\n'
chr == '\n'
}
fn is_space_or_next_line(chr: char) -> bool {
is_space(chr) || is_next_line(chr)
is_space(chr) || is_next_line(chr)
}
fn is_double_quote(chr: char) -> bool {
chr == '\"'
chr == '\"'
}
named!(quoted_value <&str, &str>,
@ -86,100 +88,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;
use nom::IResult::Done;
use nom::IResult::Error;
#[test]
fn hello() {
use crate::parsers::sam_hello;
#[test]
fn hello() {
use parsers::sam_hello;
assert_eq!(
sam_hello("HELLO REPLY RESULT=OK VERSION=3.1\n"),
Done("", vec![("RESULT", "OK"), ("VERSION", "3.1")])
);
assert_eq!(
sam_hello("HELLO REPLY RESULT=NOVERSION\n"),
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")]
)
);
}
assert_eq!(
sam_hello("HELLO REPLY RESULT=OK VERSION=3.1\n"),
Done("", vec![("RESULT", "OK"), ("VERSION", "3.1")])
);
assert_eq!(
sam_hello("HELLO REPLY RESULT=NOVERSION\n"),
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")]
)
);
}
#[test]
fn session_status() {
use crate::parsers::sam_session_status;
#[test]
fn session_status() {
use parsers::sam_session_status;
assert_eq!(
sam_session_status("SESSION STATUS RESULT=OK DESTINATION=privkey\n"),
Done("", vec![("RESULT", "OK"), ("DESTINATION", "privkey")])
);
assert_eq!(
sam_session_status("SESSION STATUS RESULT=DUPLICATED_ID\n"),
Done("", vec![("RESULT", "DUPLICATED_ID")])
);
}
assert_eq!(
sam_session_status("SESSION STATUS RESULT=OK DESTINATION=privkey\n"),
Done("", vec![("RESULT", "OK"), ("DESTINATION", "privkey")])
);
assert_eq!(
sam_session_status("SESSION STATUS RESULT=DUPLICATED_ID\n"),
Done("", vec![("RESULT", "DUPLICATED_ID")])
);
}
#[test]
fn stream_status() {
use crate::parsers::sam_stream_status;
#[test]
fn stream_status() {
use parsers::sam_stream_status;
assert_eq!(
sam_stream_status("STREAM STATUS RESULT=OK\n"),
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")
]
)
);
}
assert_eq!(
sam_stream_status("STREAM STATUS RESULT=OK\n"),
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")
]
)
);
}
#[test]
fn naming_reply() {
use crate::parsers::sam_naming_reply;
#[test]
fn naming_reply() {
use 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")]
)
);
assert_eq!(
sam_naming_reply("NAMING REPLY RESULT=KEY_NOT_FOUND\n"),
Done("", vec![("RESULT", "KEY_NOT_FOUND")])
);
assert_eq!(
sam_naming_reply("NAMING REPLY RESULT=OK NAME=name VALUE=dest\n"),
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")])
);
assert_eq!(
sam_naming_reply("NAMINGREPLY RESULT=KEY_NOT_FOUND\n"),
Error(ErrorKind::Tag)
);
assert_eq!(
sam_naming_reply("NAMING REPLY RESULT=KEY_NOT_FOUND\n"),
Error(ErrorKind::Tag)
);
}
assert_eq!(
sam_naming_reply("NAMINGREPLY RESULT=KEY_NOT_FOUND\n"),
Error(ErrorKind::Tag)
);
assert_eq!(
sam_naming_reply("NAMING REPLY RESULT=KEY_NOT_FOUND\n"),
Error(ErrorKind::Tag)
);
}
#[test]
fn dest_reply() {
use crate::parsers::sam_dest_reply;
#[test]
fn dest_reply() {
use parsers::sam_dest_reply;
assert_eq!(
sam_dest_reply("DEST REPLY PUB=foo PRIV=foobar\n"),
Done("", vec![("PUB", "foo"), ("PRIV", "foobar")])
);
}
assert_eq!(
sam_dest_reply("DEST REPLY PUB=foo PRIV=foobar\n"),
Done("", vec![("PUB", "foo"), ("PRIV", "foobar")])
);
}
}

View File

@ -17,214 +17,216 @@ static SAM_MIN: &'static str = "3.0";
static SAM_MAX: &'static str = "3.1";
pub enum SessionStyle {
Datagram,
Raw,
Stream,
Datagram,
Raw,
Stream,
}
pub struct SamConnection {
conn: TcpStream,
conn: TcpStream,
}
pub struct Session {
sam: SamConnection,
local_dest: String,
sam: SamConnection,
local_dest: String,
}
pub struct StreamConnect {
sam: SamConnection,
session: Session,
peer_dest: String,
peer_port: u16,
local_port: u16,
sam: SamConnection,
session: Session,
peer_dest: String,
peer_port: u16,
local_port: u16,
}
impl SessionStyle {
fn string(&self) -> &str {
match *self {
SessionStyle::Datagram => "DATAGRAM",
SessionStyle::Raw => "RAW",
SessionStyle::Stream => "STREAM",
}
}
fn string(&self) -> &str {
match *self {
SessionStyle::Datagram => "DATAGRAM",
SessionStyle::Raw => "RAW",
SessionStyle::Stream => "STREAM",
}
}
}
fn verify_response<'a>(vec: &'a [(&str, &str)]) -> Result<HashMap<&'a str, &'a str>, Error> {
let new_vec = vec.clone();
let map: HashMap<&str, &str> = new_vec.iter().map(|&(k, v)| (k, v)).collect();
let res = map.get("RESULT").unwrap_or(&"OK").clone();
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))
}
"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)),
"I2P_ERROR" => Err(Error::new(ErrorKind::Other, msg)),
_ => Err(Error::new(ErrorKind::Other, msg)),
}
let new_vec = vec.clone();
let map: HashMap<&str, &str> = new_vec.iter().map(|&(k, v)| (k, v)).collect();
let res = map.get("RESULT").unwrap_or(&"OK").clone();
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))
}
"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)),
"I2P_ERROR" => Err(Error::new(ErrorKind::Other, msg)),
_ => Err(Error::new(ErrorKind::Other, msg)),
}
}
impl SamConnection {
fn send<F>(&mut self, msg: String, reply_parser: F) -> Result<HashMap<String, String>, Error>
where
F: Fn(&str) -> IResult<&str, Vec<(&str, &str)>>,
{
debug!("-> {}", &msg);
self.conn.write_all(&msg.into_bytes())?;
fn send<F>(&mut self, msg: String, reply_parser: F) -> Result<HashMap<String, String>, Error>
where
F: Fn(&str) -> IResult<&str, Vec<(&str, &str)>>,
{
debug!("-> {}", &msg);
self.conn.write_all(&msg.into_bytes())?;
let mut reader = BufReader::new(&self.conn);
let mut buffer = String::new();
reader.read_line(&mut buffer)?;
debug!("<- {}", &buffer);
let mut reader = BufReader::new(&self.conn);
let mut buffer = String::new();
reader.read_line(&mut buffer)?;
debug!("<- {}", &buffer);
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()
})
}
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()
})
}
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
);
self.send(hello_msg, sam_hello)
}
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
);
self.send(hello_msg, sam_hello)
}
pub fn connect<A: ToSocketAddrs>(addr: A) -> Result<SamConnection, Error> {
let tcp_stream = TcpStream::connect(addr)?;
pub fn connect<A: ToSocketAddrs>(addr: A) -> Result<SamConnection, Error> {
let tcp_stream = TcpStream::connect(addr)?;
let mut socket = SamConnection { conn: tcp_stream };
let mut socket = SamConnection { conn: tcp_stream };
socket.handshake()?;
socket.handshake()?;
Ok(socket)
}
Ok(socket)
}
// TODO: Implement a lookup table
pub fn naming_lookup(&mut self, name: &str) -> Result<String, Error> {
let create_naming_lookup_msg = format!("NAMING LOOKUP NAME={name} \n", name = name);
let ret = self.send(create_naming_lookup_msg, sam_naming_reply)?;
Ok(ret["VALUE"].clone())
}
// TODO: Implement a lookup table
pub fn naming_lookup(&mut self, name: &str) -> Result<String, Error> {
let create_naming_lookup_msg = format!("NAMING LOOKUP NAME={name} \n", name = name);
let ret = self.send(create_naming_lookup_msg, sam_naming_reply)?;
Ok(ret["VALUE"].clone())
}
pub fn duplicate(&self) -> io::Result<SamConnection> {
self.conn.try_clone().map(|s| SamConnection { conn: s })
}
pub fn duplicate(&self) -> io::Result<SamConnection> {
self.conn.try_clone().map(|s| SamConnection { conn: s })
}
}
impl Session {
pub fn create<A: ToSocketAddrs>(
sam_addr: A,
destination: &str,
nickname: &str,
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
);
pub fn create<A: ToSocketAddrs>(
sam_addr: A,
destination: &str,
nickname: &str,
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
);
sam.send(create_session_msg, sam_session_status)?;
sam.send(create_session_msg, sam_session_status)?;
let local_dest = sam.naming_lookup("ME")?;
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> {
self.sam.conn.peer_addr()
}
pub fn sam_api(&self) -> io::Result<SocketAddr> {
self.sam.conn.peer_addr()
}
pub fn naming_lookup(&mut self, name: &str) -> io::Result<String> {
self.sam.naming_lookup(name)
}
pub fn naming_lookup(&mut self, name: &str) -> io::Result<String> {
self.sam.naming_lookup(name)
}
pub fn duplicate(&self) -> io::Result<Session> {
self.sam.duplicate().map(|s| Session {
sam: s,
local_dest: self.local_dest.clone(),
})
}
pub fn duplicate(&self) -> io::Result<Session> {
self.sam.duplicate().map(|s| Session {
sam: s,
local_dest: self.local_dest.clone(),
})
}
}
impl StreamConnect {
pub fn new<A: ToSocketAddrs>(
sam_addr: A,
destination: &str,
port: u16,
nickname: &str,
) -> io::Result<StreamConnect> {
let mut session = Session::create(sam_addr, "TRANSIENT", nickname, SessionStyle::Stream)?;
pub fn new<A: ToSocketAddrs>(
sam_addr: A,
destination: &str,
port: u16,
nickname: &str,
) -> io::Result<StreamConnect> {
let mut session = Session::create(sam_addr, "TRANSIENT", nickname, SessionStyle::Stream)?;
let mut sam = SamConnection::connect(session.sam_api()?).unwrap();
let dest = sam.naming_lookup(destination);
let mut sam = SamConnection::connect(session.sam_api()?).unwrap();
let dest = sam.naming_lookup(destination);
let create_stream_msg = format!("STREAM CONNECT ID={nickname} DESTINATION={destination} SILENT=false TO_PORT={port}\n",
nickname = nickname,
destination = dest.unwrap(),
port = port);
let create_stream_msg = format!(
"STREAM CONNECT ID={nickname} DESTINATION={destination} SILENT=false TO_PORT={port}\n",
nickname = nickname,
destination = dest.unwrap(),
port = port
);
sam.send(create_stream_msg, sam_stream_status)?;
sam.send(create_stream_msg, sam_stream_status)?;
let peer_dest = session.naming_lookup(destination)?;
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)> {
Ok((self.peer_dest.clone(), self.peer_port))
}
pub fn peer_addr(&self) -> io::Result<(String, u16)> {
Ok((self.peer_dest.clone(), self.peer_port))
}
pub fn local_addr(&self) -> io::Result<(String, u16)> {
Ok((self.session.local_dest.clone(), self.local_port))
}
pub fn local_addr(&self) -> io::Result<(String, u16)> {
Ok((self.session.local_dest.clone(), self.local_port))
}
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.sam.conn.shutdown(how)
}
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.sam.conn.shutdown(how)
}
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,
})
}
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,
})
}
}
impl Read for StreamConnect {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.sam.conn.read(buf)
}
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.sam.conn.read(buf)
}
}
impl Write for StreamConnect {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.sam.conn.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.sam.conn.flush()
}
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.sam.conn.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.sam.conn.flush()
}
}

View File

@ -1,11 +1,11 @@
#[test]
#[ignore]
fn naming_lookup() {
use i2p::sam::SamConnection;
let mut sam = SamConnection::connect("127.0.0.1:7656").unwrap();
{
let res = sam.naming_lookup("zzz.i2p");
match res {
use i2p::sam::SamConnection;
let mut sam = SamConnection::connect("127.0.0.1:7656").unwrap();
{
let res = sam.naming_lookup("zzz.i2p");
match res {
Ok(d) => {
assert_eq!(
d,
@ -14,5 +14,5 @@ fn naming_lookup() {
}
Err(ref e) => panic!("An error occurred: {}", e),
}
}
}
}