1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
//! This crate is a Bitmessage node implementation as a library for Koibumi (sync version), an experimental Bitmessage client.
//!
//! See [`koibumi-sync`](https://crates.io/crates/koibumi-sync) for more about the application.
//! See [Bitmessage](https://bitmessage.org/) for more about the protocol.
//!
//! # Examples
//!
//! ```no_run
//! use std::{path::PathBuf, str::FromStr};
//!
//! use koibumi_node_sync::{self as node, Command, Config, Event, Response};
//!
//! let (command_sender, mut response_receiver, handle) = node::spawn();
//!
//! let config = Config::builder()
//!     .server(Some("127.0.0.1:8444".parse().unwrap()))
//!     .socks(Some("127.0.0.1:9050".parse().unwrap()))
//!     .connect_to_onion(true)
//!     .connect_to_ip(true)
//!     .seeds(vec!["quzwelsuziwqgpt2.onion:8444".parse().unwrap()])
//!     .build();
//!
//! let mut sender = command_sender;
//! let response = {
//!     let db_path = PathBuf::from_str("sqlite::memory:").unwrap();
//!
//!     if let Err(err) = sender.send(Command::Start(config.into(), db_path, Vec::new())) {
//!         eprintln!("{}", err);
//!         return
//!     }
//!     response_receiver.recv()
//! };
//! let Response::Started(mut receiver) = response.unwrap();
//!
//! while let Ok(event) = receiver.recv() {
//!     match event {
//!         Event::ConnectionCounts { .. } => (),
//!         Event::AddrCount(_count) => (),
//!         Event::Established { addr, user_agent, rating } => {
//!             println!("established: {} {} rating:{}", addr, user_agent, rating);
//!         }
//!         Event::Disconnected { addr } => {
//!             println!("disconnected: {}", addr);
//!         }
//!         Event::Objects { .. } => (),
//!         Event::Stopped => {
//!             break;
//!         }
//!         Event::Broadcast {
//!             user_id,
//!             address,
//!             object,
//!         } => {
//!             println!("broadcast received from {}", address);
//!         }
//!         Event::Msg {
//!             user_id,
//!             address,
//!             object,
//!         } => {
//!             println!("received msg for {}", address);
//!         }
//!     }
//! }
//!
//! if let Err(err) = handle.join() {
//!     eprintln!("{:?}", err);
//!     return
//! }
//! ```

#![deny(unsafe_code)]
#![warn(missing_docs)]
#![recursion_limit = "2048"]

mod config;
mod connection;
mod connection_loop;
mod constant;
mod inv_manager;
mod manager;
mod message_handler;
mod net;
mod node_manager;
mod object_processor;
mod pow_manager;
mod user_manager;

use std::thread;

use crossbeam_channel::{bounded, Receiver, Sender};

pub use config::{Builder as ConfigBuilder, Config, SocksAuth};
pub use manager::{run, Command, Event, Response};
pub use net::SocketAddrNode;
pub use node_manager::Rating;
pub use user_manager::User;

/// Spawns a task that manage a Bitmessage node.
pub fn spawn() -> (Sender<Command>, Receiver<Response>, thread::JoinHandle<()>) {
    const COMMAND_BUFFER: usize = 0x10000;
    const RESPONSE_BUFFER: usize = 0x10000;
    let (command_sender, command_receiver) = bounded(COMMAND_BUFFER);
    let (response_sender, response_receiver) = bounded(RESPONSE_BUFFER);
    let handle = thread::spawn(|| manager::run(command_receiver, response_sender));
    (command_sender, response_receiver, handle)
}