Skip to content

segfault for no apparent reason. #42

@0wwafa

Description

@0wwafa
const { RTCPeerConnection } = require('wrtc');

/**
 * Checks if a TURN server is operational by attempting to gather a relay candidate.
 * @param {object} turnConfig - The TURN server configuration.
 * @param {number} [timeout=5000] - Timeout in milliseconds.
 * @returns {Promise<boolean>} - Resolves true on success, rejects on failure.
 */
function checkTurnServer(turnConfig, timeout = 5000) {
  return new Promise((resolve, reject) => {
    console.log('Testing TURN server:', turnConfig.urls);
    // The peerConnection is created here
    const peerConnection = new RTCPeerConnection({ iceServers: [turnConfig] });

    const timer = setTimeout(() => {
      // It's crucial to close the connection before rejecting
      peerConnection.close();
      reject(new Error(`Timed out after ${timeout}ms. Could not connect to the TURN server.`));
    }, timeout);

    // This is a robust way to ensure cleanup happens
    const cleanup = () => {
      clearTimeout(timer);
      // Ensure the connection is closed to prevent resource leaks
      if (peerConnection.signalingState !== 'closed') {
        peerConnection.close();
      }
    };

    peerConnection.onicecandidate = (event) => {
      if (event.candidate) {
        console.log('Found ICE candidate:', event.candidate.candidate);
        if (event.candidate.type === 'relay' || event.candidate.candidate.includes('typ relay')) {
          console.log('\nSuccessfully gathered a relay candidate!');
          cleanup();
          resolve(true);
        }
      }
    };

    peerConnection.onicegatheringstatechange = () => {
      console.log(`ICE gathering state changed to: ${peerConnection.iceGatheringState}`);
      if (peerConnection.iceGatheringState === 'complete') {
        cleanup();
        // If gathering is complete and we haven't resolved yet, it means no relay candidate was found.
        reject(new Error('ICE gathering finished, but no relay candidate was found. Check TURN server credentials and connectivity.'));
      }
    };

    peerConnection.createDataChannel('test');
    peerConnection.createOffer()
      .then(offer => peerConnection.setLocalDescription(offer))
      .catch(err => {
        cleanup();
        reject(err);
      });
  });
}

// --- Main execution block ---
async function main() {
  const args = process.argv.slice(2);

  if (args.length !== 3) {
    console.error('Invalid arguments. Please provide the required details.');
    console.error('Usage: node check_turn.js <turn_url> <username> <password>');
    console.error('Example: node check_turn.js turn:your-server.com:3478 myuser mypassword');
    process.exit(1);
  }

  const [turnUrl, username, password] = args;

  const turnConfig = {
    urls: turnUrl,
    username: username,✅ TURN server is alive and working!
    credential: password,
  };

  try {
    await checkTurnServer(turnConfig);
    console.log('\n✅ TURN server is alive and working!');
    // On success, wait briefly before exiting to allow wrtc to clean up.
    // The script will exit naturally with code 0.
    setTimeout(() => {}, 500);
  } catch (error) {
    console.error('\n❌ TURN server check failed:', error.message);
    // On failure, wait briefly and then explicitly exit with an error code.
    setTimeout(() => process.exit(1), 500);
  }
}

main();

The program works and after writing ✅ TURN server is alive and working! crashes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions