<commit_before>package lfs

import (
	"fmt"
	"os"
	"path/filepath"
	"sync"
	"sync/atomic"

	"github.com/github/git-lfs/git"
	"github.com/github/git-lfs/vendor/_nuts/github.com/cheggaaa/pb"
	"github.com/github/git-lfs/vendor/_nuts/github.com/rubyist/tracerx"
)

type Transferable interface {
	Check() (*objectResource, *WrappedError)
	Transfer(CopyCallback) *WrappedError
	Object() *objectResource
	Oid() string
	Size() int64
	Name() string
	SetObject(*objectResource)
}

// TransferQueue provides a queue that will allow concurrent transfers.
type TransferQueue struct {
	transferc        chan Transferable
	errorc           chan *WrappedError
	watchers         []chan string
	errors           []*WrappedError
	wg               sync.WaitGroup
	workers          int
	files            int
	finished         int64
	size             int64
	authCond         *sync.Cond
	transferables    map[string]Transferable
	bar              *pb.ProgressBar
	clientAuthorized int32
	transferKind     string
}

// newTransferQueue builds a TransferQueue, allowing `workers` concurrent transfers.
func newTransferQueue(workers, files int) *TransferQueue {
	return &TransferQueue{
		transferc:     make(chan Transferable, files),
		errorc:        make(chan *WrappedError),
		watchers:      make([]chan string, 0),
		workers:       workers,
		files:         files,
		authCond:      sync.NewCond(&sync.Mutex{}),
		transferables: make(map[string]Transferable),
	}
}

// Add adds a Transferable to the transfer queue.
func (q *TransferQueue) Add(t Transferable) {
	q.transferables[t.Oid()] = t
}

// Watch returns a channel where the queue will write the OID of each transfer
// as it completes. The channel will be closed when the queue finishes processing.
func (q *TransferQueue) Watch() chan string {
	c := make(chan string, q.files)
	q.watchers = append(q.watchers, c)
	return c
}

// processIndividual processes the queue of transfers one at a time by making
// a POST call for each object, feeding the results to the transfer workers.
// If configured, the object transfers can still happen concurrently, the
// sequential nature here is only for the meta POST calls.
func (q *TransferQueue) processIndividual() {
	apic := make(chan Transferable, q.files)
	workersReady := make(chan int, q.workers)
	var wg sync.WaitGroup

	for i := 0; i < q.workers; i++ {
		go func() {
			for t := range apic {
				// If an API authorization has not occured, we wait until we're woken up.
				q.authCond.L.Lock()
				if atomic.LoadInt32(&q.clientAuthorized) == 0 {
					workersReady <- 1
					q.authCond.Wait()
				}
				q.authCond.L.Unlock()

				obj, err := t.Check()
				if err != nil {
					q.errorc <- err
					wg.Done()
					continue
				}
				if obj != nil {
					q.wg.Add(1)
					t.SetObject(obj)
					q.transferc <- t
				}
				wg.Done()
			}
		}()
	}

	q.bar.Prefix(fmt.Sprintf("(%d of %d files) ", q.finished, len(q.transferables)))
	q.bar.Start()

	for _, t := range q.transferables {
		wg.Add(1)
		apic <- t
	}

	go func() {
		wg.Wait()
		close(workersReady)
	}()

	<-workersReady
	q.authCond.L.Lock()
	q.authCond.Signal() // Signal the first goroutine to run
	q.authCond.L.Unlock()

	close(apic)
	for _ = range workersReady {
	}

	close(q.transferc)
}

// processBatch processes the queue of transfers using the batch endpoint,
// making only one POST call for all objects. The results are then handed
// off to the transfer workers.
func (q *TransferQueue) processBatch() error {
	transfers := make([]*objectResource, 0, len(q.transferables))
	for _, t := range q.transferables {
		transfers = append(transfers, &objectResource{Oid: t.Oid(), Size: t.Size()})
	}

	objects, err := Batch(transfers)
	if err != nil {
		if isNotImplError(err) {
			tracerx.Printf("queue: batch not implemented, disabling")
			configFile := filepath.Join(LocalGitDir, "config")
			git.Config.SetLocal(configFile, "lfs.batch", "false")
		}

		return err
	}

	q.files = 0

	for _, o := range objects {
		if _, ok := o.Links[q.transferKind]; ok {
			// This object needs to be transfered
			if transfer, ok := q.transferables[o.Oid]; ok {
				q.files++
				q.wg.Add(1)
				transfer.SetObject(o)
				q.transferc <- transfer
			}
		}
	}

	close(q.transferc)
	q.bar.Prefix(fmt.Sprintf("(%d of %d files) ", q.finished, q.files))
	q.bar.Start()
	sendApiEvent(apiEventSuccess) // Wake up transfer workers
	return nil
}

// Process starts the transfer queue and displays a progress bar. Process will
// do individual or batch transfers depending on the Config.BatchTransfer() value.
// Process will transfer files sequentially or concurrently depending on the
// Concig.ConcurrentTransfers() value.
func (q *TransferQueue) Process() {
	q.bar = pb.New64(q.size)
	q.bar.SetUnits(pb.U_BYTES)
	q.bar.ShowBar = false

	// This goroutine collects errors returned from transfers
	go func() {
		for err := range q.errorc {
			q.errors = append(q.errors, err)
		}
	}()

	// This goroutine watches for apiEvents. In order to prevent multiple
	// credential requests from happening, the queue is processed sequentially
	// until an API request succeeds (meaning authenication has happened successfully).
	// Once the an API request succeeds, all worker goroutines are woken up and allowed
	// to process transfers. Once a success happens, this goroutine exits.
	go func() {
		for {
			event := <-apiEvent
			switch event {
			case apiEventSuccess:
				atomic.StoreInt32(&q.clientAuthorized, 1)
				q.authCond.Broadcast() // Wake all remaining goroutines
				return
			case apiEventFail:
				q.authCond.Signal() // Wake the next goroutine
			}
		}
	}()

	// This goroutine will send progress output to GIT_LFS_PROGRESS if it has been set
	progressc := make(chan string, 100)
	go func() {
		output, err := newProgressLogger()
		if err != nil {
			q.errorc <- Error(err)
		}

		for l := range progressc {
			if err := output.Write([]byte(l)); err != nil {
				q.errorc <- Error(err)
				output.Shutdown()
			}
		}

		output.Close()
	}()

	var transferCount = int64(0)
	direction := "push"
	if q.transferKind == "download" {
		direction = "pull"
	}

	for i := 0; i < q.workers; i++ {
		// These are the worker goroutines that process transfers
		go func() {
			for transfer := range q.transferc {
				c := atomic.AddInt64(&transferCount, 1)
				cb := func(total, read int64, current int) error {
					progressc <- fmt.Sprintf("%s %d/%d %d/%d %s\n", direction, c, q.files, read, total, transfer.Name())
					q.bar.Add(current)
					return nil
				}

				if err := transfer.Transfer(cb); err != nil {
					q.errorc <- err
				} else {
					oid := transfer.Oid()
					for _, c := range q.watchers {
						c <- oid
					}
				}

				f := atomic.AddInt64(&q.finished, 1)
				q.bar.Prefix(fmt.Sprintf("(%d of %d files) ", f, q.files))
				q.wg.Done()
			}
		}()
	}

	if Config.BatchTransfer() {
		if err := q.processBatch(); err != nil {
			q.processIndividual()
		}
	} else {
		q.processIndividual()
	}

	q.wg.Wait()
	close(q.errorc)
	for _, watcher := range q.watchers {
		close(watcher)
	}
	close(progressc)

	q.bar.Finish()
}

// Errors returns any errors encountered during transfer.
func (q *TransferQueue) Errors() []*WrappedError {
	return q.errors
}

// progressLogger provides a wrapper around an os.File that can either
// write to the file or ignore all writes completely.
type progressLogger struct {
	writeData bool
	log       *os.File
}

// Write will write to the file and perform a Sync() if writing succeeds.
func (l *progressLogger) Write(b []byte) error {
	if l.writeData {
		if _, err := l.log.Write(b); err != nil {
			return err
		}
		return l.log.Sync()
	}
	return nil
}

// Close will call Close() on the underlying file
func (l *progressLogger) Close() error {
	if l.log != nil {
		return l.log.Close()
	}
	return nil
}

// Shutdown will cause the logger to ignore any further writes. It should
// be used when writing causes an error.
func (l *progressLogger) Shutdown() {
	l.writeData = false
}

// newProgressLogger creates a progressLogger based on the presence of
// the GIT_LFS_PROGRESS environment variable. If it is present and a log file
// is able to be created, the logger will write to the file. If it is absent,
// or there is an err creating the file, the logger will ignore all writes.
func newProgressLogger() (*progressLogger, error) {
	logPath := Config.Getenv("GIT_LFS_PROGRESS")

	if len(logPath) == 0 {
		return &progressLogger{}, nil
	}
	if !filepath.IsAbs(logPath) {
		return &progressLogger{}, fmt.Errorf("GIT_LFS_PROGRESS must be an absolute path")
	}

	cbDir := filepath.Dir(logPath)
	if err := os.MkdirAll(cbDir, 0755); err != nil {
		return &progressLogger{}, err
	}

	file, err := os.OpenFile(logPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		return &progressLogger{}, err
	}

	return &progressLogger{true, file}, nil
}
<commit_msg>ララララー ラララー ララ<commit_after>package lfs

import (
	"fmt"
	"os"
	"path/filepath"
	"sync"
	"sync/atomic"

	"github.com/github/git-lfs/git"
	"github.com/github/git-lfs/vendor/_nuts/github.com/cheggaaa/pb"
	"github.com/github/git-lfs/vendor/_nuts/github.com/rubyist/tracerx"
)

type Transferable interface {
	Check() (*objectResource, *WrappedError)
	Transfer(CopyCallback) *WrappedError
	Object() *objectResource
	Oid() string
	Size() int64
	Name() string
	SetObject(*objectResource)
}

// TransferQueue provides a queue that will allow concurrent transfers.
type TransferQueue struct {
	transferc        chan Transferable
	errorc           chan *WrappedError
	watchers         []chan string
	errors           []*WrappedError
	wg               sync.WaitGroup
	workers          int
	files            int
	finished         int32
	size             int64
	authCond         *sync.Cond
	transferables    map[string]Transferable
	bar              *pb.ProgressBar
	clientAuthorized int32
	transferKind     string
}

// newTransferQueue builds a TransferQueue, allowing `workers` concurrent transfers.
func newTransferQueue(workers, files int) *TransferQueue {
	return &TransferQueue{
		transferc:     make(chan Transferable, files),
		errorc:        make(chan *WrappedError),
		watchers:      make([]chan string, 0),
		workers:       workers,
		files:         files,
		authCond:      sync.NewCond(&sync.Mutex{}),
		transferables: make(map[string]Transferable),
	}
}

// Add adds a Transferable to the transfer queue.
func (q *TransferQueue) Add(t Transferable) {
	q.transferables[t.Oid()] = t
}

// Watch returns a channel where the queue will write the OID of each transfer
// as it completes. The channel will be closed when the queue finishes processing.
func (q *TransferQueue) Watch() chan string {
	c := make(chan string, q.files)
	q.watchers = append(q.watchers, c)
	return c
}

// processIndividual processes the queue of transfers one at a time by making
// a POST call for each object, feeding the results to the transfer workers.
// If configured, the object transfers can still happen concurrently, the
// sequential nature here is only for the meta POST calls.
func (q *TransferQueue) processIndividual() {
	apic := make(chan Transferable, q.files)
	workersReady := make(chan int, q.workers)
	var wg sync.WaitGroup

	for i := 0; i < q.workers; i++ {
		go func() {
			for t := range apic {
				// If an API authorization has not occured, we wait until we're woken up.
				q.authCond.L.Lock()
				if atomic.LoadInt32(&q.clientAuthorized) == 0 {
					workersReady <- 1
					q.authCond.Wait()
				}
				q.authCond.L.Unlock()

				obj, err := t.Check()
				if err != nil {
					q.errorc <- err
					wg.Done()
					continue
				}
				if obj != nil {
					q.wg.Add(1)
					t.SetObject(obj)
					q.transferc <- t
				}
				wg.Done()
			}
		}()
	}

	q.bar.Prefix(fmt.Sprintf("(%d of %d files) ", q.finished, len(q.transferables)))
	q.bar.Start()

	for _, t := range q.transferables {
		wg.Add(1)
		apic <- t
	}

	go func() {
		wg.Wait()
		close(workersReady)
	}()

	<-workersReady
	q.authCond.L.Lock()
	q.authCond.Signal() // Signal the first goroutine to run
	q.authCond.L.Unlock()

	close(apic)
	for _ = range workersReady {
	}

	close(q.transferc)
}

