text:
/* 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 Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;

Cu.import("resource://services-common/log4moz.js");
Cu.import("resource://services-common/rest.js");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/util.js");

this.EXPORTED_SYMBOLS = ["JPAKEClient"];

const REQUEST_TIMEOUT         = 60; // 1 minute
const KEYEXCHANGE_VERSION     = 3;

const JPAKE_SIGNERID_SENDER   = "sender";
const JPAKE_SIGNERID_RECEIVER = "receiver";
const JPAKE_LENGTH_SECRET     = 8;
const JPAKE_LENGTH_CLIENTID   = 256;
const JPAKE_VERIFY_VALUE      = "0123456789ABCDEF";

/**
 * Client to exchange encrypted data using the J-PAKE algorithm.
 * The exchange between two clients of this type looks like this:
 *
 *
 *  Mobile                        Server                        Desktop
 *  ===================================================================
 *                                   |
 *  retrieve channel <---------------|
 *  generate random secret           |
 *  show PIN = secret + channel      |                 ask user for PIN
 *  upload Mobile's message 1 ------>|
 *                                   |----> retrieve Mobile's message 1
 *                                   |<----- upload Desktop's message 1
 *  retrieve Desktop's message 1 <---|
 *  upload Mobile's message 2 ------>|
 *                                   |----> retrieve Mobile's message 2
 *                                   |                      compute key
 *                                   |<----- upload Desktop's message 2
 *  retrieve Desktop's message 2 <---|
 *  compute key                      |
 *  encrypt known value ------------>|
 *                                   |-------> retrieve encrypted value
 *                                   | verify against local known value
 *
 *   At this point Desktop knows whether the PIN was entered correctly.
 *   If it wasn't, Desktop deletes the session. If it was, the account
 *   setup can proceed. If Desktop doesn't yet have an account set up,
 *   it will keep the channel open and let the user connect to or
 *   create an account.
 *
 *                                   |              encrypt credentials
 *                                   |<------------- upload credentials
 *  retrieve credentials <-----------|
 *  verify HMAC                      |
 *  decrypt credentials              |
 *  delete session ----------------->|
 *  start syncing                    |
 *
 *
 * Create a client object like so:
 *
 *   let client = new JPAKEClient(controller);
 *
 * The 'controller' object must implement the following methods:
 *
 *   displayPIN(pin) -- Called when a PIN has been generated and is ready to
 *     be displayed to the user. Only called on the client where the pairing
 *     was initiated with 'receiveNoPIN()'.
 *
 *   onPairingStart() -- Called when the pairing has started and messages are
 *     being sent back and forth over the channel. Only called on the client
 *     where the pairing was initiated with 'receiveNoPIN()'.
 *
 *   onPaired() -- Called when the device pairing has been established and
 *     we're ready to send the credentials over. To do that, the controller
 *     must call 'sendAndComplete()' while the channel is active.
 *
 *   onComplete(data) -- Called after transfer has been completed. On
 *     the sending side this is called with no parameter and as soon as the
 *     data has been uploaded. This does not mean the receiving side has
 *     actually retrieved them yet.
 *
 *   onAbort(error) -- Called whenever an error is encountered. All errors lead
 *     to an abort and the process has to be started again on both sides.
 *
 * To start the data transfer on the receiving side, call
 *
 *   client.receiveNoPIN();
 *
 * This will allocate a new channel on the server, generate a PIN, have it
 * displayed and then do the transfer once the protocol has been completed
 * with the sending side.
 *
 * To initiate the transfer from the sending side, call
 *
 *   client.pairWithPIN(pin, true);
 *
 * Once the pairing has been established, the controller's 'onPaired()' method
 * will be called. To then transmit the data, call
 *
 *   client.sendAndComplete(data);
 *
 * To abort the process, call
 *
 *   client.abort();
 *
 * Note that after completion or abort, the 'client' instance may not be reused.
 * You will have to create a new one in case you'd like to restart the process.
 */
