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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright (C) 2020 Matthew Waters <matthew@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// SPDX-License-Identifier: MIT OR Apache-2.0
//! # stun-proto
//!
//! A sans-IO implementation of a STUN agent as specified in [RFC5389] and [RFC8489].
//!
//! [RFC8489]: https://tools.ietf.org/html/rfc8489
//! [RFC5389]: https://tools.ietf.org/html/rfc5389
//!
//! ## Example
//!
//! ```
//! # use core::net::SocketAddr;
//! 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);
//! ```
extern crate alloc;
extern crate std;
pub use Instant;
pub use stun_types as types;
/// Public prelude.
pub