func (a *API) FetchBrokers() (*[]Broker, error) {
	result, err := a.Get(config.BrokerPrefix)
	if err != nil {
		return nil, err
	}

	var response []Broker
	if err := json.Unmarshal(result, &response); err != nil {
		return nil, err
	}

	return &response, nil
}

func ( a * API ) FetchBrokers ( ) ( * [ ] Broker , error ) { result , err := a . Get ( config . BrokerPrefix ) if err != nil { return nil , err } var response [ ] Broker if err := json . Unmarshal ( result , & response ) ; err != nil { return nil , err } return & response , nil }

// FetchBrokers returns all brokers available to the API Token.

FetchBrokers returns all brokers available to the API Token .


func (cm *CheckManager) ActivateMetric(name string) bool {
	cm.availableMetricsmu.Lock()
	defer cm.availableMetricsmu.Unlock()

	active, exists := cm.availableMetrics[name]

	if !exists {
		return true
	}

	if !active && cm.forceMetricActivation {
		return true
	}

	return false
}

func ( cm * CheckManager ) ActivateMetric ( name string ) bool { cm . availableMetricsmu . Lock ( ) defer cm . availableMetricsmu . Unlock ( ) active , exists := cm . availableMetrics [ name ] if ! exists { return true } if ! active && cm . forceMetricActivation { return true } return false }

// ActivateMetric determines if a given metric should be activated


func (cm *CheckManager) AddMetricTags(metricName string, tags []string, appendTags bool) bool {
	tagsUpdated := false

	if appendTags && len(tags) == 0 {
		return tagsUpdated
	}

	currentTags, exists := cm.metricTags[metricName]
	if !exists {
		foundMetric := false

		if cm.checkBundle != nil {
			for _, metric := range cm.checkBundle.Metrics {
				if metric.Name == metricName {
					foundMetric = true
					currentTags = metric.Tags
					break
				}
			}
		}

		if !foundMetric {
			currentTags = []string{}
		}
	}

	action := ""
	if appendTags {
		numNewTags := countNewTags(currentTags, tags)
		if numNewTags > 0 {
			action = "Added"
			currentTags = append(currentTags, tags...)
			tagsUpdated = true
		}
	} else {
		if len(tags) != len(currentTags) {
			action = "Set"
			currentTags = tags
			tagsUpdated = true
		} else {
			numNewTags := countNewTags(currentTags, tags)
			if numNewTags > 0 {
				action = "Set"
				currentTags = tags
				tagsUpdated = true
			}
		}
	}

	if tagsUpdated {
		cm.metricTags[metricName] = currentTags
	}

	if cm.Debug && action != "" {
		cm.Log.Printf("[DEBUG] %s metric tag(s) %s %v\n", action, metricName, tags)
	}

	return tagsUpdated
}

func ( cm * CheckManager ) AddMetricTags ( metricName string , tags [ ] string , appendTags bool ) bool { tagsUpdated := false if appendTags && len ( tags ) == 0 { return tagsUpdated } currentTags , exists := cm . metricTags [ metricName ] if ! exists { foundMetric := false if cm . checkBundle != nil { for _ , metric := range cm . checkBundle . Metrics { if metric . Name == metricName { foundMetric = true currentTags = metric . Tags break } } } if ! foundMetric { currentTags = [ ] string { } } } action := " " if appendTags { numNewTags := countNewTags ( currentTags , tags ) if numNewTags > 0 { action = " " currentTags = append ( currentTags , tags ... ) tagsUpdated = true } } else { if len ( tags ) != len ( currentTags ) { action = " " currentTags = tags tagsUpdated = true } else { numNewTags := countNewTags ( currentTags , tags ) if numNewTags > 0 { action = " " currentTags = tags tagsUpdated = true } } } if tagsUpdated { cm . metricTags [ metricName ] = currentTags } if cm . Debug && action != " " { cm . Log . Printf ( " \n " , action , metricName , tags ) } return tagsUpdated }

// AddMetricTags updates check bundle metrics with tags


func (cm *CheckManager) addNewMetrics(newMetrics map[string]*api.CheckBundleMetric) bool {
	updatedCheckBundle := false

	if cm.checkBundle == nil || len(newMetrics) == 0 {
		return updatedCheckBundle
	}

	cm.cbmu.Lock()
	defer cm.cbmu.Unlock()

	numCurrMetrics := len(cm.checkBundle.Metrics)
	numNewMetrics := len(newMetrics)

	if numCurrMetrics+numNewMetrics >= cap(cm.checkBundle.Metrics) {
		nm := make([]api.CheckBundleMetric, numCurrMetrics+numNewMetrics)
		copy(nm, cm.checkBundle.Metrics)
		cm.checkBundle.Metrics = nm
	}

	cm.checkBundle.Metrics = cm.checkBundle.Metrics[0 : numCurrMetrics+numNewMetrics]

	i := 0
	for _, metric := range newMetrics {
		cm.checkBundle.Metrics[numCurrMetrics+i] = *metric
		i++
		updatedCheckBundle = true
	}

	if updatedCheckBundle {
		cm.forceCheckUpdate = true
	}

	return updatedCheckBundle
}

func ( cm * CheckManager ) addNewMetrics ( newMetrics map [ string ] * api . CheckBundleMetric ) bool { updatedCheckBundle := false if cm . checkBundle == nil || len ( newMetrics ) == 0 { return updatedCheckBundle } cm . cbmu . Lock ( ) defer cm . cbmu . Unlock ( ) numCurrMetrics := len ( cm . checkBundle . Metrics ) numNewMetrics := len ( newMetrics ) if numCurrMetrics + numNewMetrics >= cap ( cm . checkBundle . Metrics ) { nm := make ( [ ] api . CheckBundleMetric , numCurrMetrics + numNewMetrics ) copy ( nm , cm . checkBundle . Metrics ) cm . checkBundle . Metrics = nm } cm . checkBundle . Metrics = cm . checkBundle . Metrics [ 0 : numCurrMetrics + numNewMetrics ] i := 0 for _ , metric := range newMetrics { cm . checkBundle . Metrics [ numCurrMetrics + i ] = * metric i ++ updatedCheckBundle = true } if updatedCheckBundle { cm . forceCheckUpdate = true } return updatedCheckBundle }

// addNewMetrics updates a check bundle with new metrics


func (cm *CheckManager) inventoryMetrics() {
	availableMetrics := make(map[string]bool)
	for _, metric := range cm.checkBundle.Metrics {
		availableMetrics[metric.Name] = metric.Status == "active"
	}
	cm.availableMetricsmu.Lock()
	cm.availableMetrics = availableMetrics
	cm.availableMetricsmu.Unlock()
}

func ( cm * CheckManager ) inventoryMetrics ( ) { availableMetrics := make ( map [ string ] bool ) for _ , metric := range cm . checkBundle . Metrics { availableMetrics [ metric . Name ] = metric . Status == " " } cm . availableMetricsmu . Lock ( ) cm . availableMetrics = availableMetrics cm . availableMetricsmu . Unlock ( ) }

// inventoryMetrics creates list of active metrics in check bundle


func countNewTags(currTags []string, newTags []string) int {
	if len(newTags) == 0 {
		return 0
	}

	if len(currTags) == 0 {
		return len(newTags)
	}

	newTagCount := 0

	for _, newTag := range newTags {
		found := false
		for _, currTag := range currTags {
			if newTag == currTag {
				found = true
				break
			}
		}
		if !found {
			newTagCount++
		}
	}

	return newTagCount
}

func countNewTags ( currTags [ ] string , newTags [ ] string ) int { if len ( newTags ) == 0 { return 0 } if len ( currTags ) == 0 { return len ( newTags ) } newTagCount := 0 for _ , newTag := range newTags { found := false for _ , currTag := range currTags { if newTag == currTag { found = true break } } if ! found { newTagCount ++ } } return newTagCount }

// countNewTags returns a count of new tags which do not exist in the current list of tags


func (rs *Ruleset) Pluralize(word string) string {
	if len(word) == 0 {
		return word
	}
	if rs.isUncountable(word) {
		return word
	}
	for _, rule := range rs.plurals {
		if rule.exact {
			if word == rule.suffix {
				return rule.replacement
			}
		} else {
			if strings.HasSuffix(word, rule.suffix) {
				return replaceLast(word, rule.suffix, rule.replacement)
			}
		}
	}
	return word + "s"
}

func ( rs * Ruleset ) Pluralize ( word string ) string { if len ( word ) == 0 { return word } if rs . isUncountable ( word ) { return word } for _ , rule := range rs . plurals { if rule . exact { if word == rule . suffix { return rule . replacement } } else { if strings . HasSuffix ( word , rule . suffix ) { return replaceLast ( word , rule . suffix , rule . replacement ) } } } return word + " " }

// returns the plural form of a singular word


func (rs *Ruleset) Singularize(word string) string {
	if len(word) == 0 {
		return word
	}
	if rs.isUncountable(word) {
		return word
	}
	for _, rule := range rs.singulars {
		if rule.exact {
			if word == rule.suffix {
				return rule.replacement
			}
		} else {
			if strings.HasSuffix(word, rule.suffix) {
				return replaceLast(word, rule.suffix, rule.replacement)
			}
		}
	}
	return word
}

func ( rs * Ruleset ) Singularize ( word string ) string { if len ( word ) == 0 { return word } if rs . isUncountable ( word ) { return word } for _ , rule := range rs . singulars { if rule . exact { if word == rule . suffix { return rule . replacement } } else { if strings . HasSuffix ( word , rule . suffix ) { return replaceLast ( word , rule . suffix , rule . replacement ) } } } return word }

// returns the singular form of a plural word


func (rs *Ruleset) Capitalize(word string) string {
	return strings.ToUpper(word[:1]) + word[1:]
}

func ( rs * Ruleset ) Capitalize ( word string ) string { return strings . ToUpper ( word [ : 1 ] ) + word [ 1 : ] }


func (rs *Ruleset) Camelize(word string) string {
	words := splitAtCaseChangeWithTitlecase(word)
	return strings.Join(words, "")
}

func ( rs * Ruleset ) Camelize ( word string ) string { words := splitAtCaseChangeWithTitlecase ( word ) return strings . Join ( words , " " ) }


func getSuitableAlgFromCurve(curve elliptic.Curve) (jwt.Algorithm, error) {
	curveBitSize := curve.Params().BitSize

	// compute curve key len
	keyLen := curveBitSize / 8
	if curveBitSize%8 > 0 {
		keyLen++
	}

	// determine alg
	var alg jwt.Algorithm
	switch 2 * keyLen {
	case 64:
		alg = jwt.ES256
	case 96:
		alg = jwt.ES384
	case 132:
		alg = jwt.ES512

	default:
		return jwt.NONE, fmt.Errorf("invalid key length %d", keyLen)
	}

	return alg, nil
}

func
getSuitableAlgFromCurve
(
curve
elliptic
.
Curve
)
(
jwt
.
Algorithm
,
error
)
{
curveBitSize
:=
curve
.
Params
(
)
.
BitSize
// compute curve key len
keyLen
:=
curveBitSize
/
8
if
curveBitSize
%
8
>
0
{
keyLen
++
}
// determine alg
var
alg
jwt
.
Algorithm
switch
2
*
keyLen
{
case
64
:
alg
=
jwt
.
ES256
case
96
:
alg
=
jwt
.
ES384
case
132
:
alg
=
jwt
.
ES512
default
:
return
jwt
.
,
fmt
.
Errorf
(
"
"
,
keyLen
)
}
return
alg
,
}

// getSuitableAlgFromCurve inspects the key length in curve, and determines the
// corresponding jwt.Algorithm.

getSuitableAlgFromCurve inspects the key length in curve and determines the corresponding jwt . Algorithm .


func getAlgFromKeyData(pem pemutil.Store) (jwt.Algorithm, error) {
	for _, v := range pem {
		// loop over crypto primitives in pemstore, and do type assertion. if
		// ecdsa.{PublicKey,PrivateKey} found, then use corresponding ESXXX as
		// algo. if rsa, then use DefaultRSAAlgorithm. if []byte, then use
		// DefaultHMACAlgorithm.
		switch k := v.(type) {
		case []byte:
			return jwt.HS512, nil

		case *ecdsa.PrivateKey:
			return getSuitableAlgFromCurve(k.Curve)

		case *ecdsa.PublicKey:
			return getSuitableAlgFromCurve(k.Curve)

		case *rsa.PrivateKey:
			return jwt.PS512, nil

		case *rsa.PublicKey:
			return jwt.PS512, nil
		}
	}

	return jwt.NONE, errors.New("cannot determine key type")
}

// getAlgFromKeyData determines the best jwt.Algorithm suitable based on the
// set of given crypto primitives in pem.

getAlgFromKeyData determines the best jwt . Algorithm suitable based on the set of given crypto primitives in pem .


func buildEncArgs(args []string) ([]byte, error) {
	m := make(map[string]interface{})

	// loop over args, splitting on '=', and attempt parsing of value
	for _, arg := range args {
		a := strings.SplitN(arg, "=", 2)
		var val interface{}

		// attempt to parse
		if len(a) == 1 { // assume bool, set as true
			val = true
		} else if u, err := strconv.ParseUint(a[1], 10, 64); err == nil {
			val = u
		} else if i, err := strconv.ParseInt(a[1], 10, 64); err == nil {
			val = i
		} else if f, err := strconv.ParseFloat(a[1], 64); err == nil {
			val = f
		} else if b, err := strconv.ParseBool(a[1]); err == nil {
			val = b
		} else if s, err := strconv.Unquote(a[1]); err == nil {
			val = s
		} else { // treat as string
			val = a[1]
		}

		m[a[0]] = val
	}

	return json.Marshal(m)
}

// buildEncArgs builds and encodes passed argument strings in the form of
// name=val as a json object.

buildEncArgs builds and encodes passed argument strings in the form of name = val as a json object .


