Skip to main content

Crate stun_proto

Crate stun_proto 

Source
Expand description

§stun-proto

A sans-IO implementation of a STUN agent as specified in RFC5389 and RFC8489.

§Example

use sans_io_time::Instant;
use stun_proto::types::TransportType;
use stun_proto::types::attribute::{MessageIntegrity, XorMappedAddress};
use stun_proto::types::message::{
    BINDING, IntegrityAlgorithm, Message, MessageIntegrityCredentials,
    MessageWriteVec, ShortTermCredentials
};
use stun_proto::types::prelude::*;
use stun_proto::agent::StunAgent;
use stun_proto::auth::ShortTermAuth;

let local_addr = "10.0.0.1:12345".parse().unwrap();
let remote_addr = "10.0.0.2:3478".parse().unwrap();

let mut auth = ShortTermAuth::new();
let mut agent = StunAgent::builder(TransportType::Udp, local_addr)
    .build();

// short term or long term credentials may optionally be used.
let credentials = ShortTermCredentials::new(String::from("password"));
auth.set_credentials(credentials.clone(), IntegrityAlgorithm::Sha1);

// and we can send a Message
let mut msg = Message::builder_request(BINDING, MessageWriteVec::new());
msg.add_message_integrity(&credentials.clone().into(), IntegrityAlgorithm::Sha1).unwrap();
let transmit = agent.send_request(msg.finish(), remote_addr, Instant::ZERO).unwrap();

// The transmit struct indicates what data and where to send it.
let request = Message::from_bytes(&transmit.data).unwrap();

let mut response = Message::builder_success(&request, MessageWriteVec::new());
let xor_addr = XorMappedAddress::new(transmit.from, request.transaction_id());
response.add_attribute(&xor_addr).unwrap();
response.add_message_integrity(&credentials.clone().into(), IntegrityAlgorithm::Sha1).unwrap();

// when receiving data on the associated socket, we should pass it through the Agent so it can
// parse and handle any STUN messages.
let data = response.finish();
let to = transmit.to;
let response = Message::from_bytes(&data).unwrap();

// If there is any authentication required for use, then that should be executed before passing
// to the agent.
assert!(matches!(auth.validate_incoming_message(&response), Ok(Some(IntegrityAlgorithm::Sha1))));

// If running over TCP then there may be multiple messages parsed. However UDP will only ever
// have a single message per datagram.
assert!(agent.handle_stun_message(&response, to));

// Once valid STUN data has been sent and received, then data can be sent and received from the
// peer.
let data = vec![42; 8];
let transmit = agent.send_data(data.as_slice(), remote_addr);
assert_eq!(transmit.data, &data);
assert_eq!(transmit.from, local_addr);
assert_eq!(transmit.to, remote_addr);

Re-exports§

pub use stun_types as types;

Modules§

agent
STUN agent
auth
STUN authentication
prelude
Public prelude.

Structs§

Instant
An absolute point in time.