this.JPAKEClient = function JPAKEClient(controller) {
  this.controller = controller;

  this._log = Log4Moz.repository.getLogger("Sync.JPAKEClient");
  this._log.level = Log4Moz.Level[Svc.Prefs.get(
    "log.logger.service.jpakeclient", "Debug")];

  this._serverURL = Svc.Prefs.get("jpake.serverURL");
  this._pollInterval = Svc.Prefs.get("jpake.pollInterval");
  this._maxTries = Svc.Prefs.get("jpake.maxTries");
  if (this._serverURL.slice(-1) != "/") {
    this._serverURL += "/";
  }

  this._jpake = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
                  .createInstance(Ci.nsISyncJPAKE);

  this._setClientID();
}
JPAKEClient.prototype = {

  _chain: Async.chain,

  /*
   * Public API
   */

  /**
   * Initiate pairing and receive data without providing a PIN. The PIN will
   * be generated and passed on to the controller to be displayed to the user.
   *
   * This is typically called on mobile devices where typing is tedious.
   */
  receiveNoPIN: function receiveNoPIN() {
    this._my_signerid = JPAKE_SIGNERID_RECEIVER;
    this._their_signerid = JPAKE_SIGNERID_SENDER;

    this._secret = this._createSecret();

    // Allow a large number of tries first while we wait for the PIN
    // to be entered on the other device.
    this._maxTries = Svc.Prefs.get("jpake.firstMsgMaxTries");
    this._chain(this._getChannel,
                this._computeStepOne,
                this._putStep,
                this._getStep,
                function(callback) {
                  // We fetched the first response from the other client.
                  // Notify controller of the pairing starting.
                  Utils.nextTick(this.controller.onPairingStart,
                                 this.controller);

                  // Now we can switch back to the smaller timeout.
                  this._maxTries = Svc.Prefs.get("jpake.maxTries");
                  callback();
                },
                this._computeStepTwo,
                this._putStep,
                this._getStep,
                this._computeFinal,
                this._computeKeyVerification,
                this._putStep,
                function(callback) {
                  // Allow longer time-out for the last message.
                  this._maxTries = Svc.Prefs.get("jpake.lastMsgMaxTries");
                  callback();
                },
                this._getStep,
                this._decryptData,
                this._complete)();
  },

  /**
   * Initiate pairing based on the PIN entered by the user.
   *
   * This is typically called on desktop devices where typing is easier than
   * on mobile.
   *
   * @param pin
   *        12 character string (in human-friendly base32) containing the PIN
   *        entered by the user.
   * @param expectDelay
   *        Flag that indicates that a significant delay between the pairing
   *        and the sending should be expected. v2 and earlier of the protocol
   *        did not allow for this and the pairing to a v2 or earlier client
   *        will be aborted if this flag is 'true'.
   */
  pairWithPIN: function pairWithPIN(pin, expectDelay) {
    this._my_signerid = JPAKE_SIGNERID_SENDER;
    this._their_signerid = JPAKE_SIGNERID_RECEIVER;

    this._channel = pin.slice(JPAKE_LENGTH_SECRET);
    this._channelURL = this._serverURL + this._channel;
    this._secret = pin.slice(0, JPAKE_LENGTH_SECRET);

    this._chain(this._computeStepOne,
                this._getStep,
                function (callback) {
                  // Ensure that the other client can deal with a delay for
                  // the last message if that's requested by the caller.
                  if (!expectDelay) {
                    return callback();
                  }
                  if (!this._incoming.version || this._incoming.version < 3) {
                    return this.abort(JPAKE_ERROR_DELAYUNSUPPORTED);
                  }
                  return callback();
                },
                this._putStep,
                this._computeStepTwo,
                this._getStep,
                this._putStep,
                this._computeFinal,
                this._getStep,
                this._verifyPairing)();
  },

  /**
   * Send data after a successful pairing.
   *
   * @param obj
   *        Object containing the data to send. It will be serialized as JSON.
   */
  sendAndComplete: function sendAndComplete(obj) {
    if (!this._paired || this._finished) {
      this._log.error("Can't send data, no active pairing!");
      throw "No active pairing!";
    }
    this._data = JSON.stringify(obj);
    this._chain(this._encryptData,
                this._putStep,
                this._complete)();
  },

  /**
   * Abort the current pairing. The channel on the server will be deleted
   * if the abort wasn't due to a network or server error. The controller's
   * 'onAbort()' method is notified in all cases.
   *
   * @param error [optional]
   *        Error constant indicating the reason for the abort. Defaults to
   *        user abort.
   */
  abort: function abort(error) {
    this._log.debug("Aborting...");
    this._finished = true;
    let self = this;

    // Default to "user aborted".
    if (!error) {
      error = JPAKE_ERROR_USERABORT;
    }

    if (error == JPAKE_ERROR_CHANNEL ||
        error == JPAKE_ERROR_NETWORK ||
        error == JPAKE_ERROR_NODATA) {
      Utils.nextTick(function() { this.controller.onAbort(error); }, this);
    } else {
      this._reportFailure(error, function() { self.controller.onAbort(error); });
    }
  },

  /*
   * Utilities
   */

  _setClientID: function _setClientID() {
    let rng = Cc["@mozilla.org/security/random-generator;1"]
                .createInstance(Ci.nsIRandomGenerator);
    let bytes = rng.generateRandomBytes(JPAKE_LENGTH_CLIENTID / 2);
    this._clientID = [("0" + byte.toString(16)).slice(-2)
                      for each (byte in bytes)].join("");
  },

  _createSecret: function _createSecret() {
    // 0-9a-z without 1,l,o,0
    const key = "23456789abcdefghijkmnpqrstuvwxyz";
    let rng = Cc["@mozilla.org/security/random-generator;1"]
                .createInstance(Ci.nsIRandomGenerator);
    let bytes = rng.generateRandomBytes(JPAKE_LENGTH_SECRET);
    return [key[Math.floor(byte * key.length / 256)]
            for each (byte in bytes)].join("");
  },

  _newRequest: function _newRequest(uri) {
    let request = new RESTRequest(uri);
    request.setHeader("X-KeyExchange-Id", this._clientID);
    request.timeout = REQUEST_TIMEOUT;
    return request;
  },

  /*
   * Steps of J-PAKE procedure
   */

  _getChannel: function _getChannel(callback) {
    this._log.trace("Requesting channel.");
    let request = this._newRequest(this._serverURL + "new_channel");
    request.get(Utils.bind2(this, function handleChannel(error) {
      if (this._finished) {
        return;
      }

      if (error) {
        this._log.error("Error acquiring channel ID. " + error);
        this.abort(JPAKE_ERROR_CHANNEL);
        return;
      }
      if (request.response.status != 200) {
        this._log.error("Error acquiring channel ID. Server responded with HTTP "
                        + request.response.status);
        this.abort(JPAKE_ERROR_CHANNEL);
        return;
      }

      try {
        this._channel = JSON.parse(request.response.body);
      } catch (ex) {
        this._log.error("Server responded with invalid JSON.");
        this.abort(JPAKE_ERROR_CHANNEL);
        return;
      }
      this._log.debug("Using channel " + this._channel);
      this._channelURL = this._serverURL + this._channel;

      // Don't block on UI code.
      let pin = this._secret + this._channel;
      Utils.nextTick(function() { this.controller.displayPIN(pin); }, this);
      callback();
    }));
  },

  // Generic handler for uploading data.
  _putStep: function _putStep(callback) {
    this._log.trace("Uploading message " + this._outgoing.type);
    let request = this._newRequest(this._channelURL);
    if (this._their_etag) {
      request.setHeader("If-Match", this._their_etag);
    } else {
      request.setHeader("If-None-Match", "*");
    }
    request.put(this._outgoing, Utils.bind2(this, function (error) {
      if (this._finished) {
        return;
      }

      if (error) {
        this._log.error("Error uploading data. " + error);
        this.abort(JPAKE_ERROR_NETWORK);
        return;
      }
      if (request.response.status != 200) {
        this._log.error("Could not upload data. Server responded with HTTP "
                        + request.response.status);
        this.abort(JPAKE_ERROR_SERVER);
        return;
      }
      // There's no point in returning early here since the next step will
      // always be a GET so let's pause for twice the poll interval.
      this._my_etag = request.response.headers["etag"];
      Utils.namedTimer(function () { callback(); }, this._pollInterval * 2,
                       this, "_pollTimer");
    }));
  },

  // Generic handler for polling for and retrieving data.
  _pollTries: 0,
  _getStep: function _getStep(callback) {
    this._log.trace("Retrieving next message.");
    let request = this._newRequest(this._channelURL);
    if (this._my_etag) {
      request.setHeader("If-None-Match", this._my_etag);
    }

    request.get(Utils.bind2(this, function (error) {
      if (this._finished) {
        return;
      }

      if (error) {
        this._log.error("Error fetching data. " + error);
        this.abort(JPAKE_ERROR_NETWORK);
        return;
      }

      if (request.response.status == 304) {
        this._log.trace("Channel hasn't been updated yet. Will try again later.");
        if (this._pollTries >= this._maxTries) {
          this._log.error("Tried for " + this._pollTries + " times, aborting.");
          this.abort(JPAKE_ERROR_TIMEOUT);
          return;
        }
        this._pollTries += 1;
        Utils.namedTimer(function() { this._getStep(callback); },
                         this._pollInterval, this, "_pollTimer");
        return;
      }
      this._pollTries = 0;

      if (request.response.status == 404) {
        this._log.error("No data found in the channel.");
        this.abort(JPAKE_ERROR_NODATA);
        return;
      }
      if (request.response.status != 200) {
        this._log.error("Could not retrieve data. Server responded with HTTP "
                        + request.response.status);
        this.abort(JPAKE_ERROR_SERVER);
        return;
      }

      this._their_etag = request.response.headers["etag"];
      if (!this._their_etag) {
        this._log.error("Server did not supply ETag for message: "
                        + request.response.body);
        this.abort(JPAKE_ERROR_SERVER);
        return;
      }

      try {
        this._incoming = JSON.parse(request.response.body);
      } catch (ex) {
        this._log.error("Server responded with invalid JSON.");
        this.abort(JPAKE_ERROR_INVALID);
        return;
      }
      this._log.trace("Fetched message " + this._incoming.type);
      callback();
    }));
  },

  _reportFailure: function _reportFailure(reason, callback) {
    this._log.debug("Reporting failure to server.");
    let request = this._newRequest(this._serverURL + "report");
    request.setHeader("X-KeyExchange-Cid", this._channel);
    request.setHeader("X-KeyExchange-Log", reason);
    request.post("", Utils.bind2(this, function (error) {
      if (error) {
        this._log.warn("Report failed: " + error);
      } else if (request.response.status != 200) {
        this._log.warn("Report failed. Server responded with HTTP "
                       + request.response.status);
      }

      // Do not block on errors, we're done or aborted by now anyway.
      callback();
    }));
  },

  _computeStepOne: function _computeStepOne(callback) {
    this._log.trace("Computing round 1.");
    let gx1 = {};
    let gv1 = {};
    let r1 = {};
    let gx2 = {};
    let gv2 = {};
    let r2 = {};
    try {
      this._jpake.round1(this._my_signerid, gx1, gv1, r1, gx2, gv2, r2);
    } catch (ex) {
      this._log.error("JPAKE round 1 threw: " + ex);
      this.abort(JPAKE_ERROR_INTERNAL);
      return;
    }
    let one = {gx1: gx1.value,
               gx2: gx2.value,
               zkp_x1: {gr: gv1.value, b: r1.value, id: this._my_signerid},
               zkp_x2: {gr: gv2.value, b: r2.value, id: this._my_signerid}};
    this._outgoing = {type: this._my_signerid + "1",
                      version: KEYEXCHANGE_VERSION,
                      payload: one};
    this._log.trace("Generated message " + this._outgoing.type);
    callback();
  },

  _computeStepTwo: function _computeStepTwo(callback) {
    this._log.trace("Computing round 2.");
    if (this._incoming.type != this._their_signerid + "1") {
      this._log.error("Invalid round 1 message: "
                      + JSON.stringify(this._incoming));
      this.abort(JPAKE_ERROR_WRONGMESSAGE);
      return;
    }

    let step1 = this._incoming.payload;
    if (!step1 || !step1.zkp_x1 || step1.zkp_x1.id != this._their_signerid
        || !step1.zkp_x2 || step1.zkp_x2.id != this._their_signerid) {
      this._log.error("Invalid round 1 payload: " + JSON.stringify(step1));
      this.abort(JPAKE_ERROR_WRONGMESSAGE);
      return;
    }

    let A = {};
    let gvA = {};
    let rA = {};

    try {
      this._jpake.round2(this._their_signerid, this._secret,
                         step1.gx1, step1.zkp_x1.gr, step1.zkp_x1.b,
                         step1.gx2, step1.zkp_x2.gr, step1.zkp_x2.b,
                         A, gvA, rA);
    } catch (ex) {
      this._log.error("JPAKE round 2 threw: " + ex);
      this.abort(JPAKE_ERROR_INTERNAL);
      return;
    }
    let two = {A: A.value,
               zkp_A: {gr: gvA.value, b: rA.value, id: this._my_signerid}};
    this._outgoing = {type: this._my_signerid + "2",
                      version: KEYEXCHANGE_VERSION,
                      payload: two};
    this._log.trace("Generated message " + this._outgoing.type);
    callback();
  },

  _computeFinal: function _computeFinal(callback) {
    if (this._incoming.type != this._their_signerid + "2") {
      this._log.error("Invalid round 2 message: "
                      + JSON.stringify(this._incoming));
      this.abort(JPAKE_ERROR_WRONGMESSAGE);
      return;
    }

    let step2 = this._incoming.payload;
    if (!step2 || !step2.zkp_A || step2.zkp_A.id != this._their_signerid) {
      this._log.error("Invalid round 2 payload: " + JSON.stringify(step1));
      this.abort(JPAKE_ERROR_WRONGMESSAGE);
      return;
    }

    let aes256Key = {};
    let hmac256Key = {};

    try {
      this._jpake.final(step2.A, step2.zkp_A.gr, step2.zkp_A.b, HMAC_INPUT,
                        aes256Key, hmac256Key);
    } catch (ex) {
      this._log.error("JPAKE final round threw: " + ex);
      this.abort(JPAKE_ERROR_INTERNAL);
      return;
    }

    this._crypto_key = aes256Key.value;
    let hmac_key = Utils.makeHMACKey(Utils.safeAtoB(hmac256Key.value));
    this._hmac_hasher = Utils.makeHMACHasher(Ci.nsICryptoHMAC.SHA256, hmac_key);

    callback();
  },

  _computeKeyVerification: function _computeKeyVerification(callback) {
    this._log.trace("Encrypting key verification value.");
    let iv, ciphertext;
    try {
      iv = Svc.Crypto.generateRandomIV();
      ciphertext = Svc.Crypto.encrypt(JPAKE_VERIFY_VALUE,
                                      this._crypto_key, iv);
    } catch (ex) {
      this._log.error("Failed to encrypt key verification value.");
      this.abort(JPAKE_ERROR_INTERNAL);
      return;
    }
    this._outgoing = {type: this._my_signerid + "3",
                      version: KEYEXCHANGE_VERSION,
                      payload: {ciphertext: ciphertext, IV: iv}};
    this._log.trace("Generated message " + this._outgoing.type);
    callback();
  },

  _verifyPairing: function _verifyPairing(callback) {
    this._log.trace("Verifying their key.");
    if (this._incoming.type != this._their_signerid + "3") {
      this._log.error("Invalid round 3 data: " +
                      JSON.stringify(this._incoming));
      this.abort(JPAKE_ERROR_WRONGMESSAGE);
      return;
    }
    let step3 = this._incoming.payload;
    let ciphertext;
    try {
      ciphertext = Svc.Crypto.encrypt(JPAKE_VERIFY_VALUE,
                                      this._crypto_key, step3.IV);
      if (ciphertext != step3.ciphertext) {
        throw "Key mismatch!";
      }
    } catch (ex) {
      this._log.error("Keys don't match!");
      this.abort(JPAKE_ERROR_KEYMISMATCH);
      return;
    }

    this._log.debug("Verified pairing!");
    this._paired = true;
    Utils.nextTick(function () { this.controller.onPaired(); }, this);
    callback();
  },

  _encryptData: function _encryptData(callback) {
    this._log.trace("Encrypting data.");
    let iv, ciphertext, hmac;
    try {
      iv = Svc.Crypto.generateRandomIV();
      ciphertext = Svc.Crypto.encrypt(this._data, this._crypto_key, iv);
      hmac = Utils.bytesAsHex(Utils.digestUTF8(ciphertext, this._hmac_hasher));
    } catch (ex) {
      this._log.error("Failed to encrypt data.");
      this.abort(JPAKE_ERROR_INTERNAL);
      return;
    }
    this._outgoing = {type: this._my_signerid + "3",
                      version: KEYEXCHANGE_VERSION,
                      payload: {ciphertext: ciphertext, IV: iv, hmac: hmac}};
    this._log.trace("Generated message " + this._outgoing.type);
    callback();
  },

  _decryptData: function _decryptData(callback) {
    this._log.trace("Verifying their key.");
    if (this._incoming.type != this._their_signerid + "3") {
      this._log.error("Invalid round 3 data: "
                      + JSON.stringify(this._incoming));
      this.abort(JPAKE_ERROR_WRONGMESSAGE);
      return;
    }
    let step3 = this._incoming.payload;
    try {
      let hmac = Utils.bytesAsHex(
        Utils.digestUTF8(step3.ciphertext, this._hmac_hasher));
      if (hmac != step3.hmac) {
        throw "HMAC validation failed!";
      }
    } catch (ex) {
      this._log.error("HMAC validation failed.");
      this.abort(JPAKE_ERROR_KEYMISMATCH);
      return;
    }

    this._log.trace("Decrypting data.");
    let cleartext;
    try {
      cleartext = Svc.Crypto.decrypt(step3.ciphertext, this._crypto_key,
                                     step3.IV);
    } catch (ex) {
      this._log.error("Failed to decrypt data.");
      this.abort(JPAKE_ERROR_INTERNAL);
      return;
    }

    try {
      this._newData = JSON.parse(cleartext);
    } catch (ex) {
      this._log.error("Invalid data data: " + JSON.stringify(cleartext));
      this.abort(JPAKE_ERROR_INVALID);
      return;
    }

    this._log.trace("Decrypted data.");
    callback();
  },

  _complete: function _complete() {
    this._log.debug("Exchange completed.");
    this._finished = true;
    Utils.nextTick(function () { this.controller.onComplete(this._newData); },
                   this);
  }

};


