dhtnode: add example with get

This commit is contained in:
Sébastien Blin authored and Adrien Béraud committed 2019-10-22 10:47:43 -04:00
1 parent 09818d779e
commit 431da16ba6
2 files changed
+104 -21

No files matched your search

+41 -5
View File
@@ -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);
}
}
+63 -16
View File
@@ -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<DhtRunner> {
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 {