text:
<resources>
    <string name="app_name">Banco Inteligente</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="button_cashdesk">Deposit</string>
    <string name="button_executive">Executive</string>
    <string name="button_procedures">Customer service</string>

    <string name="title_section1">Procedures</string>
    <string name="title_section2">FAQ</string>
    <string name="title_section3">Login</string>

    <string name="navigation_drawer_open">Open navigation drawer</string>
    <string name="navigation_drawer_close">Close navigation drawer</string>

    <string name="action_example">Example action</string>
    <string name="title_activity_cashdesk">Cash Desk</string>
    <string name="button_deposit_cash">Cash deposit</string>
    <string name="button_document_deposit">Document deposit</string>
    <string name="title_activity_deposits">Deposits</string>
    <string name="button_deposits">Deposits</string>
    <string name="button_checks">Checks and/or documents</string>
    <string name="button_billPayment">Bill payment</string>
    <string name="title_activity_bill_payment">Bill payment</string>
    <string name="button_registeredAccount">Registered account</string>
    <string name="button_newAccount">New account</string>
    <string name="button_emergencies">Emergencies</string>
    <string name="title_section4">Configuration</string>
    <string name="title_activity_customer_service">Customer Service</string>
    <string name="button_request_checkbook">Request checkbook</string>
    <string name="button_request_promissory">Promissory retreat</string>
    <string name="title_activity_deposit">Deposit</string>
    <string name="switch_myaccount_deposit">Deposit in my account</string>
    <string name="text_account_number">Account number</string>
    <string name="text_holder_name">Holder name</string>
    <string name="text_depositer_name">Depositer name</string>
    <string name="text_depositer_phone">Phone</string>
    <string name="deposit_cash">Cash</string>
    <string name="deposit_document">Document</string>
    <string name="button_save_deposit">Save</string>
    <string name="button_clear_deposit">Clear</string>
    <string name="radio_bancochile_check">Banco de Chile check</string>
    <string name="radio_bank_other">Other bank</string>
    <string name="radio_promissory_bancochile">Banco de Chile promissory</string>
    <string name="radio_bank_other_promissory">Other bank promissory</string>
    <string name="edit_document_amount">Document aumount</string>
    <string name="dialog_loading">Please wait</string>

</resources>

redpajama_set_name: RedPajamaGithub


text:
class GithubAuthorization

  CREDENTIALS = {
    client_id:     Rails.application.secrets.github_client_id,
    client_secret: Rails.application.secrets.github_client_secret
  }.map { |k, v| "#{k}=#{v}" }.join('&')

  HEADERS = {
    'User-Agent' => Rails.application.secrets.github_app_name
  }.freeze

  include ActiveRecord::HumanizedErrors
  include ActiveModel::Validations

  attr_reader :username

  validate :membership

  def initialize(username)
    @username = username
  end

  def membership
    request = Net::HTTP::Get.new(api_membership_url, HEADERS)

    response = Net::HTTP.start 'api.github.com', use_ssl: true do |http|
      http.request(request)
    end

    if response.class.in?([Net::HTTPNoContent, Net::HTTPFound])
      true
    else
      errors.add :base, 'No perteneces al grupo de organizadores'
      false
    end
  end

  private

  def api_membership_url
    "/orgs/webdevtalks/members/#{@username}?#{CREDENTIALS}"
  end

end


text:
#include "config.h"
#include "core/platform/graphics/Gradient.h"

#include "core/platform/graphics/Color.h"
#include "core/platform/graphics/FloatRect.h"
#include "core/platform/graphics/GraphicsContext.h"
#include "core/platform/graphics/skia/SkiaUtils.h"
#include "third_party/skia/include/core/SkColorShader.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "wtf/HashFunctions.h"
#include "wtf/StringHasher.h"

using WTF::pairIntHash;

namespace WebCore {

Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
    : m_radial(false)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(0)
    , m_r1(0)
    , m_aspectRatio(1)
    , m_stopsSorted(false)
    , m_spreadMethod(SpreadMethodPad)
    , m_cachedHash(0)
    , m_drawInPMColorSpace(false)
    , m_gradient(0)
{
}

Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio)
    : m_radial(true)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(r0)
    , m_r1(r1)
    , m_aspectRatio(aspectRatio)
    , m_stopsSorted(false)
    , m_spreadMethod(SpreadMethodPad)
    , m_cachedHash(0)
    , m_drawInPMColorSpace(false)
    , m_gradient(0)
{
}

Gradient::~Gradient()
{
    destroyShader();
}

void Gradient::destroyShader()
{
    SkSafeUnref(m_gradient);
    m_gradient = 0;
}

void Gradient::adjustParametersForTiledDrawing(IntSize& size, FloatRect& srcRect)
{
    if (m_radial)
        return;

    if (srcRect.isEmpty())
        return;

    if (m_p0.x() == m_p1.x()) {
        size.setWidth(1);
        srcRect.setWidth(1);
        srcRect.setX(0);
        return;
    }
    if (m_p0.y() != m_p1.y())
        return;

    size.setHeight(1);
    srcRect.setHeight(1);
    srcRect.setY(0);
}

void Gradient::addColorStop(float value, const Color& color)
{
    float r;
    float g;
    float b;
    float a;
    color.getRGBA(r, g, b, a);
    m_stops.append(ColorStop(value, r, g, b, a));

    m_stopsSorted = false;
    destroyShader();

    invalidateHash();
}

void Gradient::addColorStop(const Gradient::ColorStop& stop)
{
    m_stops.append(stop);

    m_stopsSorted = false;
    destroyShader();

    invalidateHash();
}

static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
{
    return a.stop < b.stop;
}

void Gradient::sortStopsIfNecessary()
{
    if (m_stopsSorted)
        return;

    m_stopsSorted = true;

    if (!m_stops.size())
        return;

    std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);

    invalidateHash();
}

bool Gradient::hasAlpha() const
{
    for (size_t i = 0; i < m_stops.size(); i++) {
        if (m_stops[i].alpha < 1)
            return true;
    }

    return false;
}

void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
{
    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
    ASSERT(m_gradient == 0);

    if (m_spreadMethod == spreadMethod)
        return;

    m_spreadMethod = spreadMethod;

    invalidateHash();
}

void Gradient::setDrawsInPMColorSpace(bool drawInPMColorSpace)
{
    if (drawInPMColorSpace == m_drawInPMColorSpace)
        return;

    m_drawInPMColorSpace = drawInPMColorSpace;

    if (m_gradient)
        destroyShader();

    invalidateHash();
}

void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
{
    if (m_gradientSpaceTransformation == gradientSpaceTransformation)
        return;

    m_gradientSpaceTransformation = gradientSpaceTransformation;
    if (m_gradient)
        m_gradient->setLocalMatrix(m_gradientSpaceTransformation);

    invalidateHash();
}

unsigned Gradient::hash() const
{
    if (m_cachedHash)
        return m_cachedHash;

    struct {
        AffineTransform gradientSpaceTransformation;
        FloatPoint p0;
        FloatPoint p1;
        float r0;
        float r1;
        float aspectRatio;
        GradientSpreadMethod spreadMethod;
        bool radial;
        bool drawInPMColorSpace;
    } parameters;

    // StringHasher requires that the memory it hashes be a multiple of two in size.
    COMPILE_ASSERT(!(sizeof(parameters) % 2), Gradient_parameters_size_should_be_multiple_of_two);
    COMPILE_ASSERT(!(sizeof(ColorStop) % 2), Color_stop_size_should_be_multiple_of_two);

    // Ensure that any padding in the struct is zero-filled, so it will not affect the hash value.
    memset(&parameters, 0, sizeof(parameters));

    parameters.gradientSpaceTransformation = m_gradientSpaceTransformation;
    parameters.p0 = m_p0;
    parameters.p1 = m_p1;
    parameters.r0 = m_r0;
    parameters.r1 = m_r1;
    parameters.aspectRatio = m_aspectRatio;
    parameters.spreadMethod = m_spreadMethod;
    parameters.radial = m_radial;
    parameters.drawInPMColorSpace = m_drawInPMColorSpace;

    unsigned parametersHash = StringHasher::hashMemory(&parameters, sizeof(parameters));
    unsigned stopHash = StringHasher::hashMemory(m_stops.data(), m_stops.size() * sizeof(ColorStop));

    m_cachedHash = pairIntHash(parametersHash, stopHash);

    return m_cachedHash;
}

static inline U8CPU F2B(float x)
{
    return static_cast<int>(x * 255);
}

static SkColor makeSkColor(float a, float r, float g, float b)
{
    return SkColorSetARGB(F2B(a), F2B(r), F2B(g), F2B(b));
}

// Determine the total number of stops needed, including pseudo-stops at the
// ends as necessary.
static size_t totalStopsNeeded(const Gradient::ColorStop* stopData, size_t count)
{
    // N.B.: The tests in this function should kept in sync with the ones in
    // fillStops(), or badness happens.
    const Gradient::ColorStop* stop = stopData;
    size_t countUsed = count;
    if (count < 1 || stop->stop > 0.0)
        countUsed++;
    stop += count - 1;
    if (count < 1 || stop->stop < 1.0)
        countUsed++;
    return countUsed;
}

// Collect sorted stop position and color information into the pos and colors
// buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large
// enough to hold information for all stops, including the new endpoints if
// stops at 0.0 and 1.0 aren't already included.
static void fillStops(const Gradient::ColorStop* stopData,
    size_t count, SkScalar* pos, SkColor* colors)
{
    const Gradient::ColorStop* stop = stopData;
    size_t start = 0;
    if (count < 1) {
        // A gradient with no stops must be transparent black.
        pos[0] = WebCoreFloatToSkScalar(0.0);
        colors[0] = makeSkColor(0.0, 0.0, 0.0, 0.0);
        start = 1;
    } else if (stop->stop > 0.0) {
        // Copy the first stop to 0.0. The first stop position may have a slight
        // rounding error, but we don't care in this float comparison, since
        // 0.0 comes through cleanly and people aren't likely to want a gradient
        // with a stop at (0 + epsilon).
        pos[0] = WebCoreFloatToSkScalar(0.0);
        colors[0] = makeSkColor(stop->alpha, stop->red, stop->green, stop->blue);
        start = 1;
    }

    for (size_t i = start; i < start + count; i++) {
        pos[i] = WebCoreFloatToSkScalar(stop->stop);
        colors[i] = makeSkColor(stop->alpha, stop->red, stop->green, stop->blue);
        ++stop;
    }

    // Copy the last stop to 1.0 if needed. See comment above about this float
    // comparison.
    if (count < 1 || (--stop)->stop < 1.0) {
        pos[start + count] = WebCoreFloatToSkScalar(1.0);
        colors[start + count] = colors[start + count - 1];
    }
}

SkShader* Gradient::shader()
{
    if (m_gradient)
        return m_gradient;

    sortStopsIfNecessary();
    ASSERT(m_stopsSorted);

    size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size());
    ASSERT(countUsed >= 2);
    ASSERT(countUsed >= m_stops.size());

    // FIXME: Why is all this manual pointer math needed?!
    SkAutoMalloc storage(countUsed * (sizeof(SkColor) + sizeof(SkScalar)));
    SkColor* colors = (SkColor*)storage.get();
    SkScalar* pos = (SkScalar*)(colors + countUsed);

    fillStops(m_stops.data(), m_stops.size(), pos, colors);

    SkShader::TileMode tile = SkShader::kClamp_TileMode;
    switch (m_spreadMethod) {
    case SpreadMethodReflect:
        tile = SkShader::kMirror_TileMode;
        break;
    case SpreadMethodRepeat:
        tile = SkShader::kRepeat_TileMode;
        break;
    case SpreadMethodPad:
        tile = SkShader::kClamp_TileMode;
        break;
    }

    uint32_t shouldDrawInPMColorSpace = m_drawInPMColorSpace ? SkGradientShader::kInterpolateColorsInPremul_Flag : 0;
    if (m_radial) {
        // Since the two-point radial gradient is slower than the plain radial,
        // only use it if we have to.
        if (m_p0 == m_p1 && m_r0 <= 0.0f)
            m_gradient = SkGradientShader::CreateRadial(m_p1, m_r1, colors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace);
        else {
            // The radii we give to Skia must be positive. If we're given a
            // negative radius, ask for zero instead.
            SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0;
            SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0;
            m_gradient = SkGradientShader::CreateTwoPointConical(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace);
        }

        if (aspectRatio() != 1) {
            // CSS3 elliptical gradients: apply the elliptical scaling at the
            // gradient center point.
            m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y());
            m_gradientSpaceTransformation.scale(1, 1 / aspectRatio());
            m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y());
            ASSERT(m_p0 == m_p1);
        }
    } else {
        SkPoint pts[2] = { m_p0, m_p1 };
        m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace);
    }

    if (!m_gradient)
        // use last color, since our "geometry" was degenerate (e.g. radius==0)
        m_gradient = new SkColorShader(colors[countUsed - 1]);
    else
        m_gradient->setLocalMatrix(m_gradientSpaceTransformation);
    return m_gradient;
}

} //namespace


text:
from __future__ import absolute_import
from . import version
version.append ('$Revision: 90117 $')
del version

from . import get
from . import parser