text:
package org.apache.camel.component.aws.s3;

import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;

public class S3ComponentClientRegistryTest extends CamelTestSupport {

    @Test
    public void createEndpointWithMinimalS3ClientConfiguration() throws Exception {

        AmazonS3ClientMock clientMock = new AmazonS3ClientMock();
        context.getRegistry().bind("amazonS3Client", clientMock);
        S3Component component = new S3Component(context);
        S3Endpoint endpoint = (S3Endpoint)component.createEndpoint("aws-s3://MyBucket");

        assertEquals("MyBucket", endpoint.getConfiguration().getBucketName());
        assertNotNull(endpoint.getConfiguration().getAmazonS3Client());
        assertNull(endpoint.getConfiguration().getRegion());
        assertTrue(endpoint.getConfiguration().isDeleteAfterRead());
        assertEquals(10, endpoint.getMaxMessagesPerPoll());
        assertNull(endpoint.getConfiguration().getPolicy());
        assertNull(endpoint.getConfiguration().getPrefix());
        assertTrue(endpoint.getConfiguration().isIncludeBody());
    }

    @Test(expected = IllegalArgumentException.class)
    public void createEndpointWithMinimalS3ClientMisconfiguration() throws Exception {

        S3Component component = new S3Component(context);
        S3Endpoint endpoint = (S3Endpoint)component.createEndpoint("aws-s3://MyBucket");
    }
}

redpajama_set_name: RedPajamaGithub