// processBatch processes the queue of transfers using the batch endpoint,
// making only one POST call for all objects. The results are then handed
// off to the transfer workers.
func (q *TransferQueue) processBatch() error {
	transfers := make([]*objectResource, 0, len(q.transferables))
	for _, t := range q.transferables {
		transfers = append(transfers, &objectResource{Oid: t.Oid(), Size: t.Size()})
	}

	objects, err := Batch(transfers)
	if err != nil {
		if isNotImplError(err) {
			tracerx.Printf("queue: batch not implemented, disabling")
			configFile := filepath.Join(LocalGitDir, "config")
			git.Config.SetLocal(configFile, "lfs.batch", "false")
		}

		return err
	}

	q.files = 0

	for _, o := range objects {
		if _, ok := o.Links[q.transferKind]; ok {
			// This object needs to be transfered
			if transfer, ok := q.transferables[o.Oid]; ok {
				q.files++
				q.wg.Add(1)
				transfer.SetObject(o)
				q.transferc <- transfer
			}
		}
	}

	close(q.transferc)
	q.bar.Prefix(fmt.Sprintf("(%d of %d files) ", q.finished, q.files))
	q.bar.Start()
	sendApiEvent(apiEventSuccess) // Wake up transfer workers
	return nil
}

// Process starts the transfer queue and displays a progress bar. Process will
// do individual or batch transfers depending on the Config.BatchTransfer() value.
// Process will transfer files sequentially or concurrently depending on the
// Concig.ConcurrentTransfers() value.
func (q *TransferQueue) Process() {
	q.bar = pb.New64(q.size)
	q.bar.SetUnits(pb.U_BYTES)
	q.bar.ShowBar = false

	// This goroutine collects errors returned from transfers
	go func() {
		for err := range q.errorc {
			q.errors = append(q.errors, err)
		}
	}()

	// This goroutine watches for apiEvents. In order to prevent multiple
	// credential requests from happening, the queue is processed sequentially
	// until an API request succeeds (meaning authenication has happened successfully).
	// Once the an API request succeeds, all worker goroutines are woken up and allowed
	// to process transfers. Once a success happens, this goroutine exits.
	go func() {
		for {
			event := <-apiEvent
			switch event {
			case apiEventSuccess:
				atomic.StoreInt32(&q.clientAuthorized, 1)
				q.authCond.Broadcast() // Wake all remaining goroutines
				return
			case apiEventFail:
				q.authCond.Signal() // Wake the next goroutine
			}
		}
	}()

	// This goroutine will send progress output to GIT_LFS_PROGRESS if it has been set
	progressc := make(chan string, 100)
	go func() {
		output, err := newProgressLogger()
		if err != nil {
			q.errorc <- Error(err)
		}

		for l := range progressc {
			if err := output.Write([]byte(l)); err != nil {
				q.errorc <- Error(err)
				output.Shutdown()
			}
		}

		output.Close()
	}()

	var transferCount = int32(0)
	direction := "push"
	if q.transferKind == "download" {
		direction = "pull"
	}

	for i := 0; i < q.workers; i++ {
		// These are the worker goroutines that process transfers
		go func() {
			for transfer := range q.transferc {
				c := atomic.AddInt32(&transferCount, 1)
				cb := func(total, read int64, current int) error {
					progressc <- fmt.Sprintf("%s %d/%d %d/%d %s\n", direction, c, q.files, read, total, transfer.Name())
					q.bar.Add(current)
					return nil
				}

				if err := transfer.Transfer(cb); err != nil {
					q.errorc <- err
				} else {
					oid := transfer.Oid()
					for _, c := range q.watchers {
						c <- oid
					}
				}

				f := atomic.AddInt32(&q.finished, 1)
				q.bar.Prefix(fmt.Sprintf("(%d of %d files) ", f, q.files))
				q.wg.Done()
			}
		}()
	}

	if Config.BatchTransfer() {
		if err := q.processBatch(); err != nil {
			q.processIndividual()
		}
	} else {
		q.processIndividual()
	}

	q.wg.Wait()
	close(q.errorc)
	for _, watcher := range q.watchers {
		close(watcher)
	}
	close(progressc)

	q.bar.Finish()
}

// Errors returns any errors encountered during transfer.
func (q *TransferQueue) Errors() []*WrappedError {
	return q.errors
}

// progressLogger provides a wrapper around an os.File that can either
// write to the file or ignore all writes completely.
type progressLogger struct {
	writeData bool
	log       *os.File
}

// Write will write to the file and perform a Sync() if writing succeeds.
func (l *progressLogger) Write(b []byte) error {
	if l.writeData {
		if _, err := l.log.Write(b); err != nil {
			return err
		}
		return l.log.Sync()
	}
	return nil
}

// Close will call Close() on the underlying file
func (l *progressLogger) Close() error {
	if l.log != nil {
		return l.log.Close()
	}
	return nil
}

// Shutdown will cause the logger to ignore any further writes. It should
// be used when writing causes an error.
func (l *progressLogger) Shutdown() {
	l.writeData = false
}

// newProgressLogger creates a progressLogger based on the presence of
// the GIT_LFS_PROGRESS environment variable. If it is present and a log file
// is able to be created, the logger will write to the file. If it is absent,
// or there is an err creating the file, the logger will ignore all writes.
func newProgressLogger() (*progressLogger, error) {
	logPath := Config.Getenv("GIT_LFS_PROGRESS")

	if len(logPath) == 0 {
		return &progressLogger{}, nil
	}
	if !filepath.IsAbs(logPath) {
		return &progressLogger{}, fmt.Errorf("GIT_LFS_PROGRESS must be an absolute path")
	}

	cbDir := filepath.Dir(logPath)
	if err := os.MkdirAll(cbDir, 0755); err != nil {
		return &progressLogger{}, err
	}

	file, err := os.OpenFile(logPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		return &progressLogger{}, err
	}

	return &progressLogger{true, file}, nil
}
<|endoftext|>


<commit_before>package main

import (
//	"net"
	"net/http"
	"log"
//	"io/ioutil"
	"flag"
	"os"
	"path/filepath"
	"regexp"
	"fmt"
)

var (
	rootdir string
	port string
	address string
	verbose bool
)

func init() {
	flag.StringVar(&rootdir, "root", "current directory", "webroot directory")
	flag.StringVar(&rootdir, "d", "current directory", "webroot directory" + " (shorthand)")
	flag.StringVar(&port,"port", "8080", "listen port")
	flag.StringVar(&port,"p", "8080", "listen port" + " (shorthand)")
	flag.StringVar(&address, "address", "*", "listen address")
	flag.StringVar(&address, "l", "*", "listen address" + " (shorthand)")
	flag.BoolVar(&verbose, "verbose", false, "be verbose")
	flag.BoolVar(&verbose, "v", false, "be verbose" + " (shorthand)")

	if rootdir == "current directory" {
		rootdir, err :=  filepath.Abs(filepath.Dir(os.Args[0]))
		if err != nil {
			log.Fatal(err)
		}
		log.Print("Webroot set to \"" + rootdir + "\".")
	}
	if address == "*" {
		address = ""
	}
}

func debug(s string) {
	if verbose {
		log.Print(s)
	}
}

var validLog = regexp.MustCompile("^/log/([a-zA-Z0-9-]+)/([0-9]+)/?$")

func logHandler(w http.ResponseWriter, r *http.Request) {
	m := validLog.FindStringSubmatch(r.URL.Path)
	if m == nil {
		http.Error(w, "Sensor not found", http.StatusNotFound)
	}
	debug("Sensor " + m[1] + " sent value " + m[2])
	fmt.Fprintf(w, "ok")
}

func main() {
	flag.Parse()
	http.HandleFunc("/log/", logHandler)
	http.Handle("/", http.FileServer(http.Dir(rootdir)))

	log.Print("Starting webserver. Listening on " + address + ":" + port)
	err := http.ListenAndServe(address + ":" + port, nil)
	if err != nil {
		log.Fatal("Couldn't start server. ListenAndServe: ", err)
	}
}

<commit_msg>fixed invalid sensor log url<commit_after>package main

import (
//	"net"
	"net/http"
	"log"
//	"io/ioutil"
	"flag"
	"os"
	"path/filepath"
	"regexp"
	"fmt"
//	"reflect"
)

var (
	rootdir string
	port string
	address string
	verbose bool
)

func init() {
	flag.StringVar(&rootdir, "root", "current directory", "webroot directory")
	flag.StringVar(&rootdir, "d", "current directory", "webroot directory" + " (shorthand)")
	flag.StringVar(&port,"port", "8080", "listen port")
	flag.StringVar(&port,"p", "8080", "listen port" + " (shorthand)")
	flag.StringVar(&address, "address", "*", "listen address")
	flag.StringVar(&address, "l", "*", "listen address" + " (shorthand)")
	flag.BoolVar(&verbose, "verbose", false, "be verbose")
	flag.BoolVar(&verbose, "v", false, "be verbose" + " (shorthand)")

	if rootdir == "current directory" {
		rootdir, err :=  filepath.Abs(filepath.Dir(os.Args[0]))
		if err != nil {
			log.Fatal(err)
		}
		log.Print("Webroot set to \"" + rootdir + "\".")
	}
	if address == "*" {
		address = ""
	}
}

func debug(s string) {
	if verbose {
		log.Print(s)
	}
}

var validLog = regexp.MustCompile("^/log/([a-zA-Z0-9-]+)/([0-9]+)/?$")

func logHandler(w http.ResponseWriter, r *http.Request) {
	m := validLog.FindStringSubmatch(r.URL.Path)
	if len(m) == 0 {
		http.Error(w, "Sensor not found", http.StatusNotFound)
		return
	}
	debug("Sensor " + m[1] + " sent value " + m[2])
	fmt.Fprintf(w, "ok")
}

func main() {
	flag.Parse()
	http.HandleFunc("/log/", logHandler)
	http.Handle("/", http.FileServer(http.Dir(rootdir)))

	log.Print("Starting webserver. Listening on " + address + ":" + port)
	err := http.ListenAndServe(address + ":" + port, nil)
	if err != nil {
		log.Fatal("Couldn't start server. ListenAndServe: ", err)
	}
}

<|endoftext|>


<commit_before>package common

import (
	"net"

	"github.com/miekg/dns"
)

type EDNSClientSubnetType struct {
	Policy     string `yaml:"policy"`
	ExternalIP string `yaml:"externalIP"`
	NoCookie   bool   `yaml:"noCookie"`
}

func SetEDNSClientSubnet(m *dns.Msg, ip string, isNoCookie bool) {
	if ip == "" {
		return
	}

	o := m.IsEdns0()
	if o == nil {
		o = new(dns.OPT)
		o.SetUDPSize(4096)
		o.Hdr.Name = "."
		o.Hdr.Rrtype = dns.TypeOPT
		m.Extra = append(m.Extra, o)
	}

	es := IsEDNSClientSubnet(o)
	if es == nil || es.Address.IsUnspecified() {
		nes := new(dns.EDNS0_SUBNET)
		nes.Code = dns.EDNS0SUBNET
		nes.Address = net.ParseIP(ip)
		if nes.Address.To4() != nil {
			nes.Family = 1         // 1 for IPv4 source address, 2 for IPv6
			nes.SourceNetmask = 24 // 24 for IPV4, 64 for IPv6
		} else {
			nes.Family = 2          // 1 for IPv4 source address, 2 for IPv6
			nes.SourceNetmask = 64 // 24 for IPV4, 64 for IPv6
		}
		nes.SourceScope = 0
		if es != nil && es.Address.IsUnspecified() {
			var edns0 []dns.EDNS0
			for _, s := range o.Option {
				switch e := s.(type) {
				case *dns.EDNS0_SUBNET:
				default:
					edns0 = append(edns0, e)
				}
			}
			o.Option = edns0
		}
		o.Option = append(o.Option, nes)
		if isNoCookie {
			deleteCookie(o)
		}
	}
}

