tox 0.0.5

Implementation of toxcore in pure Rust - P2P, distributed, encrypted, easy to use DHT-based network.
Documentation

C API: https://github.com/ze-tox/tox-capi

Current API allows one to e.g. find info about DHT nodes from bootstrap
nodes by sending [`GetNodes`](./toxcore/dht/struct.GetNodes.html) or request
[`Ping`](./toxcore/dht/struct.Ping.html) response.

To request a ping response:

```no_run
// for networking
extern crate tokio_core;
use tokio_core::reactor::Core;

// to get bytes from PK in hex and to make PK from them
extern crate hex;
use hex::FromHex;

extern crate tox;
use tox::toxcore::binary_io::*;
use tox::toxcore::crypto_core::*;
use tox::toxcore::dht::*;
use tox::toxcore::network::*;
use tox::toxcore::packet_kind::PacketKind;

fn main() {
    let mut reactor = Core::new().unwrap();
    let handle = reactor.handle();
    // get PK bytes from some "random" bootstrap node (Impyy's)
    let bootstrap_pk_bytes = FromHex::from_hex("6FC41E2BD381D37E9748FC0E0328CE086AF9598BECC8FEB7DDF2E440475F300E").unwrap();
    // create PK from bytes
    let bootstrap_pk = PublicKey::from_slice(&bootstrap_pk_bytes).unwrap();

    // generate own PublicKey, SecretKey keypair
    let (pk, sk) = gen_keypair();

    // and to encrypt data there precomputed symmetric key is needed, created
    // from PK of the peer you want to send data to, and your own secret key.
    let precomp = precompute(&bootstrap_pk, &sk);

    // also generate nonce that will be needed to make the encryption happen
    let nonce = gen_nonce();

    // now create Ping request
    let ping = &PingReq::new();

    // with Ping packet create DhtPacket, and serialize it to bytes
    let dhtpacket = DhtPacket::new(&precomp, &pk, &nonce, ping).to_bytes();

    // and since packet is ready, prepare the network part;
    // bind to given address and port in given range
    // `0.0.0.0` is used instead of `::` to appease windows' rage
    let socket = bind_udp("0.0.0.0".parse().unwrap(), 33445..33546, &handle)
        .expect("Failed to bind to socket!");

    // send DhtPacket via socket to the node (Imppy's)
    let sent_bytes = socket.send_dgram(&dhtpacket,
                 "51.15.37.145:33445".parse().unwrap());
    let (socket, _) = reactor.run(sent_bytes)
        .expect("Failed to send bytes!");

    // since data was sent, now receive response – for that, first prepare
    // buffer to receive data into
    let mut buf = [0; MAX_UDP_PACKET_SIZE];

    // and wait for the answer
    let future_data = socket.recv_dgram(&mut buf[..]);

    let (_socket, buf, n_bytes, _sender) = reactor.run(future_data)
        .expect("Failed to receive data");

    // try to deserialize received bytes as `DhtPacket`
    let recv_packet = match DhtPacket::from_bytes(&buf[..n_bytes]) {
        Some(p) => p,
        // if parsing fails ↓
        None => panic!("Received packet could not have been parsed!\n{:?}",
                        &buf[..n_bytes]),
    };

    // decrypt payload of the received packet
    let payload: PingResp = recv_packet.get_payload(&sk)
        .expect("Failed to decrypt payload!");

    assert_eq!(PacketKind::PingResp, payload.kind());
    assert_eq!(ping.id(), payload.id());
    println!("And contents of payload:\n{:?}", payload);
}
```