<commit_before>package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"io"
	"strings"
	"strconv"
)

/* A Simple function to verify error */
func CheckError(err error) {
    if err  != nil {
        fmt.Println("Error: " , err)
        os.Exit(0)
    }
}

func readConfig (path string) (m map[string]int)  {
	//Open File
	file, err := os.Open(path)
	CheckError(err)
	defer file.Close()

	m = make(map[string]int)

	//Start Reading..
	reader := bufio.NewReader(file)
	for {
		line, err := reader.ReadString(10) // 0x0A separator = newline
		if err == io.EOF {
			break
		}
		CheckError(err)
		key := strings.TrimSpace(line)
		m[key] = 0
	}
	return

}

func msgDigest(c chan string, m map[string]int) {
	for {
		msg := <-c
		fmt.Println(m)
		msgStr := strings.Split(msg, ":")
		if (len(msgStr) == 2) {
			//formatting
			key := msgStr[0]
			value, err := strconv.Atoi(msgStr[1])
			if (err != nil) {
				fmt.Println("recieved bad msg 0")
				fmt.Println(msg)
				continue
			}
			_, ok := m[key]
			fmt.Println(ok)
			fmt.Println(m[key])
			if (ok) {
				m[key] = value
			} else {
				fmt.Println("recieved bad msg 1")
				fmt.Println(key)
				continue
			}
		} else {
			fmt.Println("recieved bad msg 2")
			fmt.Println(msg)
			continue
		}
	}
}

func main() {

	port, configPath := ":8080","./config.json"

	fmt.Println("Reading Config...")
	fridgeStock := readConfig(configPath)
	//fridgeStock["Krombacher"]=11
	fmt.Println(len(fridgeStock))
	fmt.Println("Preparing Server...")
	/* Lets prepare a address at any address at port 	*/
	ServerAddr,err 	:= net.ResolveUDPAddr("udp", port)
	CheckError(err)

	fmt.Println("Listening on port %s...", port)
	/* Now listen at selected port */
	ServerConn, err := net.ListenUDP("udp", ServerAddr)
	CheckError(err)
	defer ServerConn.Close()

	messages := make(chan string)
	go msgDigest(messages,fridgeStock)

	buf := make([]byte, 1024)

	for {
		n,addr,err := ServerConn.ReadFromUDP(buf)
		fmt.Println("Received ",string(buf[0:n]), " from ",addr)
		messages <- string(buf[0:n])
		CheckError(err)
	}
}

<commit_msg>server functionality<commit_after>package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"io"
	"strings"
	"strconv"
)

/* A Simple function to verify error */
func CheckError(err error) {
    if err  != nil {
        fmt.Println("Error: " , err)
        os.Exit(0)
    }
}

func readConfig (path string) (m map[string]int)  {
	//Open File
	file, err := os.Open(path)
	CheckError(err)
	defer file.Close()

	m = make(map[string]int)

	//Start Reading..
	reader := bufio.NewReader(file)
	for {
		line, err := reader.ReadString(10) // 0x0A separator = newline
		if err == io.EOF {
			break
		}
		CheckError(err)
		key := strings.TrimSpace(line)
		m[key] = 0
	}
	return

}

func msgDigest(c chan string, m map[string]int) {
	for {
		msg := <-c
		msgStr := strings.Split(msg, ":")
		if (len(msgStr) == 2) {
			//formatting
			key := msgStr[0]
			value, err := strconv.Atoi(msgStr[1])
			if (err != nil) {
				fmt.Println("recieved bad msg 0")
				fmt.Println(msg)
				continue
			}

			if _, ok := m[key]; ok {
				m[key] = value
			} else {
				fmt.Println("recieved bad msg")
				fmt.Println(msg)
				continue
			}
		} else {
			fmt.Println("recieved bad msg")
			fmt.Println(msg)
			continue
		}
	}
}

func main() {

	port, configPath := ":8080","./config.json"

	fmt.Println("Reading Config...")
	fridgeStock := readConfig(configPath)

	fmt.Println("Preparing Server...")
	/* Lets prepare a address at any address at port 	*/
	ServerAddr,err 	:= net.ResolveUDPAddr("udp", port)
	CheckError(err)

	fmt.Println("Listening on port %s...", port)
	/* Now listen at selected port */
	ServerConn, err := net.ListenUDP("udp", ServerAddr)
	CheckError(err)
	defer ServerConn.Close()

	messages := make(chan string)
	go msgDigest(messages,fridgeStock)

	buf := make([]byte, 1024)

	for {
		n,addr,err := ServerConn.ReadFromUDP(buf)
		fmt.Println("Received ",string(buf[0:n]), " from ",addr)
		messages <- string(buf[0:n])
		CheckError(err)
	}
}

<|endoftext|>


<commit_before>// +build linux

/*

directory structure

  .
  |-- repositoryName
	  |-- scratch
		  |-- shardNum // the read-only read created on InitRepository, this is where to start branching
      |-- commitID
	      |-- shardNum // this is where subvolumes are

*/

package btrfs

/*
#include <stdlib.h>
#include <dirent.h>
#include <btrfs/ioctl.h>
*/
import "C"

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"

	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pfs/drive"
	"github.com/pachyderm/pachyderm/src/pkg/executil"
	"github.com/peter-edge/go-google-protobuf"
	"github.com/satori/go.uuid"
)

const (
	metadataDir = ".pfs"
)

var (
	callStrings = map[uintptr]string{
		C.BTRFS_IOC_SUBVOL_CREATE:  "btrfs subvolume create",
		C.BTRFS_IOC_SNAP_CREATE_V2: "btrfs subvolume snapshot",
	}
)

type driver struct {
	rootDir string
}

func newDriver(rootDir string) *driver {
	return &driver{rootDir}
}

func (d *driver) InitRepository(repository *pfs.Repository, shards map[int]bool) error {
	if err := os.MkdirAll(d.repositoryPath(repository), 0700); err != nil {
		return err
	}
	initialCommit := &pfs.Commit{
		Repository: repository,
		Id:         drive.InitialCommitID,
	}
	if err := os.MkdirAll(d.commitPathNoShard(initialCommit), 0700); err != nil {
		return err
	}
	for shard := range shards {
		if err := execSubvolumeCreate(d.commitPath(initialCommit, shard)); err != nil {
			return err
		}
		if err := os.Mkdir(d.filePath(&pfs.Path{Commit: initialCommit, Path: metadataDir}, shard), 0700); err != nil {
			return err
		}
		if err := d.setReadOnly(initialCommit, shard, true); err != nil {
			return err
		}
	}
	return nil
}

func (d *driver) GetFile(path *pfs.Path, shard int) (drive.ReaderAtCloser, error) {
	return os.Open(d.filePath(path, shard))
}

func (d *driver) GetFileInfo(path *pfs.Path, shard int) (_ *pfs.FileInfo, ok bool, _ error) {
	filePath, err := d.stat(path, shard)
	if err != nil && os.IsNotExist(err) {
		return nil, false, nil
	}
	if err != nil {
		return nil, false, err
	}
	return filePath, true, nil
}

func (d *driver) MakeDirectory(path *pfs.Path, shards map[int]bool) error {
	// TODO(pedge): if PutFile fails here or on another shard, the directories
	// will still exist and be returned from ListFiles, we want to do this
	// iteratively and with rollback
	// TODO(pedge): check that commit exists and is a write commit
	for shard := range shards {
		if err := d.checkWrite(path.Commit, shard); err != nil {
			return err
		}
		if err := os.MkdirAll(d.filePath(path, shard), 0700); err != nil {
			return err
		}
	}
	return nil
}

func (d *driver) PutFile(path *pfs.Path, shard int, offset int64, reader io.Reader) error {
	if err := d.checkWrite(path.Commit, shard); err != nil {
		return err
	}
	file, err := os.OpenFile(d.filePath(path, shard), os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		return err
	}
	defer file.Close()
	if _, err := file.Seek(offset, 0); err != nil { // 0 means relative to start
		return err
	}
	_, err = bufio.NewReader(reader).WriteTo(file)
	return err
}

func (d *driver) ListFiles(path *pfs.Path, shard int) (_ []*pfs.FileInfo, retErr error) {
	filePath := d.filePath(path, shard)
	stat, err := os.Stat(filePath)
	if err != nil {
		return nil, err
	}
	if !stat.IsDir() {
		return nil, fmt.Errorf("%s is not a directory", filePath)
	}
	dir, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer func() {
		if err := dir.Close(); err != nil && retErr == nil {
			retErr = err
		}
	}()
	var fileInfos []*pfs.FileInfo
	// TODO(pedge): constant
	for names, err := dir.Readdirnames(100); err != io.EOF; names, err = dir.Readdirnames(100) {
		if err != nil {
			return nil, err
		}
		for _, name := range names {
			if inMetadataDir(name) {
				continue
			}
			fileInfo, err := d.stat(
				&pfs.Path{
					Commit: path.Commit,
					Path:   filepath.Join(path.Path, name),
				},
				shard,
			)
			if err != nil {
				return nil, err
			}
			fileInfos = append(fileInfos, fileInfo)
		}
	}
	return fileInfos, nil
}

func (d *driver) stat(path *pfs.Path, shard int) (*pfs.FileInfo, error) {
	stat, err := os.Stat(d.filePath(path, shard))
	if err != nil {
		return nil, err
	}
	fileType := pfs.FileType_FILE_TYPE_OTHER
	if stat.Mode().IsRegular() {
		fileType = pfs.FileType_FILE_TYPE_REGULAR
	}
	if stat.Mode().IsDir() {
		fileType = pfs.FileType_FILE_TYPE_DIR
	}
	return &pfs.FileInfo{
		Path:      path,
		FileType:  fileType,
		SizeBytes: uint64(stat.Size()),
		Perm:      uint32(stat.Mode() & os.ModePerm),
		LastModified: &google_protobuf.Timestamp{
			Seconds: stat.ModTime().UnixNano() / int64(time.Second),
			Nanos:   int32(stat.ModTime().UnixNano() % int64(time.Second)),
		},
	}, nil
}

func (d *driver) Branch(commit *pfs.Commit, newCommit *pfs.Commit, shards map[int]bool) (*pfs.Commit, error) {
	if newCommit == nil {
		newCommit = &pfs.Commit{
			Repository: commit.Repository,
			Id:         newCommitID(),
		}
	}
	if err := os.MkdirAll(d.commitPathNoShard(newCommit), 0700); err != nil {
		return nil, err
	}
	for shard := range shards {
		if err := d.checkReadOnly(commit, shard); err != nil {
			return nil, err
		}
		commitPath := d.commitPath(commit, shard)
		newCommitPath := d.commitPath(newCommit, shard)
		if err := execSubvolumeSnapshot(commitPath, newCommitPath); err != nil {
			return nil, err
		}
		if err := ioutil.WriteFile(d.filePath(&pfs.Path{Commit: newCommit, Path: filepath.Join(metadataDir, "parent")}, shard), []byte(commit.Id), 0600); err != nil {
			return nil, err
		}
		if err := d.setReadOnly(newCommit, shard, false); err != nil {
			return nil, err
		}
	}
	return newCommit, nil
}

func (d *driver) Commit(commit *pfs.Commit, shards map[int]bool) error {
	for shard := range shards {
		if err := d.checkWrite(commit, shard); err != nil {
			return err
		}
		if err := d.setReadOnly(commit, shard, true); err != nil {
			return err
		}
	}
	return nil
}

func (d *driver) PullDiff(commit *pfs.Commit, shard int, diff io.Writer) error {
	parent, err := d.getParent(commit, shard)
	if err != nil {
		return err
	}
	if parent == nil {
		return execSend(d.commitPath(commit, shard), "", diff)
	}
	return execSend(d.commitPath(commit, shard), d.commitPath(parent, shard), diff)
}

func (d *driver) PushDiff(repository *pfs.Repository, shard int, diff io.Reader) error {
	return execRecv(d.repositoryPath(repository), diff)
}

func (d *driver) GetCommitInfo(commit *pfs.Commit, shard int) (_ *pfs.CommitInfo, ok bool, _ error) {
	_, err := os.Stat(d.commitPath(commit, shard))
	if err != nil && os.IsNotExist(err) {
		return nil, false, nil
	}
	if err != nil {
		return nil, false, err
	}
	parent, err := d.getParent(commit, shard)
	if err != nil {
		return nil, false, err
	}
	readOnly, err := d.getReadOnly(commit, shard)
	if err != nil {
		return nil, false, err
	}
	commitType := pfs.CommitType_COMMIT_TYPE_WRITE
	if readOnly {
		commitType = pfs.CommitType_COMMIT_TYPE_READ
	}
	return &pfs.CommitInfo{
		Commit:       commit,
		CommitType:   commitType,
		ParentCommit: parent,
	}, true, nil
}

func (d *driver) ListCommits(repository *pfs.Repository, shard int) (_ []*pfs.CommitInfo, retErr error) {

	dir, err := os.Open(d.repositoryPath(repository))
	if err != nil {
		return nil, err
	}
	defer func() {
		if err := dir.Close(); err != nil && retErr == nil {
			retErr = err
		}
	}()
	var commitInfos []*pfs.CommitInfo
	// TODO(pedge): constant
	for names, err := dir.Readdirnames(100); err != io.EOF; names, err = dir.Readdirnames(100) {
		if err != nil {
			return nil, err
		}
		for _, name := range names {
			commitInfo, ok, err := d.GetCommitInfo(
				&pfs.Commit{
					Repository: repository,
					Id:         path.Base(name),
				},
				shard,
			)
			if !ok {
				// This is a really weird error to get since we got this commit
				// name by listing commits. This is probably indicative of a
				// race condition.
				return nil, fmt.Errorf("Commit not found.")
			}
			if err != nil {
				return nil, err
			}
			commitInfos = append(commitInfos, commitInfo)
		}
	}
	return commitInfos, nil
}

