func (p *Message) ExpectsToReceive(description string) *Message {
	p.Description = description
	return p
}

func ( p * Message ) ExpectsToReceive ( description string ) * Message { p . Description = description return p }

// ExpectsToReceive specifies the content it is expecting to be
// given from the Provider. The function must be able to handle this
// message for the interaction to succeed.

ExpectsToReceive specifies the content it is expecting to be given from the Provider . The function must be able to handle this message for the interaction to succeed .


func (p *Message) WithMetadata(metadata MapMatcher) *Message {
	p.Metadata = metadata
	return p
}

func ( p * Message ) WithMetadata ( metadata MapMatcher ) * Message { p . Metadata = metadata return p }

// WithMetadata specifies message-implementation specific metadata
// to go with the content

WithMetadata specifies message - implementation specific metadata to go with the content


func (p *Message) AsType(t interface{}) *Message {
	fmt.Println("[DEBUG] setting Message decoding to type:", reflect.TypeOf(t))
	p.Type = t

	return p
}

func ( p * Message ) AsType ( t interface { } ) * Message { fmt . Println ( " " , reflect . TypeOf ( t ) ) p . Type = t return p }

// AsType specifies that the content sent through to the
// consumer handler should be sent as the given type

AsType specifies that the content sent through to the consumer handler should be sent as the given type


func UserLogin(c *gin.Context) {
	c.Header("X-Api-Correlation-Id", "1234")

	var json Login
	if c.BindJSON(&json) == nil {
		user, err := userRepository.ByUsername(json.User)
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{"status": "file not found"})
		} else if user.Username != json.User || user.Password != json.Password {
			c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
		} else {
			c.Header("X-Auth-Token", getAuthToken())
			c.JSON(http.StatusOK, types.LoginResponse{User: user})
		}
	}
}

func UserLogin ( c * gin . Context ) { c . Header ( " " , " " ) var json Login if c . BindJSON ( & json ) == nil { user , err := userRepository . ByUsername ( json . User ) if err != nil { c . JSON ( http . StatusNotFound , gin . H { " " : " " } ) } else if user . Username != json . User || user . Password != json . Password { c . JSON ( http . StatusUnauthorized , gin . H { " " : " " } ) } else { c . Header ( " " , getAuthToken ( ) ) c . JSON ( http . StatusOK , types . LoginResponse { User : user } ) } } }


func (s *S3) Region() string {
	region := os.Getenv("AWS_REGION")
	switch s.Domain {
	case "s3.amazonaws.com", "s3-external-1.amazonaws.com":
		return "us-east-1"
	case "s3-accelerate.amazonaws.com":
		if region == "" {
			panic("can't find endpoint region")
		}
		return region
	default:
		regions := regionMatcher.FindStringSubmatch(s.Domain)
		if len(regions) < 2 {
			if region == "" {
				panic("can't find endpoint region")
			}
			return region
		}
		return regions[1]
	}
}

func ( s * S3 ) Region ( ) string { region := os . Getenv ( " " ) switch s . Domain { case " " , " " : return " " case " " : if region == " " { panic ( " " ) } return region default : regions := regionMatcher . FindStringSubmatch ( s . Domain ) if len ( regions ) < 2 { if region == " " { panic ( " " ) } return region } return regions [ 1 ] } }

// Region returns the service region infering it from S3 domain.

Region returns the service region infering it from S3 domain .


func New(domain string, keys Keys) *S3 {
	if domain == "" {
		domain = DefaultDomain
	}
	return &S3{domain, keys}
}

func New ( domain string , keys Keys ) * S3 { if domain == " " { domain = DefaultDomain } return & S3 { domain , keys } }

// New Returns a new S3
// domain defaults to DefaultDomain if empty

New Returns a new S3 domain defaults to DefaultDomain if empty


func (s *S3) Bucket(name string) *Bucket {
	return &Bucket{
		S3:     s,
		Name:   name,
		Config: DefaultConfig,
	}
}

func ( s * S3 ) Bucket ( name string ) * Bucket { return & Bucket { S3 : s , Name : name , Config : DefaultConfig , } }

// Bucket returns a bucket on s3
// Bucket Config is initialized to DefaultConfig

Bucket returns a bucket on s3 Bucket Config is initialized to DefaultConfig


func (b *Bucket) PutWriter(path string, h http.Header, c *Config) (w io.WriteCloser, err error) {
	if c == nil {
		c = b.conf()
	}
	u, err := b.url(path, c)
	if err != nil {
		return nil, err
	}

	return newPutter(*u, h, c, b)
}

func ( b * Bucket ) PutWriter ( path string , h http . Header , c * Config ) ( w io . WriteCloser , err error ) { if c == nil { c = b . conf ( ) } u , err := b . url ( path , c ) if err != nil { return nil , err } return newPutter ( * u , h , c , b ) }

// PutWriter provides a writer to upload data as multipart upload requests.
//
// Each header in h is added to the HTTP request header. This is useful for specifying
// options such as server-side encryption in metadata as well as custom user metadata.
// DefaultConfig is used if c is nil.
// Callers should call Close on w to ensure that all resources are released.

PutWriter provides a writer to upload data as multipart upload requests . Each header in h is added to the HTTP request header . This is useful for specifying options such as server - side encryption in metadata as well as custom user metadata . DefaultConfig is used if c is nil . Callers should call Close on w to ensure that all resources are released .


func (b *Bucket) url(bPath string, c *Config) (*url.URL, error) {

	// parse versionID parameter from path, if included
	// See https://github.com/rlmcpherson/s3gof3r/issues/84 for rationale
	purl, err := url.Parse(bPath)
	if err != nil {
		return nil, err
	}
	var vals url.Values
	if v := purl.Query().Get(versionParam); v != "" {
		vals = make(url.Values)
		vals.Add(versionParam, v)
		bPath = strings.Split(bPath, "?")[0] // remove versionID from path
	}

	// handling for bucket names containing periods / explicit PathStyle addressing
	// http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html for details
	if strings.Contains(b.Name, ".") || c.PathStyle {
		return &url.URL{
			Host:     b.S3.Domain,
			Scheme:   c.Scheme,
			Path:     path.Clean(fmt.Sprintf("/%s/%s", b.Name, bPath)),
			RawQuery: vals.Encode(),
		}, nil
	} else {
		return &url.URL{
			Scheme:   c.Scheme,
			Path:     path.Clean(fmt.Sprintf("/%s", bPath)),
			Host:     path.Clean(fmt.Sprintf("%s.%s", b.Name, b.S3.Domain)),
			RawQuery: vals.Encode(),
		}, nil
	}
}

// url returns a parsed url to the given path. c must not be nil

url returns a parsed url to the given path . c must not be nil


func SetLogger(out io.Writer, prefix string, flag int, debug bool) {
	logger = internalLogger{
		log.New(out, prefix, flag),
		debug,
	}
}

func SetLogger ( out io . Writer , prefix string , flag int , debug bool ) { logger = internalLogger { log . New ( out , prefix , flag ) , debug , } }

// SetLogger wraps the standard library log package.
//
// It allows the internal logging of s3gof3r to be set to a desired output and format.
// Setting debug to true enables debug logging output. s3gof3r does not log output by default.

SetLogger wraps the standard library log package . It allows the internal logging of s3gof3r to be set to a desired output and format . Setting debug to true enables debug logging output . s3gof3r does not log output by default .


func InstanceKeys() (keys Keys, err error) {

	rolePath := "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
	var creds mdCreds

	// request the role name for the instance
	// assumes there is only one
	resp, err := ClientWithTimeout(2 * time.Second).Get(rolePath)
	if err != nil {
		return
	}
	defer checkClose(resp.Body, err)
	if resp.StatusCode != 200 {
		err = newRespError(resp)
		return
	}
	role, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return
	}

	// request the credential metadata for the role
	resp, err = http.Get(rolePath + string(role))
	if err != nil {
		return
	}
	defer checkClose(resp.Body, err)
	if resp.StatusCode != 200 {
		err = newRespError(resp)
		return
	}
	metadata, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}

	if err = json.Unmarshal([]byte(metadata), &creds); err != nil {
		return
	}
	keys = Keys{
		AccessKey:     creds.AccessKeyID,
		SecretKey:     creds.SecretAccessKey,
		SecurityToken: creds.Token,
	}

	return
}

// InstanceKeys Requests the AWS keys from the instance-based metadata on EC2
// Assumes only one IAM role.

InstanceKeys Requests the AWS keys from the instance - based metadata on EC2 Assumes only one IAM role .


func EnvKeys() (keys Keys, err error) {
	keys = Keys{
		AccessKey:     os.Getenv("AWS_ACCESS_KEY_ID"),
		SecretKey:     os.Getenv("AWS_SECRET_ACCESS_KEY"),
		SecurityToken: os.Getenv("AWS_SECURITY_TOKEN"),
	}
	if keys.AccessKey == "" || keys.SecretKey == "" {
		err = fmt.Errorf("keys not set in environment: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY")
	}
	return
}

func EnvKeys ( ) ( keys Keys , err error ) { keys = Keys { AccessKey : os . Getenv ( " " ) , SecretKey : os . Getenv ( " " ) , SecurityToken : os . Getenv ( " " ) , } if keys . AccessKey == " " || keys . SecretKey == " " { err = fmt . Errorf ( " " ) } return }

// EnvKeys Reads the AWS keys from the environment


func (b *Bucket) Sign(req *http.Request) {
	if req.Header == nil {
		req.Header = http.Header{}
	}
	if b.S3.Keys.SecurityToken != "" {
		req.Header.Set("X-Amz-Security-Token", b.S3.Keys.SecurityToken)
	}
	req.Header.Set("User-Agent", "S3Gof3r")
	s := &signer{
		Time:    time.Now(),
		Request: req,
		Region:  b.S3.Region(),
		Keys:    b.S3.Keys,
	}
	s.sign()
}

func ( b * Bucket ) Sign ( req * http . Request ) { if req . Header == nil { req . Header = http . Header { } } if b . S3 . Keys . SecurityToken != " " { req . Header . Set ( " " , b . S3 . Keys . SecurityToken ) } req . Header . Set ( " " , " " ) s := & signer { Time : time . Now ( ) , Request : req , Region : b . S3 . Region ( ) , Keys : b . S3 . Keys , } s . sign ( ) }


func getAWSKeys() (keys s3gof3r.Keys, err error) {

	keys, err = s3gof3r.EnvKeys()
	if err == nil {
		return
	}
	keys, err = s3gof3r.InstanceKeys()
	if err == nil {
		return
	}
	err = errors.New("no AWS keys found")
	return
}

func getAWSKeys ( ) ( keys s3gof3r . Keys , err error ) { keys , err = s3gof3r . EnvKeys ( ) if err == nil { return } keys , err = s3gof3r . InstanceKeys ( ) if err == nil { return } err = errors . New ( " " ) return }

// getAWSKeys gets the AWS Keys from environment variables or the instance-based metadata on EC2
// Environment variables are attempted first, followed by the instance-based credentials.

getAWSKeys gets the AWS Keys from environment variables or the instance - based metadata on EC2 Environment variables are attempted first followed by the instance - based credentials .


func homeDir() (string, error) {
	if h := os.Getenv("HOME"); h != "" {
		return h, nil
	}
	h, err := exec.Command("sh", "-c", "eval echo ~$USER").Output()
	if err == nil && len(h) > 0 {
		return strings.TrimSpace(string(h)), nil
	}
	return "", fmt.Errorf("home directory not found for current user")
}

func homeDir ( ) ( string , error ) { if h := os . Getenv ( " " ) ; h != " " { return h , nil } h , err := exec . Command ( " " , " " , " " ) . Output ( ) if err == nil && len ( h ) > 0 { return strings . TrimSpace ( string ( h ) ) , nil } return " " , fmt . Errorf ( " " ) }


func ACL(h http.Header, acl string) http.Header {
	if acl != "" {
		h.Set("x-amz-acl", acl)
	}
	return h
}

func ACL ( h http . Header , acl string ) http . Header { if acl != " " { h . Set ( " " , acl ) } return h }


func (p *putter) putPart(part *part) error {
	v := url.Values{}
	v.Set("partNumber", strconv.Itoa(part.PartNumber))
	v.Set("uploadId", p.UploadID)
	if _, err := part.r.Seek(0, 0); err != nil { // move back to beginning, if retrying
		return err
	}
	req, err := http.NewRequest("PUT", p.url.String()+"?"+v.Encode(), part.r)
	if err != nil {
		return err
	}
	req.ContentLength = part.len
	req.Header.Set(md5Header, part.md5)
	req.Header.Set(sha256Header, part.sha256)
	p.b.Sign(req)
	resp, err := p.c.Client.Do(req)
	if err != nil {
		return err
	}
	defer checkClose(resp.Body, err)
	if resp.StatusCode != 200 {
		return newRespError(resp)
	}
	s := resp.Header.Get("etag")
	if len(s) < 2 {
		return fmt.Errorf("Got Bad etag:%s", s)
	}
	s = s[1 : len(s)-1] // includes quote chars for some reason
	if part.ETag != s {
		return fmt.Errorf("Response etag does not match. Remote:%s Calculated:%s", s, p.ETag)
	}
	return nil
}