class Service:

    ''' A Service object is an organizational shortcut to the XML
        associated with every keyword within a given KTL service.

        Typical usage is:

        service_xml = ktlxml.Service (servicename)
        service_xml = ktlxml.Service (servicename, directory=xml_directory)

        keyword_xml = service_xml['keywordname']

        keyword_xml will be a standard XML node.
    '''

    keywords = None

    def __init__ (self, service, directory=None):

        name = str (service)
        name = name.strip ()

        if name == '':
            raise ValueError, 'cannot provide XML for an empty service name'

        index = parser.index (name, directory)

        if index == None:
            raise IOError, "cannot locate index.xml for service '%s'" % (name)

        bundles = parser.bundles (name, index, validate=False)
        keywords = parser.dictionary (name, index, validate=False, keyword_bundles=bundles)

        self.bundles = bundles
        self.index = index
        self.keywords = keywords
        self.name = name

    def __contains__ (self, keyword):

        keyword = str (keyword)
        keyword = keyword.upper ()

        return keyword in self.keywords

    def __getitem__ (self, keyword):

        # By convention, keyword names are upper-case.

        keyword = str (keyword)
        keyword = keyword.upper ()

        if keyword in self.keywords:
            return self.keywords[keyword]
        else:
            raise KeyError, "service '%s' does not have a keyword '%s'" % (self.name, keyword)

    def __iter__ (self):
        return ServiceIterator (self)

    def __len__ (self):

        return len (self.keywords)

    def __repr__ (self):

        return "<xml.Service %s>" % repr(self.keywords)

    def __str__ (self):

        return self.name

    def attributes (self, keyword):
        ''' Return a dictionary containing the simple attributes
            of the specified *keyword*.
        '''

        xml = self[keyword]

        if hasattr (xml, 'ktlxml_attributes'):
            pass
        else:
            xml.ktlxml_attributes = buildAttributes (xml)

        return xml.ktlxml_attributes

    def list (self):
        ''' Return a list containing all of the keyword names
            represented by this :class:`Service` instance.
        '''

        keywords = self.keywords.keys ()
        keywords.sort ()

        return keywords

    keys = list
    # keywords = list

# end of class Service

class ServiceIterator:

    def __init__ (self, service):

        self.service = service
        self.keywords = self.service.keywords.keys ()
        self.keywords.sort ()

        # Using pop(), the total iteration time is lower if the
        # list is reversed and elements are popped off the end.
        # The benefit is measurable for services both large and
        # small.

        self.keywords.reverse ()

    def next (self):

        next = None

        while next == None:

            # Using try/except clauses for this sequence of
            # operations is about 10% faster than checking
            # via conditions.

            try:
                # Pop the last keyword off the reversed list.
                keyword = self.keywords.pop ()

            except IndexError:
                # No more keywords to pop.
                raise StopIteration

            try:
                next = self.service[keyword]

            except KeyError:
                next = None

        return next

# end of class ServiceIterator

def buildAttributes (node):
    ''' *node* should be an XML node representing a keyword. Build a
        dictionary of the available attributes of the keyword, using
        key names similar to those for the ktl.Keyword class. If a
        specific attribute is not set in the KTL XML, it is set to
        None.
    '''

    if node.localName != 'keyword':
        raise ValueError, "buildAttributes() requires a <keyword> node, not a <%s> node" % (node.localName)

    attributes = {}

    # Required attributes first.

    attributes['name'] = get.keywordName (node)
    attributes['type'] = get.value (node, 'type')

    # Attributes that may or may not be set, but are valid for
    # all keyword types.

    broadcasts, reads, writes = getCapabilities (node)

    attributes['broadcasts'] = broadcasts
    attributes['reads'] = reads
    attributes['writes'] = writes

    # Attributes that may not be present for this keyword type.

    attributes['enum'] = getEnumerators (node)
    attributes['enumerators'] = attributes['enum']
    attributes['keys'] = getKeys (node)
    attributes['range'] = getRange (node)
    attributes['units'] = getUnits (node)

    return attributes

def getCapabilities (node):

    broadcast = True
    read      = True
    write      = True

    capabilities = node.getElementsByTagName ('capability')

    for capability in capabilities:

        type = capability.getAttribute ('type')

        if type == None:
            continue

        type = type.strip ()
        type = type.lower ()

        value = capability.firstChild.nodeValue
        value = value.strip ()
        value = value.lower ()

        if value == 'true':
            continue

        if type == 'broadcast':
            broadcast = False

        elif type == 'read':
            read = False

        elif type == 'write':
            write = False

    return ((broadcast, read, write))

def getEnumerators (node):

    enumerators = []

    values = node.getElementsByTagName ('values')

    if len (values) == 0:
        return None
    else:
        values = values[0]

    for entry in values.childNodes:

        if entry.nodeName != 'entry':
            continue

        try:
            value = get.value (entry, 'value')
        except ValueError:
            continue

        enumerators.append (value)

    if len (enumerators) == 0:
        enumerators = None

    return enumerators

def getKeys (node):

    keys = []

    elements = node.getElementsByTagName ('elements')

    if len (elements) == 0:
        return None
    else:
        elements = elements[0]

    for entry in elements.childNodes:

        if entry.nodeName != 'entry':
            continue

        try:
            label = get.value (entry, 'label')
        except ValueError:
            continue

        keys.append (label)

    if len (keys) == 0:
        keys = None

    return keys

def getRange (node):

    range = None

    for element in node.childNodes:
        if element.localName == 'range':
            range = element
            break

    if range == None:
        return

    minimum = getMin (range)
    maximum = getMax (range)

    if minimum == None and maximum == None:
        return

    range = {}

    range['minimum'] = minimum
    range['maximum'] = maximum

    return range

def getMin (range):

    try:
        minimum = get.value (range, 'minimum')
    except ValueError:
        return

    try:
        minimum = float (minimum)
    except (TypeError, ValueError):
        minimum = None

    return minimum

def getMax (range):

    try:
        maximum = get.value (range, 'maximum')
    except ValueError:
        return

    try:
        maximum = float (maximum)
    except (TypeError, ValueError):
        maximum = None

    return maximum

def getUnits (node):

    try:
        units = get.value (node, 'units')
    except ValueError:
        units = None

    return units


text:
package org.apache.commons.imaging.formats.png.chunks;

import java.io.IOException;

import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.common.ZLibUtils;
import org.apache.commons.imaging.formats.png.PngConstants;
import org.apache.commons.imaging.formats.png.PngText;

public class PngChunkItxt extends PngTextChunk
{
    public final String keyword, text;

    /*
     * The language tag defined in [RFC-3066] indicates the human language used
     * by the translated keyword and the text. Unlike the keyword, the language
     * tag is case-insensitive. It is an ISO 646.IRV:1991 [ISO 646] string
     * consisting of hyphen-separated words of 1-8 alphanumeric characters each
     * (for example cn, en-uk, no-bok, x-klingon, x-KlInGoN). If the first word
     * is two or three letters long, it is an ISO language code [ISO-639]. If
     * the language tag is empty, the language is unspecified.
     */
    public final String languageTag;

    public final String translatedKeyword;

    public PngChunkItxt(int length, int chunkType, int crc, byte bytes[])
            throws ImageReadException, IOException
    {
        super(length, chunkType, crc, bytes);
        {
            int terminator = findNull(bytes);
            if (terminator < 0)
                throw new ImageReadException(
                        "PNG iTXt chunk keyword is not terminated.");

            keyword = new String(bytes, 0, terminator, "ISO-8859-1");
            int index = terminator + 1;

            int compressionFlag = bytes[index++];
            if (compressionFlag != 0 && compressionFlag != 1)
                throw new ImageReadException(
                        "PNG iTXt chunk has invalid compression flag: "
                                + compressionFlag);

            boolean compressed = compressionFlag == 1;

            int compressionMethod = bytes[index++];
            if (compressed)
                if (compressionMethod != PngConstants.COMPRESSION_DEFLATE_INFLATE)
                    throw new ImageReadException(
                            "PNG iTXt chunk has unexpected compression method: "
                                    + compressionMethod);
                else if (compressionMethod != 0)
                    throw new ImageReadException(
                            "PNG iTXt chunk has unexpected compression method: "
                                    + compressionMethod);

            terminator = findNull(bytes, index);
            if (terminator < 0)
                throw new ImageReadException(
                        "PNG iTXt chunk language tag is not terminated.");

            languageTag = new String(bytes, index, terminator - index,
                    "ISO-8859-1");
            index = terminator + 1;

            terminator = findNull(bytes, index);
            if (terminator < 0)
                throw new ImageReadException(
                        "PNG iTXt chunk translated keyword is not terminated.");

            translatedKeyword = new String(bytes, index, terminator - index,
                    "utf-8");
            index = terminator + 1;

            if (compressed)
            {
                int compressedTextLength = bytes.length - index;

                byte compressedText[] = new byte[compressedTextLength];
                System.arraycopy(bytes, index, compressedText, 0,
                        compressedTextLength);

                text = new String(new ZLibUtils().inflate(compressedText),
                        "utf-8");

            } else
                text = new String(bytes, index, bytes.length - index, "utf-8");
        }
    }

    /**
     * @return Returns the keyword.
     */
    @Override
    public String getKeyword()
    {
        return keyword;
    }

    /**
     * @return Returns the text.
     */
    @Override
    public String getText()
    {
        return text;
    }

    @Override
    public PngText getContents()
    {
        return new PngText.iTXt(keyword, text, languageTag, translatedKeyword);
    }
}


text:
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"os"
	"regexp"
	"strconv"
	"strings"
	"sync"

	"github.com/gorilla/mux"
	"golang.org/x/sys/unix"

	"github.com/lxc/lxd/lxd/cluster"
	"github.com/lxc/lxd/lxd/events"
	"github.com/lxc/lxd/lxd/instance"
	"github.com/lxc/lxd/lxd/instance/instancetype"
	"github.com/lxc/lxd/lxd/project"
	"github.com/lxc/lxd/lxd/request"
	"github.com/lxc/lxd/lxd/response"
	"github.com/lxc/lxd/lxd/state"
	"github.com/lxc/lxd/lxd/ucred"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/logger"
	"github.com/lxc/lxd/shared/version"
)

type devlxdPut struct {
	State string `json:"state" yaml:"state"`
}

type devlxdGet struct {
	devlxdPut

	APIVersion   string `json:"api_version" yaml:"api_version"`
	InstanceType string `json:"instance_type" yaml:"instance_type"`
	Location     string `json:"location" yaml:"location"`
}

type hoistFunc func(f func(*Daemon, instance.Instance, http.ResponseWriter, *http.Request) response.Response, d *Daemon) func(http.ResponseWriter, *http.Request)

// DevLxdServer creates an http.Server capable of handling requests against the
// /dev/lxd Unix socket endpoint created inside containers.
func devLxdServer(d *Daemon) *http.Server {
	return &http.Server{
		Handler:     devLxdAPI(d, hoistReq),
		ConnState:   pidMapper.ConnStateHandler,
		ConnContext: request.SaveConnectionInContext,
	}
}

type devLxdHandler struct {
	path string

	/*
	 * This API will have to be changed slightly when we decide to support
	 * websocket events upgrading, but since we don't have events on the
	 * server side right now either, I went the simple route to avoid
	 * needless noise.
	 */
	f func(d *Daemon, c instance.Instance, w http.ResponseWriter, r *http.Request) response.Response
}

var devlxdConfigGet = devLxdHandler{"/1.0/config", func(d *Daemon, c instance.Instance, w http.ResponseWriter, r *http.Request) response.Response {
	filtered := []string{}
	for k := range c.ExpandedConfig() {
		if strings.HasPrefix(k, "user.") || strings.HasPrefix(k, "cloud-init.") {
			filtered = append(filtered, fmt.Sprintf("/1.0/config/%s", k))
		}
	}

	return response.DevLxdResponse(http.StatusOK, filtered, "json", c.Type() == instancetype.VM)
}}

var devlxdConfigKeyGet = devLxdHandler{"/1.0/config/{key}", func(d *Daemon, c instance.Instance, w http.ResponseWriter, r *http.Request) response.Response {
	key, err := url.PathUnescape(mux.Vars(r)["key"])
	if err != nil {
		return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusBadRequest, "bad request"), c.Type() == instancetype.VM)
	}

	if !strings.HasPrefix(key, "user.") && !strings.HasPrefix(key, "cloud-init.") {
		return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusForbidden, "not authorized"), c.Type() == instancetype.VM)
	}

	value, ok := c.ExpandedConfig()[key]
	if !ok {
		return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusNotFound, "not found"), c.Type() == instancetype.VM)
	}

	return response.DevLxdResponse(http.StatusOK, value, "raw", c.Type() == instancetype.VM)
}}

var devlxdImageExport = devLxdHandler{"/1.0/images/{fingerprint}/export", func(d *Daemon, c instance.Instance, w http.ResponseWriter, r *http.Request) response.Response {
	if shared.IsFalseOrEmpty(c.ExpandedConfig()["security.devlxd.images"]) {
		return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusForbidden, "not authorized"), c.Type() == instancetype.VM)
	}

	// Use by security checks to distinguish devlxd vs lxd APIs
	r.RemoteAddr = "@devlxd"

	resp := imageExport(d, r)

	err := resp.Render(w)
	if err != nil {
		return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusInternalServerError, "internal server error"), c.Type() == instancetype.VM)
	}

	return response.DevLxdResponse(http.StatusOK, "", "raw", c.Type() == instancetype.VM)
}}

var devlxdMetadataGet = devLxdHandler{"/1.0/meta-data", func(d *Daemon, inst instance.Instance, w http.ResponseWriter, r *http.Request) response.Response {
	value := inst.ExpandedConfig()["user.meta-data"]

	return response.DevLxdResponse(http.StatusOK, fmt.Sprintf("#cloud-config\ninstance-id: %s\nlocal-hostname: %s\n%s", inst.CloudInitID(), inst.Name(), value), "raw", inst.Type() == instancetype.VM)
}}