func (d *driver) getParent(commit *pfs.Commit, shard int) (*pfs.Commit, error) {
	if commit.Id == drive.InitialCommitID {
		return nil, nil
	}
	data, err := ioutil.ReadFile(d.filePath(&pfs.Path{Commit: commit, Path: filepath.Join(metadataDir, "parent")}, shard))
	if err != nil {
		return nil, err
	}
	return &pfs.Commit{
		Repository: commit.Repository,
		Id:         string(data),
	}, nil
}

func (d *driver) checkReadOnly(commit *pfs.Commit, shard int) error {
	ok, err := d.getReadOnly(commit, shard)
	if err != nil {
		return err
	}
	if !ok {
		return fmt.Errorf("%+v is not a read only commit", commit)
	}
	return nil
}

func (d *driver) checkWrite(commit *pfs.Commit, shard int) error {
	ok, err := d.getReadOnly(commit, shard)
	if err != nil {
		return err
	}
	if ok {
		return fmt.Errorf("%+v is not a write commit", commit)
	}
	return nil
}

func (d *driver) getReadOnly(commit *pfs.Commit, shard int) (bool, error) {
	data, err := ioutil.ReadFile(d.filePath(&pfs.Path{Commit: commit, Path: filepath.Join(metadataDir, "readonly")}, shard))
	if err != nil {
		return false, err
	}
	switch string(data) {
	case "0":
		return false, nil
	case "1":
		return true, nil
	default:
		return false, fmt.Errorf("unknown data for readonly metadata file: %s", string(data))
	}
}

func (d *driver) setReadOnly(commit *pfs.Commit, shard int, readOnly bool) error {
	data := []byte("0")
	if readOnly {
		data = []byte("1")
	}
	return ioutil.WriteFile(d.filePath(&pfs.Path{Commit: commit, Path: filepath.Join(metadataDir, "readonly")}, shard), data, 0400)
}

func (d *driver) repositoryPath(repository *pfs.Repository) string {
	return filepath.Join(d.rootDir, repository.Name)
}

func (d *driver) commitPathNoShard(commit *pfs.Commit) string {
	return filepath.Join(d.repositoryPath(commit.Repository), commit.Id)
}

func (d *driver) commitPath(commit *pfs.Commit, shard int) string {
	return filepath.Join(d.commitPathNoShard(commit), fmt.Sprintf("%d", shard))
}

func (d *driver) filePath(path *pfs.Path, shard int) string {
	return filepath.Join(d.commitPath(path.Commit, shard), path.Path)
}

func newCommitID() string {
	return strings.Replace(uuid.NewV4().String(), "-", "", -1)
}

func inMetadataDir(name string) bool {
	parts := strings.Split(name, "/")
	return (len(parts) > 0 && parts[0] == metadataDir)
}

func execSubvolumeCreate(path string) error {
	return executil.Run("btrfs", "subvolume", "create", path)
}

func execSubvolumeSnapshot(src string, dest string) error {
	return executil.Run("btrfs", "subvolume", "snapshot", src, dest)
}

func execSend(path string, parent string, diff io.Writer) error {
	if parent == "" {
		return executil.RunStdout(diff, "btrfs", "send", path)
	}
	return executil.RunStdout(diff, "btrfs", "send", "-p", parent, path)
}

func execRecv(path string, diff io.Reader) error {
	return executil.RunStdin(diff, "btrfs", "receive", path)
}
<commit_msg>Remove some ffi code.<commit_after>// +build linux

/*

directory structure

  .
  |-- repositoryName
	  |-- scratch
		  |-- shardNum // the read-only read created on InitRepository, this is where to start branching
      |-- commitID
	      |-- shardNum // this is where subvolumes are

*/

package btrfs

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"

	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pfs/drive"
	"github.com/pachyderm/pachyderm/src/pkg/executil"
	"github.com/peter-edge/go-google-protobuf"
	"github.com/satori/go.uuid"
)

const (
	metadataDir = ".pfs"
)

type driver struct {
	rootDir string
}

func newDriver(rootDir string) *driver {
	return &driver{rootDir}
}

func (d *driver) InitRepository(repository *pfs.Repository, shards map[int]bool) error {
	if err := os.MkdirAll(d.repositoryPath(repository), 0700); err != nil {
		return err
	}
	initialCommit := &pfs.Commit{
		Repository: repository,
		Id:         drive.InitialCommitID,
	}
	if err := os.MkdirAll(d.commitPathNoShard(initialCommit), 0700); err != nil {
		return err
	}
	for shard := range shards {
		if err := execSubvolumeCreate(d.commitPath(initialCommit, shard)); err != nil {
			return err
		}
		if err := os.Mkdir(d.filePath(&pfs.Path{Commit: initialCommit, Path: metadataDir}, shard), 0700); err != nil {
			return err
		}
		if err := d.setReadOnly(initialCommit, shard, true); err != nil {
			return err
		}
	}
	return nil
}

func (d *driver) GetFile(path *pfs.Path, shard int) (drive.ReaderAtCloser, error) {
	return os.Open(d.filePath(path, shard))
}

func (d *driver) GetFileInfo(path *pfs.Path, shard int) (_ *pfs.FileInfo, ok bool, _ error) {
	filePath, err := d.stat(path, shard)
	if err != nil && os.IsNotExist(err) {
		return nil, false, nil
	}
	if err != nil {
		return nil, false, err
	}
	return filePath, true, nil
}

func (d *driver) MakeDirectory(path *pfs.Path, shards map[int]bool) error {
	// TODO(pedge): if PutFile fails here or on another shard, the directories
	// will still exist and be returned from ListFiles, we want to do this
	// iteratively and with rollback
	// TODO(pedge): check that commit exists and is a write commit
	for shard := range shards {
		if err := d.checkWrite(path.Commit, shard); err != nil {
			return err
		}
		if err := os.MkdirAll(d.filePath(path, shard), 0700); err != nil {
			return err
		}
	}
	return nil
}

func (d *driver) PutFile(path *pfs.Path, shard int, offset int64, reader io.Reader) error {
	if err := d.checkWrite(path.Commit, shard); err != nil {
		return err
	}
	file, err := os.OpenFile(d.filePath(path, shard), os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		return err
	}
	defer file.Close()
	if _, err := file.Seek(offset, 0); err != nil { // 0 means relative to start
		return err
	}
	_, err = bufio.NewReader(reader).WriteTo(file)
	return err
}

func (d *driver) ListFiles(path *pfs.Path, shard int) (_ []*pfs.FileInfo, retErr error) {
	filePath := d.filePath(path, shard)
	stat, err := os.Stat(filePath)
	if err != nil {
		return nil, err
	}
	if !stat.IsDir() {
		return nil, fmt.Errorf("%s is not a directory", filePath)
	}
	dir, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer func() {
		if err := dir.Close(); err != nil && retErr == nil {
			retErr = err
		}
	}()
	var fileInfos []*pfs.FileInfo
	// TODO(pedge): constant
	for names, err := dir.Readdirnames(100); err != io.EOF; names, err = dir.Readdirnames(100) {
		if err != nil {
			return nil, err
		}
		for _, name := range names {
			if inMetadataDir(name) {
				continue
			}
			fileInfo, err := d.stat(
				&pfs.Path{
					Commit: path.Commit,
					Path:   filepath.Join(path.Path, name),
				},
				shard,
			)
			if err != nil {
				return nil, err
			}
			fileInfos = append(fileInfos, fileInfo)
		}
	}
	return fileInfos, nil
}

func (d *driver) stat(path *pfs.Path, shard int) (*pfs.FileInfo, error) {
	stat, err := os.Stat(d.filePath(path, shard))
	if err != nil {
		return nil, err
	}
	fileType := pfs.FileType_FILE_TYPE_OTHER
	if stat.Mode().IsRegular() {
		fileType = pfs.FileType_FILE_TYPE_REGULAR
	}
	if stat.Mode().IsDir() {
		fileType = pfs.FileType_FILE_TYPE_DIR
	}
	return &pfs.FileInfo{
		Path:      path,
		FileType:  fileType,
		SizeBytes: uint64(stat.Size()),
		Perm:      uint32(stat.Mode() & os.ModePerm),
		LastModified: &google_protobuf.Timestamp{
			Seconds: stat.ModTime().UnixNano() / int64(time.Second),
			Nanos:   int32(stat.ModTime().UnixNano() % int64(time.Second)),
		},
	}, nil
}

func (d *driver) Branch(commit *pfs.Commit, newCommit *pfs.Commit, shards map[int]bool) (*pfs.Commit, error) {
	if newCommit == nil {
		newCommit = &pfs.Commit{
			Repository: commit.Repository,
			Id:         newCommitID(),
		}
	}
	if err := os.MkdirAll(d.commitPathNoShard(newCommit), 0700); err != nil {
		return nil, err
	}
	for shard := range shards {
		if err := d.checkReadOnly(commit, shard); err != nil {
			return nil, err
		}
		commitPath := d.commitPath(commit, shard)
		newCommitPath := d.commitPath(newCommit, shard)
		if err := execSubvolumeSnapshot(commitPath, newCommitPath); err != nil {
			return nil, err
		}
		if err := ioutil.WriteFile(d.filePath(&pfs.Path{Commit: newCommit, Path: filepath.Join(metadataDir, "parent")}, shard), []byte(commit.Id), 0600); err != nil {
			return nil, err
		}
		if err := d.setReadOnly(newCommit, shard, false); err != nil {
			return nil, err
		}
	}
	return newCommit, nil
}

func (d *driver) Commit(commit *pfs.Commit, shards map[int]bool) error {
	for shard := range shards {
		if err := d.checkWrite(commit, shard); err != nil {
			return err
		}
		if err := d.setReadOnly(commit, shard, true); err != nil {
			return err
		}
	}
	return nil
}

func (d *driver) PullDiff(commit *pfs.Commit, shard int, diff io.Writer) error {
	parent, err := d.getParent(commit, shard)
	if err != nil {
		return err
	}
	if parent == nil {
		return execSend(d.commitPath(commit, shard), "", diff)
	}
	return execSend(d.commitPath(commit, shard), d.commitPath(parent, shard), diff)
}

func (d *driver) PushDiff(repository *pfs.Repository, shard int, diff io.Reader) error {
	return execRecv(d.repositoryPath(repository), diff)
}

func (d *driver) GetCommitInfo(commit *pfs.Commit, shard int) (_ *pfs.CommitInfo, ok bool, _ error) {
	_, err := os.Stat(d.commitPath(commit, shard))
	if err != nil && os.IsNotExist(err) {
		return nil, false, nil
	}
	if err != nil {
		return nil, false, err
	}
	parent, err := d.getParent(commit, shard)
	if err != nil {
		return nil, false, err
	}
	readOnly, err := d.getReadOnly(commit, shard)
	if err != nil {
		return nil, false, err
	}
	commitType := pfs.CommitType_COMMIT_TYPE_WRITE
	if readOnly {
		commitType = pfs.CommitType_COMMIT_TYPE_READ
	}
	return &pfs.CommitInfo{
		Commit:       commit,
		CommitType:   commitType,
		ParentCommit: parent,
	}, true, nil
}

func (d *driver) ListCommits(repository *pfs.Repository, shard int) (_ []*pfs.CommitInfo, retErr error) {

	dir, err := os.Open(d.repositoryPath(repository))
	if err != nil {
		return nil, err
	}
	defer func() {
		if err := dir.Close(); err != nil && retErr == nil {
			retErr = err
		}
	}()
	var commitInfos []*pfs.CommitInfo
	// TODO(pedge): constant
	for names, err := dir.Readdirnames(100); err != io.EOF; names, err = dir.Readdirnames(100) {
		if err != nil {
			return nil, err
		}
		for _, name := range names {
			commitInfo, ok, err := d.GetCommitInfo(
				&pfs.Commit{
					Repository: repository,
					Id:         path.Base(name),
				},
				shard,
			)
			if !ok {
				// This is a really weird error to get since we got this commit
				// name by listing commits. This is probably indicative of a
				// race condition.
				return nil, fmt.Errorf("Commit not found.")
			}
			if err != nil {
				return nil, err
			}
			commitInfos = append(commitInfos, commitInfo)
		}
	}
	return commitInfos, nil
}

func (d *driver) getParent(commit *pfs.Commit, shard int) (*pfs.Commit, error) {
	if commit.Id == drive.InitialCommitID {
		return nil, nil
	}
	data, err := ioutil.ReadFile(d.filePath(&pfs.Path{Commit: commit, Path: filepath.Join(metadataDir, "parent")}, shard))
	if err != nil {
		return nil, err
	}
	return &pfs.Commit{
		Repository: commit.Repository,
		Id:         string(data),
	}, nil
}

func (d *driver) checkReadOnly(commit *pfs.Commit, shard int) error {
	ok, err := d.getReadOnly(commit, shard)
	if err != nil {
		return err
	}
	if !ok {
		return fmt.Errorf("%+v is not a read only commit", commit)
	}
	return nil
}

func (d *driver) checkWrite(commit *pfs.Commit, shard int) error {
	ok, err := d.getReadOnly(commit, shard)
	if err != nil {
		return err
	}
	if ok {
		return fmt.Errorf("%+v is not a write commit", commit)
	}
	return nil
}

func (d *driver) getReadOnly(commit *pfs.Commit, shard int) (bool, error) {
	data, err := ioutil.ReadFile(d.filePath(&pfs.Path{Commit: commit, Path: filepath.Join(metadataDir, "readonly")}, shard))
	if err != nil {
		return false, err
	}
	switch string(data) {
	case "0":
		return false, nil
	case "1":
		return true, nil
	default:
		return false, fmt.Errorf("unknown data for readonly metadata file: %s", string(data))
	}
}

func (d *driver) setReadOnly(commit *pfs.Commit, shard int, readOnly bool) error {
	data := []byte("0")
	if readOnly {
		data = []byte("1")
	}
	return ioutil.WriteFile(d.filePath(&pfs.Path{Commit: commit, Path: filepath.Join(metadataDir, "readonly")}, shard), data, 0400)
}

func (d *driver) repositoryPath(repository *pfs.Repository) string {
	return filepath.Join(d.rootDir, repository.Name)
}

