<commit_before>package main

import (
	"errors"
	"fmt"
	ipamsapi "github.com/docker/libnetwork/ipams/remote/api"
	netlabel "github.com/docker/libnetwork/netlabel"
	ibclient "github.com/infobloxopen/infoblox-go-client"
	"log"
	"strconv"
	"strings"
)

type Container struct {
	NetworkContainer string // CIDR of Network Container
	ContainerObj     *ibclient.NetworkContainer
	exhausted        bool
}

type InfobloxAddressSpace struct {
	NetviewName  string // Network View Name
	PrefixLength uint   // Prefix Length
	Containers   []Container
}

type AddressSpaceScope int

const (
	GLOBAL AddressSpaceScope = iota
	LOCAL
)

type InfobloxDriver struct {
	objMgr              *ibclient.ObjectManager
	addressSpaceByScope map[AddressSpaceScope]*InfobloxAddressSpace
	addressSpaceByView  map[string]*InfobloxAddressSpace
}

func (ibDrv *InfobloxDriver) PluginActivate(r interface{}) (map[string]interface{}, error) {
	return map[string]interface{}{
		"Implements": []interface{}{
			"IpamDriver",
		}}, nil
}

func (ibDrv *InfobloxDriver) GetCapabilities(r interface{}) (map[string]interface{}, error) {
	return map[string]interface{}{"RequiresMACAddress": true}, nil
}

func (ibDrv *InfobloxDriver) GetDefaultAddressSpaces(r interface{}) (map[string]interface{}, error) {
	globalViewRef, localViewRef, err := ibDrv.objMgr.CreateDefaultNetviews(
		ibDrv.addressSpaceByScope[GLOBAL].NetviewName,
		ibDrv.addressSpaceByScope[LOCAL].NetviewName)

	return map[string]interface{}{"GlobalDefaultAddressSpace": globalViewRef, "LocalDefaultAddressSpace": localViewRef}, err
}

func getPrefixLength(cidr string) (prefixLength string) {
	parts := strings.Split(cidr, "/")
	return parts[1]
}

func (ibDrv *InfobloxDriver) RequestAddress(r interface{}) (map[string]interface{}, error) {
	v := r.(*ipamsapi.RequestAddressRequest)
	network := ibclient.BuildNetworkFromRef(v.PoolID)

	macAddr := v.Options[netlabel.MacAddress]
	if len(macAddr) == 0 {
		macAddr = ibclient.MACADDR_ZERO
		log.Printf("RequestAddressRequest contains empty MAC Address. '%s' will be used.\n", macAddr)
	}

	var fixedAddr *ibclient.FixedAddress
	if v.Address != "" {
		fixedAddr, _ = ibDrv.objMgr.GetFixedAddress(network.NetviewName, v.Address, "")

		if fixedAddr != nil {
			if fixedAddr.Mac != macAddr {
				log.Printf("Requested IP address '%s' is already used by a difference MAC address '%s' (%s)",
					v.Address, fixedAddr.Mac, macAddr)

				return nil, nil
			}
		}
	}

	if fixedAddr == nil {
		fixedAddr, _ = ibDrv.objMgr.AllocateIP(network.NetviewName, network.Cidr, v.Address, macAddr, "")
	}

	return map[string]interface{}{"Address": fmt.Sprintf("%s/%s", fixedAddr.IPAddress, getPrefixLength(network.Cidr))}, nil
}

func (ibDrv *InfobloxDriver) ReleaseAddress(r interface{}) (map[string]interface{}, error) {
	v := r.(*ipamsapi.ReleaseAddressRequest)
	log.Printf("Releasing Address '%s' from Pool '%s'\n", v.Address, v.PoolID)
	network := ibclient.BuildNetworkFromRef(v.PoolID)
	ref, _ := ibDrv.objMgr.ReleaseIP(network.NetviewName, v.Address, "")
	if ref == "" {
		log.Printf("***** IP Cannot be deleted '%s'! *******\n", v.Address)
	}

	return map[string]interface{}{}, nil
}

func (ibDrv *InfobloxDriver) requestSpecificNetwork(netview string, pool string, networkName string) (*ibclient.Network, error) {
	network, err := ibDrv.objMgr.GetNetwork(netview, pool, nil)
	if err != nil {
		return nil, err
	}
	if network != nil {
		if n, ok := network.Ea["Network Name"]; !ok || n != networkName {
			log.Printf("requestSpecificNetwork: network is already used '%s'", *network)
			return nil, nil
		}
	} else {
		networkByName, err := ibDrv.objMgr.GetNetwork(netview, "", ibclient.EA{"Network Name": networkName})
		if err != nil {
			return nil, err
		}
		if networkByName != nil {
			if networkByName.Cidr != pool {
				log.Printf("requestSpecificNetwork: network name has different Cidr '%s'", networkByName.Cidr)
				return nil, nil
			}
		}
	}

	if network == nil {
		network, err = ibDrv.objMgr.CreateNetwork(netview, pool, networkName)
		log.Printf("requestSpecificNetwork: CreateNetwork returns '%s', err='%s'", *network, err)
	}

	return network, err
}

func (ibDrv *InfobloxDriver) createNetworkContainer(netview string, pool string) (*ibclient.NetworkContainer, error) {
	container, err := ibDrv.objMgr.GetNetworkContainer(netview, pool)
	if container == nil {
		container, err = ibDrv.objMgr.CreateNetworkContainer(netview, pool)
	}

	return container, err
}

func nextAvailableContainer(addrSpace *InfobloxAddressSpace) *Container {
	for i, _ := range addrSpace.Containers {
		if !addrSpace.Containers[i].exhausted {
			return &addrSpace.Containers[i]
		}
	}

	return nil
}

func resetContainers(addrSpace *InfobloxAddressSpace) {
	for i, _ := range addrSpace.Containers {
		addrSpace.Containers[i].exhausted = false
	}
}

func (ibDrv *InfobloxDriver) allocateNetworkHelper(addrSpace *InfobloxAddressSpace, prefixLen uint, networkName string) (network *ibclient.Network, err error) {
	if prefixLen == 0 {
		prefixLen = addrSpace.PrefixLength
	}
	container := nextAvailableContainer(addrSpace)
	for container != nil {
		log.Printf("Allocating network from Container:'%s'", container.NetworkContainer)
		if container.ContainerObj == nil {
			var err error
			container.ContainerObj, err = ibDrv.createNetworkContainer(addrSpace.NetviewName, container.NetworkContainer)
			if err != nil {
				return nil, err
			}
		}
		network, err = ibDrv.objMgr.AllocateNetwork(addrSpace.NetviewName, container.NetworkContainer, prefixLen, networkName)
		if network != nil {
			break
		}
		container.exhausted = true
		container = nextAvailableContainer(addrSpace)
	}

	return network, nil
}

func (ibDrv *InfobloxDriver) allocateNetwork(netview string, prefixLen uint, networkName string) (network *ibclient.Network, err error) {
	addrSpace := ibDrv.addressSpaceByView[netview]

	network, err = ibDrv.allocateNetworkHelper(addrSpace, prefixLen, networkName)
	if network == nil {
		resetContainers(addrSpace)
		network, err = ibDrv.allocateNetworkHelper(addrSpace, prefixLen, networkName)
	}

	if network == nil {
		err = errors.New("Cannot allocate network in Address Space")
	}
	return
}

func (ibDrv *InfobloxDriver) RequestPool(r interface{}) (res map[string]interface{}, err error) {
	v := r.(*ipamsapi.RequestPoolRequest)
	log.Printf("RequestPoolRequest is '%v'\n", v)

	netviewName := ibclient.BuildNetworkViewFromRef(v.AddressSpace).Name

	var network *ibclient.Network
	var networkName string

	if opt, ok := v.Options["network-name"]; ok {
		networkName = opt
	}

	if len(v.Pool) > 0 {
		network, err = ibDrv.requestSpecificNetwork(netviewName, v.Pool, networkName)
	} else {
		var prefixLen uint
		var networkByName *ibclient.Network
		if networkName != "" {
			networkByName, err = ibDrv.objMgr.GetNetwork(netviewName, "", ibclient.EA{"Network Name": networkName})
			if err != nil {
				return
			}
		}
		if networkByName != nil {
			log.Printf("RequestNetwork: GetNetwork by name returns '%s'", *networkByName)
			network = networkByName
		} else {
			if opt, ok := v.Options["prefix-length"]; ok {
				if v, err := strconv.ParseUint(opt, 10, 8); err == nil {
					prefixLen = uint(v)
				}
			}
			network, err = ibDrv.allocateNetwork(netviewName, prefixLen, networkName)
		}
	}

	if network != nil {
		res = map[string]interface{}{"PoolID": network.Ref, "Pool": network.Cidr}
	}
	return
}

func (ibDrv *InfobloxDriver) ReleasePool(r interface{}) (map[string]interface{}, error) {
	v := r.(*ipamsapi.ReleasePoolRequest)

	if len(v.PoolID) > 0 {
		networkFromRef := ibclient.BuildNetworkFromRef(v.PoolID)
		network, err := ibDrv.objMgr.GetNetwork(networkFromRef.NetviewName, networkFromRef.Cidr, nil)
		if err != nil {
			return map[string]interface{}{}, err
		}

		// if network has a valid looking "Network Name" EA, assume that
		// it is shared with others - hence not deleted.
		if n, ok := network.Ea["Network Name"]; ok && n != "" {
			return map[string]interface{}{}, nil
		}

		ref, _ := ibDrv.objMgr.DeleteNetwork(v.PoolID, networkFromRef.NetviewName)
		if len(ref) > 0 {
			log.Printf("Network %s deleted from Infoblox\n", v.PoolID)
		}
	}

	return map[string]interface{}{}, nil
}

func makeContainers(containerList string) []Container {
	var containers []Container

	parts := strings.Split(containerList, ",")
	for _, p := range parts {
		containers = append(containers, Container{p, nil, false})
	}

	return containers
}

func NewInfobloxDriver(objMgr *ibclient.ObjectManager,
	globalNetview string, globalNetworkContainer string, globalPrefixLength uint,
	localNetview string, localNetworkContainer string, localPrefixLength uint) *InfobloxDriver {

	globalContainers := makeContainers(globalNetworkContainer)
	localContainers := makeContainers(localNetworkContainer)

	globalAddressSpace := &InfobloxAddressSpace{
		globalNetview, globalPrefixLength, globalContainers}
	localAddressSpace := &InfobloxAddressSpace{
		localNetview, localPrefixLength, localContainers}

	return &InfobloxDriver{
		objMgr: objMgr,
		addressSpaceByScope: map[AddressSpaceScope]*InfobloxAddressSpace{
			GLOBAL: globalAddressSpace,
			LOCAL:  localAddressSpace,
		},
		addressSpaceByView: map[string]*InfobloxAddressSpace{
			globalNetview: globalAddressSpace,
			localNetview:  localAddressSpace,
		},
	}
}
<commit_msg>Check Zero MAC<commit_after>package main

import (
	"errors"
	"fmt"
	ipamsapi "github.com/docker/libnetwork/ipams/remote/api"
	netlabel "github.com/docker/libnetwork/netlabel"
	ibclient "github.com/infobloxopen/infoblox-go-client"
	"log"
	"strconv"
	"strings"
)

type Container struct {
	NetworkContainer string // CIDR of Network Container
	ContainerObj     *ibclient.NetworkContainer
	exhausted        bool
}

type InfobloxAddressSpace struct {
	NetviewName  string // Network View Name
	PrefixLength uint   // Prefix Length
	Containers   []Container
}

type AddressSpaceScope int

const (
	GLOBAL AddressSpaceScope = iota
	LOCAL
)

type InfobloxDriver struct {
	objMgr              *ibclient.ObjectManager
	addressSpaceByScope map[AddressSpaceScope]*InfobloxAddressSpace
	addressSpaceByView  map[string]*InfobloxAddressSpace
}

func (ibDrv *InfobloxDriver) PluginActivate(r interface{}) (map[string]interface{}, error) {
	return map[string]interface{}{
		"Implements": []interface{}{
			"IpamDriver",
		}}, nil
}

func (ibDrv *InfobloxDriver) GetCapabilities(r interface{}) (map[string]interface{}, error) {
	return map[string]interface{}{"RequiresMACAddress": true}, nil
}

func (ibDrv *InfobloxDriver) GetDefaultAddressSpaces(r interface{}) (map[string]interface{}, error) {
	globalViewRef, localViewRef, err := ibDrv.objMgr.CreateDefaultNetviews(
		ibDrv.addressSpaceByScope[GLOBAL].NetviewName,
		ibDrv.addressSpaceByScope[LOCAL].NetviewName)

	return map[string]interface{}{"GlobalDefaultAddressSpace": globalViewRef, "LocalDefaultAddressSpace": localViewRef}, err
}

func getPrefixLength(cidr string) (prefixLength string) {
	parts := strings.Split(cidr, "/")
	return parts[1]
}