var devlxdEventsGet = devLxdHandler{"/1.0/events", func(d *Daemon, c instance.Instance, w http.ResponseWriter, r *http.Request) response.Response {
	typeStr := r.FormValue("type")
	if typeStr == "" {
		typeStr = "config,device"
	}

	var listenerConnection events.EventListenerConnection
	var resp response.Response

	// If the client has not requested a websocket connection then fallback to long polling event stream mode.
	if r.Header.Get("Upgrade") == "websocket" {
		conn, err := shared.WebsocketUpgrader.Upgrade(w, r, nil)
		if err != nil {
			return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusInternalServerError, "internal server error"), c.Type() == instancetype.VM)
		}

		defer func() { _ = conn.Close() }() // Ensure listener below ends when this function ends.

		listenerConnection = events.NewWebsocketListenerConnection(conn)

		resp = response.DevLxdResponse(http.StatusOK, "websocket", "websocket", c.Type() == instancetype.VM)
	} else {
		h, ok := w.(http.Hijacker)
		if !ok {
			return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusInternalServerError, "internal server error"), c.Type() == instancetype.VM)
		}

		conn, _, err := h.Hijack()
		if err != nil {
			return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusInternalServerError, "internal server error"), c.Type() == instancetype.VM)
		}

		defer func() { _ = conn.Close() }() // Ensure listener below ends when this function ends.

		listenerConnection, err = events.NewStreamListenerConnection(conn)
		if err != nil {
			return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusInternalServerError, "internal server error"), c.Type() == instancetype.VM)
		}

		resp = response.DevLxdResponse(http.StatusOK, "", "raw", c.Type() == instancetype.VM)
	}

	listener, err := d.devlxdEvents.AddListener(c.ID(), listenerConnection, strings.Split(typeStr, ","))
	if err != nil {
		return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusInternalServerError, "internal server error"), c.Type() == instancetype.VM)
	}

	logger.Debug("New container event listener", logger.Ctx{"instance": c.Name(), "project": c.Project(), "listener_id": listener.ID})
	listener.Wait(r.Context())

	return resp
}}

var devlxdAPIHandler = devLxdHandler{"/1.0", func(d *Daemon, c instance.Instance, w http.ResponseWriter, r *http.Request) response.Response {
	if r.Method == "GET" {
		location := "none"
		clustered, err := cluster.Enabled(d.db.Node)
		if err != nil {
			return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusInternalServerError, "internal server error"), c.Type() == instancetype.VM)
		}

		if clustered {
			location = c.Location()
		}

		var state api.StatusCode

		if shared.IsTrue(c.LocalConfig()["volatile.last_state.ready"]) {
			state = api.Ready
		} else {
			state = api.Started
		}

		return response.DevLxdResponse(http.StatusOK, devlxdGet{APIVersion: version.APIVersion, Location: location, InstanceType: c.Type().String(), devlxdPut: devlxdPut{State: state.String()}}, "json", c.Type() == instancetype.VM)
	} else if r.Method == "PATCH" {
		req := devlxdPut{}

		err := json.NewDecoder(r.Body).Decode(&req)
		if err != nil {
			return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusBadRequest, err.Error()), c.Type() == instancetype.VM)
		}

		state := api.StatusCodeFromString(req.State)

		if state != api.Started && state != api.Ready {
			return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusBadRequest, "Invalid state %q", req.State), c.Type() == instancetype.VM)
		}

		err = c.VolatileSet(map[string]string{"volatile.last_state.ready": strconv.FormatBool(state == api.Ready)})
		if err != nil {
			return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusInternalServerError, err.Error()), c.Type() == instancetype.VM)
		}

		return response.DevLxdResponse(http.StatusOK, "", "raw", c.Type() == instancetype.VM)
	}

	return response.DevLxdErrorResponse(api.StatusErrorf(http.StatusMethodNotAllowed, fmt.Sprintf("method %q not allowed", r.Method)), c.Type() == instancetype.VM)

}}

var devlxdDevicesGet = devLxdHandler{"/1.0/devices", func(d *Daemon, c instance.Instance, w http.ResponseWriter, r *http.Request) response.Response {
	return response.DevLxdResponse(http.StatusOK, c.ExpandedDevices(), "json", c.Type() == instancetype.VM)
}}

var handlers = []devLxdHandler{
	{"/", func(d *Daemon, c instance.Instance, w http.ResponseWriter, r *http.Request) response.Response {
		return response.DevLxdResponse(http.StatusOK, []string{"/1.0"}, "json", c.Type() == instancetype.VM)
	}},
	devlxdAPIHandler,
	devlxdConfigGet,
	devlxdConfigKeyGet,
	devlxdMetadataGet,
	devlxdEventsGet,
	devlxdImageExport,
	devlxdDevicesGet,
}

func hoistReq(f func(*Daemon, instance.Instance, http.ResponseWriter, *http.Request) response.Response, d *Daemon) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		conn := ucred.GetConnFromContext(r.Context())
		cred, ok := pidMapper.m[conn.(*net.UnixConn)]
		if !ok {
			http.Error(w, pidNotInContainerErr.Error(), http.StatusInternalServerError)
			return
		}

		c, err := findContainerForPid(cred.Pid, d.State())
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		// Access control
		rootUID := uint32(0)

		idmapset, err := c.CurrentIdmap()
		if err == nil && idmapset != nil {
			uid, _ := idmapset.ShiftIntoNs(0, 0)
			rootUID = uint32(uid)
		}

		if rootUID != cred.Uid {
			http.Error(w, "Access denied for non-root user", 401)
			return
		}

		resp := f(d, c, w, r)
		_ = resp.Render(w)
	}
}

func devLxdAPI(d *Daemon, f hoistFunc) http.Handler {
	m := mux.NewRouter()
	m.UseEncodedPath() // Allow encoded values in path segments.

	for _, handler := range handlers {
		m.HandleFunc(handler.path, f(handler.f, d))
	}

	return m
}

/*
 * Everything below here is the guts of the unix socket bits. Unfortunately,
 * golang's API does not make this easy. What happens is:
 *
 * 1. We install a ConnState listener on the http.Server, which does the
 *    initial unix socket credential exchange. When we get a connection started
 *    event, we use SO_PEERCRED to extract the creds for the socket.
 *
 * 2. We store a map from the connection pointer to the pid for that
 *    connection, so that once the HTTP negotiation occurrs and we get a
 *    ResponseWriter, we know (because we negotiated on the first byte) which
 *    pid the connection belogs to.
 *
 * 3. Regular HTTP negotiation and dispatch occurs via net/http.
 *
 * 4. When rendering the response via ResponseWriter, we match its underlying
 *    connection against what we stored in step (2) to figure out which container
 *    it came from.
 */

/*
 * We keep this in a global so that we can reference it from the server and
 * from our http handlers, since there appears to be no way to pass information
 * around here.
 */
var pidMapper = ConnPidMapper{m: map[*net.UnixConn]*unix.Ucred{}}

type ConnPidMapper struct {
	m     map[*net.UnixConn]*unix.Ucred
	mLock sync.Mutex
}

func (m *ConnPidMapper) ConnStateHandler(conn net.Conn, state http.ConnState) {
	unixConn := conn.(*net.UnixConn)
	switch state {
	case http.StateNew:
		cred, err := ucred.GetCred(unixConn)
		if err != nil {
			logger.Debugf("Error getting ucred for conn %s", err)
		} else {
			m.mLock.Lock()
			m.m[unixConn] = cred
			m.mLock.Unlock()
		}

	case http.StateActive:
		return
	case http.StateIdle:
		return
	case http.StateHijacked:
		/*
		 * The "Hijacked" state indicates that the connection has been
		 * taken over from net/http. This is useful for things like
		 * developing websocket libraries, who want to upgrade the
		 * connection to a websocket one, and not use net/http any
		 * more. Whatever the case, we want to forget about it since we
		 * won't see it either.
		 */
		m.mLock.Lock()
		delete(m.m, unixConn)
		m.mLock.Unlock()
	case http.StateClosed:
		m.mLock.Lock()
		delete(m.m, unixConn)
		m.mLock.Unlock()
	default:
		logger.Debugf("Unknown state for connection %s", state)
	}
}

var pidNotInContainerErr = fmt.Errorf("pid not in container?")

func findContainerForPid(pid int32, s *state.State) (instance.Container, error) {
	/*
	 * Try and figure out which container a pid is in. There is probably a
	 * better way to do this. Based on rharper's initial performance
	 * metrics, looping over every container and calling newLxdContainer is
	 * expensive, so I wanted to avoid that if possible, so this happens in
	 * a two step process:
	 *
	 * 1. Walk up the process tree until you see something that looks like
	 *    an lxc monitor process and extract its name from there.
	 *
	 * 2. If this fails, it may be that someone did an `lxc exec foo bash`,
	 *    so the process isn't actually a descendant of the container's
	 *    init. In this case we just look through all the containers until
	 *    we find an init with a matching pid namespace. This is probably
	 *    uncommon, so hopefully the slowness won't hurt us.
	 */

	origpid := pid

	for pid > 1 {
		cmdline, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
		if err != nil {
			return nil, err
		}

		if strings.HasPrefix(string(cmdline), "[lxc monitor]") {
			// container names can't have spaces
			parts := strings.Split(string(cmdline), " ")
			name := strings.TrimSuffix(parts[len(parts)-1], "\x00")

			projectName := project.Default
			if strings.Contains(name, "_") {
				fields := strings.SplitN(name, "_", 2)
				projectName = fields[0]
				name = fields[1]
			}

			inst, err := instance.LoadByProjectAndName(s, projectName, name)
			if err != nil {
				return nil, err
			}

			if inst.Type() != instancetype.Container {
				return nil, fmt.Errorf("Instance is not container type")
			}

			return inst.(instance.Container), nil
		}

		status, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/status", pid))
		if err != nil {
			return nil, err
		}

		re := regexp.MustCompile(`^PPid:\s+([0-9]+)`)
		for _, line := range strings.Split(string(status), "\n") {
			m := re.FindStringSubmatch(line)
			if len(m) > 1 {
				result, err := strconv.Atoi(m[1])
				if err != nil {
					return nil, err
				}

				pid = int32(result)
				break
			}
		}
	}

	origPidNs, err := os.Readlink(fmt.Sprintf("/proc/%d/ns/pid", origpid))
	if err != nil {
		return nil, err
	}

	instances, err := instance.LoadNodeAll(s, instancetype.Container)
	if err != nil {
		return nil, err
	}

	for _, inst := range instances {
		if inst.Type() != instancetype.Container {
			continue
		}

		if !inst.IsRunning() {
			continue
		}

		initpid := inst.InitPID()
		pidNs, err := os.Readlink(fmt.Sprintf("/proc/%d/ns/pid", initpid))
		if err != nil {
			return nil, err
		}

		if origPidNs == pidNs {
			return inst.(instance.Container), nil
		}
	}

	return nil, pidNotInContainerErr
}


text:
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

#include "ofpi_errno.h"
#include "ofpi_init.h"
#include "ofpi_in.h"
#include "ofpi_in_pcb.h"
#include "ofpi_protosw.h"
#include "ofpi_socketvar.h"
#include "ofpi_tcp_var.h"
#include "ofpi_tcp_shm.h"
#include "ofpi_systm.h"
#include "ofpi_route.h"
#include "ofpi_ip6_var.h"
#ifdef INET6
#include "ofpi_in6_pcb.h"
#endif /*INET6*/

#include "ofpi_pkt_processing.h"

#include "ofpi_log.h"
#include "ofpi_util.h"

#define	HASH_NOWAIT	0x00000001
#define	HASH_WAITOK	0x00000002
extern void *ofp_hashinit(int count, void *type, uint64_t *hashmask);
extern void  ofp_hashdestroy(void *vhashtbl, void *type, uint64_t hashmask);

extern struct inpcbinfo ofp_udbinfo;

static void in_pcbremlists(struct inpcb *inp);
static struct inpcb *
in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct ofp_in_addr faddr,
			 uint32_t fport_arg, struct ofp_in_addr laddr,
			 uint32_t lport_arg, int lookupflags,
			 struct ofp_ifnet *ifp);

static __inline void
refcount_init(odp_atomic_u32_t *count, uint32_t value)
{
	odp_atomic_store_u32(count, value);
}

static __inline void
refcount_acquire(odp_atomic_u32_t *count)
{
	odp_atomic_inc_u32(count);
}

static __inline int
refcount_release(odp_atomic_u32_t *count)
{
	uint32_t old;

	old = odp_atomic_fetch_sub_u32(count, 1);
	KASSERT(old > 0, ("negative refcount %p", count));
	return (old == 1);
}

#ifdef OFP_RSS
void ofp_tcp_rss_in_pcbinfo_init( int hash_nelements, int porthash_nelements,
    uma_init inpcbzone_init, uma_fini inpcbzone_fini, uint32_t inpcbzone_flags)
{
	int32_t cpu_id;

	/* make compiler happy */
	(void)inpcbzone_init;
	(void)inpcbzone_fini;
	(void)inpcbzone_flags;

	for (cpu_id = 0; cpu_id < odp_cpu_count(); cpu_id++) {
		struct inpcbinfo *pcbinfo = &shm_tcp->ofp_tcbinfo[cpu_id];
		struct inpcbhead *listhead = &shm_tcp->ofp_tcb[cpu_id];
		char name_cpu[16];

		sprintf (name_cpu, "tcp_%u", cpu_id);
		INP_INFO_LOCK_INIT(pcbinfo, name_cpu);

		sprintf (name_cpu, "pcbinfohash_%u", cpu_id);
		INP_HASH_LOCK_INIT(pcbinfo, name_cpu);
		pcbinfo->ipi_listhead = listhead;
		OFP_LIST_INIT(pcbinfo->ipi_listhead);
		pcbinfo->ipi_count = 0;

		pcbinfo->ipi_hashbase = shm_tcp->ofp_hashtbl;
		ofp_tcp_hashinit(hash_nelements, &pcbinfo->ipi_hashmask,
				pcbinfo->ipi_hashbase);

		pcbinfo->ipi_porthashbase = shm_tcp->ofp_porthashtbl;
		ofp_tcp_hashinit(porthash_nelements,
			&pcbinfo->ipi_hashmask,
			pcbinfo->ipi_porthashbase);

		sprintf (name_cpu, "tcp_inpcb_%u", cpu_id);
		pcbinfo->ipi_zone = uma_zcreate(name_cpu,
			global_param->pcb_tcp_max, sizeof(struct inpcb),
			NULL, NULL, inpcbzone_init, inpcbzone_fini,
			UMA_ALIGN_PTR, inpcbzone_flags);

		if (pcbinfo->ipi_zone == -1)
			OFP_ERR("ipi_zone for pcbinfo NOT allocated!");

		uma_zone_set_max(pcbinfo->ipi_zone, maxsockets);
	}

	return;
}
#endif