func (d *driver) commitPathNoShard(commit *pfs.Commit) string {
	return filepath.Join(d.repositoryPath(commit.Repository), commit.Id)
}

func (d *driver) commitPath(commit *pfs.Commit, shard int) string {
	return filepath.Join(d.commitPathNoShard(commit), fmt.Sprintf("%d", shard))
}

func (d *driver) filePath(path *pfs.Path, shard int) string {
	return filepath.Join(d.commitPath(path.Commit, shard), path.Path)
}

func newCommitID() string {
	return strings.Replace(uuid.NewV4().String(), "-", "", -1)
}

func inMetadataDir(name string) bool {
	parts := strings.Split(name, "/")
	return (len(parts) > 0 && parts[0] == metadataDir)
}

func execSubvolumeCreate(path string) error {
	return executil.Run("btrfs", "subvolume", "create", path)
}

func execSubvolumeSnapshot(src string, dest string) error {
	return executil.Run("btrfs", "subvolume", "snapshot", src, dest)
}

func execSend(path string, parent string, diff io.Writer) error {
	if parent == "" {
		return executil.RunStdout(diff, "btrfs", "send", path)
	}
	return executil.RunStdout(diff, "btrfs", "send", "-p", parent, path)
}

func execRecv(path string, diff io.Reader) error {
	return executil.RunStdin(diff, "btrfs", "receive", path)
}
<|endoftext|>


<commit_before>// Copyright 2011 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 (
	"os"
	"runtime"
	"testing"
)

var listenMulticastUDPTests = []struct {
	net   string
	gaddr *UDPAddr
	flags Flags
	ipv6  bool
}{
	// cf. RFC 4727: Experimental Values in IPv4, IPv6, ICMPv4, ICMPv6, UDP, and TCP Headers
	{"udp", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false},
	{"udp4", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false},
	{"udp", &UDPAddr{ParseIP("ff0e::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff01::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff02::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff04::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff05::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff08::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff0e::114"), 12345}, FlagUp | FlagLoopback, true},
}

func TestListenMulticastUDP(t *testing.T) {
	switch runtime.GOOS {
	case "netbsd", "openbsd", "plan9", "windows":
		return
	case "linux":
		if runtime.GOARCH == "arm" {
			return
		}
	}

	for _, tt := range listenMulticastUDPTests {
		if tt.ipv6 && (!supportsIPv6 || os.Getuid() != 0) {
			continue
		}
		ift, err := Interfaces()
		if err != nil {
			t.Fatalf("Interfaces failed: %v", err)
		}
		var ifi *Interface
		for _, x := range ift {
			if x.Flags&tt.flags == tt.flags {
				ifi = &x
				break
			}
		}
		if ifi == nil {
			t.Logf("an appropriate multicast interface not found")
			return
		}
		c, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr)
		if err != nil {
			t.Fatalf("ListenMulticastUDP failed: %v", err)
		}
		defer c.Close() // test to listen concurrently across multiple listeners
		if !tt.ipv6 {
			testIPv4MulticastSocketOptions(t, c.fd, ifi)
		} else {
			testIPv6MulticastSocketOptions(t, c.fd, ifi)
		}
		ifmat, err := ifi.MulticastAddrs()
		if err != nil {
			t.Fatalf("MulticastAddrs failed: %v", err)
		}
		var found bool
		for _, ifma := range ifmat {
			if ifma.(*IPAddr).IP.Equal(tt.gaddr.IP) {
				found = true
				break
			}
		}
		if !found {
			t.Fatalf("%q not found in RIB", tt.gaddr.String())
		}
	}
}

func TestSimpleListenMulticastUDP(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		return
	}

	for _, tt := range listenMulticastUDPTests {
		if tt.ipv6 {
			continue
		}
		tt.flags = FlagUp | FlagMulticast
		ift, err := Interfaces()
		if err != nil {
			t.Fatalf("Interfaces failed: %v", err)
		}
		var ifi *Interface
		for _, x := range ift {
			if x.Flags&tt.flags == tt.flags {
				ifi = &x
				break
			}
		}
		if ifi == nil {
			t.Logf("an appropriate multicast interface not found")
			return
		}
		c, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr)
		if err != nil {
			t.Fatalf("ListenMulticastUDP failed: %v", err)
		}
		c.Close()
	}
}

func testIPv4MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) {
	ifmc, err := ipv4MulticastInterface(fd)
	if err != nil {
		t.Fatalf("ipv4MulticastInterface failed: %v", err)
	}
	t.Logf("IPv4 multicast interface: %v", ifmc)
	err = setIPv4MulticastInterface(fd, ifi)
	if err != nil {
		t.Fatalf("setIPv4MulticastInterface failed: %v", err)
	}

	ttl, err := ipv4MulticastTTL(fd)
	if err != nil {
		t.Fatalf("ipv4MulticastTTL failed: %v", err)
	}
	t.Logf("IPv4 multicast TTL: %v", ttl)
	err = setIPv4MulticastTTL(fd, 1)
	if err != nil {
		t.Fatalf("setIPv4MulticastTTL failed: %v", err)
	}

	loop, err := ipv4MulticastLoopback(fd)
	if err != nil {
		t.Fatalf("ipv4MulticastLoopback failed: %v", err)
	}
	t.Logf("IPv4 multicast loopback: %v", loop)
	err = setIPv4MulticastLoopback(fd, false)
	if err != nil {
		t.Fatalf("setIPv4MulticastLoopback failed: %v", err)
	}
}

func testIPv6MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) {
	ifmc, err := ipv6MulticastInterface(fd)
	if err != nil {
		t.Fatalf("ipv6MulticastInterface failed: %v", err)
	}
	t.Logf("IPv6 multicast interface: %v", ifmc)
	err = setIPv6MulticastInterface(fd, ifi)
	if err != nil {
		t.Fatalf("setIPv6MulticastInterface failed: %v", err)
	}

	hoplim, err := ipv6MulticastHopLimit(fd)
	if err != nil {
		t.Fatalf("ipv6MulticastHopLimit failed: %v", err)
	}
	t.Logf("IPv6 multicast hop limit: %v", hoplim)
	err = setIPv6MulticastHopLimit(fd, 1)
	if err != nil {
		t.Fatalf("setIPv6MulticastHopLimit failed: %v", err)
	}

	loop, err := ipv6MulticastLoopback(fd)
	if err != nil {
		t.Fatalf("ipv6MulticastLoopback failed: %v", err)
	}
	t.Logf("IPv6 multicast loopback: %v", loop)
	err = setIPv6MulticastLoopback(fd, false)
	if err != nil {
		t.Fatalf("setIPv6MulticastLoopback failed: %v", err)
	}
}
<commit_msg>net: disable multicast test on Alpha GNU/Linux<commit_after>// Copyright 2011 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 (
	"os"
	"runtime"
	"testing"
)

var listenMulticastUDPTests = []struct {
	net   string
	gaddr *UDPAddr
	flags Flags
	ipv6  bool
}{
	// cf. RFC 4727: Experimental Values in IPv4, IPv6, ICMPv4, ICMPv6, UDP, and TCP Headers
	{"udp", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false},
	{"udp4", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false},
	{"udp", &UDPAddr{ParseIP("ff0e::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff01::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff02::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff04::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff05::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff08::114"), 12345}, FlagUp | FlagLoopback, true},
	{"udp6", &UDPAddr{ParseIP("ff0e::114"), 12345}, FlagUp | FlagLoopback, true},
}

func TestListenMulticastUDP(t *testing.T) {
	switch runtime.GOOS {
	case "netbsd", "openbsd", "plan9", "windows":
		return
	case "linux":
		if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
			return
		}
	}

	for _, tt := range listenMulticastUDPTests {
		if tt.ipv6 && (!supportsIPv6 || os.Getuid() != 0) {
			continue
		}
		ift, err := Interfaces()
		if err != nil {
			t.Fatalf("Interfaces failed: %v", err)
		}
		var ifi *Interface
		for _, x := range ift {
			if x.Flags&tt.flags == tt.flags {
				ifi = &x
				break
			}
		}
		if ifi == nil {
			t.Logf("an appropriate multicast interface not found")
			return
		}
		c, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr)
		if err != nil {
			t.Fatalf("ListenMulticastUDP failed: %v", err)
		}
		defer c.Close() // test to listen concurrently across multiple listeners
		if !tt.ipv6 {
			testIPv4MulticastSocketOptions(t, c.fd, ifi)
		} else {
			testIPv6MulticastSocketOptions(t, c.fd, ifi)
		}
		ifmat, err := ifi.MulticastAddrs()
		if err != nil {
			t.Fatalf("MulticastAddrs failed: %v", err)
		}
		var found bool
		for _, ifma := range ifmat {
			if ifma.(*IPAddr).IP.Equal(tt.gaddr.IP) {
				found = true
				break
			}
		}
		if !found {
			t.Fatalf("%q not found in RIB", tt.gaddr.String())
		}
	}
}

func TestSimpleListenMulticastUDP(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		return
	}

	for _, tt := range listenMulticastUDPTests {
		if tt.ipv6 {
			continue
		}
		tt.flags = FlagUp | FlagMulticast
		ift, err := Interfaces()
		if err != nil {
			t.Fatalf("Interfaces failed: %v", err)
		}
		var ifi *Interface
		for _, x := range ift {
			if x.Flags&tt.flags == tt.flags {
				ifi = &x
				break
			}
		}
		if ifi == nil {
			t.Logf("an appropriate multicast interface not found")
			return
		}
		c, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr)
		if err != nil {
			t.Fatalf("ListenMulticastUDP failed: %v", err)
		}
		c.Close()
	}
}

func testIPv4MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) {
	ifmc, err := ipv4MulticastInterface(fd)
	if err != nil {
		t.Fatalf("ipv4MulticastInterface failed: %v", err)
	}
	t.Logf("IPv4 multicast interface: %v", ifmc)
	err = setIPv4MulticastInterface(fd, ifi)
	if err != nil {
		t.Fatalf("setIPv4MulticastInterface failed: %v", err)
	}

	ttl, err := ipv4MulticastTTL(fd)
	if err != nil {
		t.Fatalf("ipv4MulticastTTL failed: %v", err)
	}
	t.Logf("IPv4 multicast TTL: %v", ttl)
	err = setIPv4MulticastTTL(fd, 1)
	if err != nil {
		t.Fatalf("setIPv4MulticastTTL failed: %v", err)
	}

	loop, err := ipv4MulticastLoopback(fd)
	if err != nil {
		t.Fatalf("ipv4MulticastLoopback failed: %v", err)
	}
	t.Logf("IPv4 multicast loopback: %v", loop)
	err = setIPv4MulticastLoopback(fd, false)
	if err != nil {
		t.Fatalf("setIPv4MulticastLoopback failed: %v", err)
	}
}

func testIPv6MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) {
	ifmc, err := ipv6MulticastInterface(fd)
	if err != nil {
		t.Fatalf("ipv6MulticastInterface failed: %v", err)
	}
	t.Logf("IPv6 multicast interface: %v", ifmc)
	err = setIPv6MulticastInterface(fd, ifi)
	if err != nil {
		t.Fatalf("setIPv6MulticastInterface failed: %v", err)
	}

	hoplim, err := ipv6MulticastHopLimit(fd)
	if err != nil {
		t.Fatalf("ipv6MulticastHopLimit failed: %v", err)
	}
	t.Logf("IPv6 multicast hop limit: %v", hoplim)
	err = setIPv6MulticastHopLimit(fd, 1)
	if err != nil {
		t.Fatalf("setIPv6MulticastHopLimit failed: %v", err)
	}

	loop, err := ipv6MulticastLoopback(fd)
	if err != nil {
		t.Fatalf("ipv6MulticastLoopback failed: %v", err)
	}
	t.Logf("IPv6 multicast loopback: %v", loop)
	err = setIPv6MulticastLoopback(fd, false)
	if err != nil {
		t.Fatalf("setIPv6MulticastLoopback failed: %v", err)
	}
}
<|endoftext|>


<commit_before>package martini

import (
	"log"
	"net/http"
	"path"
	"strings"
)

// Static returns a middleware handler that serves static files in the given path.
func Static(path string) Handler {
	dir := http.Dir(path)
	return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
		file := req.URL.Path
		f, err := dir.Open(file)
		if err != nil {
			// discard the error?
			return
		}
		defer f.Close()

		fi, err := f.Stat()
		if err != nil {
			return
		}

		// Try to serve index.html
		if fi.IsDir() {

			// redirect if missing trailing slash
			if !strings.HasSuffix(file, "/") {
				http.Redirect(res, req, file+"/", http.StatusFound)
				return
			}

			file = path.Join(file, "index.html")
			f, err = dir.Open(file)
			if err != nil {
				return
			}
			defer f.Close()

			fi, err = f.Stat()
			if err != nil || fi.IsDir() {
				return
			}
		}

		log.Println("[Static] Serving " + file)
		http.ServeContent(res, req, file, fi.ModTime(), f)
	}
}
<commit_msg>Removing namespace collision<commit_after>package martini

import (
	"log"
	"net/http"
	"path"
	"strings"
)

// Static returns a middleware handler that serves static files in the given directory.
func Static(directory string) Handler {
	dir := http.Dir(directory)
	return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
		file := req.URL.Path
		f, err := dir.Open(file)
		if err != nil {
			// discard the error?
			return
		}
		defer f.Close()

		fi, err := f.Stat()
		if err != nil {
			return
		}

		// Try to serve index.html
		if fi.IsDir() {

			// redirect if missing trailing slash
			if !strings.HasSuffix(file, "/") {
				http.Redirect(res, req, file+"/", http.StatusFound)
				return
			}

			file = path.Join(file, "index.html")
			f, err = dir.Open(file)
			if err != nil {
				return
			}
			defer f.Close()

			fi, err = f.Stat()
			if err != nil || fi.IsDir() {
				return
			}
		}

		log.Println("[Static] Serving " + file)
		http.ServeContent(res, req, file, fi.ModTime(), f)
	}
}
<|endoftext|>


<commit_before>package gracedown