text:
{-# LANGUAGE OverloadedStrings, FlexibleContexts, GeneralizedNewtypeDeriving #-}

module IPDetector where

import qualified Data.ByteString as BS

import Control.Monad.IO.Class
  ( MonadIO
  , liftIO
  )

import Control.Applicative (Applicative)

import Data.Text (Text, pack)

import Safe (headMay)

import Data.IP (IPv4)
import Network.DNS.Types (DNSError)
import Network.DNS.Lookup (lookupA)
import Network.DNS.Resolver
  ( FileOrNumericHost (RCHostName)
  , ResolvConf (ResolvConf)
  , defaultResolvConf
  , makeResolvSeed
  , resolvInfo
  , withResolver
  )

import Control.Monad.Except
  ( ExceptT
  , MonadError
  , runExceptT
  , throwError
  )

newtype IPDetector a = IPDetector { unIPDetector :: ExceptT IPDetectorError IO a }
  deriving ( Functor, Applicative, Monad
           , MonadError IPDetectorError, MonadIO)

runIPDetector :: IPDetector a -> IO (Either IPDetectorError a)
runIPDetector = runExceptT . unIPDetector

data IPDetectorError = IPDetectorError
                     | GetIPError DNSError
                     deriving (Show)

detectIP :: IPDetector Text
detectIP = do
  resolverIPs <- dnsLookup "resolver1.opendns.com" defaultResolvConf
  resolverIP <- maybe (throwError IPDetectorError) (return . show) (headMay resolverIPs)
  ips <- dnsLookup "myip.opendns.com"
                   defaultResolvConf { resolvInfo = RCHostName resolverIP }
  maybe (throwError IPDetectorError) (return . pack . show) (headMay ips)

dnsLookup :: (MonadIO m, MonadError IPDetectorError m)
          => BS.ByteString -> ResolvConf -> m [IPv4]
dnsLookup host resolv = do
  resp <- liftIO $ do
    rs' <- makeResolvSeed resolv
    withResolver rs' $ \resolver -> lookupA resolver host
  either (throwError . GetIPError) return resp


text:
import minidom
import xml.sax,xml.sax.handler

START_ELEMENT = "START_ELEMENT"
END_ELEMENT = "END_ELEMENT"
COMMENT = "COMMENT"
START_DOCUMENT = "START_DOCUMENT"
END_DOCUMENT = "END_DOCUMENT"
PROCESSING_INSTRUCTION = "PROCESSING_INSTRUCTION"
IGNORABLE_WHITESPACE = "IGNORABLE_WHITESPACE"
CHARACTERS = "CHARACTERS"

class PullDOM(xml.sax.ContentHandler):
    def __init__(self):
        self.firstEvent = [None, None]
        self.lastEvent = self.firstEvent
        self._ns_contexts = [{}] # contains uri -> prefix dicts
        self._current_context = self._ns_contexts[-1]

    def setDocumentLocator(self, locator): pass

    def startPrefixMapping(self, prefix, uri):
        self._ns_contexts.append(self._current_context.copy())
        self._current_context[uri] = prefix

    def endPrefixMapping(self, prefix):
        del self._ns_contexts[-1]

    def startElementNS(self, name, tagName , attrs):
        uri,localname = name
        if uri:
            # When using namespaces, the reader may or may not
            # provide us with the original name. If not, create
            # *a* valid tagName from the current context.
            if tagName is None:
                tagName = self._current_context[uri] + ":" + localname
            node = self.document.createElementNS(uri, tagName)
        else:
            # When the tagname is not prefixed, it just appears as
            # localname
            node = self.document.createElement(localname)

        for aname,value in attrs.items():
            a_uri, a_localname = aname
            if a_uri:
                qname = self._current_context[a_uri] + ":" + a_localname
                attr = self.document.createAttributeNS(a_uri, qname)
            else:
                attr = self.document.createAttribute(a_localname)
            attr.value = value
            node.setAttributeNode(attr)

        parent = self.curNode
        node.parentNode = parent
        self.curNode = node

        self.lastEvent[1] = [(START_ELEMENT, node), None]
        self.lastEvent = self.lastEvent[1]
        #self.events.append((START_ELEMENT, node))

    def endElementNS(self, name, tagName):
        node = self.curNode
        self.lastEvent[1] = [(END_ELEMENT, node), None]
        self.lastEvent = self.lastEvent[1]
        #self.events.append((END_ELEMENT, node))
        self.curNode = node.parentNode

    def startElement(self, name, attrs):
        node = self.document.createElement(name)

        for aname,value in attrs.items():
            attr = self.document.createAttribute(aname)
            attr.value = value
            node.setAttributeNode(attr)

        parent = self.curNode
        node.parentNode = parent
        self.curNode = node

        self.lastEvent[1] = [(START_ELEMENT, node), None]
        self.lastEvent = self.lastEvent[1]
        #self.events.append((START_ELEMENT, node))

    def endElement(self, name):
        node = self.curNode
        self.lastEvent[1] = [(END_ELEMENT, node), None]
        self.lastEvent = self.lastEvent[1]
        #self.events.append((END_ELEMENT, node))
        self.curNode = node.parentNode

    def comment(self, s):
        node = self.document.createComment(s)
        parent = self.curNode
        node.parentNode = parent
        self.lastEvent[1] = [(COMMENT, node), None]
        self.lastEvent = self.lastEvent[1]
        #self.events.append((COMMENT, node))

    def processingInstruction(self, target, data):
        node = self.document.createProcessingInstruction(target, data)

        parent = self.curNode
        node.parentNode = parent
        self.lastEvent[1] = [(PROCESSING_INSTRUCTION, node), None]
        self.lastEvent = self.lastEvent[1]
        #self.events.append((PROCESSING_INSTRUCTION, node))

    def ignorableWhitespace(self, chars):
        node = self.document.createTextNode(chars[start:start + length])
        parent = self.curNode
        node.parentNode = parent
        self.lastEvent[1] = [(IGNORABLE_WHITESPACE, node), None]
        self.lastEvent = self.lastEvent[1]
        #self.events.append((IGNORABLE_WHITESPACE, node))

    def characters(self, chars):
        node = self.document.createTextNode(chars)
        parent = self.curNode
        node.parentNode = parent
        self.lastEvent[1] = [(CHARACTERS, node), None]
        self.lastEvent = self.lastEvent[1]

    def startDocument(self):
        node = self.curNode = self.document = minidom.Document()
        node.parentNode = None
        self.lastEvent[1] = [(START_DOCUMENT, node), None]
        self.lastEvent = self.lastEvent[1]
        #self.events.append((START_DOCUMENT, node))

    def endDocument(self):
        assert not self.curNode.parentNode
        for node in self.curNode.childNodes:
            if node.nodeType == node.ELEMENT_NODE:
                self.document.documentElement = node
        #if not self.document.documentElement:
        #    raise Error, "No document element"

        self.lastEvent[1] = [(END_DOCUMENT, node), None]
        #self.events.append((END_DOCUMENT, self.curNode))

class ErrorHandler:
    def warning(self, exception):
        print exception
    def error(self, exception):
        raise exception
    def fatalError(self, exception):
        raise exception

class DOMEventStream:
    def __init__(self, stream, parser, bufsize):
        self.stream = stream
        self.parser = parser
        self.bufsize = bufsize
        self.reset()

    def reset(self):
        self.pulldom = PullDOM()
        # This content handler relies on namespace support
        self.parser.setFeature(xml.sax.handler.feature_namespaces,1)
        self.parser.setContentHandler(self.pulldom)

    def __getitem__(self, pos):
        rc = self.getEvent()
        if rc:
            return rc
        raise IndexError

    def expandNode(self, node):
        event = self.getEvent()
        while event:
            token, cur_node = event
            if cur_node is node:
                return
            if token != END_ELEMENT:
                cur_node.parentNode.appendChild(cur_node)
            event = self.getEvent()

    def getEvent(self):
        if not self.pulldom.firstEvent[1]:
            self.pulldom.lastEvent = self.pulldom.firstEvent
        while not self.pulldom.firstEvent[1]:
            buf=self.stream.read(self.bufsize)
            if not buf:
                #FIXME: why doesn't Expat close work?
                #self.parser.close()
                return None
            self.parser.feed(buf)
        rc = self.pulldom.firstEvent[1][0]
        self.pulldom.firstEvent[1] = self.pulldom.firstEvent[1][1]
        return rc

class SAX2DOM(PullDOM):

    def startElementNS(self, name, tagName , attrs):
        PullDOM.startElementNS(self, name, tagName, attrs)
        self.curNode.parentNode.appendChild(self.curNode)

    def startElement(self, name, attrs):
        PullDOM.startElement(self, name, attrs)
        self.curNode.parentNode.appendChild(self.curNode)

    def processingInstruction(self, target, data):
        PullDOM.processingInstruction(self, target, data)
        node = self.lastEvent[0][1]
        node.parentNode.appendChild(node)

    def ignorableWhitespace(self, chars):
        PullDOM.ignorableWhitespace(self, chars)
        node = self.lastEvent[0][1]
        node.parentNode.appendChild(node)

    def characters(self, chars):
        PullDOM.characters(self, chars)
        node = self.lastEvent[0][1]
        node.parentNode.appendChild(node)

default_bufsize = (2 ** 14) - 20

def parse(stream_or_string, parser=None, bufsize=default_bufsize):
    if type(stream_or_string) is type(""):
        stream = open(stream_or_string)
    else:
        stream = stream_or_string
    if not parser:
        parser = xml.sax.make_parser()
    return DOMEventStream(stream, parser, bufsize)

def parseString(string, parser=None):
    try:
        from cStringIO import StringIO
    except ImportError:
        from StringIO import StringIO

    bufsize = len(string)
    buf = StringIO(string)
    if not parser:
        parser = xml.sax.make_parser()
    return DOMEventStream(buf, parser, bufsize)


text:
package ipfix

type Session struct {

	//AssociatedTemplates Templates points to the list of active templates. Without a template record a data record can not be encoded or decoded
	AssociatedTemplates *ActiveTemplates
}

/*

 Achieving this goal is complicated somewhat by two factors: 1) the
   need to support the reuse of Template IDs within a Transport Session
   and 2) the need to support unreliable transmission for Templates when
   UDP is used as the transport protocol for IPFIX Messages.

   Sequencing Template Management Actions

   Since there is no guarantee of the ordering of exported IPFIX
   Messages across SCTP Streams or over UDP, an Exporting Process MUST
   sequence all Template management actions (i.e., Template Records
   defining new Templates and Template Withdrawals withdrawing them)
   using the Export Time field in the IPFIX Message Header.

   An Exporting Process MUST NOT export a Data Set described by a new
   Template in an IPFIX Message with an Export Time before the Export
   Time of the IPFIX Message containing that Template.  If a new
   Template and a Data Set described by it appear in the same IPFIX
   Message, the Template Set containing the Template MUST appear before
   the Data Set in the Message.

   An Exporting Process MUST NOT export any Data Sets described by a
   withdrawn Template in IPFIX Messages with an Export Time after the
   Export Time of the IPFIX Message containing the Template Withdrawal
   withdrawing that Template.

Claise, et al.               Standards Track                   [Page 42]

RFC 7011              IPFIX Protocol Specification        September 2013

   Put another way, a Template describes Data Records contained in IPFIX
   Messages when the Export Time of such messages is between a specific
   start and end time, inclusive.  The start time is the Export Time of
   the IPFIX Message containing the Template Record.  The end time is
   one of two times: if the template is withdrawn during the session,
   then it is the Export Time of the IPFIX Message containing the
   Template Withdrawal for the template; otherwise, it is the end of the
   Transport Session.

   Even if sent in order, IPFIX Messages containing Template management
   actions could arrive at the Collecting Process out of order, i.e., if
   sent via UDP or via different SCTP Streams.  Given this, Template
   Withdrawals and subsequent reuse of Template IDs can significantly
   complicate the problem of determining Template lifetimes at the
   Collecting Process.  A Collecting Process MAY implement a buffer and
   use Export Time information to disambiguate the order of Template
   management actions.  This buffer, if implemented, SHOULD be
   configurable to impart a delay on the order of the maximum reordering
   delay experienced at the Collecting Process.  Note, in this case,
   that the Collecting Process's clock is irrelevant: it is only
   comparing the Export Times of Messages to each other.

8.3.  Additional Considerations for Template Management over SCTP

   The specifications in this section apply only to SCTP; in cases of
   contradiction with specifications in Section 8 or Section 8.1, this
   section takes precedence.

   Template Sets and Options Template Sets MAY be sent on any SCTP
   Stream.  Data Sets sent on a given SCTP Stream MAY be represented by
   Template Records exported on any SCTP Stream.

   Template Sets and Options Template Sets MUST be sent reliably, using
   SCTP ordered delivery.

   Template Withdrawals MAY be sent on any SCTP Stream.  Template
   Withdrawals MUST be sent reliably, using SCTP ordered delivery.
   Template IDs MAY be reused by sending a Template Withdrawal and/or a
   new Template Record on a different SCTP Stream than the stream on
   which the original Template was sent.

   Additional Template Management considerations are provided in
   [RFC6526], which specifies an extension to explicitly link Templates
   with SCTP Streams.  In exchange for more restrictive rules on the
   assignment of Template Records to SCTP Streams, this extension allows
   fast, reliable reuse of Template IDs and estimation of Data Record
   loss per Template.

Additional Considerations for Template Management over UDP

   The specifications in this section apply only to UDP; in cases of
   contradiction with specifications in Section 8 or Section 8.1, this
   section takes precedence.

   Since UDP provides no method for reliable transmission of Templates,
   Exporting Processes using UDP as the transport protocol MUST
   periodically retransmit each active Template at regular intervals.
   The Template retransmission interval MUST be configurable via, for
   example, the templateRefreshTimeout and optionsTemplateRefreshTimeout
   parameters as defined in [RFC6728].  Default settings for these
   values are deployment- and application-specific.

   Before exporting any Data Records described by a given Template
   Record or Options Template Record, especially in the case of Template
   ID reuse as described in Section 8.1, the Exporting Process SHOULD
   send multiple copies of the Template Record in a separate IPFIX
   Message, in order to help ensure that the Collecting Process has
   received it.

   In order to minimize resource requirements for Templates that are no
   longer being used by the Exporting Process, the Collecting Process
   MAY associate a lifetime with each Template received in a Transport
   Session.  Templates not refreshed by the Exporting Process within the
   lifetime can then be discarded by the Collecting Process.  The
   Template lifetime at the Collecting Process MAY be exposed by a
   configuration parameter or MAY be derived from observation of the
   interval of periodic Template retransmissions from the Exporting
   Process.  In this latter case, the Template lifetime SHOULD default
   to at least 3 times the observed retransmission rate.

   Template Withdrawals (Section 8.1) MUST NOT be sent by Exporting
   Processes exporting via UDP and MUST be ignored by Collecting
   Processes collecting via UDP.  Template IDs MAY be reused by
   Exporting Processes by exporting a new Template for the Template ID
   after waiting at least 3 times the retransmission delay.  Note that
   Template ID reuse may lead to incorrect interpretation of Data
   Records if the retransmission and lifetime are not properly
   configured.

   When a Collecting Process receives a new Template Record or Options
   Template Record via UDP for an already-allocated Template ID, and
   that Template or Options Template is identical to the already-
   received Template or Options Template, it SHOULD NOT log the
   retransmission, as this is the normal operation of Template refresh
   over UDP.

Claise, et al.               Standards Track                   [Page 44]

RFC 7011              IPFIX Protocol Specification        September 2013

   When a Collecting Process receives a new Template Record or Options
   Template Record for an already-allocated Template ID, and that
   Template or Options Template is different from the already-received
   Template or Options Template, the Collecting Process MUST replace the
   Template or Options Template for that Template ID with the newly
   received Template or Options Template.  This is the normal operation
   of Template ID reuse over UDP.

   As Template IDs are unique per UDP session and per Observation
   Domain, at any given time, the Collecting Process SHOULD maintain the
   following for all the current Template Records and Options Template
   Records: <IPFIX Device, Exporter source UDP port, Collector IP
   address, Collector destination UDP port, Observation Domain ID,
   Template ID, Template Definition, Last Received>.

9.  The Collecting Process's Side

   This section describes the handling of the IPFIX protocol at the
   Collecting Process common to all transport protocols.  Additional
   considerations for SCTP and UDP are provided in Sections 9.2 and 9.3,
   respectively.  Template management at Collecting Processes is covered
   in Section 8.

   The Collecting Process MUST listen for association requests /
   connections to start new Transport Sessions from the Exporting
   Process.

   The Collecting Process MUST note the Information Element identifier
   of any Information Element that it does not understand and MAY
   discard that Information Element from received Data Records.

   The Collecting Process MUST accept padding in Data Records and
   Template Records.  The padding size is the Set Length minus the size
   of the Set Header (4 octets for the Set ID and the Set Length),
   modulo the minimum Record size deduced from the Template Record.

   The IPFIX protocol has a Sequence Number field in the Export header
   that increases with the number of IPFIX Data Records in the IPFIX
   Message.  A Collector can detect out-of-sequence, dropped, or
   duplicate IPFIX Messages by tracking the Sequence Number.  A
   Collector SHOULD provide a logging mechanism for tracking out-of-
   sequence IPFIX Messages.  Such out-of-sequence IPFIX Messages may be
   due to Exporter resource exhaustion where it cannot transmit messages
   at their creation rate, an Exporting Process reset, congestion on the
   network link between the Exporter and Collector, Collector resource
   exhaustion where it cannot process the IPFIX Messages at their
   arrival rate, out-of-order packet reception, duplicate packet
   reception, or an attacker injecting false messages.

Claise, et al.               Standards Track                   [Page 45]

RFC 7011              IPFIX Protocol Specification        September 2013

9.1.  Collecting Process Handling of Malformed IPFIX Messages

   If the Collecting Process receives a malformed IPFIX Message, it MUST
   discard the IPFIX Message and SHOULD log the error.  A malformed
   IPFIX Message is one that cannot be interpreted due to nonsensical
   length values (e.g., a variable-length Information Element longer
   than its enclosing Set, a Set longer than its enclosing IPFIX
   Message, or an IPFIX Message shorter than an IPFIX Message Header) or
   a reserved Version value (which may indicate that a future version of
   IPFIX is being used for export but in practice occurs most often when
   non-IPFIX data is sent to an IPFIX Collecting Process).  Note that
   non-zero Set padding does not constitute a malformed IPFIX Message.

   As the most likely cause of malformed IPFIX Messages is a poorly
   implemented Exporting Process, or the sending of non-IPFIX data to an
   IPFIX Collecting Process, human intervention is likely necessary to
   correct the issue.  In the meantime, the Collecting Process MAY
   attempt to rectify the situation any way it sees fit, including:

   - terminating the TCP connection or SCTP connection

   - using the receiver window to reduce network load from the
     malfunctioning Exporting Process

   - buffering and saving malformed IPFIX Message(s) to assist in
     diagnosis

   - attempting to resynchronize the stream, e.g., as described in
     Section 10.3 of [RFC5655]

   Resynchronization should only be attempted if the Collecting Process
   has reason to believe that the error is transient.  On the other
   hand, the Collecting Process SHOULD stop processing IPFIX Messages
   from clearly malfunctioning Exporting Processes (e.g., those from
   which the last few IPFIX Messages have been malformed).

9.2.  Additional Considerations for SCTP Collecting Processes

   As an Exporting Process may request and support more than one stream
   per SCTP association, the Collecting Process MUST support the opening
   of multiple SCTP Streams.

9.3.  Additional Considerations for UDP Collecting Processes

   A Transport Session for IPFIX Messages transported over UDP is
   defined from the point of view of the Exporting Process and roughly
   corresponds to the time during which a given Exporting Process sends
   IPFIX Messages over UDP to a given Collecting Process.  Since this is

Claise, et al.               Standards Track                   [Page 46]

RFC 7011              IPFIX Protocol Specification        September 2013

   difficult to detect at the Collecting Process, the Collecting Process
   MAY discard all Transport Session state after no IPFIX Messages are
   received from a given Exporting Process within a given Transport
   Session during a configurable idle timeout.

   The Collecting Process SHOULD accept Data Records without the
   associated Template Record (or other definitions such as Common
   Properties) required to decode the Data Record.  If the Template
   Records or other definitions have not been received at the time Data
   Records are received, the Collecting Process MAY store the Data
   Records for a short period of time and decode them after the Template
   Records or other definitions are received, comparing Export Times of
   IPFIX Messages containing the Template Records with those containing
   the Data Records as discussed in Section 8.2.  Note that this
   mechanism may lead to incorrectly interpreted records in the presence
   of Template ID reuse or other identifiers with limited lifetimes.

   10.  Transport Protocol

   The IPFIX Protocol Specification has been designed to be transport
   protocol independent.  Note that the Exporter can export to multiple
   Collecting Processes using independent transport protocols.

   The IPFIX Message Header 16-bit Length field limits the length of an
   IPFIX Message to 65535 octets, including the header.  A Collecting
   Process MUST be able to handle IPFIX Message lengths of up to
   65535 octets.

   While an Exporting Process or Collecting Process may support multiple
   transport protocols, Transport Sessions are bound to a transport
   protocol.  Transport Session state MUST NOT be migrated by an
   Exporting Process or Collecting Process among Transport Sessions
   using different transport protocols between the same Exporting
   Process and Collecting Process pair.  In other words, an Exporting
   Process supporting multiple transport protocols is conceptually
   multiple Exporting Processes, one per supported transport protocol.
   Likewise, a Collecting Process supporting multiple transport
   protocols is conceptually multiple Collecting Processes, one per
   supported transport protocol.

10.1.  Transport Compliance and Transport Usage

   SCTP [RFC4960] using the Partially Reliable SCTP (PR-SCTP) extension
   as specified in [RFC3758] MUST be implemented by all compliant
   implementations.  UDP [UDP] MAY also be implemented by compliant
   implementations.  TCP [TCP] MAY also be implemented by compliant
   implementations.

Claise, et al.               Standards Track                   [Page 47]

RFC 7011              IPFIX Protocol Specification        September 2013

   SCTP should be used in deployments where Exporters and Collectors are
   communicating over links that are susceptible to congestion.  SCTP is
   capable of providing any required degree of reliability when used
   with the PR-SCTP extension.

   TCP may be used in deployments where Exporters and Collectors
   communicate over links that are susceptible to congestion, but SCTP
   is preferred, due to its ability to limit back pressure on Exporters
   and its message-versus-stream orientation.

   UDP may be used, although it is not a congestion-aware protocol.
   However, in this case the IPFIX traffic between the Exporter and
   Collector must be separately contained or provisioned to minimize the
   risk of congestion-related loss.

   By default, the Collecting Process listens for connections on SCTP,
   TCP, and/or UDP port 4739.  By default, the Collecting Process
   listens for secure connections on SCTP, TCP, and/or UDP port 4740
   (refer to the Security Considerations section).  By default, the
   Exporting Process attempts to connect to one of these ports.  It MUST
   be possible to configure both the Exporting and Collecting Processes
   to use different ports than the default.

10.2.  SCTP

   This section describes how IPFIX is transported over SCTP [RFC4960]
   using the PR-SCTP [RFC3758] extension.

10.2.1.  Congestion Avoidance

   SCTP provides the required level of congestion avoidance by design.

   SCTP detects congestion in the end-to-end path between the IPFIX
   Exporting Process and the IPFIX Collecting Process, and limits the
   transfer rate accordingly.  When an IPFIX Exporting Process has
   records to export but detects that transmission by SCTP is
   temporarily impossible, it can either wait until sending is possible
   again or decide to drop the record.  In the latter case, the dropped
   export data SHOULD be accounted for, so that the amount of dropped
   export data can be reported using the mechanism described in
   Section 4.3.

Claise, et al.               Standards Track                   [Page 48]

RFC 7011              IPFIX Protocol Specification        September 2013

10.2.2.  Reliability

   The SCTP transport protocol is by default reliable but has the
   capability to deliver messages with partial reliability [RFC3758].

   Using reliable SCTP messages for IPFIX export is not in itself a
   guarantee that all Data Records will be delivered.  If there is
   congestion on the link from the Exporting Process to the Collecting
   Process, or if a significant number of retransmissions are required,
   the send queues on the Exporting Process may fill up; the Exporting
   Process MAY either suspend, export, or discard the IPFIX Messages.
   If Data Records are discarded, the IPFIX Sequence Numbers used for
   export MUST reflect the loss of data.

10.2.3.  MTU

   SCTP provides the required IPFIX Message fragmentation service based
   on Path MTU (PMTU) discovery.

10.2.4.  Association Establishment and Shutdown

   The IPFIX Exporting Process initiates an SCTP association with the
   IPFIX Collecting Process.  The Exporting Process MAY establish more
   than one association (connection "bundle" in SCTP terminology) to the
   Collecting Process.

   An Exporting Process MAY support more than one active association to
   different Collecting Processes (including the case of different
   Collecting Processes on the same host).

   When an Exporting Process is shut down, it SHOULD shut down the SCTP
   association.

   When a Collecting Process no longer wants to receive IPFIX Messages,
   it SHOULD shut down its end of the association.  The Collecting
   Process SHOULD continue to receive and process IPFIX Messages until
   the Exporting Process has closed its end of the association.

   When a Collecting Process detects that the SCTP association has been
   abnormally terminated, it MUST continue to listen for a new
   association establishment.

   When an Exporting Process detects that the SCTP association to the
   Collecting Process is abnormally terminated, it SHOULD try to
   re-establish the association.

   Association timeouts SHOULD be configurable.

Claise, et al.               Standards Track                   [Page 49]

RFC 7011              IPFIX Protocol Specification        September 2013

10.2.5.  Failover

   If the Collecting Process does not acknowledge an attempt by the
   Exporting Process to establish an association, SCTP will
   automatically retry association establishment using exponential
   backoff.  The Exporter MAY log an alarm if the underlying SCTP
   association establishment times out; this timeout should be
   configurable on the Exporter.

   The Exporting Process MAY open a backup SCTP association to a
   Collecting Process in advance, if it supports Collecting Process
   failover.

10.2.6.  Streams

   An Exporting Process MAY request more than one SCTP Stream per
   association.  Each of these streams may be used for the transmission
   of IPFIX Messages containing Data Sets, Template Sets, and/or Options
   Template Sets.

   Depending on the requirements of the application, the Exporting
   Process may send Data Sets with full or partial reliability, using
   ordered or out-of-order delivery, over any SCTP Stream established
   during SCTP association setup.

   An IPFIX Exporting Process MAY use any PR-SCTP service definition as
   per Section 4 of the PR-SCTP specification [RFC3758] when using
   partial reliability to transmit IPFIX Messages containing only
   Data Sets.

   However, Exporting Processes SHOULD mark such IPFIX Messages for
   retransmission for as long as resource or other constraints allow.

10.3.  UDP

   This section describes how IPFIX is transported over UDP [UDP].

10.3.1.  Congestion Avoidance

   UDP has no integral congestion-avoidance mechanism.  Its use over
   congestion-sensitive network paths is therefore not recommended.  UDP
   MAY be used in deployments where Exporters and Collectors always
   communicate over dedicated links that are not susceptible to
   congestion, i.e., links that are over-provisioned compared to the
   maximum export rate from the Exporters.

Claise, et al.               Standards Track                   [Page 50]

RFC 7011              IPFIX Protocol Specification        September 2013

10.3.2.  Reliability

   UDP is not a reliable transport protocol and cannot guarantee
   delivery of messages.  IPFIX Messages sent from the Exporting Process
   to the Collecting Process using UDP may therefore be lost.  UDP MUST
   NOT be used unless the application can tolerate some loss of IPFIX
   Messages.

   The Collecting Process SHOULD deduce the loss and reordering of IPFIX
   Data Records by looking at the discontinuities in the IPFIX Sequence
   Number.  In the case of UDP, the IPFIX Sequence Number contains the
   total number of IPFIX Data Records sent for the Transport Session
   prior to the receipt of this IPFIX Message, modulo 2^32.  A Collector
   SHOULD detect out-of-sequence, dropped, or duplicate IPFIX Messages
   by tracking the Sequence Number.

   Exporting Processes exporting IPFIX Messages via UDP MUST include a
   valid UDP checksum [UDP] in UDP datagrams including IPFIX Messages.

10.3.3.  MTU

   The maximum size of exported messages MUST be configured such that
   the total packet size does not exceed the PMTU.  If the PMTU is
   unknown, a maximum packet size of 512 octets SHOULD be used.

10.3.4.  Session Establishment and Shutdown

   As UDP is a connectionless protocol, there is no real session
   establishment or shutdown for IPFIX over UDP.  An Exporting Process
   starts sending IPFIX Messages to a Collecting Process at one point in
   time and stops sending them at another point in time.  This can lead
   to some complications in Template management, as outlined in
   Section 8.4 above.

10.3.5.  Failover and Session Duplication

   Because UDP is not a connection-oriented protocol, the Exporting
   Process is unable to determine from the transport protocol that the
   Collecting Process is no longer able to receive the IPFIX Messages.
   Therefore, it cannot invoke a failover mechanism.  However, the
   Exporting Process MAY duplicate the IPFIX Message to several
   Collecting Processes.

Claise, et al.               Standards Track                   [Page 51]

RFC 7011              IPFIX Protocol Specification        September 2013

10.4.  TCP

   This section describes how IPFIX is transported over TCP [TCP].

10.4.1.  Congestion Avoidance

   TCP controls the rate at which data can be sent from the Exporting
   Process to the Collecting Process, using a mechanism that takes into
   account both congestion in the network and the capabilities of the
   receiver.

   Therefore, an IPFIX Exporting Process may not be able to send IPFIX
   Messages at the rate that the Metering Process generates them, either
   because of congestion in the network or because the Collecting
   Process cannot handle IPFIX Messages fast enough.  As long as
   congestion is transient, the Exporting Process can buffer IPFIX
   Messages for transmission.  But such buffering is necessarily
   limited, both because of resource limitations and because of
   timeliness requirements, so ongoing and/or severe congestion may lead
   to a situation where the Exporting Process is blocked.

   When an Exporting Process has Data Records to export but the
   transmission buffer is full, and it wants to avoid blocking, it can
   decide to drop some Data Records.  The dropped Data Records MUST be
   accounted for, so that the number of lost records can later be
   reported as described in Section 4.3.

10.4.2.  Reliability

   TCP ensures reliable delivery of data from the Exporting Process to
   the Collecting Process.

10.4.3.  MTU

   As TCP offers a stream service instead of a datagram or sequential
   packet service, IPFIX Messages transported over TCP are instead
   separated using the Length field in the IPFIX Message Header.  The
   Exporting Process can choose any valid length for exported IPFIX
   Messages, as TCP handles segmentation.

   Exporting Processes may choose IPFIX Message lengths lower than the
   maximum in order to ensure timely export of Data Records.

Claise, et al.               Standards Track                   [Page 52]

RFC 7011              IPFIX Protocol Specification        September 2013

10.4.4.  Connection Establishment and Shutdown

   The IPFIX Exporting Process initiates a TCP connection to the
   Collecting Process.  An Exporting Process MAY support more than one
   active connection to different Collecting Processes (including the
   case of different Collecting Processes on the same host).  An
   Exporting Process MAY support more than one active connection to the
   same Collecting Process to avoid head-of-line blocking across
   Observation Domains.

   The Exporter MAY log an alarm if the underlying TCP connection
   establishment times out; this timeout should be configurable on the
   Exporter.

   When an Exporting Process is shut down, it SHOULD shut down the TCP
   connection.

   When a Collecting Process no longer wants to receive IPFIX Messages,
   it SHOULD close its end of the connection.  The Collecting Process
   SHOULD continue to read IPFIX Messages until the Exporting Process
   has closed its end.

   When a Collecting Process detects that the TCP connection to the
   Exporting Process has terminated abnormally, it MUST continue to
   listen for a new connection.

   When an Exporting Process detects that the TCP connection to the
   Collecting Process has terminated abnormally, it SHOULD try to
   re-establish the connection.  Connection timeouts and retry schedules
   SHOULD be configurable.  In the default configuration, an Exporting
   Process MUST NOT attempt to establish a connection more frequently
   than once per minute.

10.4.5.  Failover

   If the Collecting Process does not acknowledge an attempt by the
   Exporting Process to establish a connection, TCP will automatically
   retry connection establishment using exponential backoff.  The
   Exporter MAY log an alarm if the underlying TCP connection
   establishment times out; this timeout should be configurable on the
   Exporter.

   The Exporting Process MAY open a backup TCP connection to a
   Collecting Process in advance, if it supports Collecting Process
   failover.

Claise, et al.               Standards Track                   [Page 53]

RFC 7011              IPFIX Protocol Specification        September 2013

11.  Security Considerations

   The security considerations for the IPFIX protocol have been derived
   from an analysis of potential security threats, as discussed in the
   Security Considerations section of the IPFIX requirements document
   [RFC3917].  The requirements for IPFIX security are as follows:

   1. IPFIX must provide a mechanism to ensure the confidentiality of
      IPFIX data transferred from an Exporting Process to a Collecting
      Process, in order to prevent disclosure of Flow Records
      transported via IPFIX.

   2. IPFIX must provide a mechanism to ensure the integrity of IPFIX
      data transferred from an Exporting Process to a Collecting
      Process, in order to prevent the injection of incorrect data or
      control information (e.g., Templates), or the duplication of
      Messages, in an IPFIX Message stream.

   3. IPFIX must provide a mechanism to authenticate IPFIX Collecting
      and Exporting Processes, to prevent the collection of data from an
      unauthorized Exporting Process or the export of data to an
      unauthorized Collecting Process.

   Because IPFIX can be used to collect information for network
   forensics and billing purposes, attacks designed to confuse, disable,
   or take information from an IPFIX collection system may be seen as a
   prime objective during a sophisticated network attack.

   An attacker in a position to inject false messages into an IPFIX
   Message stream can affect either the application using IPFIX (by
   falsifying data) or the IPFIX Collecting Process itself (by modifying
   or revoking Templates, or changing options); for this reason, IPFIX
   Message integrity is important.

   The IPFIX Messages themselves may also contain information of value
   to an attacker, including information about the configuration of the
   network as well as end-user traffic and payload data, so care must be
   taken to confine their visibility to authorized users.  When an
   Information Element containing end-user payload information is
   exported, it SHOULD be transmitted to the Collecting Process using a
   means that secures its contents against eavesdropping.  Suitable
   mechanisms include the use of either a direct point-to-point
   connection assumed to be unavailable to attackers, or the use of an
   encryption mechanism.  It is the responsibility of the Collecting
   Process to provide a satisfactory degree of security for this
   collected data, including, if necessary, encryption and/or
   anonymization of any reported data; see Section 11.8.

*/


text:
import * as Types from '../types';
import * as gm from 'graphql-modules';
export namespace UsersModule {
  interface DefinedFields {
    User: 'id' | 'firstName' | 'lastName';
    Query: 'users' | 'userById';
  }

  export type User = Pick<Types.User, DefinedFields['User']>;
  export type Query = Pick<Types.Query, DefinedFields['Query']>;

  export type UserResolvers = Pick<Types.UserResolvers, DefinedFields['User'] | '__isTypeOf'>;
  export type QueryResolvers = Pick<Types.QueryResolvers, DefinedFields['Query']>;

  export interface Resolvers {
    User?: UserResolvers;
    Query?: QueryResolvers;
  }

  export interface MiddlewareMap {
    '*'?: {
      '*'?: gm.Middleware[];
    };
    User?: {
      '*'?: gm.Middleware[];
      id?: gm.Middleware[];
      firstName?: gm.Middleware[];
      lastName?: gm.Middleware[];
    };
    Query?: {
      '*'?: gm.Middleware[];
      users?: gm.Middleware[];
      userById?: gm.Middleware[];
    };
  }
}


text:
package fr.flegac.experiments.engine.economy.model.production;

public class Land extends EconomicEntity {

}


text:
<?php

namespace yiiunit\extensions\elasticsearch\data\ar;

use yii\elasticsearch\Command;
use yiiunit\extensions\elasticsearch\ActiveRecordTest;

/**
 * Class Customer
 *
 * @property integer $id
 * @property string $name
 * @property string $email
 * @property string $address
 * @property integer $status
 * @property bool $is_active
 */
class Customer extends ActiveRecord
{
    const STATUS_ACTIVE = 1;
    const STATUS_INACTIVE = 2;

    public function attributes()
    {
        return ['name', 'email', 'address', 'status', 'is_active'];
    }

    public function getOrders()
    {
        return $this->hasMany(Order::className(), ['customer_id' => '_id'])->orderBy('created_at');
    }

    public function getExpensiveOrders()
    {
        return $this->hasMany(Order::className(), ['customer_id' => '_id'])
            ->where([ 'gte', 'total', 50 ])
            ->orderBy('_id');
    }

    public function getOrdersWithItems()
    {
        return $this->hasMany(Order::className(), ['customer_id' => '_id'])->with('orderItems');
    }

    public function afterSave($insert, $changedAttributes)
    {
        ActiveRecordTest::$afterSaveInsert = $insert;
        ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord;
        parent::afterSave($insert, $changedAttributes);
    }

    /**
     * sets up the index for this record
     * @param Command $command
     * @param boolean $statusIsBoolean
     */
    public static function setUpMapping($command)
    {
        $command->setMapping(static::index(), static::type(), [
            "properties" => [
                "name" => ["type" => "keyword",  "store" => true],
                "email" => ["type" => "keyword", "store" => true],
                "address" => ["type" => "text"],
                "status" => ["type" => "integer", "store" => true],
                "is_active" => ["type" => "boolean", "store" => true],
            ]
        ]);

    }

    /**
     * @inheritdoc
     * @return CustomerQuery
     */
    public static function find()
    {
        return new CustomerQuery(get_called_class());
    }
}


text:
import Roundable from '../'
import {
  mount,
  MountOptions,
  Wrapper,
} from '@vue/test-utils'

describe('rippleable.ts', () => {
  const Mock = Roundable.extend({
    render (h) {
      return h('div', {
        class: this.roundableClasses,
      })
    },
  })

  type Instance = InstanceType<typeof Mock>
  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>
  beforeEach(() => {
    mountFunction = (options?: MountOptions<Instance>) => {
      return mount(Mock, options)
    }
  })

  it.each([
    [undefined, {}],
    [{ tile: true }, { 'rounded-0': true }],
    [{ rounded: true, tile: true }, { 'rounded-0': true }],
    [{ rounded: '0' }, { 'rounded-0': true }],
    [{ rounded: true }, { rounded: true }],
    [{ rounded: false }, {}],
    [{ rounded: 'tr-xl br-lg' }, { 'rounded-tr-xl rounded-br-lg': true }],
  ])('should return correct rounded classes', (propsData, expected: any) => {
    const wrapper = mountFunction({ propsData })

    expect(wrapper.vm.roundedClasses).toEqual(expected)
  })
})


text: package firecracker


text:
#ifndef CAPU_UNIXBASED_STRINGUTILS_H
#define CAPU_UNIXBASED_STRINGUTILS_H

#include "capu/Config.h"
#include <string.h>
#include <stdarg.h>

namespace capu
{
    namespace posix
    {
        class StringUtils
        {
        public:
            static void Strncpy(char* dst, const uint_t dstSize, const char* src);
            static uint_t Strnlen( const char* str, uint_t maxlen);
            static int32_t Sprintf(char* buffer, const uint_t bufferSize, const char* format, ...);
            static int32_t Vsprintf(char* buffer, const uint_t bufferSize, const char* format, va_list values);
            static int32_t Vscprintf(const char* format, va_list values);
            static uint_t Strlen(const char* str);
            static int_t Strcmp(const char* str1, const char* str2);
            static int_t LastIndexOf(const char* str, const char ch);
            static int_t IndexOf(const char* str, const char ch, const uint_t offset = 0);
            static int_t IndexOf(const char* str, const char* str2, const uint_t offset = 0);
            static bool StartsWith(const char* str, const char* prefix);
        };

        inline
        void
        StringUtils::Strncpy(char* dst, uint_t dstSize, const char* src)
        {
            // reproduce behaviour of strncpy_s
            strncpy(dst, src, dstSize - 1);
            dst[dstSize - 1] = 0;
        }

        inline
        uint_t
        StringUtils::Strnlen(const char* str, uint_t maxlen)
        {
            if (str == 0)
            {
                return 0;
            }
            return strnlen(str, maxlen);
        }

        inline
        uint_t
        StringUtils::Strlen(const char* str)
        {
            if (str == 0)
            {
                return 0;
            }
            return strlen(str);
        }

        inline
        int_t
        StringUtils::Strcmp(const char* str1, const char* str2)
        {
            return strcmp(str1, str2);
        }

        inline
        int32_t
        StringUtils::Vsprintf(char* buffer, uint_t bufferSize, const char* format, va_list values)
        {
            return vsnprintf(buffer, bufferSize, format, values);
        }

        inline
        int32_t
        StringUtils::Vscprintf(const char* format, va_list values)
        {
            char c;
            return vsnprintf(&c, 1, format, values);
        }

        inline
        int32_t
        StringUtils::Sprintf(char* buffer, uint_t bufferSize, const char* format, ...)
        {
            va_list argptr;
            va_start(argptr, format);
            int32_t result = StringUtils::Vsprintf(buffer, bufferSize, format, argptr);
            va_end(argptr);
            return result;
        }

        inline
        int_t
        StringUtils::LastIndexOf(const char* str, const char ch)
        {
            if (!str)
            {
                return -1;
            }
            const char* pos = strrchr(str, ch);
            return pos ? pos - str : -1;
        }

        inline
        int_t
        StringUtils::IndexOf(const char* str, const char ch, const uint_t offset)
        {
            if (!str)
            {
                return -1;
            }
            const char* pos = strchr(str +  offset, ch);
            return pos ? pos - str : -1;
        }

        inline
        bool
        StringUtils::StartsWith(const char* str, const char* prefix)
        {
            if (!prefix || !str)
            {
                return false;
            }
            return strncmp(str, prefix, strlen(prefix)) == 0;
        }

        inline
        int_t
        StringUtils::IndexOf(const char* str, const char* str2, const uint_t offset)
        {
            const char* start = strstr(str + offset, str2);
            return start ? (start - str) : -1;
        }
    }
}
#endif // CAPU_UNIXBASED_STRINGUTILS_H


text:
<resources>
    <string name="app_name">DelayedRunner</string>
    <string name="action_settings">Settings</string>
</resources>


text:
using System.Linq;
using NUnit.Framework;
using Potato.Database.Shared;
using Potato.Database.Shared.Serializers.NoSql;

namespace Potato.Database.Shared.Test.MongoDb {
    [TestFixture]
    public class TestSerializerMongoDbFindExplicit : TestSerializerFind {

        [Test]
        public override void TestSelectAllFromPlayer() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
        }

        [Test]
        public override void TestSelectDistinctAllFromPlayer() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectDistinctAllFromPlayerExplicit).Compile();

            Assert.AreEqual(@"distinct", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerWhereNameEqualsPhogue() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerWhereNameEqualsPhogueExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""Name"":""Phogue""}]", serialized.Conditions.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerWhereKdrGreaterThanEqualTo31D() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerWhereKdrGreaterThanEqualTo31DExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""Kdr"":{""$gte"":""3.1""}}]", serialized.Conditions.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerWhereKdrLessThanEqualTo31D() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerWhereKdrLessThanEqualTo31DExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""Kdr"":{""$lte"":""3.1""}}]", serialized.Conditions.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerWherePlayerNameEqualsPhogue() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerWherePlayerNameEqualsPhogueExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""Name"":""Phogue""}]", serialized.Conditions.First());
        }

        [Test]
        public override void TestSelectScoreFromPlayerWhereNameEqualsPhogue() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectScoreFromPlayerWhereNameEqualsPhogueExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""Name"":""Phogue""}]", serialized.Conditions.First());
            Assert.AreEqual("Score", serialized.Fields.First());
        }

        [Test]
        public override void TestSelectScoreRankFromPlayerWhereNameEqualsPhogue() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectScoreRankFromPlayerWhereNameEqualsPhogueExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""Name"":""Phogue""}]", serialized.Conditions.First());
            Assert.AreEqual("Score", serialized.Fields.First());
            Assert.AreEqual("Rank", serialized.Fields.Last());
        }

        [Test]
        public override void TestSelectAllFromPlayerWhereNameEqualsPhogueAndScoreEqualsTen() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerWhereNameEqualsPhogueAndScoreEqualsTenExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""Name"":""Phogue"",""Score"":""10""}]", serialized.Conditions.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerWhereNameEqualsPhogueOrZaeed() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerWhereNameEqualsPhogueOrZaeedExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""$or"":[{""Name"":""Phogue""},{""Name"":""Zaeed""}]}]", serialized.Conditions.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerWhereNameEqualsPhogueOrZaeedAndScoreAbove10AndBelow20() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerWhereNameEqualsPhogueOrZaeedAndScoreAbove10AndBelow20Explicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""$or"":[{""Name"":""Phogue""},{""Name"":""Zaeed""}],""Score"":{""$gt"":""10"",""$lt"":""20""}}]", serialized.Conditions.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerWhereNameEqualsPhogueAndScoreAbove50OrNameEqualsZaeedAndScoreBelow50() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerWhereNameEqualsPhogueAndScoreAbove50OrNameEqualsZaeedAndScoreBelow50Explicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""$or"":[{""Name"":""Phogue"",""Score"":{""$gt"":""50""}},{""Name"":""Zaeed"",""Score"":{""$lt"":""50""}}]}]", serialized.Conditions.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerSortByScore() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerSortByScoreExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""Score"":1}]", serialized.Sortings.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerSortByNameThenScoreDescending() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerSortByNameThenScoreDescendingExplicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(@"[{""Name"":1,""Score"":-1}]", serialized.Sortings.First());
        }

        [Test]
        public override void TestSelectAllFromPlayerLimit1() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerLimit1Explicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(1, serialized.Limit);
        }

        [Test]
        public override void TestSelectAllFromPlayerLimit1Skip2() {
            ISerializer serializer = new SerializerMongoDb();
            ICompiledQuery serialized = serializer.Parse(this.TestSelectAllFromPlayerLimit1Skip2Explicit).Compile();

            Assert.AreEqual(@"find", serialized.Methods.First());
            Assert.AreEqual(@"Player", serialized.Collections.First());
            Assert.AreEqual(1, serialized.Limit);
            Assert.AreEqual(2, serialized.Skip);
        }
    }
}