func
(
p
*
putter
)
putPart
(
part
*
part
)
error
{
v
:=
url
.
Values
{
}
v
.
Set
(
"
"
,
strconv
.
Itoa
(
part
.
PartNumber
)
)
v
.
Set
(
"
"
,
p
.
UploadID
)
if
_
,
err
:=
part
.
r
.
Seek
(
0
,
0
)
;
err
!=
{
// move back to beginning, if retrying
return
err
}
req
,
err
:=
http
.
NewRequest
(
"
"
,
p
.
url
.
String
(
)
+
"
"
+
v
.
Encode
(
)
,
part
.
r
)
if
err
!=
{
return
err
}
req
.
ContentLength
=
part
.
len
req
.
Header
.
Set
(
md5Header
,
part
.
md5
)
req
.
Header
.
Set
(
sha256Header
,
part
.
sha256
)
p
.
b
.
Sign
(
req
)
resp
,
err
:=
p
.
c
.
Client
.
Do
(
req
)
if
err
!=
{
return
err
}
defer
checkClose
(
resp
.
Body
,
err
)
if
resp
.
StatusCode
!=
200
{
return
newRespError
(
resp
)
}
s
:=
resp
.
Header
.
Get
(
"
"
)
if
len
(
s
)
<
2
{
return
fmt
.
Errorf
(
"
"
,
s
)
}
s
=
s
[
1
:
len
(
s
)
1
]
// includes quote chars for some reason
if
part
.
ETag
!=
s
{
return
fmt
.
Errorf
(
"
"
,
s
,
p
.
ETag
)
}
return
}

// uploads a part, checking the etag against the calculated value

uploads a part checking the etag against the calculated value


func (p *putter) abort() {
	v := url.Values{}
	v.Set("uploadId", p.UploadID)
	s := p.url.String() + "?" + v.Encode()
	resp, err := p.retryRequest("DELETE", s, nil, nil)
	if err != nil {
		logger.Printf("Error aborting multipart upload: %v\n", err)
		return
	}
	defer checkClose(resp.Body, err)
	if resp.StatusCode != 204 {
		logger.Printf("Error aborting multipart upload: %v", newRespError(resp))
	}
	return
}

func ( p * putter ) abort ( ) { v := url . Values { } v . Set ( " " , p . UploadID ) s := p . url . String ( ) + " " + v . Encode ( ) resp , err := p . retryRequest ( " " , s , nil , nil ) if err != nil { logger . Printf ( " \n " , err ) return } defer checkClose ( resp . Body , err ) if resp . StatusCode != 204 { logger . Printf ( " " , newRespError ( resp ) ) } return }

// Try to abort multipart upload. Do not error on failure.

Try to abort multipart upload . Do not error on failure .


func growPartSize(partIndex int, partSize, putsz int64) bool {
	return (maxObjSize-putsz)/(maxNPart-int64(partIndex)) > partSize
}

func growPartSize ( partIndex int , partSize , putsz int64 ) bool { return ( maxObjSize - putsz ) / ( maxNPart - int64 ( partIndex ) ) > partSize }

// returns true unless partSize is large enough
// to achieve maxObjSize with remaining parts

returns true unless partSize is large enough to achieve maxObjSize with remaining parts


func CheckDisallowed(prefix string, spec interface{}) error {
	infos, err := gatherInfo(prefix, spec)
	if err != nil {
		return err
	}

	vars := make(map[string]struct{})
	for _, info := range infos {
		vars[info.Key] = struct{}{}
	}

	if prefix != "" {
		prefix = strings.ToUpper(prefix) + "_"
	}

	for _, env := range os.Environ() {
		if !strings.HasPrefix(env, prefix) {
			continue
		}
		v := strings.SplitN(env, "=", 2)[0]
		if _, found := vars[v]; !found {
			return fmt.Errorf("unknown environment variable %s", v)
		}
	}

	return nil
}

func CheckDisallowed ( prefix string , spec interface { } ) error { infos , err := gatherInfo ( prefix , spec ) if err != nil { return err } vars := make ( map [ string ] struct { } ) for _ , info := range infos { vars [ info . Key ] = struct { } { } } if prefix != " " { prefix = strings . ToUpper ( prefix ) + " " } for _ , env := range os . Environ ( ) { if ! strings . HasPrefix ( env , prefix ) { continue } v := strings . SplitN ( env , " " , 2 ) [ 0 ] if _ , found := vars [ v ] ; ! found { return fmt . Errorf ( " " , v ) } } return nil }

// CheckDisallowed checks that no environment variables with the prefix are set
// that we don't know how or want to parse. This is likely only meaningful with
// a non-empty prefix.

CheckDisallowed checks that no environment variables with the prefix are set that we don t know how or want to parse . This is likely only meaningful with a non - empty prefix .


func Process(prefix string, spec interface{}) error {
	infos, err := gatherInfo(prefix, spec)

	for _, info := range infos {

		// `os.Getenv` cannot differentiate between an explicitly set empty value
		// and an unset value. `os.LookupEnv` is preferred to `syscall.Getenv`,
		// but it is only available in go1.5 or newer. We're using Go build tags
		// here to use os.LookupEnv for >=go1.5
		value, ok := lookupEnv(info.Key)
		if !ok && info.Alt != "" {
			value, ok = lookupEnv(info.Alt)
		}

		def := info.Tags.Get("default")
		if def != "" && !ok {
			value = def
		}

		req := info.Tags.Get("required")
		if !ok && def == "" {
			if isTrue(req) {
				return fmt.Errorf("required key %s missing value", info.Key)
			}
			continue
		}

		err = processField(value, info.Field)
		if err != nil {
			return &ParseError{
				KeyName:   info.Key,
				FieldName: info.Name,
				TypeName:  info.Field.Type().String(),
				Value:     value,
				Err:       err,
			}
		}
	}

	return err
}

// Process populates the specified struct based on environment variables


func MustProcess(prefix string, spec interface{}) {
	if err := Process(prefix, spec); err != nil {
		panic(err)
	}
}

func MustProcess ( prefix string , spec interface { } ) { if err := Process ( prefix , spec ) ; err != nil { panic ( err ) } }

// MustProcess is the same as Process but panics if an error occurs


func toTypeDescription(t reflect.Type) string {
	switch t.Kind() {
	case reflect.Array, reflect.Slice:
		return fmt.Sprintf("Comma-separated list of %s", toTypeDescription(t.Elem()))
	case reflect.Map:
		return fmt.Sprintf(
			"Comma-separated list of %s:%s pairs",
			toTypeDescription(t.Key()),
			toTypeDescription(t.Elem()),
		)
	case reflect.Ptr:
		return toTypeDescription(t.Elem())
	case reflect.Struct:
		if implementsInterface(t) && t.Name() != "" {
			return t.Name()
		}
		return ""
	case reflect.String:
		name := t.Name()
		if name != "" && name != "string" {
			return name
		}
		return "String"
	case reflect.Bool:
		name := t.Name()
		if name != "" && name != "bool" {
			return name
		}
		return "True or False"
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		name := t.Name()
		if name != "" && !strings.HasPrefix(name, "int") {
			return name
		}
		return "Integer"
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		name := t.Name()
		if name != "" && !strings.HasPrefix(name, "uint") {
			return name
		}
		return "Unsigned Integer"
	case reflect.Float32, reflect.Float64:
		name := t.Name()
		if name != "" && !strings.HasPrefix(name, "float") {
			return name
		}
		return "Float"
	}
	return fmt.Sprintf("%+v", t)
}

func toTypeDescription ( t reflect . Type ) string { switch t . Kind ( ) { case reflect . Array , reflect . Slice : return fmt . Sprintf ( " " , toTypeDescription ( t . Elem ( ) ) ) case reflect . Map : return fmt . Sprintf ( " " , toTypeDescription ( t . Key ( ) ) , toTypeDescription ( t . Elem ( ) ) , ) case reflect . Ptr : return toTypeDescription ( t . Elem ( ) ) case reflect . Struct : if implementsInterface ( t ) && t . Name ( ) != " " { return t . Name ( ) } return " " case reflect . String : name := t . Name ( ) if name != " " && name != " " { return name } return " " case reflect . Bool : name := t . Name ( ) if name != " " && name != " " { return name } return " " case reflect . Int , reflect . Int8 , reflect . Int16 , reflect . Int32 , reflect . Int64 : name := t . Name ( ) if name != " " && ! strings . HasPrefix ( name , " " ) { return name } return " " case reflect . Uint , reflect . Uint8 , reflect . Uint16 , reflect . Uint32 , reflect . Uint64 : name := t . Name ( ) if name != " " && ! strings . HasPrefix ( name , " " ) { return name } return " " case reflect . Float32 , reflect . Float64 : name := t . Name ( ) if name != " " && ! strings . HasPrefix ( name , " " ) { return name } return " " } return fmt . Sprintf ( " " , t ) }

// toTypeDescription converts Go types into a human readable description


func Usage(prefix string, spec interface{}) error {
	// The default is to output the usage information as a table
	// Create tabwriter instance to support table output
	tabs := tabwriter.NewWriter(os.Stdout, 1, 0, 4, ' ', 0)

	err := Usagef(prefix, spec, tabs, DefaultTableFormat)
	tabs.Flush()
	return err
}

// Usage writes usage information to stderr using the default header and table format


func Usagef(prefix string, spec interface{}, out io.Writer, format string) error {

	// Specify the default usage template functions
	functions := template.FuncMap{
		"usage_key":         func(v varInfo) string { return v.Key },
		"usage_description": func(v varInfo) string { return v.Tags.Get("desc") },
		"usage_type":        func(v varInfo) string { return toTypeDescription(v.Field.Type()) },
		"usage_default":     func(v varInfo) string { return v.Tags.Get("default") },
		"usage_required": func(v varInfo) (string, error) {
			req := v.Tags.Get("required")
			if req != "" {
				reqB, err := strconv.ParseBool(req)
				if err != nil {
					return "", err
				}
				if reqB {
					req = "true"
				}
			}
			return req, nil
		},
	}

	tmpl, err := template.New("envconfig").Funcs(functions).Parse(format)
	if err != nil {
		return err
	}

	return Usaget(prefix, spec, out, tmpl)
}

// Usagef writes usage information to the specified io.Writer using the specifed template specification

Usagef writes usage information to the specified io . Writer using the specifed template specification


func Usaget(prefix string, spec interface{}, out io.Writer, tmpl *template.Template) error {
	// gather first
	infos, err := gatherInfo(prefix, spec)
	if err != nil {
		return err
	}

	return tmpl.Execute(out, infos)
}

func
Usaget
(
prefix
string
,
spec
interface
{
}
,
out
io
.
Writer
,
tmpl
*
template
.
Template
)
error
{
// gather first
infos
,
err
:=
gatherInfo
(
prefix
,
spec
)
if
err
!=
{
return
err
}
return
tmpl
.
Execute
(
out
,
infos
)
}

// Usaget writes usage information to the specified io.Writer using the specified template

Usaget writes usage information to the specified io . Writer using the specified template


func (t *Time) Scan(value interface{}) error {
	var err error
	switch x := value.(type) {
	case time.Time:
		t.Time = x
	case nil:
		t.Valid = false
		return nil
	default:
		err = fmt.Errorf("null: cannot scan type %T into null.Time: %v", value, value)
	}
	t.Valid = err == nil
	return err
}

func ( t * Time ) Scan ( value interface { } ) error { var err error switch x := value . ( type ) { case time . Time : t . Time = x case nil : t . Valid = false return nil default : err = fmt . Errorf ( " " , value , value ) } t . Valid = err == nil return err }

// Scan implements the Scanner interface.


func (t Time) Value() (driver.Value, error) {
	if !t.Valid {
		return nil, nil
	}
	return t.Time, nil
}

func ( t Time ) Value ( ) ( driver . Value , error ) { if ! t . Valid { return nil , nil } return t . Time , nil }

// Value implements the driver Valuer interface.

Value implements the driver Valuer interface .


func NewTime(t time.Time, valid bool) Time {
	return Time{
		Time:  t,
		Valid: valid,
	}
}

func NewTime ( t time . Time , valid bool ) Time { return Time { Time : t , Valid : valid , } }


func TimeFromPtr(t *time.Time) Time {
	if t == nil {
		return NewTime(time.Time{}, false)
	}
	return NewTime(*t, true)
}

func TimeFromPtr ( t * time . Time ) Time { if t == nil { return NewTime ( time . Time { } , false ) } return NewTime ( * t , true ) }

// TimeFromPtr creates a new Time that will be null if t is nil.

TimeFromPtr creates a new Time that will be null if t is nil .


func (t Time) ValueOrZero() time.Time {
	if !t.Valid {
		return time.Time{}
	}
	return t.Time
}

func ( t Time ) ValueOrZero ( ) time . Time { if ! t . Valid { return time . Time { } } return t . Time }

// ValueOrZero returns the inner value if valid, otherwise zero.

ValueOrZero returns the inner value if valid otherwise zero .


func (t Time) MarshalJSON() ([]byte, error) {
	if !t.Valid {
		return []byte("null"), nil
	}
	return t.Time.MarshalJSON()
}

func ( t Time ) MarshalJSON ( ) ( [ ] byte , error ) { if ! t . Valid { return [ ] byte ( " " ) , nil } return t . Time . MarshalJSON ( ) }

// MarshalJSON implements json.Marshaler.
// It will encode null if this time is null.

MarshalJSON implements json . Marshaler . It will encode null if this time is null .


func (t *Time) SetValid(v time.Time) {
	t.Time = v
	t.Valid = true
}

func ( t * Time ) SetValid ( v time . Time ) { t . Time = v t . Valid = true }

// SetValid changes this Time's value and sets it to be non-null.

SetValid changes this Time s value and sets it to be non - null .


func (t Time) Ptr() *time.Time {
	if !t.Valid {
		return nil
	}
	return &t.Time
}