import (
	"net"
	"net/http"
)

var defaultServer *Server

// ListenAndServe provides a graceful version of the function provided by the
// net/http package. Call Close() to stop the server.
func ListenAndServe(addr string, handler http.Handler) error {
	defaultServer = NewWithServer(&http.Server{Addr: addr, Handler: handler})
	return defaultServer.ListenAndServe()
}

// ListenAndServeTLS provides a graceful version of the function provided by the
// net/http package. Call Close() to stop the server.
func ListenAndServeTLS(addr string, certFile string, keyFile string, handler http.Handler) error {
	defaultServer = NewWithServer(&http.Server{Addr: addr, Handler: handler})
	return defaultServer.ListenAndServeTLS(certFile, keyFile)
}

// Serve provides a graceful version of the function provided by the net/http
// package. Call Close() to stop the server.
func Serve(l net.Listener, handler http.Handler) error {
	defaultServer = NewWithServer(&http.Server{Handler: handler})
	return defaultServer.Serve(l)
}

// Shuts down the default server used by ListenAndServe, ListenAndServeTLS and
// Serve. It returns true if it's the first time Close is called.
func Close() bool {
	return defaultServer.Close()
}
<commit_msg>remove TLS method temporary<commit_after>package gracedown

import (
	"net"
	"net/http"
)

var defaultServer *Server

// ListenAndServe provides a graceful version of the function provided by the
// net/http package. Call Close() to stop the server.
func ListenAndServe(addr string, handler http.Handler) error {
	defaultServer = NewWithServer(&http.Server{Addr: addr, Handler: handler})
	return defaultServer.ListenAndServe()
}

// Serve provides a graceful version of the function provided by the net/http
// package. Call Close() to stop the server.
func Serve(l net.Listener, handler http.Handler) error {
	defaultServer = NewWithServer(&http.Server{Handler: handler})
	return defaultServer.Serve(l)
}

// Shuts down the default server used by ListenAndServe, ListenAndServeTLS and
// Serve. It returns true if it's the first time Close is called.
func Close() bool {
	return defaultServer.Close()
}
<|endoftext|>


<commit_before>package martini

import (
	"log"
	"path/filepath"
	"net/http"
)

// Static returns a middleware handler that serves static files in the given path.
func Static(path string) Handler {
	dir := http.Dir(path)
	return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
		file := req.URL.Path
		f, err := dir.Open(file)
		if err != nil {
			// discard the error?
			return
		}
		defer f.Close()

		fi, err := f.Stat()
		if err != nil {
			return
		}
		if fi.IsDir() {
			file = filepath.Join(file, "index.html")
			f, err = dir.Open(file)
			if err != nil {
				return
			}
			fi, err = f.Stat()
			if err != nil || fi.IsDir() {
				return
			}
		}

		log.Println("[Static] Serving " + file)
		http.ServeContent(res, req, file, fi.ModTime(), f)
	}
}
<commit_msg>Closing file. Added comment<commit_after>package martini

import (
	"log"
	"net/http"
	"path/filepath"
)

// Static returns a middleware handler that serves static files in the given path.
func Static(path string) Handler {
	dir := http.Dir(path)
	return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
		file := req.URL.Path
		f, err := dir.Open(file)
		if err != nil {
			// discard the error?
			return
		}
		defer f.Close()

		fi, err := f.Stat()
		if err != nil {
			return
		}

		// Try to serve index.html
		if fi.IsDir() {
			file = filepath.Join(file, "index.html")
			f, err = dir.Open(file)
			if err != nil {
				return
			}
			defer f.Close()

			fi, err = f.Stat()
			if err != nil || fi.IsDir() {
				return
			}
		}

		log.Println("[Static] Serving " + file)
		http.ServeContent(res, req, file, fi.ModTime(), f)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strings"
	"time"
)

const (
	networkDeviceStatsMetricPrefix = "net.dev."
	netstatStatsMetricPrefix       = "net.netstat."
	sockstatStatsMetricPrefix      = "net.sockstat."
)

type LoggedStat struct {
	Name string      `json:"name"`
	Time time.Time   `json:"time"`
	Stat interface{} `json:"stat"`
}

func collectNetworkDeviceStats() {
	stats, err := readNetworkDeviceStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading network device stats. Can't collect network device stats.")
	}

	for _, stat := range stats {
		if ifaceRegExp == nil || !ifaceRegExp.MatchString(stat.Iface) {
			elem := reflect.ValueOf(&stat).Elem()
			typeOfElem := elem.Type()

			for i := 0; i < elem.NumField(); i++ {
				field := typeOfElem.Field(i)

				if field.Name == "Iface" {
					continue
				}

				value := elem.Field(i).Uint()

				_, collect := StatsMap[field.Name]

				if metricName := field.Tag.Get("json"); collect && metricName != "" {
					if err := StatsdClient.Count(strings.Join([]string{networkDeviceStatsMetricPrefix, metricName}, ""), int64(value), []string{"iface:" + stat.Iface}, 1); err != nil {
						Log.WithField("error", err).Error("Couldn't submit event to statsd.")
					}
				}
			}
		}
	}
}

func logNetworkDeviceStats() {
	stats, err := readNetworkDeviceStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading network device stats. Can't log network device stats.")
	}

	loggedStat := LoggedStat{NetworkStatPath, time.Now(), stats}

	jsonBytes, err := json.Marshal(loggedStat)
	if err != nil {
		Log.WithField("error", err).Errorf("Error JSON marshalling: %+v.", stats)
	}

	fmt.Println(string(jsonBytes))
}

func collectNetstatStats() {
	stats, err := readNetstatStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading network device stats. Can't collect netstat stats.")
	}

	elem := reflect.ValueOf(stats).Elem()
	typeOfElem := elem.Type()

	for i := 0; i < elem.NumField(); i++ {
		field := typeOfElem.Field(i)

		value := elem.Field(i).Uint()

		_, collect := StatsMap[field.Name]

		if metricName := field.Tag.Get("json"); collect && metricName != "" {
			if err := StatsdClient.Count(strings.Join([]string{netstatStatsMetricPrefix, metricName}, ""), int64(value), []string{}, 1); err != nil {
				Log.WithField("error", err).Error("Couldn't submit event to statsd.")
			}
		}
	}
}

func logNetstatStats() {
	stats, err := readNetstatStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading network device stats. Can't log netstat stats.")
	}

	loggedStat := LoggedStat{NetstatStatPath, time.Now(), stats}

	jsonBytes, err := json.Marshal(loggedStat)
	if err != nil {
		Log.WithField("error", err).Errorf("Error JSON marshalling: %+v.", stats)
	}

	fmt.Println(string(jsonBytes))
}

func collectSockstatStats() {
	stats, err := readSockstatStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading sockstat stats. Can't collect netstat stats.")
	}

	elem := reflect.ValueOf(stats).Elem()
	typeOfElem := elem.Type()

	for i := 0; i < elem.NumField(); i++ {
		field := typeOfElem.Field(i)

		value := elem.Field(i).Uint()

		_, collect := StatsMap[field.Name]

		if metricName := field.Tag.Get("json"); collect && metricName != "" {
			if err := StatsdClient.Count(strings.Join([]string{sockstatStatsMetricPrefix, metricName}, ""), int64(value), []string{}, 1); err != nil {
				Log.WithField("error", err).Error("Couldn't submit event to statsd.")
			}
		}
	}
}

func logSockstatStats() {
	stats, err := readSockstatStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading sockstat stats. Can't log netstat stats.")
	}

	loggedStat := LoggedStat{SockstatStatPath, time.Now(), stats}

	jsonBytes, err := json.Marshal(loggedStat)
	if err != nil {
		Log.WithField("error", err).Errorf("Error JSON marshalling: %+v.", stats)
	}

	fmt.Println(string(jsonBytes))
}
<commit_msg>Changed the sockstat statsd metrics type from a "count" to a "gauge".<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strings"
	"time"
)

const (
	networkDeviceStatsMetricPrefix = "net.dev."
	netstatStatsMetricPrefix       = "net.netstat."
	sockstatStatsMetricPrefix      = "net.sockstat."
)

type LoggedStat struct {
	Name string      `json:"name"`
	Time time.Time   `json:"time"`
	Stat interface{} `json:"stat"`
}

func collectNetworkDeviceStats() {
	stats, err := readNetworkDeviceStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading network device stats. Can't collect network device stats.")
	}

	for _, stat := range stats {
		if ifaceRegExp == nil || !ifaceRegExp.MatchString(stat.Iface) {
			elem := reflect.ValueOf(&stat).Elem()
			typeOfElem := elem.Type()

			for i := 0; i < elem.NumField(); i++ {
				field := typeOfElem.Field(i)

				if field.Name == "Iface" {
					continue
				}

				value := elem.Field(i).Uint()

				_, collect := StatsMap[field.Name]

				if metricName := field.Tag.Get("json"); collect && metricName != "" {
					if err := StatsdClient.Count(strings.Join([]string{networkDeviceStatsMetricPrefix, metricName}, ""), int64(value), []string{"iface:" + stat.Iface}, 1); err != nil {
						Log.WithField("error", err).Error("Couldn't submit event to statsd.")
					}
				}
			}
		}
	}
}

func logNetworkDeviceStats() {
	stats, err := readNetworkDeviceStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading network device stats. Can't log network device stats.")
	}

	loggedStat := LoggedStat{NetworkStatPath, time.Now(), stats}

	jsonBytes, err := json.Marshal(loggedStat)
	if err != nil {
		Log.WithField("error", err).Errorf("Error JSON marshalling: %+v.", stats)
	}

	fmt.Println(string(jsonBytes))
}

func collectNetstatStats() {
	stats, err := readNetstatStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading network device stats. Can't collect netstat stats.")
	}

	elem := reflect.ValueOf(stats).Elem()
	typeOfElem := elem.Type()

	for i := 0; i < elem.NumField(); i++ {
		field := typeOfElem.Field(i)

		value := elem.Field(i).Uint()

		_, collect := StatsMap[field.Name]

		if metricName := field.Tag.Get("json"); collect && metricName != "" {
			if err := StatsdClient.Count(strings.Join([]string{netstatStatsMetricPrefix, metricName}, ""), int64(value), []string{}, 1); err != nil {
				Log.WithField("error", err).Error("Couldn't submit event to statsd.")
			}
		}
	}
}

func logNetstatStats() {
	stats, err := readNetstatStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading network device stats. Can't log netstat stats.")
	}

	loggedStat := LoggedStat{NetstatStatPath, time.Now(), stats}

	jsonBytes, err := json.Marshal(loggedStat)
	if err != nil {
		Log.WithField("error", err).Errorf("Error JSON marshalling: %+v.", stats)
	}

	fmt.Println(string(jsonBytes))
}

func collectSockstatStats() {
	stats, err := readSockstatStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading sockstat stats. Can't collect netstat stats.")
	}

	elem := reflect.ValueOf(stats).Elem()
	typeOfElem := elem.Type()

	for i := 0; i < elem.NumField(); i++ {
		field := typeOfElem.Field(i)

		value := elem.Field(i).Uint()

		_, collect := StatsMap[field.Name]

		if metricName := field.Tag.Get("json"); collect && metricName != "" {
			if err := StatsdClient.Gauge(strings.Join([]string{sockstatStatsMetricPrefix, metricName}, ""), float64(value), []string{}, 1); err != nil {
				Log.WithField("error", err).Error("Couldn't submit event to statsd.")
			}
		}
	}
}

func logSockstatStats() {
	stats, err := readSockstatStats()

	if err != nil {
		Log.WithField("error", err).Error("Error reading sockstat stats. Can't log netstat stats.")
	}

	loggedStat := LoggedStat{SockstatStatPath, time.Now(), stats}

	jsonBytes, err := json.Marshal(loggedStat)
	if err != nil {
		Log.WithField("error", err).Errorf("Error JSON marshalling: %+v.", stats)
	}

	fmt.Println(string(jsonBytes))
}
<|endoftext|>


<commit_before>package command_factory

import (
	"fmt"
	"strconv"
	"strings"
	"text/tabwriter"

	"github.com/cloudfoundry/gunk/timeprovider"
	"github.com/codegangsta/cli"
	"github.com/pivotal-cf-experimental/lattice-cli/app_examiner"
	"github.com/pivotal-cf-experimental/lattice-cli/app_examiner/command_factory/presentation"
	"github.com/pivotal-cf-experimental/lattice-cli/colors"
	"github.com/pivotal-cf-experimental/lattice-cli/output"
	"github.com/pivotal-cf-experimental/lattice-cli/output/cursor"
)

type AppExaminerCommandFactory struct {
	appExaminerCommand *appExaminerCommand
}

type exitHandler interface {
	OnExit(func())
}

func NewAppExaminerCommandFactory(appExaminer app_examiner.AppExaminer, output *output.Output, timeProvider timeprovider.TimeProvider, exitHandler exitHandler) *AppExaminerCommandFactory {
	return &AppExaminerCommandFactory{&appExaminerCommand{appExaminer, output, timeProvider, exitHandler}}
}

func (commandFactory *AppExaminerCommandFactory) MakeListAppCommand() cli.Command {

	var startCommand = cli.Command{
		Name:        "list",
		ShortName:   "li",
		Description: "List all apps on lattice.",
		Usage:       "ltc list",
		Action:      commandFactory.appExaminerCommand.listApps,
		Flags:       []cli.Flag{},
	}

	return startCommand
}

func (commandFactory *AppExaminerCommandFactory) MakeVisualizeCommand() cli.Command {

	var visualizeFlags = []cli.Flag{
		cli.DurationFlag{
			Name:  "rate, r",
			Usage: "The rate in seconds at which to refresh the visualization.",
		},
	}

	var startCommand = cli.Command{
		Name:        "visualize",
		Description: "Visualize Lattice Cells",
		Usage:       "ltc visualize",
		Action:      commandFactory.appExaminerCommand.visualizeCells,
		Flags:       visualizeFlags,
	}

	return startCommand
}