func (ibDrv *InfobloxDriver) RequestAddress(r interface{}) (map[string]interface{}, error) {
	v := r.(*ipamsapi.RequestAddressRequest)
	network := ibclient.BuildNetworkFromRef(v.PoolID)

	macAddr := v.Options[netlabel.MacAddress]
	if len(macAddr) == 0 {
		macAddr = ibclient.MACADDR_ZERO
		log.Printf("RequestAddressRequest contains empty MAC Address. '%s' will be used.\n", macAddr)
	}

	var fixedAddr *ibclient.FixedAddress
	if v.Address != "" {
		fixedAddr, _ = ibDrv.objMgr.GetFixedAddress(network.NetviewName, v.Address, "")

		if fixedAddr != nil {
			if fixedAddr.Mac == "" {
				fixedAddr.Mac = ibclient.MACADDR_ZERO
			}
			if fixedAddr.Mac != macAddr {
				log.Printf("Requested IP address '%s' is already used by a difference MAC address '%s' (%s)",
					v.Address, fixedAddr.Mac, macAddr)

				return nil, nil
			}
		}
	}

	if fixedAddr == nil {
		fixedAddr, _ = ibDrv.objMgr.AllocateIP(network.NetviewName, network.Cidr, v.Address, macAddr, "")
	}

	return map[string]interface{}{"Address": fmt.Sprintf("%s/%s", fixedAddr.IPAddress, getPrefixLength(network.Cidr))}, nil
}

func (ibDrv *InfobloxDriver) ReleaseAddress(r interface{}) (map[string]interface{}, error) {
	v := r.(*ipamsapi.ReleaseAddressRequest)
	log.Printf("Releasing Address '%s' from Pool '%s'\n", v.Address, v.PoolID)
	network := ibclient.BuildNetworkFromRef(v.PoolID)
	ref, _ := ibDrv.objMgr.ReleaseIP(network.NetviewName, v.Address, "")
	if ref == "" {
		log.Printf("***** IP Cannot be deleted '%s'! *******\n", v.Address)
	}

	return map[string]interface{}{}, nil
}

func (ibDrv *InfobloxDriver) requestSpecificNetwork(netview string, pool string, networkName string) (*ibclient.Network, error) {
	network, err := ibDrv.objMgr.GetNetwork(netview, pool, nil)
	if err != nil {
		return nil, err
	}
	if network != nil {
		if n, ok := network.Ea["Network Name"]; !ok || n != networkName {
			log.Printf("requestSpecificNetwork: network is already used '%s'", *network)
			return nil, nil
		}
	} else {
		networkByName, err := ibDrv.objMgr.GetNetwork(netview, "", ibclient.EA{"Network Name": networkName})
		if err != nil {
			return nil, err
		}
		if networkByName != nil {
			if networkByName.Cidr != pool {
				log.Printf("requestSpecificNetwork: network name has different Cidr '%s'", networkByName.Cidr)
				return nil, nil
			}
		}
	}

	if network == nil {
		network, err = ibDrv.objMgr.CreateNetwork(netview, pool, networkName)
		log.Printf("requestSpecificNetwork: CreateNetwork returns '%s', err='%s'", *network, err)
	}

	return network, err
}

func (ibDrv *InfobloxDriver) createNetworkContainer(netview string, pool string) (*ibclient.NetworkContainer, error) {
	container, err := ibDrv.objMgr.GetNetworkContainer(netview, pool)
	if container == nil {
		container, err = ibDrv.objMgr.CreateNetworkContainer(netview, pool)
	}

	return container, err
}

func nextAvailableContainer(addrSpace *InfobloxAddressSpace) *Container {
	for i, _ := range addrSpace.Containers {
		if !addrSpace.Containers[i].exhausted {
			return &addrSpace.Containers[i]
		}
	}

	return nil
}

func resetContainers(addrSpace *InfobloxAddressSpace) {
	for i, _ := range addrSpace.Containers {
		addrSpace.Containers[i].exhausted = false
	}
}

func (ibDrv *InfobloxDriver) allocateNetworkHelper(addrSpace *InfobloxAddressSpace, prefixLen uint, networkName string) (network *ibclient.Network, err error) {
	if prefixLen == 0 {
		prefixLen = addrSpace.PrefixLength
	}
	container := nextAvailableContainer(addrSpace)
	for container != nil {
		log.Printf("Allocating network from Container:'%s'", container.NetworkContainer)
		if container.ContainerObj == nil {
			var err error
			container.ContainerObj, err = ibDrv.createNetworkContainer(addrSpace.NetviewName, container.NetworkContainer)
			if err != nil {
				return nil, err
			}
		}
		network, err = ibDrv.objMgr.AllocateNetwork(addrSpace.NetviewName, container.NetworkContainer, prefixLen, networkName)
		if network != nil {
			break
		}
		container.exhausted = true
		container = nextAvailableContainer(addrSpace)
	}

	return network, nil
}

func (ibDrv *InfobloxDriver) allocateNetwork(netview string, prefixLen uint, networkName string) (network *ibclient.Network, err error) {
	addrSpace := ibDrv.addressSpaceByView[netview]

	network, err = ibDrv.allocateNetworkHelper(addrSpace, prefixLen, networkName)
	if network == nil {
		resetContainers(addrSpace)
		network, err = ibDrv.allocateNetworkHelper(addrSpace, prefixLen, networkName)
	}

	if network == nil {
		err = errors.New("Cannot allocate network in Address Space")
	}
	return
}

func (ibDrv *InfobloxDriver) RequestPool(r interface{}) (res map[string]interface{}, err error) {
	v := r.(*ipamsapi.RequestPoolRequest)
	log.Printf("RequestPoolRequest is '%v'\n", v)

	netviewName := ibclient.BuildNetworkViewFromRef(v.AddressSpace).Name

	var network *ibclient.Network
	var networkName string

	if opt, ok := v.Options["network-name"]; ok {
		networkName = opt
	}

	if len(v.Pool) > 0 {
		network, err = ibDrv.requestSpecificNetwork(netviewName, v.Pool, networkName)
	} else {
		var prefixLen uint
		var networkByName *ibclient.Network
		if networkName != "" {
			networkByName, err = ibDrv.objMgr.GetNetwork(netviewName, "", ibclient.EA{"Network Name": networkName})
			if err != nil {
				return
			}
		}
		if networkByName != nil {
			log.Printf("RequestNetwork: GetNetwork by name returns '%s'", *networkByName)
			network = networkByName
		} else {
			if opt, ok := v.Options["prefix-length"]; ok {
				if v, err := strconv.ParseUint(opt, 10, 8); err == nil {
					prefixLen = uint(v)
				}
			}
			network, err = ibDrv.allocateNetwork(netviewName, prefixLen, networkName)
		}
	}

	if network != nil {
		res = map[string]interface{}{"PoolID": network.Ref, "Pool": network.Cidr}
	}
	return
}

func (ibDrv *InfobloxDriver) ReleasePool(r interface{}) (map[string]interface{}, error) {
	v := r.(*ipamsapi.ReleasePoolRequest)

	if len(v.PoolID) > 0 {
		networkFromRef := ibclient.BuildNetworkFromRef(v.PoolID)
		network, err := ibDrv.objMgr.GetNetwork(networkFromRef.NetviewName, networkFromRef.Cidr, nil)
		if err != nil {
			return map[string]interface{}{}, err
		}

		// if network has a valid looking "Network Name" EA, assume that
		// it is shared with others - hence not deleted.
		if n, ok := network.Ea["Network Name"]; ok && n != "" {
			return map[string]interface{}{}, nil
		}

		ref, _ := ibDrv.objMgr.DeleteNetwork(v.PoolID, networkFromRef.NetviewName)
		if len(ref) > 0 {
			log.Printf("Network %s deleted from Infoblox\n", v.PoolID)
		}
	}

	return map[string]interface{}{}, nil
}

func makeContainers(containerList string) []Container {
	var containers []Container

	parts := strings.Split(containerList, ",")
	for _, p := range parts {
		containers = append(containers, Container{p, nil, false})
	}

	return containers
}