func ( t Time ) Ptr ( ) * time . Time { if ! t . Valid { return nil } return & t . Time }

// Ptr returns a pointer to this Time's value, or a nil pointer if this Time is null.

Ptr returns a pointer to this Time s value or a nil pointer if this Time is null .


func NewBool(b bool, valid bool) Bool {
	return Bool{
		NullBool: sql.NullBool{
			Bool:  b,
			Valid: valid,
		},
	}
}

func NewBool ( b bool , valid bool ) Bool { return Bool { NullBool : sql . NullBool { Bool : b , Valid : valid , } , } }


func BoolFromPtr(b *bool) Bool {
	if b == nil {
		return NewBool(false, false)
	}
	return NewBool(*b, true)
}

func BoolFromPtr ( b * bool ) Bool { if b == nil { return NewBool ( false , false ) } return NewBool ( * b , true ) }

// BoolFromPtr creates a new Bool that will be null if f is nil.

BoolFromPtr creates a new Bool that will be null if f is nil .


func (b *Bool) UnmarshalJSON(data []byte) error {
	var err error
	var v interface{}
	if err = json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch x := v.(type) {
	case bool:
		b.Bool = x
	case map[string]interface{}:
		err = json.Unmarshal(data, &b.NullBool)
	case nil:
		b.Valid = false
		return nil
	default:
		err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Bool", reflect.TypeOf(v).Name())
	}
	b.Valid = err == nil
	return err
}

func ( b * Bool ) UnmarshalJSON ( data [ ] byte ) error { var err error var v interface { } if err = json . Unmarshal ( data , & v ) ; err != nil { return err } switch x := v . ( type ) { case bool : b . Bool = x case map [ string ] interface { } : err = json . Unmarshal ( data , & b . NullBool ) case nil : b . Valid = false return nil default : err = fmt . Errorf ( " " , reflect . TypeOf ( v ) . Name ( ) ) } b . Valid = err == nil return err }

// UnmarshalJSON implements json.Unmarshaler.
// It supports number and null input.
// 0 will not be considered a null Bool.
// It also supports unmarshalling a sql.NullBool.

UnmarshalJSON implements json . Unmarshaler . It supports number and null input . 0 will not be considered a null Bool . It also supports unmarshalling a sql . NullBool .


func (b *Bool) UnmarshalText(text []byte) error {
	str := string(text)
	switch str {
	case "", "null":
		b.Valid = false
		return nil
	case "true":
		b.Bool = true
	case "false":
		b.Bool = false
	default:
		b.Valid = false
		return errors.New("invalid input:" + str)
	}
	b.Valid = true
	return nil
}

func ( b * Bool ) UnmarshalText ( text [ ] byte ) error { str := string ( text ) switch str { case " " , " " : b . Valid = false return nil case " " : b . Bool = true case " " : b . Bool = false default : b . Valid = false return errors . New ( " " + str ) } b . Valid = true return nil }

// UnmarshalText implements encoding.TextUnmarshaler.
// It will unmarshal to a null Bool if the input is a blank or not an integer.
// It will return an error if the input is not an integer, blank, or "null".

UnmarshalText implements encoding . TextUnmarshaler . It will unmarshal to a null Bool if the input is a blank or not an integer . It will return an error if the input is not an integer blank or null .


func (b Bool) MarshalJSON() ([]byte, error) {
	if !b.Valid {
		return []byte("null"), nil
	}
	if !b.Bool {
		return []byte("false"), nil
	}
	return []byte("true"), nil
}

func ( b Bool ) MarshalJSON ( ) ( [ ] byte , error ) { if ! b . Valid { return [ ] byte ( " " ) , nil } if ! b . Bool { return [ ] byte ( " " ) , nil } return [ ] byte ( " " ) , nil }

// MarshalJSON implements json.Marshaler.
// It will encode null if this Bool is null.

MarshalJSON implements json . Marshaler . It will encode null if this Bool is null .


func (b *Bool) SetValid(v bool) {
	b.Bool = v
	b.Valid = true
}

func ( b * Bool ) SetValid ( v bool ) { b . Bool = v b . Valid = true }

// SetValid changes this Bool's value and also sets it to be non-null.

SetValid changes this Bool s value and also sets it to be non - null .


func NewString(s string, valid bool) String {
	return String{
		NullString: sql.NullString{
			String: s,
			Valid:  valid,
		},
	}
}

func NewString ( s string , valid bool ) String { return String { NullString : sql . NullString { String : s , Valid : valid , } , } }


func (s *String) UnmarshalJSON(data []byte) error {
	var err error
	var v interface{}
	if err = json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch x := v.(type) {
	case string:
		s.String = x
	case map[string]interface{}:
		err = json.Unmarshal(data, &s.NullString)
	case nil:
		s.Valid = false
		return nil
	default:
		err = fmt.Errorf("json: cannot unmarshal %v into Go value of type zero.String", reflect.TypeOf(v).Name())
	}
	s.Valid = (err == nil) && (s.String != "")
	return err
}

func ( s * String ) UnmarshalJSON ( data [ ] byte ) error { var err error var v interface { } if err = json . Unmarshal ( data , & v ) ; err != nil { return err } switch x := v . ( type ) { case string : s . String = x case map [ string ] interface { } : err = json . Unmarshal ( data , & s . NullString ) case nil : s . Valid = false return nil default : err = fmt . Errorf ( " " , reflect . TypeOf ( v ) . Name ( ) ) } s . Valid = ( err == nil ) && ( s . String != " " ) return err }

// UnmarshalJSON implements json.Unmarshaler.
// It supports string and null input. Blank string input produces a null String.
// It also supports unmarshalling a sql.NullString.

UnmarshalJSON implements json . Unmarshaler . It supports string and null input . Blank string input produces a null String . It also supports unmarshalling a sql . NullString .


func (s String) MarshalText() ([]byte, error) {
	if !s.Valid {
		return []byte{}, nil
	}
	return []byte(s.String), nil
}

func ( s String ) MarshalText ( ) ( [ ] byte , error ) { if ! s . Valid { return [ ] byte { } , nil } return [ ] byte ( s . String ) , nil }

// MarshalText implements encoding.TextMarshaler.
// It will encode a blank string when this String is null.

MarshalText implements encoding . TextMarshaler . It will encode a blank string when this String is null .


func (s *String) UnmarshalText(text []byte) error {
	s.String = string(text)
	s.Valid = s.String != ""
	return nil
}

func ( s * String ) UnmarshalText ( text [ ] byte ) error { s . String = string ( text ) s . Valid = s . String != " " return nil }

// UnmarshalText implements encoding.TextUnmarshaler.
// It will unmarshal to a null String if the input is a blank string.

UnmarshalText implements encoding . TextUnmarshaler . It will unmarshal to a null String if the input is a blank string .


func (s *String) SetValid(v string) {
	s.String = v
	s.Valid = true
}

func ( s * String ) SetValid ( v string ) { s . String = v s . Valid = true }

// SetValid changes this String's value and also sets it to be non-null.

SetValid changes this String s value and also sets it to be non - null .


func StringFromPtr(s *string) String {
	if s == nil {
		return NewString("", false)
	}
	return NewString(*s, true)
}

func StringFromPtr ( s * string ) String { if s == nil { return NewString ( " " , false ) } return NewString ( * s , true ) }

// StringFromPtr creates a new String that be null if s is nil.

StringFromPtr creates a new String that be null if s is nil .


func (s String) MarshalJSON() ([]byte, error) {
	if !s.Valid {
		return []byte("null"), nil
	}
	return json.Marshal(s.String)
}

func ( s String ) MarshalJSON ( ) ( [ ] byte , error ) { if ! s . Valid { return [ ] byte ( " " ) , nil } return json . Marshal ( s . String ) }

// MarshalJSON implements json.Marshaler.
// It will encode null if this String is null.

MarshalJSON implements json . Marshaler . It will encode null if this String is null .


func NewInt(i int64, valid bool) Int {
	return Int{
		NullInt64: sql.NullInt64{
			Int64: i,
			Valid: valid,
		},
	}
}

func NewInt ( i int64 , valid bool ) Int { return Int { NullInt64 : sql . NullInt64 { Int64 : i , Valid : valid , } , } }


func IntFromPtr(i *int64) Int {
	if i == nil {
		return NewInt(0, false)
	}
	n := NewInt(*i, true)
	return n
}

func IntFromPtr ( i * int64 ) Int { if i == nil { return NewInt ( 0 , false ) } n := NewInt ( * i , true ) return n }

// IntFromPtr creates a new Int that be null if i is nil.

IntFromPtr creates a new Int that be null if i is nil .


func (i *Int) UnmarshalJSON(data []byte) error {
	var err error
	var v interface{}
	if err = json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch x := v.(type) {
	case float64:
		// Unmarshal again, directly to int64, to avoid intermediate float64
		err = json.Unmarshal(data, &i.Int64)
	case string:
		str := string(x)
		if len(str) == 0 {
			i.Valid = false
			return nil
		}
		i.Int64, err = strconv.ParseInt(str, 10, 64)
	case map[string]interface{}:
		err = json.Unmarshal(data, &i.NullInt64)
	case nil:
		i.Valid = false
		return nil
	default:
		err = fmt.Errorf("json: cannot unmarshal %v into Go value of type zero.Int", reflect.TypeOf(v).Name())
	}
	i.Valid = (err == nil) && (i.Int64 != 0)
	return err
}

// UnmarshalJSON implements json.Unmarshaler.
// It supports number and null input.
// 0 will be considered a null Int.
// It also supports unmarshalling a sql.NullInt64.

UnmarshalJSON implements json . Unmarshaler . It supports number and null input . 0 will be considered a null Int . It also supports unmarshalling a sql . NullInt64 .


func (i Int) MarshalText() ([]byte, error) {
	n := i.Int64
	if !i.Valid {
		n = 0
	}
	return []byte(strconv.FormatInt(n, 10)), nil
}

func ( i Int ) MarshalText ( ) ( [ ] byte , error ) { n := i . Int64 if ! i . Valid { n = 0 } return [ ] byte ( strconv . FormatInt ( n , 10 ) ) , nil }

// MarshalText implements encoding.TextMarshaler.
// It will encode a zero if this Int is null.

MarshalText implements encoding . TextMarshaler . It will encode a zero if this Int is null .


func (i *Int) SetValid(n int64) {
	i.Int64 = n
	i.Valid = true
}

func ( i * Int ) SetValid ( n int64 ) { i . Int64 = n i . Valid = true }

// SetValid changes this Int's value and also sets it to be non-null.

SetValid changes this Int s value and also sets it to be non - null .


func (i *Int) UnmarshalText(text []byte) error {
	str := string(text)
	if str == "" || str == "null" {
		i.Valid = false
		return nil
	}
	var err error
	i.Int64, err = strconv.ParseInt(string(text), 10, 64)
	i.Valid = err == nil
	return err
}

func ( i * Int ) UnmarshalText ( text [ ] byte ) error { str := string ( text ) if str == " " || str == " " { i . Valid = false return nil } var err error i . Int64 , err = strconv . ParseInt ( string ( text ) , 10 , 64 ) i . Valid = err == nil return err }

// UnmarshalText implements encoding.TextUnmarshaler.
// It will unmarshal to a null Int if the input is a blank or not an integer.
// It will return an error if the input is not an integer, blank, or "null".

UnmarshalText implements encoding . TextUnmarshaler . It will unmarshal to a null Int if the input is a blank or not an integer . It will return an error if the input is not an integer blank or null .


func (b Bool) MarshalText() ([]byte, error) {
	if !b.Valid || !b.Bool {
		return []byte("false"), nil
	}
	return []byte("true"), nil
}

func ( b Bool ) MarshalText ( ) ( [ ] byte , error ) { if ! b . Valid || ! b . Bool { return [ ] byte ( " " ) , nil } return [ ] byte ( " " ) , nil }

// MarshalText implements encoding.TextMarshaler.
// It will encode a zero if this Bool is null.

MarshalText implements encoding . TextMarshaler . It will encode a zero if this Bool is null .


func (f *Float) SetValid(v float64) {
	f.Float64 = v
	f.Valid = true
}

func ( f * Float ) SetValid ( v float64 ) { f . Float64 = v f . Valid = true }

// SetValid changes this Float's value and also sets it to be non-null.

SetValid changes this Float s value and also sets it to be non - null .


func (t Time) MarshalJSON() ([]byte, error) {
	if !t.Valid {
		return (time.Time{}).MarshalJSON()
	}
	return t.Time.MarshalJSON()
}

func ( t Time ) MarshalJSON ( ) ( [ ] byte , error ) { if ! t . Valid { return ( time . Time { } ) . MarshalJSON ( ) } return t . Time . MarshalJSON ( ) }

// MarshalJSON implements json.Marshaler.
// It will encode the zero value of time.Time
// if this time is invalid.

MarshalJSON implements json . Marshaler . It will encode the zero value of time . Time if this time is invalid .


func (f *Float) UnmarshalJSON(data []byte) error {
	var err error
	var v interface{}
	if err = json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch x := v.(type) {
	case float64:
		f.Float64 = float64(x)
	case string:
		str := string(x)
		if len(str) == 0 {
			f.Valid = false
			return nil
		}
		f.Float64, err = strconv.ParseFloat(str, 64)
	case map[string]interface{}:
		err = json.Unmarshal(data, &f.NullFloat64)
	case nil:
		f.Valid = false
		return nil
	default:
		err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Float", reflect.TypeOf(v).Name())
	}
	f.Valid = err == nil
	return err
}

