Stun
Low-level Session Traversal Utilities for NAT (STUN) client and server
Install / Use
/learn @nodertc/StunREADME
stun
Session Traversal Utilities for NAT (STUN) server. Implements RFC5389 with partial support RFC5766, RFC5245, RFC5780.
Support
Install
npm i stun
Usage
const stun = require('stun');
stun.request('stun.l.google.com:19302', (err, res) => {
if (err) {
console.error(err);
} else {
const { address } = res.getXorAddress();
console.log('your ip', address);
}
});
// or with promise
const res = await stun.request('stun.l.google.com:19302');
console.log('your ip', res.getXorAddress().address);
CLI
$ npm i -g stun
$ stun # started on udp/0.0.0.0:3478
API
createMessage(type: number [, transaction: Buffer]): StunRequestcreateTransaction(): BuffercreateServer(options: Object): StunServervalidateFingerprint(message: StunMessage): boolvalidateMessageIntegrity(message: StunMessage, key: string): boolrequest(url: string, [options: RequestOptions], callback: function): voidencode(message: StunMessage): Bufferdecode(message: Buffer): StunResponseclass StunRequestsetType(type)setTransactionId(transaction: Buffer): booladdAttribute(type, address: string, port: number)addAttribute(type, value: String|Buffer[, encoding: string = 'utf8'])addAttribute(type, value: number)addAttribute(type, value: array<number>)addAttribute(type, code: number, reason: string)addAddress(ip: string, port: number): StunAddressAttributeaddAlternateServer(ip: string, port: number): StunAddressAttributeaddXorAddress(ip: string, port: number): StunXorAddressAttributeaddUsername(username: string): StunByteStringAttributeaddRealm(realm: string): StunByteStringAttributeaddNonce(nonce: string): StunByteStringAttributeaddSoftware(software: string): StunByteStringAttributeaddUnknownAttributes(attributes: number[]): StunUInt16ListAttributeaddError(code: number, reason: string): StunErrorCodeAttributeaddPriority(priority: number): StunUInt32AttributeaddUseCandidate(): StunByteStringAttributeaddIceControlled(tiebreaker: Buffer): StunByteStringAttributeaddIceControlling(tiebreaker: Buffer): StunByteStringAttributeremoveAttribute(type): booladdMessageIntegrity(key: string)addFingerprint()toBuffer(): Buffer
class StunResponsegetAddress(): ObjectgetXorAddress(): ObjectgetAlternateServer(): ObjectgetUsername(): stringgetError(): ObjectgetRealm(): stringgetNonce(): stringgetSoftware(): stringgetUnknownAttributes(): number[]getMessageIntegrity(): BuffergetFingerprint(): numbergetPriority(): numbergetIceControlled(): BuffergetIceControlling(): Buffer
class StunMessageclass StunServernew StunServer(socket: dgram.Socket)send(message: StunMessage, port: number, address: string[, cb: function])close()listen(port: number, [address: string], [callback: function()])Event: bindingRequestEvent: bindingIndicationEvent: bindingResponseEvent: bindingErrorEvent: closeEvent: errorEvent: listening
class StunAttributeconstants: Objectclass StunErrorclass StunMessageErrorclass StunResponseError
createMessage(type: number [, transaction: Buffer]): StunRequest
Creates an StunRequest object of the specified type with random transaction field. The type argument is a number that should be a message type. See constants below.
createTransaction(): Buffer
Create transaction id for STUN message. Follow RFC5389.
<a name="create-server" />createServer(options: Object): StunServer
options.type: string
The type of socket. Must be 'udp4' or 'udp6'. Required.
options.socket: dgram.Socket
Creates a StunServer object of the specified type. The type argument should be 'udp' at the moment. An optional socket argument should be instance of dgram.Socket. If socket is not specifed, the dgram.Socket will be created with udp4 type and will bound to the "all interfaces" address on a random port.
validateFingerprint(message: StunMessage): bool
Check a FINGERPRINT attribute if it is specifed.
validateMessageIntegrity(message: StunMessage, key: string): bool
Check a MESSAGE_INTEGRITY attribute if it is specifed.
stunServer.on('bindingResponse', (msg) => {
if (!stun.validateFingerprint(msg)) {
// do stuff..
}
if (!stun.validateMessageIntegrity(msg, icePassword)) {
// do stuff...
}
})
<a name="request" />
request(url: string, [options: RequestOptions], callback: function): void
request(url: string, [options: RequestOptions]): Promise
Create a request STUN_BINDING_REQUEST to stun server, follow RFC5389. The first argument may be a host (stun.example.com), host with port (stun.example.com:1234) or host with port and protocol (stun://stun.example.com:1234). By default, port is 3478.
All options described below are optional.
options.server: StunServer- A stun server to receive responses.options.socket: dgram.Socket- A UDP socket over which the message will be send.options.message: StunMessage- ASTUN_BINDING_REQUESTmessage to send.options.timeout: number- Initial retransmission timeout (RTO) in ms, default is 500ms.options.maxTimeout: number- Maximal RTO, default is infinity.options.retries: number- Maximal the number of retries, default is 6
The last argument is a function with 2 arguments err and res. It's follow nodejs callback style. The second argument is instance of StunMessage.
encode(message: StunMessage): Buffer
Encode StunRequest or StunResponse into the Buffer.
decode(message: Buffer): StunResponse
Decode the Buffer into a StunResponse.
const socket = dgram.createSocket({ type: 'udp4' });
socket.on('message', (message) => {
con