func doDec(signer jwt.Signer, in []byte) ([]byte, error) {
	var err error

	// decode token
	ut := UnstructuredToken{}
	err = signer.Decode(bytes.TrimSpace(in), &ut)
	if err != nil {
		return nil, err
	}

	// pretty format output
	out, err := json.MarshalIndent(&ut, "", "  ")
	if err != nil {
		return nil, err
	}

	return out, nil
}

func
doDec
(
signer
jwt
.
Signer
,
in
[
]
byte
)
(
[
]
byte
,
error
)
{
var
err
error
// decode token
ut
:=
UnstructuredToken
{
}
err
=
signer
.
Decode
(
bytes
.
TrimSpace
(
in
)
,
&
ut
)
if
err
!=
{
return
,
err
}
// pretty format output
out
,
err
:=
json
.
MarshalIndent
(
&
ut
,
"
"
,
"
"
)
if
err
!=
{
return
,
err
}
return
out
,
}


func doEnc(signer jwt.Signer, in []byte) ([]byte, error) {
	var err error

	// make sure its valid json first
	m := make(map[string]interface{})

	// do the initial decode
	d := json.NewDecoder(bytes.NewBuffer(in))
	d.UseNumber()
	err = d.Decode(&m)
	if err != nil {
		return nil, err
	}

	// encode claims
	out, err := signer.Encode(&m)
	if err != nil {
		return nil, err
	}

	return out, nil
}

func
doEnc
(
signer
jwt
.
Signer
,
in
[
]
byte
)
(
[
]
byte
,
error
)
{
var
err
error
// make sure its valid json first
m
:=
make
(
map
[
string
]
interface
{
}
)
// do the initial decode
d
:=
json
.
NewDecoder
(
bytes
.
NewBuffer
(
in
)
)
d
.
UseNumber
(
)
err
=
d
.
Decode
(
&
m
)
if
err
!=
{
return
,
err
}
// encode claims
out
,
err
:=
signer
.
Encode
(
&
m
)
if
err
!=
{
return
,
err
}
return
out
,
}

// doEnc encodes in as the payload in a JWT.

doEnc encodes in as the payload in a JWT .


func Transport(transport http.RoundTripper) Option {
	return func(gsa *GServiceAccount) error {
		gsa.transport = transport
		return nil
	}
}

func Transport ( transport http . RoundTripper ) Option { return func ( gsa * GServiceAccount ) error { gsa . transport = transport return nil } }

// Transport is a GServiceAccount option to set the client transport used by
// the token source.

Transport is a GServiceAccount option to set the client transport used by the token source .


func Proxy(proxy string) Option {
	return func(gsa *GServiceAccount) error {
		u, err := url.Parse(proxy)
		if err != nil {
			return err
		}
		return Transport(&http.Transport{
			Proxy: http.ProxyURL(u),
		})(gsa)
	}
}

func Proxy ( proxy string ) Option { return func ( gsa * GServiceAccount ) error { u , err := url . Parse ( proxy ) if err != nil { return err } return Transport ( & http . Transport { Proxy : http . ProxyURL ( u ) , } ) ( gsa ) } }

// Proxy is a GServiceAccount option to set a HTTP proxy used for by the token
// source.

Proxy is a GServiceAccount option to set a HTTP proxy used for by the token source .


func Expiration(expiration time.Duration) Option {
	return func(gsa *GServiceAccount) error {
		gsa.expiration = expiration
		return nil
	}
}

func Expiration ( expiration time . Duration ) Option { return func ( gsa * GServiceAccount ) error { gsa . expiration = expiration return nil } }

// Expiration is a GServiceAccount option to set a expiration limit for tokens
// generated from the token source.

Expiration is a GServiceAccount option to set a expiration limit for tokens generated from the token source .