func ( f * Float ) UnmarshalJSON ( data [ ] byte ) error { var err error var v interface { } if err = json . Unmarshal ( data , & v ) ; err != nil { return err } switch x := v . ( type ) { case float64 : f . Float64 = float64 ( x ) case string : str := string ( x ) if len ( str ) == 0 { f . Valid = false return nil } f . Float64 , err = strconv . ParseFloat ( str , 64 ) case map [ string ] interface { } : err = json . Unmarshal ( data , & f . NullFloat64 ) case nil : f . Valid = false return nil default : err = fmt . Errorf ( " " , reflect . TypeOf ( v ) . Name ( ) ) } f . Valid = err == nil return err }

// UnmarshalJSON implements json.Unmarshaler.
// It supports number and null input.
// 0 will not be considered a null Float.
// It also supports unmarshalling a sql.NullFloat64.

UnmarshalJSON implements json . Unmarshaler . It supports number and null input . 0 will not be considered a null Float . It also supports unmarshalling a sql . NullFloat64 .


func (f *Float) UnmarshalText(text []byte) error {
	str := string(text)
	if str == "" || str == "null" {
		f.Valid = false
		return nil
	}
	var err error
	f.Float64, err = strconv.ParseFloat(string(text), 64)
	f.Valid = err == nil
	return err
}

func ( f * Float ) UnmarshalText ( text [ ] byte ) error { str := string ( text ) if str == " " || str == " " { f . Valid = false return nil } var err error f . Float64 , err = strconv . ParseFloat ( string ( text ) , 64 ) f . Valid = err == nil return err }

// UnmarshalText implements encoding.TextUnmarshaler.
// It will unmarshal to a null Float if the input is a blank or not an integer.
// It will return an error if the input is not an integer, blank, or "null".

UnmarshalText implements encoding . TextUnmarshaler . It will unmarshal to a null Float if the input is a blank or not an integer . It will return an error if the input is not an integer blank or null .


func (f Float) MarshalJSON() ([]byte, error) {
	if !f.Valid {
		return []byte("null"), nil
	}
	if math.IsInf(f.Float64, 0) || math.IsNaN(f.Float64) {
		return nil, &json.UnsupportedValueError{
			Value: reflect.ValueOf(f.Float64),
			Str:   strconv.FormatFloat(f.Float64, 'g', -1, 64),
		}
	}
	return []byte(strconv.FormatFloat(f.Float64, 'f', -1, 64)), nil
}

func ( f Float ) MarshalJSON ( ) ( [ ] byte , error ) { if ! f . Valid { return [ ] byte ( " " ) , nil } if math . IsInf ( f . Float64 , 0 ) || math . IsNaN ( f . Float64 ) { return nil , & json . UnsupportedValueError { Value : reflect . ValueOf ( f . Float64 ) , Str : strconv . FormatFloat ( f . Float64 , 'g' , - 1 , 64 ) , } } return [ ] byte ( strconv . FormatFloat ( f . Float64 , 'f' , - 1 , 64 ) ) , nil }

// MarshalJSON implements json.Marshaler.
// It will encode null if this Float is null.

MarshalJSON implements json . Marshaler . It will encode null if this Float is null .


func newGossipChannel(channelName string, ourself *localPeer, r *routes, g Gossiper, logger Logger) *gossipChannel {
	return &gossipChannel{
		name:     channelName,
		ourself:  ourself,
		routes:   r,
		gossiper: g,
		logger:   logger,
	}
}

func newGossipChannel ( channelName string , ourself * localPeer , r * routes , g Gossiper , logger Logger ) * gossipChannel { return & gossipChannel { name : channelName , ourself : ourself , routes : r , gossiper : g , logger : logger , } }

// newGossipChannel returns a named, usable channel.
// It delegates receiving duties to the passed Gossiper.

newGossipChannel returns a named usable channel . It delegates receiving duties to the passed Gossiper .


func (c *gossipChannel) GossipUnicast(dstPeerName PeerName, msg []byte) error {
	return c.relayUnicast(dstPeerName, gobEncode(c.name, c.ourself.Name, dstPeerName, msg))
}

func ( c * gossipChannel ) GossipUnicast ( dstPeerName PeerName , msg [ ] byte ) error { return c . relayUnicast ( dstPeerName , gobEncode ( c . name , c . ourself . Name , dstPeerName , msg ) ) }

// GossipUnicast implements Gossip, relaying msg to dst, which must be a
// member of the channel.

GossipUnicast implements Gossip relaying msg to dst which must be a member of the channel .


func (c *gossipChannel) GossipBroadcast(update GossipData) {
	c.relayBroadcast(c.ourself.Name, update)
}

func ( c * gossipChannel ) GossipBroadcast ( update GossipData ) { c . relayBroadcast ( c . ourself . Name , update ) }

// GossipBroadcast implements Gossip, relaying update to all members of the
// channel.

GossipBroadcast implements Gossip relaying update to all members of the channel .


func (c *gossipChannel) Send(data GossipData) {
	c.relay(c.ourself.Name, data)
}

func ( c * gossipChannel ) Send ( data GossipData ) { c . relay ( c . ourself . Name , data ) }

// Send relays data into the channel topology via random neighbours.

Send relays data into the channel topology via random neighbours .


func (c *gossipChannel) SendDown(conn Connection, data GossipData) {
	c.senderFor(conn).Send(data)
}

func ( c * gossipChannel ) SendDown ( conn Connection , data GossipData ) { c . senderFor ( conn ) . Send ( data ) }

// SendDown relays data into the channel topology via conn.

SendDown relays data into the channel topology via conn .


func gobEncode(items ...interface{}) []byte {
	buf := new(bytes.Buffer)
	enc := gob.NewEncoder(buf)
	for _, i := range items {
		if err := enc.Encode(i); err != nil {
			panic(err)
		}
	}
	return buf.Bytes()
}

func gobEncode ( items ... interface { } ) [ ] byte { buf := new ( bytes . Buffer ) enc := gob . NewEncoder ( buf ) for _ , i := range items { if err := enc . Encode ( i ) ; err != nil { panic ( err ) } } return buf . Bytes ( ) }

// GobEncode gob-encodes each item and returns the resulting byte slice.

GobEncode gob - encodes each item and returns the resulting byte slice .


func newTokenBucket(capacity int64, tokenInterval time.Duration) *tokenBucket {
	tb := tokenBucket{
		capacity:       capacity,
		tokenInterval:  tokenInterval,
		refillDuration: tokenInterval * time.Duration(capacity)}

	tb.earliestUnspentToken = tb.capacityToken()

	return &tb
}

func newTokenBucket ( capacity int64 , tokenInterval time . Duration ) * tokenBucket { tb := tokenBucket { capacity : capacity , tokenInterval : tokenInterval , refillDuration : tokenInterval * time . Duration ( capacity ) } tb . earliestUnspentToken = tb . capacityToken ( ) return & tb }

// newTokenBucket returns a bucket containing capacity tokens, refilled at a
// rate of one token per tokenInterval.

newTokenBucket returns a bucket containing capacity tokens refilled at a rate of one token per tokenInterval .


func (tb *tokenBucket) wait() {
	// If earliest unspent token is in the future, sleep until then
	time.Sleep(time.Until(tb.earliestUnspentToken))

	// Alternatively, enforce bucket capacity if necessary
	capacityToken := tb.capacityToken()
	if tb.earliestUnspentToken.Before(capacityToken) {
		tb.earliestUnspentToken = capacityToken
	}

	// 'Remove' a token from the bucket
	tb.earliestUnspentToken = tb.earliestUnspentToken.Add(tb.tokenInterval)
}

// Blocks until there is a token available.
// Not safe for concurrent use by multiple goroutines.

Blocks until there is a token available . Not safe for concurrent use by multiple goroutines .


func (tb *tokenBucket) capacityToken() time.Time {
	return time.Now().Add(-tb.refillDuration).Truncate(tb.tokenInterval)
}

func ( tb * tokenBucket ) capacityToken ( ) time . Time { return time . Now ( ) . Add ( - tb . refillDuration ) . Truncate ( tb . tokenInterval ) }

// Determine the historic token timestamp representing a full bucket


func PrefixRangeEnd(prefix []byte) []byte {
	// https://github.com/coreos/etcd/blob/17e32b6/clientv3/op.go#L187
	end := make([]byte, len(prefix))
	copy(end, prefix)
	for i := len(end) - 1; i >= 0; i-- {
		if end[i] < 0xff {
			end[i] = end[i] + 1
			end = end[:i+1]
			return end
		}
	}
	// next prefix does not exist (e.g., 0xffff);
	// default to WithFromKey policy
	return []byte{0}
}

// PrefixRangeEnd allows Get, Delete, and Watch requests to operate on all keys
// with a matching prefix. Pass the prefix to this function, and use the result
// as the RangeEnd value.

PrefixRangeEnd allows Get Delete and Watch requests to operate on all keys with a matching prefix . Pass the prefix to this function and use the result as the RangeEnd value .


func newLocalPeer(name PeerName, nickName string, router *Router) *localPeer {
	actionChan := make(chan localPeerAction, ChannelSize)
	peer := &localPeer{
		Peer:       newPeer(name, nickName, randomPeerUID(), 0, randomPeerShortID()),
		router:     router,
		actionChan: actionChan,
	}
	go peer.actorLoop(actionChan)
	return peer
}

func newLocalPeer ( name PeerName , nickName string , router * Router ) * localPeer { actionChan := make ( chan localPeerAction , ChannelSize ) peer := & localPeer { Peer : newPeer ( name , nickName , randomPeerUID ( ) , 0 , randomPeerShortID ( ) ) , router : router , actionChan : actionChan , } go peer . actorLoop ( actionChan ) return peer }

// newLocalPeer returns a usable LocalPeer.

newLocalPeer returns a usable LocalPeer .


func (peer *localPeer) getConnections() connectionSet {
	connections := make(connectionSet)
	peer.RLock()
	defer peer.RUnlock()
	for _, conn := range peer.connections {
		connections[conn] = struct{}{}
	}
	return connections
}

func ( peer * localPeer ) getConnections ( ) connectionSet { connections := make ( connectionSet ) peer . RLock ( ) defer peer . RUnlock ( ) for _ , conn := range peer . connections { connections [ conn ] = struct { } { } } return connections }

// Connections returns all the connections that the local peer is aware of.

Connections returns all the connections that the local peer is aware of .


func (peer *localPeer) createConnection(localAddr string, peerAddr string, acceptNewPeer bool, logger Logger) error {
	if err := peer.checkConnectionLimit(); err != nil {
		return err
	}
	localTCPAddr, err := net.ResolveTCPAddr("tcp", localAddr)
	if err != nil {
		return err
	}
	remoteTCPAddr, err := net.ResolveTCPAddr("tcp", peerAddr)
	if err != nil {
		return err
	}
	tcpConn, err := net.DialTCP("tcp", localTCPAddr, remoteTCPAddr)
	if err != nil {
		return err
	}
	connRemote := newRemoteConnection(peer.Peer, nil, peerAddr, true, false)
	startLocalConnection(connRemote, tcpConn, peer.router, acceptNewPeer, logger)
	return nil
}

func ( peer * localPeer ) createConnection ( localAddr string , peerAddr string , acceptNewPeer bool , logger Logger ) error { if err := peer . checkConnectionLimit ( ) ; err != nil { return err } localTCPAddr , err := net . ResolveTCPAddr ( " " , localAddr ) if err != nil { return err } remoteTCPAddr , err := net . ResolveTCPAddr ( " " , peerAddr ) if err != nil { return err } tcpConn , err := net . DialTCP ( " " , localTCPAddr , remoteTCPAddr ) if err != nil { return err } connRemote := newRemoteConnection ( peer . Peer , nil , peerAddr , true , false ) startLocalConnection ( connRemote , tcpConn , peer . router , acceptNewPeer , logger ) return nil }

// createConnection creates a new connection, originating from
// localAddr, to peerAddr. If acceptNewPeer is false, peerAddr must
// already be a member of the mesh.

createConnection creates a new connection originating from localAddr to peerAddr . If acceptNewPeer is false peerAddr must already be a member of the mesh .


func (peer *localPeer) doAddConnection(conn ourConnection, isRestartedPeer bool) error {
	resultChan := make(chan error)
	peer.actionChan <- func() {
		resultChan <- peer.handleAddConnection(conn, isRestartedPeer)
	}
	return <-resultChan
}

func ( peer * localPeer ) doAddConnection ( conn ourConnection , isRestartedPeer bool ) error { resultChan := make ( chan error ) peer . actionChan <- func ( ) { resultChan <- peer . handleAddConnection ( conn , isRestartedPeer ) } return <- resultChan }


func startLocalConnection(connRemote *remoteConnection, tcpConn *net.TCPConn, router *Router, acceptNewPeer bool, logger Logger) {
	if connRemote.local != router.Ourself.Peer {
		panic("attempt to create local connection from a peer which is not ourself")
	}
	errorChan := make(chan error, 1)
	finished := make(chan struct{})
	conn := &LocalConnection{
		remoteConnection: *connRemote, // NB, we're taking a copy of connRemote here.
		router:           router,
		tcpConn:          tcpConn,
		trustRemote:      router.trusts(connRemote),
		uid:              randUint64(),
		errorChan:        errorChan,
		finished:         finished,
		logger:           logger,
	}
	conn.senders = newGossipSenders(conn, finished)
	go conn.run(errorChan, finished, acceptNewPeer)
}

// If the connection is successful, it will end up in the local peer's
// connections map.