func (commandFactory *AppExaminerCommandFactory) MakeStatusCommand() cli.Command {
	return cli.Command{
		Name:        "status",
		Description: "Displays detailed status information about the app and its instances",
		Usage:       "ltc status",
		Action:      commandFactory.appExaminerCommand.appStatus,
		Flags:       []cli.Flag{},
	}
}

type appExaminerCommand struct {
	appExaminer  app_examiner.AppExaminer
	output       *output.Output
	timeProvider timeprovider.TimeProvider
	exitHandler  exitHandler
}

func (cmd *appExaminerCommand) listApps(context *cli.Context) {
	appList, err := cmd.appExaminer.ListApps()
	if err != nil {
		cmd.output.Say("Error listing apps: " + err.Error())
		return
	} else if len(appList) == 0 {
		cmd.output.Say("No apps to display.")
		return
	}

	w := &tabwriter.Writer{}
	w.Init(cmd.output, 10+colors.ColorCodeLength, 8, 1, '\t', 0)

	header := fmt.Sprintf("%s\t%s\t%s\t%s\t%s", colors.Bold("App Name"), colors.Bold("Instances"), colors.Bold("DiskMB"), colors.Bold("MemoryMB"), colors.Bold("Routes"))
	fmt.Fprintln(w, header)

	for _, appInfo := range appList {
		routes := strings.Join(appInfo.Routes, " ")

		fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", colors.Bold(appInfo.ProcessGuid), colorInstances(appInfo), colors.NoColor(strconv.Itoa(appInfo.DiskMB)), colors.NoColor(strconv.Itoa(appInfo.MemoryMB)), colors.Cyan(routes))
	}
	w.Flush()
}

func (cmd *appExaminerCommand) appStatus(context *cli.Context) {
	if len(context.Args()) < 1 {
		cmd.output.IncorrectUsage("App Name required")
		return
	}

	appName := context.Args()[0]
	appInfo, err := cmd.appExaminer.AppStatus(appName)

	if err != nil {
		cmd.output.Say(err.Error())
		return
	}

	minColumnWidth := 13
	w := tabwriter.NewWriter(cmd.output, minColumnWidth, 8, 1, '\t', 0)

	horizontalRule := func(pattern string) {
		header := strings.Repeat(pattern, 80) + "\n"
		fmt.Fprintf(w, header)
	}

	headingIndentation := strings.Repeat(" ", minColumnWidth/2)

	titleBar := func(title string) {
		horizontalRule("=")
		fmt.Fprintf(w, "%s%s\n", headingIndentation, title)
		horizontalRule("-")
	}

	titleBar(appName)

	fmt.Fprintf(w, "%s\t%s\n", "Instances", colorInstances(appInfo))
	fmt.Fprintf(w, "%s\t%s\n", "Stack", appInfo.Stack)

	fmt.Fprintf(w, "%s\t%d\n", "Start Timeout", appInfo.StartTimeout)
	fmt.Fprintf(w, "%s\t%d\n", "DiskMB", appInfo.DiskMB)
	fmt.Fprintf(w, "%s\t%d\n", "MemoryMB", appInfo.MemoryMB)
	fmt.Fprintf(w, "%s\t%d\n", "CPUWeight", appInfo.CPUWeight)

	portStrings := make([]string, 0)
	for _, port := range appInfo.Ports {
		portStrings = append(portStrings, fmt.Sprint(port))
	}

	fmt.Fprintf(w, "%s\t%s\n", "Ports", strings.Join(portStrings, ","))
	fmt.Fprintf(w, "%s\t%s\n", "Routes", strings.Join(appInfo.Routes, " "))
	fmt.Fprintf(w, "%s\t%s\n", "LogGuid", appInfo.LogGuid)
	fmt.Fprintf(w, "%s\t%s\n", "LogSource", appInfo.LogSource)
	fmt.Fprintf(w, "%s\t%s\n", "Annotation", appInfo.Annotation)

	horizontalRule("-")
	var envVars string
	for _, envVar := range appInfo.EnvironmentVariables {
		envVars += envVar.Name + `="` + envVar.Value + `" ` + "\n"
	}
	fmt.Fprintf(w, "%s\n\n%s", "Environment", envVars)

	fmt.Fprintln(w, "")
	horizontalRule("=")

	instanceBar := func(index, state string) {
		fmt.Fprintf(w, "%sInstance %s  [%s]\n", headingIndentation, index, state)
		horizontalRule("-")
	}

	for _, instance := range appInfo.ActualInstances {
		instanceBar(fmt.Sprint(instance.Index), presentation.ColorInstanceState(instance.State))

		fmt.Fprintf(w, "%s\t%s\n", "InstanceGuid", instance.InstanceGuid)
		fmt.Fprintf(w, "%s\t%s\n", "Cell ID", instance.CellID)
		fmt.Fprintf(w, "%s\t%s\n", "Ip", instance.Ip)

		portMappingStrings := make([]string, 0)
		for _, portMapping := range instance.Ports {
			portMappingStrings = append(portMappingStrings, fmt.Sprintf("%d:%d", portMapping.HostPort, portMapping.ContainerPort))
		}
		fmt.Fprintf(w, "%s\t%s\n", "Ports", strings.Join(portMappingStrings, ";"))

		fmt.Fprintf(w, "%s\t%s\n", "Since", fmt.Sprint(instance.Since))

		horizontalRule("-")
	}

	w.Flush()
}

func (cmd *appExaminerCommand) visualizeCells(context *cli.Context) {
	rate := context.Duration("rate")

	cmd.output.Say(colors.Bold("Distribution\n"))
	linesWritten := cmd.printDistribution()

	if rate == 0 {
		return
	}

	closeChan := make(chan bool)
	cmd.output.Say(cursor.Hide())

	cmd.exitHandler.OnExit(func() {
		closeChan <- true
		cmd.output.Say(cursor.Show())
	})

	for {
		select {
		case <-closeChan:
			return
		case <-cmd.timeProvider.NewTimer(rate).C():
			cmd.output.Say(cursor.Up(linesWritten))
			linesWritten = cmd.printDistribution()
		}
	}
}

func (cmd *appExaminerCommand) printDistribution() int {
	defer cmd.output.Say(cursor.ClearToEndOfDisplay())

	cells, err := cmd.appExaminer.ListCells()
	if err != nil {
		cmd.output.Say("Error visualizing: " + err.Error())
		cmd.output.Say(cursor.ClearToEndOfLine())
		cmd.output.NewLine()
		return 1
	}

	for _, cell := range cells {
		cmd.output.Say(cell.CellID)
		if cell.Missing {
			cmd.output.Say(colors.Red("[MISSING]"))
		}
		cmd.output.Say(": ")

		cmd.output.Say(colors.Green(strings.Repeat("•", cell.RunningInstances)))
		cmd.output.Say(colors.Yellow(strings.Repeat("•", cell.ClaimedInstances)))
		cmd.output.Say(cursor.ClearToEndOfLine())
		cmd.output.NewLine()
	}

	return len(cells)
}

func colorInstances(appInfo app_examiner.AppInfo) string {
	instances := fmt.Sprintf("%d/%d", appInfo.ActualRunningInstances, appInfo.DesiredInstances)
	if appInfo.ActualRunningInstances == appInfo.DesiredInstances {
		return colors.Green(instances)
	} else if appInfo.ActualRunningInstances == 0 {
		return colors.Red(instances)
	}

	return colors.Yellow(instances)
}
<commit_msg>Make app name bold in status output.<commit_after>package command_factory

import (
	"fmt"
	"strconv"
	"strings"
	"text/tabwriter"

	"github.com/cloudfoundry/gunk/timeprovider"
	"github.com/codegangsta/cli"
	"github.com/pivotal-cf-experimental/lattice-cli/app_examiner"
	"github.com/pivotal-cf-experimental/lattice-cli/app_examiner/command_factory/presentation"
	"github.com/pivotal-cf-experimental/lattice-cli/colors"
	"github.com/pivotal-cf-experimental/lattice-cli/output"
	"github.com/pivotal-cf-experimental/lattice-cli/output/cursor"
)

type AppExaminerCommandFactory struct {
	appExaminerCommand *appExaminerCommand
}

type exitHandler interface {
	OnExit(func())
}

func NewAppExaminerCommandFactory(appExaminer app_examiner.AppExaminer, output *output.Output, timeProvider timeprovider.TimeProvider, exitHandler exitHandler) *AppExaminerCommandFactory {
	return &AppExaminerCommandFactory{&appExaminerCommand{appExaminer, output, timeProvider, exitHandler}}
}

func (commandFactory *AppExaminerCommandFactory) MakeListAppCommand() cli.Command {

	var startCommand = cli.Command{
		Name:        "list",
		ShortName:   "li",
		Description: "List all apps on lattice.",
		Usage:       "ltc list",
		Action:      commandFactory.appExaminerCommand.listApps,
		Flags:       []cli.Flag{},
	}

	return startCommand
}

func (commandFactory *AppExaminerCommandFactory) MakeVisualizeCommand() cli.Command {

	var visualizeFlags = []cli.Flag{
		cli.DurationFlag{
			Name:  "rate, r",
			Usage: "The rate in seconds at which to refresh the visualization.",
		},
	}

	var startCommand = cli.Command{
		Name:        "visualize",
		Description: "Visualize Lattice Cells",
		Usage:       "ltc visualize",
		Action:      commandFactory.appExaminerCommand.visualizeCells,
		Flags:       visualizeFlags,
	}

	return startCommand
}

func (commandFactory *AppExaminerCommandFactory) MakeStatusCommand() cli.Command {
	return cli.Command{
		Name:        "status",
		Description: "Displays detailed status information about the app and its instances",
		Usage:       "ltc status",
		Action:      commandFactory.appExaminerCommand.appStatus,
		Flags:       []cli.Flag{},
	}
}

type appExaminerCommand struct {
	appExaminer  app_examiner.AppExaminer
	output       *output.Output
	timeProvider timeprovider.TimeProvider
	exitHandler  exitHandler
}

func (cmd *appExaminerCommand) listApps(context *cli.Context) {
	appList, err := cmd.appExaminer.ListApps()
	if err != nil {
		cmd.output.Say("Error listing apps: " + err.Error())
		return
	} else if len(appList) == 0 {
		cmd.output.Say("No apps to display.")
		return
	}

	w := &tabwriter.Writer{}
	w.Init(cmd.output, 10+colors.ColorCodeLength, 8, 1, '\t', 0)

	header := fmt.Sprintf("%s\t%s\t%s\t%s\t%s", colors.Bold("App Name"), colors.Bold("Instances"), colors.Bold("DiskMB"), colors.Bold("MemoryMB"), colors.Bold("Routes"))
	fmt.Fprintln(w, header)

	for _, appInfo := range appList {
		routes := strings.Join(appInfo.Routes, " ")

		fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", colors.Bold(appInfo.ProcessGuid), colorInstances(appInfo), colors.NoColor(strconv.Itoa(appInfo.DiskMB)), colors.NoColor(strconv.Itoa(appInfo.MemoryMB)), colors.Cyan(routes))
	}
	w.Flush()
}

func (cmd *appExaminerCommand) appStatus(context *cli.Context) {
	if len(context.Args()) < 1 {
		cmd.output.IncorrectUsage("App Name required")
		return
	}

	appName := context.Args()[0]
	appInfo, err := cmd.appExaminer.AppStatus(appName)

	if err != nil {
		cmd.output.Say(err.Error())
		return
	}

	minColumnWidth := 13
	w := tabwriter.NewWriter(cmd.output, minColumnWidth, 8, 1, '\t', 0)

	horizontalRule := func(pattern string) {
		header := strings.Repeat(pattern, 80) + "\n"
		fmt.Fprintf(w, header)
	}

	headingIndentation := strings.Repeat(" ", minColumnWidth/2)

	titleBar := func(title string) {
		horizontalRule("=")
		fmt.Fprintf(w, "%s%s\n", headingIndentation, title)
		horizontalRule("-")
	}

	titleBar(colors.Bold(appName))

	fmt.Fprintf(w, "%s\t%s\n", "Instances", colorInstances(appInfo))
	fmt.Fprintf(w, "%s\t%s\n", "Stack", appInfo.Stack)

	fmt.Fprintf(w, "%s\t%d\n", "Start Timeout", appInfo.StartTimeout)
	fmt.Fprintf(w, "%s\t%d\n", "DiskMB", appInfo.DiskMB)
	fmt.Fprintf(w, "%s\t%d\n", "MemoryMB", appInfo.MemoryMB)
	fmt.Fprintf(w, "%s\t%d\n", "CPUWeight", appInfo.CPUWeight)

	portStrings := make([]string, 0)
	for _, port := range appInfo.Ports {
		portStrings = append(portStrings, fmt.Sprint(port))
	}

	fmt.Fprintf(w, "%s\t%s\n", "Ports", strings.Join(portStrings, ","))
	fmt.Fprintf(w, "%s\t%s\n", "Routes", strings.Join(appInfo.Routes, " "))
	fmt.Fprintf(w, "%s\t%s\n", "LogGuid", appInfo.LogGuid)
	fmt.Fprintf(w, "%s\t%s\n", "LogSource", appInfo.LogSource)
	fmt.Fprintf(w, "%s\t%s\n", "Annotation", appInfo.Annotation)

	horizontalRule("-")
	var envVars string
	for _, envVar := range appInfo.EnvironmentVariables {
		envVars += envVar.Name + `="` + envVar.Value + `" ` + "\n"
	}
	fmt.Fprintf(w, "%s\n\n%s", "Environment", envVars)

	fmt.Fprintln(w, "")
	horizontalRule("=")

	instanceBar := func(index, state string) {
		fmt.Fprintf(w, "%sInstance %s  [%s]\n", headingIndentation, index, state)
		horizontalRule("-")
	}

	for _, instance := range appInfo.ActualInstances {
		instanceBar(fmt.Sprint(instance.Index), presentation.ColorInstanceState(instance.State))

		fmt.Fprintf(w, "%s\t%s\n", "InstanceGuid", instance.InstanceGuid)
		fmt.Fprintf(w, "%s\t%s\n", "Cell ID", instance.CellID)
		fmt.Fprintf(w, "%s\t%s\n", "Ip", instance.Ip)

		portMappingStrings := make([]string, 0)
		for _, portMapping := range instance.Ports {
			portMappingStrings = append(portMappingStrings, fmt.Sprintf("%d:%d", portMapping.HostPort, portMapping.ContainerPort))
		}
		fmt.Fprintf(w, "%s\t%s\n", "Ports", strings.Join(portMappingStrings, ";"))

		fmt.Fprintf(w, "%s\t%s\n", "Since", fmt.Sprint(instance.Since))

		horizontalRule("-")
	}

	w.Flush()
}

