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);
}
```