func deleteCookie(o *dns.OPT) {
	for i, e0 := range o.Option {
		switch e0.(type) {
		case *dns.EDNS0_COOKIE:
			o.Option = append(o.Option[:i], o.Option[i+1:]...)
		}
	}
}

func IsEDNSClientSubnet(o *dns.OPT) *dns.EDNS0_SUBNET {
	for _, s := range o.Option {
		switch e := s.(type) {
		case *dns.EDNS0_SUBNET:
			return e
		}
	}
	return nil
}

func GetEDNSClientSubnetIP(m *dns.Msg) string {
	o := m.IsEdns0()
	if o != nil {
		for _, s := range o.Option {
			switch e := s.(type) {
			case *dns.EDNS0_SUBNET:
				return e.Address.String()
			}
		}
	}
	return ""
}
<commit_msg>fix(edns): modify `SourceNetmask` for IPv6 (#260)<commit_after>package common

import (
	"net"

	"github.com/miekg/dns"
)

type EDNSClientSubnetType struct {
	Policy     string `yaml:"policy"`
	ExternalIP string `yaml:"externalIP"`
	NoCookie   bool   `yaml:"noCookie"`
}

func SetEDNSClientSubnet(m *dns.Msg, ip string, isNoCookie bool) {
	if ip == "" {
		return
	}

	o := m.IsEdns0()
	if o == nil {
		o = new(dns.OPT)
		o.SetUDPSize(4096)
		o.Hdr.Name = "."
		o.Hdr.Rrtype = dns.TypeOPT
		m.Extra = append(m.Extra, o)
	}

	es := IsEDNSClientSubnet(o)
	if es == nil || es.Address.IsUnspecified() {
		nes := new(dns.EDNS0_SUBNET)
		nes.Code = dns.EDNS0SUBNET
		nes.Address = net.ParseIP(ip)
		if nes.Address.To4() != nil {
			nes.Family = 1         // 1 for IPv4 source address, 2 for IPv6
			nes.SourceNetmask = 24 // 24 for IPV4, 56 for IPv6
		} else {
			nes.Family = 2          // 1 for IPv4 source address, 2 for IPv6
			nes.SourceNetmask = 56 // 24 for IPV4, 56 for IPv6
		}
		nes.SourceScope = 0
		if es != nil && es.Address.IsUnspecified() {
			var edns0 []dns.EDNS0
			for _, s := range o.Option {
				switch e := s.(type) {
				case *dns.EDNS0_SUBNET:
				default:
					edns0 = append(edns0, e)
				}
			}
			o.Option = edns0
		}
		o.Option = append(o.Option, nes)
		if isNoCookie {
			deleteCookie(o)
		}
	}
}

func deleteCookie(o *dns.OPT) {
	for i, e0 := range o.Option {
		switch e0.(type) {
		case *dns.EDNS0_COOKIE:
			o.Option = append(o.Option[:i], o.Option[i+1:]...)
		}
	}
}

func IsEDNSClientSubnet(o *dns.OPT) *dns.EDNS0_SUBNET {
	for _, s := range o.Option {
		switch e := s.(type) {
		case *dns.EDNS0_SUBNET:
			return e
		}
	}
	return nil
}

func GetEDNSClientSubnetIP(m *dns.Msg) string {
	o := m.IsEdns0()
	if o != nil {
		for _, s := range o.Option {
			switch e := s.(type) {
			case *dns.EDNS0_SUBNET:
				return e.Address.String()
			}
		}
	}
	return ""
}
<|endoftext|>


<commit_before>package platform

import (
	"time"

	"github.com/cloudfoundry/bosh-agent/infrastructure/devicepathresolver"
	boshcdrom "github.com/cloudfoundry/bosh-agent/platform/cdrom"
	boshcert "github.com/cloudfoundry/bosh-agent/platform/cert"
	boshdisk "github.com/cloudfoundry/bosh-agent/platform/disk"
	boshnet "github.com/cloudfoundry/bosh-agent/platform/net"
	bosharp "github.com/cloudfoundry/bosh-agent/platform/net/arp"
	boship "github.com/cloudfoundry/bosh-agent/platform/net/ip"
	boshstats "github.com/cloudfoundry/bosh-agent/platform/stats"
	boshudev "github.com/cloudfoundry/bosh-agent/platform/udevdevice"
	boshvitals "github.com/cloudfoundry/bosh-agent/platform/vitals"
	boshdirs "github.com/cloudfoundry/bosh-agent/settings/directories"
	bosherror "github.com/cloudfoundry/bosh-utils/errors"
	boshcmd "github.com/cloudfoundry/bosh-utils/fileutil"
	boshlog "github.com/cloudfoundry/bosh-utils/logger"
	boshretry "github.com/cloudfoundry/bosh-utils/retrystrategy"
	boshsys "github.com/cloudfoundry/bosh-utils/system"

	"github.com/pivotal-golang/clock"
)

const (
	ArpIterations          = 20
	ArpIterationDelay      = 5 * time.Second
	ArpInterfaceCheckDelay = 100 * time.Millisecond
)

const (
	SigarStatsCollectionInterval = 10 * time.Second
)

type Provider interface {
	Get(name string) (Platform, error)
}

type provider struct {
	platforms map[string]Platform
}

type Options struct {
	Linux LinuxOptions
}

func NewProvider(logger boshlog.Logger, dirProvider boshdirs.Provider, statsCollector boshstats.Collector, scriptCommandFactory boshsys.ScriptCommandFactory, fs boshsys.FileSystem, options Options, bootstrapState *BootstrapState, clock clock.Clock) Provider {
	runner := boshsys.NewExecCmdRunner(logger)
	linuxDiskManager := boshdisk.NewLinuxDiskManager(logger, runner, fs, options.Linux.BindMountPersistentDisk)

	udev := boshudev.NewConcreteUdevDevice(runner, logger)
	linuxCdrom := boshcdrom.NewLinuxCdrom("/dev/sr0", udev, runner)
	linuxCdutil := boshcdrom.NewCdUtil(dirProvider.SettingsDir(), fs, linuxCdrom, logger)

	compressor := boshcmd.NewTarballCompressor(runner, fs)
	copier := boshcmd.NewCpCopier(runner, fs, logger)

	// Kick of stats collection as soon as possible
	statsCollector.StartCollecting(SigarStatsCollectionInterval, nil)

	vitalsService := boshvitals.NewService(statsCollector, dirProvider)

	ipResolver := boship.NewResolver(boship.NetworkInterfaceToAddrsFunc)

	arping := bosharp.NewArping(runner, fs, logger, ArpIterations, ArpIterationDelay, ArpInterfaceCheckDelay)
	interfaceConfigurationCreator := boshnet.NewInterfaceConfigurationCreator(logger)

	interfaceAddressesProvider := boship.NewSystemInterfaceAddressesProvider()
	interfaceAddressesValidator := boship.NewInterfaceAddressesValidator(interfaceAddressesProvider)
	dnsValidator := boshnet.NewDNSValidator(fs)

	centosNetManager := boshnet.NewCentosNetManager(fs, runner, ipResolver, interfaceConfigurationCreator, interfaceAddressesValidator, dnsValidator, arping, logger)
	ubuntuNetManager := boshnet.NewUbuntuNetManager(fs, runner, ipResolver, interfaceConfigurationCreator, interfaceAddressesValidator, dnsValidator, arping, logger)

	scriptRunner := boshsys.NewConcreteScriptRunner(scriptCommandFactory, runner, fs, logger)
	windowsNetManager := boshnet.NewWindowsNetManager(scriptRunner, logger, clock)

	centosCertManager := boshcert.NewCentOSCertManager(fs, runner, 0, logger)
	ubuntuCertManager := boshcert.NewUbuntuCertManager(fs, runner, 60, logger)

	routesSearcher := boshnet.NewCmdRoutesSearcher(runner)
	linuxDefaultNetworkResolver := boshnet.NewDefaultNetworkResolver(routesSearcher, ipResolver)

	monitRetryable := NewMonitRetryable(runner)
	monitRetryStrategy := boshretry.NewAttemptRetryStrategy(10, 1*time.Second, monitRetryable, logger)

	var devicePathResolver devicepathresolver.DevicePathResolver
	switch options.Linux.DevicePathResolutionType {
	case "virtio":
		udev := boshudev.NewConcreteUdevDevice(runner, logger)
		idDevicePathResolver := devicepathresolver.NewIDDevicePathResolver(500*time.Millisecond, options.Linux.VirtioDevicePrefix, udev, fs)
		mappedDevicePathResolver := devicepathresolver.NewMappedDevicePathResolver(500*time.Millisecond, fs)
		devicePathResolver = devicepathresolver.NewVirtioDevicePathResolver(idDevicePathResolver, mappedDevicePathResolver, logger)
	case "scsi":
		scsiIDPathResolver := devicepathresolver.NewSCSIIDDevicePathResolver(50000*time.Millisecond, fs, logger)
		scsiVolumeIDPathResolver := devicepathresolver.NewSCSIVolumeIDDevicePathResolver(500*time.Millisecond, fs)
		scsiLunPathResolver := devicepathresolver.NewSCSILunDevicePathResolver(50000*time.Millisecond, fs, logger)
		devicePathResolver = devicepathresolver.NewScsiDevicePathResolver(scsiVolumeIDPathResolver, scsiIDPathResolver, scsiLunPathResolver)
	default:
		devicePathResolver = devicepathresolver.NewIdentityDevicePathResolver()
	}

	centos := NewLinuxPlatform(
		fs,
		runner,
		statsCollector,
		compressor,
		copier,
		dirProvider,
		vitalsService,
		linuxCdutil,
		linuxDiskManager,
		centosNetManager,
		centosCertManager,
		monitRetryStrategy,
		devicePathResolver,
		500*time.Millisecond,
		bootstrapState,
		options.Linux,
		logger,
		linuxDefaultNetworkResolver,
	)

	ubuntu := NewLinuxPlatform(
		fs,
		runner,
		statsCollector,
		compressor,
		copier,
		dirProvider,
		vitalsService,
		linuxCdutil,
		linuxDiskManager,
		ubuntuNetManager,
		ubuntuCertManager,
		monitRetryStrategy,
		devicePathResolver,
		500*time.Millisecond,
		bootstrapState,
		options.Linux,
		logger,
		linuxDefaultNetworkResolver,
	)

	return provider{
		platforms: map[string]Platform{
			"ubuntu":  ubuntu,
			"centos":  centos,
			"dummy":   NewDummyPlatform(statsCollector, fs, runner, dirProvider, devicePathResolver, logger),
			"windows": NewWindowsPlatform(statsCollector, fs, runner, dirProvider, windowsNetManager, devicePathResolver, logger),
		},
	}
}

func (p provider) Get(name string) (Platform, error) {
	plat, found := p.platforms[name]
	if !found {
		return nil, bosherror.Errorf("Platform %s could not be found", name)
	}
	return plat, nil
}
<commit_msg>Increase disk resolver timeout<commit_after>package platform

import (
	"time"

	"github.com/cloudfoundry/bosh-agent/infrastructure/devicepathresolver"
	boshcdrom "github.com/cloudfoundry/bosh-agent/platform/cdrom"
	boshcert "github.com/cloudfoundry/bosh-agent/platform/cert"
	boshdisk "github.com/cloudfoundry/bosh-agent/platform/disk"
	boshnet "github.com/cloudfoundry/bosh-agent/platform/net"
	bosharp "github.com/cloudfoundry/bosh-agent/platform/net/arp"
	boship "github.com/cloudfoundry/bosh-agent/platform/net/ip"
	boshstats "github.com/cloudfoundry/bosh-agent/platform/stats"
	boshudev "github.com/cloudfoundry/bosh-agent/platform/udevdevice"
	boshvitals "github.com/cloudfoundry/bosh-agent/platform/vitals"
	boshdirs "github.com/cloudfoundry/bosh-agent/settings/directories"
	bosherror "github.com/cloudfoundry/bosh-utils/errors"
	boshcmd "github.com/cloudfoundry/bosh-utils/fileutil"
	boshlog "github.com/cloudfoundry/bosh-utils/logger"
	boshretry "github.com/cloudfoundry/bosh-utils/retrystrategy"
	boshsys "github.com/cloudfoundry/bosh-utils/system"

	"github.com/pivotal-golang/clock"
)

const (
	ArpIterations          = 20
	ArpIterationDelay      = 5 * time.Second
	ArpInterfaceCheckDelay = 100 * time.Millisecond
)

const (
	SigarStatsCollectionInterval = 10 * time.Second
)

type Provider interface {
	Get(name string) (Platform, error)
}

type provider struct {
	platforms map[string]Platform
}

type Options struct {
	Linux LinuxOptions
}

func NewProvider(logger boshlog.Logger, dirProvider boshdirs.Provider, statsCollector boshstats.Collector, scriptCommandFactory boshsys.ScriptCommandFactory, fs boshsys.FileSystem, options Options, bootstrapState *BootstrapState, clock clock.Clock) Provider {
	runner := boshsys.NewExecCmdRunner(logger)
	linuxDiskManager := boshdisk.NewLinuxDiskManager(logger, runner, fs, options.Linux.BindMountPersistentDisk)

	udev := boshudev.NewConcreteUdevDevice(runner, logger)
	linuxCdrom := boshcdrom.NewLinuxCdrom("/dev/sr0", udev, runner)
	linuxCdutil := boshcdrom.NewCdUtil(dirProvider.SettingsDir(), fs, linuxCdrom, logger)

	compressor := boshcmd.NewTarballCompressor(runner, fs)
	copier := boshcmd.NewCpCopier(runner, fs, logger)

	// Kick of stats collection as soon as possible
	statsCollector.StartCollecting(SigarStatsCollectionInterval, nil)

	vitalsService := boshvitals.NewService(statsCollector, dirProvider)

	ipResolver := boship.NewResolver(boship.NetworkInterfaceToAddrsFunc)

	arping := bosharp.NewArping(runner, fs, logger, ArpIterations, ArpIterationDelay, ArpInterfaceCheckDelay)
	interfaceConfigurationCreator := boshnet.NewInterfaceConfigurationCreator(logger)

	interfaceAddressesProvider := boship.NewSystemInterfaceAddressesProvider()
	interfaceAddressesValidator := boship.NewInterfaceAddressesValidator(interfaceAddressesProvider)
	dnsValidator := boshnet.NewDNSValidator(fs)

	centosNetManager := boshnet.NewCentosNetManager(fs, runner, ipResolver, interfaceConfigurationCreator, interfaceAddressesValidator, dnsValidator, arping, logger)
	ubuntuNetManager := boshnet.NewUbuntuNetManager(fs, runner, ipResolver, interfaceConfigurationCreator, interfaceAddressesValidator, dnsValidator, arping, logger)

	scriptRunner := boshsys.NewConcreteScriptRunner(scriptCommandFactory, runner, fs, logger)
	windowsNetManager := boshnet.NewWindowsNetManager(scriptRunner, logger, clock)

	centosCertManager := boshcert.NewCentOSCertManager(fs, runner, 0, logger)
	ubuntuCertManager := boshcert.NewUbuntuCertManager(fs, runner, 60, logger)

	routesSearcher := boshnet.NewCmdRoutesSearcher(runner)
	linuxDefaultNetworkResolver := boshnet.NewDefaultNetworkResolver(routesSearcher, ipResolver)

	monitRetryable := NewMonitRetryable(runner)
	monitRetryStrategy := boshretry.NewAttemptRetryStrategy(10, 1*time.Second, monitRetryable, logger)

	var devicePathResolver devicepathresolver.DevicePathResolver
	switch options.Linux.DevicePathResolutionType {
	case "virtio":
		udev := boshudev.NewConcreteUdevDevice(runner, logger)
		idDevicePathResolver := devicepathresolver.NewIDDevicePathResolver(500*time.Millisecond, options.Linux.VirtioDevicePrefix, udev, fs)
		mappedDevicePathResolver := devicepathresolver.NewMappedDevicePathResolver(30000*time.Millisecond, fs)
		devicePathResolver = devicepathresolver.NewVirtioDevicePathResolver(idDevicePathResolver, mappedDevicePathResolver, logger)
	case "scsi":
		scsiIDPathResolver := devicepathresolver.NewSCSIIDDevicePathResolver(50000*time.Millisecond, fs, logger)
		scsiVolumeIDPathResolver := devicepathresolver.NewSCSIVolumeIDDevicePathResolver(500*time.Millisecond, fs)
		scsiLunPathResolver := devicepathresolver.NewSCSILunDevicePathResolver(50000*time.Millisecond, fs, logger)
		devicePathResolver = devicepathresolver.NewScsiDevicePathResolver(scsiVolumeIDPathResolver, scsiIDPathResolver, scsiLunPathResolver)
	default:
		devicePathResolver = devicepathresolver.NewIdentityDevicePathResolver()
	}

	centos := NewLinuxPlatform(
		fs,
		runner,
		statsCollector,
		compressor,
		copier,
		dirProvider,
		vitalsService,
		linuxCdutil,
		linuxDiskManager,
		centosNetManager,
		centosCertManager,
		monitRetryStrategy,
		devicePathResolver,
		500*time.Millisecond,
		bootstrapState,
		options.Linux,
		logger,
		linuxDefaultNetworkResolver,
	)

	ubuntu := NewLinuxPlatform(
		fs,
		runner,
		statsCollector,
		compressor,
		copier,
		dirProvider,
		vitalsService,
		linuxCdutil,
		linuxDiskManager,
		ubuntuNetManager,
		ubuntuCertManager,
		monitRetryStrategy,
		devicePathResolver,
		500*time.Millisecond,
		bootstrapState,
		options.Linux,
		logger,
		linuxDefaultNetworkResolver,
	)

	return provider{
		platforms: map[string]Platform{
			"ubuntu":  ubuntu,
			"centos":  centos,
			"dummy":   NewDummyPlatform(statsCollector, fs, runner, dirProvider, devicePathResolver, logger),
			"windows": NewWindowsPlatform(statsCollector, fs, runner, dirProvider, windowsNetManager, devicePathResolver, logger),
		},
	}
}

func (p provider) Get(name string) (Platform, error) {
	plat, found := p.platforms[name]
	if !found {
		return nil, bosherror.Errorf("Platform %s could not be found", name)
	}
	return plat, nil
}
<|endoftext|>


<commit_before>package the_platinum_searcher

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"runtime"

	"github.com/monochromegane/conflag"
	"github.com/monochromegane/go-home"
	"github.com/monochromegane/terminal"
)