/*
 * Initialize an inpcbinfo -- we should be able to reduce the number of
 * arguments in time.
 */
void
ofp_in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name,
    struct inpcbhead *listhead, int hash_nelements, int porthash_nelements,
    const char *inpcbzone_name, uma_init inpcbzone_init, uma_fini inpcbzone_fini,
    uint32_t inpcbzone_flags)
{
	int pcb_size = OFP_NUM_SOCKETS_MAX;

	/* make compiler happy */
	(void)inpcbzone_init;
	(void)inpcbzone_fini;
	(void)inpcbzone_flags;

	INP_INFO_LOCK_INIT(pcbinfo, name);
	INP_HASH_LOCK_INIT(pcbinfo, "pcbinfohash");	/* XXXRW: argument? */
	pcbinfo->ipi_listhead = listhead;
	OFP_LIST_INIT(pcbinfo->ipi_listhead);
	pcbinfo->ipi_count = 0;
	pcbinfo->ipi_gencnt = 0;

	if (strcmp(name, "tcp") == 0) {
		pcbinfo->ipi_hashbase = shm_tcp->ofp_hashtbl;
		ofp_tcp_hashinit(hash_nelements, &pcbinfo->ipi_hashmask,
			pcbinfo->ipi_hashbase);

		pcbinfo->ipi_porthashbase = shm_tcp->ofp_porthashtbl;
		ofp_tcp_hashinit(porthash_nelements, &pcbinfo->ipi_porthashmask,
                        pcbinfo->ipi_porthashbase);
		pcb_size = global_param->pcb_tcp_max;
	} else {
		pcbinfo->ipi_hashbase = ofp_hashinit(hash_nelements, 0,
		    &pcbinfo->ipi_hashmask);
		pcbinfo->ipi_porthashbase = ofp_hashinit(porthash_nelements, 0,
		    &pcbinfo->ipi_porthashmask);
	}

	pcbinfo->ipi_zone = uma_zcreate(
		inpcbzone_name, pcb_size, sizeof(struct inpcb),
		NULL, NULL, inpcbzone_init, inpcbzone_fini, UMA_ALIGN_PTR,
		inpcbzone_flags);
	uma_zone_set_max(pcbinfo->ipi_zone, maxsockets);
}

/*
 * Destroy an inpcbinfo.
 */
void
ofp_in_pcbinfo_destroy(struct inpcbinfo *pcbinfo)
{
	KASSERT(pcbinfo->ipi_count == 0,
		("%s: ipi_count = %u", __func__, pcbinfo->ipi_count));

	ofp_hashdestroy(pcbinfo->ipi_hashbase, 0, pcbinfo->ipi_hashmask);
	ofp_hashdestroy(pcbinfo->ipi_porthashbase, 0,
		    pcbinfo->ipi_porthashmask);
	/* INP_HASH_LOCK_DESTROY(pcbinfo);
	   INP_INFO_LOCK_DESTROY(pcbinfo);*/
}

void
ofp_in_pcbinfo_hashstats(struct inpcbinfo *pcbinfo, unsigned int *min,
		     unsigned int *avg, unsigned int *max)
{
	unsigned int bucket;
	unsigned int bucket_count;
	unsigned int occupied;
	unsigned int lmin, lsum, lmax;
	struct inpcb *inp;
	struct inpcbhead *head;

	INP_HASH_WLOCK(pcbinfo);

	lmin = (unsigned int)-1;
	lsum = 0;
	lmax = 0;
	occupied = 0;

	for (bucket = 0; bucket <= pcbinfo->ipi_hashmask; bucket++) {

		bucket_count = 0;

		head = &pcbinfo->ipi_hashbase[bucket];
		OFP_LIST_FOREACH(inp, head, inp_hash) {
			bucket_count++;
		}

		if (bucket_count < lmin) lmin = bucket_count;

		if (bucket_count > 0) {
			lsum += bucket_count;
			occupied++;
		}
		if (bucket_count > lmax) lmax = bucket_count;
	}

	*min = lmin;
	*avg = lsum / occupied;
	*max = lmax;

	INP_HASH_WUNLOCK(pcbinfo);
}

/*
 * Allocate a PCB and associate it with the socket.
 * On success return with the PCB locked.
 */
int
ofp_in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
{
	struct inpcb *inp;
	int error;

	INP_INFO_WLOCK_ASSERT(pcbinfo);
	error = 0;
	inp = uma_zalloc(pcbinfo->ipi_zone, OFP_M_NOWAIT);
	if (inp == NULL)
		return (OFP_ENOBUFS);
	bzero(inp, inp_zero_size);
	INP_LOCK_INIT(inp, "inp", "inptcp");
	inp->inp_pcbinfo = pcbinfo;
	inp->inp_socket = so;
	inp->inp_cred = so->so_cred; // HJo: ref inc removed
	inp->inp_inc.inc_fibnum = so->so_fibnum;
	inp->inp_options = ODP_PACKET_INVALID;
#ifdef INET6
	if (INP_SOCKAF(so) == OFP_AF_INET6) {
		inp->inp_vflag |= INP_IPV6PROTO;
		if (V_ip6_v6only)
			inp->inp_flags |= IN6P_IPV6_V6ONLY;
	}
#endif
	OFP_LIST_INSERT_HEAD(pcbinfo->ipi_listhead, inp, inp_list);
	pcbinfo->ipi_count++;
	so->so_pcb = (char *)inp;
#ifdef INET6
	if (V_ip6_auto_flowlabel)
		inp->inp_flags |= IN6P_AUTOFLOWLABEL;
#endif
	INP_WLOCK(inp);
	inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
	refcount_init(&inp->inp_refcount, 1);	/* Reference from inpcbinfo */
	return (error);
}

int
ofp_in_pcbbind(struct inpcb *inp, struct ofp_sockaddr *nam, struct ofp_ucred *cred)
{
	int anonport, error;

	INP_WLOCK_ASSERT(inp);
	INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);

	if (inp->inp_lport != 0 || inp->inp_laddr.s_addr != OFP_INADDR_ANY)
		return (OFP_EINVAL);
	anonport = inp->inp_lport == 0 &&
		(nam == NULL ||
		 ((struct ofp_sockaddr_in *)nam)->sin_port == 0);
	error = ofp_in_pcbbind_setup(inp, nam, &inp->inp_laddr.s_addr,
				 &inp->inp_lport, cred);
	if (error)
		return (error);
	if (ofp_in_pcbinshash(inp) != 0) {
		inp->inp_laddr.s_addr = OFP_INADDR_ANY;
		inp->inp_lport = 0;
		return (OFP_EAGAIN);
	}
	if (anonport)
		inp->inp_flags |= INP_ANONPORT;
	return (0);
}

/* HJo: FIX: sysctl variables */
int ofp_ipport_hifirstauto = 1200;	/* sysctl */
int ofp_ipport_hilastauto = 40000;
int ofp_ipport_lowfirstauto = 1023;	/* 1023 */
int ofp_ipport_lowlastauto = 40000;	/* 600 */
int ofp_ipport_firstauto = 1023;	/* sysctl */
int ofp_ipport_lastauto = 40000;

/*
 * Reserved ports accessible only to root. There are significant
 * security considerations that must be accounted for when changing these,
 * but the security benefits can be great. Please be careful.
 */
VNET_DEFINE(int, ofp_ipport_reservedhigh) = OFP_IPPORT_RESERVED - 1;	/* 1023 */
VNET_DEFINE(int, ofp_ipport_reservedlow);

/* Variables dealing with random ephemeral port allocation. */
VNET_DEFINE(int, ofp_ipport_randomized) = 1;	/* user controlled via sysctl */
VNET_DEFINE(int, ofp_ipport_randomcps) = 10;	/* user controlled via sysctl */
VNET_DEFINE(int, ofp_ipport_randomtime) = 45;	/* user controlled via sysctl */
VNET_DEFINE(int, ofp_ipport_stoprandom);		/* toggled by ipport_tick */
VNET_DEFINE(int, ofp_ipport_tcpallocs);

#define	V_ipport_tcplastcount		VNET(ipport_tcplastcount)

#define RANGECHK(var, min, max) \
	if ((var) < (min)) { (var) = (min); } \
	else if ((var) > (max)) { (var) = (max); }

static int
sysctl_net_ipport_check(OFP_SYSCTL_HANDLER_ARGS)
{
	int error;

	error = sysctl_handle_int(oidp, arg1, arg2, req);

	if (error == 0) {
		RANGECHK(V_ipport_lowfirstauto, 1, OFP_IPPORT_RESERVED - 1);
		RANGECHK(V_ipport_lowlastauto, 1, OFP_IPPORT_RESERVED - 1);
		RANGECHK(V_ipport_firstauto, OFP_IPPORT_RESERVED, OFP_IPPORT_MAX);
		RANGECHK(V_ipport_lastauto, OFP_IPPORT_RESERVED, OFP_IPPORT_MAX);
		RANGECHK(V_ipport_hifirstauto, OFP_IPPORT_RESERVED, OFP_IPPORT_MAX);
		RANGECHK(V_ipport_hilastauto, OFP_IPPORT_RESERVED, OFP_IPPORT_MAX);
	}
	return (error);
}

#define SYSCTL_VNET_PROC OFP_SYSCTL_PROC
#define SYSCTL_VNET_INT OFP_SYSCTL_INT

SYSCTL_DECL(_net_inet_ip);
OFP_SYSCTL_NODE(_net_inet_ip, OFP_IPPROTO_IP, portrange, OFP_CTLFLAG_RW, 0, "IP Ports");

SYSCTL_VNET_PROC(_net_inet_ip_portrange, OFP_OID_AUTO, lowfirst,
	OFP_CTLTYPE_INT|OFP_CTLFLAG_RW, &VNET_NAME(ofp_ipport_lowfirstauto), 0,
	&sysctl_net_ipport_check, "I", "");
SYSCTL_VNET_PROC(_net_inet_ip_portrange, OFP_OID_AUTO, lowlast,
	OFP_CTLTYPE_INT|OFP_CTLFLAG_RW, &VNET_NAME(ofp_ipport_lowlastauto), 0,
	&sysctl_net_ipport_check, "I", "");
SYSCTL_VNET_PROC(_net_inet_ip_portrange, OFP_OID_AUTO, first,
	OFP_CTLTYPE_INT|OFP_CTLFLAG_RW, &VNET_NAME(ofp_ipport_firstauto), 0,
	&sysctl_net_ipport_check, "I", "");
SYSCTL_VNET_PROC(_net_inet_ip_portrange, OFP_OID_AUTO, last,
	OFP_CTLTYPE_INT|OFP_CTLFLAG_RW, &VNET_NAME(ofp_ipport_lastauto), 0,
	&sysctl_net_ipport_check, "I", "");
SYSCTL_VNET_PROC(_net_inet_ip_portrange, OFP_OID_AUTO, hifirst,
	OFP_CTLTYPE_INT|OFP_CTLFLAG_RW, &VNET_NAME(ofp_ipport_hifirstauto), 0,
	&sysctl_net_ipport_check, "I", "");
SYSCTL_VNET_PROC(_net_inet_ip_portrange, OFP_OID_AUTO, hilast,
	OFP_CTLTYPE_INT|OFP_CTLFLAG_RW, &VNET_NAME(ofp_ipport_hilastauto), 0,
	&sysctl_net_ipport_check, "I", "");
SYSCTL_VNET_INT(_net_inet_ip_portrange, OFP_OID_AUTO, reservedhigh,
	OFP_CTLFLAG_RW|OFP_CTLFLAG_SECURE, &VNET_NAME(ofp_ipport_reservedhigh), 0, "");
SYSCTL_VNET_INT(_net_inet_ip_portrange, OFP_OID_AUTO, reservedlow,
	OFP_CTLFLAG_RW|OFP_CTLFLAG_SECURE, &VNET_NAME(ofp_ipport_reservedlow), 0, "");
SYSCTL_VNET_INT(_net_inet_ip_portrange, OFP_OID_AUTO, randomized, OFP_CTLFLAG_RW,
	&VNET_NAME(ofp_ipport_randomized), 0, "Enable random port allocation");
SYSCTL_VNET_INT(_net_inet_ip_portrange, OFP_OID_AUTO, randomcps, OFP_CTLFLAG_RW,
	&VNET_NAME(ofp_ipport_randomcps), 0, "Maximum number of random port "
	"allocations before switching to a sequental one");
SYSCTL_VNET_INT(_net_inet_ip_portrange, OFP_OID_AUTO, randomtime, OFP_CTLFLAG_RW,
	&VNET_NAME(ofp_ipport_randomtime), 0,
	"Minimum time to keep sequental port "
	"allocation before switching to a random one");