If the connection is successful it will end up in the local peer s connections map .


func (conn *LocalConnection) SendProtocolMsg(m protocolMsg) error {
	if err := conn.sendProtocolMsg(m); err != nil {
		conn.shutdown(err)
		return err
	}
	return nil
}

func ( conn * LocalConnection ) SendProtocolMsg ( m protocolMsg ) error { if err := conn . sendProtocolMsg ( m ) ; err != nil { conn . shutdown ( err ) return err } return nil }

// SendProtocolMsg implements ProtocolSender.

SendProtocolMsg implements ProtocolSender .


func NewStatus(router *Router) *Status {
	return &Status{
		Protocol:           Protocol,
		ProtocolMinVersion: int(router.ProtocolMinVersion),
		ProtocolMaxVersion: ProtocolMaxVersion,
		Encryption:         router.usingPassword(),
		PeerDiscovery:      router.PeerDiscovery,
		Name:               router.Ourself.Name.String(),
		NickName:           router.Ourself.NickName,
		Port:               router.Port,
		Peers:              makePeerStatusSlice(router.Peers),
		UnicastRoutes:      makeUnicastRouteStatusSlice(router.Routes),
		BroadcastRoutes:    makeBroadcastRouteStatusSlice(router.Routes),
		Connections:        makeLocalConnectionStatusSlice(router.ConnectionMaker),
		TerminationCount:   router.ConnectionMaker.terminationCount,
		Targets:            router.ConnectionMaker.Targets(false),
		OverlayDiagnostics: router.Overlay.Diagnostics(),
		TrustedSubnets:     makeTrustedSubnetsSlice(router.TrustedSubnets),
	}
}

func NewStatus ( router * Router ) * Status { return & Status { Protocol : Protocol , ProtocolMinVersion : int ( router . ProtocolMinVersion ) , ProtocolMaxVersion : ProtocolMaxVersion , Encryption : router . usingPassword ( ) , PeerDiscovery : router . PeerDiscovery , Name : router . Ourself . Name . String ( ) , NickName : router . Ourself . NickName , Port : router . Port , Peers : makePeerStatusSlice ( router . Peers ) , UnicastRoutes : makeUnicastRouteStatusSlice ( router . Routes ) , BroadcastRoutes : makeBroadcastRouteStatusSlice ( router . Routes ) , Connections : makeLocalConnectionStatusSlice ( router . ConnectionMaker ) , TerminationCount : router . ConnectionMaker . terminationCount , Targets : router . ConnectionMaker . Targets ( false ) , OverlayDiagnostics : router . Overlay . Diagnostics ( ) , TrustedSubnets : makeTrustedSubnetsSlice ( router . TrustedSubnets ) , } }

// NewStatus returns a Status object, taken as a snapshot from the router.

NewStatus returns a Status object taken as a snapshot from the router .


func makePeerStatusSlice(peers *Peers) []PeerStatus {
	var slice []PeerStatus

	peers.forEach(func(peer *Peer) {
		var connections []connectionStatus
		if peer == peers.ourself.Peer {
			for conn := range peers.ourself.getConnections() {
				connections = append(connections, makeConnectionStatus(conn))
			}
		} else {
			// Modifying peer.connections requires a write lock on
			// Peers, and since we are holding a read lock (due to the
			// ForEach), access without locking the peer is safe.
			for _, conn := range peer.connections {
				connections = append(connections, makeConnectionStatus(conn))
			}
		}
		slice = append(slice, PeerStatus{
			peer.Name.String(),
			peer.NickName,
			peer.UID,
			peer.ShortID,
			peer.Version,
			connections,
		})
	})

	return slice
}

// makePeerStatusSlice takes a snapshot of the state of peers.

makePeerStatusSlice takes a snapshot of the state of peers .


func makeUnicastRouteStatusSlice(r *routes) []unicastRouteStatus {
	r.RLock()
	defer r.RUnlock()

	var slice []unicastRouteStatus
	for dest, via := range r.unicast {
		slice = append(slice, unicastRouteStatus{dest.String(), via.String()})
	}
	return slice
}

func makeUnicastRouteStatusSlice ( r * routes ) [ ] unicastRouteStatus { r . RLock ( ) defer r . RUnlock ( ) var slice [ ] unicastRouteStatus for dest , via := range r . unicast { slice = append ( slice , unicastRouteStatus { dest . String ( ) , via . String ( ) } ) } return slice }

// makeUnicastRouteStatusSlice takes a snapshot of the unicast routes in routes.

makeUnicastRouteStatusSlice takes a snapshot of the unicast routes in routes .


func makeBroadcastRouteStatusSlice(r *routes) []broadcastRouteStatus {
	r.RLock()
	defer r.RUnlock()

	var slice []broadcastRouteStatus
	for source, via := range r.broadcast {
		var hops []string
		for _, hop := range via {
			hops = append(hops, hop.String())
		}
		slice = append(slice, broadcastRouteStatus{source.String(), hops})
	}
	return slice
}

func makeBroadcastRouteStatusSlice ( r * routes ) [ ] broadcastRouteStatus { r . RLock ( ) defer r . RUnlock ( ) var slice [ ] broadcastRouteStatus for source , via := range r . broadcast { var hops [ ] string for _ , hop := range via { hops = append ( hops , hop . String ( ) ) } slice = append ( slice , broadcastRouteStatus { source . String ( ) , hops } ) } return slice }

// makeBroadcastRouteStatusSlice takes a snapshot of the broadcast routes in routes.

makeBroadcastRouteStatusSlice takes a snapshot of the broadcast routes in routes .


func makeLocalConnectionStatusSlice(cm *connectionMaker) []LocalConnectionStatus {
	resultChan := make(chan []LocalConnectionStatus)
	cm.actionChan <- func() bool {
		var slice []LocalConnectionStatus
		for conn := range cm.connections {
			state := "pending"
			if conn.isEstablished() {
				state = "established"
			}
			lc, _ := conn.(*LocalConnection)
			attrs := lc.OverlayConn.Attrs()
			name, ok := attrs["name"]
			if !ok {
				name = "none"
			}
			info := fmt.Sprintf("%-6v %v", name, conn.Remote())
			if lc.router.usingPassword() {
				if lc.untrusted() {
					info = fmt.Sprintf("%-11v %v", "encrypted", info)
					if attrs != nil {
						attrs["encrypted"] = true
					}
				} else {
					info = fmt.Sprintf("%-11v %v", "unencrypted", info)
				}
			}
			slice = append(slice, LocalConnectionStatus{conn.remoteTCPAddress(), conn.isOutbound(), state, info, attrs})
		}
		for address, target := range cm.targets {
			add := func(state, info string) {
				slice = append(slice, LocalConnectionStatus{address, true, state, info, nil})
			}
			switch target.state {
			case targetWaiting:
				until := "never"
				if !target.tryAfter.IsZero() {
					until = target.tryAfter.String()
				}
				if target.lastError == nil { // shouldn't happen
					add("waiting", "until: "+until)
				} else {
					add("failed", target.lastError.Error()+", retry: "+until)
				}
			case targetAttempting:
				if target.lastError == nil {
					add("connecting", "")
				} else {
					add("retrying", target.lastError.Error())
				}
			case targetConnected:
			case targetSuspended:
			}
		}
		resultChan <- slice
		return false
	}
	return <-resultChan
}

func
makeLocalConnectionStatusSlice
(
cm
*
connectionMaker
)
[
]
LocalConnectionStatus
{
resultChan
:=
make
(
chan
[
]
LocalConnectionStatus
)
cm
.
actionChan
<-
func
(
)
bool
{
var
slice
[
]
LocalConnectionStatus
for
conn
:=
range
cm
.
connections
{
state
:=
"
"
if
conn
.
isEstablished
(
)
{
state
=
"
"
}
lc
,
_
:=
conn
.
(
*
LocalConnection
)
attrs
:=
lc
.
OverlayConn
.
Attrs
(
)
name
,
ok
:=
attrs
[
"
"
]
if
!
ok
{
name
=
"
"
}
info
:=
fmt
.
Sprintf
(
"
"
,
name
,
conn
.
Remote
(
)
)
if
lc
.
router
.
usingPassword
(
)
{
if
lc
.
untrusted
(
)
{
info
=
fmt
.
Sprintf
(
"
"
,
"
"
,
info
)
if
attrs
!=
{
attrs
[
"
"
]
=
true
}
}
else
{
info
=
fmt
.
Sprintf
(
"
"
,
"
"
,
info
)
}
}
slice
=
append
(
slice
,
LocalConnectionStatus
{
conn
.
remoteTCPAddress
(
)
,
conn
.
isOutbound
(
)
,
state
,
info
,
attrs
}
)
}
for
address
,
target
:=
range
cm
.
targets
{
add
:=
func
(
state
,
info
string
)
{
slice
=
append
(
slice
,
LocalConnectionStatus
{
address
,
true
,
state
,
info
,
}
)
}
switch
target
.
state
{
case
targetWaiting
:
until
:=
"
"
if
!
target
.
tryAfter
.
IsZero
(
)
{
until
=
target
.
tryAfter
.
String
(
)
}
if
target
.
lastError
==
{
// shouldn't happen
add
(
"
"
,
"
"
+
until
)
}
else
{
add
(
"
"
,
target
.
lastError
.
Error
(
)
+
"
"
+
until
)
}
case
targetAttempting
:
if
target
.
lastError
==
{
add
(
"
"
,
"
"
)
}
else
{
add
(
"
"
,
target
.
lastError
.
Error
(
)
)
}
case
targetConnected
:
case
targetSuspended
:
}
}
resultChan
<-
slice
return
false
}
return
<-
resultChan
}

// makeLocalConnectionStatusSlice takes a snapshot of the active local
// connections in the ConnectionMaker.

makeLocalConnectionStatusSlice takes a snapshot of the active local connections in the ConnectionMaker .


func makeTrustedSubnetsSlice(trustedSubnets []*net.IPNet) []string {
	trustedSubnetStrs := []string{}
	for _, trustedSubnet := range trustedSubnets {
		trustedSubnetStrs = append(trustedSubnetStrs, trustedSubnet.String())
	}
	return trustedSubnetStrs
}

func makeTrustedSubnetsSlice ( trustedSubnets [ ] * net . IPNet ) [ ] string { trustedSubnetStrs := [ ] string { } for _ , trustedSubnet := range trustedSubnets { trustedSubnetStrs = append ( trustedSubnetStrs , trustedSubnet . String ( ) ) } return trustedSubnetStrs }

// makeTrustedSubnetsSlice makes a human-readable copy of the trustedSubnets.

makeTrustedSubnetsSlice makes a human - readable copy of the trustedSubnets .


func (s *etcdStore) Range(ctx context.Context, req *etcdserverpb.RangeRequest) (*etcdserverpb.RangeResponse, error) {
	ireq := etcdserverpb.InternalRaftRequest{ID: <-s.idgen, Range: req}
	msgc, errc, err := s.proposeInternalRaftRequest(ireq)
	if err != nil {
		return nil, err
	}
	select {
	case <-ctx.Done():
		s.cancelInternalRaftRequest(ireq)
		return nil, ctx.Err()
	case msg := <-msgc:
		return msg.(*etcdserverpb.RangeResponse), nil
	case err := <-errc:
		return nil, err
	case <-s.quitc:
		return nil, errStopped
	}
}

func ( s * etcdStore ) Range ( ctx context . Context , req * etcdserverpb . RangeRequest ) ( * etcdserverpb . RangeResponse , error ) { ireq := etcdserverpb . InternalRaftRequest { ID : <- s . idgen , Range : req } msgc , errc , err := s . proposeInternalRaftRequest ( ireq ) if err != nil { return nil , err } select { case <- ctx . Done ( ) : s . cancelInternalRaftRequest ( ireq ) return nil , ctx . Err ( ) case msg := <- msgc : return msg . ( * etcdserverpb . RangeResponse ) , nil case err := <- errc : return nil , err case <- s . quitc : return nil , errStopped } }

// Range implements gRPC KVServer.
// Range gets the keys in the range from the store.

Range implements gRPC KVServer . Range gets the keys in the range from the store .


func (s *etcdStore) Put(ctx context.Context, req *etcdserverpb.PutRequest) (*etcdserverpb.PutResponse, error) {
	ireq := etcdserverpb.InternalRaftRequest{ID: <-s.idgen, Put: req}
	msgc, errc, err := s.proposeInternalRaftRequest(ireq)
	if err != nil {
		return nil, err
	}
	select {
	case <-ctx.Done():
		s.cancelInternalRaftRequest(ireq)
		return nil, ctx.Err()
	case msg := <-msgc:
		return msg.(*etcdserverpb.PutResponse), nil
	case err := <-errc:
		return nil, err
	case <-s.quitc:
		return nil, errStopped
	}
}

func ( s * etcdStore ) Put ( ctx context . Context , req * etcdserverpb . PutRequest ) ( * etcdserverpb . PutResponse , error ) { ireq := etcdserverpb . InternalRaftRequest { ID : <- s . idgen , Put : req } msgc , errc , err := s . proposeInternalRaftRequest ( ireq ) if err != nil { return nil , err } select { case <- ctx . Done ( ) : s . cancelInternalRaftRequest ( ireq ) return nil , ctx . Err ( ) case msg := <- msgc : return msg . ( * etcdserverpb . PutResponse ) , nil case err := <- errc : return nil , err case <- s . quitc : return nil , errStopped } }

// Put implements gRPC KVServer.
// Put puts the given key into the store.
// A put request increases the revision of the store,
// and generates one event in the event history.