func Encode(alg Algorithm, signer Signer, obj interface{}) ([]byte, error) {
	var err error

	// grab encode targets
	headerObj, payloadObj, err := encodeTargets(alg, obj)
	if err != nil {
		return nil, err
	}

	// json encode header
	header, err := json.Marshal(headerObj)
	if err != nil {
		return nil, err
	}

	// b64 encode playload
	headerEnc := make([]byte, b64.EncodedLen(len(header)))
	b64.Encode(headerEnc, header)

	// json encode payload
	payload, err := json.Marshal(payloadObj)
	if err != nil {
		return nil, err
	}

	// b64 encode playload
	payloadEnc := make([]byte, b64.EncodedLen(len(payload)))
	b64.Encode(payloadEnc, payload)

	// allocate result
	var buf bytes.Buffer

	// add header
	_, err = buf.Write(headerEnc)
	if err != nil {
		return nil, err
	}

	// add 1st separator
	_, err = buf.Write(tokenSep)
	if err != nil {
		return nil, err
	}

	// add payload
	_, err = buf.Write(payloadEnc)
	if err != nil {
		return nil, err
	}

	// sign
	sig, err := signer.Sign(buf.Bytes())
	if err != nil {
		return nil, err
	}

	// add 2nd separator
	_, err = buf.Write(tokenSep)
	if err != nil {
		return nil, err
	}

	// add sig
	_, err = buf.Write(sig)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

func
Encode
(
alg
Algorithm
,
signer
Signer
,
obj
interface
{
}
)
(
[
]
byte
,
error
)
{
var
err
error
// grab encode targets
headerObj
,
payloadObj
,
err
:=
encodeTargets
(
alg
,
obj
)
if
err
!=
{
return
,
err
}
// json encode header
header
,
err
:=
json
.
Marshal
(
headerObj
)
if
err
!=
{
return
,
err
}
// b64 encode playload
headerEnc
:=
make
(
[
]
byte
,
b64
.
EncodedLen
(
len
(
header
)
)
)
b64
.
Encode
(
headerEnc
,
header
)
// json encode payload
payload
,
err
:=
json
.
Marshal
(
payloadObj
)
if
err
!=
{
return
,
err
}
// b64 encode playload
payloadEnc
:=
make
(
[
]
byte
,
b64
.
EncodedLen
(
len
(
payload
)
)
)
b64
.
Encode
(
payloadEnc
,
payload
)
// allocate result
var
buf
bytes
.
Buffer
// add header
_
,
err
=
buf
.
Write
(
headerEnc
)
if
err
!=
{
return
,
err
}
// add 1st separator
_
,
err
=
buf
.
Write
(
tokenSep
)
if
err
!=
{
return
,
err
}
// add payload
_
,
err
=
buf
.
Write
(
payloadEnc
)
if
err
!=
{
return
,
err
}
// sign
sig
,
err
:=
signer
.
Sign
(
buf
.
Bytes
(
)
)
if
err
!=
{
return
,
err
}
// add 2nd separator
_
,
err
=
buf
.
Write
(
tokenSep
)
if
err
!=
{
return
,
err
}
// add sig
_
,
err
=
buf
.
Write
(
sig
)
if
err
!=
{
return
,
err
}
return
buf
.
Bytes
(
)
,
}

// Encode encodes a JWT using the Algorithm and Signer, returning the URL-safe
// encoded token or any errors encountered during encoding.

Encode encodes a JWT using the Algorithm and Signer returning the URL - safe encoded token or any errors encountered during encoding .


func PeekHeaderField(buf []byte, field string) (string, error) {
	return peekField(buf, field, tokenPositionHeader)
}

func PeekHeaderField ( buf [ ] byte , field string ) ( string , error ) { return peekField ( buf , field , tokenPositionHeader ) }

// PeekHeaderField extracts the specified field from the serialized JWT buf's
// header. An error will be returned if the field is not present in the decoded
// header.

PeekHeaderField extracts the specified field from the serialized JWT buf s header . An error will be returned if the field is not present in the decoded header .


func PeekAlgorithm(buf []byte) (Algorithm, error) {
	alg := NONE

	// get alg
	algVal, err := PeekHeaderField(buf, "alg")
	if err != nil {
		return NONE, err
	}

	// decode alg
	err = (&alg).UnmarshalText([]byte(algVal))
	if err != nil {
		return NONE, err
	}

	return alg, nil
}

func
PeekAlgorithm
(
buf
[
]
byte
)
(
Algorithm
,
error
)
{
alg
:=
// get alg
algVal
,
err
:=
PeekHeaderField
(
buf
,
"
"
)
if
err
!=
{
return
,
err
}
// decode alg
err
=
(
&
alg
)
.
UnmarshalText
(
[
]
byte
(
algVal
)
)
if
err
!=
{
return
,
err
}
return
alg
,
}

// PeekAlgorithm extracts the signing algorithm listed in the "alg" field of
// the serialized JWT buf's header and attempts to unmarshal it into an
// Algorithm. An error will be returned if the alg field is not specified in
// the JWT header, or is otherwise invalid.

PeekAlgorithm extracts the signing algorithm listed in the alg field of the serialized JWT buf s header and attempts to unmarshal it into an Algorithm . An error will be returned if the alg field is not specified in the JWT header or is otherwise invalid .


func PeekAlgorithmAndIssuer(buf []byte) (Algorithm, string, error) {
	var err error

	// get algorithm
	alg, err := PeekAlgorithm(buf)
	if err != nil {
		return NONE, "", err
	}

	// get issuer
	issuer, err := PeekPayloadField(buf, "iss")
	if err != nil {
		return NONE, "", err
	}

	return alg, issuer, nil
}

func
PeekAlgorithmAndIssuer
(
buf
[
]
byte
)
(
Algorithm
,
string
,
error
)
{
var
err
error
// get algorithm
alg
,
err
:=
PeekAlgorithm
(
buf
)
if
err
!=
{
return
,
"
"
,
err
}
// get issuer
issuer
,
err
:=
PeekPayloadField
(
buf
,
"
"
)
if
err
!=
{
return
,
"
"
,
err
}
return
alg
,
issuer
,
}

// PeekAlgorithmAndIssuer extracts the signing algorithm listed in the "alg"
// field and the issuer from the "iss" field of the serialized JWT buf's header
// and payload, attempting to unmarshal alg to Algorithm and iss to a string.
// An error will be returned if the Algorithm or Issuer fields are not
// specified in the JWT header and payload, or are otherwise invalid.

PeekAlgorithmAndIssuer extracts the signing algorithm listed in the alg field and the issuer from the iss field of the serialized JWT buf s header and payload attempting to unmarshal alg to Algorithm and iss to a string . An error will be returned if the Algorithm or Issuer fields are not specified in the JWT header and payload or are otherwise invalid .


func NewEllipticSigner(alg Algorithm, curve elliptic.Curve) func(Store, crypto.Hash) (Signer, error) {
	curveBitSize := curve.Params().BitSize

	// precompute curve key len
	keyLen := curveBitSize / 8
	if curveBitSize%8 > 0 {
		keyLen++
	}

	return func(store Store, hash crypto.Hash) (Signer, error) {
		var ok bool
		var privRaw, pubRaw interface{}
		var priv *ecdsa.PrivateKey
		var pub *ecdsa.PublicKey

		// check private key
		if privRaw, ok = store.PrivateKey(); ok {
			if priv, ok = privRaw.(*ecdsa.PrivateKey); !ok {
				return nil, ErrInvalidPrivateKey
			}

			// check curve type matches private key curve type
			if curveBitSize != priv.Curve.Params().BitSize {
				return nil, ErrInvalidPrivateKeySize
			}
		}

		// check public key
		if pubRaw, ok = store.PublicKey(); ok {
			if pub, ok = pubRaw.(*ecdsa.PublicKey); !ok {
				return nil, ErrInvalidPublicKey
			}
		}

		// check that either a private or public key has been provided
		if priv == nil && pub == nil {
			return nil, ErrMissingPrivateOrPublicKey
		}

		return &EccSigner{
			alg:    alg,
			curve:  curve,
			hash:   hash,
			priv:   priv,
			pub:    pub,
			keyLen: keyLen,
		}, nil
	}
}

// NewEllipticSigner creates an Elliptic Curve Signer for the specified curve.

NewEllipticSigner creates an Elliptic Curve Signer for the specified curve .


func NewTokenSource(signer jwt.Signer, tokenURL string, ctxt context.Context, opts ...Option) (*Bearer, error) {
	var err error

	b := &Bearer{
		signer:   signer,
		tokenURL: tokenURL,
		context:  ctxt,
		claims:   make(map[string]interface{}),
	}

	// apply opts
	for _, o := range opts {
		if err = o(b); err != nil {
			return nil, fmt.Errorf("jwt/bearer: %v", err)
		}
	}

	return b, nil
}

func
NewTokenSource
(
signer
jwt
.
Signer
,
tokenURL
string
,
ctxt
context
.
Context
,
opts
...
Option
)
(
*
Bearer
,
error
)
{
var
err
error
b
:=
&
Bearer
{
signer
:
signer
,
tokenURL
:
tokenURL
,
context
:
ctxt
,
claims
:
make
(
map
[
string
]
interface
{
}
)
,
}
// apply opts
for
_
,
o
:=
range
opts
{
if
err
=
o
(
b
)
;
err
!=
{
return
,
fmt
.
Errorf
(
"
"
,
err
)
}
}
return
b
,
}

// NewTokenSource creates a oauth2.TokenSource that generates auth tokens
// redeemed using the JWT Bearer Grant assertion auth flow using the supplied
// jwt.Signer. A token redemption will be invoked at the tokenURL using the
// supplied context.
//
// Use the Claim option to pass additional claims to the token source.

NewTokenSource creates a oauth2 . TokenSource that generates auth tokens redeemed using the JWT Bearer Grant assertion auth flow using the supplied jwt . Signer . A token redemption will be invoked at the tokenURL using the supplied context . Use the Claim option to pass additional claims to the token source .


func (b *Bearer) Client() *http.Client {
	return &http.Client{
		Transport: &oauth2.Transport{
			Source: b,
		},
	}
}

func ( b * Bearer ) Client ( ) * http . Client { return & http . Client { Transport : & oauth2 . Transport { Source : b , } , } }

// Client returns a HTTP client using the bearer token.

Client returns a HTTP client using the bearer token .


func (r RSAMethod) Sign(rand io.Reader, priv *rsa.PrivateKey, hash crypto.Hash, buf []byte) ([]byte, error) {
	return r.SignFunc(rand, priv, hash, buf)
}

func ( r RSAMethod ) Sign ( rand io . Reader , priv * rsa . PrivateKey , hash crypto . Hash , buf [ ] byte ) ( [ ] byte , error ) { return r . SignFunc ( rand , priv , hash , buf ) }

// Sign signs the data in buf using rand, priv and hash.

Sign signs the data in buf using rand priv and hash .


func (r RSAMethod) Verify(pub *rsa.PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
	return r.VerifyFunc(pub, hash, hashed, sig)
}

func ( r RSAMethod ) Verify ( pub * rsa . PublicKey , hash crypto . Hash , hashed [ ] byte , sig [ ] byte ) error { return r . VerifyFunc ( pub , hash , hashed , sig ) }

// Verify verifies the signature sig against using pub, hash, and the hashed
// data.

Verify verifies the signature sig against using pub hash and the hashed data .


func NewRSASigner(alg Algorithm, method RSASignerVerifier) func(Store, crypto.Hash) (Signer, error) {
	return func(store Store, hash crypto.Hash) (Signer, error) {
		var ok bool
		var privRaw, pubRaw interface{}
		var priv *rsa.PrivateKey
		var pub *rsa.PublicKey

		// check private key
		if privRaw, ok = store.PrivateKey(); ok {
			if priv, ok = privRaw.(*rsa.PrivateKey); !ok {
				return nil, ErrInvalidPrivateKey
			}

			// check private key length
			if priv.N.BitLen() < RSAMinimumBitLen {
				return nil, ErrInvalidPrivateKeySize
			}
		}

		// check public key
		if pubRaw, ok = store.PublicKey(); ok {
			if pub, ok = pubRaw.(*rsa.PublicKey); !ok {
				return nil, ErrInvalidPublicKey
			}

			// check public key length
			if pub.N.BitLen() < RSAMinimumBitLen {
				return nil, ErrInvalidPublicKeySize
			}
		}

		// check that either a private or public key has been provided
		if priv == nil && pub == nil {
			return nil, ErrMissingPrivateOrPublicKey
		}

		return &RSASigner{
			alg:    alg,
			method: method,
			hash:   hash,
			priv:   priv,
			pub:    pub,
		}, nil
	}
}

// NewRSASigner creates an RSA Signer for the specified Algorithm and provided
// low level RSA implementation.

NewRSASigner creates an RSA Signer for the specified Algorithm and provided low level RSA implementation .


func getFieldWithTag(obj interface{}, tagName string) *reflect.Value {
	objVal := reflect.ValueOf(obj)
	if objVal.Kind() != reflect.Struct {
		objVal = objVal.Elem()
	}

	for i := 0; i < objVal.NumField(); i++ {
		fieldType := objVal.Type().Field(i)
		if tagName == fieldType.Tag.Get("jwt") {
			field := objVal.Field(i)
			return &field
		}
	}

	return nil
}

func getFieldWithTag ( obj interface { } , tagName string ) * reflect . Value { objVal := reflect . ValueOf ( obj ) if objVal . Kind ( ) != reflect . Struct { objVal = objVal . Elem ( ) } for i := 0 ; i < objVal . NumField ( ) ; i ++ { fieldType := objVal . Type ( ) . Field ( i ) if tagName == fieldType . Tag . Get ( " " ) { field := objVal . Field ( i ) return & field } } return nil }

// getFieldWithTag lookups jwt tag, with specified tagName on obj, returning
// its reflected value.

getFieldWithTag lookups jwt tag with specified tagName on obj returning its reflected value .


func decodeToObjOrFieldWithTag(buf []byte, obj interface{}, tagName string, defaultObj interface{}) error {
	// reflect values
	objValElem := reflect.ValueOf(obj).Elem()
	defaultObjValElem := reflect.ValueOf(defaultObj).Elem()

	// first check type, if same type, then set
	if objValElem.Type() == defaultObjValElem.Type() {
		objValElem.Set(defaultObjValElem)
		return nil
	}

	// get field with specified jwt tagName (if any)
	fieldVal := getFieldWithTag(obj, tagName)
	if fieldVal != nil {
		// check field type and defaultObj type, if same, set
		if fieldVal.Type() == defaultObjValElem.Type() {
			fieldVal.Set(defaultObjValElem)
			return nil
		}

		// otherwise, assign obj address of field
		obj = fieldVal.Addr().Interface()
	}

	// decode json
	d := json.NewDecoder(bytes.NewBuffer(buf))
	d.UseNumber()
	return d.Decode(obj)
}

// decodeToObjOrFieldWithTag decodes the buf into obj's field having the
// specified jwt tagName. If the provided obj's has the same type as
// defaultObj, then the obj is set to the defaultObj, otherwise an attempt is
// made to json.Decode the buf into obj.

decodeToObjOrFieldWithTag decodes the buf into obj s field having the specified jwt tagName . If the provided obj s has the same type as defaultObj then the obj is set to the defaultObj otherwise an attempt is made to json . Decode the buf into obj .


func grabEncodeTargets(alg Algorithm, obj interface{}) (interface{}, interface{}, error) {
	var headerObj, payloadObj interface{}

	// get header
	if headerVal := getFieldWithTag(obj, "header"); headerVal != nil {
		headerObj = headerVal.Interface()
	}
	if headerObj == nil {
		headerObj = alg.Header()
	}

	// get payload
	if payloadVal := getFieldWithTag(obj, "payload"); payloadVal != nil {
		payloadObj = payloadVal.Interface()
	}
	if payloadObj == nil {
		payloadObj = obj
	}

	return headerObj, payloadObj, nil
}

func
grabEncodeTargets
(
alg
Algorithm
,
obj
interface
{
}
)
(
interface
{
}
,
interface
{
}
,
error
)
{
var
headerObj
,
payloadObj
interface
{
}
// get header
if
headerVal
:=
getFieldWithTag
(
obj
,
"
"
)
;
headerVal
!=
{
headerObj
=
headerVal
.
Interface
(
)
}
if
headerObj
==
{
headerObj
=
alg
.
Header
(
)
}
// get payload
if
payloadVal
:=
getFieldWithTag
(
obj
,
"
"
)
;
payloadVal
!=
{
payloadObj
=
payloadVal
.
Interface
(
)
}
if
payloadObj
==
{
payloadObj
=
obj
}
return
headerObj
,
payloadObj
,
}

// grabEncodeTargets grabs the fields for the obj.

grabEncodeTargets grabs the fields for the obj .


func encodeTargets(alg Algorithm, obj interface{}) (interface{}, interface{}, error) {
	// determine what to encode
	switch val := obj.(type) {
	case *Token:
		return val.Header, val.Payload, nil
	}

	objVal := reflect.ValueOf(obj)
	objKind := objVal.Kind()
	if objKind == reflect.Struct || (objKind == reflect.Ptr && objVal.Elem().Kind() == reflect.Struct) {
		return grabEncodeTargets(alg, obj)
	}

	return alg.Header(), obj, nil
}

func
encodeTargets
(
alg
Algorithm
,
obj
interface
{
}
)
(
interface
{
}
,
interface
{
}
,
error
)
{
// determine what to encode
switch
val
:=
obj
.
(
type
)
{
case
*
Token
:
return
val
.
Header
,
val
.
Payload
,
}
objVal
:=
reflect
.
ValueOf
(
obj
)
objKind
:=
objVal
.
Kind
(
)
if
objKind
==
reflect
.
Struct
||
(
objKind
==
reflect
.
Ptr
&&
objVal
.
Elem
(
)
.
Kind
(
)
==
reflect
.
Struct
)
{
return
grabEncodeTargets
(
alg
,
obj
)
}
return
alg
.
Header
(
)
,
obj
,
}

// encodeTargets determines what to encode.

encodeTargets determines what to encode .


func peekField(buf []byte, fieldName string, pos tokenPosition) (string, error) {
	var err error

	// split token
	ut := UnverifiedToken{}
	err = DecodeUnverifiedToken(buf, &ut)
	if err != nil {
		return "", err
	}

	// determine position decode
	var typ string
	var b []byte
	switch pos {
	case tokenPositionHeader:
		typ = "header"
		b = ut.Header
	case tokenPositionPayload:
		typ = "payload"
		b = ut.Payload

	default:
		return "", fmt.Errorf("invalid field %d", pos)
	}

	// b64 decode
	dec, err := b64.DecodeString(string(b))
	if err != nil {
		return "", fmt.Errorf("could not decode token %s", typ)
	}

	// json decode
	m := make(map[string]interface{})
	err = json.Unmarshal(dec, &m)
	if err != nil {
		return "", err
	}

	if val, ok := m[fieldName]; ok {
		return fmt.Sprintf("%v", val), nil
	}

	return "", fmt.Errorf("token %s field %s not present or invalid", typ, fieldName)
}

func
peekField
(
buf
[
]
byte
,
fieldName
string
,
pos
tokenPosition
)
(
string
,
error
)
{
var
err
error
// split token
ut
:=
UnverifiedToken
{
}
err
=
DecodeUnverifiedToken
(
buf
,
&
ut
)
if
err
!=
{
return
"
"
,
err
}
// determine position decode
var
typ
string
var
b
[
]
byte
switch
pos
{
case
tokenPositionHeader
:
typ
=
"
"
b
=
ut
.
Header
case
tokenPositionPayload
:
typ
=
"
"
b
=
ut
.
Payload
default
:
return
"
"
,
fmt
.
Errorf
(
"
"
,
pos
)
}
// b64 decode
dec
,
err
:=
b64
.
DecodeString
(
string
(
b
)
)
if
err
!=
{
return
"
"
,
fmt
.
Errorf
(
"
"
,
typ
)
}
// json decode
m
:=
make
(
map
[
string
]
interface
{
}
)
err
=
json
.
Unmarshal
(
dec
,
&
m
)
if
err
!=
{
return
"
"
,
err
}
if
val
,
ok
:=
m
[
fieldName
]
;
ok
{
return
fmt
.
Sprintf
(
"
"
,
val
)
,
}
return
"
"
,
fmt
.
Errorf
(
"
"
,
typ
,
fieldName
)
}

// peekField looks at an undecoded JWT, JSON decoding the data at pos, and
// returning the specified field's value as string.
//
// If the fieldName is not present, then an error will be returned.

peekField looks at an undecoded JWT JSON decoding the data at pos and returning the specified field s value as string . If the fieldName is not present then an error will be returned .


func ExpiresIn(d time.Duration) Option {
	return func(tok *Bearer) error {
		if d != 0 {
			tok.addExpiration = true
			tok.expiresIn = d
		} else {
			tok.addExpiration = false
			tok.expiresIn = 0
		}

		return nil
	}
}

func ExpiresIn ( d time . Duration ) Option { return func ( tok * Bearer ) error { if d != 0 { tok . addExpiration = true tok . expiresIn = d } else { tok . addExpiration = false tok . expiresIn = 0 } return nil } }

// ExpiresIn is an option that will set the expiration duration generated for
// tokens to the specified duration.

ExpiresIn is an option that will set the expiration duration generated for tokens to the specified duration .


func Claim(name string, v interface{}) Option {
	return func(tok *Bearer) error {
		if tok.claims == nil {
			return errors.New("attempting to add claim to improperly created token")
		}

		tok.claims[name] = v

		return nil
	}
}

func Claim ( name string , v interface { } ) Option { return func ( tok * Bearer ) error { if tok . claims == nil { return errors . New ( " " ) } tok . claims [ name ] = v return nil } }

// Claim is an option that adds an additional claim that is generated with the
// token.

Claim is an option that adds an additional claim that is generated with the token .


func Transport(transport http.RoundTripper) Option {
	return func(tok *Bearer) error {
		tok.transport = transport
		return nil
	}
}

func Transport ( transport http . RoundTripper ) Option { return func ( tok * Bearer ) error { tok . transport = transport return nil } }

// Transport is an option that sets an underlying client transport to the
// exchange process.

Transport is an option that sets an underlying client transport to the exchange process .


func NewHMACSigner(alg Algorithm) func(Store, crypto.Hash) (Signer, error) {
	return func(store Store, hash crypto.Hash) (Signer, error) {
		var ok bool
		var keyRaw interface{}
		var key []byte

		// check private key
		if keyRaw, ok = store.PrivateKey(); !ok {
			return nil, ErrMissingPrivateKey
		}

		// check key type
		if key, ok = keyRaw.([]byte); !ok {
			return nil, ErrInvalidPrivateKey
		}

		return &HmacSigner{
			alg:  alg,
			hash: hash,
			key:  key,
		}, nil
	}
}

func
NewHMACSigner
(
alg
Algorithm
)
func
(
Store
,
crypto
.
Hash
)
(
Signer
,
error
)
{
return
func
(
store
Store
,
hash
crypto
.
Hash
)
(
Signer
,
error
)
{
var
ok
bool
var
keyRaw
interface
{
}
var
key
[
]
byte
// check private key
if
keyRaw
,
ok
=
store
.
PrivateKey
(
)
;
!
ok
{
return
,
ErrMissingPrivateKey
}
// check key type
if
key
,
ok
=
keyRaw
.
(
[
]
byte
)
;
!
ok
{
return
,
ErrInvalidPrivateKey
}
return
&
HmacSigner
{
alg
:
alg
,
hash
:
hash
,
key
:
key
,
}
,
}
}

// NewHMACSigner creates a HMAC Signer for the specified Algorithm.

NewHMACSigner creates a HMAC Signer for the specified Algorithm .


func FromJSON(buf []byte, opts ...Option) (*GServiceAccount, error) {
	var err error

	// unmarshal
	gsa := new(GServiceAccount)
	if err = json.Unmarshal(buf, gsa); err != nil {
		return nil, err
	}

	// apply opts
	for _, o := range opts {
		if err = o(gsa); err != nil {
			return nil, err
		}
	}

	return gsa, nil
}

func
FromJSON
(
buf
[
]
byte
,
opts
...
Option
)
(
*
GServiceAccount
,
error
)
{
var
err
error
// unmarshal
gsa
:=
new
(
GServiceAccount
)
if
err
=
json
.
Unmarshal
(
buf
,
gsa
)
;
err
!=
{
return
,
err
}
// apply opts
for
_
,
o
:=
range
opts
{
if
err
=
o
(
gsa
)
;
err
!=
{
return
,
err
}
}
return
gsa
,
}

// FromJSON loads service account credentials from the JSON encoded buf.

FromJSON loads service account credentials from the JSON encoded buf .


func FromReader(r io.Reader, opts ...Option) (*GServiceAccount, error) {
	buf, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}

	return FromJSON(buf, opts...)
}