int
ofp_in_pcb_lport(struct inpcb *inp, struct ofp_in_addr *laddrp, uint16_t *lportp,
	     struct ofp_ucred *cred, int lookupflags)
{
	struct inpcbinfo *pcbinfo;
	struct inpcb *tmpinp;
	unsigned short *lastport;
	int count, dorandom;
	uint16_t aux, first, last, lport;
	struct ofp_in_addr laddr;

	/* make compiler happy */
	(void)cred;
	(void)lookupflags;

	pcbinfo = inp->inp_pcbinfo;

	/*
	 * Because no actual state changes occur here, a global write lock on
	 * the pcbinfo isn't required.
	 */
	INP_LOCK_ASSERT(inp);
	INP_HASH_LOCK_ASSERT(pcbinfo);

	if (inp->inp_flags & INP_HIGHPORT) {
		first = ofp_ipport_hifirstauto;	/* sysctl */
		last  = ofp_ipport_hilastauto;
		lastport = &pcbinfo->ipi_lasthi;
	} else if (inp->inp_flags & INP_LOWPORT) {
		first = ofp_ipport_lowfirstauto;	/* 1023 */
		last  = ofp_ipport_lowlastauto;	/* 600 */
		lastport = &pcbinfo->ipi_lastlow;
	} else {
		first = ofp_ipport_firstauto;	/* sysctl */
		last  = ofp_ipport_lastauto;
		lastport = &pcbinfo->ipi_lastport;
	}
	/*
	 * For UDP, use random port allocation as long as the user
	 * allows it.  For TCP (and as of yet unknown) connections,
	 * use random port allocation only if the user allows it AND
	 * ipport_tick() allows it.
	 */

	if (ofp_ipport_randomized && pcbinfo == &ofp_udbinfo)
		dorandom = 1;
	else
		dorandom = 0;

	/*
	 * It makes no sense to do random port allocation if
	 * we have the only port available.
	 */
	if (first == last)
		dorandom = 0;

	/*
	 * Instead of having two loops further down counting up or down
	 * make sure that first is always <= last and go with only one
	 * code path implementing all logic.
	 */
	if (first > last) {
		aux = first;
		first = last;
		last = aux;
	}

	/* Make the compiler happy. */
	laddr.s_addr = 0;
	if ((inp->inp_vflag & (INP_IPV4|INP_IPV6)) == INP_IPV4) {
		KASSERT(laddrp != NULL, ("%s: laddrp NULL for v4 inp %p",
					 __func__, inp));
		laddr = *laddrp;
		(void)laddr; /* Compiler happy */
	}

	tmpinp = NULL;	/* Make compiler happy. */
	lport = *lportp;

	if (dorandom)
		*lastport = first + (random() % (last - first));

	count = last - first;

	do {
		if (count-- < 0)	/* completely used? */
			return (OFP_EADDRNOTAVAIL);
		++*lastport;
		if (*lastport < first || *lastport > last)
			*lastport = first;
		lport = odp_cpu_to_be_16(*lastport);

#ifdef INET6
		if ((inp->inp_vflag & INP_IPV6) != 0)
			tmpinp = ofp_in6_pcblookup_local(pcbinfo,
			    &inp->in6p_laddr, lport, lookupflags, cred);
		else
#endif
			tmpinp = ofp_in_pcblookup_local(pcbinfo, laddr,
			    lport, lookupflags, cred);
	} while (tmpinp != NULL);

	if ((inp->inp_vflag & (INP_IPV4|INP_IPV6)) == INP_IPV4)
		laddrp->s_addr = laddr.s_addr;

	*lportp = lport;

	return (0);
}

/*
 * Set up a bind operation on a PCB, performing port allocation
 * as required, but do not actually modify the PCB. Callers can
 * either complete the bind by setting inp_laddr/inp_lport and
 * calling ofp_in_pcbinshash(), or they can just use the resulting
 * port and address to authorise the sending of a once-off packet.
 *
 * On error, the values of *laddrp and *lportp are not changed.
 */
int
ofp_in_pcbbind_setup(struct inpcb *inp, struct ofp_sockaddr *nam,
		 ofp_in_addr_t *laddrp,
		 uint16_t *lportp, struct ofp_ucred *cred)
{
	struct socket *so = inp->inp_socket;
	struct ofp_sockaddr_in *sin;
	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
	struct ofp_in_addr laddr;
	uint16_t lport = 0;
	int lookupflags = 0, reuseport = (so->so_options & OFP_SO_REUSEPORT);
	int error;

	/*
	 * No state changes, so read locks are sufficient here.
	 */
	INP_LOCK_ASSERT(inp);
	INP_HASH_LOCK_ASSERT(pcbinfo);

	if (OFP_TAILQ_EMPTY(ofp_get_ifaddrhead())) /* XXX broken! */
		return (OFP_EADDRNOTAVAIL);

	laddr.s_addr = *laddrp;
	if (nam != NULL && laddr.s_addr != OFP_INADDR_ANY)
		return (OFP_EINVAL);
	if ((so->so_options & (OFP_SO_REUSEADDR|OFP_SO_REUSEPORT)) == 0)
		lookupflags = INPLOOKUP_WILDCARD;
	if (nam) {
		sin = (struct ofp_sockaddr_in *)nam;
		if (nam->sa_len != sizeof (*sin))
			return (OFP_EINVAL);
#ifdef notdef
		/*
		 * We should check the family, but old programs
		 * incorrectly fail to initialize it.
		 */
		if (sin->sin_family != OFP_AF_INET)
			return (OFP_EAFNOSUPPORT);
#endif
		if (sin->sin_port != *lportp) {
			/* Don't allow the port to change. */
			if (*lportp != 0)
				return (OFP_EINVAL);
			lport = sin->sin_port;
		}
		/* NB: lport is left as 0 if the port isn't being changed. */
		if (OFP_IN_MULTICAST(odp_be_to_cpu_32(sin->sin_addr.s_addr))) {
			/*
			 * Treat OFP_SO_REUSEADDR as OFP_SO_REUSEPORT for multicast;
			 * allow complete duplication of binding if
			 * OFP_SO_REUSEPORT is set, or if OFP_SO_REUSEADDR is set
			 * and a multicast address is bound on both
			 * new and duplicated sockets.
			 */
			if (so->so_options & OFP_SO_REUSEADDR)
				reuseport = OFP_SO_REUSEADDR|OFP_SO_REUSEPORT;
		} else if (sin->sin_addr.s_addr != OFP_INADDR_ANY) {
			sin->sin_port = 0;		/* yech... */
			bzero(&sin->sin_zero, sizeof(sin->sin_zero));

			/*
			 * Is the address a local IP address?
			 * If INP_BINDANY is set, then the socket may be bound
			 * to any endpoint address, local or not.
			 */
			if ((inp->inp_flags & INP_BINDANY) == 0 &&
				ofp_ifaddr_elem_get(
				inp->inp_inc.inc_fibnum,
				(uint8_t *)&(sin->sin_addr.s_addr)) == NULL)
				return (OFP_EADDRNOTAVAIL);
		}
		laddr = sin->sin_addr;
		if (lport) {
			struct inpcb *t;
			struct tcptw *tw;

			if (!OFP_IN_MULTICAST(odp_be_to_cpu_32(sin->sin_addr.s_addr))) {
				t = ofp_in_pcblookup_local(pcbinfo, sin->sin_addr,
						       lport, INPLOOKUP_WILDCARD, cred);
				/*
				 * XXX
				 * This entire block sorely needs a rewrite.
				 * (HJo: this comment is from FreeBSD)
				 */
				if (t &&
				    ((t->inp_flags & INP_TIMEWAIT) == 0) &&
				    (so->so_type != OFP_SOCK_STREAM ||
				     odp_be_to_cpu_32(t->inp_faddr.s_addr) == OFP_INADDR_ANY) &&
				    (odp_be_to_cpu_32(sin->sin_addr.s_addr) != OFP_INADDR_ANY ||
				     odp_be_to_cpu_32(t->inp_laddr.s_addr) != OFP_INADDR_ANY ||
				     (t->inp_flags2 & INP_REUSEPORT) == 0) &&
				    (inp->inp_cred->cr_uid !=
				     t->inp_cred->cr_uid))
					return (OFP_EADDRINUSE);
			}
			t = ofp_in_pcblookup_local(pcbinfo, sin->sin_addr,
					       lport, lookupflags, cred);
			if (t && (t->inp_flags & INP_TIMEWAIT)) {
				/*
				 * XXXRW: If an incpb has had its timewait
				 * state recycled, we treat the address as
				 * being in use (for now).  This is better
				 * than a panic, but not desirable.
				 */
				tw = intotw(t);
				if (tw == NULL ||
				    (reuseport & tw->tw_so_options) == 0)
					return (OFP_EADDRINUSE);
			} else if (t && (reuseport == 0 ||
			    (t->inp_flags2 & INP_REUSEPORT) == 0)) {
#ifdef INET6
				if (odp_be_to_cpu_32(sin->sin_addr.s_addr) !=
				    OFP_INADDR_ANY ||
				    odp_be_to_cpu_32(t->inp_laddr.s_addr) !=
				    OFP_INADDR_ANY ||
				    (inp->inp_vflag & INP_IPV6PROTO) == 0 ||
				    (t->inp_vflag & INP_IPV6PROTO) == 0)
#endif
				return (OFP_EADDRINUSE);
			}
		}
	}
	if (*lportp != 0)
		lport = *lportp;

	if (lport == 0)
	{
		error = ofp_in_pcb_lport(inp, &laddr, &lport, cred, lookupflags);
		if (error != 0)
			return (error);
	}
	*laddrp = laddr.s_addr;
	*lportp = lport;
	return (0);
}

/*
 * Connect from a socket to a specified address.
 * Both address and port must be specified in argument sin.
 * If don't have a local address for this socket yet,
 * then pick one.
 */
int
ofp_in_pcbconnect_mbuf(struct inpcb *inp, struct ofp_sockaddr *nam,
		   struct ofp_ucred *cred, odp_packet_t m)
{
	u_short lport, fport;
	ofp_in_addr_t laddr, faddr;
	int anonport, error;

	INP_WLOCK_ASSERT(inp);
	INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);

	lport = inp->inp_lport;
	laddr = inp->inp_laddr.s_addr;
	anonport = (lport == 0);
	error = ofp_in_pcbconnect_setup(inp, nam, &laddr, &lport, &faddr, &fport,
					  NULL, cred);
	if (error)
		return (error);

	/* Do the initial binding of the local address if required. */
	if (inp->inp_laddr.s_addr == OFP_INADDR_ANY && inp->inp_lport == 0) {
		inp->inp_lport = lport;
		inp->inp_laddr.s_addr = laddr;
		if (ofp_in_pcbinshash(inp) != 0) {
			inp->inp_laddr.s_addr = OFP_INADDR_ANY;
			inp->inp_lport = 0;
			return (OFP_EAGAIN);
		}
	}

	/* Commit the remaining changes. */
	inp->inp_lport = lport;
	inp->inp_laddr.s_addr = laddr;
	inp->inp_faddr.s_addr = faddr;
	inp->inp_fport = fport;
	ofp_in_pcbrehash_mbuf(inp, m);

	if (anonport)
		inp->inp_flags |= INP_ANONPORT;
	return (0);
}

/*
 * Connect from a socket to a specified address.
 * Both address and port must be specified in argument sin.
 * If don't have a local address for this socket yet,
 * then pick one.
 */
int
ofp_in_pcbconnect(struct inpcb *inp, struct ofp_sockaddr *nam, struct ofp_ucred *cred)
{
	uint16_t lport, fport;
	ofp_in_addr_t laddr, faddr;
	int anonport, error;

	INP_WLOCK_ASSERT(inp);
	INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);

	lport = inp->inp_lport;
	laddr = inp->inp_laddr.s_addr;
	anonport = (lport == 0);
	error = ofp_in_pcbconnect_setup(inp, nam, &laddr, &lport, &faddr, &fport,
				    NULL, cred);
	if (error)
		return (error);

	/* Do the initial binding of the local address if required. */
	if (inp->inp_laddr.s_addr == OFP_INADDR_ANY && inp->inp_lport == 0) {
		inp->inp_lport = lport;
		inp->inp_laddr.s_addr = laddr;
		if (ofp_in_pcbinshash(inp) != 0) {
			inp->inp_laddr.s_addr = OFP_INADDR_ANY;
			inp->inp_lport = 0;
			return (OFP_EAGAIN);
		}
	}

	/* Commit the remaining changes. */
	inp->inp_lport = lport;
	inp->inp_laddr.s_addr = laddr;
	inp->inp_faddr.s_addr = faddr;
	inp->inp_fport = fport;
	ofp_in_pcbrehash(inp);

	if (anonport)
		inp->inp_flags |= INP_ANONPORT;
	return (0);
}

/*
 * Do proper source address selection on an unbound socket in case
 * of connect.
 */
static int
in_pcbladdr(struct inpcb *inp, struct ofp_in_addr *faddr,
	    struct ofp_in_addr *laddr, struct ofp_ucred *cred)
{
	struct ofp_nh_entry *nh;
	struct ofp_ifnet *dev_out;
	uint32_t flags;
	(void)inp;
	(void)faddr;
	(void)cred;

	KASSERT(laddr != NULL, ("%s: laddr NULL", __func__));

	nh = ofp_get_next_hop(0, faddr->s_addr, &flags);
	if (!nh)
		return OFP_ENETUNREACH;

	dev_out = ofp_get_ifnet(nh->port, nh->vlan);

	if (dev_out) {
		laddr->s_addr = dev_out->ip_addr_info[0].ip_addr;
		return 0;
	}