text:
function [interval_ii,idx_current_pz,prev_upper_bound] = ds07f_negative_pz(this,interval_ii,idx_current_pz,prev_upper_bound)
    im_pz_sorted =          this.im_pz_sorted;
    interval_list =         this.interval_list;
    pole_zero_combinations =this.im_pz_combinations;
    secant_pole =           this.secant_pole;
    secant_zero =           this.secant_zero;
    halfsecant_pole =       this.halfsecant_pole;
    halfsecant_zero =       this.halfsecant_zero;
    arc_lengths =           this.arc_lengths;
    radii =                 this.radii;

        % treat negative p/z
    pz = [im_pz_sorted.value];
    negative_pz_remain = sum(pz<0) - any([[im_pz_sorted.neg_on_origin],[im_pz_sorted.neg_overlapping]]);

    while(negative_pz_remain)
        % there are negative poles/zeros left to treat

        interval_list(interval_ii).type = [repmat('detour_pole', im_pz_sorted(idx_current_pz).pole), ...
                                           repmat('detour_zero', im_pz_sorted(idx_current_pz).zero)];
        interval_list(interval_ii).q(1) = prev_upper_bound;

        interval_length = arc_lengths.detour_pole * im_pz_sorted(idx_current_pz).pole + ...
                          arc_lengths.detour_zero * im_pz_sorted(idx_current_pz).zero;
        interval_list(interval_ii).q_len = interval_length;

        interval_list(interval_ii).q(2) = interval_list(interval_ii).q(1) + interval_length;
        prev_upper_bound = interval_list(interval_ii).q(2);

        switch im_pz_sorted(idx_current_pz).type
            case 'p'
                interval_list(interval_ii).input_fct_handle = @(q) circ_detour(map(q,interval_list(interval_ii).q(1),interval_list(interval_ii).q(2),0,arc_lengths.detour_pole), ...
                                                                               radii.detour_pole, ...
                                                                               secant_pole, ...
                                                                               im_pz_sorted(idx_current_pz).value);
            case 'z'
                interval_list(interval_ii).input_fct_handle = @(q) circ_detour(map(q,interval_list(interval_ii).q(1),interval_list(interval_ii).q(2),0,arc_lengths.detour_zero), ...
                                                                               radii.detour_zero, ...
                                                                               secant_zero, ...
                                                                               im_pz_sorted(idx_current_pz).value);
        end

        dbg_out('interval\t[%.3f\t%.3f],\tlength = %.3f,\tdetour_neg\n',interval_list(interval_ii).q(1),interval_list(interval_ii).q(2),interval_length);
        interval_ii = interval_ii + 1;

        if negative_pz_remain > 1
            interval_list(interval_ii).type = 'axis';
            interval_list(interval_ii).q(1) = prev_upper_bound;

            interval_length = pole_zero_combinations(idx_current_pz).distance + ...
                              -halfsecant_pole * ( im_pz_sorted(idx_current_pz).pole + ...
                                                   im_pz_sorted(idx_current_pz+1).pole) + ...
                              -halfsecant_zero * ( im_pz_sorted(idx_current_pz).zero + ...
                                                   im_pz_sorted(idx_current_pz+1).zero);
            interval_list(interval_ii).q_len = interval_length;

            interval_list(interval_ii).q(2) = interval_list(interval_ii).q(1) + interval_length;
            prev_upper_bound = interval_list(interval_ii).q(2);

            za = im_pz_sorted(idx_current_pz).value + ...
                 halfsecant_pole * im_pz_sorted(idx_current_pz).pole + ...
                 halfsecant_zero * im_pz_sorted(idx_current_pz).zero;
            zb = im_pz_sorted(idx_current_pz+1).value + ...
                 -halfsecant_pole * im_pz_sorted(idx_current_pz+1).pole + ...
                 -halfsecant_zero * im_pz_sorted(idx_current_pz+1).zero;
            interval_list(interval_ii).input_fct_handle = @(q) im_axis_line(q,interval_list(interval_ii).q(1),interval_list(interval_ii).q(2),za,zb);

            dbg_out('interval\t[%.3f\t%.3f],\tlength = %.3f,\tlinear_neg\n',interval_list(interval_ii).q(1),interval_list(interval_ii).q(2),interval_length);
            idx_current_pz = idx_current_pz + 1;
            interval_ii = interval_ii + 1;
            negative_pz_remain = negative_pz_remain - 1;
        else
            break;
        end
    end

    this.interval_list = interval_list;