func FromReader ( r io . Reader , opts ... Option ) ( * GServiceAccount , error ) { buf , err := ioutil . ReadAll ( r ) if err != nil { return nil , err } return FromJSON ( buf , opts ... ) }

// FromReader loads Google service account credentials from a reader.

FromReader loads Google service account credentials from a reader .


func FromFile(path string, opts ...Option) (*GServiceAccount, error) {
	buf, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	return FromJSON(buf, opts...)
}

func FromFile ( path string , opts ... Option ) ( * GServiceAccount , error ) { buf , err := ioutil . ReadFile ( path ) if err != nil { return nil , err } return FromJSON ( buf , opts ... ) }

// FromFile loads Google service account credentials from a reader.

FromFile loads Google service account credentials from a reader .


func (gsa *GServiceAccount) Signer() (jwt.Signer, error) {
	gsa.mu.Lock()
	defer gsa.mu.Unlock()

	if gsa.signer == nil {
		keyset, err := pemutil.DecodeBytes([]byte(gsa.PrivateKey))
		if err != nil {
			return nil, fmt.Errorf("jwt/gserviceaccount: could not decode private key: %v", err)
		}
		keyset.AddPublicKeys()

		s, err := DefaultAlgorithm.New(keyset)
		if err != nil {
			return nil, err
		}
		gsa.signer = s
	}

	return gsa.signer, nil
}

func ( gsa * GServiceAccount ) Signer ( ) ( jwt . Signer , error ) { gsa . mu . Lock ( ) defer gsa . mu . Unlock ( ) if gsa . signer == nil { keyset , err := pemutil . DecodeBytes ( [ ] byte ( gsa . PrivateKey ) ) if err != nil { return nil , fmt . Errorf ( " " , err ) } keyset . AddPublicKeys ( ) s , err := DefaultAlgorithm . New ( keyset ) if err != nil { return nil , err } gsa . signer = s } return gsa . signer , nil }

// Signer returns a jwt.Signer for use when signing tokens.

Signer returns a jwt . Signer for use when signing tokens .


func (alg Algorithm) Encode(signer Signer, obj interface{}) ([]byte, error) {
	return Encode(alg, signer, obj)
}

func ( alg Algorithm ) Encode ( signer Signer , obj interface { } ) ( [ ] byte , error ) { return Encode ( alg , signer , obj ) }

// Encode serializes a JWT using the Algorithm and Signer.

Encode serializes a JWT using the Algorithm and Signer .


func (alg *Algorithm) UnmarshalText(buf []byte) error {
	switch string(buf) {
	// hmac
	case "HS256":
		*alg = HS256
	case "HS384":
		*alg = HS384
	case "HS512":
		*alg = HS512

	// rsa-pkcs1v15
	case "RS256":
		*alg = RS256
	case "RS384":
		*alg = RS384
	case "RS512":
		*alg = RS512

	// ecc
	case "ES256":
		*alg = ES256
	case "ES384":
		*alg = ES384
	case "ES512":
		*alg = ES512

	// rsa-pss
	case "PS256":
		*alg = PS256
	case "PS384":
		*alg = PS384
	case "PS512":
		*alg = PS512

	// error
	default:
		return ErrInvalidAlgorithm
	}

	return nil
}

func
(
alg
*
Algorithm
)
UnmarshalText
(
buf
[
]
byte
)
error
{
switch
string
(
buf
)
{
// hmac
case
"
"
:
*
alg
=
HS256
case
"
"
:
*
alg
=
HS384
case
"
"
:
*
alg
=
HS512
// rsa-pkcs1v15
case
"
"
:
*
alg
=
RS256
case
"
"
:
*
alg
=
RS384
case
"
"
:
*
alg
=
RS512
// ecc
case
"
"
:
*
alg
=
ES256
case
"
"
:
*
alg
=
ES384
case
"
"
:
*
alg
=
ES512
// rsa-pss
case
"
"
:
*
alg
=
PS256
case
"
"
:
*
alg
=
PS384
case
"
"
:
*
alg
=
PS512
// error
default
:
return
ErrInvalidAlgorithm
}
return
}

// UnmarshalText attempts to unmarshal buf into an Algorithm.

UnmarshalText attempts to unmarshal buf into an Algorithm .


func DecodeUnverifiedToken(buf []byte, ut *UnverifiedToken) error {
	b := bytes.Split(buf, tokenSep)
	if len(b) != 3 {
		return ErrInvalidToken
	}

	ut.Header = b[0]
	ut.Payload = b[1]
	ut.Signature = b[2]

	return nil
}

func DecodeUnverifiedToken ( buf [ ] byte , ut * UnverifiedToken ) error { b := bytes . Split ( buf , tokenSep ) if len ( b ) != 3 { return ErrInvalidToken } ut . Header = b [ 0 ] ut . Payload = b [ 1 ] ut . Signature = b [ 2 ] return nil }

// DecodeUnverifiedToken decodes a token into the provided UnverifiedToken.

DecodeUnverifiedToken decodes a token into the provided UnverifiedToken .


func (ks *Keystore) PublicKey() (crypto.PublicKey, bool) {
	ks.rw.RLock()
	key, pub := ks.Key, ks.PubKey
	ks.rw.RUnlock()
	if pub != nil {
		return pub, true
	}

	// generate the public key
	if key != nil {
		ks.rw.Lock()
		defer ks.rw.Unlock()

		if x, ok := key.(interface {
			Public() crypto.PublicKey
		}); ok {
			ks.PubKey = x.Public()
		}

		return ks.PubKey, ks.PubKey != nil
	}

	return nil, false
}

func
(
ks
*
Keystore
)
PublicKey
(
)
(
crypto
.
PublicKey
,
bool
)
{
ks
.
rw
.
RLock
(
)
key
,
pub
:=
ks
.
Key
,
ks
.
PubKey
ks
.
rw
.
RUnlock
(
)
if
pub
!=
{
return
pub
,
true
}
// generate the public key
if
key
!=
{
ks
.
rw
.
Lock
(
)
defer
ks
.
rw
.
Unlock
(
)
if
x
,
ok
:=
key
.
(
interface
{
Public
(
)
crypto
.
PublicKey
}
)
;
ok
{
ks
.
PubKey
=
x
.
Public
(
)
}
return
ks
.
PubKey
,
ks
.
PubKey
!=
}
return
,
false
}

// PublicKey returns the stored public key for the keystore, alternately
// generating the public key from the private key if the public key was not
// supplied and the private key was.

PublicKey returns the stored public key for the keystore alternately generating the public key from the private key if the public key was not supplied and the private key was .


func (ks *Keystore) PrivateKey() (crypto.PrivateKey, bool) {
	ks.rw.RLock()
	defer ks.rw.RUnlock()
	return ks.Key, ks.Key != nil
}

func ( ks * Keystore ) PrivateKey ( ) ( crypto . PrivateKey , bool ) { ks . rw . RLock ( ) defer ks . rw . RUnlock ( ) return ks . Key , ks . Key != nil }

// PrivateKey returns the stored private key for the keystore.

PrivateKey returns the stored private key for the keystore .


func (t *Transport) RegisterLocation(loc string, path string) {
	t.mu.Lock()
	defer t.mu.Unlock()
	if t.loc == nil {
		t.loc = make(map[string]string)
	}
	if _, exists := t.loc[loc]; exists {
		panic("location " + loc + " already registered")
	}
	t.loc[loc] = path
}

func ( t * Transport ) RegisterLocation ( loc string , path string ) { t . mu . Lock ( ) defer t . mu . Unlock ( ) if t . loc == nil { t . loc = make ( map [ string ] string ) } if _ , exists := t . loc [ loc ] ; exists { panic ( " " + loc + " " ) } t . loc [ loc ] = path }

// RegisterLocation registers an URL location and maps it to the given
// file system path.
//
// Calling RegisterLocation twice for the same location is a
// programmer error, and causes a panic.

RegisterLocation registers an URL location and maps it to the given file system path . Calling RegisterLocation twice for the same location is a programmer error and causes a panic .


func NewArena(size uint32) *Arena {
	// Don't store data at position 0 in order to reserve offset=0 as a kind
	// of nil pointer.
	out := &Arena{
		n:   1,
		buf: make([]byte, size),
	}

	return out
}

// NewArena allocates a new arena of the specified size and returns it.

NewArena allocates a new arena of the specified size and returns it .


func NewSkiplist(arena *Arena) *Skiplist {
	// Allocate head and tail nodes.
	head, err := newNode(arena, maxHeight)
	if err != nil {
		panic("arenaSize is not large enough to hold the head node")
	}

	tail, err := newNode(arena, maxHeight)
	if err != nil {
		panic("arenaSize is not large enough to hold the tail node")
	}

	// Link all head/tail levels together.
	headOffset := arena.GetPointerOffset(unsafe.Pointer(head))
	tailOffset := arena.GetPointerOffset(unsafe.Pointer(tail))
	for i := 0; i < maxHeight; i++ {
		head.tower[i].nextOffset = tailOffset
		tail.tower[i].prevOffset = headOffset
	}

	skl := &Skiplist{
		arena:  arena,
		head:   head,
		tail:   tail,
		height: 1,
	}

	return skl
}

func
NewSkiplist
(
arena
*
Arena
)
*
Skiplist
{
// Allocate head and tail nodes.
head
,
err
:=
newNode
(
arena
,
maxHeight
)
if
err
!=
{
panic
(
"
"
)
}
tail
,
err
:=
newNode
(
arena
,
maxHeight
)
if
err
!=
{
panic
(
"
"
)
}
// Link all head/tail levels together.
headOffset
:=
arena
.
GetPointerOffset
(
unsafe
.
Pointer
(
head
)
)
tailOffset
:=
arena
.
GetPointerOffset
(
unsafe
.
Pointer
(
tail
)
)
for
i
:=
0
;
i
<
maxHeight
;
i
++
{
head
.
tower
[
i
]
.
nextOffset
=
tailOffset
tail
.
tower
[
i
]
.
prevOffset
=
headOffset
}
skl
:=
&
Skiplist
{
arena
:
arena
,
head
:
head
,
tail
:
tail
,
height
:
1
,
}
return
skl
}

// NewSkiplist constructs and initializes a new, empty skiplist. All nodes, keys,
// and values in the skiplist will be allocated from the given arena.

NewSkiplist constructs and initializes a new empty skiplist . All nodes keys and values in the skiplist will be allocated from the given arena .


func (it *Iterator) Init(list *Skiplist) {
	it.list = list
	it.arena = list.arena
	it.nd = nil
	it.value = 0
}

func ( it * Iterator ) Init ( list * Skiplist ) { it . list = list it . arena = list . arena it . nd = nil it . value = 0 }

// Init associates the iterator with a skiplist and resets all state.

Init associates the iterator with a skiplist and resets all state .


func (it *Iterator) Value() []byte {
	valOffset, valSize := decodeValue(it.value)
	return it.arena.GetBytes(valOffset, uint32(valSize))
}

func ( it * Iterator ) Value ( ) [ ] byte { valOffset , valSize := decodeValue ( it . value ) return it . arena . GetBytes ( valOffset , uint32 ( valSize ) ) }

// Value returns the value at the current position.

Value returns the value at the current position .


func (it *Iterator) Set(val []byte, meta uint16) error {
	new, err := it.list.allocVal(val, meta)
	if err != nil {
		return err
	}

	return it.trySetValue(new)
}

func ( it * Iterator ) Set ( val [ ] byte , meta uint16 ) error { new , err := it . list . allocVal ( val , meta ) if err != nil { return err } return it . trySetValue ( new ) }

// Set updates the value of the current iteration record if it has not been
// updated or deleted since iterating or seeking to it. If the record has been
// updated, then Set positions the iterator on the most current value and
// returns ErrRecordUpdated. If the record has been deleted, then Set keeps
// the iterator positioned on the current record with the current value and
// returns ErrRecordDeleted.

Set updates the value of the current iteration record if it has not been updated or deleted since iterating or seeking to it . If the record has been updated then Set positions the iterator on the most current value and returns ErrRecordUpdated . If the record has been deleted then Set keeps the iterator positioned on the current record with the current value and returns ErrRecordDeleted .


func (it *Iterator) SetMeta(meta uint16) error {
	// Try to reuse the same value bytes. Do this only in the case where meta
	// is increasing, in order to avoid cases where the meta is changed, then
	// changed back to the original value, which would make it impossible to
	// detect updates had occurred in the interim.
	if meta > decodeMeta(it.value) {
		valOffset, valSize := decodeValue(it.value)
		new := encodeValue(valOffset, valSize, meta)
		return it.trySetValue(new)
	}

	return it.Set(it.Value(), meta)
}