	return OFP_ENETUNREACH;
}

/*
 * Set up for a connect from a socket to the specified address.
 * On entry, *laddrp and *lportp should contain the current local
 * address and port for the PCB; these are updated to the values
 * that should be placed in inp_laddr and inp_lport to complete
 * the connect.
 *
 * On success, *faddrp and *fportp will be set to the remote address
 * and port. These are not updated in the error case.
 *
 * If the operation fails because the connection already exists,
 * *oinpp will be set to the PCB of that connection so that the
 * caller can decide to override it. In all other cases, *oinpp
 * is set to NULL.
 */
int
ofp_in_pcbconnect_setup(struct inpcb *inp, struct ofp_sockaddr *nam,
    ofp_in_addr_t *laddrp, uint16_t *lportp, ofp_in_addr_t *faddrp, uint16_t *fportp,
    struct inpcb **oinpp, struct ofp_ucred *cred)
{
	struct ofp_sockaddr_in *sin = (struct ofp_sockaddr_in *)nam;
	struct inpcb *oinp;
	struct ofp_in_addr laddr, faddr;
	uint16_t lport, fport;
	int error;

	/*
	 * Because a global state change doesn't actually occur here, a read
	 * lock is sufficient.
	 */
	INP_LOCK_ASSERT(inp);
	INP_HASH_LOCK_ASSERT(inp->inp_pcbinfo);

	if (oinpp != NULL)
		*oinpp = NULL;
	if (nam->sa_len != sizeof (*sin))
		return (OFP_EINVAL);
	if (sin->sin_family != OFP_AF_INET)
		return (OFP_EAFNOSUPPORT);
	if (sin->sin_port == 0)
		return (OFP_EADDRNOTAVAIL);
	laddr.s_addr = *laddrp;
	lport = *lportp;
	faddr = sin->sin_addr;
	fport = sin->sin_port;

	if (!OFP_TAILQ_EMPTY(ofp_get_ifaddrhead())) {
		/*
		 * If the destination address is OFP_INADDR_ANY,
		 * use the primary local address.
		 * If the supplied address is OFP_INADDR_BROADCAST,
		 * and the primary interface supports broadcast,
		 * choose the broadcast address for that interface.
		 */
		if (faddr.s_addr == OFP_INADDR_ANY) {
			IN_IFADDR_RLOCK();
			faddr.s_addr = OFP_TAILQ_FIRST(ofp_get_ifaddrhead())->ip_addr_info[0].ip_addr;
			IN_IFADDR_RUNLOCK();
		} else if (faddr.s_addr == (uint64_t)OFP_INADDR_BROADCAST) {
			/* HJo: FIX
			IN_IFADDR_RLOCK();
			if (OFP_TAILQ_FIRST(ofp_get_ifaddrhead())->ia_ifp->if_flags &
			    IFF_BROADCAST)
				faddr = ((struct ofp_sockaddr_in *)(&OFP_TAILQ_FIRST
								(ofp_get_ifaddrhead())->
								ia_broadaddr))->sin_addr;
			IN_IFADDR_RUNLOCK();
			*/
		}
	}
	if (laddr.s_addr == OFP_INADDR_ANY) {
		error = in_pcbladdr(inp, &faddr, &laddr, cred);
		/*
		 * If the destination address is multicast and an outgoing
		 * interface has been set as a multicast option, prefer the
		 * address of that interface as our source address.
		 */
		/* HJo: Multicast is not supported. */
		if (OFP_IN_MULTICAST(odp_be_to_cpu_32(faddr.s_addr)) &&
		    inp->inp_moptions != NULL) {
			struct ofp_ip_moptions *imo;
			struct ofp_ifnet *ifp;

			imo = inp->inp_moptions;
			if (imo->imo_multicast_ifp != NULL) {
				ifp = imo->imo_multicast_ifp;
				laddr.s_addr = ifp->ip_addr_info[0].ip_addr;
				error = 0;
			}
		}
		if (error)
			return (error);
	}
	oinp = in_pcblookup_hash_locked(inp->inp_pcbinfo, faddr, fport,
	    laddr, lport, 0, NULL);

	if (oinp != NULL) {
		if (oinpp != NULL)
			*oinpp = oinp;
		return (OFP_EADDRINUSE);
	}
	if (lport == 0) {
		error = ofp_in_pcbbind_setup(inp, NULL, &laddr.s_addr, &lport,
		    cred);
		if (error)
			return (error);
	}
	*laddrp = laddr.s_addr;
	*lportp = lport;
	*faddrp = faddr.s_addr;
	*fportp = fport;

	return (0);
}

void
ofp_in_pcbdisconnect(struct inpcb *inp)
{

	INP_WLOCK_ASSERT(inp);
	INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);

	inp->inp_faddr.s_addr = OFP_INADDR_ANY;
	inp->inp_fport = 0;
	ofp_in_pcbrehash(inp);
}

/*
 * ofp_in_pcbdetach() is responsibe for disassociating a socket from an inpcb.
 * For most protocols, this will be invoked immediately prior to calling
 * ofp_in_pcbfree().  However, with TCP the inpcb may significantly outlive the
 * socket, in which case ofp_in_pcbfree() is deferred.
 */
void
ofp_in_pcbdetach(struct inpcb *inp)
{
	KASSERT(inp->inp_socket != NULL, ("%s: inp_socket == NULL", __func__));

	inp->inp_socket->so_pcb = NULL;
	inp->inp_socket = NULL;
}

/*
 * ofp_in_pcbref() bumps the reference count on an inpcb in order to maintain
 * stability of an inpcb pointer despite the inpcb lock being released.  This
 * is used in TCP when the inpcbinfo lock needs to be acquired or upgraded,
 * but where the inpcb lock may already held, or when acquiring a reference
 * via a pcbgroup.
 *
 * ofp_in_pcbref() should be used only to provide brief memory stability, and
 * must always be followed by a call to INP_WLOCK() and in_pcbrele() to
 * garbage collect the inpcb if it has been ofp_in_pcbfree()'d from another
 * context.  Until in_pcbrele() has returned that the inpcb is still valid,
 * lock and rele are the *only* safe operations that may be performed on the
 * inpcb.
 *
 * While the inpcb will not be freed, releasing the inpcb lock means that the
 * connection's state may change, so the caller should be careful to
 * revalidate any cached state on reacquiring the lock.  Drop the reference
 * using in_pcbrele().
 */
void
ofp_in_pcbref(struct inpcb *inp)
{

	KASSERT(inp->inp_refcount.v > 0, ("%s: refcount 0", __func__));

	refcount_acquire(&inp->inp_refcount);
}

/*
 * Drop a refcount on an inpcb elevated using ofp_in_pcbref(); because a call to
 * ofp_in_pcbfree() may have been made between ofp_in_pcbref() and in_pcbrele(), we
 * return a flag indicating whether or not the inpcb remains valid.  If it is
 * valid, we return with the inpcb lock held.
 *
 * Notice that, unlike ofp_in_pcbref(), the inpcb lock must be held to drop a
 * reference on an inpcb.  Historically more work was done here (actually, in
 * in_pcbfree_internal()) but has been moved to ofp_in_pcbfree() to avoid the
 * need for the pcbinfo lock in in_pcbrele().  Deferring the free is entirely
 * about memory stability (and continued use of the write lock).
 */
int
ofp_in_pcbrele_rlocked(struct inpcb *inp)
{
	KASSERT(inp->inp_refcount.v > 0, ("%s: refcount 0", __func__));

	INP_RLOCK_ASSERT(inp);

	if (refcount_release(&inp->inp_refcount) == 0)
		return (0);

	KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));

	INP_RUNLOCK(inp);
	uma_zfree(inp->inp_pcbinfo->ipi_zone, inp);
	return (1);
}

int
ofp_in_pcbrele_wlocked(struct inpcb *inp)
{
	KASSERT(inp->inp_refcount.v > 0, ("%s: refcount 0", __func__));

	INP_WLOCK_ASSERT(inp);

	if (refcount_release(&inp->inp_refcount) == 0)
		return (0);

	KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));

	INP_WUNLOCK(inp);
	uma_zfree(inp->inp_pcbinfo->ipi_zone, inp);
	return (1);
}

/*
 * Unconditionally schedule an inpcb to be freed by decrementing its
 * reference count, which should occur only after the inpcb has been detached
 * from its socket.  If another thread holds a temporary reference (acquired
 * using ofp_in_pcbref()) then the free is deferred until that reference is
 * released using in_pcbrele(), but the inpcb is still unlocked.  Almost all
 * work, including removal from global lists, is done in this context, where
 * the pcbinfo lock is held.
 */
void
ofp_in_pcbfree(struct inpcb *inp)
{
	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;

	KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));

	INP_INFO_WLOCK_ASSERT(pcbinfo);
	INP_WLOCK_ASSERT(inp);

	inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
	in_pcbremlists(inp);
#ifdef INET6
#if 0
	if (inp->inp_vflag & INP_IPV6PROTO) {
		ip6_freepcbopts(inp->in6p_outputopts);
		if (inp->in6p_moptions != NULL)
			ip6_freemoptions(inp->in6p_moptions);*/
	}
#endif /*0*/
#endif
	/* HJo: FIX
	if (inp->inp_options)
		(void)m_free(inp->inp_options);
	*/
	/* HJo: Multicast not supported
	if (inp->inp_moptions != NULL)
		ofp_inp_freemoptions(inp->inp_moptions);
	*/

	inp->inp_vflag = 0;
	/* HJo: cred structure not used
	crfree(inp->inp_cred);
	*/

	if (!ofp_in_pcbrele_wlocked(inp))
		INP_WUNLOCK(inp);
}

/*
 * ofp_in_pcbdrop() removes an inpcb from hashed lists, releasing its address and
 * port reservation, and preventing it from being returned by inpcb lookups.
 *
 * It is used by TCP to mark an inpcb as unused and avoid future packet
 * delivery or event notification when a socket remains open but TCP has
 * closed.  This might occur as a result of a shutdown()-initiated TCP close
 * or a RST on the wire, and allows the port binding to be reused while still
 * maintaining the invariant that so_pcb always points to a valid inpcb until
 * ofp_in_pcbdetach().
 *
 * XXXRW: Possibly ofp_in_pcbdrop() should also prevent future notifications by
 * in_pcbnotifyall() and in_pcbpurgeif0()?
 */
void
ofp_in_pcbdrop(struct inpcb *inp)
{
	INP_WLOCK_ASSERT(inp);

	/*
	 * XXXRW: Possibly we should protect the setting of INP_DROPPED with
	 * the hash lock...?
	 */
	inp->inp_flags |= INP_DROPPED;
	if (inp->inp_flags & INP_INHASHLIST) {
		struct inpcbport *phd = inp->inp_phd;

		INP_HASH_WLOCK(inp->inp_pcbinfo);
		OFP_LIST_REMOVE(inp, inp_hash);
		OFP_LIST_REMOVE(inp, inp_portlist);
		if (OFP_LIST_FIRST(&phd->phd_pcblist) == NULL) {
			OFP_LIST_REMOVE(phd, phd_hash);
			free(phd);
		}
		INP_HASH_WUNLOCK(inp->inp_pcbinfo);
		inp->inp_flags &= ~INP_INHASHLIST;
	}
}

/*
 * Common routines to return the socket addresses associated with inpcbs.
 */
struct ofp_sockaddr *
ofp_in_sockaddr(ofp_in_port_t port, struct ofp_in_addr *addr_p)
{
	struct ofp_sockaddr_in *sin;

	sin = malloc(sizeof *sin);
	sin->sin_family = OFP_AF_INET;
	sin->sin_len = sizeof(*sin);
	sin->sin_addr = *addr_p;
	sin->sin_port = port;

	return (struct ofp_sockaddr *)sin;
}

int
ofp_in_getsockaddr(struct socket *so, struct ofp_sockaddr **nam)
{
	struct inpcb *inp;
	struct ofp_in_addr addr;
	ofp_in_port_t port;

	inp = sotoinpcb(so);
	KASSERT(inp != NULL, ("ofp_in_getsockaddr: inp == NULL"));

	INP_RLOCK(inp);
	port = inp->inp_lport;
	addr = inp->inp_laddr;
	INP_RUNLOCK(inp);

	*nam = ofp_in_sockaddr(port, &addr);
	return 0;
}

int
ofp_in_getpeeraddr(struct socket *so, struct ofp_sockaddr **nam)
{
	struct inpcb *inp;
	struct ofp_in_addr addr;
	ofp_in_port_t port;

	inp = sotoinpcb(so);
	KASSERT(inp != NULL, ("ofp_in_getpeeraddr: inp == NULL"));

	INP_RLOCK(inp);
	port = inp->inp_fport;
	addr = inp->inp_faddr;
	INP_RUNLOCK(inp);

	*nam = ofp_in_sockaddr(port, &addr);
	return 0;
}

void ofp_in_pcbnotifyall(struct inpcbinfo *pcbinfo,
	struct ofp_in_addr faddr, int error_val,
	struct inpcb *(*notify)(struct inpcb *inpcb_, int int_val)) {
	struct inpcb *inp, *inp_temp;

	INP_INFO_WLOCK(pcbinfo);
	OFP_LIST_FOREACH_SAFE(inp, pcbinfo->ipi_listhead, inp_list, inp_temp) {
		INP_WLOCK(inp);
#ifdef INET6
		if ((inp->inp_vflag & INP_IPV4) == 0) {
			INP_WUNLOCK(inp);
			continue;
		}
#endif
		if (inp->inp_faddr.s_addr != faddr.s_addr ||
		    inp->inp_socket == NULL) {
			INP_WUNLOCK(inp);
			continue;
		}
		if ((*notify)(inp, error_val))
			INP_WUNLOCK(inp);
	}
	INP_INFO_WUNLOCK(pcbinfo);
}