func NewInfobloxDriver(objMgr *ibclient.ObjectManager,
	globalNetview string, globalNetworkContainer string, globalPrefixLength uint,
	localNetview string, localNetworkContainer string, localPrefixLength uint) *InfobloxDriver {

	globalContainers := makeContainers(globalNetworkContainer)
	localContainers := makeContainers(localNetworkContainer)

	globalAddressSpace := &InfobloxAddressSpace{
		globalNetview, globalPrefixLength, globalContainers}
	localAddressSpace := &InfobloxAddressSpace{
		localNetview, localPrefixLength, localContainers}

	return &InfobloxDriver{
		objMgr: objMgr,
		addressSpaceByScope: map[AddressSpaceScope]*InfobloxAddressSpace{
			GLOBAL: globalAddressSpace,
			LOCAL:  localAddressSpace,
		},
		addressSpaceByView: map[string]*InfobloxAddressSpace{
			globalNetview: globalAddressSpace,
			localNetview:  localAddressSpace,
		},
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Tigera, Inc. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package node

import (
	"fmt"
	"os"
)

func enforceRoot() {
	// Make sure the command is run with super user priviladges
	if os.Getuid() != 0 {
		fmt.Println("Need super user privilages: Operation not permitted")
		os.Exit(1)
	}
}
<commit_msg>Fix typo<commit_after>// Copyright (c) 2016 Tigera, Inc. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package node

import (
	"fmt"
	"os"
)

func enforceRoot() {
	// Make sure the command is run with super user priviladges
	if os.Getuid() != 0 {
		fmt.Println("Need super user privileges: Operation not permitted")
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 The Go 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 net

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"sort"
	"strings"
	"syscall"
	"testing"
	"time"
)

func toErrno(err error) (syscall.Errno, bool) {
	operr, ok := err.(*OpError)
	if !ok {
		return 0, false
	}
	syserr, ok := operr.Err.(*os.SyscallError)
	if !ok {
		return 0, false
	}
	errno, ok := syserr.Err.(syscall.Errno)
	if !ok {
		return 0, false
	}
	return errno, true
}

// TestAcceptIgnoreSomeErrors tests that windows TCPListener.AcceptTCP
// handles broken connections. It verifies that broken connections do
// not affect future connections.
func TestAcceptIgnoreSomeErrors(t *testing.T) {
	recv := func(ln Listener, ignoreSomeReadErrors bool) (string, error) {
		c, err := ln.Accept()
		if err != nil {
			// Display windows errno in error message.
			errno, ok := toErrno(err)
			if !ok {
				return "", err
			}
			return "", fmt.Errorf("%v (windows errno=%d)", err, errno)
		}
		defer c.Close()

		b := make([]byte, 100)
		n, err := c.Read(b)
		if err == nil || err == io.EOF {
			return string(b[:n]), nil
		}
		errno, ok := toErrno(err)
		if ok && ignoreSomeReadErrors && (errno == syscall.ERROR_NETNAME_DELETED || errno == syscall.WSAECONNRESET) {
			return "", nil
		}
		return "", err
	}

	send := func(addr string, data string) error {
		c, err := Dial("tcp", addr)
		if err != nil {
			return err
		}
		defer c.Close()

		b := []byte(data)
		n, err := c.Write(b)
		if err != nil {
			return err
		}
		if n != len(b) {
			return fmt.Errorf(`Only %d chars of string "%s" sent`, n, data)
		}
		return nil
	}

	if envaddr := os.Getenv("GOTEST_DIAL_ADDR"); envaddr != "" {
		// In child process.
		c, err := Dial("tcp", envaddr)
		if err != nil {
			t.Fatal(err)
		}
		fmt.Printf("sleeping\n")
		time.Sleep(time.Minute) // process will be killed here
		c.Close()
	}

	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	defer ln.Close()

	// Start child process that connects to our listener.
	cmd := exec.Command(os.Args[0], "-test.run=TestAcceptIgnoreSomeErrors")
	cmd.Env = append(os.Environ(), "GOTEST_DIAL_ADDR="+ln.Addr().String())
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		t.Fatalf("cmd.StdoutPipe failed: %v", err)
	}
	err = cmd.Start()
	if err != nil {
		t.Fatalf("cmd.Start failed: %v\n", err)
	}
	outReader := bufio.NewReader(stdout)
	for {
		s, err := outReader.ReadString('\n')
		if err != nil {
			t.Fatalf("reading stdout failed: %v", err)
		}
		if s == "sleeping\n" {
			break
		}
	}
	defer cmd.Wait() // ignore error - we know it is getting killed

	const alittle = 100 * time.Millisecond
	time.Sleep(alittle)
	cmd.Process.Kill() // the only way to trigger the errors
	time.Sleep(alittle)

	// Send second connection data (with delay in a separate goroutine).
	result := make(chan error)
	go func() {
		time.Sleep(alittle)
		err := send(ln.Addr().String(), "abc")
		if err != nil {
			result <- err
		}
		result <- nil
	}()
	defer func() {
		err := <-result
		if err != nil {
			t.Fatalf("send failed: %v", err)
		}
	}()

	// Receive first or second connection.
	s, err := recv(ln, true)
	if err != nil {
		t.Fatalf("recv failed: %v", err)
	}
	switch s {
	case "":
		// First connection data is received, let's get second connection data.
	case "abc":
		// First connection is lost forever, but that is ok.
		return
	default:
		t.Fatalf(`"%s" received from recv, but "" or "abc" expected`, s)
	}

	// Get second connection data.
	s, err = recv(ln, false)
	if err != nil {
		t.Fatalf("recv failed: %v", err)
	}
	if s != "abc" {
		t.Fatalf(`"%s" received from recv, but "abc" expected`, s)
	}
}

func isWindowsXP(t *testing.T) bool {
	v, err := syscall.GetVersion()
	if err != nil {
		t.Fatalf("GetVersion failed: %v", err)
	}
	major := byte(v)
	return major < 6
}

func runNetsh(args ...string) ([]byte, error) {
	removeUTF8BOM := func(b []byte) []byte {
		if len(b) >= 3 && b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF {
			return b[3:]
		}
		return b
	}
	f, err := ioutil.TempFile("", "netsh")
	if err != nil {
		return nil, err
	}
	f.Close()
	defer os.Remove(f.Name())
	cmd := fmt.Sprintf(`%s | Out-File "%s" -encoding UTF8`, strings.Join(args, " "), f.Name())
	out, err := exec.Command("powershell", "-Command", cmd).CombinedOutput()
	if err != nil {
		if len(out) != 0 {
			return nil, fmt.Errorf("netsh failed: %v: %q", err, string(removeUTF8BOM(out)))
		}
		var err2 error
		out, err2 = ioutil.ReadFile(f.Name())
		if err2 != nil {
			return nil, err2
		}
		if len(out) != 0 {
			return nil, fmt.Errorf("netsh failed: %v: %q", err, string(removeUTF8BOM(out)))
		}
		return nil, fmt.Errorf("netsh failed: %v", err)
	}
	out, err = ioutil.ReadFile(f.Name())
	if err != nil {
		return nil, err
	}
	return removeUTF8BOM(out), nil
}

func netshInterfaceIPShowConfig() ([]string, error) {
	out, err := runNetsh("netsh", "interface", "ip", "show", "config")
	if err != nil {
		return nil, err
	}
	lines := bytes.Split(out, []byte{'\r', '\n'})
	names := make([]string, 0)
	for _, line := range lines {
		f := bytes.Split(line, []byte{'"'})
		if len(f) == 3 {
			names = append(names, string(f[1]))
		}
	}
	return names, nil
}

func TestInterfacesWithNetsh(t *testing.T) {
	if isWindowsXP(t) {
		t.Skip("Windows XP netsh command does not provide required functionality")
	}
	ift, err := Interfaces()
	if err != nil {
		t.Fatal(err)
	}
	have := make([]string, 0)
	for _, ifi := range ift {
		have = append(have, ifi.Name)
	}
	sort.Strings(have)

	want, err := netshInterfaceIPShowConfig()
	if err != nil {
		t.Fatal(err)
	}
	sort.Strings(want)

	if strings.Join(want, "/") != strings.Join(have, "/") {
		t.Fatalf("unexpected interface list %q, want %q", have, want)
	}
}

func netshInterfaceIPv4ShowAddress(name string) ([]string, error) {
	out, err := runNetsh("netsh", "interface", "ipv4", "show", "address", "name=\""+name+"\"")
	if err != nil {
		return nil, err
	}
	// adress information is listed like:
	//    IP Address:                           10.0.0.2
	//    Subnet Prefix:                        10.0.0.0/24 (mask 255.255.255.0)
	//    IP Address:                           10.0.0.3
	//    Subnet Prefix:                        10.0.0.0/24 (mask 255.255.255.0)
	addrs := make([]string, 0)
	var addr, subnetprefix string
	lines := bytes.Split(out, []byte{'\r', '\n'})
	for _, line := range lines {
		if bytes.Contains(line, []byte("Subnet Prefix:")) {
			f := bytes.Split(line, []byte{':'})
			if len(f) == 2 {
				f = bytes.Split(f[1], []byte{'('})
				if len(f) == 2 {
					f = bytes.Split(f[0], []byte{'/'})
					if len(f) == 2 {
						subnetprefix = string(bytes.TrimSpace(f[1]))
						if addr != "" && subnetprefix != "" {
							addrs = append(addrs, addr+"/"+subnetprefix)
						}
					}
				}
			}
		}
		addr = ""
		if bytes.Contains(line, []byte("IP Address:")) {
			f := bytes.Split(line, []byte{':'})
			if len(f) == 2 {
				addr = string(bytes.TrimSpace(f[1]))
			}
		}
	}
	return addrs, nil
}

func netshInterfaceIPv6ShowAddress(name string) ([]string, error) {
	// TODO: need to test ipv6 netmask too, but netsh does not outputs it
	out, err := runNetsh("netsh", "interface", "ipv6", "show", "address", "interface=\""+name+"\"")
	if err != nil {
		return nil, err
	}
	addrs := make([]string, 0)
	lines := bytes.Split(out, []byte{'\r', '\n'})
	for _, line := range lines {
		if !bytes.HasPrefix(line, []byte("Address")) {
			continue
		}
		if !bytes.HasSuffix(line, []byte("Parameters")) {
			continue
		}
		f := bytes.Split(line, []byte{' '})
		if len(f) != 3 {
			continue
		}
		// remove scope ID if present
		f = bytes.Split(f[1], []byte{'%'})
		addrs = append(addrs, string(bytes.TrimSpace(f[0])))
	}
	return addrs, nil
}

func TestInterfaceAddrsWithNetsh(t *testing.T) {
	t.Skip("skipping test; see https://golang.org/issue/12811")
	if isWindowsXP(t) {
		t.Skip("Windows XP netsh command does not provide required functionality")
	}
	ift, err := Interfaces()
	if err != nil {
		t.Fatal(err)
	}
	for _, ifi := range ift {
		have := make([]string, 0)
		addrs, err := ifi.Addrs()
		if err != nil {
			t.Fatal(err)
		}
		for _, addr := range addrs {
			switch addr := addr.(type) {
			case *IPNet:
				if addr.IP.To4() != nil {
					have = append(have, addr.String())
				}
				if addr.IP.To16() != nil && addr.IP.To4() == nil {
					// netsh does not output netmask for ipv6, so ignore ipv6 mask
					have = append(have, addr.IP.String())
				}
			case *IPAddr:
				if addr.IP.To4() != nil {
					have = append(have, addr.String())
				}
				if addr.IP.To16() != nil && addr.IP.To4() == nil {
					// netsh does not output netmask for ipv6, so ignore ipv6 mask
					have = append(have, addr.IP.String())
				}
			}
		}
		sort.Strings(have)

		want, err := netshInterfaceIPv4ShowAddress(ifi.Name)
		if err != nil {
			t.Fatal(err)
		}
		wantIPv6, err := netshInterfaceIPv6ShowAddress(ifi.Name)
		if err != nil {
			t.Fatal(err)
		}
		want = append(want, wantIPv6...)
		sort.Strings(want)

		if strings.Join(want, "/") != strings.Join(have, "/") {
			t.Errorf("%s: unexpected addresses list %q, want %q", ifi.Name, have, want)
		}
	}
}
<commit_msg>net: add TestInterfaceHardwareAddrWithGetmac<commit_after>// Copyright 2014 The Go 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 net

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"sort"
	"strings"
	"syscall"
	"testing"
	"time"
)

func toErrno(err error) (syscall.Errno, bool) {
	operr, ok := err.(*OpError)
	if !ok {
		return 0, false
	}
	syserr, ok := operr.Err.(*os.SyscallError)
	if !ok {
		return 0, false
	}
	errno, ok := syserr.Err.(syscall.Errno)
	if !ok {
		return 0, false
	}
	return errno, true
}

// TestAcceptIgnoreSomeErrors tests that windows TCPListener.AcceptTCP
// handles broken connections. It verifies that broken connections do
// not affect future connections.
func TestAcceptIgnoreSomeErrors(t *testing.T) {
	recv := func(ln Listener, ignoreSomeReadErrors bool) (string, error) {
		c, err := ln.Accept()
		if err != nil {
			// Display windows errno in error message.
			errno, ok := toErrno(err)
			if !ok {
				return "", err
			}
			return "", fmt.Errorf("%v (windows errno=%d)", err, errno)
		}
		defer c.Close()

		b := make([]byte, 100)
		n, err := c.Read(b)
		if err == nil || err == io.EOF {
			return string(b[:n]), nil
		}
		errno, ok := toErrno(err)
		if ok && ignoreSomeReadErrors && (errno == syscall.ERROR_NETNAME_DELETED || errno == syscall.WSAECONNRESET) {
			return "", nil
		}
		return "", err
	}

	send := func(addr string, data string) error {
		c, err := Dial("tcp", addr)
		if err != nil {
			return err
		}
		defer c.Close()

		b := []byte(data)
		n, err := c.Write(b)
		if err != nil {
			return err
		}
		if n != len(b) {
			return fmt.Errorf(`Only %d chars of string "%s" sent`, n, data)
		}
		return nil
	}

	if envaddr := os.Getenv("GOTEST_DIAL_ADDR"); envaddr != "" {
		// In child process.
		c, err := Dial("tcp", envaddr)
		if err != nil {
			t.Fatal(err)
		}
		fmt.Printf("sleeping\n")
		time.Sleep(time.Minute) // process will be killed here
		c.Close()
	}

	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	defer ln.Close()

	// Start child process that connects to our listener.
	cmd := exec.Command(os.Args[0], "-test.run=TestAcceptIgnoreSomeErrors")
	cmd.Env = append(os.Environ(), "GOTEST_DIAL_ADDR="+ln.Addr().String())
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		t.Fatalf("cmd.StdoutPipe failed: %v", err)
	}
	err = cmd.Start()
	if err != nil {
		t.Fatalf("cmd.Start failed: %v\n", err)
	}
	outReader := bufio.NewReader(stdout)
	for {
		s, err := outReader.ReadString('\n')
		if err != nil {
			t.Fatalf("reading stdout failed: %v", err)
		}
		if s == "sleeping\n" {
			break
		}
	}
	defer cmd.Wait() // ignore error - we know it is getting killed

	const alittle = 100 * time.Millisecond
	time.Sleep(alittle)
	cmd.Process.Kill() // the only way to trigger the errors
	time.Sleep(alittle)

	// Send second connection data (with delay in a separate goroutine).
	result := make(chan error)
	go func() {
		time.Sleep(alittle)
		err := send(ln.Addr().String(), "abc")
		if err != nil {
			result <- err
		}
		result <- nil
	}()
	defer func() {
		err := <-result
		if err != nil {
			t.Fatalf("send failed: %v", err)
		}
	}()

	// Receive first or second connection.
	s, err := recv(ln, true)
	if err != nil {
		t.Fatalf("recv failed: %v", err)
	}
	switch s {
	case "":
		// First connection data is received, let's get second connection data.
	case "abc":
		// First connection is lost forever, but that is ok.
		return
	default:
		t.Fatalf(`"%s" received from recv, but "" or "abc" expected`, s)
	}

	// Get second connection data.
	s, err = recv(ln, false)
	if err != nil {
		t.Fatalf("recv failed: %v", err)
	}
	if s != "abc" {
		t.Fatalf(`"%s" received from recv, but "abc" expected`, s)
	}
}

func isWindowsXP(t *testing.T) bool {
	v, err := syscall.GetVersion()
	if err != nil {
		t.Fatalf("GetVersion failed: %v", err)
	}
	major := byte(v)
	return major < 6
}

func runCmd(args ...string) ([]byte, error) {
	removeUTF8BOM := func(b []byte) []byte {
		if len(b) >= 3 && b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF {
			return b[3:]
		}
		return b
	}
	f, err := ioutil.TempFile("", "netcmd")
	if err != nil {
		return nil, err
	}
	f.Close()
	defer os.Remove(f.Name())
	cmd := fmt.Sprintf(`%s | Out-File "%s" -encoding UTF8`, strings.Join(args, " "), f.Name())
	out, err := exec.Command("powershell", "-Command", cmd).CombinedOutput()
	if err != nil {
		if len(out) != 0 {
			return nil, fmt.Errorf("%s failed: %v: %q", args[0], err, string(removeUTF8BOM(out)))
		}
		var err2 error
		out, err2 = ioutil.ReadFile(f.Name())
		if err2 != nil {
			return nil, err2
		}
		if len(out) != 0 {
			return nil, fmt.Errorf("%s failed: %v: %q", args[0], err, string(removeUTF8BOM(out)))
		}
		return nil, fmt.Errorf("%s failed: %v", args[0], err)
	}
	out, err = ioutil.ReadFile(f.Name())
	if err != nil {
		return nil, err
	}
	return removeUTF8BOM(out), nil
}

func netshInterfaceIPShowConfig() ([]string, error) {
	out, err := runCmd("netsh", "interface", "ip", "show", "config")
	if err != nil {
		return nil, err
	}
	lines := bytes.Split(out, []byte{'\r', '\n'})
	names := make([]string, 0)
	for _, line := range lines {
		f := bytes.Split(line, []byte{'"'})
		if len(f) == 3 {
			names = append(names, string(f[1]))
		}
	}
	return names, nil
}

