<commit_before>/*
 * Copyright (c) 2017 <NAME>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

const dgram = require('dgram');
const debug = require('debug')('zyre:zbeacon');
const ZHelper = require('./zhelper');

// Static header: Z R E {version}
const BEACON_VERSION = 1;
const BEACON_HEADER = [0x5a, 0x52, 0x45, BEACON_VERSION];

/**
 * Creates a new UDP datagram as Buffer in the ZRE beacon format.
 *
 * @protected
 * @param {Buffer} identity - 16 byte UUID as Buffer
 * @param {number} mailbox - Network port of the zyre node
 * @return {Buffer} Binary Buffer in ZRE beacon format
 */
function createDataGramBuffer(identity, mailbox) {
  // Write mailbox port in network order
  const dgMailbox = Buffer.alloc(2);
  dgMailbox.writeUInt16BE(mailbox);

  return Buffer.concat([Buffer.from(BEACON_HEADER), identity, dgMailbox]);
}

/**
 * @typedef {object} DataGram
 * @property {string} identity - UUID as string
 * @property {number} mailbox - Network port
 */

/**
 * Reads and validates a given Buffer, returns an object with the identity and the mailbox port.
 *
 * @protected
 * @param {Buffer} dgBuffer - UDP datagram buffer
 * @return {DataGram}
 */
function readDataGramBuffer(dgBuffer) {
  try {
    if ((dgBuffer.length !== 22)) throw Error;
    if ((dgBuffer.compare(Buffer.from(BEACON_HEADER), 0, 4, 0, 4) !== 0)) throw Error;

    const dataGram = {};
    dataGram.identity = dgBuffer.toString('hex', 4, 20);
    dataGram.mailbox = dgBuffer.readUInt16BE(20);

    return dataGram;
  } catch (err) {
    return undefined;
  }
}

/**
 * ZBeacon implements the discovery beacon defined in the ZRE protocol, it listens for foreign
 * beacons and broadcasts his own datagram.
 */
class ZBeacon {

  /**
   * @param {object} options - Options object
   * @param {Buffer} options.identity - 16 byte UUID as Buffer
   * @param {number} options.mailbox - Mailbox of the zyre node
   * @param {IfaceData} options.ifaceData - Interface data
   * @param {number} [options.port=5670] - Broadcast port
   * @param {number} [options.interval=1000] - Interval of the beacon in ms
   * @param {ZyrePeers} options.zyrePeers - Global ZyrePeers object
   */
  constructor({ identity, mailbox, ifaceData, port = 5670, interval = 1000, zyrePeers }) {
    this._identity = identity;
    this._mailbox = mailbox;
    this._network = ifaceData.network;
    this._netmask = ifaceData.netmask;
    this._broadcast = ifaceData.broadcast;
    this._port = port;
    this._interval = interval;
    this._zyrePeers = zyrePeers;
    this._dgBuffer = createDataGramBuffer(identity, mailbox);
  }

  /**
   * Starts broadcasting the beacon.
   *
   * @return {Promise}
   */
  startBroadcasting() {
    this._nodeSock = dgram.createSocket('udp4');

    this._sendBroadcast = () => {
      this._nodeSock.send(this._dgBuffer, this._port, this._broadcast, () => {
        debug(`sent beacon to ${this._broadcast}:${this._port}`);
      });
    };

    return new Promise((resolve) => {
      this._nodeSock.bind(() => {
        this._nodeSock.setBroadcast(true);
        this._sendBroadcast();
        this._broadcastTimer = setInterval(this._sendBroadcast, this._interval);
        resolve();
      });
    });
  }