// SetMeta updates the meta value of the current iteration record if it has not
// been updated or deleted since iterating or seeking to it. If the record has
// been updated, then SetMeta positions the iterator on the most current value
// and returns ErrRecordUpdated. If the record has been deleted, then SetMeta
// keeps the iterator positioned on the current record with the current value
// and returns ErrRecordDeleted.

SetMeta updates the meta value of the current iteration record if it has not been updated or deleted since iterating or seeking to it . If the record has been updated then SetMeta positions the iterator on the most current value and returns ErrRecordUpdated . If the record has been deleted then SetMeta keeps the iterator positioned on the current record with the current value and returns ErrRecordDeleted .


func (it *Iterator) Delete() error {
	if !atomic.CompareAndSwapUint64(&it.nd.value, it.value, deletedVal) {
		if it.setNode(it.nd, false) {
			return ErrRecordUpdated
		}

		return nil
	}

	// Deletion succeeded, so position iterator on next non-deleted node.
	next := it.list.getNext(it.nd, 0)
	it.setNode(next, false)
	return nil
}

// Delete marks the current iterator record as deleted from the store if it
// has not been updated since iterating or seeking to it. If the record has
// been updated, then Delete positions the iterator on the most current value
// and returns ErrRecordUpdated. If the record is deleted, then Delete positions
// the iterator on the next record.

Delete marks the current iterator record as deleted from the store if it has not been updated since iterating or seeking to it . If the record has been updated then Delete positions the iterator on the most current value and returns ErrRecordUpdated . If the record is deleted then Delete positions the iterator on the next record .


func isSameArray(val1, val2 []byte) bool {
	if len(val1) == len(val2) && len(val1) > 0 {
		return &val1[0] == &val2[0]
	}

	return false
}

func isSameArray ( val1 , val2 [ ] byte ) bool { if len ( val1 ) == len ( val2 ) && len ( val1 ) > 0 { return & val1 [ 0 ] == & val2 [ 0 ] } return false }

// IsSameArray returns true if the slices are the same length and the array
// underlying the two slices is the same. Always returns false for empty arrays.

IsSameArray returns true if the slices are the same length and the array underlying the two slices is the same . Always returns false for empty arrays .


func New(
	ctx context.Context,
	host string,
	opts ClientOptions,
	debug bool) (Client, error) {

	if host == "" {
		return nil, errNewClient
	}

	host = strings.Replace(host, "/api", "", 1)

	c := &client{
		http: &http.Client{},
		host: host,
	}

	if opts.Timeout != 0 {
		c.http.Timeout = opts.Timeout
	}

	if opts.Insecure {
		c.http.Transport = &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		}
	}

	if opts.UseCerts {
		pool, err := x509.SystemCertPool()
		if err != nil {
			return nil, errSysCerts
		}
		c.http.Transport = &http.Transport{
			TLSClientConfig: &tls.Config{
				RootCAs:            pool,
				InsecureSkipVerify: opts.Insecure,
			},
		}
	}

	if opts.ShowHTTP {
		c.showHTTP = true
	}

	c.debug = debug

	return c, nil
}

func New ( ctx context . Context , host string , opts ClientOptions , debug bool ) ( Client , error ) { if host == " " { return nil , errNewClient } host = strings . Replace ( host , " " , " " , 1 ) c := & client { http : & http . Client { } , host : host , } if opts . Timeout != 0 { c . http . Timeout = opts . Timeout } if opts . Insecure { c . http . Transport = & http . Transport { TLSClientConfig : & tls . Config { InsecureSkipVerify : true , } , } } if opts . UseCerts { pool , err := x509 . SystemCertPool ( ) if err != nil { return nil , errSysCerts } c . http . Transport = & http . Transport { TLSClientConfig : & tls . Config { RootCAs : pool , InsecureSkipVerify : opts . Insecure , } , } } if opts . ShowHTTP { c . showHTTP = true } c . debug = debug return c , nil }


func WriteIndentedN(w io.Writer, b []byte, n int) error {
	s := bufio.NewScanner(bytes.NewReader(b))
	if !s.Scan() {
		return nil
	}
	l := s.Text()
	for {
		for x := 0; x < n; x++ {
			if _, err := fmt.Fprint(w, " "); err != nil {
				return err
			}
		}
		if _, err := fmt.Fprint(w, l); err != nil {
			return err
		}
		if !s.Scan() {
			break
		}
		l = s.Text()
		if _, err := fmt.Fprint(w, "\n"); err != nil {
			return err
		}
	}
	return nil
}

func WriteIndentedN ( w io . Writer , b [ ] byte , n int ) error { s := bufio . NewScanner ( bytes . NewReader ( b ) ) if ! s . Scan ( ) { return nil } l := s . Text ( ) for { for x := 0 ; x < n ; x ++ { if _ , err := fmt . Fprint ( w , " " ) ; err != nil { return err } } if _ , err := fmt . Fprint ( w , l ) ; err != nil { return err } if ! s . Scan ( ) { break } l = s . Text ( ) if _ , err := fmt . Fprint ( w , " \n " ) ; err != nil { return err } } return nil }

// WriteIndentedN indents all lines n spaces.

WriteIndentedN indents all lines n spaces .


func WriteIndented(w io.Writer, b []byte) error {
	return WriteIndentedN(w, b, 4)
}

func WriteIndented ( w io . Writer , b [ ] byte ) error { return WriteIndentedN ( w , b , 4 ) }

// WriteIndented indents all lines four spaces.

WriteIndented indents all lines four spaces .


func NewReporter(bufferSize, poolSize int, transport http.RoundTripper) Reporter {
	r := new(BasicReporter)
	if transport == nil {
		transport = &http.Transport{
			// Allow for an idle connection per goroutine.
			MaxIdleConnsPerHost: poolSize,
		}
	}
	r.client = &http.Client{Transport: transport}
	r.reports = make(chan *statReport, bufferSize)
	r.done = make(chan bool)
	r.wg = new(sync.WaitGroup)
	for i := 0; i < poolSize; i++ {
		r.wg.Add(1)
		go r.processReports()
	}
	return r
}

// NewReporter returns a new Reporter.  You must specify the channel bufferSize and the
// goroutine poolSize.  You can pass in nil for the transport and it will create an
// http transport with MaxIdleConnsPerHost set to the goroutine poolSize.  Note if you
// pass in your own transport, it's a good idea to have its MaxIdleConnsPerHost be set
// to at least the poolSize to allow for effective connection reuse.

NewReporter returns a new Reporter . You must specify the channel bufferSize and the goroutine poolSize . You can pass in nil for the transport and it will create an http transport with MaxIdleConnsPerHost set to the goroutine poolSize . Note if you pass in your own transport it s a good idea to have its MaxIdleConnsPerHost be set to at least the poolSize to allow for effective connection reuse .


func PostCount(statKey, userKey string, count int) error {
	return DefaultReporter.PostCount(statKey, userKey, count)
}

func PostCount ( statKey , userKey string , count int ) error { return DefaultReporter . PostCount ( statKey , userKey , count ) }

// Using the classic API, posts a count to a stat using DefaultReporter.

Using the classic API posts a count to a stat using DefaultReporter .


func PostCountTime(statKey, userKey string, count int, timestamp int64) error {
	return DefaultReporter.PostCountTime(statKey, userKey, count, timestamp)
}

func PostCountTime ( statKey , userKey string , count int , timestamp int64 ) error { return DefaultReporter . PostCountTime ( statKey , userKey , count , timestamp ) }

// Using the classic API, posts a count to a stat using DefaultReporter at a specific
// time.

Using the classic API posts a count to a stat using DefaultReporter at a specific time .


func PostValue(statKey, userKey string, value float64) error {
	return DefaultReporter.PostValue(statKey, userKey, value)
}

func PostValue ( statKey , userKey string , value float64 ) error { return DefaultReporter . PostValue ( statKey , userKey , value ) }

// Using the classic API, posts a value to a stat using DefaultReporter.

Using the classic API posts a value to a stat using DefaultReporter .


func PostValueTime(statKey, userKey string, value float64, timestamp int64) error {
	return DefaultReporter.PostValueTime(statKey, userKey, value, timestamp)
}

func PostValueTime ( statKey , userKey string , value float64 , timestamp int64 ) error { return DefaultReporter . PostValueTime ( statKey , userKey , value , timestamp ) }

// Using the classic API, posts a value to a stat at a specific time using DefaultReporter.

Using the classic API posts a value to a stat at a specific time using DefaultReporter .


func PostEZCount(statName, ezkey string, count int) error {
	return DefaultReporter.PostEZCount(statName, ezkey, count)
}

func PostEZCount ( statName , ezkey string , count int ) error { return DefaultReporter . PostEZCount ( statName , ezkey , count ) }

// Using the EZ API, posts a count to a stat using DefaultReporter.

Using the EZ API posts a count to a stat using DefaultReporter .


func PostEZCountTime(statName, ezkey string, count int, timestamp int64) error {
	return DefaultReporter.PostEZCountTime(statName, ezkey, count, timestamp)
}

func PostEZCountTime ( statName , ezkey string , count int , timestamp int64 ) error { return DefaultReporter . PostEZCountTime ( statName , ezkey , count , timestamp ) }

// Using the EZ API, posts a count to a stat at a specific time using DefaultReporter.

Using the EZ API posts a count to a stat at a specific time using DefaultReporter .


func PostEZValue(statName, ezkey string, value float64) error {
	return DefaultReporter.PostEZValue(statName, ezkey, value)
}

func PostEZValue ( statName , ezkey string , value float64 ) error { return DefaultReporter . PostEZValue ( statName , ezkey , value ) }

// Using the EZ API, posts a value to a stat using DefaultReporter.

Using the EZ API posts a value to a stat using DefaultReporter .


func PostEZValueTime(statName, ezkey string, value float64, timestamp int64) error {
	return DefaultReporter.PostEZValueTime(statName, ezkey, value, timestamp)
}

func PostEZValueTime ( statName , ezkey string , value float64 , timestamp int64 ) error { return DefaultReporter . PostEZValueTime ( statName , ezkey , value , timestamp ) }

// Using the EZ API, posts a value to a stat at a specific time using DefaultReporter.

Using the EZ API posts a value to a stat at a specific time using DefaultReporter .


func (r *BasicReporter) PostCount(statKey, userKey string, count int) error {
	r.add(newClassicStatCount(statKey, userKey, count))
	return nil
}

func ( r * BasicReporter ) PostCount ( statKey , userKey string , count int ) error { r . add ( newClassicStatCount ( statKey , userKey , count ) ) return nil }

// Using the classic API, posts a count to a stat.

Using the classic API posts a count to a stat .


func (r *BasicReporter) PostCountTime(statKey, userKey string, count int, timestamp int64) error {
	x := newClassicStatCount(statKey, userKey, count)
	x.Timestamp = timestamp
	r.add(x)
	return nil
}

func ( r * BasicReporter ) PostCountTime ( statKey , userKey string , count int , timestamp int64 ) error { x := newClassicStatCount ( statKey , userKey , count ) x . Timestamp = timestamp r . add ( x ) return nil }

// Using the classic API, posts a count to a stat at a specific time.

Using the classic API posts a count to a stat at a specific time .


func (r *BasicReporter) PostCountOne(statKey, userKey string) error {
	return r.PostCount(statKey, userKey, 1)
}

func ( r * BasicReporter ) PostCountOne ( statKey , userKey string ) error { return r . PostCount ( statKey , userKey , 1 ) }

// Using the classic API, posts a count of 1 to a stat.

Using the classic API posts a count of 1 to a stat .


func (r *BasicReporter) PostValue(statKey, userKey string, value float64) error {
	r.add(newClassicStatValue(statKey, userKey, value))
	return nil
}

func ( r * BasicReporter ) PostValue ( statKey , userKey string , value float64 ) error { r . add ( newClassicStatValue ( statKey , userKey , value ) ) return nil }

// Using the classic API, posts a value to a stat.

Using the classic API posts a value to a stat .


func (r *BasicReporter) PostValueTime(statKey, userKey string, value float64, timestamp int64) error {
	x := newClassicStatValue(statKey, userKey, value)
	x.Timestamp = timestamp
	r.add(x)
	return nil
}

func ( r * BasicReporter ) PostValueTime ( statKey , userKey string , value float64 , timestamp int64 ) error { x := newClassicStatValue ( statKey , userKey , value ) x . Timestamp = timestamp r . add ( x ) return nil }

// Using the classic API, posts a value to a stat at a specific time.

Using the classic API posts a value to a stat at a specific time .


func (r *BasicReporter) PostEZCountOne(statName, ezkey string) error {
	return r.PostEZCount(statName, ezkey, 1)
}

func ( r * BasicReporter ) PostEZCountOne ( statName , ezkey string ) error { return r . PostEZCount ( statName , ezkey , 1 ) }

// Using the EZ API, posts a count of 1 to a stat.

Using the EZ API posts a count of 1 to a stat .


func (r *BasicReporter) PostEZCount(statName, ezkey string, count int) error {
	r.add(newEZStatCount(statName, ezkey, count))
	return nil
}

func ( r * BasicReporter ) PostEZCount ( statName , ezkey string , count int ) error { r . add ( newEZStatCount ( statName , ezkey , count ) ) return nil }

// Using the EZ API, posts a count to a stat.

Using the EZ API posts a count to a stat .


func (r *BasicReporter) PostEZCountTime(statName, ezkey string, count int, timestamp int64) error {
	x := newEZStatCount(statName, ezkey, count)
	x.Timestamp = timestamp
	r.add(x)
	return nil
}

func ( r * BasicReporter ) PostEZCountTime ( statName , ezkey string , count int , timestamp int64 ) error { x := newEZStatCount ( statName , ezkey , count ) x . Timestamp = timestamp r . add ( x ) return nil }

// Using the EZ API, posts a count to a stat at a specific time.

Using the EZ API posts a count to a stat at a specific time .


func (r *BasicReporter) PostEZValue(statName, ezkey string, value float64) error {
	r.add(newEZStatValue(statName, ezkey, value))
	return nil
}

