Noncollinear Perpendicular Microcrystalline
    Wondering what’s next for npm?Check out our public roadmap! »

    stun

    2.1.0 • Public • Published

    stun

    Build Status npm node license downloads Coverage Status Gitter chat

    Session Traversal Utilities for NAT (STUN) server. Implements RFC5389 with partial support RFC5766, RFC5245, RFC5780.

    Support

    Buy Me A Coffee

    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]): 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.

    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...
      }
    })

    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 - A STUN_BINDING_REQUEST message 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) => {
      const response = stun.decode(message);
      // do stuff ...
    });

    class StunMessage

    The StunMessage class is an utility that encapsulates the STUN protocol. This is a base class for StunRequest and StunResponse.

    • get type
    • get transactionId

    Returns the type and transactionId fields from the current message.

    • isLegacy(): bool

    Returns true if the message confirms to RFC3489 rather than RFC5389.

    • getAttribute(type): StunAttribute

    Returns the StunAttribute attribute of the specified type. The type argument is a number that should be an attribute type. See constants below. Return undefined if attribute is not exist.

    N.B. This method return only first matched attribute. If you want to get another one, try this:

    const attributes = Array.from(stunMessage).filter(attribute => attribute.type === STUN_ATTR_MAPPED_ADDRESS);
    • get count: number

    Returns the number of an attributes in the current message.

    class StunRequest

    The StunRequest encapsulates outgoing messages of the STUN protocol. Instances of the StunRequest can be created using the createMessage().

    • setType(type)

    Set the type of the message. The type argument is a number that should be a message type. See constants below.

    • setTransactionId(transaction: Buffer): bool

    Set the transaction id of the message. The transaction argument should be a Buffer and have length 12 bytes.

    • addAttribute(type, address: string, port: number)

    Adds a type attribute to the current message. The type argument should be one of:

    • STUN_ATTR_MAPPED_ADDRESS
    • STUN_ATTR_ALTERNATE_SERVER
    • STUN_ATTR_XOR_MAPPED_ADDRESS
    • STUN_ATTR_RESPONSE_ORIGIN
    • STUN_ATTR_OTHER_ADDRESS
    • STUN_ATTR_XOR_PEER_ADDRESS
    • STUN_ATTR_XOR_RELAYED_ADDRESS.
    stunMsg.addAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, '8.8.8.8', 19302)
    • addAttribute(type, value: String|Buffer[, encoding: string = 'utf8'])

    Adds a type attribute to the current message. The type argument should be one of:

    • STUN_ATTR_USERNAME
    • STUN_ATTR_REALM
    • STUN_ATTR_NONCE
    • STUN_ATTR_SOFTWARE
    • STUN_ATTR_ORIGIN
    • STUN_ATTR_USE_CANDIDATE
    • STUN_ATTR_ICE_CONTROLLED
    • STUN_ATTR_ICE_CONTROLLING
    • STUN_ATTR_DATA
    • STUN_ATTR_EVEN_PORT
    • STUN_ATTR_RESERVATION_TOKEN
    • STUN_ATTR_DONT_FRAGMENT
    • STUN_ATTR_PADDING.
    stunMsg.addAttribute(STUN_ATTR_SOFTWARE, 'node/8.2.0 stun/1.0.0')
    • addAttribute(type, value: number)

    Adds a type attribute to the current message. The type argument should be one of:

    • STUN_ATTR_RETRANSMIT_COUNT
    • STUN_ATTR_PRIORITY
    • STUN_ATTR_NETWORK_INFO
    • STUN_ATTR_NOMINATION
    • STUN_ATTR_CHANNEL_NUMBER
    • STUN_ATTR_LIFETIME
    • STUN_ATTR_REQUESTED_TRANSPORT
    • STUN_ATTR_CHANGE_REQUEST
    • STUN_ATTR_RESPONSE_PORT.
    stunMsg.addAttribute(STUN_ATTR_PRIORITY, 123)
    • addAttribute(type, value: array<number>)

    Adds a type attribute to the current message. The type argument should be STUN_ATTR_UNKNOWN_ATTRIBUTES.

    stunMsg.addAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES, [2, 3, 4])
    • addAttribute(type, code: number, reason: string)

    Adds a type attribute to the current message. The type argument should be STUN_ATTR_ERROR_CODE.

    stunMsg.addAttribute(STUN_ATTR_ERROR_CODE, STUN_CODE_UNAUTHORIZED, STUN_REASON_UNAUTHORIZED)
    • addAddress(ip: string, port: number): StunAddressAttribute

    Adds a MAPPED-ADDRESS attribute to the message.

    See RFC5389

    • addAlternateServer(ip: string, port: number): StunAddressAttribute

    Adds a ALTERNATE-SERVER attribute to the message.

    See RFC5389

    • addXorAddress(ip: string, port: number): StunXorAddressAttribute

    Adds a XOR-MAPPED-ADDRESS attribute to the message.

    See RFC5389

    • addUsername(username: string): StunByteStringAttribute

    Adds a USERNAME attribute to the message.

    See RFC5389

    • addRealm(realm: string): StunByteStringAttribute

    Adds a REALM attribute to the message.

    See RFC5389

    • addNonce(nonce: string): StunByteStringAttribute

    Adds a NONCE attribute to the message.

    See RFC5389

    • addSoftware(software: string): StunByteStringAttribute

    Adds a SOFTWARE attribute to the message.

    See RFC5389

    • addUnknownAttributes(attributes: number[]): StunUInt16ListAttribute

    Adds a UNKNOWN-ATTRIBUTES attribute to the message.

    See RFC5389

    • addError(code: number, reason: string): StunErrorCodeAttribute

    Adds a ERROR-CODE attribute to the message.

    See RFC5389

    • addPriority(priority: number): StunUInt32Attribute

    Adds a PRIORITY attribute to the message.

    See RFC8445

    • addUseCandidate(): StunByteStringAttribute

    Adds a USE-CANDIDATE attribute to the message.

    See RFC8445

    • addIceControlled(tiebreaker: Buffer): StunByteStringAttribute

    Adds a ICE-CONTROLLED attribute to the message.

    See RFC8445

    • addIceControlling(tiebreaker: Buffer): StunByteStringAttribute

    Adds a ICE-CONTROLLING attribute to the message.

    See RFC8445

    • removeAttribute(type): bool

    Remove a type attribute from the current message. Returns true if an attribute was removed. The type argument is a number that should be an attribute type. See constants below.

    • addMessageIntegrity(key: string)

    Adds a MESSAGE-INTEGRITY attribute that is valid for the current message. The key is the HMAC key used to generate the cryptographic HMAC hash.

    • addFingerprint()

    Adds a FINGERPRINT attribute that is valid for the current message.

    • toBuffer(): Buffer

    Converts a StunMessage object to the buffer.

    class StunServer

    The StunServer class is an EventEmitter that encapsulates a STUN server.

    • new StunServer(socket: dgram.Socket)

    Creates a new StunServer object. The socket argument should be an instance of dgram.Socket. The incoming message is silently ignored when it is not a stun one.

    • send(message: StunMessage, port: number, address: string[, cb: function])

    Sends the StunMessage message on the socket. The destination port and address must be specified. An optional callback function will be called when the message has been sent.

    • close()

    Stops the processing of the incoming messages and emits close event.

    • listen(port: number, [address: string], [callback: function()])

    Attemt to listen for messages on a named port and optional address. For UDP servers calls socket.bind under the hood.

    • Event: bindingRequest

    Emitted when the STUN_BINDING_REQUEST message is available on a socket.

    • Event: bindingIndication

    Emitted when the STUN_BINDING_INDICATION message is available on a socket.

    • Event: bindingResponse

    Emitted when the STUN_BINDING_RESPONSE message is available on a socket.

    • Event: bindingError

    Emitted when the STUN_BINDING_ERROR_RESPONSE message is available on a socket.

    • Event: close

    Emitted when the server closes.

    • Event: error

    Emitted when the server got an invalid message.

    • Event: listening

    The 'listening' event is emitted whenever a socket begins listening for messages.

    class StunAttribute

    The StunAttribute class is an utility for adding an attributes to the StunMessage message.

    • get type

    Returns the attribute type. See constants below.

    • get value

    Returns the value of the attribute. It depends on the value type of the attribute.

    stunMsg.getAttribute(STUN_ATTR_USERNAME).value        // string
    stunMsg.getAttribute(STUN_ATTR_PRIORITY).value        // number
    stunMsg.getAttribute(STUN_ATTR_MAPPED_ADDRESS).value  // object

    constants: object

    These are the types of STUN messages defined in RFC5389:

    • STUN_BINDING_REQUEST
    • STUN_BINDING_INDICATION
    • STUN_BINDING_RESPONSE
    • STUN_BINDING_ERROR_RESPONSE

    These are the event names for STUN messages above:

    • STUN_EVENT_BINDING_REQUEST
    • STUN_EVENT_BINDING_INDICATION
    • STUN_EVENT_BINDING_RESPONSE
    • STUN_EVENT_BINDING_ERROR_RESPONSE

    These are the types of STUN messages defined in RFC5766:

    • STUN_ALLOCATE_REQUEST
    • STUN_ALLOCATE_RESPONSE
    • STUN_ALLOCATE_ERROR_RESPONSE
    • STUN_REFRESH_REQUEST
    • STUN_REFRESH_RESPONSE
    • STUN_REFRESH_ERROR_RESPONSE
    • STUN_SEND_INDICATION
    • STUN_DATA_INDICATION
    • STUN_CREATE_PERMISSION_REQUEST
    • STUN_CREATE_PERMISSION_RESPONSE
    • STUN_CREATE_PERMISSION_ERROR_RESPONSE
    • STUN_CHANNEL_BIND_REQUEST
    • STUN_CHANNEL_BIND_RESPONSE
    • STUN_CHANNEL_BIND_ERROR_RESPONSE

    Thsese are all known STUN attributes, defined in RFC5389 and elsewhere:

    • STUN_ATTR_MAPPED_ADDRESS
    • STUN_ATTR_USERNAME
    • STUN_ATTR_MESSAGE_INTEGRITY
    • STUN_ATTR_ERROR_CODE
    • STUN_ATTR_UNKNOWN_ATTRIBUTES
    • STUN_ATTR_REALM
    • STUN_ATTR_NONCE
    • STUN_ATTR_XOR_MAPPED_ADDRESS
    • STUN_ATTR_SOFTWARE
    • STUN_ATTR_ALTERNATE_SERVER
    • STUN_ATTR_FINGERPRINT
    • STUN_ATTR_ORIGIN
    • STUN_ATTR_RETRANSMIT_COUNT
    • STUN_ATTR_PRIORITY
    • STUN_ATTR_USE_CANDIDATE
    • STUN_ATTR_ICE_CONTROLLED
    • STUN_ATTR_ICE_CONTROLLING
    • STUN_ATTR_NOMINATION
    • STUN_ATTR_NETWORK_INFO
    • STUN_ATTR_CHANNEL_NUMBER
    • STUN_ATTR_LIFETIME
    • STUN_ATTR_XOR_PEER_ADDRESS
    • STUN_ATTR_DATA
    • STUN_ATTR_XOR_RELAYED_ADDRESS
    • STUN_ATTR_EVEN_PORT
    • STUN_ATTR_REQUESTED_TRANSPORT
    • STUN_ATTR_DONT_FRAGMENT
    • STUN_ATTR_RESERVATION_TOKEN
    • STUN_ATTR_CHANGE_REQUEST
    • STUN_ATTR_PADDING
    • STUN_ATTR_RESPONSE_PORT
    • STUN_ATTR_RESPONSE_ORIGIN
    • STUN_ATTR_OTHER_ADDRESS

    These are the types of STUN error codes defined in RFC5389 and elsewhere:

    • STUN_CODE_TRY_ALTERNATE
    • STUN_CODE_BAD_REQUEST
    • STUN_CODE_UNAUTHORIZED
    • STUN_CODE_UNKNOWN_ATTRIBUTE
    • STUN_CODE_STALE_CREDENTIALS
    • STUN_CODE_STALE_NONCE
    • STUN_CODE_SERVER_ERROR
    • STUN_CODE_GLOBAL_FAILURE
    • STUN_CODE_ROLE_CONFLICT
    • STUN_CODE_FORBIDDEN
    • STUN_CODE_ALLOCATION_MISMATCH
    • STUN_CODE_WRONG_CREDENTIALS
    • STUN_CODE_UNSUPPORTED_PROTOCOL
    • STUN_CODE_ALLOCATION_QUOTA
    • STUN_CODE_INSUFFICIENT_CAPACITY

    These are the strings for the error codes above:

    • STUN_REASON_TRY_ALTERNATE
    • STUN_REASON_BAD_REQUEST
    • STUN_REASON_UNAUTHORIZED
    • STUN_REASON_UNKNOWN_ATTRIBUTE
    • STUN_REASON_STALE_CREDENTIALS
    • STUN_REASON_STALE_NONCE
    • STUN_REASON_SERVER_ERROR
    • STUN_REASON_ROLE_CONFLICT
    • STUN_REASON_FORBIDDEN
    • STUN_REASON_ALLOCATION_MISMATCH
    • STUN_REASON_WRONG_CREDENTIALS
    • STUN_REASON_UNSUPPORTED_PROTOCOL
    • STUN_REASON_ALLOCATION_QUOTA
    • STUN_REASON_INSUFFICIENT_CAPACITY

    class StunError

    Base class for all generated errors.

    • get packet: Buffer|StunMessage

    Received data.

    • get sender: object

    For UDP, this is an rinfo attribute.

    class StunMessageError

    The STUN server may receive invalid messages. This error class represent ones. Inherits from StunError.

    • get packet: Buffer

    See above.

    class StunResponseError

    This class represent protocol level errors, for messages with class type ERROR. Inherits from StunError.

    • get packet: StunMessage

    See above.

    License

    MIT, 2017-2019 (c) Dmitriy Tsvettsikh

    Install

    npm i stun

    DownloadsWeekly Downloads

    2,003

    Version

    2.1.0

    License

    MIT

    Unpacked Size

    135 kB

    Total Files

    55

    Last publish

    Collaborators

    • avatar
    • avatar