func (cmd *appExaminerCommand) visualizeCells(context *cli.Context) {
	rate := context.Duration("rate")

	cmd.output.Say(colors.Bold("Distribution\n"))
	linesWritten := cmd.printDistribution()

	if rate == 0 {
		return
	}

	closeChan := make(chan bool)
	cmd.output.Say(cursor.Hide())

	cmd.exitHandler.OnExit(func() {
		closeChan <- true
		cmd.output.Say(cursor.Show())
	})

	for {
		select {
		case <-closeChan:
			return
		case <-cmd.timeProvider.NewTimer(rate).C():
			cmd.output.Say(cursor.Up(linesWritten))
			linesWritten = cmd.printDistribution()
		}
	}
}

func (cmd *appExaminerCommand) printDistribution() int {
	defer cmd.output.Say(cursor.ClearToEndOfDisplay())

	cells, err := cmd.appExaminer.ListCells()
	if err != nil {
		cmd.output.Say("Error visualizing: " + err.Error())
		cmd.output.Say(cursor.ClearToEndOfLine())
		cmd.output.NewLine()
		return 1
	}

	for _, cell := range cells {
		cmd.output.Say(cell.CellID)
		if cell.Missing {
			cmd.output.Say(colors.Red("[MISSING]"))
		}
		cmd.output.Say(": ")

		cmd.output.Say(colors.Green(strings.Repeat("•", cell.RunningInstances)))
		cmd.output.Say(colors.Yellow(strings.Repeat("•", cell.ClaimedInstances)))
		cmd.output.Say(cursor.ClearToEndOfLine())
		cmd.output.NewLine()
	}

	return len(cells)
}

func colorInstances(appInfo app_examiner.AppInfo) string {
	instances := fmt.Sprintf("%d/%d", appInfo.ActualRunningInstances, appInfo.DesiredInstances)
	if appInfo.ActualRunningInstances == appInfo.DesiredInstances {
		return colors.Green(instances)
	} else if appInfo.ActualRunningInstances == 0 {
		return colors.Red(instances)
	}

	return colors.Yellow(instances)
}
<|endoftext|>


<commit_before>// Copyright 2017 Intel Corporation.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package packet

import (
	. "github.com/intel-go/yanff/common"
	"unsafe"
)

// Calculates checksum of memory for a given pointer. Length and
// offset are in bytes. Offset is signed, so negative offset is
// possible. Checksum is calculated in uint16 words. Returned is
// checksum with carry, so carry should be added and value negated for
// use as network checksum.
func calculateDataChecksum(ptr unsafe.Pointer, length, offset int) uint32 {
	var sum uint32
	uptr := uintptr(ptr) + uintptr(offset)

	slice := (*[1 << 30]uint16)(unsafe.Pointer(uptr))[0 : length/2]
	for i := range slice {
		sum += uint32(SwapBytesUint16(slice[i]))
	}

	if length&1 != 0 {
		sum += uint32(*(*byte)(unsafe.Pointer(uptr + uintptr(length-1)))) << 8
	}

	return sum
}

// CalculatePseudoHdrIPv4TCPCksum implements one step of TCP checksum calculation. Separately computes checksum
// for TCP pseudo-header for case if L3 protocol is IPv4.
// This precalculation is required for checksum compute by hardware offload.
// Result should be put into TCP.Cksum field. See test_cksum as an example.
func CalculatePseudoHdrIPv4TCPCksum(hdr *IPv4Hdr) uint16 {
	dataLength := SwapBytesUint16(hdr.TotalLength) - IPv4MinLen
	pHdrCksum := calculateIPv4AddrChecksum(hdr) +
		uint32(hdr.NextProtoID) +
		uint32(dataLength)
	return reduceChecksum(pHdrCksum)
}

// CalculatePseudoHdrIPv4UDPCksum implements one step of UDP checksum calculation. Separately computes checksum
// for TCP pseudo-header for case if L3 protocol is IPv4.
// This precalculation is required for checksum compute by hardware offload.
// Result should be put into UDP.DgramCksum field. See test_cksum as an example.
func CalculatePseudoHdrIPv4UDPCksum(hdr *IPv4Hdr, udp *UDPHdr) uint16 {
	pHdrCksum := calculateIPv4AddrChecksum(hdr) +
		uint32(hdr.NextProtoID) +
		uint32(SwapBytesUint16(udp.DgramLen))
	return reduceChecksum(pHdrCksum)
}

// CalculatePseudoHdrIPv6TCPCksum implements one step of TCP checksum calculation. Separately computes checksum
// for TCP pseudo-header for case if L3 protocol is IPv6.
// This precalculation is required for checksum compute by hardware offload.
// Result should be put into TCP.Cksum field. See test_cksum as an example.
func CalculatePseudoHdrIPv6TCPCksum(hdr *IPv6Hdr) uint16 {
	dataLength := SwapBytesUint16(hdr.PayloadLen)
	pHdrCksum := calculateIPv6AddrChecksum(hdr) +
		uint32(dataLength) +
		uint32(hdr.Proto)
	return reduceChecksum(pHdrCksum)
}

// CalculatePseudoHdrIPv6UDPCksum implements one step of UDP checksum calculation. Separately computes checksum
// for UDP pseudo-header for case if L3 protocol is IPv6.
// This precalculation is required for checksum compute by hardware offload.
// Result should be put into UDP.DgramCksum field. See test_cksum as an example.
func CalculatePseudoHdrIPv6UDPCksum(hdr *IPv6Hdr, udp *UDPHdr) uint16 {
	pHdrCksum := calculateIPv6AddrChecksum(hdr) +
		uint32(hdr.Proto) +
		uint32(SwapBytesUint16(udp.DgramLen))
	return reduceChecksum(pHdrCksum)
}

// SetPseudoHdrChecksum makes precalculation of pseudo header checksum. Separately computes
// checksum for required pseudo-header and writes result to correct place. This
// is required for checksum compute by hardware offload.
func SetPseudoHdrChecksum(p *Packet) {
	ipv4, ipv6 := p.ParseAllKnownL3()
	if ipv4 != nil {
		p.GetIPv4().HdrChecksum = 0
		tcp, udp, _ := p.ParseAllKnownL4ForIPv4()
		if tcp != nil {
			p.GetTCPForIPv4().Cksum = SwapBytesUint16(CalculatePseudoHdrIPv4TCPCksum(p.GetIPv4()))
		} else if udp != nil {
			p.GetUDPForIPv4().DgramCksum = SwapBytesUint16(CalculatePseudoHdrIPv4UDPCksum(p.GetIPv4(), p.GetUDPForIPv4()))
		}
	} else if ipv6 != nil {
		tcp, udp, _ := p.ParseAllKnownL4ForIPv6()
		if tcp != nil {
			p.GetTCPForIPv6().Cksum = SwapBytesUint16(CalculatePseudoHdrIPv6TCPCksum(p.GetIPv6()))
		} else if udp != nil {
			p.GetUDPForIPv6().DgramCksum = SwapBytesUint16(CalculatePseudoHdrIPv6UDPCksum(p.GetIPv6(), p.GetUDPForIPv6()))
		}
	}
}

func reduceChecksum(sum uint32) uint16 {
	for sum > 0xffff {
		sum = (sum >> 16) + (sum & 0xffff)
	}
	return uint16(sum)
}

// CalculateIPv4Checksum calculates checksum of IP header
func CalculateIPv4Checksum(p *Packet) uint16 {
	var sum uint32
	hdr := p.GetIPv4()
	sum = uint32(hdr.VersionIhl)<<8 + uint32(hdr.TypeOfService) +
		uint32(SwapBytesUint16(hdr.TotalLength)) +
		uint32(SwapBytesUint16(hdr.PacketID)) +
		uint32(SwapBytesUint16(hdr.FragmentOffset)) +
		uint32(hdr.TimeToLive)<<8 + uint32(hdr.NextProtoID) +
		uint32(SwapBytesUint16(uint16(hdr.SrcAddr>>16))) +
		uint32(SwapBytesUint16(uint16(hdr.SrcAddr))) +
		uint32(SwapBytesUint16(uint16(hdr.DstAddr>>16))) +
		uint32(SwapBytesUint16(uint16(hdr.DstAddr)))

	return ^reduceChecksum(sum)
}

func calculateIPv4AddrChecksum(hdr *IPv4Hdr) uint32 {
	return uint32(SwapBytesUint16(uint16(hdr.SrcAddr>>16))) +
		uint32(SwapBytesUint16(uint16(hdr.SrcAddr))) +
		uint32(SwapBytesUint16(uint16(hdr.DstAddr>>16))) +
		uint32(SwapBytesUint16(uint16(hdr.DstAddr)))
}

// CalculateIPv4UDPChecksum calculates UDP checksum for case if L3 protocol is IPv4.
func CalculateIPv4UDPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv4()
	udp := p.GetUDPForIPv4()
	dataLength := SwapBytesUint16(hdr.TotalLength) - IPv4MinLen

	sum := calculateDataChecksum(p.Data, int(dataLength-UDPLen), 0)

	sum += calculateIPv4AddrChecksum(hdr) +
		uint32(hdr.NextProtoID) +
		uint32(SwapBytesUint16(udp.DgramLen)) +
		uint32(SwapBytesUint16(udp.SrcPort)) +
		uint32(SwapBytesUint16(udp.DstPort)) +
		uint32(SwapBytesUint16(udp.DgramLen))

	return ^reduceChecksum(sum)
}

func calculateTCPChecksum(tcp *TCPHdr) uint32 {
	return uint32(SwapBytesUint16(tcp.SrcPort)) +
		uint32(SwapBytesUint16(tcp.DstPort)) +
		uint32(SwapBytesUint16(uint16(tcp.SentSeq>>16))) +
		uint32(SwapBytesUint16(uint16(tcp.SentSeq))) +
		uint32(SwapBytesUint16(uint16(tcp.RecvAck>>16))) +
		uint32(SwapBytesUint16(uint16(tcp.RecvAck))) +
		uint32(tcp.DataOff)<<8 +
		uint32(tcp.TCPFlags) +
		uint32(SwapBytesUint16(tcp.RxWin)) +
		uint32(SwapBytesUint16(tcp.TCPUrp))
}

// CalculateIPv4TCPChecksum calculates TCP checksum for case if L3 protocol is IPv4.
func CalculateIPv4TCPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv4()
	tcp := p.GetTCPForIPv4()

	dataLength := SwapBytesUint16(hdr.TotalLength) - IPv4MinLen

	sum := calculateDataChecksum(p.Data, int(dataLength-TCPMinLen), 0)

	sum += calculateIPv4AddrChecksum(hdr) +
		uint32(hdr.NextProtoID) +
		uint32(dataLength) +
		calculateTCPChecksum(tcp)

	return ^reduceChecksum(sum)
}

func calculateIPv6AddrChecksum(hdr *IPv6Hdr) uint32 {
	return uint32(uint16(hdr.SrcAddr[0])<<8|uint16(hdr.SrcAddr[1])) +
		uint32(uint16(hdr.SrcAddr[2])<<8|uint16(hdr.SrcAddr[3])) +
		uint32(uint16(hdr.SrcAddr[4])<<8|uint16(hdr.SrcAddr[5])) +
		uint32(uint16(hdr.SrcAddr[6])<<8|uint16(hdr.SrcAddr[7])) +
		uint32(uint16(hdr.SrcAddr[8])<<8|uint16(hdr.SrcAddr[9])) +
		uint32(uint16(hdr.SrcAddr[10])<<8|uint16(hdr.SrcAddr[11])) +
		uint32(uint16(hdr.SrcAddr[12])<<8|uint16(hdr.SrcAddr[13])) +
		uint32(uint16(hdr.SrcAddr[14])<<8|uint16(hdr.SrcAddr[15])) +
		uint32(uint16(hdr.DstAddr[0])<<8|uint16(hdr.DstAddr[1])) +
		uint32(uint16(hdr.DstAddr[2])<<8|uint16(hdr.DstAddr[3])) +
		uint32(uint16(hdr.DstAddr[4])<<8|uint16(hdr.DstAddr[5])) +
		uint32(uint16(hdr.DstAddr[6])<<8|uint16(hdr.DstAddr[7])) +
		uint32(uint16(hdr.DstAddr[8])<<8|uint16(hdr.DstAddr[9])) +
		uint32(uint16(hdr.DstAddr[10])<<8|uint16(hdr.DstAddr[11])) +
		uint32(uint16(hdr.DstAddr[12])<<8|uint16(hdr.DstAddr[13])) +
		uint32(uint16(hdr.DstAddr[14])<<8|uint16(hdr.DstAddr[15]))
}

// CalculateIPv6UDPChecksum calculates UDP checksum for case if L3 protocol is IPv6.
func CalculateIPv6UDPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv6()
	udp := p.GetUDPForIPv6()
	dataLength := SwapBytesUint16(hdr.PayloadLen)

	sum := calculateDataChecksum(p.Data, int(dataLength-UDPLen), 0)

	sum += calculateIPv6AddrChecksum(hdr) +
		uint32(SwapBytesUint16(udp.DgramLen)) +
		uint32(hdr.Proto) +
		uint32(SwapBytesUint16(udp.SrcPort)) +
		uint32(SwapBytesUint16(udp.DstPort)) +
		uint32(SwapBytesUint16(udp.DgramLen))

	return ^reduceChecksum(sum)
}