Put implements gRPC KVServer . Put puts the given key into the store . A put request increases the revision of the store and generates one event in the event history .


func (s *etcdStore) DeleteRange(ctx context.Context, req *etcdserverpb.DeleteRangeRequest) (*etcdserverpb.DeleteRangeResponse, error) {
	ireq := etcdserverpb.InternalRaftRequest{ID: <-s.idgen, DeleteRange: req}
	msgc, errc, err := s.proposeInternalRaftRequest(ireq)
	if err != nil {
		return nil, err
	}
	select {
	case <-ctx.Done():
		s.cancelInternalRaftRequest(ireq)
		return nil, ctx.Err()
	case msg := <-msgc:
		return msg.(*etcdserverpb.DeleteRangeResponse), nil
	case err := <-errc:
		return nil, err
	case <-s.quitc:
		return nil, errStopped
	}
}

func ( s * etcdStore ) DeleteRange ( ctx context . Context , req * etcdserverpb . DeleteRangeRequest ) ( * etcdserverpb . DeleteRangeResponse , error ) { ireq := etcdserverpb . InternalRaftRequest { ID : <- s . idgen , DeleteRange : req } msgc , errc , err := s . proposeInternalRaftRequest ( ireq ) if err != nil { return nil , err } select { case <- ctx . Done ( ) : s . cancelInternalRaftRequest ( ireq ) return nil , ctx . Err ( ) case msg := <- msgc : return msg . ( * etcdserverpb . DeleteRangeResponse ) , nil case err := <- errc : return nil , err case <- s . quitc : return nil , errStopped } }

// Delete implements gRPC KVServer.
// Delete deletes the given range from the store.
// A delete request increase the revision of the store,
// and generates one event in the event history.

Delete implements gRPC KVServer . Delete deletes the given range from the store . A delete request increase the revision of the store and generates one event in the event history .


func (s *etcdStore) Txn(ctx context.Context, req *etcdserverpb.TxnRequest) (*etcdserverpb.TxnResponse, error) {
	ireq := etcdserverpb.InternalRaftRequest{ID: <-s.idgen, Txn: req}
	msgc, errc, err := s.proposeInternalRaftRequest(ireq)
	if err != nil {
		return nil, err
	}
	select {
	case <-ctx.Done():
		s.cancelInternalRaftRequest(ireq)
		return nil, ctx.Err()
	case msg := <-msgc:
		return msg.(*etcdserverpb.TxnResponse), nil
	case err := <-errc:
		return nil, err
	case <-s.quitc:
		return nil, errStopped
	}
}

func ( s * etcdStore ) Txn ( ctx context . Context , req * etcdserverpb . TxnRequest ) ( * etcdserverpb . TxnResponse , error ) { ireq := etcdserverpb . InternalRaftRequest { ID : <- s . idgen , Txn : req } msgc , errc , err := s . proposeInternalRaftRequest ( ireq ) if err != nil { return nil , err } select { case <- ctx . Done ( ) : s . cancelInternalRaftRequest ( ireq ) return nil , ctx . Err ( ) case msg := <- msgc : return msg . ( * etcdserverpb . TxnResponse ) , nil case err := <- errc : return nil , err case <- s . quitc : return nil , errStopped } }

// Txn implements gRPC KVServer.
// Txn processes all the requests in one transaction.
// A txn request increases the revision of the store,
// and generates events with the same revision in the event history.
// It is not allowed to modify the same key several times within one txn.

Txn implements gRPC KVServer . Txn processes all the requests in one transaction . A txn request increases the revision of the store and generates events with the same revision in the event history . It is not allowed to modify the same key several times within one txn .


func (s *etcdStore) Compact(ctx context.Context, req *etcdserverpb.CompactionRequest) (*etcdserverpb.CompactionResponse, error) {
	// We don't have snapshotting yet, so compact just puts us in a bad state.
	// TODO(pb): fix this when we implement snapshotting.
	return nil, errors.New("not implemented")
}

// Compact implements gRPC KVServer.
// Compact compacts the event history in s. User should compact the
// event history periodically, or it will grow infinitely.

Compact implements gRPC KVServer . Compact compacts the event history in s . User should compact the event history periodically or it will grow infinitely .


func (s *etcdStore) proposeInternalRaftRequest(req etcdserverpb.InternalRaftRequest) (<-chan proto.Message, <-chan error, error) {
	data, err := req.Marshal()
	if err != nil {
		return nil, nil, err
	}
	if len(data) > maxRequestBytes {
		return nil, nil, errTooBig
	}
	msgc, errc, err := s.registerPending(req.ID)
	if err != nil {
		return nil, nil, err
	}
	s.proposalc <- data
	return msgc, errc, nil
}

func ( s * etcdStore ) proposeInternalRaftRequest ( req etcdserverpb . InternalRaftRequest ) ( <- chan proto . Message , <- chan error , error ) { data , err := req . Marshal ( ) if err != nil { return nil , nil , err } if len ( data ) > maxRequestBytes { return nil , nil , errTooBig } msgc , errc , err := s . registerPending ( req . ID ) if err != nil { return nil , nil , err } s . proposalc <- data return msgc , errc , nil }


func applyCompare(kv mvcc.KV, c *etcdserverpb.Compare) (int64, bool) {
	ckvs, rev, err := kv.Range(c.Key, nil, 1, 0)
	if err != nil {
		if err == mvcc.ErrTxnIDMismatch {
			panic("unexpected txn ID mismatch error")
		}
		return rev, false
	}
	var ckv mvccpb.KeyValue
	if len(ckvs) != 0 {
		ckv = ckvs[0]
	} else {
		// Use the zero value of ckv normally. However...
		if c.Target == etcdserverpb.Compare_VALUE {
			// Always fail if we're comparing a value on a key that doesn't exist.
			// We can treat non-existence as the empty set explicitly, such that
			// even a key with a value of length 0 bytes is still a real key
			// that was written that way
			return rev, false
		}
	}

	// -1 is less, 0 is equal, 1 is greater
	var result int
	switch c.Target {
	case etcdserverpb.Compare_VALUE:
		tv, _ := c.TargetUnion.(*etcdserverpb.Compare_Value)
		if tv != nil {
			result = bytes.Compare(ckv.Value, tv.Value)
		}
	case etcdserverpb.Compare_CREATE:
		tv, _ := c.TargetUnion.(*etcdserverpb.Compare_CreateRevision)
		if tv != nil {
			result = compareInt64(ckv.CreateRevision, tv.CreateRevision)
		}

	case etcdserverpb.Compare_MOD:
		tv, _ := c.TargetUnion.(*etcdserverpb.Compare_ModRevision)
		if tv != nil {
			result = compareInt64(ckv.ModRevision, tv.ModRevision)
		}
	case etcdserverpb.Compare_VERSION:
		tv, _ := c.TargetUnion.(*etcdserverpb.Compare_Version)
		if tv != nil {
			result = compareInt64(ckv.Version, tv.Version)
		}
	}

	switch c.Result {
	case etcdserverpb.Compare_EQUAL:
		if result != 0 {
			return rev, false
		}
	case etcdserverpb.Compare_GREATER:
		if result != 1 {
			return rev, false
		}
	case etcdserverpb.Compare_LESS:
		if result != -1 {
			return rev, false
		}
	}
	return rev, true
}

// applyCompare applies the compare request.
// It returns the revision at which the comparison happens. If the comparison
// succeeds, the it returns true. Otherwise it returns false.

applyCompare applies the compare request . It returns the revision at which the comparison happens . If the comparison succeeds the it returns true . Otherwise it returns false .


func (peers *Peers) Descriptions() []PeerDescription {
	peers.RLock()
	defer peers.RUnlock()
	descriptions := make([]PeerDescription, 0, len(peers.byName))
	for _, peer := range peers.byName {
		descriptions = append(descriptions, PeerDescription{
			Name:           peer.Name,
			NickName:       peer.peerSummary.NickName,
			UID:            peer.UID,
			Self:           peer.Name == peers.ourself.Name,
			NumConnections: len(peer.connections),
		})
	}
	return descriptions
}

func ( peers * Peers ) Descriptions ( ) [ ] PeerDescription { peers . RLock ( ) defer peers . RUnlock ( ) descriptions := make ( [ ] PeerDescription , 0 , len ( peers . byName ) ) for _ , peer := range peers . byName { descriptions = append ( descriptions , PeerDescription { Name : peer . Name , NickName : peer . peerSummary . NickName , UID : peer . UID , Self : peer . Name == peers . ourself . Name , NumConnections : len ( peer . connections ) , } ) } return descriptions }

// Descriptions returns descriptions for all known peers.

Descriptions returns descriptions for all known peers .


func (peers *Peers) OnGC(callback func(*Peer)) {
	peers.Lock()
	defer peers.Unlock()

	// Although the array underlying peers.onGC might be accessed
	// without holding the lock in unlockAndNotify, we don't
	// support removing callbacks, so a simple append here is
	// safe.
	peers.onGC = append(peers.onGC, callback)
}

// OnGC adds a new function to be set of functions that will be executed on
// all subsequent GC runs, receiving the GC'd peer.

OnGC adds a new function to be set of functions that will be executed on all subsequent GC runs receiving the GC d peer .


func (peers *Peers) OnInvalidateShortIDs(callback func()) {
	peers.Lock()
	defer peers.Unlock()

	// Safe, as in OnGC
	peers.onInvalidateShortIDs = append(peers.onInvalidateShortIDs, callback)
}

func
(
peers
*
Peers
)
OnInvalidateShortIDs
(
callback
func
(
)
)
{
peers
.
Lock
(
)
defer
peers
.
Unlock
(
)
// Safe, as in OnGC
peers
.
onInvalidateShortIDs
=
append
(
peers
.
onInvalidateShortIDs
,
callback
)
}

// OnInvalidateShortIDs adds a new function to a set of functions that will be
// executed on all subsequent GC runs, when the mapping from short IDs to
// peers has changed.

OnInvalidateShortIDs adds a new function to a set of functions that will be executed on all subsequent GC runs when the mapping from short IDs to peers has changed .


func (peers *Peers) chooseShortID() (PeerShortID, bool) {
	rng := rand.New(rand.NewSource(int64(randUint64())))

	// First, just try picking some short IDs at random, and
	// seeing if they are available:
	for i := 0; i < 10; i++ {
		shortID := PeerShortID(rng.Intn(1 << peerShortIDBits))
		if peers.byShortID[shortID].peer == nil {
			return shortID, true
		}
	}

	// Looks like most short IDs are used. So count the number of
	// unused ones, and pick one at random.
	available := int(1 << peerShortIDBits)
	for _, entry := range peers.byShortID {
		if entry.peer != nil {
			available--
		}
	}

	if available == 0 {
		// All short IDs are used.
		return 0, false
	}

	n := rng.Intn(available)
	var i PeerShortID
	for {
		if peers.byShortID[i].peer == nil {
			if n == 0 {
				return i, true
			}

			n--
		}

		i++
	}
}

// Choose an available short ID at random.

Choose an available short ID at random .


func (peers *Peers) fetchWithDefault(peer *Peer) *Peer {
	peers.Lock()
	var pending peersPendingNotifications
	defer peers.unlockAndNotify(&pending)

	if existingPeer, found := peers.byName[peer.Name]; found {
		existingPeer.localRefCount++
		return existingPeer
	}

	peers.byName[peer.Name] = peer
	peers.addByShortID(peer, &pending)
	peer.localRefCount++
	return peer
}

func ( peers * Peers ) fetchWithDefault ( peer * Peer ) * Peer { peers . Lock ( ) var pending peersPendingNotifications defer peers . unlockAndNotify ( & pending ) if existingPeer , found := peers . byName [ peer . Name ] ; found { existingPeer . localRefCount ++ return existingPeer } peers . byName [ peer . Name ] = peer peers . addByShortID ( peer , & pending ) peer . localRefCount ++ return peer }

// fetchWithDefault will use reference fields of the passed peer object to
// look up and return an existing, matching peer. If no matching peer is
// found, the passed peer is saved and returned.

fetchWithDefault will use reference fields of the passed peer object to look up and return an existing matching peer . If no matching peer is found the passed peer is saved and returned .


func (peers *Peers) Fetch(name PeerName) *Peer {
	peers.RLock()
	defer peers.RUnlock()
	return peers.byName[name]
}

func ( peers * Peers ) Fetch ( name PeerName ) * Peer { peers . RLock ( ) defer peers . RUnlock ( ) return peers . byName [ name ] }

// Fetch returns a peer matching the passed name, without incrementing its
// refcount. If no matching peer is found, Fetch returns nil.

Fetch returns a peer matching the passed name without incrementing its refcount . If no matching peer is found Fetch returns nil .


func (peers *Peers) fetchAndAddRef(name PeerName) *Peer {
	peers.Lock()
	defer peers.Unlock()
	peer := peers.byName[name]
	if peer != nil {
		peer.localRefCount++
	}
	return peer
}

func ( peers * Peers ) fetchAndAddRef ( name PeerName ) * Peer { peers . Lock ( ) defer peers . Unlock ( ) peer := peers . byName [ name ] if peer != nil { peer . localRefCount ++ } return peer }

// Like fetch, but increments local refcount.

Like fetch but increments local refcount .


func (peers *Peers) FetchByShortID(shortID PeerShortID) *Peer {
	peers.RLock()
	defer peers.RUnlock()
	return peers.byShortID[shortID].peer
}