/*
 * Lookup a PCB based on the local address and port.  Caller must hold the
 * hash lock.  No inpcb locks or references are acquired.
 */
#define INP_LOOKUP_MAPPED_PCB_COST	3
struct inpcb *
ofp_in_pcblookup_local(struct inpcbinfo *pcbinfo, struct ofp_in_addr laddr,
		   uint16_t lport, int lookupflags, struct ofp_ucred *cred)
{
	struct inpcb *inp;

	(void)cred;
#ifdef INET6
	int matchwild = 3 + INP_LOOKUP_MAPPED_PCB_COST;
#else
	int matchwild = 3;
#endif
	int wildcard;

	KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
		("%s: invalid lookup flags %d", __func__, lookupflags));

	INP_HASH_LOCK_ASSERT(pcbinfo);

	if ((lookupflags & INPLOOKUP_WILDCARD) == 0) {
		struct inpcbhead *head;
		/*
		 * Look for an unconnected (wildcard foreign addr) PCB that
		 * matches the local address and port we're looking for.
		 */
		head = &pcbinfo->ipi_hashbase[INP_PCBHASH(OFP_INADDR_ANY, lport,
		    0, pcbinfo->ipi_hashmask)];
		OFP_LIST_FOREACH(inp, head, inp_hash) {
#ifdef INET6
			/* XXX inp locking */
			if ((inp->inp_vflag & INP_IPV4) == 0)
				continue;
#endif
			if (inp->inp_faddr.s_addr == OFP_INADDR_ANY &&
			    inp->inp_laddr.s_addr == laddr.s_addr &&
			    inp->inp_lport == lport) {
				/*
				 * Found
				 */
				return (inp);
			}
		}
		/*
		 * Not found.
		 */
		return (NULL);
	} else {
		struct inpcbporthead *porthash;
		struct inpcbport *phd;
		struct inpcb *match = NULL;
		/*
		 * Best fit PCB lookup.
		 *
		 * First see if this local port is in use by looking on the
		 * port hash list.
		 */
		porthash = &pcbinfo->ipi_porthashbase[INP_PCBPORTHASH(lport,
		    pcbinfo->ipi_porthashmask)];
		OFP_LIST_FOREACH(phd, porthash, phd_hash) {
			if (phd->phd_port == lport)
				break;
		}
		if (phd != NULL) {
			/*
			 * Port is in use by one or more PCBs. Look for best
			 * fit.
			 */
			OFP_LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) {
				wildcard = 0;
#ifdef INET6
				/* XXX inp locking */
				if ((inp->inp_vflag & INP_IPV4) == 0)
					continue;
				/*
				 * We never select the PCB that has
				 * INP_IPV6 flag and is bound to :: if
				 * we have another PCB which is bound
				 * to 0.0.0.0.  If a PCB has the
				 * INP_IPV6 flag, then we set its cost
				 * higher than IPv4 only PCBs.
				 *
				 * Note that the case only happens
				 * when a socket is bound to ::, under
				 * the condition that the use of the
				 * mapped address is allowed.
				 */
				if ((inp->inp_vflag & INP_IPV6) != 0)
					wildcard += INP_LOOKUP_MAPPED_PCB_COST;
#endif
				if (inp->inp_faddr.s_addr != OFP_INADDR_ANY)
					wildcard++;
				if (inp->inp_laddr.s_addr != OFP_INADDR_ANY) {
					if (laddr.s_addr == OFP_INADDR_ANY)
						wildcard++;
					else if (inp->inp_laddr.s_addr != laddr.s_addr)
						continue;
				} else {
					if (laddr.s_addr != OFP_INADDR_ANY)
						wildcard++;
				}
				if (wildcard < matchwild) {
					match = inp;
					matchwild = wildcard;
					if (matchwild == 0)
						break;
				}
			}
		}
		return (match);
	}
}

/*
 * Insert PCB onto various hash lists.
 */
static int
in_pcbinshash_internal(struct inpcb *inp, int do_pcbgroup_update)
{
	struct inpcbhead *pcbhash;
	struct inpcbporthead *pcbporthash;
	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
	struct inpcbport *phd;
	uint32_t hashkey_faddr;
	uint32_t hashkey;

	(void)do_pcbgroup_update;

	INP_WLOCK_ASSERT(inp);
	INP_HASH_WLOCK_ASSERT(pcbinfo);

	KASSERT((inp->inp_flags & INP_INHASHLIST) == 0,
	    ("ofp_in_pcbinshash: INP_INHASHLIST"));

#ifdef INET6
	if (inp->inp_vflag & INP_IPV6)
		hashkey_faddr = inp->in6p_faddr.ofp_s6_addr32[3] /* XXX */;
	else
#endif /* INET6 */
	hashkey_faddr = inp->inp_faddr.s_addr;

	hashkey = INP_PCBHASH(hashkey_faddr,
		 inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask);

	pcbhash = &pcbinfo->ipi_hashbase[hashkey];

	hashkey = INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask);

	pcbporthash = &pcbinfo->ipi_porthashbase[hashkey];
	/*
	 * Go through port list and look for a head for this lport.
	 */
	OFP_LIST_FOREACH(phd, pcbporthash, phd_hash) {
		if (phd->phd_port == inp->inp_lport)
			break;
	}
	/*
	 * If none exists, malloc one and tack it on.
	 */
	if (phd == NULL) {
		phd = malloc(sizeof(struct inpcbport));
		if (phd == NULL) {
			return (OFP_ENOBUFS); /* XXX */
		}
		phd->phd_port = inp->inp_lport;
		OFP_LIST_INIT(&phd->phd_pcblist);
		OFP_LIST_INSERT_HEAD(pcbporthash, phd, phd_hash);
	}
	inp->inp_phd = phd;
	OFP_LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist);
	OFP_LIST_INSERT_HEAD(pcbhash, inp, inp_hash);
	inp->inp_flags |= INP_INHASHLIST;

	return (0);
}

/*
 * For now, there are two public interfaces to insert an inpcb into the hash
 * lists -- one that does update pcbgroups, and one that doesn't.  The latter
 * is used only in the TCP syncache, where ofp_in_pcbinshash is called before the
 * full 4-tuple is set for the inpcb, and we don't want to install in the
 * pcbgroup until later.
 *
 * XXXRW: This seems like a misfeature.  ofp_in_pcbinshash should always update
 * connection groups, and partially initialised inpcbs should not be exposed
 * to either reservation hash tables or pcbgroups.
 */
int
ofp_in_pcbinshash(struct inpcb *inp)
{

	return (in_pcbinshash_internal(inp, 1));
}

int
ofp_in_pcbinshash_nopcbgroup(struct inpcb *inp)
{

	return (in_pcbinshash_internal(inp, 0));
}

/*
 * Lookup PCB in hash list, using pcbinfo tables.  This variation assumes
 * that the caller has locked the hash list, and will not perform any further
 * locking or reference operations on either the hash list or the connection.
 */
static struct inpcb *
in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct ofp_in_addr faddr,
			 uint32_t fport_arg, struct ofp_in_addr laddr,\
			 uint32_t lport_arg, int lookupflags,
			 struct ofp_ifnet *ifp)
{
	struct inpcbhead *head;
	struct inpcb *inp;
	uint16_t fport = fport_arg, lport = lport_arg;

	(void)ifp;

	KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
		("%s: invalid lookup flags %d", __func__, lookupflags));

	INP_HASH_LOCK_ASSERT(pcbinfo);

	/*
	 * First look for an exact match.
	 */
	head = &pcbinfo->ipi_hashbase[INP_PCBHASH(faddr.s_addr, lport, fport,
	    pcbinfo->ipi_hashmask)];
	OFP_LIST_FOREACH(inp, head, inp_hash) {
#ifdef INET6
		/* XXX inp locking */
		if (odp_unlikely((inp->inp_vflag & INP_IPV4) == 0))
			continue;
#endif
		if (inp->inp_faddr.s_addr == faddr.s_addr &&
		    inp->inp_laddr.s_addr == laddr.s_addr &&
		    inp->inp_fport == fport &&
		    inp->inp_lport == lport) {
			/*
			 * XXX We should be able to directly return
			 * the inp here, without any checks.
			 * Well unless both bound with OFP_SO_REUSEPORT?
			 */
			return (inp);
		}
	}

	/*
	 * Then look for a wildcard match, if requested.
	 */
	if ((lookupflags & INPLOOKUP_WILDCARD) != 0) {
		struct inpcb *local_wild = NULL, *local_exact = NULL;
#ifdef _INET6
		struct inpcb *local_wild_mapped = NULL;
#endif
		struct inpcb *jail_wild = NULL;
		int injail = 0;

		/*
		 * Order of socket selection - we always prefer jails.
		 *      1. jailed, non-wild.
		 *      2. jailed, wild.
		 *      3. non-jailed, non-wild.
		 *      4. non-jailed, wild.
		 */

		head = &pcbinfo->ipi_hashbase[INP_PCBHASH(OFP_INADDR_ANY, lport,
		    0, pcbinfo->ipi_hashmask)];
		OFP_LIST_FOREACH(inp, head, inp_hash) {
#ifdef _INET6
			/* XXX inp locking */
			if ((inp->inp_vflag & INP_IPV4) == 0)
				continue;
#endif
			if (inp->inp_faddr.s_addr != OFP_INADDR_ANY ||
			    inp->inp_lport != lport)
				continue;

#if 0
			/* XXX inp locking */
			if (ifp && ifp->if_type == IFT_FAITH &&
			    (inp->inp_flags & INP_FAITH) == 0)
				continue;

			injail = prison_flag(inp->inp_cred, PR_IP4);
#endif
			if (injail) {
#if 0
				if (prison_check_ip4(inp->inp_cred,
				    &laddr) != 0)
					continue;
#endif
			} else {
				if (local_exact != NULL)
					continue;
			}

			if (inp->inp_laddr.s_addr == laddr.s_addr) {
				if (injail)
					return (inp);
				else
					local_exact = inp;
			} else if (inp->inp_laddr.s_addr == OFP_INADDR_ANY) {
#ifdef _INET6
				/* XXX inp locking, NULL check */
				if (inp->inp_vflag & INP_IPV6PROTO)
					local_wild_mapped = inp;
				else
#endif /* INET6 */
					if (injail)
						jail_wild = inp;
					else
						local_wild = inp;
			}
		} /* OFP_LIST_FOREACH */
		if (jail_wild != NULL) {
			return (jail_wild);
		}
		if (local_exact != NULL) {
			return (local_exact);
		}
		if (local_wild != NULL) {
			return (local_wild);
		}
#ifdef _INET6
		if (local_wild_mapped != NULL) {
			return (local_wild_mapped);
		}
#endif /* defined(INET6) */
	} /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */

	return (NULL);
}

static struct inpcb *
in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct ofp_in_addr faddr,
		  uint32_t fport, struct ofp_in_addr laddr, uint32_t lport,
		  int lookupflags, struct ofp_ifnet *ifp)
{
	struct inpcb *inp;

	INP_HASH_RLOCK(pcbinfo);

	inp = in_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport,
				       (lookupflags & ~(INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)), ifp);
	if (inp != NULL) {
		ofp_in_pcbref(inp);
		INP_HASH_RUNLOCK(pcbinfo);
		if (lookupflags & INPLOOKUP_WLOCKPCB) {
			INP_WLOCK(inp);
			if (ofp_in_pcbrele_wlocked(inp)) {
				return (NULL);
			}
		} else if (lookupflags & INPLOOKUP_RLOCKPCB) {
			INP_RLOCK(inp);
			if (ofp_in_pcbrele_rlocked(inp)) {
				return (NULL);
			}
		} else
			panic("locking bug");
	} else {
		INP_HASH_RUNLOCK(pcbinfo);
	}

	return (inp);
}

/*
 * Public inpcb lookup routines, accepting a 4-tuple, and optionally, an mbuf
 * from which a pre-calculated hash value may be extracted.
 *
 * Possibly more of this logic should be in in_pcbgroup.c.
 */
struct inpcb *
ofp_in_pcblookup(struct inpcbinfo *pcbinfo, struct ofp_in_addr faddr,
	     uint32_t fport, struct ofp_in_addr laddr, uint32_t lport,
	     int lookupflags, struct ofp_ifnet *ifp)
{
	KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0,
	    ("%s: invalid lookup flags %d", __func__, lookupflags));
	KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)) != 0,
	    ("%s: LOCKPCB not set", __func__));

	return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport,
				  lookupflags, ifp));
}

struct inpcb *
ofp_in_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct ofp_in_addr faddr,
    uint32_t fport, struct ofp_in_addr laddr, uint32_t lport, int lookupflags,
    struct ofp_ifnet *ifp, odp_packet_t m)
{
	(void)m;
	KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0,
	    ("%s: invalid lookup flags %d", __func__, lookupflags));
	KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)) != 0,
	    ("%s: LOCKPCB not set", __func__));

	return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport,
				  lookupflags, ifp));
}

/*
 * Move PCB to the proper hash bucket when { faddr, fport } have  been
 * changed. NOTE: This does not handle the case of the lport changing (the
 * hashed port list would have to be updated as well), so the lport must
 * not change after ofp_in_pcbinshash() has been called.
 */