func TestInterfacesWithNetsh(t *testing.T) {
	if isWindowsXP(t) {
		t.Skip("Windows XP netsh command does not provide required functionality")
	}
	ift, err := Interfaces()
	if err != nil {
		t.Fatal(err)
	}
	have := make([]string, 0)
	for _, ifi := range ift {
		have = append(have, ifi.Name)
	}
	sort.Strings(have)

	want, err := netshInterfaceIPShowConfig()
	if err != nil {
		t.Fatal(err)
	}
	sort.Strings(want)

	if strings.Join(want, "/") != strings.Join(have, "/") {
		t.Fatalf("unexpected interface list %q, want %q", have, want)
	}
}

func netshInterfaceIPv4ShowAddress(name string) ([]string, error) {
	out, err := runCmd("netsh", "interface", "ipv4", "show", "address", "name=\""+name+"\"")
	if err != nil {
		return nil, err
	}
	// adress information is listed like:
	//    IP Address:                           10.0.0.2
	//    Subnet Prefix:                        10.0.0.0/24 (mask 255.255.255.0)
	//    IP Address:                           10.0.0.3
	//    Subnet Prefix:                        10.0.0.0/24 (mask 255.255.255.0)
	addrs := make([]string, 0)
	var addr, subnetprefix string
	lines := bytes.Split(out, []byte{'\r', '\n'})
	for _, line := range lines {
		if bytes.Contains(line, []byte("Subnet Prefix:")) {
			f := bytes.Split(line, []byte{':'})
			if len(f) == 2 {
				f = bytes.Split(f[1], []byte{'('})
				if len(f) == 2 {
					f = bytes.Split(f[0], []byte{'/'})
					if len(f) == 2 {
						subnetprefix = string(bytes.TrimSpace(f[1]))
						if addr != "" && subnetprefix != "" {
							addrs = append(addrs, addr+"/"+subnetprefix)
						}
					}
				}
			}
		}
		addr = ""
		if bytes.Contains(line, []byte("IP Address:")) {
			f := bytes.Split(line, []byte{':'})
			if len(f) == 2 {
				addr = string(bytes.TrimSpace(f[1]))
			}
		}
	}
	return addrs, nil
}

func netshInterfaceIPv6ShowAddress(name string) ([]string, error) {
	// TODO: need to test ipv6 netmask too, but netsh does not outputs it
	out, err := runCmd("netsh", "interface", "ipv6", "show", "address", "interface=\""+name+"\"")
	if err != nil {
		return nil, err
	}
	addrs := make([]string, 0)
	lines := bytes.Split(out, []byte{'\r', '\n'})
	for _, line := range lines {
		if !bytes.HasPrefix(line, []byte("Address")) {
			continue
		}
		if !bytes.HasSuffix(line, []byte("Parameters")) {
			continue
		}
		f := bytes.Split(line, []byte{' '})
		if len(f) != 3 {
			continue
		}
		// remove scope ID if present
		f = bytes.Split(f[1], []byte{'%'})
		addrs = append(addrs, string(bytes.TrimSpace(f[0])))
	}
	return addrs, nil
}

func TestInterfaceAddrsWithNetsh(t *testing.T) {
	t.Skip("skipping test; see https://golang.org/issue/12811")
	if isWindowsXP(t) {
		t.Skip("Windows XP netsh command does not provide required functionality")
	}
	ift, err := Interfaces()
	if err != nil {
		t.Fatal(err)
	}
	for _, ifi := range ift {
		have := make([]string, 0)
		addrs, err := ifi.Addrs()
		if err != nil {
			t.Fatal(err)
		}
		for _, addr := range addrs {
			switch addr := addr.(type) {
			case *IPNet:
				if addr.IP.To4() != nil {
					have = append(have, addr.String())
				}
				if addr.IP.To16() != nil && addr.IP.To4() == nil {
					// netsh does not output netmask for ipv6, so ignore ipv6 mask
					have = append(have, addr.IP.String())
				}
			case *IPAddr:
				if addr.IP.To4() != nil {
					have = append(have, addr.String())
				}
				if addr.IP.To16() != nil && addr.IP.To4() == nil {
					// netsh does not output netmask for ipv6, so ignore ipv6 mask
					have = append(have, addr.IP.String())
				}
			}
		}
		sort.Strings(have)

		want, err := netshInterfaceIPv4ShowAddress(ifi.Name)
		if err != nil {
			t.Fatal(err)
		}
		wantIPv6, err := netshInterfaceIPv6ShowAddress(ifi.Name)
		if err != nil {
			t.Fatal(err)
		}
		want = append(want, wantIPv6...)
		sort.Strings(want)

		if strings.Join(want, "/") != strings.Join(have, "/") {
			t.Errorf("%s: unexpected addresses list %q, want %q", ifi.Name, have, want)
		}
	}
}

func TestInterfaceHardwareAddrWithGetmac(t *testing.T) {
	t.Skip("skipping test; see https://golang.org/issue/12691")
	if isWindowsXP(t) {
		t.Skip("Windows XP does not have powershell command")
	}
	ift, err := Interfaces()
	if err != nil {
		t.Fatal(err)
	}
	have := make([]string, 0)
	for _, ifi := range ift {
		if ifi.Flags&FlagLoopback != 0 {
			// no MAC for loopback interfaces
			continue
		}
		have = append(have, ifi.Name+"="+ifi.HardwareAddr.String())
	}
	sort.Strings(have)

	out, err := runCmd("getmac", "/fo", "list", "/v")
	if err != nil {
		t.Fatal(err)
	}
	// getmac output looks like:
	//
	//Connection Name:  Local Area Connection
	//Network Adapter:  Intel Gigabit Network Connection
	//Physical Address: XX-XX-XX-XX-XX-XX
	//Transport Name:   \Device\Tcpip_{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
	//
	//Connection Name:  Wireless Network Connection
	//Network Adapter:  Wireles WLAN Card
	//Physical Address: XX-XX-XX-XX-XX-XX
	//Transport Name:   Media disconnected
	//
	//Connection Name:  Bluetooth Network Connection
	//Network Adapter:  Bluetooth Device (Personal Area Network)
	//Physical Address: XX-XX-XX-XX-XX-XX
	//Transport Name:   Media disconnected
	//
	want := make([]string, 0)
	var name string
	lines := bytes.Split(out, []byte{'\r', '\n'})
	for _, line := range lines {
		if bytes.Contains(line, []byte("Connection Name:")) {
			f := bytes.Split(line, []byte{':'})
			if len(f) != 2 {
				t.Fatal("unexpected \"Connection Name\" line: %q", line)
			}
			name = string(bytes.TrimSpace(f[1]))
			if name == "" {
				t.Fatal("empty name on \"Connection Name\" line: %q", line)
			}
		}
		if bytes.Contains(line, []byte("Physical Address:")) {
			if name == "" {
				t.Fatal("no matching name found: %q", string(out))
			}
			f := bytes.Split(line, []byte{':'})
			if len(f) != 2 {
				t.Fatal("unexpected \"Physical Address\" line: %q", line)
			}
			addr := string(bytes.TrimSpace(f[1]))
			if addr == "" {
				t.Fatal("empty address on \"Physical Address\" line: %q", line)
			}
			addr = strings.Replace(addr, "-", ":", -1)
			want = append(want, name+"="+addr)
			name = ""
		}
	}
	sort.Strings(want)

	if strings.Join(want, "/") != strings.Join(have, "/") {
		t.Fatalf("unexpected MAC addresses %q, want %q", have, want)
	}
}
<|endoftext|>


<commit_before><commit_msg>보안을 위해서 localhost로부터의 접속만을 허용하도록 수정.<commit_after><|endoftext|>


<commit_before>package common

import (
	crand "crypto/rand"
	mrand "math/rand"
	"sync"
	"time"
)

const (
	strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
)

// pseudo random number generator.
// seeded with OS randomness (crand)

type Rand struct {
	sync.Mutex
	*mrand.Rand
}

var grand *Rand

func init() {
	grand = New()
	grand.init()
}

func New() *Rand {
	rand := &Rand{}
	rand.init()
	return rand
}

func (r *Rand) init() {
	bz := cRandBytes(8)
	var seed uint64
	for i := 0; i < 8; i++ {
		seed |= uint64(bz[i])
		seed <<= 8
	}
	r.reset(int64(seed))
}

func (r *Rand) reset(seed int64) {
	r.Rand = mrand.New(mrand.NewSource(seed))
}

//----------------------------------------
// Global functions

func Seed(seed int64) {
	grand.Seed(seed)
}

func RandStr(length int) string {
	return grand.RandStr(length)
}

func RandUint16() uint16 {
	return grand.RandUint16()
}

func RandUint32() uint32 {
	return grand.RandUint32()
}

func RandUint64() uint64 {
	return grand.RandUint64()
}

func RandUint() uint {
	return grand.RandUint()
}

func RandInt16() int16 {
	return grand.RandInt16()
}

func RandInt32() int32 {
	return grand.RandInt32()
}

func RandInt64() int64 {
	return grand.RandInt64()
}

func RandInt() int {
	return grand.RandInt()
}

func RandInt31() int32 {
	return grand.RandInt31()
}

func RandInt63() int64 {
	return grand.RandInt63()
}

func RandUint16Exp() uint16 {
	return grand.RandUint16Exp()
}

func RandUint32Exp() uint32 {
	return grand.RandUint32Exp()
}

func RandUint64Exp() uint64 {
	return grand.RandUint64Exp()
}

func RandFloat32() float32 {
	return grand.RandFloat32()
}

func RandTime() time.Time {
	return grand.RandTime()
}

func RandBytes(n int) []byte {
	return grand.RandBytes(n)
}

func RandIntn(n int) int {
	return grand.RandIntn(n)
}

func RandPerm(n int) []int {
	return grand.RandPerm(n)
}

//----------------------------------------
// Rand methods

func (r *Rand) Seed(seed int64) {
	r.Lock()
	r.reset(seed)
	r.Unlock()
}

// Constructs an alphanumeric string of given length.
// It is not safe for cryptographic usage.
func (r *Rand) RandStr(length int) string {
	chars := []byte{}
MAIN_LOOP:
	for {
		val := r.RandInt63()
		for i := 0; i < 10; i++ {
			v := int(val & 0x3f) // rightmost 6 bits
			if v >= 62 {         // only 62 characters in strChars
				val >>= 6
				continue
			} else {
				chars = append(chars, strChars[v])
				if len(chars) == length {
					break MAIN_LOOP
				}
				val >>= 6
			}
		}
	}

	return string(chars)
}

// It is not safe for cryptographic usage.
func (r *Rand) RandUint16() uint16 {
	return uint16(r.RandUint32() & (1<<16 - 1))
}

// It is not safe for cryptographic usage.
func (r *Rand) RandUint32() uint32 {
	r.Lock()
	u32 := r.Uint32()
	r.Unlock()
	return u32
}

// It is not safe for cryptographic usage.
func (r *Rand) RandUint64() uint64 {
	return uint64(r.RandUint32())<<32 + uint64(r.RandUint32())
}