const version = "2.1.4"

const (
	ExitCodeOK = iota
	ExitCodeError
)

var opts Option

type PlatinumSearcher struct {
	Out, Err io.Writer
}

func (p PlatinumSearcher) Run(args []string) int {

	parser := newOptionParser(&opts)

	conflag.LongHyphen = true
	conflag.BoolValue = false
	for _, c := range []string{
		filepath.Join(os.Getenv("XDG_CONFIG_HOME"), "pt", "config.toml"),
		filepath.Join(home.Dir(), ".ptconfig.toml"),
		".ptconfig.toml",
	} {
		if args, err := conflag.ArgsFrom(c); err == nil {
			parser.ParseArgs(args)
		}
	}

	args, err := parser.ParseArgs(args)
	if err != nil {
		return ExitCodeError
	}

	if opts.Version {
		fmt.Printf("pt version %s\n", version)
		return ExitCodeOK
	}

	if len(args) == 0 && !opts.SearchOption.EnableFilesWithRegexp {
		parser.WriteHelp(p.Err)
		return ExitCodeError
	}

	if !terminal.IsTerminal(os.Stdout) {
		if !opts.OutputOption.ForceColor {
			opts.OutputOption.EnableColor = false
		}
		if !opts.OutputOption.ForceGroup {
			opts.OutputOption.EnableGroup = false
		}
	}

	if p.givenStdin() && p.noRootPathIn(args) {
		opts.SearchOption.SearchStream = true
	}

	if opts.SearchOption.EnableFilesWithRegexp {
		args = append([]string{""}, args...)
	}

	if opts.OutputOption.Count {
		opts.OutputOption.Before = 0
		opts.OutputOption.After = 0
		opts.OutputOption.Context = 0
	}

	search := search{
		roots: p.rootsFrom(args),
		out:   p.Out,
	}
	if err = search.start(p.patternFrom(args)); err != nil {
		fmt.Fprintf(p.Err, "%s\n", err)
		return ExitCodeError
	}
	return ExitCodeOK
}

func (p PlatinumSearcher) patternFrom(args []string) string {
	return args[0]
}

func (p PlatinumSearcher) rootsFrom(args []string) []string {
	if len(args) > 1 {
		return args[1:]
	} else {
		return []string{"."}
	}
}

func (p PlatinumSearcher) givenStdin() bool {
	fi, err := os.Stdin.Stat()
	if runtime.GOOS == "windows" {
		if err == nil {
			return true
		}
	} else {
		if err != nil {
			return false
		}

		mode := fi.Mode()
		if (mode&os.ModeNamedPipe != 0) || mode.IsRegular() {
			return true
		}
	}
	return false
}

func (p PlatinumSearcher) noRootPathIn(args []string) bool {
	return len(args) == 1
}
<commit_msg>Fix XDG spec implementation<commit_after>package the_platinum_searcher

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"runtime"

	"github.com/monochromegane/conflag"
	"github.com/monochromegane/go-home"
	"github.com/monochromegane/terminal"
)

const version = "2.1.4"

const (
	ExitCodeOK = iota
	ExitCodeError
)

var opts Option

type PlatinumSearcher struct {
	Out, Err io.Writer
}

func (p PlatinumSearcher) Run(args []string) int {

	parser := newOptionParser(&opts)

	conflag.LongHyphen = true
	conflag.BoolValue = false
	for _, c := range []string{
		filepath.Join(xdgConfigHomeDir(), "pt", "config.toml"),
		filepath.Join(home.Dir(), ".ptconfig.toml"),
		".ptconfig.toml",
	} {
		if args, err := conflag.ArgsFrom(c); err == nil {
			parser.ParseArgs(args)
		}
	}

	args, err := parser.ParseArgs(args)
	if err != nil {
		return ExitCodeError
	}

	if opts.Version {
		fmt.Printf("pt version %s\n", version)
		return ExitCodeOK
	}

	if len(args) == 0 && !opts.SearchOption.EnableFilesWithRegexp {
		parser.WriteHelp(p.Err)
		return ExitCodeError
	}

	if !terminal.IsTerminal(os.Stdout) {
		if !opts.OutputOption.ForceColor {
			opts.OutputOption.EnableColor = false
		}
		if !opts.OutputOption.ForceGroup {
			opts.OutputOption.EnableGroup = false
		}
	}

	if p.givenStdin() && p.noRootPathIn(args) {
		opts.SearchOption.SearchStream = true
	}

	if opts.SearchOption.EnableFilesWithRegexp {
		args = append([]string{""}, args...)
	}

	if opts.OutputOption.Count {
		opts.OutputOption.Before = 0
		opts.OutputOption.After = 0
		opts.OutputOption.Context = 0
	}

	search := search{
		roots: p.rootsFrom(args),
		out:   p.Out,
	}
	if err = search.start(p.patternFrom(args)); err != nil {
		fmt.Fprintf(p.Err, "%s\n", err)
		return ExitCodeError
	}
	return ExitCodeOK
}