func ( r * BasicReporter ) PostEZValue ( statName , ezkey string , value float64 ) error { r . add ( newEZStatValue ( statName , ezkey , value ) ) return nil }

// Using the EZ API, posts a value to a stat.

Using the EZ API posts a value to a stat .


func (r *BasicReporter) PostEZValueTime(statName, ezkey string, value float64, timestamp int64) error {
	x := newEZStatValue(statName, ezkey, value)
	x.Timestamp = timestamp
	r.add(x)
	return nil
}

func ( r * BasicReporter ) PostEZValueTime ( statName , ezkey string , value float64 , timestamp int64 ) error { x := newEZStatValue ( statName , ezkey , value ) x . Timestamp = timestamp r . add ( x ) return nil }

// Using the EZ API, posts a value to a stat at a specific time.

Using the EZ API posts a value to a stat at a specific time .


func NewBatchReporter(reporter Reporter, interval time.Duration) Reporter {

	br := &BatchReporter{
		r:               reporter,
		batchInterval:   interval,
		caches:          make(map[string]*statCache),
		shutdownBatchCh: make(chan struct{}),
	}

	go br.batchLoop()

	return br
}

func NewBatchReporter ( reporter Reporter , interval time . Duration ) Reporter { br := & BatchReporter { r : reporter , batchInterval : interval , caches : make ( map [ string ] * statCache ) , shutdownBatchCh : make ( chan struct { } ) , } go br . batchLoop ( ) return br }

// NewBatchReporter creates a batching stat reporter. The interval parameter
// specifies how often stats should be posted to the StatHat server.

NewBatchReporter creates a batching stat reporter . The interval parameter specifies how often stats should be posted to the StatHat server .


func (host rawHost) cleanHost() Host {
	output := Host{
		nil,
		host.Status.State,
		host.Address.Address,
		host.Address.AddressType,
		[]Hostname{},
		[]Port{},
	}

	for _, hostname := range host.Hostnames.Hostnames {
		output.Hostnames = append(output.Hostnames,
			Hostname{hostname.Name, hostname.Type})
	}
	for _, port := range host.Ports.Ports {
		output.Ports = append(output.Ports, port.cleanPort())
	}

	return output
}

func ( host rawHost ) cleanHost ( ) Host { output := Host { nil , host . Status . State , host . Address . Address , host . Address . AddressType , [ ] Hostname { } , [ ] Port { } , } for _ , hostname := range host . Hostnames . Hostnames { output . Hostnames = append ( output . Hostnames , Hostname { hostname . Name , hostname . Type } ) } for _ , port := range host . Ports . Ports { output . Ports = append ( output . Ports , port . cleanPort ( ) ) } return output }

// cleanHost is used to conver from the rawHost format to a more usable format


func (s Scan) GetHost(hostTarget string) (target Host, exists bool) {
	target, ok := s.Hosts[hostTarget]
	if ok {
		return target, true
	}

	for _, host := range s.Hosts {
		for _, hostname := range host.Hostnames {
			if hostname.Name == hostTarget {
				return host, true
			}
		}
	}

	return Host{}, false
}

func ( s Scan ) GetHost ( hostTarget string ) ( target Host , exists bool ) { target , ok := s . Hosts [ hostTarget ] if ok { return target , true } for _ , host := range s . Hosts { for _ , hostname := range host . Hostnames { if hostname . Name == hostTarget { return host , true } } } return Host { } , false }

// GetHost will get a specified host by either hostname or ip. The first
// return value is the host, if it was found. The second return value is the
// wether the host was found or not

GetHost will get a specified host by either hostname or ip . The first return value is the host if it was found . The second return value is the wether the host was found or not


func (h Host) Rescan() (scan Scan) {
	return Init().
		AddPorts(h.parentScan.configPorts...).
		AddTCPPorts(h.parentScan.configTCPPorts...).
		AddUDPPorts(h.parentScan.configUDPPorts...).
		AddHosts(h.Address).
		AddFlags(h.parentScan.configOpts...)
}

func ( h Host ) Rescan ( ) ( scan Scan ) { return Init ( ) . AddPorts ( h . parentScan . configPorts ... ) . AddTCPPorts ( h . parentScan . configTCPPorts ... ) . AddUDPPorts ( h . parentScan . configUDPPorts ... ) . AddHosts ( h . Address ) . AddFlags ( h . parentScan . configOpts ... ) }

// Rescan the target. Normally used for finding differences between scans
// at two points in time.

Rescan the target . Normally used for finding differences between scans at two points in time .


func (h Host) Diff(altHost Host) (added []Port, removed []Port) {
	targetPorts := h.Ports
	altPorts := altHost.Ports

	addedWithClosed := array.Except(altPorts, targetPorts).([]Port)
	for _, add := range addedWithClosed {
		if add.State != "closed" {
			added = append(added, add)
		}
	}
	removedWithClosed := array.Except(targetPorts, altPorts).([]Port)
	for _, remove := range removedWithClosed {
		if remove.State != "closed" {
			removed = append(removed, remove)
		}
	}

	return
}

func ( h Host ) Diff ( altHost Host ) ( added [ ] Port , removed [ ] Port ) { targetPorts := h . Ports altPorts := altHost . Ports addedWithClosed := array . Except ( altPorts , targetPorts ) . ( [ ] Port ) for _ , add := range addedWithClosed { if add . State != " " { added = append ( added , add ) } } removedWithClosed := array . Except ( targetPorts , altPorts ) . ( [ ] Port ) for _ , remove := range removedWithClosed { if remove . State != " " { removed = append ( removed , remove ) } } return }

// Diff gets the difference between the the target host and the argument host.
//The first returned value is the added ports and the second returned value is
// the removed ports.

Diff gets the difference between the the target host and the argument host . The first returned value is the added ports and the second returned value is the removed ports .


func (h Host) ToString() (out string) {
	out += fmt.Sprintf("%s is %s\n", h.Address, h.State)
	if len(h.Hostnames) != 0 {
		out += "Hostnames:\n"
		for _, hostname := range h.Hostnames {
			out += fmt.Sprintf("  %s/%s\n", hostname.Name, hostname.Type)
		}
	}
	if len(h.Ports) != 0 {
		out += "Ports:\n"
		for _, port := range h.Ports {
			for _, line := range strings.Split(port.ToString(), "\n") {
				if line != "" {
					out += fmt.Sprintf("  %s\n", line)
				}
			}
		}
	}
	return
}

func ( h Host ) ToString ( ) ( out string ) { out += fmt . Sprintf ( " \n " , h . Address , h . State ) if len ( h . Hostnames ) != 0 { out += " \n " for _ , hostname := range h . Hostnames { out += fmt . Sprintf ( " \n " , hostname . Name , hostname . Type ) } } if len ( h . Ports ) != 0 { out += " \n " for _ , port := range h . Ports { for _ , line := range strings . Split ( port . ToString ( ) , " \n " ) { if line != " " { out += fmt . Sprintf ( " \n " , line ) } } } } return }

// ToString converts the host into a nicely formatted string


func Init() Scan {
	scan := Scan{}
	scan.Hosts = make(map[string]Host, 0)
	return scan
}

func Init ( ) Scan { scan := Scan { } scan . Hosts = make ( map [ string ] Host , 0 ) return scan }

// Init initializes a scan object. This is the easiest way to create a Scan
// object. If you are trying to create a Scan object by hand, make sure to
// instantiate the Hosts map

Init initializes a scan object . This is the easiest way to create a Scan object . If you are trying to create a Scan object by hand make sure to instantiate the Hosts map


func (s Scan) AddHosts(hosts ...string) Scan {
	s.configHosts = append(s.configHosts, hosts...)
	return s
}

func ( s Scan ) AddHosts ( hosts ... string ) Scan { s . configHosts = append ( s . configHosts , hosts ... ) return s }

// AddHosts adds a list of hosts to the list of hosts to be scanned


func (s Scan) SetHosts(hosts ...string) Scan {
	s.configHosts = hosts
	return s
}

func ( s Scan ) SetHosts ( hosts ... string ) Scan { s . configHosts = hosts return s }

// SetHosts sets the hosts that will be scanned


func (s Scan) AddPorts(ports ...uint16) Scan {
	s.configPorts = append(s.configPorts, ports...)
	return s
}

func ( s Scan ) AddPorts ( ports ... uint16 ) Scan { s . configPorts = append ( s . configPorts , ports ... ) return s }

// AddPorts appends a list of ports to the list of ports to be scanned


func (s Scan) SetPorts(ports ...uint16) Scan {
	s.configPorts = ports
	return s
}

func ( s Scan ) SetPorts ( ports ... uint16 ) Scan { s . configPorts = ports return s }

// SetPorts sets the ports that wil be used


func (s Scan) SetTCPPorts(ports ...uint16) Scan {
	s.configTCPPorts = ports
	return s
}

func ( s Scan ) SetTCPPorts ( ports ... uint16 ) Scan { s . configTCPPorts = ports return s }

// SetTCPPorts sets which TCP-only ports are used to scan

SetTCPPorts sets which TCP - only ports are used to scan


func (s Scan) SetUDPPorts(ports ...uint16) Scan {
	s.configUDPPorts = ports
	return s
}

func ( s Scan ) SetUDPPorts ( ports ... uint16 ) Scan { s . configUDPPorts = ports return s }

// SetUDPPort sets which TCP-only ports are used to scan

SetUDPPort sets which TCP - only ports are used to scan


func (s Scan) AddFlags(flags ...string) Scan {
	for _, flag := range flags {
		if strings.Contains(flag, " ") {
			s.configErr = errors.New("Flags must not have spaces in them")
			return s
		}
		for _, df := range DisallowedFlags {
			if flag == df {
				s.configErr = &DisallowedFlagError{df}
				return s
			}
		}
	}

	s.configOpts = append(s.configOpts, flags...)
	return s
}

func ( s Scan ) AddFlags ( flags ... string ) Scan { for _ , flag := range flags { if strings . Contains ( flag , " " ) { s . configErr = errors . New ( " " ) return s } for _ , df := range DisallowedFlags { if flag == df { s . configErr = & DisallowedFlagError { df } return s } } } s . configOpts = append ( s . configOpts , flags ... ) return s }

// AddFlags adds a list of flags to be used by nmap. Seperate flags by new
// arguments. The order of the flag is kept, so when using flags that require
// file names, seperate it by using multiple arguments.
//
// Use the DisallowedFlags variable to guide you on which flags are not allowed
// to be used.

AddFlags adds a list of flags to be used by nmap . Seperate flags by new arguments . The order of the flag is kept so when using flags that require file names seperate it by using multiple arguments . Use the DisallowedFlags variable to guide you on which flags are not allowed to be used .


func (s Scan) IntenseAllTCPPorts() Scan {
	return s.Intense().
		SetPorts().
		SetUDPPorts().
		SetTCPPorts().
		AddPortRange(1, 65535)
}

func ( s Scan ) IntenseAllTCPPorts ( ) Scan { return s . Intense ( ) . SetPorts ( ) . SetUDPPorts ( ) . SetTCPPorts ( ) . AddPortRange ( 1 , 65535 ) }

// IntenseAllTCPPorts does an intense scan, but adds all TCP ports

IntenseAllTCPPorts does an intense scan but adds all TCP ports


func (s Scan) ToString() (out string) {
	for _, host := range s.Hosts {
		out += fmt.Sprintf("%s\n", host.ToString())
	}
	return
}

func ( s Scan ) ToString ( ) ( out string ) { for _ , host := range s . Hosts { out += fmt . Sprintf ( " \n " , host . ToString ( ) ) } return }

// ToString returns the list of hosts into a pretty-printed format

ToString returns the list of hosts into a pretty - printed format


func (s Scan) CreateNmapArgs() ([]string, error) {
	// Parse arguments
	args := []string{"-oX", "-"}
	const seperator string = ","

	// Set up ports
	portList := ""
	portList += strings.Join(uint16ListToStringList(s.configPorts), seperator)
	if len(s.configUDPPorts) != 0 {
		if portList != "" {
			portList += ","
		}
		portList += "U:"
	}
	portList += strings.Join(uint16ListToStringList(s.configUDPPorts), seperator)
	if len(s.configTCPPorts) != 0 {
		if portList != "" {
			portList += ","
		}
		portList += "T:"
	}
	portList += strings.Join(uint16ListToStringList(s.configTCPPorts), seperator)

	// Check to make sure all TCP/UDP flags are correct
	// Check TCP flags
	tcpOptions := []string{"-sS", "-sT", "-sA", "-sW", "-sM"}
	iflag := array.Intersection(tcpOptions, s.configOpts).([]string)
	if len(iflag) == 0 {
		s.configOpts = append(s.configOpts, tcpOptions[1])
	}

	// Check UDP flag
	if len(s.configUDPPorts) != 0 && !array.In("-sU", s.configOpts) {
		s.configOpts = append(s.configOpts, "-sU")
	}

	// Append arguments
	args = append(args, s.configOpts...)

	// Append port list
	if portList != "" {
		args = append(args, "-p"+portList)
	}
	// Append hosts
	if len(s.configHosts) == 0 {
		s.configErr = errors.New("No hosts added")
	}
	args = append(args, s.configHosts...)

	fmt.Println(args)
	return args, nil
}

// CreateNmapArgs takes a Scan object and returns a list of strings that map to
// arguments for an nmap scan.

CreateNmapArgs takes a Scan object and returns a list of strings that map to arguments for an nmap scan .


func uint16ListToStringList(source []uint16) (o []string) {
	for _, s := range source {
		o = append(o, strconv.FormatUint(uint64(s), 10))
	}
	return
}

func uint16ListToStringList ( source [ ] uint16 ) ( o [ ] string ) { for _ , s := range source { o = append ( o , strconv . FormatUint ( uint64 ( s ) , 10 ) ) } return }