// CalculateIPv6TCPChecksum calculates TCP checksum for case if L3 protocol is IPv6.
func CalculateIPv6TCPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv6()
	tcp := p.GetTCPForIPv4()
	dataLength := SwapBytesUint16(hdr.PayloadLen)

	sum := calculateDataChecksum(p.Data, int(dataLength-TCPMinLen), 0)

	sum += calculateIPv6AddrChecksum(hdr) +
		uint32(dataLength) +
		uint32(hdr.Proto) +
		calculateTCPChecksum(tcp)

	return ^reduceChecksum(sum)
}

// CalculateIPv4ICMPChecksum calculates ICMP checksum in case if L3 protocol is IPv4.
func CalculateIPv4ICMPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv4()
	dataLength := SwapBytesUint16(hdr.TotalLength) - IPv4MinLen

	sum := calculateDataChecksum(unsafe.Pointer(p.GetICMPForIPv4()), int(dataLength), 0)

	return ^reduceChecksum(sum)
}

// CalculateIPv6ICMPChecksum calculates ICMP checksum in case if L3 protocol is IPv6.
func CalculateIPv6ICMPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv6()
	dataLength := SwapBytesUint16(hdr.PayloadLen)

	sum := calculateDataChecksum(unsafe.Pointer(p.GetICMPForIPv6()), int(dataLength), 0)

	return ^reduceChecksum(sum)
}
<commit_msg>Bugfix: segfault in packet.CalculateIPv6TCPChecksum<commit_after>// Copyright 2017 Intel Corporation.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package packet

import (
	. "github.com/intel-go/yanff/common"
	"unsafe"
)

// Calculates checksum of memory for a given pointer. Length and
// offset are in bytes. Offset is signed, so negative offset is
// possible. Checksum is calculated in uint16 words. Returned is
// checksum with carry, so carry should be added and value negated for
// use as network checksum.
func calculateDataChecksum(ptr unsafe.Pointer, length, offset int) uint32 {
	var sum uint32
	uptr := uintptr(ptr) + uintptr(offset)

	slice := (*[1 << 30]uint16)(unsafe.Pointer(uptr))[0 : length/2]
	for i := range slice {
		sum += uint32(SwapBytesUint16(slice[i]))
	}

	if length&1 != 0 {
		sum += uint32(*(*byte)(unsafe.Pointer(uptr + uintptr(length-1)))) << 8
	}

	return sum
}

// CalculatePseudoHdrIPv4TCPCksum implements one step of TCP checksum calculation. Separately computes checksum
// for TCP pseudo-header for case if L3 protocol is IPv4.
// This precalculation is required for checksum compute by hardware offload.
// Result should be put into TCP.Cksum field. See test_cksum as an example.
func CalculatePseudoHdrIPv4TCPCksum(hdr *IPv4Hdr) uint16 {
	dataLength := SwapBytesUint16(hdr.TotalLength) - IPv4MinLen
	pHdrCksum := calculateIPv4AddrChecksum(hdr) +
		uint32(hdr.NextProtoID) +
		uint32(dataLength)
	return reduceChecksum(pHdrCksum)
}

// CalculatePseudoHdrIPv4UDPCksum implements one step of UDP checksum calculation. Separately computes checksum
// for TCP pseudo-header for case if L3 protocol is IPv4.
// This precalculation is required for checksum compute by hardware offload.
// Result should be put into UDP.DgramCksum field. See test_cksum as an example.
func CalculatePseudoHdrIPv4UDPCksum(hdr *IPv4Hdr, udp *UDPHdr) uint16 {
	pHdrCksum := calculateIPv4AddrChecksum(hdr) +
		uint32(hdr.NextProtoID) +
		uint32(SwapBytesUint16(udp.DgramLen))
	return reduceChecksum(pHdrCksum)
}

// CalculatePseudoHdrIPv6TCPCksum implements one step of TCP checksum calculation. Separately computes checksum
// for TCP pseudo-header for case if L3 protocol is IPv6.
// This precalculation is required for checksum compute by hardware offload.
// Result should be put into TCP.Cksum field. See test_cksum as an example.
func CalculatePseudoHdrIPv6TCPCksum(hdr *IPv6Hdr) uint16 {
	dataLength := SwapBytesUint16(hdr.PayloadLen)
	pHdrCksum := calculateIPv6AddrChecksum(hdr) +
		uint32(dataLength) +
		uint32(hdr.Proto)
	return reduceChecksum(pHdrCksum)
}

// CalculatePseudoHdrIPv6UDPCksum implements one step of UDP checksum calculation. Separately computes checksum
// for UDP pseudo-header for case if L3 protocol is IPv6.
// This precalculation is required for checksum compute by hardware offload.
// Result should be put into UDP.DgramCksum field. See test_cksum as an example.
func CalculatePseudoHdrIPv6UDPCksum(hdr *IPv6Hdr, udp *UDPHdr) uint16 {
	pHdrCksum := calculateIPv6AddrChecksum(hdr) +
		uint32(hdr.Proto) +
		uint32(SwapBytesUint16(udp.DgramLen))
	return reduceChecksum(pHdrCksum)
}

// SetPseudoHdrChecksum makes precalculation of pseudo header checksum. Separately computes
// checksum for required pseudo-header and writes result to correct place. This
// is required for checksum compute by hardware offload.
func SetPseudoHdrChecksum(p *Packet) {
	ipv4, ipv6 := p.ParseAllKnownL3()
	if ipv4 != nil {
		p.GetIPv4().HdrChecksum = 0
		tcp, udp, _ := p.ParseAllKnownL4ForIPv4()
		if tcp != nil {
			p.GetTCPForIPv4().Cksum = SwapBytesUint16(CalculatePseudoHdrIPv4TCPCksum(p.GetIPv4()))
		} else if udp != nil {
			p.GetUDPForIPv4().DgramCksum = SwapBytesUint16(CalculatePseudoHdrIPv4UDPCksum(p.GetIPv4(), p.GetUDPForIPv4()))
		}
	} else if ipv6 != nil {
		tcp, udp, _ := p.ParseAllKnownL4ForIPv6()
		if tcp != nil {
			p.GetTCPForIPv6().Cksum = SwapBytesUint16(CalculatePseudoHdrIPv6TCPCksum(p.GetIPv6()))
		} else if udp != nil {
			p.GetUDPForIPv6().DgramCksum = SwapBytesUint16(CalculatePseudoHdrIPv6UDPCksum(p.GetIPv6(), p.GetUDPForIPv6()))
		}
	}
}

func reduceChecksum(sum uint32) uint16 {
	for sum > 0xffff {
		sum = (sum >> 16) + (sum & 0xffff)
	}
	return uint16(sum)
}

// CalculateIPv4Checksum calculates checksum of IP header
func CalculateIPv4Checksum(p *Packet) uint16 {
	var sum uint32
	hdr := p.GetIPv4()
	sum = uint32(hdr.VersionIhl)<<8 + uint32(hdr.TypeOfService) +
		uint32(SwapBytesUint16(hdr.TotalLength)) +
		uint32(SwapBytesUint16(hdr.PacketID)) +
		uint32(SwapBytesUint16(hdr.FragmentOffset)) +
		uint32(hdr.TimeToLive)<<8 + uint32(hdr.NextProtoID) +
		uint32(SwapBytesUint16(uint16(hdr.SrcAddr>>16))) +
		uint32(SwapBytesUint16(uint16(hdr.SrcAddr))) +
		uint32(SwapBytesUint16(uint16(hdr.DstAddr>>16))) +
		uint32(SwapBytesUint16(uint16(hdr.DstAddr)))

	return ^reduceChecksum(sum)
}

func calculateIPv4AddrChecksum(hdr *IPv4Hdr) uint32 {
	return uint32(SwapBytesUint16(uint16(hdr.SrcAddr>>16))) +
		uint32(SwapBytesUint16(uint16(hdr.SrcAddr))) +
		uint32(SwapBytesUint16(uint16(hdr.DstAddr>>16))) +
		uint32(SwapBytesUint16(uint16(hdr.DstAddr)))
}

// CalculateIPv4UDPChecksum calculates UDP checksum for case if L3 protocol is IPv4.
func CalculateIPv4UDPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv4()
	udp := p.GetUDPForIPv4()
	dataLength := SwapBytesUint16(hdr.TotalLength) - IPv4MinLen

	sum := calculateDataChecksum(p.Data, int(dataLength-UDPLen), 0)

	sum += calculateIPv4AddrChecksum(hdr) +
		uint32(hdr.NextProtoID) +
		uint32(SwapBytesUint16(udp.DgramLen)) +
		uint32(SwapBytesUint16(udp.SrcPort)) +
		uint32(SwapBytesUint16(udp.DstPort)) +
		uint32(SwapBytesUint16(udp.DgramLen))

	return ^reduceChecksum(sum)
}

func calculateTCPChecksum(tcp *TCPHdr) uint32 {
	return uint32(SwapBytesUint16(tcp.SrcPort)) +
		uint32(SwapBytesUint16(tcp.DstPort)) +
		uint32(SwapBytesUint16(uint16(tcp.SentSeq>>16))) +
		uint32(SwapBytesUint16(uint16(tcp.SentSeq))) +
		uint32(SwapBytesUint16(uint16(tcp.RecvAck>>16))) +
		uint32(SwapBytesUint16(uint16(tcp.RecvAck))) +
		uint32(tcp.DataOff)<<8 +
		uint32(tcp.TCPFlags) +
		uint32(SwapBytesUint16(tcp.RxWin)) +
		uint32(SwapBytesUint16(tcp.TCPUrp))
}

// CalculateIPv4TCPChecksum calculates TCP checksum for case if L3 protocol is IPv4.
func CalculateIPv4TCPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv4()
	tcp := p.GetTCPForIPv4()

	dataLength := SwapBytesUint16(hdr.TotalLength) - IPv4MinLen

	sum := calculateDataChecksum(p.Data, int(dataLength-TCPMinLen), 0)

	sum += calculateIPv4AddrChecksum(hdr) +
		uint32(hdr.NextProtoID) +
		uint32(dataLength) +
		calculateTCPChecksum(tcp)

	return ^reduceChecksum(sum)
}

func calculateIPv6AddrChecksum(hdr *IPv6Hdr) uint32 {
	return uint32(uint16(hdr.SrcAddr[0])<<8|uint16(hdr.SrcAddr[1])) +
		uint32(uint16(hdr.SrcAddr[2])<<8|uint16(hdr.SrcAddr[3])) +
		uint32(uint16(hdr.SrcAddr[4])<<8|uint16(hdr.SrcAddr[5])) +
		uint32(uint16(hdr.SrcAddr[6])<<8|uint16(hdr.SrcAddr[7])) +
		uint32(uint16(hdr.SrcAddr[8])<<8|uint16(hdr.SrcAddr[9])) +
		uint32(uint16(hdr.SrcAddr[10])<<8|uint16(hdr.SrcAddr[11])) +
		uint32(uint16(hdr.SrcAddr[12])<<8|uint16(hdr.SrcAddr[13])) +
		uint32(uint16(hdr.SrcAddr[14])<<8|uint16(hdr.SrcAddr[15])) +
		uint32(uint16(hdr.DstAddr[0])<<8|uint16(hdr.DstAddr[1])) +
		uint32(uint16(hdr.DstAddr[2])<<8|uint16(hdr.DstAddr[3])) +
		uint32(uint16(hdr.DstAddr[4])<<8|uint16(hdr.DstAddr[5])) +
		uint32(uint16(hdr.DstAddr[6])<<8|uint16(hdr.DstAddr[7])) +
		uint32(uint16(hdr.DstAddr[8])<<8|uint16(hdr.DstAddr[9])) +
		uint32(uint16(hdr.DstAddr[10])<<8|uint16(hdr.DstAddr[11])) +
		uint32(uint16(hdr.DstAddr[12])<<8|uint16(hdr.DstAddr[13])) +
		uint32(uint16(hdr.DstAddr[14])<<8|uint16(hdr.DstAddr[15]))
}

// CalculateIPv6UDPChecksum calculates UDP checksum for case if L3 protocol is IPv6.
func CalculateIPv6UDPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv6()
	udp := p.GetUDPForIPv6()
	dataLength := SwapBytesUint16(hdr.PayloadLen)

	sum := calculateDataChecksum(p.Data, int(dataLength-UDPLen), 0)

	sum += calculateIPv6AddrChecksum(hdr) +
		uint32(SwapBytesUint16(udp.DgramLen)) +
		uint32(hdr.Proto) +
		uint32(SwapBytesUint16(udp.SrcPort)) +
		uint32(SwapBytesUint16(udp.DstPort)) +
		uint32(SwapBytesUint16(udp.DgramLen))

	return ^reduceChecksum(sum)
}

// CalculateIPv6TCPChecksum calculates TCP checksum for case if L3 protocol is IPv6.
func CalculateIPv6TCPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv6()
	tcp := p.GetTCPForIPv6()
	dataLength := SwapBytesUint16(hdr.PayloadLen)

	sum := calculateDataChecksum(p.Data, int(dataLength-TCPMinLen), 0)

	sum += calculateIPv6AddrChecksum(hdr) +
		uint32(dataLength) +
		uint32(hdr.Proto) +
		calculateTCPChecksum(tcp)

	return ^reduceChecksum(sum)
}

// CalculateIPv4ICMPChecksum calculates ICMP checksum in case if L3 protocol is IPv4.
func CalculateIPv4ICMPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv4()
	dataLength := SwapBytesUint16(hdr.TotalLength) - IPv4MinLen

	sum := calculateDataChecksum(unsafe.Pointer(p.GetICMPForIPv4()), int(dataLength), 0)

	return ^reduceChecksum(sum)
}

// CalculateIPv6ICMPChecksum calculates ICMP checksum in case if L3 protocol is IPv6.
func CalculateIPv6ICMPChecksum(p *Packet) uint16 {
	hdr := p.GetIPv6()
	dataLength := SwapBytesUint16(hdr.PayloadLen)

	sum := calculateDataChecksum(unsafe.Pointer(p.GetICMPForIPv6()), int(dataLength), 0)

	return ^reduceChecksum(sum)
}
<|endoftext|>