end


text:
'use strict';
var WPTAggregator = require('../wptAggregator');

module.exports = new WPTAggregator('TTFBWPT',
  'TTFB',
  'Time To First Byte (fetched using WebPageTest)',
  'timing', 'milliseconds', 0,
  'TTFB');


text:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:state_pressed="true" android:drawable="@drawable/scringo_activation_ribbon_right_pressed" />
	<item android:drawable="@drawable/scringo_activation_ribbon_right_normal" /> <!-- default -->
</selector>


text:
import unittest

from test_helper import test_is_not_empty, get_file_output

class TestCase(unittest.TestCase):
    def test_not_empty(self):
        self.assertTrue(test_is_not_empty(), 'The output is empty')

    def test_output(self):
        output = get_file_output(path='task.py')

        answers = [
            "WordsAlphabet(alphabet:'a', fruit='apple', country='australia')",
            "WordsAlphabet(alphabet:'b', fruit='banana', country='brazil')",
            "WordsAlphabet(alphabet:'c', fruit='cherry', country='canada')"
        ]

        for ans in answers:
            self.assertIn(ans, output, "Incorrect output. Generate WordsAlphabet objects after CoGroupByKey.")


text:
package aws

import (
	"io/ioutil"
	"net/http"
)

// MetadataKey is the identifier for a metadata entry.
type MetadataKey string