func ( peers * Peers ) FetchByShortID ( shortID PeerShortID ) * Peer { peers . RLock ( ) defer peers . RUnlock ( ) return peers . byShortID [ shortID ] . peer }

// FetchByShortID returns a peer matching the passed short ID.
// If no matching peer is found, FetchByShortID returns nil.

FetchByShortID returns a peer matching the passed short ID . If no matching peer is found FetchByShortID returns nil .


func (peers *Peers) GarbageCollect() {
	peers.Lock()
	var pending peersPendingNotifications
	defer peers.unlockAndNotify(&pending)

	peers.garbageCollect(&pending)
}

func ( peers * Peers ) GarbageCollect ( ) { peers . Lock ( ) var pending peersPendingNotifications defer peers . unlockAndNotify ( & pending ) peers . garbageCollect ( & pending ) }

// GarbageCollect takes a lock, triggers a GC, and invokes the accumulated GC
// callbacks.

GarbageCollect takes a lock triggers a GC and invokes the accumulated GC callbacks .


func newRoutes(ourself *localPeer, peers *Peers) *routes {
	recalculate := make(chan *struct{}, 1)
	wait := make(chan chan struct{})
	action := make(chan func())
	r := &routes{
		ourself:      ourself,
		peers:        peers,
		unicast:      unicastRoutes{ourself.Name: UnknownPeerName},
		unicastAll:   unicastRoutes{ourself.Name: UnknownPeerName},
		broadcast:    broadcastRoutes{ourself.Name: []PeerName{}},
		broadcastAll: broadcastRoutes{ourself.Name: []PeerName{}},
		recalc:       recalculate,
		wait:         wait,
		action:       action,
	}
	go r.run(recalculate, wait, action)
	return r
}

func newRoutes ( ourself * localPeer , peers * Peers ) * routes { recalculate := make ( chan * struct { } , 1 ) wait := make ( chan chan struct { } ) action := make ( chan func ( ) ) r := & routes { ourself : ourself , peers : peers , unicast : unicastRoutes { ourself . Name : UnknownPeerName } , unicastAll : unicastRoutes { ourself . Name : UnknownPeerName } , broadcast : broadcastRoutes { ourself . Name : [ ] PeerName { } } , broadcastAll : broadcastRoutes { ourself . Name : [ ] PeerName { } } , recalc : recalculate , wait : wait , action : action , } go r . run ( recalculate , wait , action ) return r }

// newRoutes returns a usable Routes based on the LocalPeer and existing Peers.

newRoutes returns a usable Routes based on the LocalPeer and existing Peers .


func (r *routes) OnChange(callback func()) {
	r.Lock()
	defer r.Unlock()
	r.onChange = append(r.onChange, callback)
}

func ( r * routes ) OnChange ( callback func ( ) ) { r . Lock ( ) defer r . Unlock ( ) r . onChange = append ( r . onChange , callback ) }

// OnChange appends callback to the functions that will be called whenever the
// routes are recalculated.

OnChange appends callback to the functions that will be called whenever the routes are recalculated .


func (r *routes) Unicast(name PeerName) (PeerName, bool) {
	r.RLock()
	defer r.RUnlock()
	hop, found := r.unicast[name]
	return hop, found
}

func ( r * routes ) Unicast ( name PeerName ) ( PeerName , bool ) { r . RLock ( ) defer r . RUnlock ( ) hop , found := r . unicast [ name ] return hop , found }

// Unicast returns the next hop on the unicast route to the named peer,
// based on established and symmetric connections.

Unicast returns the next hop on the unicast route to the named peer based on established and symmetric connections .


func (r *routes) UnicastAll(name PeerName) (PeerName, bool) {
	r.RLock()
	defer r.RUnlock()
	hop, found := r.unicastAll[name]
	return hop, found
}

func ( r * routes ) UnicastAll ( name PeerName ) ( PeerName , bool ) { r . RLock ( ) defer r . RUnlock ( ) hop , found := r . unicastAll [ name ] return hop , found }

// UnicastAll returns the next hop on the unicast route to the named peer,
// based on all connections.

UnicastAll returns the next hop on the unicast route to the named peer based on all connections .


func (r *routes) Broadcast(name PeerName) []PeerName {
	return r.lookupOrCalculate(name, &r.broadcast, true)
}

func ( r * routes ) Broadcast ( name PeerName ) [ ] PeerName { return r . lookupOrCalculate ( name , & r . broadcast , true ) }

// Broadcast returns the set of peer names that should be notified
// when we receive a broadcast message originating from the named peer
// based on established and symmetric connections.

Broadcast returns the set of peer names that should be notified when we receive a broadcast message originating from the named peer based on established and symmetric connections .


func (r *routes) BroadcastAll(name PeerName) []PeerName {
	return r.lookupOrCalculate(name, &r.broadcastAll, false)
}

func ( r * routes ) BroadcastAll ( name PeerName ) [ ] PeerName { return r . lookupOrCalculate ( name , & r . broadcastAll , false ) }

// BroadcastAll returns the set of peer names that should be notified
// when we receive a broadcast message originating from the named peer
// based on all connections.

BroadcastAll returns the set of peer names that should be notified when we receive a broadcast message originating from the named peer based on all connections .


func NewPeer(name mesh.PeerName, uid mesh.PeerUID, logger mesh.Logger) *Peer {
	p := &Peer{
		name:    name,
		uid:     uid,
		gossip:  nil, // initially no gossip
		recv:    make(chan pkt),
		actions: make(chan func()),
		quit:    make(chan struct{}),
		logger:  logger,
	}
	go p.loop()
	return p
}

func
NewPeer
(
name
mesh
.
PeerName
,
uid
mesh
.
PeerUID
,
logger
mesh
.
Logger
)
*
Peer
{
p
:=
&
Peer
{
name
:
name
,
uid
:
uid
,
gossip
:
,
// initially no gossip
recv
:
make
(
chan
pkt
)
,
actions
:
make
(
chan
func
(
)
)
,
quit
:
make
(
chan
struct
{
}
)
,
logger
:
logger
,
}
go
p
.
loop
(
)
return
p
}

// NewPeer returns a Peer, which can be used as a net.PacketConn.
// Clients must Register a mesh.Gossip before calling ReadFrom or WriteTo.
// Clients should aggressively consume from ReadFrom.

NewPeer returns a Peer which can be used as a net . PacketConn . Clients must Register a mesh . Gossip before calling ReadFrom or WriteTo . Clients should aggressively consume from ReadFrom .


func (p *Peer) Register(gossip mesh.Gossip) {
	p.actions <- func() { p.gossip = gossip }
}

func ( p * Peer ) Register ( gossip mesh . Gossip ) { p . actions <- func ( ) { p . gossip = gossip } }

// Register injects the mesh.Gossip and enables full-duplex communication.
// Clients should consume from ReadFrom without blocking.

Register injects the mesh . Gossip and enables full - duplex communication . Clients should consume from ReadFrom without blocking .


func (p *Peer) ReadFrom(b []byte) (n int, remote net.Addr, err error) {
	c := make(chan struct{})
	p.actions <- func() {
		go func() { // so as not to block loop
			defer close(c)
			select {
			case pkt := <-p.recv:
				n = copy(b, pkt.Buf)
				remote = MeshAddr{PeerName: pkt.SrcName, PeerUID: pkt.SrcUID}
				if n < len(pkt.Buf) {
					err = ErrShortRead
				}
			case <-p.quit:
				err = ErrPeerClosed
			}
		}()
	}
	<-c
	return n, remote, err
}

func
(
p
*
Peer
)
ReadFrom
(
b
[
]
byte
)
(
n
int
,
remote
net
.
Addr
,
err
error
)
{
c
:=
make
(
chan
struct
{
}
)
p
.
actions
<-
func
(
)
{
go
func
(
)
{
// so as not to block loop
defer
close
(
c
)
select
{
case
pkt
:=
<-
p
.
recv
:
n
=
copy
(
b
,
pkt
.
Buf
)
remote
=
MeshAddr
{
PeerName
:
pkt
.
SrcName
,
PeerUID
:
pkt
.
SrcUID
}
if
n
<
len
(
pkt
.
Buf
)
{
err
=
ErrShortRead
}
case
<-
p
.
quit
:
err
=
ErrPeerClosed
}
}
(
)
}
<-
c
return
n
,
remote
,
err
}

// ReadFrom implements net.PacketConn.
// Clients should consume from ReadFrom without blocking.

ReadFrom implements net . PacketConn . Clients should consume from ReadFrom without blocking .


func (p *Peer) WriteTo(b []byte, dst net.Addr) (n int, err error) {
	c := make(chan struct{})
	p.actions <- func() {
		defer close(c)
		if p.gossip == nil {
			err = ErrGossipNotRegistered
			return
		}
		meshAddr, ok := dst.(MeshAddr)
		if !ok {
			err = ErrNotMeshAddr
			return
		}
		pkt := pkt{SrcName: p.name, SrcUID: p.uid, Buf: b}
		if meshAddr.PeerName == p.name {
			p.recv <- pkt
			return
		}
		// TODO(pb): detect and support broadcast
		buf := pkt.encode()
		n = len(buf)
		err = p.gossip.GossipUnicast(meshAddr.PeerName, buf)
	}
	<-c
	return n, err
}


func (p *Peer) LocalAddr() net.Addr {
	return MeshAddr{PeerName: p.name, PeerUID: p.uid}
}

func ( p * Peer ) LocalAddr ( ) net . Addr { return MeshAddr { PeerName : p . name , PeerUID : p . uid } }


func (p *Peer) OnGossip(buf []byte) (delta mesh.GossipData, err error) {
	return pktSlice{makePkt(buf)}, nil
}

func ( p * Peer ) OnGossip ( buf [ ] byte ) ( delta mesh . GossipData , err error ) { return pktSlice { makePkt ( buf ) } , nil }

// OnGossip implements mesh.Gossiper.
// The buf is a single pkt.

OnGossip implements mesh . Gossiper . The buf is a single pkt .


func (p *Peer) OnGossipBroadcast(_ mesh.PeerName, buf []byte) (received mesh.GossipData, err error) {
	pkt := makePkt(buf)
	p.recv <- pkt // to ReadFrom
	return pktSlice{pkt}, nil
}

func
(
p
*
Peer
)
OnGossipBroadcast
(
_
mesh
.
PeerName
,
buf
[
]
byte
)
(
received
mesh
.
GossipData
,
err
error
)
{
pkt
:=
makePkt
(
buf
)
p
.
recv
<-
pkt
// to ReadFrom
return
pktSlice
{
pkt
}
,
}

// OnGossipBroadcast implements mesh.Gossiper.
// The buf is a single pkt

OnGossipBroadcast implements mesh . Gossiper . The buf is a single pkt


func (p *Peer) OnGossipUnicast(_ mesh.PeerName, buf []byte) error {
	pkt := makePkt(buf)
	p.recv <- pkt // to ReadFrom
	return nil
}

func
(
p
*
Peer
)
OnGossipUnicast
(
_
mesh
.
PeerName
,
buf
[
]
byte
)
error
{
pkt
:=
makePkt
(
buf
)
p
.
recv
<-
pkt
// to ReadFrom
return
}

// OnGossipUnicast implements mesh.Gossiper.
// The buf is a single pkt.

OnGossipUnicast implements mesh . Gossiper . The buf is a single pkt .


func NewDefaultServer(
	minPeerCount int,
	terminatec <-chan struct{},
	terminatedc chan<- error,
	logger mesh.Logger,
) Server {
	var (
		peerName = mustPeerName()
		nickName = mustHostname()
		host     = "0.0.0.0"
		port     = 6379
		password = ""
		channel  = "metcd"
	)
	router := mesh.NewRouter(mesh.Config{
		Host:               host,
		Port:               port,
		ProtocolMinVersion: mesh.ProtocolMinVersion,
		Password:           []byte(password),
		ConnLimit:          64,
		PeerDiscovery:      true,
		TrustedSubnets:     []*net.IPNet{},
	}, peerName, nickName, mesh.NullOverlay{}, logger)

	// Create a meshconn.Peer and connect it to a channel.
	peer := meshconn.NewPeer(router.Ourself.Peer.Name, router.Ourself.UID, logger)
	gossip := router.NewGossip(channel, peer)
	peer.Register(gossip)

	// Start the router and join the mesh.
	// Note that we don't ever stop the router.
	// This may or may not be a problem.
	// TODO(pb): determine if this is a super huge problem
	router.Start()

	return NewServer(router, peer, minPeerCount, terminatec, terminatedc, logger)
}

// NewDefaultServer is like NewServer, but we take care of creating a
// mesh.Router and meshconn.Peer for you, with sane defaults. If you need more
// fine-grained control, create the components yourself and use NewServer.

NewDefaultServer is like NewServer but we take care of creating a mesh . Router and meshconn . Peer for you with sane defaults . If you need more fine - grained control create the components yourself and use NewServer .


func PeerNameFromUserInput(userInput string) (PeerName, error) {
	// fixed-length identity
	nameByteAry := sha256.Sum256([]byte(userInput))
	return PeerNameFromBin(nameByteAry[:NameSize]), nil
}

func
PeerNameFromUserInput
(
userInput
string
)
(
PeerName
,
error
)
{
// fixed-length identity
nameByteAry
:=
sha256
.
Sum256
(
[
]
byte
(
userInput
)
)
return
PeerNameFromBin
(
nameByteAry
[
:
NameSize
]
)
,
}

// PeerNameFromUserInput parses PeerName from a user-provided string.

PeerNameFromUserInput parses PeerName from a user - provided string .