// It is not safe for cryptographic usage.
func (r *Rand) RandUint() uint {
	r.Lock()
	i := r.Int()
	r.Unlock()
	return uint(i)
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt16() int16 {
	return int16(r.RandUint32() & (1<<16 - 1))
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt32() int32 {
	return int32(r.RandUint32())
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt64() int64 {
	return int64(r.RandUint64())
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt() int {
	r.Lock()
	i := r.Int()
	r.Unlock()
	return i
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt31() int32 {
	r.Lock()
	i31 := r.Int31()
	r.Unlock()
	return i31
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt63() int64 {
	r.Lock()
	i63 := r.Int63()
	r.Unlock()
	return i63
}

// Distributed pseudo-exponentially to test for various cases
// It is not safe for cryptographic usage.
func (r *Rand) RandUint16Exp() uint16 {
	bits := r.RandUint32() % 16
	if bits == 0 {
		return 0
	}
	n := uint16(1 << (bits - 1))
	n += uint16(r.RandInt31()) & ((1 << (bits - 1)) - 1)
	return n
}

// Distributed pseudo-exponentially to test for various cases
// It is not safe for cryptographic usage.
func (r *Rand) RandUint32Exp() uint32 {
	bits := r.RandUint32() % 32
	if bits == 0 {
		return 0
	}
	n := uint32(1 << (bits - 1))
	n += uint32(r.RandInt31()) & ((1 << (bits - 1)) - 1)
	return n
}

// Distributed pseudo-exponentially to test for various cases
// It is not safe for cryptographic usage.
func (r *Rand) RandUint64Exp() uint64 {
	bits := r.RandUint32() % 64
	if bits == 0 {
		return 0
	}
	n := uint64(1 << (bits - 1))
	n += uint64(r.RandInt63()) & ((1 << (bits - 1)) - 1)
	return n
}

// It is not safe for cryptographic usage.
func (r *Rand) RandFloat32() float32 {
	r.Lock()
	f32 := r.Float32()
	r.Unlock()
	return f32
}

// It is not safe for cryptographic usage.
func (r *Rand) RandTime() time.Time {
	return time.Unix(int64(r.RandUint64Exp()), 0)
}

// RandBytes returns n random bytes from the OS's source of entropy ie. via crypto/rand.
// It is not safe for cryptographic usage.
func (r *Rand) RandBytes(n int) []byte {
	// cRandBytes isn't guaranteed to be fast so instead
	// use random bytes generated from the internal PRNG
	bs := make([]byte, n)
	for i := 0; i < len(bs); i++ {
		bs[i] = byte(r.RandInt() & 0xFF)
	}
	return bs
}

// RandIntn returns, as an int, a non-negative pseudo-random number in [0, n).
// It panics if n <= 0.
// It is not safe for cryptographic usage.
func (r *Rand) RandIntn(n int) int {
	r.Lock()
	i := r.Intn(n)
	r.Unlock()
	return i
}

// RandPerm returns a pseudo-random permutation of n integers in [0, n).
// It is not safe for cryptographic usage.
func (r *Rand) RandPerm(n int) []int {
	r.Lock()
	perm := r.Perm(n)
	r.Unlock()
	return perm
}

// NOTE: This relies on the os's random number generator.
// For real security, we should salt that with some seed.
// See github.com/tendermint/go-crypto for a more secure reader.
func cRandBytes(numBytes int) []byte {
	b := make([]byte, numBytes)
	_, err := crand.Read(b)
	if err != nil {
		PanicCrisis(err)
	}
	return b
}
<commit_msg>New -> NewRand<commit_after>package common

import (
	crand "crypto/rand"
	mrand "math/rand"
	"sync"
	"time"
)

const (
	strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
)

// pseudo random number generator.
// seeded with OS randomness (crand)

type Rand struct {
	sync.Mutex
	*mrand.Rand
}

var grand *Rand

func init() {
	grand = NewRand()
	grand.init()
}

func NewRand() *Rand {
	rand := &Rand{}
	rand.init()
	return rand
}

func (r *Rand) init() {
	bz := cRandBytes(8)
	var seed uint64
	for i := 0; i < 8; i++ {
		seed |= uint64(bz[i])
		seed <<= 8
	}
	r.reset(int64(seed))
}

func (r *Rand) reset(seed int64) {
	r.Rand = mrand.New(mrand.NewSource(seed))
}

//----------------------------------------
// Global functions

func Seed(seed int64) {
	grand.Seed(seed)
}

func RandStr(length int) string {
	return grand.RandStr(length)
}

func RandUint16() uint16 {
	return grand.RandUint16()
}

func RandUint32() uint32 {
	return grand.RandUint32()
}

func RandUint64() uint64 {
	return grand.RandUint64()
}

func RandUint() uint {
	return grand.RandUint()
}

func RandInt16() int16 {
	return grand.RandInt16()
}

func RandInt32() int32 {
	return grand.RandInt32()
}

func RandInt64() int64 {
	return grand.RandInt64()
}

func RandInt() int {
	return grand.RandInt()
}

func RandInt31() int32 {
	return grand.RandInt31()
}

func RandInt63() int64 {
	return grand.RandInt63()
}

func RandUint16Exp() uint16 {
	return grand.RandUint16Exp()
}

func RandUint32Exp() uint32 {
	return grand.RandUint32Exp()
}

func RandUint64Exp() uint64 {
	return grand.RandUint64Exp()
}

func RandFloat32() float32 {
	return grand.RandFloat32()
}

func RandTime() time.Time {
	return grand.RandTime()
}

func RandBytes(n int) []byte {
	return grand.RandBytes(n)
}

func RandIntn(n int) int {
	return grand.RandIntn(n)
}

func RandPerm(n int) []int {
	return grand.RandPerm(n)
}

//----------------------------------------
// Rand methods

func (r *Rand) Seed(seed int64) {
	r.Lock()
	r.reset(seed)
	r.Unlock()
}

// Constructs an alphanumeric string of given length.
// It is not safe for cryptographic usage.
func (r *Rand) RandStr(length int) string {
	chars := []byte{}
MAIN_LOOP:
	for {
		val := r.RandInt63()
		for i := 0; i < 10; i++ {
			v := int(val & 0x3f) // rightmost 6 bits
			if v >= 62 {         // only 62 characters in strChars
				val >>= 6
				continue
			} else {
				chars = append(chars, strChars[v])
				if len(chars) == length {
					break MAIN_LOOP
				}
				val >>= 6
			}
		}
	}

	return string(chars)
}

// It is not safe for cryptographic usage.
func (r *Rand) RandUint16() uint16 {
	return uint16(r.RandUint32() & (1<<16 - 1))
}

// It is not safe for cryptographic usage.
func (r *Rand) RandUint32() uint32 {
	r.Lock()
	u32 := r.Uint32()
	r.Unlock()
	return u32
}

// It is not safe for cryptographic usage.
func (r *Rand) RandUint64() uint64 {
	return uint64(r.RandUint32())<<32 + uint64(r.RandUint32())
}

// It is not safe for cryptographic usage.
func (r *Rand) RandUint() uint {
	r.Lock()
	i := r.Int()
	r.Unlock()
	return uint(i)
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt16() int16 {
	return int16(r.RandUint32() & (1<<16 - 1))
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt32() int32 {
	return int32(r.RandUint32())
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt64() int64 {
	return int64(r.RandUint64())
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt() int {
	r.Lock()
	i := r.Int()
	r.Unlock()
	return i
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt31() int32 {
	r.Lock()
	i31 := r.Int31()
	r.Unlock()
	return i31
}

// It is not safe for cryptographic usage.
func (r *Rand) RandInt63() int64 {
	r.Lock()
	i63 := r.Int63()
	r.Unlock()
	return i63
}

// Distributed pseudo-exponentially to test for various cases
// It is not safe for cryptographic usage.
func (r *Rand) RandUint16Exp() uint16 {
	bits := r.RandUint32() % 16
	if bits == 0 {
		return 0
	}
	n := uint16(1 << (bits - 1))
	n += uint16(r.RandInt31()) & ((1 << (bits - 1)) - 1)
	return n
}

// Distributed pseudo-exponentially to test for various cases
// It is not safe for cryptographic usage.
func (r *Rand) RandUint32Exp() uint32 {
	bits := r.RandUint32() % 32
	if bits == 0 {
		return 0
	}
	n := uint32(1 << (bits - 1))
	n += uint32(r.RandInt31()) & ((1 << (bits - 1)) - 1)
	return n
}

// Distributed pseudo-exponentially to test for various cases
// It is not safe for cryptographic usage.
func (r *Rand) RandUint64Exp() uint64 {
	bits := r.RandUint32() % 64
	if bits == 0 {
		return 0
	}
	n := uint64(1 << (bits - 1))
	n += uint64(r.RandInt63()) & ((1 << (bits - 1)) - 1)
	return n
}

// It is not safe for cryptographic usage.
func (r *Rand) RandFloat32() float32 {
	r.Lock()
	f32 := r.Float32()
	r.Unlock()
	return f32
}

// It is not safe for cryptographic usage.
func (r *Rand) RandTime() time.Time {
	return time.Unix(int64(r.RandUint64Exp()), 0)
}

// RandBytes returns n random bytes from the OS's source of entropy ie. via crypto/rand.
// It is not safe for cryptographic usage.
func (r *Rand) RandBytes(n int) []byte {
	// cRandBytes isn't guaranteed to be fast so instead
	// use random bytes generated from the internal PRNG
	bs := make([]byte, n)
	for i := 0; i < len(bs); i++ {
		bs[i] = byte(r.RandInt() & 0xFF)
	}
	return bs
}

// RandIntn returns, as an int, a non-negative pseudo-random number in [0, n).
// It panics if n <= 0.
// It is not safe for cryptographic usage.
func (r *Rand) RandIntn(n int) int {
	r.Lock()
	i := r.Intn(n)
	r.Unlock()
	return i
}

// RandPerm returns a pseudo-random permutation of n integers in [0, n).
// It is not safe for cryptographic usage.
func (r *Rand) RandPerm(n int) []int {
	r.Lock()
	perm := r.Perm(n)
	r.Unlock()
	return perm
}

// NOTE: This relies on the os's random number generator.
// For real security, we should salt that with some seed.
// See github.com/tendermint/go-crypto for a more secure reader.
func cRandBytes(numBytes int) []byte {
	b := make([]byte, numBytes)
	_, err := crand.Read(b)
	if err != nil {
		PanicCrisis(err)
	}
	return b
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// server runs a waterfall gRPC server
package main

import (
	"crypto/tls"
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/google/waterfall/golang/constants"
	"github.com/google/waterfall/golang/mux"
	"github.com/google/waterfall/golang/net/qemu"
	"github.com/google/waterfall/golang/server"
	"github.com/google/waterfall/golang/utils"
	waterfall_grpc_pb "github.com/google/waterfall/proto/waterfall_go_grpc"
	"github.com/mdlayher/vsock"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	_ "google.golang.org/grpc/encoding/gzip"
)

var (
	addr = flag.String(
		"addr", "qemu-guest:sockets/h2o", "Where to start listening. <qemu|qemu2|tcp|unix|mux>:addr."+
			" If qemu is specified, addr is the name of the pipe socket."+
			" If mux addr is a file descriptor which is used to create mulitplexed connections.")
	sessionID = flag.String(
		"session_id", "", "Only accept requests with this string in x-session-id header."+
			" If empty, allow all requests.")

	cert       = flag.String("cert", "", "The path to the server certificate")
	privateKey = flag.String("private_key", "", "Path to the server private key")
	daemon     = flag.Bool("daemon", false, "If true the server runs in daemon mode")
)

func makeCredentials(cert, privateKey string) (credentials.TransportCredentials, error) {
	crt, err := tls.LoadX509KeyPair(cert, privateKey)
	if err != nil {
		return nil, err
	}

	return credentials.NewTLS(&tls.Config{Certificates: []tls.Certificate{crt}}), nil
}

func forkInDaemonMode(path string, paddr *utils.ParsedAddr, sessionID, cert, privateKey string) error {
	a := fmt.Sprintf("%s:%s", paddr.Kind, paddr.Addr)
	ef := []*os.File{}
	if paddr.Kind == utils.TCP {
		// allocate port before forking to avoid race conditions
		// this is specially useful for situations where port is unknown (i.e :0)
		// This way we can pick port here and hand it to the child.
		// This way child doesent need to talk to the parent.
		lis, err := net.Listen("tcp", paddr.Addr)
		if err != nil {
			return err
		}

		l, _ := lis.(*net.TCPListener)

		pts := strings.Split(l.Addr().String(), ":")
		fmt.Printf("Waterfall server port: [%s]\n", pts[len(pts)-1])
		f, err := l.File()
		if err != nil {
			return err
		}
		a = "fd:3"
		ef = append(ef, f)
	}

	cmd := exec.Command(
		path, "-addr", a, "-daemon=false", "-session_id", sessionID, "-cert", cert, "-private_key", privateKey)
	cmd.ExtraFiles = ef
	return cmd.Start()
}

func main() {
	flag.Parse()

	// do not chown - owners and groups will not be valid.
	// adb will always create files with 0644 permission
	syscall.Umask(0)

	log.SetPrefix("waterfall: ")
	log.Println("Starting waterfall server ...")

	if *addr == "" {
		log.Fatalf("Need to specify -addr.")
	}

	var lis net.Listener
	var err error

	pa, err := utils.ParseAddr(*addr)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("Starting %s:%s\n", pa.Kind, pa.Addr)
	if *daemon {
		if err := forkInDaemonMode(os.Args[0], pa, *sessionID, *cert, *privateKey); err != nil {
			log.Fatalf("Failed to start waterfall in daemon mode: %v", err)
		}
		return
	}

	switch pa.Kind {
	case utils.QemuGuest:
		pip, err := qemu.MakePipe(pa.SocketName)
		if err != nil {
			log.Fatalf("failed to open qemu_pipe %v", err)
		}
		lis = qemu.MakePipeConnBuilder(pip)
	case utils.QemuCtrl:
		pip, err := qemu.MakePipe(pa.SocketName)
		if err != nil {
			log.Fatalf("failed to open qemu_pipe %v", err)
		}
		lis = qemu.MakeControlSocket(pip)
	case utils.VsockGuest:
		p, err := strconv.Atoi(pa.SocketName)
		if err != nil {
			log.Fatalf("Failed to parse vsock: %v", pa)
		}
		lis, err = vsock.ListenAny(uint32(p))
		if err != nil {
			log.Fatalf("failed to open vsock %v", err)
		}
	case utils.Unix:
		fallthrough
	case utils.TCP:
		lis, err = net.Listen(pa.Kind, pa.Addr)
		if err != nil {
			log.Fatalf("Failed to listen %v", err)
		}
	case utils.FD:
		lis, err = net.FileListener(os.NewFile(uintptr(pa.FD), ""))
		if err != nil {
			log.Fatalf("Failed to create fd listener %v", err)
		}
	case utils.Mux:
		lis = mux.NewListener(os.NewFile(uintptr(pa.MuxAddr.FD), ""))
	default:
		log.Fatalf("Unsupported kind %s", pa.Kind)
	}
	defer lis.Close()

	options := []grpc.ServerOption{
		grpc.WriteBufferSize(constants.WriteBufferSize),
		// Don't timeout connections (1 year timeout)
		grpc.ConnectionTimeout(8760 * time.Hour),
	}
	if *cert != "" || *privateKey != "" {
		if *cert == "" || *privateKey == "" {
			log.Fatal("Need to specify -cert and -private_key")
		}

		creds, err := makeCredentials(*cert, *privateKey)
		if err != nil {
			log.Fatalf("failed to create tls credentials")
		}
		options = append(options, grpc.Creds(creds))
	} else {
		log.Println("Warning! running unsecure server ...")
	}

	if *sessionID != "" {
		log.Println("Verifying session ID for all requests.")
		ai := server.NewAuthInterceptor(*sessionID)
		options = append(
			options,
			grpc.UnaryInterceptor(ai.UnaryServerInterceptor),
			grpc.StreamInterceptor(ai.StreamServerInterceptor))
	}

	grpcServer := grpc.NewServer(options...)
	waterfall_grpc_pb.RegisterWaterfallServer(grpcServer, server.New())

	log.Println("Serving ...")
	if err := grpcServer.Serve(lis); err != nil {
		log.Printf("Unable to serve! %v", err)
	}
}
<commit_msg>Send Waterfall server logs to the kernel log when possible.<commit_after>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// server runs a waterfall gRPC server
package main

import (
	"crypto/tls"
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/google/waterfall/golang/constants"
	"github.com/google/waterfall/golang/mux"
	"github.com/google/waterfall/golang/net/qemu"
	"github.com/google/waterfall/golang/server"
	"github.com/google/waterfall/golang/utils"
	waterfall_grpc_pb "github.com/google/waterfall/proto/waterfall_go_grpc"
	"github.com/mdlayher/vsock"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	_ "google.golang.org/grpc/encoding/gzip"
)

var (
	addr = flag.String(
		"addr", "qemu-guest:sockets/h2o", "Where to start listening. <qemu|qemu2|tcp|unix|mux>:addr."+
			" If qemu is specified, addr is the name of the pipe socket."+
			" If mux addr is a file descriptor which is used to create mulitplexed connections.")
	sessionID = flag.String(
		"session_id", "", "Only accept requests with this string in x-session-id header."+
			" If empty, allow all requests.")

	cert       = flag.String("cert", "", "The path to the server certificate")
	privateKey = flag.String("private_key", "", "Path to the server private key")
	daemon     = flag.Bool("daemon", false, "If true the server runs in daemon mode")
)

func makeCredentials(cert, privateKey string) (credentials.TransportCredentials, error) {
	crt, err := tls.LoadX509KeyPair(cert, privateKey)
	if err != nil {
		return nil, err
	}

	return credentials.NewTLS(&tls.Config{Certificates: []tls.Certificate{crt}}), nil
}

func forkInDaemonMode(path string, paddr *utils.ParsedAddr, sessionID, cert, privateKey string) error {
	a := fmt.Sprintf("%s:%s", paddr.Kind, paddr.Addr)
	ef := []*os.File{}
	if paddr.Kind == utils.TCP {
		// allocate port before forking to avoid race conditions
		// this is specially useful for situations where port is unknown (i.e :0)
		// This way we can pick port here and hand it to the child.
		// This way child doesent need to talk to the parent.
		lis, err := net.Listen("tcp", paddr.Addr)
		if err != nil {
			return err
		}

		l, _ := lis.(*net.TCPListener)

		pts := strings.Split(l.Addr().String(), ":")
		fmt.Printf("Waterfall server port: [%s]\n", pts[len(pts)-1])
		f, err := l.File()
		if err != nil {
			return err
		}
		a = "fd:3"
		ef = append(ef, f)
	}

	cmd := exec.Command(
		path, "-addr", a, "-daemon=false", "-session_id", sessionID, "-cert", cert, "-private_key", privateKey)
	cmd.ExtraFiles = ef
	return cmd.Start()
}

func main() {
	flag.Parse()

	// do not chown - owners and groups will not be valid.
	// adb will always create files with 0644 permission
	syscall.Umask(0)

	log.SetPrefix("waterfall: ")
	// Log to the Kernel logs if possible
	// This requires "file /dev/kmsg w" to be in the Waterfall service definition
	if kmsgFd := os.Getenv("ANDROID_FILE__dev_kmsg"); kmsgFd != "" {
		fd, err := strconv.Atoi(kmsgFd)
		if err == nil {
			log.SetOutput(os.NewFile(uintptr(fd), "/dev/kmsg"))
		}
	}
	log.Println("Starting waterfall server ...")

	if *addr == "" {
		log.Fatalf("Need to specify -addr.")
	}

	var lis net.Listener
	var err error

	pa, err := utils.ParseAddr(*addr)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("Starting %s:%s\n", pa.Kind, pa.Addr)
	if *daemon {
		if err := forkInDaemonMode(os.Args[0], pa, *sessionID, *cert, *privateKey); err != nil {
			log.Fatalf("Failed to start waterfall in daemon mode: %v", err)
		}
		return
	}

	switch pa.Kind {
	case utils.QemuGuest:
		pip, err := qemu.MakePipe(pa.SocketName)
		if err != nil {
			log.Fatalf("failed to open qemu_pipe %v", err)
		}
		lis = qemu.MakePipeConnBuilder(pip)
	case utils.QemuCtrl:
		pip, err := qemu.MakePipe(pa.SocketName)
		if err != nil {
			log.Fatalf("failed to open qemu_pipe %v", err)
		}
		lis = qemu.MakeControlSocket(pip)
	case utils.VsockGuest:
		p, err := strconv.Atoi(pa.SocketName)
		if err != nil {
			log.Fatalf("Failed to parse vsock: %v", pa)
		}
		lis, err = vsock.ListenAny(uint32(p))
		if err != nil {
			log.Fatalf("failed to open vsock %v", err)
		}
	case utils.Unix:
		fallthrough
	case utils.TCP:
		lis, err = net.Listen(pa.Kind, pa.Addr)
		if err != nil {
			log.Fatalf("Failed to listen %v", err)
		}
	case utils.FD:
		lis, err = net.FileListener(os.NewFile(uintptr(pa.FD), ""))
		if err != nil {
			log.Fatalf("Failed to create fd listener %v", err)
		}
	case utils.Mux:
		lis = mux.NewListener(os.NewFile(uintptr(pa.MuxAddr.FD), ""))
	default:
		log.Fatalf("Unsupported kind %s", pa.Kind)
	}
	defer lis.Close()

	options := []grpc.ServerOption{
		grpc.WriteBufferSize(constants.WriteBufferSize),
		// Don't timeout connections (1 year timeout)
		grpc.ConnectionTimeout(8760 * time.Hour),
	}
	if *cert != "" || *privateKey != "" {
		if *cert == "" || *privateKey == "" {
			log.Fatal("Need to specify -cert and -private_key")
		}

		creds, err := makeCredentials(*cert, *privateKey)
		if err != nil {
			log.Fatalf("failed to create tls credentials")
		}
		options = append(options, grpc.Creds(creds))
	} else {
		log.Println("Warning! running unsecure server ...")
	}

	if *sessionID != "" {
		log.Println("Verifying session ID for all requests.")
		ai := server.NewAuthInterceptor(*sessionID)
		options = append(
			options,
			grpc.UnaryInterceptor(ai.UnaryServerInterceptor),
			grpc.StreamInterceptor(ai.StreamServerInterceptor))
	}

	grpcServer := grpc.NewServer(options...)
	waterfall_grpc_pb.RegisterWaterfallServer(grpcServer, server.New())

	log.Println("Serving ...")
	if err := grpcServer.Serve(lis); err != nil {
		log.Printf("Unable to serve! %v", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"strings"
	"testing"
	"time"
)

var catBinary string
var trueBinary string
var falseBinary string

func init() {
	for _, s := range []string{"/bin/true"} {
		if _, err := os.Stat(s); err == nil {
			trueBinary = s
			break
		}
	}
	for _, s := range []string{"/bin/false"} {
		if _, err := os.Stat(s); err == nil {
			falseBinary = s
			break
		}
	}
	for _, s := range []string{"/bin/cat"} {
		if _, err := os.Stat(s); err == nil {
			catBinary = s
			break
		}
	}
}

func checkedWait(t *testing.T, instance *Instance) error {
	ch := make(chan error, 1)
	go func() {
		ch <- instance.Wait()
	}()
	err := instance.Wait()
	if err1 := <-ch; err1 != err {
		t.Errorf("Instance.Wait() gave contradictory return values: %v != %v", err, err1)
	}
	return err
}

func TestInstanceSuccess(t *testing.T) {
	if trueBinary == "" {
		t.Skip("no /bin/true equivalent found")
	}
	instance := &Instance{ID: 0, TotalInstances: 1, Cmd: exec.Command(trueBinary)}
	if err := instance.Start(); err != nil {
		t.Fatalf("error starting an instance of %s: %v", trueBinary, err)
	}
	if err := checkedWait(t, instance); err != nil {
		t.Fatalf("error running %s: %v", trueBinary, err)
	}
}

func TestInstanceFailure(t *testing.T) {
	if falseBinary == "" {
		t.Skip("no /bin/false equivalent found")
	}
	instance := &Instance{ID: 0, TotalInstances: 1, Cmd: exec.Command(falseBinary)}
	if err := instance.Start(); err != nil {
		t.Fatalf("error starting an instance of %s: %v", falseBinary, err)
	}
	if err := checkedWait(t, instance); err == nil {
		t.Fatalf("no error when running %s", falseBinary)
	}
}

func TestInstanceKill(t *testing.T) {
	if catBinary == "" {
		t.Skip("no /bin/cat equivalent found")
	}
	cmd := exec.Command(catBinary)
	if _, err := cmd.StdinPipe(); err != nil {
		t.Fatalf("error in Cmd.StdinPipe: %v", err)
	}
	cmd.Stdout = ioutil.Discard
	instance := &Instance{ID: 0, TotalInstances: 1, Cmd: cmd}
	if err := instance.Start(); err != nil {
		t.Fatalf("error starting an instance of %s: %v", falseBinary, err)
	}
	waitChan := make(chan error)
	go func() {
		waitChan <- checkedWait(t, instance)
	}()
	// The instance shouldn't finish of its own accord
	select {
	case err := <-waitChan:
		t.Fatalf("/bin/cat has finished prematurely, err=%v", err)
	case <-time.After(100 * time.Millisecond):
	}
	instance.Kill()
	if err := <-waitChan; err != ErrKilled {
		t.Errorf("a killed instance has finished with error %v, instead of %v", err, ErrKilled)
	}
}

func TestInstanceComm(t *testing.T) {
	testerBinary := filepath.Join("zeus", "tester")
	if _, err := os.Stat(testerBinary); err != nil {
		t.Skipf("%s not found", testerBinary)
	}
	type testcase struct {
		name             string
		input            string
		expectedOutput   string
		expectedRequests []*request // expectedRequests[].time is a lower bound on the actual time
		responses        []*response
	}
	singleCase := func(tc testcase) {
		quit := make(chan bool)

		cmd := exec.Command(testerBinary)
		cmd.Stdin = strings.NewReader(tc.input)
		var stdout bytes.Buffer
		cmd.Stdout = &stdout
		instance := &Instance{
			ID:             5,
			TotalInstances: 20,
			Cmd:            cmd,
			RequestChan:    make(chan *request, 1),
			ResponseChan:   make(chan *response, 1),
		}
		if err := instance.Start(); err != nil {
			t.Errorf("test %s: error starting an instance of %s: %v", tc.name, testerBinary, err)
			return
		}

		go func() {
			var prevTime time.Duration
			var i int
			for req := range instance.RequestChan {
				if req.time < prevTime {
					t.Errorf("test %s: request %+v is earlier than %v, the time of the previous request", tc.name, req, prevTime)
				}
				if i < len(tc.expectedRequests) {
					if req.time < tc.expectedRequests[i].time {
						t.Errorf("test %s: request %+v has time %v, expected at least %v", tc.name, req, req.time, tc.expectedRequests[i].time)
					}
					realTime := req.time
					req.time = tc.expectedRequests[i].time
					if got, want := req, tc.expectedRequests[i]; !reflect.DeepEqual(got, want) {
						got.time = realTime
						t.Errorf("test %s: got request %+v, expected %+v", tc.name, got, want)
					}
				} else {
					t.Errorf("test %s: got request number %d, expected %d total", i, len(tc.expectedRequests))
				}
				i++
			}
			if i < len(tc.expectedRequests) {
				t.Errorf("test %s: got only %d requests, expected %d", i, len(tc.expectedRequests))
			}
			<-quit
		}()
		go func() {
			for i, resp := range tc.responses {
				select {
				case instance.ResponseChan <- resp:
				case <-quit:
					t.Errorf("test %s: instance was done before receiving response number %d", tc.name, i)
					return
				}
			}
			<-quit
		}()
		defer func() {
			quit <- true
			quit <- true
		}()

		if err := checkedWait(t, instance); err != nil {
			t.Fatalf("test %s: error running an instance of %s: %v", tc.name, testerBinary, err)
			return
		}
		close(instance.RequestChan)
		if got, want := stdout.String(), tc.expectedOutput; got != want {
			t.Errorf("test %s: wrong output; got=%q, want=%q", tc.name, got, want)
		}
	}
	testcases := []testcase{
		{"header", "", "5 20\n", []*request{}, []*response{}},
		{"send", "Scfoobar\n", "5 20\n", []*request{&request{requestType: requestSend, destination: 2, message: []byte("foobar")}}, []*response{}},
		{"recv", "Rd\n", "5 20\n3 6 foobaz\n", []*request{&request{requestType: requestRecv, source: 3}}, []*response{&response{&Message{Source: 3, Target: 5, Message: []byte("foobaz")}}}},
		{"recvany", "R*\n", "5 20\n3 6 foobaz\n", []*request{&request{requestType: requestRecvAny}}, []*response{&response{&Message{Source: 3, Target: 5, Message: []byte("foobaz")}}}},
		{"blockingTime", "R*\nScblah\n", "5 20\n3 6 foobaz\n", []*request{
			&request{requestType: requestRecvAny},
			&request{requestType: requestSend, time: time.Duration(1234), destination: 2, message: []byte("blah")},
		}, []*response{&response{&Message{Source: 3, Target: 5, SendTime: time.Duration(1234), Message: []byte("foobaz")}}}},
	}

	for _, tc := range testcases {
		singleCase(tc)
	}
}

// Stop receiving in the middle of a message
func TestInstanceBrokenPipe(t *testing.T) {
	hangerBinary := filepath.Join("zeus", "hanger")
	if _, err := os.Stat(hangerBinary); err != nil {
		t.Skipf("%s not found", hangerBinary)
	}
	cmd := exec.Command(hangerBinary)
	instance := &Instance{
		ID:             0,
		TotalInstances: 2,
		Cmd:            cmd,
		RequestChan:    make(chan *request, 1),
		ResponseChan:   make(chan *response, 1),
	}
	if err := instance.Start(); err != nil {
		t.Fatalf("error starting an instance of %s: %v", hangerBinary, err)
	}
	go func() {
		for _ = range instance.RequestChan {
		}
	}()
	defer close(instance.RequestChan)
	instance.ResponseChan <- &response{&Message{
		Source:   1,
		Target:   0,
		SendTime: time.Duration(0),
		Message:  []byte("abcdefghijlkmnopqrstuvwxyz"), // this message will take >20 bytes on the wire
	}}
	if err := checkedWait(t, instance); err != nil {
		t.Fatalf("error running an instance of %s: %v", hangerBinary, err)
	}
}
<commit_msg>fix error printfs in instance_test<commit_after>package main

import (
	"bytes"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"strings"
	"testing"
	"time"
)

var catBinary string
var trueBinary string
var falseBinary string

func init() {
	for _, s := range []string{"/bin/true"} {
		if _, err := os.Stat(s); err == nil {
			trueBinary = s
			break
		}
	}
	for _, s := range []string{"/bin/false"} {
		if _, err := os.Stat(s); err == nil {
			falseBinary = s
			break
		}
	}
	for _, s := range []string{"/bin/cat"} {
		if _, err := os.Stat(s); err == nil {
			catBinary = s
			break
		}
	}
}

func checkedWait(t *testing.T, instance *Instance) error {
	ch := make(chan error, 1)
	go func() {
		ch <- instance.Wait()
	}()
	err := instance.Wait()
	if err1 := <-ch; err1 != err {
		t.Errorf("Instance.Wait() gave contradictory return values: %v != %v", err, err1)
	}
	return err
}

func TestInstanceSuccess(t *testing.T) {
	if trueBinary == "" {
		t.Skip("no /bin/true equivalent found")
	}
	instance := &Instance{ID: 0, TotalInstances: 1, Cmd: exec.Command(trueBinary)}
	if err := instance.Start(); err != nil {
		t.Fatalf("error starting an instance of %s: %v", trueBinary, err)
	}
	if err := checkedWait(t, instance); err != nil {
		t.Fatalf("error running %s: %v", trueBinary, err)
	}
}

func TestInstanceFailure(t *testing.T) {
	if falseBinary == "" {
		t.Skip("no /bin/false equivalent found")
	}
	instance := &Instance{ID: 0, TotalInstances: 1, Cmd: exec.Command(falseBinary)}
	if err := instance.Start(); err != nil {
		t.Fatalf("error starting an instance of %s: %v", falseBinary, err)
	}
	if err := checkedWait(t, instance); err == nil {
		t.Fatalf("no error when running %s", falseBinary)
	}
}

func TestInstanceKill(t *testing.T) {
	if catBinary == "" {
		t.Skip("no /bin/cat equivalent found")
	}
	cmd := exec.Command(catBinary)
	if _, err := cmd.StdinPipe(); err != nil {
		t.Fatalf("error in Cmd.StdinPipe: %v", err)
	}
	cmd.Stdout = ioutil.Discard
	instance := &Instance{ID: 0, TotalInstances: 1, Cmd: cmd}
	if err := instance.Start(); err != nil {
		t.Fatalf("error starting an instance of %s: %v", falseBinary, err)
	}
	waitChan := make(chan error)
	go func() {
		waitChan <- checkedWait(t, instance)
	}()
	// The instance shouldn't finish of its own accord
	select {
	case err := <-waitChan:
		t.Fatalf("/bin/cat has finished prematurely, err=%v", err)
	case <-time.After(100 * time.Millisecond):
	}
	instance.Kill()
	if err := <-waitChan; err != ErrKilled {
		t.Errorf("a killed instance has finished with error %v, instead of %v", err, ErrKilled)
	}
}

func TestInstanceComm(t *testing.T) {
	testerBinary := filepath.Join("zeus", "tester")
	if _, err := os.Stat(testerBinary); err != nil {
		t.Skipf("%s not found", testerBinary)
	}
	type testcase struct {
		name             string
		input            string
		expectedOutput   string
		expectedRequests []*request // expectedRequests[].time is a lower bound on the actual time
		responses        []*response
	}
	singleCase := func(tc testcase) {
		quit := make(chan bool)

		cmd := exec.Command(testerBinary)
		cmd.Stdin = strings.NewReader(tc.input)
		var stdout bytes.Buffer
		cmd.Stdout = &stdout
		instance := &Instance{
			ID:             5,
			TotalInstances: 20,
			Cmd:            cmd,
			RequestChan:    make(chan *request, 1),
			ResponseChan:   make(chan *response, 1),
		}
		if err := instance.Start(); err != nil {
			t.Errorf("test %s: error starting an instance of %s: %v", tc.name, testerBinary, err)
			return
		}

		go func() {
			var prevTime time.Duration
			var i int
			for req := range instance.RequestChan {
				if req.time < prevTime {
					t.Errorf("test %s: request %+v is earlier than %v, the time of the previous request", tc.name, req, prevTime)
				}
				if i < len(tc.expectedRequests) {
					if req.time < tc.expectedRequests[i].time {
						t.Errorf("test %s: request %+v has time %v, expected at least %v", tc.name, req, req.time, tc.expectedRequests[i].time)
					}
					realTime := req.time
					req.time = tc.expectedRequests[i].time
					if got, want := req, tc.expectedRequests[i]; !reflect.DeepEqual(got, want) {
						got.time = realTime
						t.Errorf("test %s: got request %+v, expected %+v", tc.name, got, want)
					}
				} else {
					t.Errorf("test %s: got request number %d, expected %d total", tc.name, i, len(tc.expectedRequests))
				}
				i++
			}
			if i < len(tc.expectedRequests) {
				t.Errorf("test %s: got only %d requests, expected %d", tc.name, i, len(tc.expectedRequests))
			}
			<-quit
		}()
		go func() {
			for i, resp := range tc.responses {
				select {
				case instance.ResponseChan <- resp:
				case <-quit:
					t.Errorf("test %s: instance was done before receiving response number %d", tc.name, i)
					return
				}
			}
			<-quit
		}()
		defer func() {
			quit <- true
			quit <- true
		}()

		if err := checkedWait(t, instance); err != nil {
			t.Fatalf("test %s: error running an instance of %s: %v", tc.name, testerBinary, err)
			return
		}
		close(instance.RequestChan)
		if got, want := stdout.String(), tc.expectedOutput; got != want {
			t.Errorf("test %s: wrong output; got=%q, want=%q", tc.name, got, want)
		}
	}
	testcases := []testcase{
		{"header", "", "5 20\n", []*request{}, []*response{}},
		{"send", "Scfoobar\n", "5 20\n", []*request{&request{requestType: requestSend, destination: 2, message: []byte("foobar")}}, []*response{}},
		{"recv", "Rd\n", "5 20\n3 6 foobaz\n", []*request{&request{requestType: requestRecv, source: 3}}, []*response{&response{&Message{Source: 3, Target: 5, Message: []byte("foobaz")}}}},
		{"recvany", "R*\n", "5 20\n3 6 foobaz\n", []*request{&request{requestType: requestRecvAny}}, []*response{&response{&Message{Source: 3, Target: 5, Message: []byte("foobaz")}}}},
		{"blockingTime", "R*\nScblah\n", "5 20\n3 6 foobaz\n", []*request{
			&request{requestType: requestRecvAny},
			&request{requestType: requestSend, time: time.Duration(1234), destination: 2, message: []byte("blah")},
		}, []*response{&response{&Message{Source: 3, Target: 5, SendTime: time.Duration(1234), Message: []byte("foobaz")}}}},
	}

	for _, tc := range testcases {
		singleCase(tc)
	}
}

// Stop receiving in the middle of a message
func TestInstanceBrokenPipe(t *testing.T) {
	hangerBinary := filepath.Join("zeus", "hanger")
	if _, err := os.Stat(hangerBinary); err != nil {
		t.Skipf("%s not found", hangerBinary)
	}
	cmd := exec.Command(hangerBinary)
	instance := &Instance{
		ID:             0,
		TotalInstances: 2,
		Cmd:            cmd,
		RequestChan:    make(chan *request, 1),
		ResponseChan:   make(chan *response, 1),
	}
	if err := instance.Start(); err != nil {
		t.Fatalf("error starting an instance of %s: %v", hangerBinary, err)
	}
	go func() {
		for _ = range instance.RequestChan {
		}
	}()
	defer close(instance.RequestChan)
	instance.ResponseChan <- &response{&Message{
		Source:   1,
		Target:   0,
		SendTime: time.Duration(0),
		Message:  []byte("abcdefghijlkmnopqrstuvwxyz"), // this message will take >20 bytes on the wire
	}}
	if err := checkedWait(t, instance); err != nil {
		t.Fatalf("error running an instance of %s: %v", hangerBinary, err)
	}
}
<|endoftext|>


<commit_before>package internal

import (
	"encoding/csv"
	"errors"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"time"
)

/***** Define DataHandler interface *****/

// DataHandler is the combined data interface
type DataHandler interface {
	DataLoader
	DataStreamer
}

// DataLoader is the interface loading the data into the data stream
type DataLoader interface {
	Load([]string) error
}

// DataStreamer is the interface returning the data streams
type DataStreamer interface {
	Next() (DataEvent, bool)
	Stream() []DataEvent
	History() []DataEvent
	Latest(string) DataEvent
	List(string) []DataEvent
}

/***** Basic Data struct with implemented interface methods *****/

// Data is a basic data struct
type Data struct {
	latest        map[string]DataEvent
	list          map[string][]DataEvent
	stream        []DataEvent
	streamHistory []DataEvent
}

// Load loads data endpoints into a stream
func (d *Data) Load(s []string) error {
	return nil
}

// Stream returns the data stream
func (d *Data) Stream() []DataEvent {
	return d.stream
}

// Next returns the first element of the data stream
// deletes it from the stream and appends it to history
func (d *Data) Next() (event DataEvent, ok bool) {
	// check for element in datastream
	if len(d.stream) == 0 {
		return event, false
	}

	event = d.stream[0]
	d.stream = d.stream[1:] // delete first element from stream
	d.streamHistory = append(d.stream, event)

	// update list of current data events
	d.updateLatest(event)
	// update list of data events for single symbol
	d.updateList(event)

	return event, true
}

// History returns the historic data stream
func (d *Data) History() []DataEvent {
	return d.streamHistory
}

// Latest returns the last known data event for a symbol.
func (d *Data) Latest(symbol string) DataEvent {
	return d.latest[symbol]
}

// updateCurrent puts the last current data event to the current list.
func (d *Data) updateLatest(event DataEvent) {
	// check for nil map, else initialise the map
	if d.latest == nil {
		d.latest = make(map[string]DataEvent)
	}

	d.latest[event.Symbol()] = event
}

// List returns the data event list for a symbol.
func (d *Data) List(symbol string) []DataEvent {
	return d.list[symbol]
}

// updateList appends an event to the data list.
func (d *Data) updateList(event DataEvent) {
	// Check for nil map, else initialise the map
	if d.list == nil {
		d.list = make(map[string][]DataEvent)
	}

	d.list[event.Symbol()] = append(d.list[event.Symbol()], event)
}

// sortStream sorts the dataStream
func (d *Data) sortStream() {
	sort.Slice(d.stream, func(i, j int) bool {
		b1 := d.stream[i]
		b2 := d.stream[j]

		// if date is equal sort by symbol
		if b1.Timestamp().Equal(b2.Timestamp()) {
			return b1.Symbol() < b2.Symbol()
		}
		// else sort by date
		return b1.Timestamp().Before(b2.Timestamp())
	})
}

/***** Concrete BarEventFromCSVFileData struct *****/

// BarEventFromCSVFileData is a data struct, which loads the market data from csv files.
// It expands the underlying data struct
type BarEventFromCSVFileData struct {
	Data
	FileDir string
}

// Load loads single data endpoints into a stream ordered by date (latest first).
func (d *BarEventFromCSVFileData) Load(symbols []string) (err error) {
	// check file location
	if len(d.FileDir) == 0 {
		return errors.New("no directory for data provided: ")
	}

	// create a map for holding the file name for each symbol
	files := make(map[string]string)

	// read all files from directory
	if len(symbols) == 0 {
		files, err = fetchFilesFromDir(d.FileDir)
		if err != nil {
			return err
		}
	}

	// construct filenames for provided symbols
	for _, symbol := range symbols {
		file := symbol + ".csv"
		files[symbol] = file
	}

	// read file for each fileName
	for symbol, file := range files {
		// open file for corresponding symbol
		lines, err := readCSVFile(d.FileDir + file)
		if err != nil {
			return err
		}

		// for each found record create an event
		for _, line := range lines {
			event, err := createBarEventFromLine(line, symbol)
			if err != nil {
				log.Println(err)
			}
			d.stream = append(d.stream, event)
		}
	}

	// sort data stream
	d.sortStream()

	return nil
}

// fetchFilesFromDir returns a map of all filenames in a directory
// e.g map{"BAS.DE": "BAS.DE.csv"}
func fetchFilesFromDir(dir string) (m map[string]string, err error) {
	// read filenames from directory
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		return m, err
	}
	// read filenames from directory
	for _, file := range files {
		// file is directory
		if file.IsDir() {
			continue
		}

		filename := file.Name()
		extension := filepath.Ext(filename)
		// file is not CSV
		if extension != ".csv" {
			continue
		}

		name := filename[0 : len(filename)-len(extension)]
		m[name] = filename
	}
	return m, nil
}

// readCSVFile opens and reads a csv file line by line
// and returns a slice with a key/value map for each line
func readCSVFile(path string) (lines []map[string]string, err error) {
	// open file
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	// create scanner on top of file
	reader := csv.NewReader(file)
	// set delimeter
	reader.Comma = ','
	// read first line for keys and fill in array
	keys, err := reader.Read()

	// create a slice for holding the different maps of each line
	// var lines []map[string]string

	// read each line and create a map of values combined to the keys
	for line, err := reader.Read(); err == nil; line, err = reader.Read() {
		l := make(map[string]string)
		for i, v := range line {
			l[keys[i]] = v
		}
		// put found line as map into stream holder item
		lines = append(lines, l)
	}

	return lines, nil
}

// createBarEventFromLine takes a key/value map and a string and builds a bar struct
func createBarEventFromLine(line map[string]string, symbol string) (BarEvent, error) {
	// parse each string in line to corresponding record value
	date, _ := time.Parse("2006-01-02", line["Date"])
	openPrice, _ := strconv.ParseFloat(line["Open"], 64)
	highPrice, _ := strconv.ParseFloat(line["High"], 64)
	lowPrice, _ := strconv.ParseFloat(line["Low"], 64)
	closePrice, _ := strconv.ParseFloat(line["Close"], 64)
	adjClosePrice, _ := strconv.ParseFloat(line["Adj Close"], 64)
	volume, _ := strconv.ParseInt(line["Volume"], 10, 64)

	// create and populate new event
	event := bar{
		event:         event{timestamp: date, symbol: strings.ToUpper(symbol)},
		openPrice:     openPrice,
		highPrice:     highPrice,
		lowPrice:      lowPrice,
		closePrice:    closePrice,
		adjClosePrice: adjClosePrice,
		volume:        volume,
	}

	return event, nil
}
<commit_msg>fix nil map initialization while loading filenames<commit_after>package internal

import (
	"encoding/csv"
	"errors"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"time"
)

/***** Define DataHandler interface *****/

// DataHandler is the combined data interface
type DataHandler interface {
	DataLoader
	DataStreamer
}

// DataLoader is the interface loading the data into the data stream
type DataLoader interface {
	Load([]string) error
}

// DataStreamer is the interface returning the data streams
type DataStreamer interface {
	Next() (DataEvent, bool)
	Stream() []DataEvent
	History() []DataEvent
	Latest(string) DataEvent
	List(string) []DataEvent
}

/***** Basic Data struct with implemented interface methods *****/

// Data is a basic data struct
type Data struct {
	latest        map[string]DataEvent
	list          map[string][]DataEvent
	stream        []DataEvent
	streamHistory []DataEvent
}

// Load loads data endpoints into a stream
func (d *Data) Load(s []string) error {
	return nil
}

// Stream returns the data stream
func (d *Data) Stream() []DataEvent {
	return d.stream
}

// Next returns the first element of the data stream
// deletes it from the stream and appends it to history
func (d *Data) Next() (event DataEvent, ok bool) {
	// check for element in datastream
	if len(d.stream) == 0 {
		return event, false
	}

	event = d.stream[0]
	d.stream = d.stream[1:] // delete first element from stream
	d.streamHistory = append(d.stream, event)

	// update list of current data events
	d.updateLatest(event)
	// update list of data events for single symbol
	d.updateList(event)

	return event, true
}

// History returns the historic data stream
func (d *Data) History() []DataEvent {
	return d.streamHistory
}

// Latest returns the last known data event for a symbol.
func (d *Data) Latest(symbol string) DataEvent {
	return d.latest[symbol]
}

// updateCurrent puts the last current data event to the current list.
func (d *Data) updateLatest(event DataEvent) {
	// check for nil map, else initialise the map
	if d.latest == nil {
		d.latest = make(map[string]DataEvent)
	}

	d.latest[event.Symbol()] = event
}

// List returns the data event list for a symbol.
func (d *Data) List(symbol string) []DataEvent {
	return d.list[symbol]
}

// updateList appends an event to the data list.
func (d *Data) updateList(event DataEvent) {
	// Check for nil map, else initialise the map
	if d.list == nil {
		d.list = make(map[string][]DataEvent)
	}

	d.list[event.Symbol()] = append(d.list[event.Symbol()], event)
}

// sortStream sorts the dataStream
func (d *Data) sortStream() {
	sort.Slice(d.stream, func(i, j int) bool {
		b1 := d.stream[i]
		b2 := d.stream[j]

		// if date is equal sort by symbol
		if b1.Timestamp().Equal(b2.Timestamp()) {
			return b1.Symbol() < b2.Symbol()
		}
		// else sort by date
		return b1.Timestamp().Before(b2.Timestamp())
	})
}

/***** Concrete BarEventFromCSVFileData struct *****/

// BarEventFromCSVFileData is a data struct, which loads the market data from csv files.
// It expands the underlying data struct
type BarEventFromCSVFileData struct {
	Data
	FileDir string
}

// Load loads single data endpoints into a stream ordered by date (latest first).
func (d *BarEventFromCSVFileData) Load(symbols []string) (err error) {
	// check file location
	if len(d.FileDir) == 0 {
		return errors.New("no directory for data provided: ")
	}

	// create a map for holding the file name for each symbol
	files := make(map[string]string)

	// read all files from directory
	if len(symbols) == 0 {
		files, err = fetchFilesFromDir(d.FileDir)
		if err != nil {
			return err
		}
	}

	// construct filenames for provided symbols
	for _, symbol := range symbols {
		file := symbol + ".csv"
		files[symbol] = file
	}

	// read file for each fileName
	for symbol, file := range files {
		// open file for corresponding symbol
		lines, err := readCSVFile(d.FileDir + file)
		if err != nil {
			return err
		}

		// for each found record create an event
		for _, line := range lines {
			event, err := createBarEventFromLine(line, symbol)
			if err != nil {
				log.Println(err)
			}
			d.stream = append(d.stream, event)
		}
	}

	// sort data stream
	d.sortStream()

	return nil
}

// fetchFilesFromDir returns a map of all filenames in a directory
// e.g map{"BAS.DE": "BAS.DE.csv"}
func fetchFilesFromDir(dir string) (m map[string]string, err error) {
	// read filenames from directory
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		return m, err
	}

	// initialise the map
	m = make(map[string]string)

	// read filenames from directory
	for _, file := range files {
		// file is directory
		if file.IsDir() {
			continue
		}

		filename := file.Name()
		extension := filepath.Ext(filename)
		// file is not CSV
		if extension != ".csv" {
			continue
		}

		name := filename[0 : len(filename)-len(extension)]
		m[name] = filename
	}
	return m, nil
}

// readCSVFile opens and reads a csv file line by line
// and returns a slice with a key/value map for each line
func readCSVFile(path string) (lines []map[string]string, err error) {
	// open file
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	// create scanner on top of file
	reader := csv.NewReader(file)
	// set delimeter
	reader.Comma = ','
	// read first line for keys and fill in array
	keys, err := reader.Read()

	// create a slice for holding the different maps of each line
	// var lines []map[string]string

	// read each line and create a map of values combined to the keys
	for line, err := reader.Read(); err == nil; line, err = reader.Read() {
		l := make(map[string]string)
		for i, v := range line {
			l[keys[i]] = v
		}
		// put found line as map into stream holder item
		lines = append(lines, l)
	}

	return lines, nil
}

// createBarEventFromLine takes a key/value map and a string and builds a bar struct
func createBarEventFromLine(line map[string]string, symbol string) (BarEvent, error) {
	// parse each string in line to corresponding record value
	date, _ := time.Parse("2006-01-02", line["Date"])
	openPrice, _ := strconv.ParseFloat(line["Open"], 64)
	highPrice, _ := strconv.ParseFloat(line["High"], 64)
	lowPrice, _ := strconv.ParseFloat(line["Low"], 64)
	closePrice, _ := strconv.ParseFloat(line["Close"], 64)
	adjClosePrice, _ := strconv.ParseFloat(line["Adj Close"], 64)
	volume, _ := strconv.ParseInt(line["Volume"], 10, 64)

	// create and populate new event
	event := bar{
		event:         event{timestamp: date, symbol: strings.ToUpper(symbol)},
		openPrice:     openPrice,
		highPrice:     highPrice,
		lowPrice:      lowPrice,
		closePrice:    closePrice,
		adjClosePrice: adjClosePrice,
		volume:        volume,
	}

	return event, nil
}
<|endoftext|>


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

// +build darwin freebsd linux netbsd openbsd

package net

import (
	"testing"
)

// Issue 3590. netFd.AddFD should return an error
// from the underlying pollster rather than panicing.
func TestAddFDReturnsError(t *testing.T) {
	l, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	defer l.Close()

	go func() {
		for {
			c, err := l.Accept()
			if err != nil {
				return
			}
			defer c.Close()
		}
	}()

	c, err := Dial("tcp", l.Addr().String())
	if err != nil {
		t.Fatal(err)
	}
	defer c.Close()

	// replace c's pollServer with a closed version.
	ps, err := newPollServer()
	if err != nil {
		t.Fatal(err)
	}
	ps.poll.Close()
	c.(*TCPConn).conn.fd.pollServer = ps

	var b [1]byte
	_, err = c.Read(b[:])
	if err, ok := err.(*OpError); ok {
		if err.Op == "addfd" {
			return
		}
		if err, ok := err.Err.(*OpError); ok {
			// the err is sometimes wrapped by another OpError
			if err.Op == "addfd" {
				return
			}
		}
	}
	t.Error(err)
}
<commit_msg>net: fix intermittent TestAddFDReturnsError failure<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin freebsd linux netbsd openbsd

package net

import (
	"testing"
)

// Issue 3590. netFd.AddFD should return an error
// from the underlying pollster rather than panicing.
func TestAddFDReturnsError(t *testing.T) {
	ln := newLocalListener(t).(*TCPListener)
	defer ln.Close()
	connected := make(chan bool)
	go func() {
		for {
			c, err := ln.Accept()
			if err != nil {
				return
			}
			connected <- true
			defer c.Close()
		}
	}()

	c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr))
	if err != nil {
		t.Fatal(err)
	}
	defer c.Close()
	<-connected

	// replace c's pollServer with a closed version.
	ps, err := newPollServer()
	if err != nil {
		t.Fatal(err)
	}
	ps.poll.Close()
	c.conn.fd.pollServer = ps

	var b [1]byte
	_, err = c.Read(b[:])
	if err, ok := err.(*OpError); ok {
		if err.Op == "addfd" {
			return
		}
		if err, ok := err.Err.(*OpError); ok {
			// the err is sometimes wrapped by another OpError
			if err.Op == "addfd" {
				return
			}
		}
	}
	t.Error("unexpected error:", err)
}
<|endoftext|>