<commit_before>package page

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
)

func serve() *httptest.Server {
	return httptest.NewServer(http.FileServer(http.Dir("test")))
}

func ExampleNew() {
	s := serve()
	defer s.Close()
	p, _ := New(context.Background(), s.URL+"/external.html")
	fmt.Printf("%s: %s\n", p.HTML.URL.Path, p.HTML.Body)
	fmt.Printf("%s: %s\n", p.CSS[0].URL.Path, p.CSS[0].Body)
	// Output:
	// /external.html: <link rel="stylesheet" href="style.css">
	// /style.css: body { color: #c0c0c0 }
}

// Test fetching a HTML file with no external CSS.
func TestNewSimple(t *testing.T) {
	s := serve()
	defer s.Close()
	p, err := New(context.Background(), s.URL + "/embedded.html")
	if err != nil {
		t.Fatal(err)
	}
	if p.HTML.Body == "" {
		t.Fatal("Body must not be empty")
	}
	if len(p.CSS) != 0 {
		t.Fatalf("Must not have any CSS files")
	}
}

// Test fetching a HTML file with one external CSS file.
func TestNewExternal(t *testing.T) {
	s := serve()
	defer s.Close()
	p, err := New(context.Background(), s.URL + "/external.html")
	if err != nil {
		t.Fatal(err)
	}
	if p.HTML.Body == "" {
		t.Fatal("Body must not be empty")
	}
	if p.Count() != 2 {
		t.Fatal("Count must be 2: HTML & CSS")
	}
	if p.CSS[0].Body == "" {
		t.Fatal("Body of CSS file must not be empty")
	}
	if p.Size() <= 0 {
		t.Fatal("Size must be greater than 0")
	}
}

func TestNewErrorWhenHTMLMissing(t *testing.T) {
	s := serve()
	defer s.Close()
	_, err := New(context.Background(), s.URL + "/404.html")
	if err == nil {
		t.Fatal("Must return error on anything but HTTP status 200")
	}
}

func TestNewNoErrorWhenMissingExternal(t *testing.T) {
	s := serve()
	defer s.Close()
	_, err := New(context.Background(), s.URL + "/missingexternal.html")
	if err != nil {
		t.Fatal("Must not return error when missing external CSS files")
	}
}

func TestNewNoErrorWhenInvalidExternalURL(t *testing.T) {
	s := serve()
	defer s.Close()
	_, err := New(context.Background(), s.URL + "/invalidexternal.html")
	if err != nil {
		t.Fatalf("Must not return error when external URLs are invalid: %s", err)
	}
}

func TestNewInvalidHost(t *testing.T) {
	_, err := New(context.Background(), "http://Ksm3Acmkk.foobar/")
	if err == nil {
		t.Fatal("Must return error for unknown domain")
	}
}
<commit_msg>Apply CS fixes<commit_after>package page

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
)

func serve() *httptest.Server {
	return httptest.NewServer(http.FileServer(http.Dir("test")))
}

func ExampleNew() {
	s := serve()
	defer s.Close()
	p, _ := New(context.Background(), s.URL+"/external.html")
	fmt.Printf("%s: %s\n", p.HTML.URL.Path, p.HTML.Body)
	fmt.Printf("%s: %s\n", p.CSS[0].URL.Path, p.CSS[0].Body)
	// Output:
	// /external.html: <link rel="stylesheet" href="style.css">
	// /style.css: body { color: #c0c0c0 }
}

// Test fetching a HTML file with no external CSS.
func TestNewSimple(t *testing.T) {
	s := serve()
	defer s.Close()
	p, err := New(context.Background(), s.URL+"/embedded.html")
	if err != nil {
		t.Fatal(err)
	}
	if p.HTML.Body == "" {
		t.Fatal("Body must not be empty")
	}
	if len(p.CSS) != 0 {
		t.Fatalf("Must not have any CSS files")
	}
}

// Test fetching a HTML file with one external CSS file.
func TestNewExternal(t *testing.T) {
	s := serve()
	defer s.Close()
	p, err := New(context.Background(), s.URL+"/external.html")
	if err != nil {
		t.Fatal(err)
	}
	if p.HTML.Body == "" {
		t.Fatal("Body must not be empty")
	}
	if p.Count() != 2 {
		t.Fatal("Count must be 2: HTML & CSS")
	}
	if p.CSS[0].Body == "" {
		t.Fatal("Body of CSS file must not be empty")
	}
	if p.Size() <= 0 {
		t.Fatal("Size must be greater than 0")
	}
}

func TestNewErrorWhenHTMLMissing(t *testing.T) {
	s := serve()
	defer s.Close()
	_, err := New(context.Background(), s.URL+"/404.html")
	if err == nil {
		t.Fatal("Must return error on anything but HTTP status 200")
	}
}

func TestNewNoErrorWhenMissingExternal(t *testing.T) {
	s := serve()
	defer s.Close()
	_, err := New(context.Background(), s.URL+"/missingexternal.html")
	if err != nil {
		t.Fatal("Must not return error when missing external CSS files")
	}
}

func TestNewNoErrorWhenInvalidExternalURL(t *testing.T) {
	s := serve()
	defer s.Close()
	_, err := New(context.Background(), s.URL+"/invalidexternal.html")
	if err != nil {
		t.Fatalf("Must not return error when external URLs are invalid: %s", err)
	}
}

func TestNewInvalidHost(t *testing.T) {
	_, err := New(context.Background(), "http://Ksm3Acmkk.foobar/")
	if err == nil {
		t.Fatal("Must return error for unknown domain")
	}
}
<|endoftext|>


<commit_before>package glpclient

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"sync/atomic"
	"time"
)

const (
	DEFAULT_TIMEOUT   = 30
	DEFAULT_REATTEMPT = 30
)

type PollResponse struct {
	Events    []PollEvent `json:"events"`
	Timestamp int64       `json:"timestamp"`
}

// Taken from https://github.com/jcuga/golongpoll/blob/master/events.go
type PollEvent struct {
	// Timestamp is milliseconds since epoch to match javascrits Date.getTime()
	Timestamp int64  `json:"timestamp"`
	Category  string `json:"category"`
	// NOTE: Data can be anything that is able to passed to json.Marshal()
	Data json.RawMessage `json:"data"`
}

type Client struct {
	url      *url.URL
	category string
	// Timeout controls the timeout in all the requests, can be changed after instantiating the client
	Timeout uint64
	// Reattempt controls the amount of time the client waits to reconnect to the server after a failure
	Reattempt uint64
	// Will get all the events data
	EventsChan chan json.RawMessage
	// Flag that tracks the current run ID
	runID uint64
	// The HTTP client to perform the requests, any changes on this should be done prior to starting the client the first time
	HttpClient *http.Client
}

// Instantiate a new client to connect to a given URL and send the events into a channel
// The URL shouldn't contain any GET parameters although its fine if it contains some but category, since_time and timeout will be overriten
// stubChanData must either be an empty structure of the events data or a map[string]interface{} if the events do not follow a specific structure
func NewClient(url *url.URL, category string) *Client {
	return &Client{
		url:        url,
		category:   category,
		Timeout:    DEFAULT_TIMEOUT,
		Reattempt:  DEFAULT_REATTEMPT,
		EventsChan: make(chan json.RawMessage),
		HttpClient: &http.Client{},
	}
}

// Start the polling of the events on the URL defined in the client
// Will send the events in the EventsChan of the client
func (c *Client) Start() {
	u := c.url
	fmt.Println("Now observing changes on", u.String())

	atomic.AddUint64(&(c.runID), 1)
	currentRunID := atomic.LoadUint64(&(c.runID))

	go func(runID uint64, u *url.URL) {
		since := time.Now().Unix() * 1000
		for {
			pr, err := c.fetchEvents(since)

			if err != nil {
				fmt.Println(err)
				fmt.Printf("Reattempting to connect to %s in %d seconds \n", u.String(), c.Reattempt)
				time.Sleep(time.Duration(c.Reattempt) * time.Second)
				continue
			}

			// We check that its still the same runID as when this goroutine was started
			clientRunID := atomic.LoadUint64(&(c.runID))
			if clientRunID != runID {
				fmt.Printf("Client on URL %s has been stopped, not sending events \n", u.String())
				return
			}

			if len(pr.Events) > 0 {
				fmt.Println("Got", len(pr.Events), "event(s) from URL", u.String())
				for _, event := range pr.Events {
					since = event.Timestamp
					c.EventsChan <- event.Data
				}
			} else {
				// Only push timestamp forward if its greater than the last we checked
				if pr.Timestamp > since {
					since = pr.Timestamp
				}
			}
		}
	}(currentRunID, u)
}

func (c *Client) Stop() {
	// Changing the runID will have any previous goroutine ignore any events it may receive
	atomic.AddUint64(&(c.runID), 1)
}

func (c Client) fetchEvents(since int64) (PollResponse, error) {
	u := c.url
	fmt.Println("Checking for changes events since", since, "on URL", u.String())

	query := u.Query()
	query.Set("category", c.category)
	query.Set("since_time", fmt.Sprintf("%d", since))
	query.Set("timeout", fmt.Sprintf("%d", c.Timeout))
	u.RawQuery = query.Encode()

	resp, err := c.HttpClient.Get(u.String())
	if err != nil {
		msg := fmt.Sprintf("Error while connecting to %s to observe changes. Error was: %s", u, err)
		return PollResponse{}, errors.New(msg)
	}

	decoder := json.NewDecoder(resp.Body)
	defer resp.Body.Close()

	var pr PollResponse
	err = decoder.Decode(&pr)
	if err != nil {
		fmt.Errorf("Error while decoding poll response: %s", err)
		return PollResponse{}, err
	}

	return pr, nil
}
<commit_msg>have client Reattempt be a time.Duration<commit_after>package glpclient

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"sync/atomic"
	"time"
)

const (
	DEFAULT_TIMEOUT   = 30
	DEFAULT_REATTEMPT = 30
)

type PollResponse struct {
	Events    []PollEvent `json:"events"`
	Timestamp int64       `json:"timestamp"`
}

// Taken from https://github.com/jcuga/golongpoll/blob/master/events.go
type PollEvent struct {
	// Timestamp is milliseconds since epoch to match javascrits Date.getTime()
	Timestamp int64  `json:"timestamp"`
	Category  string `json:"category"`
	// NOTE: Data can be anything that is able to passed to json.Marshal()
	Data json.RawMessage `json:"data"`
}

type Client struct {
	url      *url.URL
	category string
	// Timeout controls the timeout in all the requests, can be changed after instantiating the client
	Timeout uint64
	// Reattempt controls the amount of time the client waits to reconnect to the server after a failure
	Reattempt time.Duration
	// Will get all the events data
	EventsChan chan json.RawMessage
	// Flag that tracks the current run ID
	runID uint64
	// The HTTP client to perform the requests, any changes on this should be done prior to starting the client the first time
	HttpClient *http.Client
}

// Instantiate a new client to connect to a given URL and send the events into a channel
// The URL shouldn't contain any GET parameters although its fine if it contains some but category, since_time and timeout will be overriten
// stubChanData must either be an empty structure of the events data or a map[string]interface{} if the events do not follow a specific structure
func NewClient(url *url.URL, category string) *Client {
	return &Client{
		url:        url,
		category:   category,
		Timeout:    DEFAULT_TIMEOUT,
		Reattempt:  DEFAULT_REATTEMPT,
		EventsChan: make(chan json.RawMessage),
		HttpClient: &http.Client{},
	}
}

// Start the polling of the events on the URL defined in the client
// Will send the events in the EventsChan of the client
func (c *Client) Start() {
	u := c.url
	fmt.Println("Now observing changes on", u.String())

	atomic.AddUint64(&(c.runID), 1)
	currentRunID := atomic.LoadUint64(&(c.runID))

	go func(runID uint64, u *url.URL) {
		since := time.Now().Unix() * 1000
		for {
			pr, err := c.fetchEvents(since)

			if err != nil {
				fmt.Println(err)
				fmt.Printf("Reattempting to connect to %s in %d seconds \n", u.String(), c.Reattempt)
				time.Sleep(c.Reattempt)
				continue
			}

			// We check that its still the same runID as when this goroutine was started
			clientRunID := atomic.LoadUint64(&(c.runID))
			if clientRunID != runID {
				fmt.Printf("Client on URL %s has been stopped, not sending events \n", u.String())
				return
			}

			if len(pr.Events) > 0 {
				fmt.Println("Got", len(pr.Events), "event(s) from URL", u.String())
				for _, event := range pr.Events {
					since = event.Timestamp
					c.EventsChan <- event.Data
				}
			} else {
				// Only push timestamp forward if its greater than the last we checked
				if pr.Timestamp > since {
					since = pr.Timestamp
				}
			}
		}
	}(currentRunID, u)
}

func (c *Client) Stop() {
	// Changing the runID will have any previous goroutine ignore any events it may receive
	atomic.AddUint64(&(c.runID), 1)
}

// Call the longpoll server to get the events since a specific timestamp
func (c Client) fetchEvents(since int64) (PollResponse, error) {
	u := c.url
	fmt.Println("Checking for changes events since", since, "on URL", u.String())

	query := u.Query()
	query.Set("category", c.category)
	query.Set("since_time", fmt.Sprintf("%d", since))
	query.Set("timeout", fmt.Sprintf("%d", c.Timeout))
	u.RawQuery = query.Encode()

	resp, err := c.HttpClient.Get(u.String())
	if err != nil {
		msg := fmt.Sprintf("Error while connecting to %s to observe changes. Error was: %s", u, err)
		return PollResponse{}, errors.New(msg)
	}

	decoder := json.NewDecoder(resp.Body)
	defer resp.Body.Close()

	var pr PollResponse
	err = decoder.Decode(&pr)
	if err != nil {
		fmt.Errorf("Error while decoding poll response: %s", err)
		return PollResponse{}, err
	}

	return pr, nil
}
<|endoftext|>