  /**
   * Starts listening for foreign beacons and pushes discovered peers to the ZyrePeers object.
   *
   * @return {Promise}
   */
  startListening() {
    this._peerSock = dgram.createSocket({
      type: 'udp4',
      reuseAddr: true,
    });

    this._peerSock.on('listening', () => {
      const address = this._peerSock.address();
      debug(`listening on ${address.address}:${address.port}`);
    });

    this._peerSock.on('message', (msg, rinfo) => {
      // Return if received udp beacon from different subnet
      if (!ZHelper.ipInSubnet(rinfo.address, this._network, this._netmask)) return;

      // Return if received own beacon
      if (msg.equals(this._dgBuffer)) return;

      // Return if received no valid zbeacon datagram
      const dataGram = readDataGramBuffer(msg);
      if (typeof dataGram === 'undefined') return;

      debug(`got beacon from ${rinfo.address}:${rinfo.port}`);

      this._zyrePeers.push({
        identity: dataGram.identity,
        address: rinfo.address,
        mailbox: dataGram.mailbox,
      });
    });

    return new Promise((resolve) => {
      this._peerSock.bind({<commit_msg>Don't check subnet if received own beacon<commit_after>/*
 * Copyright (c) 2017 <NAME>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

const dgram = require('dgram');
const debug = require('debug')('zyre:zbeacon');
const ZHelper = require('./zhelper');

// Static header: Z R E {version}
const BEACON_VERSION = 1;
const BEACON_HEADER = [0x5a, 0x52, 0x45, BEACON_VERSION];

/**
 * Creates a new UDP datagram as Buffer in the ZRE beacon format.
 *
 * @protected
 * @param {Buffer} identity - 16 byte UUID as Buffer
 * @param {number} mailbox - Network port of the zyre node
 * @return {Buffer} Binary Buffer in ZRE beacon format
 */
function createDataGramBuffer(identity, mailbox) {
  // Write mailbox port in network order
  const dgMailbox = Buffer.alloc(2);
  dgMailbox.writeUInt16BE(mailbox);

  return Buffer.concat([Buffer.from(BEACON_HEADER), identity, dgMailbox]);
}

/**
 * @typedef {object} DataGram
 * @property {string} identity - UUID as string
 * @property {number} mailbox - Network port
 */

/**
 * Reads and validates a given Buffer, returns an object with the identity and the mailbox port.
 *
 * @protected
 * @param {Buffer} dgBuffer - UDP datagram buffer
 * @return {DataGram}
 */
function readDataGramBuffer(dgBuffer) {
  try {
    if ((dgBuffer.length !== 22)) throw Error;
    if ((dgBuffer.compare(Buffer.from(BEACON_HEADER), 0, 4, 0, 4) !== 0)) throw Error;

    const dataGram = {};
    dataGram.identity = dgBuffer.toString('hex', 4, 20);
    dataGram.mailbox = dgBuffer.readUInt16BE(20);

    return dataGram;
  } catch (err) {
    return undefined;
  }
}

/**
 * ZBeacon implements the discovery beacon defined in the ZRE protocol, it listens for foreign
 * beacons and broadcasts his own datagram.
 */
class ZBeacon {

  /**
   * @param {object} options - Options object
   * @param {Buffer} options.identity - 16 byte UUID as Buffer
   * @param {number} options.mailbox - Mailbox of the zyre node
   * @param {IfaceData} options.ifaceData - Interface data
   * @param {number} [options.port=5670] - Broadcast port
   * @param {number} [options.interval=1000] - Interval of the beacon in ms
   * @param {ZyrePeers} options.zyrePeers - Global ZyrePeers object
   */
  constructor({ identity, mailbox, ifaceData, port = 5670, interval = 1000, zyrePeers }) {
    this._identity = identity;
    this._mailbox = mailbox;
    this._network = ifaceData.network;
    this._netmask = ifaceData.netmask;
    this._broadcast = ifaceData.broadcast;
    this._port = port;
    this._interval = interval;
    this._zyrePeers = zyrePeers;
    this._dgBuffer = createDataGramBuffer(identity, mailbox);
  }

  /**
   * Starts broadcasting the beacon.
   *
   * @return {Promise}
   */
  startBroadcasting() {
    this._nodeSock = dgram.createSocket('udp4');

    this._sendBroadcast = () => {
      this._nodeSock.send(this._dgBuffer, this._port, this._broadcast, () => {
        debug(`sent beacon to ${this._broadcast}:${this._port}`);
      });
    };

    return new Promise((resolve) => {
      this._nodeSock.bind(() => {
        this._nodeSock.setBroadcast(true);
        this._sendBroadcast();
        this._broadcastTimer = setInterval(this._sendBroadcast, this._interval);
        resolve();
      });
    });
  }

  /**
   * Starts listening for foreign beacons and pushes discovered peers to the ZyrePeers object.
   *
   * @return {Promise}
   */
  startListening() {
    this._peerSock = dgram.createSocket({
      type: 'udp4',
      reuseAddr: true,
    });

    this._peerSock.on('listening', () => {
      const address = this._peerSock.address();
      debug(`listening on ${address.address}:${address.port}`);
    });

    this._peerSock.on('message', (msg, rinfo) => {
      // Return if received own beacon
      if (msg.equals(this._dgBuffer)) return;

      // Return if received udp beacon from different subnet
      if (!ZHelper.ipInSubnet(rinfo.address, this._network, this._netmask)) return;

      // Return if received no valid zbeacon datagram
      const dataGram = readDataGramBuffer(msg);
      if (typeof dataGram === 'undefined') return;

      debug(`got beacon from ${rinfo.address}:${rinfo.port}`);

      this._zyrePeers.push({
        identity: dataGram.identity,
        address: rinfo.address,
        mailbox: dataGram.mailbox,
      });
    });

    return new Promise((resolve) => {
      this._peerSock.bind({
{'fraction_non_alphanumeric': 0.12959274015050906, 'fraction_numerical': 0.01239486498450642, 'mean_word_length': 3.201301720130172, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5157096', 'n_tokens_mistral': 3017, 'n_tokens_neox': 2836, 'n_words': 793}