dart_stun
is a Dart library designed for fast handling of the STUN (Session Traversal Utilities for NAT) protocol. It supports RFC 3489, RFC 5389, and RFC 5780 standards, as well as UDP, TCP, and TLS transport protocols, enabling developers to quickly send and receive STUN messages.
- Standards Supported: RFC 3489, RFC 5389, RFC 5780.
- Multiple Transport Protocols: Supports UDP, TCP, and TLS.
- Simple and Easy to Use: Quickly constructs and parses STUN messages.
Add the dependency in your pubspec.yaml
file:
dependencies:
stun:
git:
url: https://github.com/halifox/dart_stun
ref: 2.0.3
Use StunClient.create
to create a client instance.
StunClient client = StunClient.create(
transport: Transport.udp, // Transport protocol: udp, tcp, or tls
serverHost: "stun.hot-chilli.net", // STUN server address
serverPort: 3478, // STUN server port
localIp: "0.0.0.0", // Local IP address
localPort: 54320, // Local port
stunProtocol: StunProtocol.RFC5780 // STUN protocol version
);
Generate a binding request message using createBindingStunMessage
.
StunMessage bindingRequest = client.createBindingStunMessage();
Generate a change request message using createChangeStunMessage
.
StunMessage changeRequest = client.createChangeStunMessage(
flagChangeIp: true, // Request to change IP
flagChangePort: true // Request to change port
);
Send a STUN message and wait for a response with sendAndAwait
.
try {
StunMessage response = await client.sendAndAwait(bindingRequest, isAutoClose: true);
// Handle response
} catch (e) {
print("Request timed out or encountered an error: $e");
}
Send a STUN message directly using send
.
await client.send(bindingRequest);
Add or remove message listeners to handle incoming STUN messages.
Add Message Listener
client.addOnMessageListener((StunMessage message) {
print("Received message: \$message");
});
Remove Message Listener
client.removeOnMessageListener(listener);
sendAndAwait
has a default timeout of 6 seconds.- If exceeded, a
TimeoutException
is thrown.
- Ensure the STUN server address is resolved before sending messages.
- If
isAutoClose
is set totrue
, the connection will close automatically after receiving a response. - Transaction IDs must be randomly generated for uniqueness.
- If the STUN server cannot be resolved,
send
will throw an exception. - A timeout will result in a
TimeoutException
.
Use the NatChecker
constructor with optional parameters:
serverHost
: STUN server hostname (default:"stun.hot-chilli.net"
).serverPort
: STUN server port (default:3478
).localIp
: Local listening IP address (default:"0.0.0.0"
).localPort
: Local listening port (default:54320
).
Example:
import 'package:stun/src/nat_checker_rfc_5780.dart' as rfc5780;
void main() async {
rfc5780.NatChecker checker = rfc5780.NatChecker(
serverHost: "stun.l.google.com",
serverPort: 19302,
localIp: "0.0.0.0",
localPort: 12345,
);
final (mappingBehavior, filteringBehavior) = await checker.check();
print('NAT Mapping Behavior: $mappingBehavior');
print('NAT Filtering Behavior: $filteringBehavior');
}
Call check
to return the NAT mapping and filtering behaviors:
NatMappingBehavior
: Indicates how NAT maps external ports.NatFilteringBehavior
: Indicates how NAT filters external traffic.
Example Output:
NAT Mapping Behavior: NatMappingBehavior.EndpointIndependent
NAT Filtering Behavior: NatFilteringBehavior.AddressAndPortDependent
We welcome all forms of community contributions!
Please read the Contributing Guide to learn how to submit issues, request features, or contribute code.
This project is licensed under the LGPL-3.0 License.
- P2P Technology Explained (Part 1): NAT in Depth
- P2P Technology Explained (Part 2): NAT Traversal Methods
- P2P Technology Explained (Part 3): Advanced NAT Traversal
- Netmanias Comparison of RFC 3489 and STUN (RFC 5389/5780)
- RFC 3489
- RFC 5389
- RFC 5780
- RFC 3489 (Chinese)
- RFC 5389 (Chinese)
- RFC 5780 (Chinese)
This open-source project is for educational and research purposes only.
Due to possible patent or copyright implications, ensure you understand relevant laws before use.
Do not use this tool for commercial purposes or distribute it in any form without authorization.
All code and related content are for personal learning and reference. Any legal liability arising from use is solely the user's responsibility.
Thank you for your understanding and support.