func (name PeerName) bytes() []byte {
	res, err := hex.DecodeString(string(name))
	if err != nil {
		panic("unable to decode name to bytes: " + name)
	}
	return res
}

func ( name PeerName ) bytes ( ) [ ] byte { res , err := hex . DecodeString ( string ( name ) ) if err != nil { panic ( " " + name ) } return res }

// bytes encodes PeerName as a byte slice.

bytes encodes PeerName as a byte slice .


func NewRouter(config Config, name PeerName, nickName string, overlay Overlay, logger Logger) (*Router, error) {
	router := &Router{Config: config, gossipChannels: make(gossipChannels)}

	if overlay == nil {
		overlay = NullOverlay{}
	}

	router.Overlay = overlay
	router.Ourself = newLocalPeer(name, nickName, router)
	router.Peers = newPeers(router.Ourself)
	router.Peers.OnGC(func(peer *Peer) {
		logger.Printf("Removed unreachable peer %s", peer)
	})
	router.Routes = newRoutes(router.Ourself, router.Peers)
	router.ConnectionMaker = newConnectionMaker(router.Ourself, router.Peers, net.JoinHostPort(router.Host, "0"), router.Port, router.PeerDiscovery, logger)
	router.logger = logger
	gossip, err := router.NewGossip("topology", router)
	if err != nil {
		return nil, err
	}
	router.topologyGossip = gossip
	router.acceptLimiter = newTokenBucket(acceptMaxTokens, acceptTokenDelay)
	return router, nil
}

func NewRouter ( config Config , name PeerName , nickName string , overlay Overlay , logger Logger ) ( * Router , error ) { router := & Router { Config : config , gossipChannels : make ( gossipChannels ) } if overlay == nil { overlay = NullOverlay { } } router . Overlay = overlay router . Ourself = newLocalPeer ( name , nickName , router ) router . Peers = newPeers ( router . Ourself ) router . Peers . OnGC ( func ( peer * Peer ) { logger . Printf ( " " , peer ) } ) router . Routes = newRoutes ( router . Ourself , router . Peers ) router . ConnectionMaker = newConnectionMaker ( router . Ourself , router . Peers , net . JoinHostPort ( router . Host , " " ) , router . Port , router . PeerDiscovery , logger ) router . logger = logger gossip , err := router . NewGossip ( " " , router ) if err != nil { return nil , err } router . topologyGossip = gossip router . acceptLimiter = newTokenBucket ( acceptMaxTokens , acceptTokenDelay ) return router , nil }

// NewRouter returns a new router. It must be started.

NewRouter returns a new router . It must be started .


func (router *Router) sendAllGossip() {
	for channel := range router.gossipChannelSet() {
		if gossip := channel.gossiper.Gossip(); gossip != nil {
			channel.Send(gossip)
		}
	}
}

func ( router * Router ) sendAllGossip ( ) { for channel := range router . gossipChannelSet ( ) { if gossip := channel . gossiper . Gossip ( ) ; gossip != nil { channel . Send ( gossip ) } } }

// Relay all pending gossip data for each channel via random neighbours.

Relay all pending gossip data for each channel via random neighbours .


func (router *Router) sendAllGossipDown(conn Connection) {
	for channel := range router.gossipChannelSet() {
		if gossip := channel.gossiper.Gossip(); gossip != nil {
			channel.SendDown(conn, gossip)
		}
	}
}

func ( router * Router ) sendAllGossipDown ( conn Connection ) { for channel := range router . gossipChannelSet ( ) { if gossip := channel . gossiper . Gossip ( ) ; gossip != nil { channel . SendDown ( conn , gossip ) } } }

// Relay all pending gossip data for each channel via conn.

Relay all pending gossip data for each channel via conn .


func (router *Router) broadcastTopologyUpdate(update []*Peer) {
	names := make(peerNameSet)
	for _, p := range update {
		names[p.Name] = struct{}{}
	}
	router.topologyGossip.GossipBroadcast(&topologyGossipData{peers: router.Peers, update: names})
}

func ( router * Router ) broadcastTopologyUpdate ( update [ ] * Peer ) { names := make ( peerNameSet ) for _ , p := range update { names [ p . Name ] = struct { } { } } router . topologyGossip . GossipBroadcast ( & topologyGossipData { peers : router . Peers , update : names } ) }

// BroadcastTopologyUpdate is invoked whenever there is a change to the mesh
// topology, and broadcasts the new set of peers to the mesh.

BroadcastTopologyUpdate is invoked whenever there is a change to the mesh topology and broadcasts the new set of peers to the mesh .


func (router *Router) OnGossipUnicast(sender PeerName, msg []byte) error {
	return fmt.Errorf("unexpected topology gossip unicast: %v", msg)
}

func ( router * Router ) OnGossipUnicast ( sender PeerName , msg [ ] byte ) error { return fmt . Errorf ( " " , msg ) }

// OnGossipUnicast implements Gossiper, but always returns an error, as a
// router should only receive gossip broadcasts of TopologyGossipData.

OnGossipUnicast implements Gossiper but always returns an error as a router should only receive gossip broadcasts of TopologyGossipData .


func (router *Router) OnGossipBroadcast(_ PeerName, update []byte) (GossipData, error) {
	origUpdate, _, err := router.applyTopologyUpdate(update)
	if err != nil || len(origUpdate) == 0 {
		return nil, err
	}
	return &topologyGossipData{peers: router.Peers, update: origUpdate}, nil
}

func ( router * Router ) OnGossipBroadcast ( _ PeerName , update [ ] byte ) ( GossipData , error ) { origUpdate , _ , err := router . applyTopologyUpdate ( update ) if err != nil || len ( origUpdate ) == 0 { return nil , err } return & topologyGossipData { peers : router . Peers , update : origUpdate } , nil }

// OnGossipBroadcast receives broadcasts of TopologyGossipData.
// It returns the received update unchanged.

OnGossipBroadcast receives broadcasts of TopologyGossipData . It returns the received update unchanged .


func (router *Router) Gossip() GossipData {
	return &topologyGossipData{peers: router.Peers, update: router.Peers.names()}
}

func ( router * Router ) Gossip ( ) GossipData { return & topologyGossipData { peers : router . Peers , update : router . Peers . names ( ) } }

// Gossip yields the current topology as GossipData.

Gossip yields the current topology as GossipData .


func (router *Router) OnGossip(update []byte) (GossipData, error) {
	_, newUpdate, err := router.applyTopologyUpdate(update)
	if err != nil || len(newUpdate) == 0 {
		return nil, err
	}
	return &topologyGossipData{peers: router.Peers, update: newUpdate}, nil
}

func ( router * Router ) OnGossip ( update [ ] byte ) ( GossipData , error ) { _ , newUpdate , err := router . applyTopologyUpdate ( update ) if err != nil || len ( newUpdate ) == 0 { return nil , err } return & topologyGossipData { peers : router . Peers , update : newUpdate } , nil }

// OnGossip receives broadcasts of TopologyGossipData.
// It returns an "improved" version of the received update.
// See peers.ApplyUpdate.

OnGossip receives broadcasts of TopologyGossipData . It returns an improved version of the received update . See peers . ApplyUpdate .


func (d *topologyGossipData) Encode() [][]byte {
	return [][]byte{d.peers.encodePeers(d.update)}
}

func ( d * topologyGossipData ) Encode ( ) [ ] [ ] byte { return [ ] [ ] byte { d . peers . encodePeers ( d . update ) } }


func newState(self mesh.PeerName) *state {
	return &state{
		set:  map[mesh.PeerName]int{},
		self: self,
	}
}

func newState ( self mesh . PeerName ) * state { return & state { set : map [ mesh . PeerName ] int { } , self : self , } }

// Construct an empty state object, ready to receive updates.
// This is suitable to use at program start.
// Other peers will populate us with data.

Construct an empty state object ready to receive updates . This is suitable to use at program start . Other peers will populate us with data .


func (st *state) Merge(other mesh.GossipData) (complete mesh.GossipData) {
	return st.mergeComplete(other.(*state).copy().set)
}

func ( st * state ) Merge ( other mesh . GossipData ) ( complete mesh . GossipData ) { return st . mergeComplete ( other . ( * state ) . copy ( ) . set ) }

// Merge merges the other GossipData into this one,
// and returns our resulting, complete state.

Merge merges the other GossipData into this one and returns our resulting complete state .


func (st *state) mergeReceived(set map[mesh.PeerName]int) (received mesh.GossipData) {
	st.mtx.Lock()
	defer st.mtx.Unlock()

	for peer, v := range set {
		if v <= st.set[peer] {
			delete(set, peer) // optimization: make the forwarded data smaller
			continue
		}
		st.set[peer] = v
	}

	return &state{
		set: set, // all remaining elements were novel to us
	}
}

// Merge the set into our state, abiding increment-only semantics.
// Return a non-nil mesh.GossipData representation of the received set.

Merge the set into our state abiding increment - only semantics . Return a non - nil mesh . GossipData representation of the received set .


func (st *state) mergeComplete(set map[mesh.PeerName]int) (complete mesh.GossipData) {
	st.mtx.Lock()
	defer st.mtx.Unlock()

	for peer, v := range set {
		if v > st.set[peer] {
			st.set[peer] = v
		}
	}

	return &state{
		set: st.set, // n.b. can't .copy() due to lock contention
	}
}

// Merge the set into our state, abiding increment-only semantics.
// Return our resulting, complete state.

Merge the set into our state abiding increment - only semantics . Return our resulting complete state .


func (*surrogateGossiper) OnGossipBroadcast(_ PeerName, update []byte) (GossipData, error) {
	return newSurrogateGossipData(update), nil
}

func ( * surrogateGossiper ) OnGossipBroadcast ( _ PeerName , update [ ] byte ) ( GossipData , error ) { return newSurrogateGossipData ( update ) , nil }

// OnGossipBroadcast implements Gossiper.


func (s *surrogateGossiper) OnGossip(update []byte) (GossipData, error) {
	hash := fnv.New64a()
	_, _ = hash.Write(update)
	updateHash := hash.Sum64()
	s.Lock()
	defer s.Unlock()
	for _, p := range s.prevUpdates {
		if updateHash == p.hash && bytes.Equal(update, p.update) {
			return nil, nil
		}
	}
	// Delete anything that's older than the gossip interval, so we don't grow forever
	// (this time limit is arbitrary; surrogateGossiper should pass on new gossip immediately
	// so there should be no reason for a duplicate to show up after a long time)
	updateTime := now()
	deleteBefore := updateTime.Add(-gossipInterval)
	keepFrom := len(s.prevUpdates)
	for i, p := range s.prevUpdates {
		if p.t.After(deleteBefore) {
			keepFrom = i
			break
		}
	}
	s.prevUpdates = append(s.prevUpdates[keepFrom:], prevUpdate{update, updateHash, updateTime})
	return newSurrogateGossipData(update), nil
}

// OnGossip should return "everything new I've just learnt".
// surrogateGossiper doesn't understand the content of messages, but it can eliminate simple duplicates

OnGossip should return everything new I ve just learnt . surrogateGossiper doesn t understand the content of messages but it can eliminate simple duplicates


func generateKeyPair() (publicKey, privateKey *[32]byte, err error) {
	return box.GenerateKey(rand.Reader)
}

func generateKeyPair ( ) ( publicKey , privateKey * [ 32 ] byte , err error ) { return box . GenerateKey ( rand . Reader ) }

// GenerateKeyPair is used during encrypted protocol introduction.

GenerateKeyPair is used during encrypted protocol introduction .


func formSessionKey(remotePublicKey, localPrivateKey *[32]byte, secretKey []byte) *[32]byte {
	var sharedKey [32]byte
	box.Precompute(&sharedKey, remotePublicKey, localPrivateKey)
	sharedKeySlice := sharedKey[:]
	sharedKeySlice = append(sharedKeySlice, secretKey...)
	sessionKey := sha256.Sum256(sharedKeySlice)
	return &sessionKey
}

func formSessionKey ( remotePublicKey , localPrivateKey * [ 32 ] byte , secretKey [ ] byte ) * [ 32 ] byte { var sharedKey [ 32 ] byte box . Precompute ( & sharedKey , remotePublicKey , localPrivateKey ) sharedKeySlice := sharedKey [ : ] sharedKeySlice = append ( sharedKeySlice , secretKey ... ) sessionKey := sha256 . Sum256 ( sharedKeySlice ) return & sessionKey }

// FormSessionKey is used during encrypted protocol introduction.

FormSessionKey is used during encrypted protocol introduction .


func newTCPCryptoState(sessionKey *[32]byte, outbound bool) *tcpCryptoState {
	s := &tcpCryptoState{sessionKey: sessionKey}
	if outbound {
		s.nonce[0] |= (1 << 7)
	}
	s.nonce[0] |= (1 << 6)
	return s
}

func newTCPCryptoState ( sessionKey * [ 32 ] byte , outbound bool ) * tcpCryptoState { s := & tcpCryptoState { sessionKey : sessionKey } if outbound { s . nonce [ 0 ] |= ( 1 << 7 ) } s . nonce [ 0 ] |= ( 1 << 6 ) return s }

// NewTCPCryptoState returns a valid TCPCryptoState.

NewTCPCryptoState returns a valid TCPCryptoState .


func (sender *gobTCPSender) Send(msg []byte) error {
	return sender.encoder.Encode(msg)
}

func ( sender * gobTCPSender ) Send ( msg [ ] byte ) error { return sender . encoder . Encode ( msg ) }

// Send implements TCPSender by encoding the msg.

Send implements TCPSender by encoding the msg .