From 431da16ba689ca5bb1b06b8247088cdb0bbaf804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= Date: Wed, 16 Oct 2019 16:15:43 -0400 Subject: [PATCH] dhtnode: add example with get --- rust/examples/dhtnode.rs | 46 ++++++++++++++++++++--- rust/src/lib.rs | 79 ++++++++++++++++++++++++++++++++-------- 2 files changed, 104 insertions(+), 21 deletions(-) diff --git a/rust/examples/dhtnode.rs b/rust/examples/dhtnode.rs index 482214ab..353f6d15 100644 --- a/rust/examples/dhtnode.rs +++ b/rust/examples/dhtnode.rs @@ -1,13 +1,49 @@ extern crate opendht; +use std::ffi::CString; +use std::{thread, time}; +use libc::c_void; use opendht::*; +extern fn get_cb(v: *mut Value, ptr: *mut c_void) { + if ptr.is_null() { + return; + } + let _handler: &mut Handler = unsafe { &mut *(ptr as *mut Handler) }; + unsafe { + println!("Got data: {}", *v); + } +} + +extern fn done_cb(ok: bool, ptr: *mut c_void) { + let _handler: &mut Handler = unsafe { &mut *(ptr as *mut Handler) }; + println!("In done - {}", ok); +} + +struct Handler { + _data: u8, +} + + fn main() { println!("{}", InfoHash::random()); println!("{}", InfoHash::new()); -// - //let mut dht = DhtRunner::new(); - //dht.run(1412); - //let bootstrap_address = CString::new("bootstrap.jami.net").unwrap(); - //dht.ping(&bootstrap_address, bootstrap_address.len()); + println!("{}", InfoHash::get("toto")); + + let mut dht = DhtRunner::new(); + dht.run(1412); + dht.bootstrap( + &CString::new("bootstrap.jami.net").unwrap(), + &CString::new("4222").unwrap() + ); + let ten_secs = time::Duration::from_secs(10); + let mut handler = Handler { + _data: 8, + }; + loop { + println!("Get /toto"); + let ptr = &mut handler as *mut _ as *mut c_void; + dht.get(&InfoHash::get("toto"), get_cb, done_cb, ptr); + thread::sleep(ten_secs); + } } \ No newline at end of file diff --git a/rust/src/lib.rs b/rust/src/lib.rs index aaceec57..b50513cd 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -2,7 +2,10 @@ extern crate libc; use std::fmt; use std::ffi::CStr; use std::ffi::CString; -use libc::{c_char, c_void, in_port_t, sockaddr, socklen_t}; +use std::ptr; +use std::str; +use std::slice; +use libc::{c_char, c_void, in_port_t, size_t, uint8_t}; const HASH_LEN: usize = 20; @@ -13,29 +16,39 @@ pub struct InfoHash } #[repr(C)] -pub struct DhtRunner; +pub struct DhtRunner +{ + _opaque: [u8; 0] +} #[repr(C)] -pub struct Value; +pub struct Value +{ + _opaque: [u8; 0] +} +#[repr(C)] +pub struct DataView +{ + data: *const uint8_t, + size: size_t +} -// TODO remove Box? -// TODO callbacks -// TODO dhtnode-rust #[link(name = "opendht-c")] -extern { +extern { fn dht_infohash_print(h: *const InfoHash) -> *mut c_char; fn dht_infohash_random(h: *mut InfoHash); + fn dht_infohash_get(h: *mut InfoHash, dat: *mut uint8_t, dat_size: size_t); - + fn dht_value_get_data(data: *const Value) -> DataView; fn dht_runner_new() -> *mut DhtRunner; fn dht_runner_delete(dht: *mut DhtRunner); fn dht_runner_run(dht: *mut DhtRunner, port: in_port_t); - fn dht_runner_ping(dht: *mut DhtRunner, addr: *mut sockaddr, addr_len: socklen_t); + fn dht_runner_bootstrap(dht: *mut DhtRunner, host: *const c_char, service: *const c_char); fn dht_runner_get(dht: *mut DhtRunner, h: *const InfoHash, - get_cb: extern fn(*mut Value, i32, *mut c_void), + get_cb: extern fn(*mut Value, *mut c_void), done_cb: extern fn(bool, *mut c_void), cb_user_data: *mut c_void); } @@ -54,6 +67,15 @@ impl InfoHash { } h } + + pub fn get(data: &str) -> InfoHash { + let mut h = InfoHash::new(); + unsafe { + let c_str = CString::new(data).unwrap(); + dht_infohash_get(&mut h, c_str.as_ptr() as *mut u8, data.len()); + } + h + } } impl fmt::Display for InfoHash { @@ -67,6 +89,7 @@ impl fmt::Display for InfoHash { } } + impl DhtRunner { pub fn new() -> Box { unsafe { @@ -80,13 +103,19 @@ impl DhtRunner { } } - pub fn ping(&mut self, addr: &CString, addr_len: u32) { + pub fn bootstrap(&mut self, host: &CString, service: &CString) { unsafe { - let mut s = sockaddr { - sa_family: 0 /* TODO AF_UNSPEC */, - sa_data: [0; 14] /* TODO */, - }; - dht_runner_ping(&mut *self, &mut s, addr_len) + dht_runner_bootstrap(&mut *self, host.as_ptr(), service.as_ptr()) + } + } + + pub fn get(&mut self, h: &InfoHash, + get_cb: extern fn(*mut Value, *mut c_void), + done_cb: extern fn(bool, *mut c_void), + cb_user_data: *mut c_void) { + + unsafe { + dht_runner_get(&mut *self, h, get_cb, done_cb, cb_user_data) } } } @@ -99,6 +128,24 @@ impl Drop for DhtRunner { } } +impl Value { + fn dataview(&self) -> DataView { + unsafe { + dht_value_get_data(self) + } + } +} + +impl fmt::Display for Value { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + unsafe { + let dataview = self.dataview(); + let slice = slice::from_raw_parts(dataview.data, dataview.size); + write!(f, "{}", str::from_utf8(slice).unwrap_or("")) + } + } +} + #[cfg(test)] mod tests {