void
ofp_in_pcbrehash_mbuf(struct inpcb *inp, odp_packet_t m)
{
	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
	struct inpcbhead *head;
	uint32_t hashkey_faddr;
	uint32_t hashkey;
	(void)m;

	INP_WLOCK_ASSERT(inp);
	INP_HASH_WLOCK_ASSERT(pcbinfo);

	KASSERT(inp->inp_flags & INP_INHASHLIST,
	    ("ofp_in_pcbrehash: !INP_INHASHLIST"));

#ifdef INET6
	if (inp->inp_vflag & INP_IPV6)
		hashkey_faddr = inp->in6p_faddr.ofp_s6_addr32[3] /* XXX */;
	else
#endif /* INET6 */
	hashkey_faddr = inp->inp_faddr.s_addr;

	hashkey = INP_PCBHASH(hashkey_faddr,
			      inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask);

	head = &pcbinfo->ipi_hashbase[hashkey];

	OFP_LIST_REMOVE(inp, inp_hash);
	OFP_LIST_INSERT_HEAD(head, inp, inp_hash);

}

/*
 * Move PCB to the proper hash bucket when { faddr, fport } have  been
 * changed. NOTE: This does not handle the case of the lport changing (the
 * hashed port list would have to be updated as well), so the lport must
 * not change after ofp_in_pcbinshash() has been called.
 */
void
ofp_in_pcbrehash(struct inpcb *inp)
{
	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
	struct inpcbhead *head;
	uint32_t hashkey_faddr;
	uint32_t hashkey;

	INP_WLOCK_ASSERT(inp);
	INP_HASH_WLOCK_ASSERT(pcbinfo);

	KASSERT(inp->inp_flags & INP_INHASHLIST,
		("ofp_in_pcbrehash: !INP_INHASHLIST"));

#ifdef INET6
	if (inp->inp_vflag & INP_IPV6)
		hashkey_faddr = inp->in6p_faddr.ofp_s6_addr32[3] /* XXX */;
	else
#endif /* INET6 */
	hashkey_faddr = inp->inp_faddr.s_addr;

	hashkey = INP_PCBHASH(hashkey_faddr,
			      inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask);

	head = &pcbinfo->ipi_hashbase[hashkey];

	OFP_LIST_REMOVE(inp, inp_hash);
	OFP_LIST_INSERT_HEAD(head, inp, inp_hash);
}

/*
 * Remove PCB from various lists.
 */
static void
in_pcbremlists(struct inpcb *inp)
{
	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;

	INP_INFO_WLOCK_ASSERT(pcbinfo);
	INP_WLOCK_ASSERT(inp);

	inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
	if (inp->inp_flags & INP_INHASHLIST) {
		struct inpcbport *phd = inp->inp_phd;

		INP_HASH_WLOCK(pcbinfo);
		OFP_LIST_REMOVE(inp, inp_hash);
		OFP_LIST_REMOVE(inp, inp_portlist);
		if (OFP_LIST_FIRST(&phd->phd_pcblist) == NULL) {
			OFP_LIST_REMOVE(phd, phd_hash);
			free(phd);
		}
		INP_HASH_WUNLOCK(pcbinfo);
		inp->inp_flags &= ~INP_INHASHLIST;
	}
	OFP_LIST_REMOVE(inp, inp_list);
	pcbinfo->ipi_count--;
}

/*
 * A set label operation has occurred at the socket layer, propagate the
 * label change into the in_pcb for the socket.
 */
void
ofp_in_pcbsosetlabel(struct socket *so)
{
	(void)so;
}

/*
 * in_pcb.c: manage the Protocol Control Blocks.
 *
 * NOTE: It is assumed that most of these functions will be called with
 * the pcbinfo lock held, and often, the inpcb lock held, as these utility
 * functions often modify hash chains or addresses in pcbs.
 */


text:
namespace cc {

AnimationEvent::AnimationEvent(AnimationEvent::Type type,
                               UniqueKeyframeModelId uid,
                               int group_id,
                               int target_property,
                               base::TimeTicks monotonic_time)
    : type(type),
      uid(uid),
      group_id(group_id),
      target_property(target_property),
      monotonic_time(monotonic_time),
      is_impl_only(false),
      local_time() {}

AnimationEvent::AnimationEvent(int timeline_id,
                               int animation_id,
                               absl::optional<base::TimeDelta> local_time)
    : type(TIME_UPDATED),
      // Initializing model_id with an invalid value (0).
      // Also initializing keyframe_id with 0 which in its case is a valid
      // value. However this is safe since keyframe_id and model_id are not used
      // when routing a TIME_UPDATED event.
      uid({timeline_id, animation_id, 0}),
      group_id(),
      target_property(),
      monotonic_time(),
      is_impl_only(false),
      local_time(local_time) {}

AnimationEvent::AnimationEvent(const AnimationEvent& other) {
  type = other.type;
  uid = other.uid;
  group_id = other.group_id;
  target_property = other.target_property;
  monotonic_time = other.monotonic_time;
  is_impl_only = other.is_impl_only;
  animation_start_time = other.animation_start_time;
  if (other.curve)
    curve = other.curve->Clone();
  local_time = other.local_time;
}

AnimationEvent& AnimationEvent::operator=(const AnimationEvent& other) {
  type = other.type;
  uid = other.uid;
  group_id = other.group_id;
  target_property = other.target_property;
  monotonic_time = other.monotonic_time;
  is_impl_only = other.is_impl_only;
  animation_start_time = other.animation_start_time;
  if (other.curve)
    curve = other.curve->Clone();
  local_time = other.local_time;
  return *this;
}

AnimationEvent::~AnimationEvent() = default;

AnimationEvents::AnimationEvents() : needs_time_updated_events_(false) {}

AnimationEvents::~AnimationEvents() = default;

bool AnimationEvents::IsEmpty() const {
  return events_.empty() && !needs_time_updated_events_;
}

bool AnimationEvent::ShouldDispatchToKeyframeEffectAndModel() const {
  // TIME_UPDATED events are used to synchronize effect time between cc and
  // main thread worklet animations. Keyframe models are not involved in
  // this process.
  // is_impl_only events are not dispatched because they don't have
  // corresponding main thread components.
  return type != TIME_UPDATED && !is_impl_only;
}

}  // namespace cc


text:
var centrality = require('../');
var createGraph = require('ngraph.graph');
var test = require('tap').test;

test('It finds closeness centrality', function(t) {
  var g = createGraph();
  g.addLink(1, 2);
  g.addLink(2, 3);

  var closeness = centrality.closeness(g);

  t.equal(Object.keys(closeness).length, 3, 'Three nodes considered');
  t.equal(closeness[2], 1, 'Second node centrality is 1');
  t.equal(closeness[1], closeness[3], 'First and last node have the same value');
  t.end();
});


text:
package cromwell.engine.backend.io.filesystem.gcs

import java.nio.file.OpenOption

object ContentTypeOption {
  sealed trait ContentType
  case object PlainText extends ContentType with OpenOption {
    override def toString = "plain/text"
  }
  case object Json extends ContentType with OpenOption {
    override def toString = "application/json"
  }
}


text:
<style>
    .preferenceview-category-item {
        height: 24px;
        padding-left: 10px;
        padding-top: 5px;
    }

    .preferenceview-category-item.selected {
        background-image: -moz-linear-gradient(top, #B0C2D6 0%, #9EADBE 100%);
        background-image: -webkit-linear-gradient(top, #B0C2D6 0%, #9EADBE 100%);
        background-image: -o-linear-gradient(top, #B0C2D6 0%, #9EADBE 100%);
        background-image: linear-gradient(to bottom, #B0C2D6 0%, #9EADBE 100%);
    }

    .claro .dijitSplitterV .dijitSplitterThumb {
        background: transparent;
    }

    .claro .dijitSplitterV {
        width: 2px;
    }

    .preferenceview-category-item__tree {
        width: 16px;
        height: 16px;
        display: inline-block;
        border: 0;
        padding: 0;
        vertical-align: middle;
    }
    .preferenceview-category-item__tree.expanded {
        background-image: url("./styles/images/treeExpandImages.png");
        background-position: -35px 0;
    }
    .preferenceview-category-item__tree.expanded.hover {
        background-image: url("./styles/images/treeExpandImages.png");
        background-position: -53px 0;
    }
    .preferenceview-category-item__tree.collapsed {
        background-image: url("./styles/images/treeExpandImages.png");
        background-position: 0px 0;
    }
    .preferenceview-category-item__tree.collapsed.hover {
        background-image: url("./styles/images/treeExpandImages.png");
        background-position: -18px 0;
    }
</style>


text:
//
//  BCsecp256k1.h
//  Breadcrumb
//
//  Created by Andrew Hurst on 2/11/15.
//  Copyright (c) 2015 Breadcrumb.
//
//  Distributed under the MIT software license, see the accompanying
//  file LICENSE or http://www.opensource.org/licenses/mit-license.php.
//
//

#import <Foundation/Foundation.h>
#import "tommath.h"

/*!
 @brief This is a helper class for secp256k1 functions.

 @discussion you should always use the shared instance of this class, there is
 no reason to have more than one instance of this.

 This is an abstraction of https://github.com/bitcoin/secp256k1
 */
@interface BCsecp256k1 : NSObject
#pragma mark Operations
/*!
 @brief Derives a public key for the given private key.

 @param privateKey The private key to generate the public key from.
 */
- (NSData *)publicKeyFromKey:(NSData *)privateKey compressed:(BOOL)compressed;

/*!
 @brief Signs the inputted hash with the inputed private key.

 @param hash The 32 byte hash to sign,
 @param key  The 32 byte key to sign the hash with.
 */
- (NSData *)signatureForHash:(NSData *)hash withPrivateKey:(NSData *)key;

/*!
 @brief Checks if the signature is valid given the signed data, the origin data,
 and the public key.

 @param signature The signed data.
 @param hash      The origin data before it was signed.
 @param publicKey The public key of the key pair that signed the data.
 */
- (BOOL)signature:(NSData *)signature
             originHash:(NSData *)hash
    isValidForPublicKey:(NSData *)publicKey;

#pragma mark Public Key Tweeks

- (NSData *)publicKey:(NSData *)publicKey add:(NSData *)tweek;

- (NSData *)privateKey:(NSData *)privateKey add:(NSData *)tweek;

#pragma mark Shared access

/*!
 @brief This is the instance you should use for secp256k1 operations. First call
 can take (10-100ms)

 @discussion First access of this instance allocates memory for secp256k1
 operations, upon deallocation of this instance memory for the c library will
 be also deallocated.
 */
+ (instancetype)sharedInstance;

#pragma mark Utilities
+ (NSData *)pseudoRandomDataWithLength:(NSUInteger)length;
+ (mp_int)curveOrder;
@end


text:
// Copyright (c) 2012 Ecma International.  All rights reserved.
// Ecma International makes this code available under the terms and conditions set
// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
// "Use Terms").   Any redistribution of this code must retain the above
// copyright and this notice and otherwise comply with the Use Terms.

/*---
es5id: 15.10.7.2-1
description: RegExp.prototype.global is a non-generic accessor property
includes: [runTestCase.js]
---*/

function testcase() {
  try {
    RegExp.prototype.global;
  } catch (e) {
    if (e instanceof TypeError) {
      return true;
    }
  }
  return false;
}
runTestCase(testcase);


text:
from temboo.core.choreography import Choreography
from temboo.core.choreography import InputSet
from temboo.core.choreography import ResultSet
from temboo.core.choreography import ChoreographyExecution

import json

class GetNewsletterScheduleTime(Choreography):

    def __init__(self, temboo_session):
        """
        Create a new instance of the GetNewsletterScheduleTime Choreo. A TembooSession object, containing a valid
        set of Temboo credentials, must be supplied.
        """
        Choreography.__init__(self, temboo_session, '/Library/SendGrid/NewsletterAPI/Schedule/GetNewsletterScheduleTime')

    def new_input_set(self):
        return GetNewsletterScheduleTimeInputSet()

    def _make_result_set(self, result, path):
        return GetNewsletterScheduleTimeResultSet(result, path)

    def _make_execution(self, session, exec_id, path):
        return GetNewsletterScheduleTimeChoreographyExecution(session, exec_id, path)

class GetNewsletterScheduleTimeInputSet(InputSet):
    """
    An InputSet with methods appropriate for specifying the inputs to the GetNewsletterScheduleTime
    Choreo. The InputSet object is used to specify input parameters when executing this Choreo.
    """
    def set_APIKey(self, value):
        """
        Set the value of the APIKey input for this Choreo. ((required, string) The API Key obtained from SendGrid.)
        """
        InputSet._set_input(self, 'APIKey', value)
    def set_APIUser(self, value):
        """
        Set the value of the APIUser input for this Choreo. ((required, string) The username registered with SendGrid.)
        """
        InputSet._set_input(self, 'APIUser', value)
    def set_Name(self, value):
        """
        Set the value of the Name input for this Choreo. ((required, string) The name of the newsletter for which delivery schedule information will be retrieved.)
        """
        InputSet._set_input(self, 'Name', value)
    def set_ResponseFormat(self, value):
        """
        Set the value of the ResponseFormat input for this Choreo. ((optional, string) The format of the response from SendGrid, in either json, or xml.  Default is set to json.)
        """
        InputSet._set_input(self, 'ResponseFormat', value)

class GetNewsletterScheduleTimeResultSet(ResultSet):
    """
    A ResultSet with methods tailored to the values returned by the GetNewsletterScheduleTime Choreo.
    The ResultSet object is used to retrieve the results of a Choreo execution.
    """

    def getJSONFromString(self, str):
        return json.loads(str)

    def get_Response(self):
        """
        Retrieve the value for the "Response" output from this Choreo execution. (The response from SendGrid. The format corresponds to the ResponseFormat input. Default is json.)
        """
        return self._output.get('Response', None)

class GetNewsletterScheduleTimeChoreographyExecution(ChoreographyExecution):

    def _make_result_set(self, response, path):
        return GetNewsletterScheduleTimeResultSet(response, path)