// uint16ListToStringList is used to reduce lines for joining strings in
// the CreateNmapArgs function

uint16ListToStringList is used to reduce lines for joining strings in the CreateNmapArgs function


func (p Port) ToString() (out string) {
	out += fmt.Sprintf("Port %d/%s is %s\n", p.ID, p.Protocol, p.State)
	for _, script := range p.Scripts {
		output := ""
		for _, line := range strings.Split(script.Output, "\n") {
			output += fmt.Sprintf("      %s\n", line)
		}
		out += fmt.Sprintf("  Script: %s\n%s\n", script.Name, output)
	}
	return
}

func ( p Port ) ToString ( ) ( out string ) { out += fmt . Sprintf ( " \n " , p . ID , p . Protocol , p . State ) for _ , script := range p . Scripts { output := " " for _ , line := range strings . Split ( script . Output , " \n " ) { output += fmt . Sprintf ( " \n " , line ) } out += fmt . Sprintf ( " \n \n " , script . Name , output ) } return }

// ToString returns port information in a pretty-printed format

ToString returns port information in a pretty - printed format


func (otp HOTP) Counter() uint64 {
	counter := binary.BigEndian.Uint64(otp.counter[:])
	return counter
}

func ( otp HOTP ) Counter ( ) uint64 { counter := binary . BigEndian . Uint64 ( otp . counter [ : ] ) return counter }

// Counter returns the HOTP's 8-byte counter as an unsigned 64-bit
// integer.

Counter returns the HOTP s 8 - byte counter as an unsigned 64 - bit integer .


func (otp HOTP) Increment() {
	for i := ctrSize - 1; i >= 0; i-- {
		if otp.counter[i]++; otp.counter[i] != 0 {
			return
		}
	}
}

func ( otp HOTP ) Increment ( ) { for i := ctrSize - 1 ; i >= 0 ; i -- { if otp . counter [ i ] ++ ; otp . counter [ i ] != 0 { return } } }

// Increment will increment an HOTP source's counter. This is useful
// for providers like the Google Authenticator app, which immediately
// increments the counter and uses the 0 counter value as an integrity
// check.

Increment will increment an HOTP source s counter . This is useful for providers like the Google Authenticator app which immediately increments the counter and uses the 0 counter value as an integrity check .


func NewHOTP(key []byte, counter uint64, digits int) *HOTP {
	otp := &HOTP{
		Key:    key,
		Digits: digits,
	}
	otp.counter = new([ctrSize]byte)
	binary.BigEndian.PutUint64(otp.counter[:], counter)

	return otp
}

func NewHOTP ( key [ ] byte , counter uint64 , digits int ) * HOTP { otp := & HOTP { Key : key , Digits : digits , } otp . counter = new ( [ ctrSize ] byte ) binary . BigEndian . PutUint64 ( otp . counter [ : ] , counter ) return otp }

// NewHOTP intialises a new HOTP instance with the key and counter
// values. No check is done on the digits, but typical values are 6
// and 8.

NewHOTP intialises a new HOTP instance with the key and counter values . No check is done on the digits but typical values are 6 and 8 .


func (otp *HOTP) URL(label string) string {
	secret := base32.StdEncoding.EncodeToString(otp.Key)
	u := url.URL{}
	v := url.Values{}
	u.Scheme = "otpauth"
	u.Host = "hotp"
	u.Path = label
	v.Add("secret", secret)
	v.Add("counter", fmt.Sprintf("%d", otp.Counter()))
	u.RawQuery = v.Encode()
	return u.String()
}

func ( otp * HOTP ) URL ( label string ) string { secret := base32 . StdEncoding . EncodeToString ( otp . Key ) u := url . URL { } v := url . Values { } u . Scheme = " " u . Host = " " u . Path = label v . Add ( " " , secret ) v . Add ( " " , fmt . Sprintf ( " " , otp . Counter ( ) ) ) u . RawQuery = v . Encode ( ) return u . String ( ) }

// URL returns a suitable URL, such as for the Google Authenticator
// app. The label is used by these apps to identify the service to
// which this OTP belongs. The digits value is ignored by the Google
// authenticator app, and is therefore elided in the resulting URL.

URL returns a suitable URL such as for the Google Authenticator app . The label is used by these apps to identify the service to which this OTP belongs . The digits value is ignored by the Google authenticator app and is therefore elided in the resulting URL .


func (otp *HOTP) QR(label string) ([]byte, error) {
	u := otp.URL(label)
	code, err := qr.Encode(u, qr.Q)
	if err != nil {
		return nil, err
	}
	return code.PNG(), nil
}

func ( otp * HOTP ) QR ( label string ) ( [ ] byte , error ) { u := otp . URL ( label ) code , err := qr . Encode ( u , qr . Q ) if err != nil { return nil , err } return code . PNG ( ) , nil }

// QR generates a byte slice containing the a QR code encoded as a
// PNG with level Q error correction.

QR generates a byte slice containing the a QR code encoded as a PNG with level Q error correction .


func truncate(in []byte) int64 {
	offset := int(in[len(in)-1] & 0xF)
	p := in[offset : offset+4]
	var binCode int32
	binCode = int32((p[0] & 0x7f)) << 24
	binCode += int32((p[1] & 0xff)) << 16
	binCode += int32((p[2] & 0xff)) << 8
	binCode += int32((p[3] & 0xff))
	return int64(binCode) & 0x7FFFFFFF
}

func truncate ( in [ ] byte ) int64 { offset := int ( in [ len ( in ) - 1 ] & 0xF ) p := in [ offset : offset + 4 ] var binCode int32 binCode = int32 ( ( p [ 0 ] & 0x7f ) ) << 24 binCode += int32 ( ( p [ 1 ] & 0xff ) ) << 16 binCode += int32 ( ( p [ 2 ] & 0xff ) ) << 8 binCode += int32 ( ( p [ 3 ] & 0xff ) ) return int64 ( binCode ) & 0x7FFFFFFF }

// truncate contains the DT function from the RFC; this is used to
// deterministically select a sequence of 4 bytes from the HMAC
// counter hash.

truncate contains the DT function from the RFC ; this is used to deterministically select a sequence of 4 bytes from the HMAC counter hash .


func FromURL(urlString string) (*HOTP, string, error) {
	u, err := url.Parse(urlString)
	if err != nil {
		return nil, "", err
	}

	if u.Scheme != "otpauth" {
		return nil, "", ErrInvalidHOTPURL
	} else if u.Host != "hotp" {
		return nil, "", ErrInvalidHOTPURL
	}

	v := u.Query()
	if len(v) == 0 {
		return nil, "", ErrInvalidHOTPURL
	}
	if v.Get("secret") == "" {
		return nil, "", ErrInvalidHOTPURL
	} else if algo := v.Get("algorithm"); algo != "" && algo != "SHA1" {
		return nil, "", ErrInvalidHOTPURL
	}

	var identity string
	if len(u.Path) > 1 {
		identity = u.Path[1:]
	}

	var counter uint64
	if ctr := v.Get("counter"); ctr != "" {
		counter, err = strconv.ParseUint(ctr, 10, 64)
		if err != nil {
			return nil, "", ErrInvalidHOTPURL
		}
	}

	secret, err := base32.StdEncoding.DecodeString(v.Get("secret"))
	if err != nil {
		return nil, "", ErrInvalidHOTPURL
	}

	var digits int64 = 6
	if v.Get("digits") != "" {
		digits, err = strconv.ParseInt(v.Get("digits"), 10, 8)
		if err != nil {
			return nil, "", ErrInvalidHOTPURL
		}
	}

	otp := NewHOTP(secret, counter, int(digits))
	return otp, identity, nil
}

func FromURL ( urlString string ) ( * HOTP , string , error ) { u , err := url . Parse ( urlString ) if err != nil { return nil , " " , err } if u . Scheme != " " { return nil , " " , ErrInvalidHOTPURL } else if u . Host != " " { return nil , " " , ErrInvalidHOTPURL } v := u . Query ( ) if len ( v ) == 0 { return nil , " " , ErrInvalidHOTPURL } if v . Get ( " " ) == " " { return nil , " " , ErrInvalidHOTPURL } else if algo := v . Get ( " " ) ; algo != " " && algo != " " { return nil , " " , ErrInvalidHOTPURL } var identity string if len ( u . Path ) > 1 { identity = u . Path [ 1 : ] } var counter uint64 if ctr := v . Get ( " " ) ; ctr != " " { counter , err = strconv . ParseUint ( ctr , 10 , 64 ) if err != nil { return nil , " " , ErrInvalidHOTPURL } } secret , err := base32 . StdEncoding . DecodeString ( v . Get ( " " ) ) if err != nil { return nil , " " , ErrInvalidHOTPURL } var digits int64 = 6 if v . Get ( " " ) != " " { digits , err = strconv . ParseInt ( v . Get ( " " ) , 10 , 8 ) if err != nil { return nil , " " , ErrInvalidHOTPURL } } otp := NewHOTP ( secret , counter , int ( digits ) ) return otp , identity , nil }

// FromURL parses a new HOTP from a URL string. It returns the OTP,
// the label associated with the OTP, and any errors that occurred.

FromURL parses a new HOTP from a URL string . It returns the OTP the label associated with the OTP and any errors that occurred .


func GenerateHOTP(digits int, randCounter bool) (*HOTP, error) {
	key := make([]byte, sha1.Size)
	_, err := io.ReadFull(PRNG, key)
	if err != nil {
		return nil, err
	}

	var counter uint64
	if randCounter {
		ctr, err := rand.Int(PRNG, big.NewInt(int64(math.MaxInt64)))
		if err != nil {
			return nil, err
		}
		counter = ctr.Uint64()
	}

	return NewHOTP(key, counter, digits), nil
}

func GenerateHOTP ( digits int , randCounter bool ) ( * HOTP , error ) { key := make ( [ ] byte , sha1 . Size ) _ , err := io . ReadFull ( PRNG , key ) if err != nil { return nil , err } var counter uint64 if randCounter { ctr , err := rand . Int ( PRNG , big . NewInt ( int64 ( math . MaxInt64 ) ) ) if err != nil { return nil , err } counter = ctr . Uint64 ( ) } return NewHOTP ( key , counter , digits ) , nil }

// GenerateHOTP will generate a randomised HOTP source; if the
// randCounter parameter is true, the counter will be randomised.

GenerateHOTP will generate a randomised HOTP source ; if the randCounter parameter is true the counter will be randomised .


func (otp *HOTP) YubiKey(in string) (string, string, bool) {
	if len(in) < otp.Digits {
		return "", "", false
	}

	otpStart := len(in) - otp.Digits
	code := in[otpStart:]
	pubid := in[:otpStart]
	return code, pubid, true
}

func ( otp * HOTP ) YubiKey ( in string ) ( string , string , bool ) { if len ( in ) < otp . Digits { return " " , " " , false } otpStart := len ( in ) - otp . Digits code := in [ otpStart : ] pubid := in [ : otpStart ] return code , pubid , true }

// YubiKey reads an OATH-HOTP string as returned by a YubiKey, and
// returns three values. The first value contains the actual OTP, the
// second value contains the YubiKey's token identifier, and the final
// value indicates whether the input string was a valid YubiKey
// OTP. This does not check whether the code is correct or not, it
// only ensures that it is well-formed output from a token and
// splits the output into the code and the public identity.

YubiKey reads an OATH - HOTP string as returned by a YubiKey and returns three values . The first value contains the actual OTP the second value contains the YubiKey s token identifier and the final value indicates whether the input string was a valid YubiKey OTP . This does not check whether the code is correct or not it only ensures that it is well - formed output from a token and splits the output into the code and the public identity .


func (otp *HOTP) IntegrityCheck() (string, uint64) {
	h := hmac.New(sha1.New, otp.Key)
	counter := make([]byte, 8)
	h.Write(counter)
	hash := h.Sum(nil)
	result := truncate(hash)

	mod := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(otp.Digits)), nil)
	mod = mod.Mod(big.NewInt(result), mod)
	fmtStr := fmt.Sprintf("%%0%dd", otp.Digits)
	return fmt.Sprintf(fmtStr, mod.Uint64()), otp.Counter()
}

func ( otp * HOTP ) IntegrityCheck ( ) ( string , uint64 ) { h := hmac . New ( sha1 . New , otp . Key ) counter := make ( [ ] byte , 8 ) h . Write ( counter ) hash := h . Sum ( nil ) result := truncate ( hash ) mod := new ( big . Int ) . Exp ( big . NewInt ( 10 ) , big . NewInt ( int64 ( otp . Digits ) ) , nil ) mod = mod . Mod ( big . NewInt ( result ) , mod ) fmtStr := fmt . Sprintf ( " " , otp . Digits ) return fmt . Sprintf ( fmtStr , mod . Uint64 ( ) ) , otp . Counter ( ) }

// IntegrityCheck returns two values, the base OTP and the current
// counter. This is used, for example, with the Google Authenticator
// app's "Check key value" function and can be used to verify that
// the application and the provider are in sync.

IntegrityCheck returns two values the base OTP and the current counter . This is used for example with the Google Authenticator app s Check key value function and can be used to verify that the application and the provider are in sync .


func (otp *HOTP) Check(code string) bool {
	codeBytes := []byte(code)
	genCode := []byte(otp.OTP())
	if subtle.ConstantTimeCompare(codeBytes, genCode) != 1 {
		otp.setCounter(otp.Counter() - 1)
		return false
	}
	return true
}

func ( otp * HOTP ) Check ( code string ) bool { codeBytes := [ ] byte ( code ) genCode := [ ] byte ( otp . OTP ( ) ) if subtle . ConstantTimeCompare ( codeBytes , genCode ) != 1 { otp . setCounter ( otp . Counter ( ) - 1 ) return false } return true }

// Check takes an input code and verifies it against the OTP. If
// successful, the counter is incremented.