func (p PlatinumSearcher) patternFrom(args []string) string {
	return args[0]
}

func (p PlatinumSearcher) rootsFrom(args []string) []string {
	if len(args) > 1 {
		return args[1:]
	} else {
		return []string{"."}
	}
}

func (p PlatinumSearcher) givenStdin() bool {
	fi, err := os.Stdin.Stat()
	if runtime.GOOS == "windows" {
		if err == nil {
			return true
		}
	} else {
		if err != nil {
			return false
		}

		mode := fi.Mode()
		if (mode&os.ModeNamedPipe != 0) || mode.IsRegular() {
			return true
		}
	}
	return false
}

func (p PlatinumSearcher) noRootPathIn(args []string) bool {
	return len(args) == 1
}

func xdgConfigHomeDir() string {
	xdgConfigHome := os.Getenv("XDG_CONFIG_HOME")
	if xdgConfigHome == "" {
		xdgConfigHome = filepath.Join(home.Dir(), ".config")
	}
	return xdgConfigHome
}
<|endoftext|>


<commit_before>// Copyright © 2016 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package mocks

import (
	"fmt"
	"reflect"
	"testing"

	. "github.com/TheThingsNetwork/ttn/core"
	"github.com/TheThingsNetwork/ttn/utils/pointer"
	. "github.com/TheThingsNetwork/ttn/utils/testing"
	"github.com/brocaar/lorawan"
)

// MockRecipient implements the core.Recipient interface
//
// It declares a `Failures` attributes that can be used to
// simulate failures on demand, associating the name of the method
// which needs to fail with the actual failure.
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockRecipient struct {
	Failures          map[string]error
	InUnmarshalBinary []byte // Data received by UnmarshalBinary()
	OutMarshalBinary  []byte // Data spit out by MarshalBinary()
}

// NewMockRecipient constructs a new mock recipient.
func NewMockRecipient() *MockRecipient {
	return &MockRecipient{
		OutMarshalBinary: []byte("MockRecipientData"),
		Failures:         make(map[string]error),
	}
}

func (r *MockRecipient) MarshalBinary() ([]byte, error) {
	if r.Failures["MarshalBinary"] != nil {
		return nil, r.Failures["MarshalBinary"]
	}
	return r.OutMarshalBinary, nil
}

func (r *MockRecipient) UnmarshalBinary(data []byte) error {
	r.InUnmarshalBinary = data
	if r.Failures["UnmarshalBinary"] != nil {
		return r.Failures["UnmarshalBinary"]
	}
	return nil
}

type MockJSONRecipient struct {
	*MockRecipient
	InUnmarshalJSON []byte
	OutMarshalJSON  []byte
}

func NewMockJSONRecipient() *MockJSONRecipient {
	return &MockJSONRecipient{
		MockRecipient:  NewMockRecipient(),
		OutMarshalJSON: []byte(`{"out":"MockJSONRecipientData"}`),
	}
}

func (r *MockJSONRecipient) MarshalJSON() ([]byte, error) {
	if r.Failures["MarshalJSON"] != nil {
		return nil, r.Failures["MarshalJSON"]
	}
	return r.OutMarshalJSON, nil
}

func (r *MockJSONRecipient) UnmarshalJSON(data []byte) error {
	r.InUnmarshalJSON = data
	if r.Failures["UnmarshalJSON"] != nil {
		return r.Failures["UnmarshalJSON"]
	}
	return nil
}

// MockRegistration implements the core.Registration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockRegistration struct {
	OutRecipient Recipient
}

func NewMockRegistration() MockRegistration {
	return MockRegistration{
		OutRecipient: NewMockRecipient(),
	}
}

func (r MockRegistration) RawRecipient() []byte {
	data, _ := r.Recipient().MarshalBinary()
	return data
}

func (r MockRegistration) Recipient() Recipient {
	return r.OutRecipient
}

// MockARegistration implements the core.ARegistration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockARegistration struct {
	MockRegistration
	OutAppEUI lorawan.EUI64
}

func NewMockARegistration() MockARegistration {
	return MockARegistration{
		MockRegistration: NewMockRegistration(),
		OutAppEUI:        lorawan.EUI64([8]byte{9, 0, 9, 2, 2, 2, 3, 4}),
	}
}

func (r MockARegistration) AppEUI() lorawan.EUI64 {
	return r.OutAppEUI
}

// MockRRegistration implements the core.RRegistration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockRRegistration struct {
	MockRegistration
	OutDevEUI lorawan.EUI64
}

func NewMockRRegistration() MockRRegistration {
	return MockRRegistration{
		MockRegistration: NewMockRegistration(),
		OutDevEUI:        lorawan.EUI64([8]byte{2, 2, 2, 2, 2, 2, 2, 2}),
	}
}

func (r MockRRegistration) DevEUI() lorawan.EUI64 {
	return r.OutDevEUI
}

// MockBRegistration implements the core.BRegistration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockBRegistration struct {
	MockRRegistration
	OutAppEUI  lorawan.EUI64
	OutNwkSKey lorawan.AES128Key
}

func NewMockBRegistration() MockBRegistration {
	return MockBRegistration{
		MockRRegistration: NewMockRRegistration(),
		OutAppEUI:         lorawan.EUI64([8]byte{1, 1, 1, 1, 1, 1, 1, 1}),
		OutNwkSKey:        lorawan.AES128Key([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}),
	}
}

func (r MockBRegistration) AppEUI() lorawan.EUI64 {
	return r.OutAppEUI
}

func (r MockBRegistration) NwkSKey() lorawan.AES128Key {
	return r.OutNwkSKey
}

// MockHRegistration implements the core.HRegistration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockHRegistration struct {
	MockBRegistration
	OutAppSKey lorawan.AES128Key
}

func NewMockHRegistration() MockHRegistration {
	return MockHRegistration{
		MockBRegistration: NewMockBRegistration(),
		OutAppSKey:        lorawan.AES128Key([16]byte{6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1}),
	}
}

func (r MockHRegistration) AppSKey() lorawan.AES128Key {
	return r.OutAppSKey
}

// MockAckNacker implements the core.AckNacker interface
//
// It declares a `Failures` attributes that can be used to
// simulate failures on demand, associating the name of the method
// which needs to fail with the actual failure.
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockAckNacker struct {
	InAck struct {
		Ack    *bool
		Packet Packet
	}
}

func NewMockAckNacker() *MockAckNacker {
	return &MockAckNacker{}
}

func (an *MockAckNacker) Ack(p Packet) error {
	an.InAck = struct {
		Ack    *bool
		Packet Packet
	}{
		Ack:    pointer.Bool(true),
		Packet: p,
	}
	return nil
}

func (an *MockAckNacker) Nack() error {
	an.InAck = struct {
		Ack    *bool
		Packet Packet
	}{
		Ack:    pointer.Bool(false),
		Packet: nil,
	}
	return nil
}

// MockAdapter implements the core.Adapter interface
//
// It declares a `Failures` attributes that can be used to
// simulate failures on demand, associating the name of the method
// which needs to fail with the actual failure.
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockAdapter struct {
	Failures            map[string]error
	InSendPacket        Packet
	InSendRecipients    []Recipient
	InGetRecipient      []byte
	OutSend             []byte
	OutGetRecipient     Recipient
	OutNextPacket       []byte
	OutNextAckNacker    AckNacker
	OutNextRegReg       Registration
	OutNextRegAckNacker AckNacker
}

func NewMockAdapter() *MockAdapter {
	return &MockAdapter{
		Failures:            make(map[string]error),
		OutSend:             []byte("MockAdapterSend"),
		OutGetRecipient:     NewMockRecipient(),
		OutNextPacket:       []byte("MockAdapterNextPacket"),
		OutNextAckNacker:    NewMockAckNacker(),
		OutNextRegReg:       NewMockHRegistration(),
		OutNextRegAckNacker: NewMockAckNacker(),
	}
}

func (a *MockAdapter) Send(p Packet, r ...Recipient) ([]byte, error) {
	a.InSendPacket = p
	a.InSendRecipients = r
	if a.Failures["Send"] != nil {
		return nil, a.Failures["Send"]
	}
	return a.OutSend, nil
}

func (a *MockAdapter) GetRecipient(raw []byte) (Recipient, error) {
	a.InGetRecipient = raw
	if a.Failures["GetRecipient"] != nil {
		return nil, a.Failures["GetRecipient"]
	}
	return a.OutGetRecipient, nil
}

func (a *MockAdapter) Next() ([]byte, AckNacker, error) {
	if a.Failures["Next"] != nil {
		return nil, nil, a.Failures["Next"]
	}
	return a.OutNextPacket, a.OutNextAckNacker, nil
}

func (a *MockAdapter) NextRegistration() (Registration, AckNacker, error) {
	if a.Failures["NextRegistration"] != nil {
		return nil, nil, a.Failures["NextRegistration"]
	}
	return a.OutNextRegReg, a.OutNextRegAckNacker, nil
}

// MockSubscriber implements the core.Subscriber interface
//
// It declares a `Failures` attributes that can be used to
// simulate failures on demand, associating the name of the method
// which needs to fail with the actual failure.
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockSubscriber struct {
	Failures                map[string]error
	InSubscribeRegistration Registration
}

func NewMockSubscriber() *MockSubscriber {
	return &MockSubscriber{
		Failures: make(map[string]error),
	}
}

func (s *MockSubscriber) Subscribe(reg Registration) error {
	s.InSubscribeRegistration = reg
	return s.Failures["Subscribe"]
}

// ----- CHECK utilities

func Check(t *testing.T, want, got interface{}, name string) {
	if !reflect.DeepEqual(want, got) {
		Ko(t, "%s don't match expectations.\nWant: %+v\nGot:  %+v", name, want, got)
	}
	Ok(t, fmt.Sprintf("Check %s", name))
}

func CheckAcks(t *testing.T, want interface{}, gotItf interface{}) {
	got := gotItf.(struct {
		Ack    *bool
		Packet Packet
	})

	if got.Ack == nil {
		Ko(t, "Invalid ack got: %+v", got)
	}

	switch want.(type) {
	case bool:
		Check(t, want.(bool), *(got.Ack), "Acks")
	case Packet:
		Check(t, want.(Packet), got.Packet, "Acks")
	default:
		panic("Unexpect ack wanted")
	}
}

func CheckRecipients(t *testing.T, want []Recipient, got []Recipient) {
	Check(t, want, got, "Recipients")
}

func CheckSent(t *testing.T, want Packet, got Packet) {
	Check(t, want, got, "Sent")
}
<commit_msg>[test/http-adapter] Introduce a mock packet type<commit_after>// Copyright © 2016 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package mocks

import (
	"fmt"
	"reflect"
	"testing"

	. "github.com/TheThingsNetwork/ttn/core"
	"github.com/TheThingsNetwork/ttn/utils/pointer"
	. "github.com/TheThingsNetwork/ttn/utils/testing"
	"github.com/brocaar/lorawan"
)

// MockRecipient implements the core.Recipient interface
//
// It declares a `Failures` attributes that can be used to
// simulate failures on demand, associating the name of the method
// which needs to fail with the actual failure.
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockRecipient struct {
	Failures          map[string]error
	InUnmarshalBinary []byte // Data received by UnmarshalBinary()
	OutMarshalBinary  []byte // Data spit out by MarshalBinary()
}

// NewMockRecipient constructs a new mock recipient.
func NewMockRecipient() *MockRecipient {
	return &MockRecipient{
		OutMarshalBinary: []byte("MockRecipientData"),
		Failures:         make(map[string]error),
	}
}

func (r *MockRecipient) MarshalBinary() ([]byte, error) {
	if r.Failures["MarshalBinary"] != nil {
		return nil, r.Failures["MarshalBinary"]
	}
	return r.OutMarshalBinary, nil
}

func (r *MockRecipient) UnmarshalBinary(data []byte) error {
	r.InUnmarshalBinary = data
	if r.Failures["UnmarshalBinary"] != nil {
		return r.Failures["UnmarshalBinary"]
	}
	return nil
}