const (
	// MetadataAmiID - AMI ID
	MetadataAmiID = MetadataKey("http://169.254.169.254/latest/meta-data/ami-id")

	// MetadataInstanceID - Instance ID
	MetadataInstanceID = MetadataKey("http://169.254.169.254/latest/meta-data/instance-id")

	// MetadataInstanceType - Instance type
	MetadataInstanceType = MetadataKey("http://169.254.169.254/latest/meta-data/instance-type")

	// MetadataHostname - Host name
	MetadataHostname = MetadataKey("http://169.254.169.254/latest/meta-data/hostname")

	// MetadataLocalIPv4 - Local IPv4 address
	MetadataLocalIPv4 = MetadataKey("http://169.254.169.254/latest/meta-data/local-ipv4")

	// MetadataPublicIPv4 - Public IPv4 address
	MetadataPublicIPv4 = MetadataKey("http://169.254.169.254/latest/meta-data/public-ipv4")

	// MetadataAvailabilityZone - Availability zone
	MetadataAvailabilityZone = MetadataKey("http://169.254.169.254/latest/meta-data/placement/availability-zone")
)

// GetMetadata returns the value of the metadata by key
func GetMetadata(key MetadataKey) (string, error) {
	resp, err := http.Get(string(key))
	if err != nil {
		return "", err
	}
	buff, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		return "", err
	}
	return string(buff), nil
}

