mirror of
https://github.com/pradt2/always-online-stun.git
synced 2025-09-26 19:41:34 +08:00
55 lines
2.0 KiB
Rust
55 lines
2.0 KiB
Rust
use std::io::{Read, Write};
|
|
use stun_proto::rfc5389::*;
|
|
|
|
/**
|
|
In this example, we are calling a TCP stun server
|
|
To get our external IP and port
|
|
*/
|
|
fn main() {
|
|
let mut buf = [0u8; 32];
|
|
|
|
let mut writer = Writer::new(&mut buf);
|
|
writer.set_message_type(MessageType::BindingRequest).unwrap();
|
|
writer.set_transaction_id(1).unwrap();
|
|
let bytes_written = writer.finish().unwrap();
|
|
|
|
let mut socket = std::net::TcpStream::connect("stun.stunprotocol.org:3478").unwrap();
|
|
socket.write_all(&buf[0..bytes_written as usize]).unwrap();
|
|
|
|
socket.set_read_timeout(Some(std::time::Duration::from_millis(1000))).unwrap();
|
|
let bytes_read = socket.read(&mut buf).unwrap();
|
|
|
|
// we assume that the entire message has been read in one go
|
|
// a more robust client would look at the message length and keep reading if necessary
|
|
|
|
let reader = Reader::new(&buf[0..bytes_read]);
|
|
if let MessageType::BindingResponse = reader.get_message_type().unwrap() {
|
|
assert_eq!(1u128, reader.get_transaction_id().unwrap());
|
|
let external_addr = reader.get_attributes()
|
|
.map(|attr| {
|
|
match attr {
|
|
Ok(ReaderAttribute::MappedAddress(addr)) => Some(addr.get_address().unwrap()),
|
|
Ok(ReaderAttribute::XorMappedAddress(addr)) => Some(addr.get_address().unwrap()),
|
|
_ => None,
|
|
}
|
|
})
|
|
.filter(|opt| opt.is_some())
|
|
.map(|opt| opt.unwrap())
|
|
.next()
|
|
.unwrap();
|
|
|
|
let std_external_addr = match external_addr {
|
|
SocketAddr::V4(ip, port) => {
|
|
std::net::SocketAddr::new(std::net::IpAddr::from(ip.to_be_bytes()), port)
|
|
},
|
|
SocketAddr::V6(ip, port) => {
|
|
std::net::SocketAddr::new(std::net::IpAddr::from(ip.to_be_bytes()), port)
|
|
},
|
|
};
|
|
|
|
println!("NAT mapping {} -> {}", socket.local_addr().unwrap(), std_external_addr);
|
|
} else {
|
|
assert!(false, "Response is not a BindingResponse")
|
|
}
|
|
}
|