type MockJSONRecipient struct {
	*MockRecipient
	InUnmarshalJSON []byte
	OutMarshalJSON  []byte
}

func NewMockJSONRecipient() *MockJSONRecipient {
	return &MockJSONRecipient{
		MockRecipient:  NewMockRecipient(),
		OutMarshalJSON: []byte(`{"out":"MockJSONRecipientData"}`),
	}
}

func (r *MockJSONRecipient) MarshalJSON() ([]byte, error) {
	if r.Failures["MarshalJSON"] != nil {
		return nil, r.Failures["MarshalJSON"]
	}
	return r.OutMarshalJSON, nil
}

func (r *MockJSONRecipient) UnmarshalJSON(data []byte) error {
	r.InUnmarshalJSON = data
	if r.Failures["UnmarshalJSON"] != nil {
		return r.Failures["UnmarshalJSON"]
	}
	return nil
}

// MockRegistration implements the core.Registration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockRegistration struct {
	OutRecipient Recipient
}

func NewMockRegistration() MockRegistration {
	return MockRegistration{
		OutRecipient: NewMockRecipient(),
	}
}

func (r MockRegistration) RawRecipient() []byte {
	data, _ := r.Recipient().MarshalBinary()
	return data
}

func (r MockRegistration) Recipient() Recipient {
	return r.OutRecipient
}

// MockARegistration implements the core.ARegistration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockARegistration struct {
	MockRegistration
	OutAppEUI lorawan.EUI64
}

func NewMockARegistration() MockARegistration {
	return MockARegistration{
		MockRegistration: NewMockRegistration(),
		OutAppEUI:        lorawan.EUI64([8]byte{9, 0, 9, 2, 2, 2, 3, 4}),
	}
}

func (r MockARegistration) AppEUI() lorawan.EUI64 {
	return r.OutAppEUI
}

// MockRRegistration implements the core.RRegistration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockRRegistration struct {
	MockRegistration
	OutDevEUI lorawan.EUI64
}

func NewMockRRegistration() MockRRegistration {
	return MockRRegistration{
		MockRegistration: NewMockRegistration(),
		OutDevEUI:        lorawan.EUI64([8]byte{2, 2, 2, 2, 2, 2, 2, 2}),
	}
}

func (r MockRRegistration) DevEUI() lorawan.EUI64 {
	return r.OutDevEUI
}

// MockBRegistration implements the core.BRegistration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockBRegistration struct {
	MockRRegistration
	OutAppEUI  lorawan.EUI64
	OutNwkSKey lorawan.AES128Key
}

func NewMockBRegistration() MockBRegistration {
	return MockBRegistration{
		MockRRegistration: NewMockRRegistration(),
		OutAppEUI:         lorawan.EUI64([8]byte{1, 1, 1, 1, 1, 1, 1, 1}),
		OutNwkSKey:        lorawan.AES128Key([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}),
	}
}

func (r MockBRegistration) AppEUI() lorawan.EUI64 {
	return r.OutAppEUI
}

func (r MockBRegistration) NwkSKey() lorawan.AES128Key {
	return r.OutNwkSKey
}

// MockHRegistration implements the core.HRegistration interface
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockHRegistration struct {
	MockBRegistration
	OutAppSKey lorawan.AES128Key
}

func NewMockHRegistration() MockHRegistration {
	return MockHRegistration{
		MockBRegistration: NewMockBRegistration(),
		OutAppSKey:        lorawan.AES128Key([16]byte{6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1}),
	}
}

func (r MockHRegistration) AppSKey() lorawan.AES128Key {
	return r.OutAppSKey
}

// MockAckNacker implements the core.AckNacker interface
//
// It declares a `Failures` attributes that can be used to
// simulate failures on demand, associating the name of the method
// which needs to fail with the actual failure.
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockAckNacker struct {
	InAck struct {
		Ack    *bool
		Packet Packet
	}
}

func NewMockAckNacker() *MockAckNacker {
	return &MockAckNacker{}
}

func (an *MockAckNacker) Ack(p Packet) error {
	an.InAck = struct {
		Ack    *bool
		Packet Packet
	}{
		Ack:    pointer.Bool(true),
		Packet: p,
	}
	return nil
}

func (an *MockAckNacker) Nack() error {
	an.InAck = struct {
		Ack    *bool
		Packet Packet
	}{
		Ack:    pointer.Bool(false),
		Packet: nil,
	}
	return nil
}

// MockAdapter implements the core.Adapter interface
//
// It declares a `Failures` attributes that can be used to
// simulate failures on demand, associating the name of the method
// which needs to fail with the actual failure.
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockAdapter struct {
	Failures            map[string]error
	InSendPacket        Packet
	InSendRecipients    []Recipient
	InGetRecipient      []byte
	OutSend             []byte
	OutGetRecipient     Recipient
	OutNextPacket       []byte
	OutNextAckNacker    AckNacker
	OutNextRegReg       Registration
	OutNextRegAckNacker AckNacker
}

func NewMockAdapter() *MockAdapter {
	return &MockAdapter{
		Failures:            make(map[string]error),
		OutSend:             []byte("MockAdapterSend"),
		OutGetRecipient:     NewMockRecipient(),
		OutNextPacket:       []byte("MockAdapterNextPacket"),
		OutNextAckNacker:    NewMockAckNacker(),
		OutNextRegReg:       NewMockHRegistration(),
		OutNextRegAckNacker: NewMockAckNacker(),
	}
}

func (a *MockAdapter) Send(p Packet, r ...Recipient) ([]byte, error) {
	a.InSendPacket = p
	a.InSendRecipients = r
	if a.Failures["Send"] != nil {
		return nil, a.Failures["Send"]
	}
	return a.OutSend, nil
}

func (a *MockAdapter) GetRecipient(raw []byte) (Recipient, error) {
	a.InGetRecipient = raw
	if a.Failures["GetRecipient"] != nil {
		return nil, a.Failures["GetRecipient"]
	}
	return a.OutGetRecipient, nil
}

func (a *MockAdapter) Next() ([]byte, AckNacker, error) {
	if a.Failures["Next"] != nil {
		return nil, nil, a.Failures["Next"]
	}
	return a.OutNextPacket, a.OutNextAckNacker, nil
}

func (a *MockAdapter) NextRegistration() (Registration, AckNacker, error) {
	if a.Failures["NextRegistration"] != nil {
		return nil, nil, a.Failures["NextRegistration"]
	}
	return a.OutNextRegReg, a.OutNextRegAckNacker, nil
}

// MockSubscriber implements the core.Subscriber interface
//
// It declares a `Failures` attributes that can be used to
// simulate failures on demand, associating the name of the method
// which needs to fail with the actual failure.
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockSubscriber struct {
	Failures                map[string]error
	InSubscribeRegistration Registration
}

func NewMockSubscriber() *MockSubscriber {
	return &MockSubscriber{
		Failures: make(map[string]error),
	}
}

func (s *MockSubscriber) Subscribe(reg Registration) error {
	s.InSubscribeRegistration = reg
	return s.Failures["Subscribe"]
}

// MockPacket implements the core.Packet interface
//
// It declares a `Failures` attributes that can be used to
// simulate failures on demand, associating the name of the method
// which needs to fail with the actual failure.
//
// It also stores the last arguments of each function call in appropriated
// attributes. Because there's no computation going on, the expected / wanted
// responses should also be defined. Default values are provided but can be changed
// if needed.
type MockPacket struct {
	Failures         map[string]error
	OutMarshalBinary []byte
	OutString        string
	OutDevEUI        lorawan.EUI64
}

func NewMockPacket() *MockPacket {
	return &MockPacket{
		Failures:         make(map[string]error),
		OutMarshalBinary: []byte("MockPacketBinary"),
		OutString:        "MockPacket",
		OutDevEUI:        lorawan.EUI64([8]byte{1, 2, 1, 2, 4, 4, 5, 5}),
	}
}

func (p *MockPacket) DevEUI() lorawan.EUI64 {
	return p.OutDevEUI
}

func (p *MockPacket) MarshalBinary() ([]byte, error) {
	if p.Failures["MarshalBinary"] != nil {
		return nil, p.Failures["MarshalBinary"]
	}
	return p.OutMarshalBinary, nil
}

func (p *MockPacket) String() string {
	return p.OutString
}

// ----- CHECK utilities

func Check(t *testing.T, want, got interface{}, name string) {
	if !reflect.DeepEqual(want, got) {
		Ko(t, "%s don't match expectations.\nWant: %+v\nGot:  %+v", name, want, got)
	}
	Ok(t, fmt.Sprintf("Check %s", name))
}

func CheckAcks(t *testing.T, want interface{}, gotItf interface{}) {
	got := gotItf.(struct {
		Ack    *bool
		Packet Packet
	})

	if got.Ack == nil {
		Ko(t, "Invalid ack got: %+v", got)
	}

	switch want.(type) {
	case bool:
		Check(t, want.(bool), *(got.Ack), "Acks")
	case Packet:
		Check(t, want.(Packet), got.Packet, "Acks")
	default:
		panic("Unexpect ack wanted")
	}
}

func CheckRecipients(t *testing.T, want []Recipient, got []Recipient) {
	Check(t, want, got, "Recipients")
}

func CheckSent(t *testing.T, want Packet, got Packet) {
	Check(t, want, got, "Sent")
}
<|endoftext|>


<commit_before>// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"encoding/json"
	"strings"

	"fmt"

	"errors"

	"github.com/gorilla/websocket"
)

type onForwardDataReceived func(addr string, header map[string]string, data []byte)

// RequestMsg is a struct containing information
// to forward to client
type RequestMsg struct {
	// The websocket connection.
	conn *websocket.Conn
	msg  []byte
}

// Hub maintains the set of active clients and broadcasts messages to the
// clients.
type Hub struct {
	// Registered clients.
	clients map[string]*Client

	// Inbound messages from the clients.
	request chan *RequestMsg

	// Register requests from the clients.
	register chan *Client

	// Unregister requests from clients.
	unregister chan *Client
}

func newHub() *Hub {
	return &Hub{
		request:    make(chan *RequestMsg),
		register:   make(chan *Client),
		unregister: make(chan *Client),
		clients:    make(map[string]*Client),
	}
}

func (h *Hub) sendMessageToClient(sendToIP string, message []byte) error {

	if client, ok := h.clients[sendToIP]; ok {
		fmt.Print("Sending data to client")
		client.send <- message
	} else {
		fmt.Println("\nError: client not connected")
		return errors.New("forward: " + sendToIP + " not connected")
	}

	return nil
}

func (h *Hub) run(cb onForwardDataReceived) {
	for {
		select {
		case client := <-h.register:
			clientIP := strings.Split(client.conn.RemoteAddr().String(), ":")[0]
			h.clients[clientIP] = client
		case client := <-h.unregister:
			clientIP := strings.Split(client.conn.RemoteAddr().String(), ":")[0]
			if _, ok := h.clients[clientIP]; ok {
				delete(h.clients, clientIP)
				close(client.send)
			}
		case req := <-h.request:
			header, data, err := parseRequest(req.msg)
			if err == nil {
				fromAddr := strings.Split(req.conn.RemoteAddr().String(), ":")[0]
				cb(fromAddr, header, data)
			}
		}
	}
}

func parseRequest(data []byte) (map[string]string, []byte, error) {

	headerLen := 0
	// find closing brace of header
	for i := 0; i < len(data); i++ {
		if string(data[i]) == "}" {
			headerLen = i + 1
			break
		}

		if i > 64 {
			return nil, nil, errors.New("bad request: header too large")
		}
	}

	header := map[string]string{}
	err := json.Unmarshal(data[:headerLen], &header)
	return header, data[headerLen:], err
}
<commit_msg>fixed nill pointer dereference<commit_after>// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"encoding/json"
	"strings"

	"fmt"

	"errors"

	"github.com/gorilla/websocket"
)

type onForwardDataReceived func(addr string, header map[string]string, data []byte)

// RequestMsg is a struct containing information
// to forward to client
type RequestMsg struct {
	// The websocket connection.
	conn *websocket.Conn
	msg  []byte
}