// GetRegion returns the AWS region this instance is in.
func GetRegion() (string, error) {
	az, err := GetMetadata(MetadataAvailabilityZone)
	if err != nil {
		return "", err
	}
	return az[0 : len(az)-1], nil
}


text:
<?php
namespace oasis\names\specification\ubl\schema\xsd\CommonAggregateComponents_2;

/**
 * @xmlNamespace urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2
 * @xmlType LineReferenceType
 * @xmlName QuotationLineReference
 * @var oasis\names\specification\ubl\schema\xsd\CommonAggregateComponents_2\QuotationLineReference
 */
class QuotationLineReference
	extends LineReferenceType
	{

} // end class QuotationLineReference


text:
package core

import "math"

type Timer struct {
	cycleCount int64
	fuse       int64
	counters   *Counter
}

func NewTimer() *Timer {
	timer := &Timer{}
	timer.AddCounter(NewCounter(math.MaxInt64, nil))
	return timer
}

func (t *Timer) Tick(cycles int64) {
	for cycles >= t.fuse {
		cycles -= t.fuse
		t.cycleCount += t.fuse
		ctr := t.counters
		if ctr.fire() {
			t.counters = t.counters.next
			t.AddCounter(ctr)
		} else {
			ctr = ctr.next
			t.fuse = ctr.end - t.cycleCount
			t.counters = ctr
		}
	}
	t.fuse -= cycles
	t.cycleCount += cycles
}

func (t *Timer) GetCount() int64 {
	return t.cycleCount
}

func (t *Timer) AddCounter(ctr *Counter) {
	if ctr.len == 0 {
		panic("zero-length counter")
	}
	ctr.end = ctr.len + t.cycleCount
	ctr.next = nil
	t.insertCounter(ctr)
}

func (t *Timer) insertCounter(ctr *Counter) {
	var prev *Counter
	next := t.counters
	for ; next != nil; next = next.next {
		if ctr.end < next.end {
			break
		}
		prev = next
	}
	if prev == nil {
		ctr.next = t.counters
		t.counters = ctr
	} else {
		ctr.next = next
		prev.next = ctr
	}
	t.fuse = t.counters.end - t.cycleCount
}

type Counter struct {
	next *Counter
	end  int64
	len  int64
	fire func() bool
}

func NewCounter(ln int64, action func() bool) *Counter {
	return &Counter{len: ln, fire: action}
}


text:
<?php

namespace App\SubsectionBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Box4
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="App\SubsectionBundle\Entity\Box4Repository")
 */
class Box4
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
    * @ORM\OneToOne(targetEntity="App\PagePartsBundle\Entity\Title", cascade={"persist"})
    * @ORM\JoinColumn(nullable=true)
    */
    private $title;

    /**
    * @ORM\OneToOne(targetEntity="App\PagePartsBundle\Entity\Text", cascade={"persist"})
    * @ORM\JoinColumn(nullable=true)
    */
    private $text;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set title
     *
     * @param \App\PagePartsBundle\Entity\Title $title
     * @return Box4
     */
    public function setTitle(\App\PagePartsBundle\Entity\Title $title = null)
    {
        $this->title = $title;

        return $this;
    }

    /**
     * Get title
     *
     * @return \App\PagePartsBundle\Entity\Title
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * Set text
     *
     * @param \App\PagePartsBundle\Entity\Text $text
     * @return Box4
     */
    public function setText(\App\PagePartsBundle\Entity\Text $text = null)
    {
        $this->text = $text;

        return $this;
    }

    /**
     * Get text
     *
     * @return \App\PagePartsBundle\Entity\Text
     */
    public function getText()
    {
        return $this->text;
    }

    /**
     * Set link_text
     *
     * @param \App\PagePartsBundle\Entity\Short $linkText
     * @return Box4
     */
    public function setLinkText(\App\PagePartsBundle\Entity\Short $linkText = null)
    {
        $this->link_text = $linkText;

        return $this;
    }

    /**
     * Get link_text
     *
     * @return \App\PagePartsBundle\Entity\Short
     */
    public function getLinkText()
    {
        return $this->link_text;
    }

    /**
     * Set link
     *
     * @param \App\PagePartsBundle\Entity\Link $link
     * @return Box4
     */
    public function setLink(\App\PagePartsBundle\Entity\Link $link = null)
    {
        $this->link = $link;

        return $this;
    }

    /**
     * Get link
     *
     * @return \App\PagePartsBundle\Entity\Link
     */
    public function getLink()
    {
        return $this->link;
    }
}