Check takes an input code and verifies it against the OTP . If successful the counter is incremented .


func Marshal(otp *HOTP) ([]byte, error) {
	var asnHOTP struct {
		Key     []byte
		Counter *big.Int
		Digits  int
	}
	asnHOTP.Key = otp.Key[:]
	asnHOTP.Counter = new(big.Int).SetUint64(otp.Counter())
	asnHOTP.Digits = otp.Digits
	return asn1.Marshal(asnHOTP)
}

func Marshal ( otp * HOTP ) ( [ ] byte , error ) { var asnHOTP struct { Key [ ] byte Counter * big . Int Digits int } asnHOTP . Key = otp . Key [ : ] asnHOTP . Counter = new ( big . Int ) . SetUint64 ( otp . Counter ( ) ) asnHOTP . Digits = otp . Digits return asn1 . Marshal ( asnHOTP ) }

// Marshal serialises an HOTP key value as a DER-encoded byte slice.

Marshal serialises an HOTP key value as a DER - encoded byte slice .


func Unmarshal(in []byte) (otp *HOTP, err error) {
	var asnHOTP struct {
		Key     []byte
		Counter *big.Int
		Digits  int
	}
	_, err = asn1.Unmarshal(in, &asnHOTP)
	if err != nil {
		return
	}

	otp = &HOTP{
		Key:    asnHOTP.Key[:],
		Digits: asnHOTP.Digits,
	}
	otp.setCounter(asnHOTP.Counter.Uint64())
	return
}

func Unmarshal ( in [ ] byte ) ( otp * HOTP , err error ) { var asnHOTP struct { Key [ ] byte Counter * big . Int Digits int } _ , err = asn1 . Unmarshal ( in , & asnHOTP ) if err != nil { return } otp = & HOTP { Key : asnHOTP . Key [ : ] , Digits : asnHOTP . Digits , } otp . setCounter ( asnHOTP . Counter . Uint64 ( ) ) return }

// Unmarshal parses a DER-encoded serialised HOTP key value.

Unmarshal parses a DER - encoded serialised HOTP key value .


func NewWriterPool(maxRate int, maxBurst time.Duration) *WriterPool {
	return &WriterPool{
		maxRate:  maxRate,
		maxBurst: maxBurst,
		givenOut: make(map[ThrottlerWriter]struct{}),
	}
}

func NewWriterPool ( maxRate int , maxBurst time . Duration ) * WriterPool { return & WriterPool { maxRate : maxRate , maxBurst : maxBurst , givenOut : make ( map [ ThrottlerWriter ] struct { } ) , } }

// NewWriterPool creates a pool that ensures the writers it wraps will
// respect an overall maxRate, with maxBurst resolution. The semantics
// of the wrapped writers are the same as those of using a plain
// ThrottledWriter.

NewWriterPool creates a pool that ensures the writers it wraps will respect an overall maxRate with maxBurst resolution . The semantics of the wrapped writers are the same as those of using a plain ThrottledWriter .


func (pool *WriterPool) Get(w io.Writer) (writer io.Writer, release func()) {
	// don't export a ThrottlerWriter to prevent users changing the rate
	// and expecting their change to be respected, since we might modify
	// the rate under their feet

	// make the initial rate be 0, the actual rate is
	// set in the call to `setSharedRates`.
	wr := ThrottledWriter(w, 0, pool.maxBurst)

	pool.mu.Lock()
	pool.givenOut[wr] = struct{}{}
	pool.setSharedRates()
	pool.mu.Unlock()

	return wr, func() {
		pool.mu.Lock()
		delete(pool.givenOut, wr)
		pool.setSharedRates()
		pool.mu.Unlock()
	}
}


func (pool *WriterPool) Len() int {
	pool.mu.Lock()
	l := len(pool.givenOut)
	pool.mu.Unlock()
	return l
}

func ( pool * WriterPool ) Len ( ) int { pool . mu . Lock ( ) l := len ( pool . givenOut ) pool . mu . Unlock ( ) return l }

// Len is the number of currently given out throttled writers.

Len is the number of currently given out throttled writers .


func NewReaderPool(maxRate int, maxBurst time.Duration) *ReaderPool {
	return &ReaderPool{
		maxRate:  maxRate,
		maxBurst: maxBurst,
		givenOut: make(map[ThrottlerReader]struct{}),
	}
}

func NewReaderPool ( maxRate int , maxBurst time . Duration ) * ReaderPool { return & ReaderPool { maxRate : maxRate , maxBurst : maxBurst , givenOut : make ( map [ ThrottlerReader ] struct { } ) , } }

// NewReaderPool creates a pool that ensures the writers it wraps will
// respect an overall maxRate, with maxBurst resolution. The semantics
// of the wrapped writers are the same as those of using a plain
// ThrottledReader.

NewReaderPool creates a pool that ensures the writers it wraps will respect an overall maxRate with maxBurst resolution . The semantics of the wrapped writers are the same as those of using a plain ThrottledReader .


func (pool *ReaderPool) Get(r io.Reader) (reader io.Reader, release func()) {
	// don't export a ThrottlerReader to prevent users changing the rate
	// and expecting their change to be respected, since we might modify
	// the rate under their feet

	// make the initial rate be 0, the actual rate is
	// set in the call to `setSharedRates`.
	rd := ThrottledReader(r, 0, pool.maxBurst)

	pool.mu.Lock()
	pool.givenOut[rd] = struct{}{}
	pool.setSharedRates()
	pool.mu.Unlock()

	return rd, func() {
		pool.mu.Lock()
		delete(pool.givenOut, rd)
		pool.setSharedRates()
		pool.mu.Unlock()
	}
}


func (pool *ReaderPool) SetRate(rate int) int {
	pool.mu.Lock()
	old := pool.maxRate
	pool.maxRate = rate
	pool.setSharedRates()
	pool.mu.Unlock()
	return old
}

func ( pool * ReaderPool ) SetRate ( rate int ) int { pool . mu . Lock ( ) old := pool . maxRate pool . maxRate = rate pool . setSharedRates ( ) pool . mu . Unlock ( ) return old }

// SetRate of the pool, updating each given out reader to respect the
// newly set rate. Returns the old rate.

SetRate of the pool updating each given out reader to respect the newly set rate . Returns the old rate .


func (pool *ReaderPool) Len() int {
	pool.mu.Lock()
	defer pool.mu.Unlock()
	return len(pool.givenOut)
}

func ( pool * ReaderPool ) Len ( ) int { pool . mu . Lock ( ) defer pool . mu . Unlock ( ) return len ( pool . givenOut ) }

// Len is the number of currently given out throttled readers.

Len is the number of currently given out throttled readers .


func NewMeasuredWriter(w io.Writer) *MeasuredWriter {
	return &MeasuredWriter{wrap: w, rate: newCounter()}
}

func NewMeasuredWriter ( w io . Writer ) * MeasuredWriter { return & MeasuredWriter { wrap : w , rate : newCounter ( ) } }


func (m *MeasuredWriter) BytesPerSec() uint64 {
	return uint64(m.rate.Rate(time.Second))
}

func ( m * MeasuredWriter ) BytesPerSec ( ) uint64 { return uint64 ( m . rate . Rate ( time . Second ) ) }

// BytesPerSec tells the rate per second at which bytes were written since last
// measurement.

BytesPerSec tells the rate per second at which bytes were written since last measurement .


func NewMeasuredReader(r io.Reader) *MeasuredReader {
	return &MeasuredReader{wrap: r, rate: newCounter()}
}

func NewMeasuredReader ( r io . Reader ) * MeasuredReader { return & MeasuredReader { wrap : r , rate : newCounter ( ) } }


func (m *MeasuredReader) BytesPer(perPeriod time.Duration) uint64 {
	return uint64(m.rate.Rate(perPeriod))
}

func ( m * MeasuredReader ) BytesPer ( perPeriod time . Duration ) uint64 { return uint64 ( m . rate . Rate ( perPeriod ) ) }

// BytesPer tells the rate per period at which bytes were read since last
// measurement.

BytesPer tells the rate per period at which bytes were read since last measurement .


func (m *MeasuredReader) BytesPerSec() uint64 {
	return uint64(m.rate.Rate(time.Second))
}

func ( m * MeasuredReader ) BytesPerSec ( ) uint64 { return uint64 ( m . rate . Rate ( time . Second ) ) }

// BytesPerSec tells the rate per second at which bytes were read since last
// measurement.

BytesPerSec tells the rate per second at which bytes were read since last measurement .


func ThrottledReader(r io.Reader, bytesPerSec int, maxBurst time.Duration) ThrottlerReader {
	return &throttledReader{
		wrap:    r,
		limiter: newRateLimiter(bytesPerSec, maxBurst),
	}
}

func ThrottledReader ( r io . Reader , bytesPerSec int , maxBurst time . Duration ) ThrottlerReader { return & throttledReader { wrap : r , limiter : newRateLimiter ( bytesPerSec , maxBurst ) , } }

// ThrottledReader ensures that reads to `r` never exceeds a specified rate of
// bytes per second. The `maxBurst` duration changes how often the verification is
// done. The smaller the value, the less bursty, but also the more overhead there
// is to the throttling.

ThrottledReader ensures that reads to r never exceeds a specified rate of bytes per second . The maxBurst duration changes how often the verification is done . The smaller the value the less bursty but also the more overhead there is to the throttling .


func ThrottledWriter(w io.Writer, bytesPerSec int, maxBurst time.Duration) ThrottlerWriter {
	return &throttledWriter{
		wrap:    w,
		limiter: newRateLimiter(bytesPerSec, maxBurst),
	}
}

func ThrottledWriter ( w io . Writer , bytesPerSec int , maxBurst time . Duration ) ThrottlerWriter { return & throttledWriter { wrap : w , limiter : newRateLimiter ( bytesPerSec , maxBurst ) , } }

// ThrottledWriter ensures that writes to `w` never exceeds a specified rate of
// bytes per second. The `maxBurst` duration changes how often the verification is
// done. The smaller the value, the less bursty, but also the more overhead there
// is to the throttling.

ThrottledWriter ensures that writes to w never exceeds a specified rate of bytes per second . The maxBurst duration changes how often the verification is done . The smaller the value the less bursty but also the more overhead there is to the throttling .


func NewDNSServer(domain string) *DNSServer {
	return &DNSServer{
		Domain:     domain + ".",
		aRecords:   map[string]net.IP{},
		srvRecords: map[string][]SRVRecord{},
		aMutex:     sync.RWMutex{},
		srvMutex:   sync.RWMutex{},
	}
}

func NewDNSServer ( domain string ) * DNSServer { return & DNSServer { Domain : domain + " " , aRecords : map [ string ] net . IP { } , srvRecords : map [ string ] [ ] SRVRecord { } , aMutex : sync . RWMutex { } , srvMutex : sync . RWMutex { } , } }

// Create a new DNS server. Domain is an unqualified domain that will be used
// as the TLD.

Create a new DNS server . Domain is an unqualified domain that will be used as the TLD .


func (ds *DNSServer) qualifySrv(service, protocol string) string {
	return fmt.Sprintf("_%s._%s.%s", service, protocol, ds.Domain)
}

func ( ds * DNSServer ) qualifySrv ( service , protocol string ) string { return fmt . Sprintf ( " " , service , protocol , ds . Domain ) }

// Convenience function to ensure that SRV names are well-formed.

Convenience function to ensure that SRV names are well - formed .


func (ds *DNSServer) qualifySrvHosts(srvs []SRVRecord) []SRVRecord {
	newsrvs := []SRVRecord{}

	for _, srv := range srvs {
		newsrvs = append(newsrvs, SRVRecord{
			Host: ds.qualifyHost(srv.Host),
			Port: srv.Port,
		})
	}

	return newsrvs
}

func ( ds * DNSServer ) qualifySrvHosts ( srvs [ ] SRVRecord ) [ ] SRVRecord { newsrvs := [ ] SRVRecord { } for _ , srv := range srvs { newsrvs = append ( newsrvs , SRVRecord { Host : ds . qualifyHost ( srv . Host ) , Port : srv . Port , } ) } return newsrvs }

// rewrites supplied host entries to use the domain this dns server manages


func (ds *DNSServer) GetA(fqdn string) *dns.A {
	ds.aMutex.RLock()
	defer ds.aMutex.RUnlock()
	val, ok := ds.aRecords[fqdn]

	if ok {
		return &dns.A{
			Hdr: dns.RR_Header{
				Name:   fqdn,
				Rrtype: dns.TypeA,
				Class:  dns.ClassINET,
				// 0 TTL results in UB for DNS resolvers and generally causes problems.
				Ttl: 1,
			},
			A: val,
		}
	}

	return nil
}

// Receives a FQDN; looks up and supplies the A record.

Receives a FQDN ; looks up and supplies the A record .


func (ds *DNSServer) SetA(host string, ip net.IP) {
	ds.aMutex.Lock()
	ds.aRecords[ds.qualifyHost(host)] = ip
	ds.aMutex.Unlock()
}

func ( ds * DNSServer ) SetA ( host string , ip net . IP ) { ds . aMutex . Lock ( ) ds . aRecords [ ds . qualifyHost ( host ) ] = ip ds . aMutex . Unlock ( ) }

// Sets a host to an IP. Note that this is not the FQDN, but a hostname.

Sets a host to an IP . Note that this is not the FQDN but a hostname .


func (ds *DNSServer) DeleteA(host string) {
	ds.aMutex.Lock()
	delete(ds.aRecords, ds.qualifyHost(host))
	ds.aMutex.Unlock()
}

func ( ds * DNSServer ) DeleteA ( host string ) { ds . aMutex . Lock ( ) delete ( ds . aRecords , ds . qualifyHost ( host ) ) ds . aMutex . Unlock ( ) }

// Deletes a host. Note that this is not the FQDN, but a hostname.

Deletes a host . Note that this is not the FQDN but a hostname .