// Hub maintains the set of active clients and broadcasts messages to the
// clients.
type Hub struct {
	// Registered clients.
	clients map[string]*Client

	// Inbound messages from the clients.
	request chan *RequestMsg

	// Register requests from the clients.
	register chan *Client

	// Unregister requests from clients.
	unregister chan *Client
}

func newHub() *Hub {
	return &Hub{
		request:    make(chan *RequestMsg),
		register:   make(chan *Client),
		unregister: make(chan *Client),
		clients:    make(map[string]*Client),
	}
}

func (h *Hub) sendMessageToClient(sendToIP string, message []byte) error {

	if _, ok := h.clients[sendToIP]; ok {
		fmt.Print("Sending data to client")
		client := h.clients[sendToIP]
		client.send <- message
	} else {
		fmt.Println("\nError: client not connected")
		return errors.New("forward: " + sendToIP + " not connected")
	}

	return nil
}

func (h *Hub) run(cb onForwardDataReceived) {
	for {
		select {
		case client := <-h.register:
			clientIP := strings.Split(client.conn.RemoteAddr().String(), ":")[0]
			h.clients[clientIP] = client
		case client := <-h.unregister:
			clientIP := strings.Split(client.conn.RemoteAddr().String(), ":")[0]
			if _, ok := h.clients[clientIP]; ok {
				delete(h.clients, clientIP)
				close(client.send)
			}
		case req := <-h.request:
			header, data, err := parseRequest(req.msg)
			if err == nil {
				fromAddr := strings.Split(req.conn.RemoteAddr().String(), ":")[0]
				cb(fromAddr, header, data)
			}
		}
	}
}

func parseRequest(data []byte) (map[string]string, []byte, error) {

	headerLen := 0
	// find closing brace of header
	for i := 0; i < len(data); i++ {
		if string(data[i]) == "}" {
			headerLen = i + 1
			break
		}

		if i > 64 {
			return nil, nil, errors.New("bad request: header too large")
		}
	}

	header := map[string]string{}
	err := json.Unmarshal(data[:headerLen], &header)
	return header, data[headerLen:], err
}
<|endoftext|>


<commit_before>// Copyright 2016 Apcera Inc. All rights reserved.

package server

import (
	"github.com/nats-io/gnatsd/logger"
	natsd "github.com/nats-io/gnatsd/server"
	"os"
	"sync"
	"sync/atomic"
)

// Logging in STAN
//
// The STAN logger is an instance of a NATS logger, (basically duplicated
// from the NATS server code), and is passed into the NATS server.
//
// A note on Debugf and Tracef:  These will be enabled within the log if
// either STAN or the NATS server enables them.  However, STAN will only
// trace/debug if the local STAN debug/trace flags are set.  NATS will do
// the same with it's logger flags.  This enables us to use the same logger,
// but differentiate between STAN and NATS debug/trace.
//
// All logging functions are fully implemented (versus calling into the NATS
// server) in case STAN is decoupled from the NATS server.

// Package globals for performance checks
var trace int32
var debug int32
const LogPrefix = "STREAM: "

// The STAN logger, encapsulates a NATS logger
var stanLog = struct {
	sync.Mutex
	logger natsd.Logger
}{}

// ConfigureLogger configures logging for STAN and the embedded NATS server
// based on options passed.
func ConfigureLogger(stanOpts *Options, natsOpts *natsd.Options) {

	var s *natsd.Server
	var newLogger natsd.Logger

	sOpts := stanOpts
	nOpts := natsOpts

	if sOpts == nil {
		sOpts = GetDefaultOptions()
	}
	if nOpts == nil {
		nOpts = &natsd.Options{}
	}

	enableDebug := nOpts.Debug || sOpts.Debug
	enableTrace := nOpts.Trace || sOpts.Trace

	if nOpts.LogFile != "" {
		newLogger = logger.NewFileLogger(nOpts.LogFile, nOpts.Logtime, enableDebug, sOpts.Trace, true)
	} else if nOpts.RemoteSyslog != "" {
		newLogger = logger.NewRemoteSysLogger(nOpts.RemoteSyslog, sOpts.Debug, sOpts.Trace)
	} else if nOpts.Syslog {
		newLogger = logger.NewSysLogger(sOpts.Debug, sOpts.Trace)
	} else {
		colors := true
		// Check to see if stderr is being redirected and if so turn off color
		// Also turn off colors if we're running on Windows where os.Stderr.Stat() returns an invalid handle-error
		stat, err := os.Stderr.Stat()
		if err != nil || (stat.Mode()&os.ModeCharDevice) == 0 {
			colors = false
		}
		newLogger = logger.NewStdLogger(nOpts.Logtime, enableDebug, enableTrace, colors, true)
	}
	if sOpts.Debug {
		atomic.StoreInt32(&debug, 1)
	}
	if sOpts.Trace {
		atomic.StoreInt32(&trace, 1)
	}

	// The NATS server will use the STAN logger
	s.SetLogger(newLogger, nOpts.Debug, nOpts.Trace)

	stanLog.Lock()
	stanLog.logger = newLogger
	stanLog.Unlock()
}

// RemoveLogger clears the logger instance and debug/trace flags.
// Used for testing.
func RemoveLogger() {
	var s *natsd.Server

	atomic.StoreInt32(&trace, 0)
	atomic.StoreInt32(&debug, 0)

	stanLog.Lock()
	stanLog.logger = nil
	stanLog.Unlock()

	s.SetLogger(nil, false, false)
}

// Noticef logs a notice statement
func Noticef(format string, v ...interface{}) {
	executeLogCall(func(log natsd.Logger, format string, v ...interface{}) {
		log.Noticef(format, v...)
	}, format, v...)
}

// Errorf logs an error
func Errorf(format string, v ...interface{}) {
	executeLogCall(func(log natsd.Logger, format string, v ...interface{}) {
		log.Errorf(format, v...)
	}, format, v...)
}

// Fatalf logs a fatal error
func Fatalf(format string, v ...interface{}) {
	executeLogCall(func(log natsd.Logger, format string, v ...interface{}) {
		log.Fatalf(format, v...)
	}, format, v...)
}

// Debugf logs a debug statement
func Debugf(format string, v ...interface{}) {
	if atomic.LoadInt32(&debug) != 0 {
		executeLogCall(func(log natsd.Logger, format string, v ...interface{}) {
			log.Debugf(format, v...)
		}, format, v...)
	}
}

// Tracef logs a trace statement
func Tracef(format string, v ...interface{}) {
	if atomic.LoadInt32(&trace) != 0 {
		executeLogCall(func(logger natsd.Logger, format string, v ...interface{}) {
			logger.Tracef(format, v...)
		}, format, v...)
	}
}

func executeLogCall(f func(logger natsd.Logger, format string, v ...interface{}), format string, args ...interface{}) {
	stanLog.Lock()
	defer stanLog.Unlock()
	if stanLog.logger == nil {
		return
	}
	f(stanLog.logger, LogPrefix + format, args...)
}
<commit_msg>Added comment to LogPrefix [ci skip]<commit_after>// Copyright 2016 Apcera Inc. All rights reserved.

package server

import (
	"github.com/nats-io/gnatsd/logger"
	natsd "github.com/nats-io/gnatsd/server"
	"os"
	"sync"
	"sync/atomic"
)

// Logging in STAN
//
// The STAN logger is an instance of a NATS logger, (basically duplicated
// from the NATS server code), and is passed into the NATS server.
//
// A note on Debugf and Tracef:  These will be enabled within the log if
// either STAN or the NATS server enables them.  However, STAN will only
// trace/debug if the local STAN debug/trace flags are set.  NATS will do
// the same with it's logger flags.  This enables us to use the same logger,
// but differentiate between STAN and NATS debug/trace.
//
// All logging functions are fully implemented (versus calling into the NATS
// server) in case STAN is decoupled from the NATS server.

// Package globals for performance checks
var trace int32
var debug int32

// LogPrefix is prefixed to all NATS Streaming log messages
const LogPrefix = "STREAM: "

// The STAN logger, encapsulates a NATS logger
var stanLog = struct {
	sync.Mutex
	logger natsd.Logger
}{}

// ConfigureLogger configures logging for STAN and the embedded NATS server
// based on options passed.
func ConfigureLogger(stanOpts *Options, natsOpts *natsd.Options) {

	var s *natsd.Server
	var newLogger natsd.Logger

	sOpts := stanOpts
	nOpts := natsOpts

	if sOpts == nil {
		sOpts = GetDefaultOptions()
	}
	if nOpts == nil {
		nOpts = &natsd.Options{}
	}

	enableDebug := nOpts.Debug || sOpts.Debug
	enableTrace := nOpts.Trace || sOpts.Trace

	if nOpts.LogFile != "" {
		newLogger = logger.NewFileLogger(nOpts.LogFile, nOpts.Logtime, enableDebug, sOpts.Trace, true)
	} else if nOpts.RemoteSyslog != "" {
		newLogger = logger.NewRemoteSysLogger(nOpts.RemoteSyslog, sOpts.Debug, sOpts.Trace)
	} else if nOpts.Syslog {
		newLogger = logger.NewSysLogger(sOpts.Debug, sOpts.Trace)
	} else {
		colors := true
		// Check to see if stderr is being redirected and if so turn off color
		// Also turn off colors if we're running on Windows where os.Stderr.Stat() returns an invalid handle-error
		stat, err := os.Stderr.Stat()
		if err != nil || (stat.Mode()&os.ModeCharDevice) == 0 {
			colors = false
		}
		newLogger = logger.NewStdLogger(nOpts.Logtime, enableDebug, enableTrace, colors, true)
	}
	if sOpts.Debug {
		atomic.StoreInt32(&debug, 1)
	}
	if sOpts.Trace {
		atomic.StoreInt32(&trace, 1)
	}

	// The NATS server will use the STAN logger
	s.SetLogger(newLogger, nOpts.Debug, nOpts.Trace)

	stanLog.Lock()
	stanLog.logger = newLogger
	stanLog.Unlock()
}

// RemoveLogger clears the logger instance and debug/trace flags.
// Used for testing.
func RemoveLogger() {
	var s *natsd.Server

	atomic.StoreInt32(&trace, 0)
	atomic.StoreInt32(&debug, 0)

	stanLog.Lock()
	stanLog.logger = nil
	stanLog.Unlock()

	s.SetLogger(nil, false, false)
}

// Noticef logs a notice statement
func Noticef(format string, v ...interface{}) {
	executeLogCall(func(log natsd.Logger, format string, v ...interface{}) {
		log.Noticef(format, v...)
	}, format, v...)
}

// Errorf logs an error
func Errorf(format string, v ...interface{}) {
	executeLogCall(func(log natsd.Logger, format string, v ...interface{}) {
		log.Errorf(format, v...)
	}, format, v...)
}

// Fatalf logs a fatal error
func Fatalf(format string, v ...interface{}) {
	executeLogCall(func(log natsd.Logger, format string, v ...interface{}) {
		log.Fatalf(format, v...)
	}, format, v...)
}

// Debugf logs a debug statement
func Debugf(format string, v ...interface{}) {
	if atomic.LoadInt32(&debug) != 0 {
		executeLogCall(func(log natsd.Logger, format string, v ...interface{}) {
			log.Debugf(format, v...)
		}, format, v...)
	}
}

// Tracef logs a trace statement
func Tracef(format string, v ...interface{}) {
	if atomic.LoadInt32(&trace) != 0 {
		executeLogCall(func(logger natsd.Logger, format string, v ...interface{}) {
			logger.Tracef(format, v...)
		}, format, v...)
	}
}

func executeLogCall(f func(logger natsd.Logger, format string, v ...interface{}), format string, args ...interface{}) {
	stanLog.Lock()
	defer stanLog.Unlock()
	if stanLog.logger == nil {
		return
	}
	f(stanLog.logger, LogPrefix+format, args...)
}
<|endoftext|>


<commit_before>package core

import (
	"ark-go/arkcoin"
	"ark-go/arkcoin/base58"
	"bytes"
	"crypto/sha256"
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"log"
)

