This crate provides a simple but high effective framework to manage STUN protocol messages. The implementation is based on:
* RFC8489
. Session Traversal Utilities for NAT (STUN).
* RFC8445
. Interactive Connectivity Establishment (ICE).
* RFC8656
. Traversal Using Relays around NAT (TURN)
* RFC5769
. Test Vectors for Session Traversal Utilities for NAT (STUN).
Example that creates and encodes a STUN Binding request ```rust // Create attributes let username = UserName::new("\u{30DE}\u{30C8}\u{30EA}\u{30C3}\u{30AF}\u{30B9}")?; let nonce = Nonce::new("f//499k954d6OL34oL9FSTvy64sA")?; let realm = Realm::new("example.org")?; let password = "TheMatrIX"; let algorithm = Algorithm::from(AlgorithmId::MD5); let key = HMACKey::newlongterm(&username, &realm, password, algorithm)?; let integrity = MessageIntegrity::new(key);
// Create the message let msg = StunMessageBuilder::new( BINDING, MessageClass::Request, ) .withattribute(username) .withattribute(nonce) .withattribute(realm) .withattribute(integrity) .build();
// Create an encoder to encode the message into a buffer let encoder = MessageEncoderBuilder::default().build(); let mut buffer: [u8; 150] = [0x00; 150]; let size = encoder.encode(&mut buffer, &msg)?; assert_eq!(size, 116); ```
Example that decodes a STUN Binding response and fetches some attributes.
``rust
// This response uses the following parameter:
// Password:
VOkJxbRl1RmTxUk/WvJxBt` (without quotes)
// Software name: "test vector" (without quotes)
// Mapped address: 192.0.2.1 port 32853
let sampleipv4response = [
0x01, 0x01, 0x00, 0x3c, // Response type and message length
0x21, 0x12, 0xa4, 0x42, // Magic cookie
0xb7, 0xe7, 0xa7, 0x01, // }
0xbc, 0x34, 0xd6, 0x86, // } Transaction ID
0xfa, 0x87, 0xdf, 0xae, // }
0x80, 0x22, 0x00, 0x0b, // SOFTWARE attribute header
0x74, 0x65, 0x73, 0x74, // }
0x20, 0x76, 0x65, 0x63, // } UTF-8 server name
0x74, 0x6f, 0x72, 0x20, // }
0x00, 0x20, 0x00, 0x08, // XOR-MAPPED-ADDRESS attribute header
0x00, 0x01, 0xa1, 0x47, // Address family (IPv4) and xor'd mapped port number
0xe1, 0x12, 0xa6, 0x43, // Xor'd mapped IPv4 address
0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY header
0x2b, 0x91, 0xf5, 0x99, // }
0xfd, 0x9e, 0x90, 0xc3, // }
0x8c, 0x74, 0x89, 0xf9, // } HMAC-SHA1 fingerprint
0x2a, 0xf9, 0xba, 0x53, // }
0xf0, 0x6b, 0xe7, 0xd7, // }
0x80, 0x28, 0x00, 0x04, // FINGERPRINT attribute header
0xc0, 0x7d, 0x4c, 0x96, // Reserved for CRC32 fingerprint
];
// Create a STUN decoder context using the password as a short credential // mechanism and force validation of MESSAGE-INTEGRITY and FINGERPRINT let ctx = DecoderContextBuilder::default() .withkey( HMACKey::newshortterm("VOkJxbRl1RmTxUk/WvJxBt")?, ) .withvalidation() .build(); let decoder = MessageDecoderBuilder::default().with_context(ctx).build();
let (msg, size) = decoder.decode(&sampleipv4response)?; asserteq!(size, sampleipv4_response.len());
// Check message method is a BINDING response asserteq!(msg.method(), BINDING); asserteq!(msg.class(), MessageClass::SuccessResponse);
let software = msg.get::
let xoraddr = msg.get::
This crate defines next feature flags that can be enabled:
* turn: Extends support for parsing attributes defined in RFC8656
. Traversal Using Relays around NAT (TURN)
* ice: Extends support for parsing attributes defined in RFC8445
. Interactive Connectivity Establishment (ICE).
* experiments: This flag can be set to adjust some behavior of the library, such as default padding. When testing protocols, we can use this flag to force the library to keep the data associated with unknown attributes. By default, unknown attributes store no data to save memory consumption.
Patches and feedback are welcome.
If you find this project helpful, you may consider making a donation:
This project is licensed under either of * Apache License, Version 2.0 * MIT license