-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement i2p SAM handshake. The library uses nom to parse the response.
- Loading branch information
0 parents
commit b2e8e41
Showing
5 changed files
with
129 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
target | ||
Cargo.lock | ||
|
||
# -*- mode: gitignore; -*- | ||
*~ | ||
\#*\# | ||
/.emacs.desktop | ||
/.emacs.desktop.lock | ||
*.elc | ||
auto-save-list | ||
tramp | ||
.\#* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
name = "i2p" | ||
version = "0.1.0" | ||
authors = ["Igor Oliveira <igor@work.co>"] | ||
|
||
[dependencies] | ||
nom = "^1.2.3" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
use nom::IResult; | ||
use parsers::{sam_hello}; | ||
use std::net::{TcpStream, ToSocketAddrs}; | ||
use std::io::{Error, Read, Write}; | ||
|
||
static SAM_MIN: &'static str = "3.0"; | ||
static SAM_MAX: &'static str = "3.1"; | ||
|
||
pub struct I2p { | ||
stream: TcpStream | ||
} | ||
|
||
impl I2p { | ||
fn handshake(&mut self) { | ||
let hello_msg = format!("HELLO VERSION MIN={min} MAX={max} \n", | ||
min = SAM_MIN, | ||
max = SAM_MAX); | ||
let _ = self.stream.write(&hello_msg.into_bytes()); | ||
|
||
let mut buffer = String::new(); | ||
let _ = self.stream.read_to_string(&mut buffer); | ||
|
||
let res = sam_hello(&buffer); | ||
match res { | ||
IResult::Done(i, o) => println!("i: {} | o: {:?}", i, o), | ||
_ => println!("error") | ||
} | ||
} | ||
|
||
pub fn connect<A: ToSocketAddrs>(addr: A) -> Result<I2p, Error> { | ||
let tcp_stream = try!(TcpStream::connect(addr)); | ||
let mut i2p = I2p { stream: tcp_stream }; | ||
|
||
i2p.handshake(); | ||
|
||
Ok(i2p) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#[macro_use] | ||
extern crate nom; | ||
|
||
pub use i2p::I2p; | ||
|
||
mod i2p; | ||
mod parsers; | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
#[test] | ||
fn it_works() { | ||
use i2p::I2p; | ||
match I2p::connect("127.0.0.1:7656") { | ||
Ok(_) => println!("works"), | ||
Err(err) => println!("An error occurred: {}", err), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use std::collections::HashMap; | ||
use nom::{IResult, space, alphanumeric}; | ||
|
||
fn is_space(chr: char) -> bool { | ||
chr == ' ' || chr == '\t' | ||
} | ||
|
||
fn is_next_line(chr: char) -> bool { | ||
chr == '\n' | ||
} | ||
|
||
fn is_space_or_next_line(chr: char) -> bool { | ||
is_space(chr) || is_next_line(chr) | ||
} | ||
|
||
named!(key_value <&str, (&str, &str)>, | ||
chain!( | ||
space? ~ | ||
key: alphanumeric ~ | ||
space? ~ | ||
tag_s!("=") ~ | ||
space? ~ | ||
val: take_till_s!(is_space_or_next_line) , | ||
|| { (key, val) } | ||
) | ||
); | ||
|
||
named!(keys_and_values<&str, Vec<(&str, &str)> >, many0!(key_value)); | ||
|
||
fn options(input: &str) -> IResult<&str, HashMap<&str, &str> > { | ||
let mut h: HashMap<&str, &str> = HashMap::new(); | ||
|
||
match keys_and_values(input) { | ||
IResult::Done(i, tuple_vec) => { | ||
for &(k,v) in &tuple_vec { | ||
h.insert(k, v); | ||
} | ||
IResult::Done(i, h) | ||
}, | ||
IResult::Incomplete(a) => IResult::Incomplete(a), | ||
IResult::Error(a) => IResult::Error(a) | ||
} | ||
} | ||
|
||
named!(pub sam_hello <&str, HashMap<&str, &str> >, | ||
chain!( | ||
tag_s!("HELLO") ~ | ||
space? ~ | ||
tag_s!("REPLY") ~ | ||
parse_options: options , | ||
|| { parse_options } | ||
) | ||
); |