//Transaction struct - represents structure of ARK.io blockchain transaction
type Transaction struct {
	Timestamp          int32
	RecipientID        string
	Amount             int64
	Fee                int64
	Type               byte
	VendorField        string
	Signature          string
	SignSignature      string
	SenderPublicKey    string
	RequesterPublicKey string
	ID                 string
}

//ToBytes returns bytearray of the Transaction object to be signed and send to blockchain
func (tx *Transaction) toBytes(skipSignature, skipSecondSignature bool) []byte {
	txBuf := new(bytes.Buffer)
	binary.Write(txBuf, binary.LittleEndian, tx.Type)
	binary.Write(txBuf, binary.LittleEndian, uint32(tx.Timestamp))

	binary.Write(txBuf, binary.LittleEndian, quickHexDecode(tx.SenderPublicKey))

	if tx.RequesterPublicKey != "" {
		res, err := base58.Decode(tx.RequesterPublicKey)
		if err != nil {
			binary.Write(txBuf, binary.LittleEndian, res)
		}
	}

	if tx.RecipientID != "" {
		res, err := base58.Decode(tx.RecipientID)
		if err != nil {
			log.Fatal("Error converting Decoding b58 ", err.Error())
		}
		binary.Write(txBuf, binary.LittleEndian, res)
	} else {
		binary.Write(txBuf, binary.LittleEndian, make([]byte, 21))
	}

	if tx.VendorField != "" {
		vendorBytes := []byte(tx.VendorField)
		if len(vendorBytes) < 65 {
			binary.Write(txBuf, binary.LittleEndian, vendorBytes)

			bs := make([]byte, 64-len(vendorBytes))
			binary.Write(txBuf, binary.LittleEndian, bs)
		}
	} else {
		binary.Write(txBuf, binary.LittleEndian, make([]byte, 64))
	}

	binary.Write(txBuf, binary.LittleEndian, uint64(tx.Amount))
	binary.Write(txBuf, binary.LittleEndian, uint64(tx.Fee))

	switch tx.Type {
	case 1:
		binary.Write(txBuf, binary.LittleEndian, quickHexDecode(tx.Signature))
	case 2:
		//buffer.Put(Encoding.ASCII.GetBytes(asset["username"]));
	case 3:
		//votes
	}

	if !skipSignature && len(tx.Signature) > 0 {
		binary.Write(txBuf, binary.LittleEndian, quickHexDecode(tx.Signature))
	}

	if !skipSecondSignature && len(tx.SignSignature) > 0 {
		binary.Write(txBuf, binary.LittleEndian, quickHexDecode(tx.SignSignature))
	}

	return txBuf.Bytes()
}

//CreateTransaction creates and returns new Transaction struct...
func CreateTransaction(recipientID string, satoshiAmount int64, vendorField, passphrase, secondPassphrase string) *Transaction {
	tx := Transaction{Type: 0,
		RecipientID: recipientID,
		Amount:      satoshiAmount,
		Fee:         arkcoin.ArkCoinMain.Fees.Send,
		VendorField: vendorField}

	tx.Timestamp = 1 //Slot.GetTime();
	tx.sign(passphrase)

	if len(secondPassphrase) > 0 {
		tx.secondSign(secondPassphrase)
	}

	tx.getID() //calculates id of transaction
	return &tx
}

//Sign the Transaction
func (tx *Transaction) sign(passphrase string) {
	key := arkcoin.NewPrivateKeyFromPassword(passphrase, arkcoin.ArkCoinMain)

	tx.SenderPublicKey = hex.EncodeToString(key.PublicKey.Serialize())

	trHashBytes := sha256.New()
	trHashBytes.Write(tx.toBytes(true, true))

	sig, err := key.Sign(trHashBytes.Sum(nil))
	if err == nil {
		tx.Signature = hex.EncodeToString(sig)
	}
}

//SecondSign the Transaction
func (tx *Transaction) secondSign(passphrase string) {
	key := arkcoin.NewPrivateKeyFromPassword(passphrase, arkcoin.ArkCoinMain)

	trHashBytes := sha256.New()
	trHashBytes.Write(tx.toBytes(false, true))

	sig, err := key.Sign(trHashBytes.Sum(nil))
	if err == nil {
		tx.SignSignature = hex.EncodeToString(sig)
	}
}

//GetID returns calculated ID of trancation - hashed s256
func (tx *Transaction) getID() {
	trHashBytes := sha256.New()
	trHashBytes.Write(tx.toBytes(false, false))

	tx.ID = hex.EncodeToString(trHashBytes.Sum(nil))
}

//ToJSON converts transaction object to JSON string
func (tx *Transaction) ToJSON() string {
	txJSON, err := json.Marshal(tx)
	if err != nil {
		log.Fatal(err.Error())
	}
	return string(txJSON)
}

func quickHexDecode(data string) []byte {
	res, err := hex.DecodeString(data)
	if err != nil {
		log.Fatal(err.Error())
	}
	return res
}

//Verify function verifies if tx is validly signed
func (tx *Transaction) Verify() bool {
	return tx.verifyHelper(true)
}

//SecondVerify function verifies if tx is validly signed
func (tx *Transaction) SecondVerify() bool {
	return tx.verifyHelper(false)
}

func (tx *Transaction) verifyHelper(first bool) bool {
	key, err := arkcoin.NewPublicKey(quickHexDecode(tx.SenderPublicKey), arkcoin.ArkCoinMain)
	if err != nil {
		log.Fatal(err.Error())
	}

	trHashBytes := sha256.New()
	trHashBytes.Write(tx.toBytes(first, true))

	var res
	if first {
		res := key.Verify(quickHexDecode(tx.Signature), trHashBytes.Sum(nil))
	} else {
		res := key.Verify(quickHexDecode(tx.SignSignature), trHashBytes.Sum(nil))
	}

	if res == nil {
		return true
	}
	return false

}
<commit_msg>verifiy transaction  - signature cleanup code - removing duplicate stuff<commit_after>package core

import (
	"ark-go/arkcoin"
	"ark-go/arkcoin/base58"
	"bytes"
	"crypto/sha256"
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"log"
)

//Transaction struct - represents structure of ARK.io blockchain transaction
type Transaction struct {
	Timestamp          int32
	RecipientID        string
	Amount             int64
	Fee                int64
	Type               byte
	VendorField        string
	Signature          string
	SignSignature      string
	SenderPublicKey    string
	RequesterPublicKey string
	ID                 string
}

//ToBytes returns bytearray of the Transaction object to be signed and send to blockchain
func (tx *Transaction) toBytes(skipSignature, skipSecondSignature bool) []byte {
	txBuf := new(bytes.Buffer)
	binary.Write(txBuf, binary.LittleEndian, tx.Type)
	binary.Write(txBuf, binary.LittleEndian, uint32(tx.Timestamp))

	binary.Write(txBuf, binary.LittleEndian, quickHexDecode(tx.SenderPublicKey))

	if tx.RequesterPublicKey != "" {
		res, err := base58.Decode(tx.RequesterPublicKey)
		if err != nil {
			binary.Write(txBuf, binary.LittleEndian, res)
		}
	}

	if tx.RecipientID != "" {
		res, err := base58.Decode(tx.RecipientID)
		if err != nil {
			log.Fatal("Error converting Decoding b58 ", err.Error())
		}
		binary.Write(txBuf, binary.LittleEndian, res)
	} else {
		binary.Write(txBuf, binary.LittleEndian, make([]byte, 21))
	}

	if tx.VendorField != "" {
		vendorBytes := []byte(tx.VendorField)
		if len(vendorBytes) < 65 {
			binary.Write(txBuf, binary.LittleEndian, vendorBytes)

			bs := make([]byte, 64-len(vendorBytes))
			binary.Write(txBuf, binary.LittleEndian, bs)
		}
	} else {
		binary.Write(txBuf, binary.LittleEndian, make([]byte, 64))
	}

	binary.Write(txBuf, binary.LittleEndian, uint64(tx.Amount))
	binary.Write(txBuf, binary.LittleEndian, uint64(tx.Fee))

	switch tx.Type {
	case 1:
		binary.Write(txBuf, binary.LittleEndian, quickHexDecode(tx.Signature))
	case 2:
		//buffer.Put(Encoding.ASCII.GetBytes(asset["username"]));
	case 3:
		//votes
	}

	if !skipSignature && len(tx.Signature) > 0 {
		binary.Write(txBuf, binary.LittleEndian, quickHexDecode(tx.Signature))
	}

	if !skipSecondSignature && len(tx.SignSignature) > 0 {
		binary.Write(txBuf, binary.LittleEndian, quickHexDecode(tx.SignSignature))
	}

	return txBuf.Bytes()
}

//CreateTransaction creates and returns new Transaction struct...
func CreateTransaction(recipientID string, satoshiAmount int64, vendorField, passphrase, secondPassphrase string) *Transaction {
	tx := Transaction{Type: 0,
		RecipientID: recipientID,
		Amount:      satoshiAmount,
		Fee:         arkcoin.ArkCoinMain.Fees.Send,
		VendorField: vendorField}

	tx.Timestamp = 1 //Slot.GetTime();
	tx.sign(passphrase)

	if len(secondPassphrase) > 0 {
		tx.secondSign(secondPassphrase)
	}

	tx.getID() //calculates id of transaction
	return &tx
}

//Sign the Transaction
func (tx *Transaction) sign(passphrase string) {
	key := arkcoin.NewPrivateKeyFromPassword(passphrase, arkcoin.ArkCoinMain)

	tx.SenderPublicKey = hex.EncodeToString(key.PublicKey.Serialize())

	trHashBytes := sha256.New()
	trHashBytes.Write(tx.toBytes(true, true))

	sig, err := key.Sign(trHashBytes.Sum(nil))
	if err == nil {
		tx.Signature = hex.EncodeToString(sig)
	}
}

//SecondSign the Transaction
func (tx *Transaction) secondSign(passphrase string) {
	key := arkcoin.NewPrivateKeyFromPassword(passphrase, arkcoin.ArkCoinMain)

	trHashBytes := sha256.New()
	trHashBytes.Write(tx.toBytes(false, true))

	sig, err := key.Sign(trHashBytes.Sum(nil))
	if err == nil {
		tx.SignSignature = hex.EncodeToString(sig)
	}
}

//GetID returns calculated ID of trancation - hashed s256
func (tx *Transaction) getID() {
	trHashBytes := sha256.New()
	trHashBytes.Write(tx.toBytes(false, false))

	tx.ID = hex.EncodeToString(trHashBytes.Sum(nil))
}

//ToJSON converts transaction object to JSON string
func (tx *Transaction) ToJSON() string {
	txJSON, err := json.Marshal(tx)
	if err != nil {
		log.Fatal(err.Error())
	}
	return string(txJSON)
}

func quickHexDecode(data string) []byte {
	res, err := hex.DecodeString(data)
	if err != nil {
		log.Fatal(err.Error())
	}
	return res
}

//Verify function verifies if tx is validly signed
//if return == nill verification was succesfull
func (tx *Transaction) Verify() error {
	return tx.verifyHelper(true)
}

//SecondVerify function verifies if tx is validly signed
//if return == nill verification was succesfull
func (tx *Transaction) SecondVerify() error {
	return tx.verifyHelper(false)
}

//verifyHelper helps Signature verification. If parameter first is set to true
//first signature is checked, if verified is set to false second signature is checked
//if err == nill - verification was succesfull
func (tx *Transaction) verifyHelper(first bool) error {
	key, err := arkcoin.NewPublicKey(quickHexDecode(tx.SenderPublicKey), arkcoin.ArkCoinMain)
	if err != nil {
		log.Fatal(err.Error())
	}

	trHashBytes := sha256.New()
	trHashBytes.Write(tx.toBytes(first, true))

	if first {
		return key.Verify(quickHexDecode(tx.Signature), trHashBytes.Sum(nil))
	} else {
		return key.Verify(quickHexDecode(tx.SignSignature), trHashBytes.Sum(nil))
	}

}
<|endoftext|>