Update vendoring (#722)

* Update vendor github.com/beevik/ntp@v0.2.0

* Update vendor github.com/mdlayher/netlink/...

* Update vendor github.com/mdlayher/wifi/...

Adds vendor github.com/mdlayher/genetlink

* Update vendor github.com/prometheus/common/...

* Update vendor github.com/prometheus/procfs/...

* Update vendor golang.org/x/sys/unix

* Update vendor golang.org/x/sys/windows
This commit is contained in:
Ben Kochie 2017-11-02 12:30:34 +01:00 committed by GitHub
parent eb3a917bd8
commit 4d7aa57da0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 587 additions and 283 deletions

View file

@ -1,4 +1,4 @@
Copyright 2015 Brett Vickers. All rights reserved.
Copyright 2015-2017 Brett Vickers. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

View file

@ -6,20 +6,66 @@ ntp
The ntp package is an implementation of a Simple NTP (SNTP) client based on
[RFC5905](https://tools.ietf.org/html/rfc5905). It allows you to connect to
a remote NTP server and request the current time.
a remote NTP server and request information about the current time.
If all you care about is the current time according to a known remote NTP
server, simply use the `Time` function:
## Querying the current time
If all you care about is the current time according to a remote NTP server,
simply use the `Time` function:
```go
time, err := ntp.Time("0.beevik-ntp.pool.ntp.org")
```
If you want the time as well as additional metadata about the time, use the
`Query` function instead:
## Querying time metadata
To obtain the current time as well as some additional metadata about the time,
use the `Query` function:
```go
response, err := ntp.Query("0.beevik-ntp.pool.ntp.org")
time := time.Now().Add(response.ClockOffset)
```
To use the NTP pool in your application, please request your own
[vendor zone](http://www.pool.ntp.org/en/vendors.html). Avoid using
the `[number].pool.ntp.org` zone names in your applications.
Alternatively, use the `QueryWithOptions` function if you want to change the
default behavior used by the `Query` function:
```go
options := ntp.QueryOptions{ Timeout: 30*time.Second, TTL: 5 }
response, err := ntp.QueryWithOptions("0.beevik-ntp.pool.ntp.org", options)
time := time.Now().Add(response.ClockOffset)
```
The `Response` structure returned by `Query` includes the following
information:
* `Time`: The time the server transmitted its response, according to its own clock.
* `ClockOffset`: The estimated offset of the local system clock relative to the server's clock. For a more accurate time reading, you may add this offset to any subsequent system clock reading.
* `RTT`: An estimate of the round-trip-time delay between the client and the server.
* `Precision`: The precision of the server's clock reading.
* `Stratum`: The server's stratum, which indicates the number of hops from the server to the reference clock. A stratum 1 server is directly attached to the reference clock. If the stratum is zero, the server has responded with the "kiss of death".
* `ReferenceID`: A unique identifier for the consulted reference clock.
* `ReferenceTime`: The time at which the server last updated its local clock setting.
* `RootDelay`: The server's aggregate round-trip-time delay to the stratum 1 server.
* `RootDispersion`: The server's estimated maximum measurement error relative to the reference clock.
* `RootDistance`: An estimate of the root synchronization distance between the client and the stratum 1 server.
* `Leap`: The leap second indicator, indicating whether a second should be added to or removed from the current month's last minute.
* `MinError`: A lower bound on the clock error between the client and the server.
* `KissCode`: A 4-character string describing the reason for a "kiss of death" response (stratum=0).
* `Poll`: The maximum polling interval between successive messages to the server.
The `Response` structure's `Validate` method performs additional sanity checks
to determine whether the response is suitable for time synchronization
purposes.
```go
err := response.Validate()
if err == nil {
// response data is suitable for synchronization purposes
}
```
## Using the NTP pool
The NTP pool is a shared resource used by people all over the world.
To prevent it from becoming overloaded, please avoid querying the standard
`pool.ntp.org` zone names in your applications. Instead, consider requesting
your own [vendor zone](http://www.pool.ntp.org/en/vendors.html) or [joining
the pool](http://www.pool.ntp.org/join.html).

View file

@ -1,3 +1,13 @@
Release v0.2.0
==============
There are no breaking changes or further deprecations in this release.
**Changes**
* Added `KissCode` to the `Response` structure.
Release v0.1.1
==============

66
vendor/github.com/beevik/ntp/ntp.go generated vendored
View file

@ -14,6 +14,7 @@ import (
"crypto/rand"
"encoding/binary"
"errors"
"fmt"
"net"
"time"
@ -223,6 +224,11 @@ type Response struct {
// minimum error may be useful.
MinError time.Duration
// KissCode is a 4-character string describing the reason for a
// "kiss of death" response (stratum = 0). For a list of standard kiss
// codes, see https://tools.ietf.org/html/rfc5905#section-7.4.
KissCode string
// Poll is the maximum interval between successive NTP polling messages.
// It is not relevant for simple NTP clients like this one.
Poll time.Duration
@ -233,7 +239,7 @@ type Response struct {
func (r *Response) Validate() error {
// Handle invalid stratum values.
if r.Stratum == 0 {
return errors.New("kiss of death received")
return fmt.Errorf("kiss of death received: %s", r.KissCode)
}
if r.Stratum >= maxStratum {
return errors.New("invalid stratum in response")
@ -379,16 +385,16 @@ func getTime(host string, opt QueryOptions) (*msg, ntpTime, error) {
// To ensure privacy and prevent spoofing, try to use a random 64-bit
// value for the TransmitTime. If crypto/rand couldn't generate a
// random value, fall back to using the system clock. Keep track of
// when the messsage was actually sent.
r := make([]byte, 8)
_, err = rand.Read(r)
var sendTime time.Time
// when the messsage was actually transmitted.
bits := make([]byte, 8)
_, err = rand.Read(bits)
var xmitTime time.Time
if err == nil {
xmitMsg.TransmitTime = ntpTime(binary.BigEndian.Uint64(r))
sendTime = time.Now()
xmitMsg.TransmitTime = ntpTime(binary.BigEndian.Uint64(bits))
xmitTime = time.Now()
} else {
sendTime = time.Now()
xmitMsg.TransmitTime = toNtpTime(sendTime)
xmitTime = time.Now()
xmitMsg.TransmitTime = toNtpTime(xmitTime)
}
// Transmit the query.
@ -404,15 +410,16 @@ func getTime(host string, opt QueryOptions) (*msg, ntpTime, error) {
}
// Keep track of the time the response was received.
delta := time.Since(sendTime)
delta := time.Since(xmitTime)
if delta < 0 {
// The system clock may have been set backwards since the packet was
// transmitted. In go 1.9 and later, time.Since ensures that a
// monotonic clock is used, and delta can never be less than zero.
// In versions before 1.9, we have to check.
// The local system may have had its clock adjusted since it
// sent the query. In go 1.9 and later, time.Since ensures
// that a monotonic clock is used, so delta can never be less
// than zero. In versions before 1.9, a monotonic clock is
// not used, so we have to check.
return nil, 0, errors.New("client clock ticked backwards")
}
recvTime := toNtpTime(sendTime.Add(delta))
recvTime := toNtpTime(xmitTime.Add(delta))
// Check for invalid fields.
if recvMsg.getMode() != server {
@ -428,9 +435,9 @@ func getTime(host string, opt QueryOptions) (*msg, ntpTime, error) {
return nil, 0, errors.New("server clock ticked backwards")
}
// Correct the received message's origin time using the actual send
// time.
recvMsg.OriginTime = toNtpTime(sendTime)
// Correct the received message's origin time using the actual
// transmit time.
recvMsg.OriginTime = toNtpTime(xmitTime)
return recvMsg, recvTime, nil
}
@ -456,6 +463,12 @@ func parseTime(m *msg, recvTime ntpTime) *Response {
// Calculate values depending on other calculated values
r.RootDistance = rootDistance(r.RTT, r.RootDelay, r.RootDispersion)
// If a kiss of death was received, interpret the reference ID as
// a kiss code.
if r.Stratum == 0 {
r.KissCode = kissCode(r.ReferenceID)
}
return r
}
@ -533,3 +546,20 @@ func toInterval(t int8) time.Duration {
return time.Second
}
}
func kissCode(id uint32) string {
isPrintable := func(ch byte) bool { return ch >= 32 && ch <= 126 }
b := []byte{
byte(id >> 24),
byte(id >> 16),
byte(id >> 8),
byte(id),
}
for _, ch := range b {
if !isPrintable(ch) {
return ""
}
}
return string(b)
}

10
vendor/github.com/mdlayher/genetlink/LICENSE.md generated vendored Normal file
View file

@ -0,0 +1,10 @@
MIT License
===========
Copyright (C) 2016-2017 Matt Layher
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

8
vendor/github.com/mdlayher/genetlink/README.md generated vendored Normal file
View file

@ -0,0 +1,8 @@
genetlink [![Build Status](https://travis-ci.org/mdlayher/genetlink.svg?branch=master)](https://travis-ci.org/mdlayher/genetlink) [![GoDoc](https://godoc.org/github.com/mdlayher/genetlink?status.svg)](https://godoc.org/github.com/mdlayher/genetlink) [![Go Report Card](https://goreportcard.com/badge/github.com/mdlayher/genetlink)](https://goreportcard.com/report/github.com/mdlayher/genetlink)
=========
Package `genetlink` implements generic netlink interactions and data types.
MIT Licensed.
For more information about how netlink and generic netlink work,
check out my blog series on [Linux, Netlink, and Go](https://medium.com/@mdlayher/linux-netlink-and-go-part-1-netlink-4781aaeeaca8).

View file

@ -1,32 +1,18 @@
package genetlink
import "github.com/mdlayher/netlink"
// Controller is the generic netlink controller family ID, used to issue
// requests to the controller.
const Controller = 0x10
import (
"github.com/mdlayher/netlink"
"golang.org/x/net/bpf"
)
// Protocol is the netlink protocol constant used to specify generic netlink.
const Protocol = 0x10
const Protocol = 0x10 // unix.NETLINK_GENERIC
// A Conn is a generic netlink connection. A Conn can be used to send and
// receive generic netlink messages to and from netlink.
type Conn struct {
// Family provides functions to help retrieve generic netlink families.
Family *FamilyService
c conn
}
var _ conn = &netlink.Conn{}
// A conn is a netlink connection, which can be swapped for tests.
type conn interface {
Close() error
JoinGroup(group uint32) error
LeaveGroup(group uint32) error
Send(m netlink.Message) (netlink.Message, error)
Receive() ([]netlink.Message, error)
// Operating system-specific netlink connection.
c *netlink.Conn
}
// Dial dials a generic netlink connection. Config specifies optional
@ -38,18 +24,16 @@ func Dial(config *netlink.Config) (*Conn, error) {
return nil, err
}
return newConn(c), nil
return NewConn(c), nil
}
// newConn is the internal constructor for Conn, used in tests.
func newConn(c conn) *Conn {
gc := &Conn{
c: c,
}
gc.Family = &FamilyService{c: gc}
return gc
// NewConn creates a Conn that wraps an existing *netlink.Conn for
// generic netlink communications.
//
// NewConn is primarily useful for tests. Most applications should use
// Dial instead.
func NewConn(c *netlink.Conn) *Conn {
return &Conn{c: c}
}
// Close closes the connection.
@ -57,6 +41,17 @@ func (c *Conn) Close() error {
return c.c.Close()
}
// GetFamily retrieves a generic netlink family with the specified name. If the
// family does not exist, the error value can be checked using os.IsNotExist.
func (c *Conn) GetFamily(name string) (Family, error) {
return c.getFamily(name)
}
// ListFamilies retrieves all registered generic netlink families.
func (c *Conn) ListFamilies() ([]Family, error) {
return c.listFamilies()
}
// JoinGroup joins a netlink multicast group by its ID.
func (c *Conn) JoinGroup(group uint32) error {
return c.c.JoinGroup(group)
@ -67,6 +62,11 @@ func (c *Conn) LeaveGroup(group uint32) error {
return c.c.LeaveGroup(group)
}
// SetBPF attaches an assembled BPF program to a Conn.
func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
return c.c.SetBPF(filter)
}
// Send sends a single Message to netlink, wrapping it in a netlink.Message
// using the specified generic netlink family and flags. On success, Send
// returns a copy of the netlink.Message with all parameters populated, for

17
vendor/github.com/mdlayher/genetlink/family.go generated vendored Normal file
View file

@ -0,0 +1,17 @@
package genetlink
// A Family is a generic netlink family.
type Family struct {
ID uint16
Version uint8
Name string
Groups []MulticastGroup
}
// A MulticastGroup is a generic netlink multicast group, which can be joined
// for notifications from generic netlink families when specific events take
// place.
type MulticastGroup struct {
ID uint32
Name string
}

View file

@ -1,3 +1,5 @@
//+build linux
package genetlink
import (
@ -7,14 +9,7 @@ import (
"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/nlenc"
)
// Constants used to request information from generic netlink controller.
// Reference: http://lxr.free-electrons.com/source/include/linux/genetlink.h?v=3.3#L35
const (
ctrlVersion = 1
ctrlCommandGetFamily = 3
"golang.org/x/sys/unix"
)
var (
@ -27,32 +22,10 @@ var (
errInvalidMulticastGroupArray = errors.New("invalid multicast group attribute array")
)
// A Family is a generic netlink family.
type Family struct {
ID uint16
Version uint8
Name string
Groups []MulticastGroup
}
// A MulticastGroup is a generic netlink multicast group, which can be joined
// for notifications from generic netlink families when specific events take
// place.
type MulticastGroup struct {
ID uint32
Name string
}
// A FamilyService is used to retrieve generic netlink family information.
type FamilyService struct {
c *Conn
}
// Get retrieves a generic netlink family with the specified name. If the
// family does not exist, the error value can be checked using os.IsNotExist.
func (s *FamilyService) Get(name string) (Family, error) {
// getFamily retrieves a generic netlink family with the specified name.
func (c *Conn) getFamily(name string) (Family, error) {
b, err := netlink.MarshalAttributes([]netlink.Attribute{{
Type: attrFamilyName,
Type: unix.CTRL_ATTR_FAMILY_NAME,
Data: nlenc.Bytes(name),
}})
if err != nil {
@ -61,13 +34,14 @@ func (s *FamilyService) Get(name string) (Family, error) {
req := Message{
Header: Header{
Command: ctrlCommandGetFamily,
Version: ctrlVersion,
Command: unix.CTRL_CMD_GETFAMILY,
// TODO(mdlayher): grab nlctrl version?
Version: 1,
},
Data: b,
}
msgs, err := s.c.Execute(req, Controller, netlink.HeaderFlagsRequest)
msgs, err := c.Execute(req, unix.GENL_ID_CTRL, netlink.HeaderFlagsRequest)
if err != nil {
return Family{}, err
}
@ -87,17 +61,18 @@ func (s *FamilyService) Get(name string) (Family, error) {
return families[0], nil
}
// List retrieves all registered generic netlink families.
func (s *FamilyService) List() ([]Family, error) {
// listFamilies retrieves all registered generic netlink families.
func (c *Conn) listFamilies() ([]Family, error) {
req := Message{
Header: Header{
Command: ctrlCommandGetFamily,
Version: ctrlVersion,
Command: unix.CTRL_CMD_GETFAMILY,
// TODO(mdlayher): grab nlctrl version?
Version: 1,
},
}
flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump
msgs, err := s.c.Execute(req, Controller, flags)
msgs, err := c.Execute(req, unix.GENL_ID_CTRL, flags)
if err != nil {
return nil, err
}
@ -126,38 +101,22 @@ func buildFamilies(msgs []Message) ([]Family, error) {
return families, nil
}
// Attribute IDs mapped to specific family fields.
const (
// TODO(mdlayher): parse additional attributes
// Family attributes
attrUnspecified = 0
attrFamilyID = 1
attrFamilyName = 2
attrVersion = 3
attrMulticastGroups = 7
// Multicast group-specific attributes
attrMGName = 1
attrMGID = 2
)
// parseAttributes parses netlink attributes into a Family's fields.
func (f *Family) parseAttributes(attrs []netlink.Attribute) error {
for _, a := range attrs {
switch a.Type {
case attrFamilyID:
case unix.CTRL_ATTR_FAMILY_ID:
f.ID = nlenc.Uint16(a.Data)
case attrFamilyName:
case unix.CTRL_ATTR_FAMILY_NAME:
f.Name = nlenc.String(a.Data)
case attrVersion:
case unix.CTRL_ATTR_VERSION:
v := nlenc.Uint32(a.Data)
if v > math.MaxUint8 {
return errInvalidFamilyVersion
}
f.Version = uint8(v)
case attrMulticastGroups:
case unix.CTRL_ATTR_MCAST_GROUPS:
groups, err := parseMulticastGroups(a.Data)
if err != nil {
return err
@ -194,9 +153,9 @@ func parseMulticastGroups(b []byte) ([]MulticastGroup, error) {
var g MulticastGroup
for _, na := range nattrs {
switch na.Type {
case attrMGName:
case unix.CTRL_ATTR_MCAST_GRP_NAME:
g.Name = nlenc.String(na.Data)
case attrMGID:
case unix.CTRL_ATTR_MCAST_GRP_ID:
g.ID = nlenc.Uint32(na.Data)
}
}

25
vendor/github.com/mdlayher/genetlink/family_others.go generated vendored Normal file
View file

@ -0,0 +1,25 @@
//+build !linux
package genetlink
import (
"fmt"
"runtime"
)
var (
// errUnimplemented is returned by all functions on platforms that
// cannot make use of generic netlink.
errUnimplemented = fmt.Errorf("generic netlink not implemented on %s/%s",
runtime.GOOS, runtime.GOARCH)
)
// getFamily always returns an error.
func (c *Conn) getFamily(name string) (Family, error) {
return Family{}, errUnimplemented
}
// listFamilies always returns an error.
func (c *Conn) listFamilies() ([]Family, error) {
return nil, errUnimplemented
}

View file

@ -20,7 +20,7 @@ type Header struct {
}
// headerLen is the length of a Header.
const headerLen = 4
const headerLen = 4 // unix.GENL_HDRLEN
// A Message is a generic netlink message. It contains a Header and an
// arbitrary byte payload, which may be decoded using information from the

View file

@ -1,7 +1,7 @@
MIT License
===========
Copyright (C) 2016 Matt Layher
Copyright (C) 2016-2017 Matt Layher
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View file

@ -4,6 +4,12 @@ netlink [![Build Status](https://travis-ci.org/mdlayher/netlink.svg?branch=maste
Package `netlink` provides low-level access to Linux netlink sockets.
MIT Licensed.
For more information about how netlink works, check out my blog series
on [Linux, Netlink, and Go](https://medium.com/@mdlayher/linux-netlink-and-go-part-1-netlink-4781aaeeaca8).
If you're looking for package `genetlink`, it's been moved to its own
repository at [`github.com/mdlayher/genetlink`](https://github.com/mdlayher/genetlink).
Why?
----
@ -18,4 +24,4 @@ I wanted in a netlink package:
- Doesn't need root to work
My goal for this package is to use it as a building block for the creation
of other netlink protocol family packages.
of other netlink family packages.

View file

@ -9,10 +9,13 @@ import (
var (
// errInvalidAttribute specifies if an Attribute's length is incorrect.
errInvalidAttribute = errors.New("invalid attribute; length too short or too large")
// errInvalidAttributeFlags specifies if an Attribute's flag configuration is invalid.
// From a comment in Linux/include/uapi/linux/netlink.h, Nested and NetByteOrder are mutually exclusive.
errInvalidAttributeFlags = errors.New("invalid attribute; type cannot have both nested and net byte order flags")
)
// An Attribute is a netlink attribute. Attributes are packed and unpacked
// to and from the Data field of Message for some netlink protocol families.
// to and from the Data field of Message for some netlink families.
type Attribute struct {
// Length of an Attribute, including this field and Type.
Length uint16
@ -22,19 +25,50 @@ type Attribute struct {
// An arbitrary payload which is specified by Type.
Data []byte
// Whether the attribute's data contains nested attributes. Note that not
// all netlink families set this value. The programmer should consult
// documentation and inspect an attribute's data to determine if nested
// attributes are present.
Nested bool
// Whether the attribute's data is in network (true) or native (false) byte order.
NetByteOrder bool
}
// #define NLA_F_NESTED
const nlaNested uint16 = 0x8000
// #define NLA_F_NET_BYTE_ORDER
const nlaNetByteOrder uint16 = 0x4000
// Masks all bits except for Nested and NetByteOrder.
const nlaTypeMask = ^(nlaNested | nlaNetByteOrder)
// MarshalBinary marshals an Attribute into a byte slice.
func (a Attribute) MarshalBinary() ([]byte, error) {
if int(a.Length) < nlaHeaderLen {
return nil, errInvalidAttribute
}
if a.NetByteOrder && a.Nested {
return nil, errInvalidAttributeFlags
}
b := make([]byte, nlaAlign(int(a.Length)))
nlenc.PutUint16(b[0:2], a.Length)
switch {
case a.Nested:
nlenc.PutUint16(b[2:4], a.Type|nlaNested)
case a.NetByteOrder:
nlenc.PutUint16(b[2:4], a.Type|nlaNetByteOrder)
default:
nlenc.PutUint16(b[2:4], a.Type)
copy(b[4:], a.Data)
}
copy(b[nlaHeaderLen:], a.Data)
return b, nil
}
@ -46,23 +80,33 @@ func (a *Attribute) UnmarshalBinary(b []byte) error {
}
a.Length = nlenc.Uint16(b[0:2])
a.Type = nlenc.Uint16(b[2:4])
// Only hold the rightmost 14 bits in Type
a.Type = nlenc.Uint16(b[2:4]) & nlaTypeMask
// Boolean flags extracted from the two leftmost bits of Type
a.Nested = (nlenc.Uint16(b[2:4]) & nlaNested) > 0
a.NetByteOrder = (nlenc.Uint16(b[2:4]) & nlaNetByteOrder) > 0
if nlaAlign(int(a.Length)) > len(b) {
return errInvalidAttribute
}
if a.NetByteOrder && a.Nested {
return errInvalidAttributeFlags
}
switch {
// No length, no data
case a.Length == 0:
a.Data = make([]byte, 0)
// Not enough length for any data
case a.Length < 4:
case int(a.Length) < nlaHeaderLen:
return errInvalidAttribute
// Data present
case a.Length >= 4:
a.Data = make([]byte, len(b[4:a.Length]))
copy(a.Data, b[4:a.Length])
case int(a.Length) >= nlaHeaderLen:
a.Data = make([]byte, len(b[nlaHeaderLen:a.Length]))
copy(a.Data, b[nlaHeaderLen:a.Length])
}
return nil

View file

@ -2,7 +2,9 @@ package netlink
import (
"errors"
"io"
"math/rand"
"os"
"sync/atomic"
"golang.org/x/net/bpf"
@ -15,12 +17,20 @@ var (
errShortErrorMessage = errors.New("not enough data for netlink error code")
)
// Errors which can be returned by a Socket that does not implement
// all exposed methods of Conn.
var (
errReadWriteCloserNotSupported = errors.New("raw read/write/closer not supported")
errMulticastGroupsNotSupported = errors.New("multicast groups not supported")
errBPFFiltersNotSupported = errors.New("BPF filters not supported")
)
// A Conn is a connection to netlink. A Conn can be used to send and
// receives messages to and from netlink.
type Conn struct {
// osConn is the operating system-specific implementation of
// sock is the operating system-specific implementation of
// a netlink sockets connection.
c osConn
sock Socket
// seq is an atomically incremented integer used to provide sequence
// numbers when Conn.Send is called.
@ -30,36 +40,37 @@ type Conn struct {
pid uint32
}
// An osConn is an operating-system specific implementation of netlink
// A Socket is an operating-system specific implementation of netlink
// sockets used by Conn.
type osConn interface {
type Socket interface {
Close() error
Send(m Message) error
Receive() ([]Message, error)
JoinGroup(group uint32) error
LeaveGroup(group uint32) error
SetBPF(filter []bpf.RawInstruction) error
}
// Dial dials a connection to netlink, using the specified protocol number.
// Dial dials a connection to netlink, using the specified netlink family.
// Config specifies optional configuration for Conn. If config is nil, a default
// configuration will be used.
func Dial(proto int, config *Config) (*Conn, error) {
// Use OS-specific dial() to create osConn
c, pid, err := dial(proto, config)
func Dial(family int, config *Config) (*Conn, error) {
// Use OS-specific dial() to create Socket
c, pid, err := dial(family, config)
if err != nil {
return nil, err
}
return newConn(c, pid), nil
return NewConn(c, pid), nil
}
// newConn is the internal constructor for Conn, used in tests.
func newConn(c osConn, pid uint32) *Conn {
// NewConn creates a Conn using the specified Socket and PID for netlink
// communications.
//
// NewConn is primarily useful for tests. Most applications should use
// Dial instead.
func NewConn(c Socket, pid uint32) *Conn {
seq := rand.Uint32()
return &Conn{
c: c,
sock: c,
seq: &seq,
pid: pid,
}
@ -67,7 +78,7 @@ func newConn(c osConn, pid uint32) *Conn {
// Close closes the connection.
func (c *Conn) Close() error {
return c.c.Close()
return c.sock.Close()
}
// Execute sends a single Message to netlink using Conn.Send, receives one or more
@ -127,7 +138,7 @@ func (c *Conn) Send(m Message) (Message, error) {
m.Header.PID = c.pid
}
if err := c.c.Send(m); err != nil {
if err := c.sock.Send(m); err != nil {
return Message{}, err
}
@ -145,8 +156,13 @@ func (c *Conn) Receive() ([]Message, error) {
return nil, err
}
// When using nltest, it's possible for zero messages to be returned by receive.
if len(msgs) == 0 {
return msgs, nil
}
// Trim the final message with multi-part done indicator if
// present
// present.
if m := msgs[len(msgs)-1]; m.Header.Flags&HeaderFlagsMulti != 0 && m.Header.Type == HeaderTypeDone {
return msgs[:len(msgs)-1], nil
}
@ -157,7 +173,7 @@ func (c *Conn) Receive() ([]Message, error) {
// receive is the internal implementation of Conn.Receive, which can be called
// recursively to handle multi-part messages.
func (c *Conn) receive() ([]Message, error) {
msgs, err := c.c.Receive()
msgs, err := c.sock.Receive()
if err != nil {
return nil, err
}
@ -190,19 +206,93 @@ func (c *Conn) receive() ([]Message, error) {
return append(msgs, mmsgs...), nil
}
// An fder is a Socket that supports retrieving its raw file descriptor.
type fder interface {
Socket
FD() int
}
var _ io.ReadWriteCloser = &fileReadWriteCloser{}
// A fileReadWriteCloser is a limited *os.File which only allows access to its
// Read and Write methods.
type fileReadWriteCloser struct {
f *os.File
}
// Read implements io.ReadWriteCloser.
func (rwc *fileReadWriteCloser) Read(b []byte) (int, error) { return rwc.f.Read(b) }
// Write implements io.ReadWriteCloser.
func (rwc *fileReadWriteCloser) Write(b []byte) (int, error) { return rwc.f.Write(b) }
// Close implements io.ReadWriteCloser.
func (rwc *fileReadWriteCloser) Close() error { return rwc.f.Close() }
// ReadWriteCloser returns a raw io.ReadWriteCloser backed by the connection
// of the Conn.
//
// ReadWriteCloser is intended for advanced use cases, such as those that do
// not involve standard netlink message passing.
//
// Once invoked, it is the caller's responsibility to ensure that operations
// performed using Conn and the raw io.ReadWriteCloser do not conflict with
// each other. In almost all scenarios, only one of the two should be used.
func (c *Conn) ReadWriteCloser() (io.ReadWriteCloser, error) {
fc, ok := c.sock.(fder)
if !ok {
return nil, errReadWriteCloserNotSupported
}
return &fileReadWriteCloser{
// Backing the io.ReadWriteCloser with an *os.File enables easy reading
// and writing without more system call boilerplate.
f: os.NewFile(uintptr(fc.FD()), "netlink"),
}, nil
}
// A groupJoinLeaver is a Socket that supports joining and leaving
// netlink multicast groups.
type groupJoinLeaver interface {
Socket
JoinGroup(group uint32) error
LeaveGroup(group uint32) error
}
// JoinGroup joins a netlink multicast group by its ID.
func (c *Conn) JoinGroup(group uint32) error {
return c.c.JoinGroup(group)
gc, ok := c.sock.(groupJoinLeaver)
if !ok {
return errMulticastGroupsNotSupported
}
return gc.JoinGroup(group)
}
// LeaveGroup leaves a netlink multicast group by its ID.
func (c *Conn) LeaveGroup(group uint32) error {
return c.c.LeaveGroup(group)
gc, ok := c.sock.(groupJoinLeaver)
if !ok {
return errMulticastGroupsNotSupported
}
return gc.LeaveGroup(group)
}
// A bpfSetter is a Socket that supports setting BPF filters.
type bpfSetter interface {
Socket
bpf.Setter
}
// SetBPF attaches an assembled BPF program to a Conn.
func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
return c.c.SetBPF(filter)
bc, ok := c.sock.(bpfSetter)
if !ok {
return errBPFFiltersNotSupported
}
return bc.SetBPF(filter)
}
// nextSequence atomically increments Conn's sequence number and returns

View file

@ -17,7 +17,7 @@ var (
errInvalidFamily = errors.New("received invalid netlink family")
)
var _ osConn = &conn{}
var _ Socket = &conn{}
// A conn is the Linux implementation of a netlink sockets connection.
type conn struct {
@ -29,6 +29,7 @@ type conn struct {
type socket interface {
Bind(sa unix.Sockaddr) error
Close() error
FD() int
Getsockname() (unix.Sockaddr, error)
Recvmsg(p, oob []byte, flags int) (n int, oobn int, recvflags int, from unix.Sockaddr, err error)
Sendmsg(p, oob []byte, to unix.Sockaddr, flags int) error
@ -154,6 +155,11 @@ func (c *conn) Close() error {
return c.s.Close()
}
// FD retrieves the file descriptor of the Conn.
func (c *conn) FD() int {
return c.s.FD()
}
// JoinGroup joins a multicast group by ID.
func (c *conn) JoinGroup(group uint32) error {
return c.s.SetSockopt(
@ -211,6 +217,7 @@ type sysSocket struct {
func (s *sysSocket) Bind(sa unix.Sockaddr) error { return unix.Bind(s.fd, sa) }
func (s *sysSocket) Close() error { return unix.Close(s.fd) }
func (s *sysSocket) FD() int { return s.fd }
func (s *sysSocket) Getsockname() (unix.Sockaddr, error) { return unix.Getsockname(s.fd) }
func (s *sysSocket) Recvmsg(p, oob []byte, flags int) (int, int, int, unix.Sockaddr, error) {
return unix.Recvmsg(s.fd, p, oob, flags)

View file

@ -16,14 +16,14 @@ var (
runtime.GOOS, runtime.GOARCH)
)
var _ osConn = &conn{}
var _ Socket = &conn{}
// A conn is the no-op implementation of a netlink sockets connection.
type conn struct{}
// dial is the entry point for Dial. dial always returns an error.
func dial(family int, config *Config) (*conn, error) {
return nil, errUnimplemented
func dial(family int, config *Config) (*conn, uint32, error) {
return nil, 0, errUnimplemented
}
// Send always returns an error.

View file

@ -5,6 +5,16 @@ import (
"unsafe"
)
// PutUint8 encodes a uint8 into b.
// If b is not exactly 1 byte in length, PutUint8 will panic.
func PutUint8(b []byte, v uint8) {
if l := len(b); l != 1 {
panic(fmt.Sprintf("PutUint8: unexpected byte slice length: %d", l))
}
b[0] = v
}
// PutUint16 encodes a uint16 into b using the host machine's native endianness.
// If b is not exactly 2 bytes in length, PutUint16 will panic.
func PutUint16(b []byte, v uint16) {
@ -35,6 +45,26 @@ func PutUint64(b []byte, v uint64) {
*(*uint64)(unsafe.Pointer(&b[0])) = v
}
// PutInt32 encodes a int32 into b using the host machine's native endianness.
// If b is not exactly 4 bytes in length, PutInt32 will panic.
func PutInt32(b []byte, v int32) {
if l := len(b); l != 4 {
panic(fmt.Sprintf("PutInt32: unexpected byte slice length: %d", l))
}
*(*int32)(unsafe.Pointer(&b[0])) = v
}
// Uint8 decodes a uint8 from b.
// If b is not exactly 1 byte in length, Uint8 will panic.
func Uint8(b []byte) uint8 {
if l := len(b); l != 1 {
panic(fmt.Sprintf("Uint8: unexpected byte slice length: %d", l))
}
return b[0]
}
// Uint16 decodes a uint16 from b using the host machine's native endianness.
// If b is not exactly 2 bytes in length, Uint16 will panic.
func Uint16(b []byte) uint16 {
@ -75,6 +105,14 @@ func Int32(b []byte) int32 {
return *(*int32)(unsafe.Pointer(&b[0]))
}
// Uint8Bytes encodes a uint8 into a newly-allocated byte slice. It is a
// shortcut for allocating a new byte slice and filling it using PutUint8.
func Uint8Bytes(v uint8) []byte {
b := make([]byte, 1)
PutUint8(b, v)
return b
}
// Uint16Bytes encodes a uint16 into a newly-allocated byte slice using the
// host machine's native endianness. It is a shortcut for allocating a new
// byte slice and filling it using PutUint16.
@ -101,3 +139,12 @@ func Uint64Bytes(v uint64) []byte {
PutUint64(b, v)
return b
}
// Int32Bytes encodes a int32 into a newly-allocated byte slice using the
// host machine's native endianness. It is a shortcut for allocating a new
// byte slice and filling it using PutInt32.
func Int32Bytes(v int32) []byte {
b := make([]byte, 4)
PutInt32(b, v)
return b
}

View file

@ -11,8 +11,8 @@ import (
"time"
"unicode/utf8"
"github.com/mdlayher/genetlink"
"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/genetlink"
"github.com/mdlayher/netlink/nlenc"
"github.com/mdlayher/wifi/internal/nl80211"
)
@ -30,19 +30,11 @@ var _ osClient = &client{}
// netlink, generic netlink, and nl80211 to provide access to WiFi device
// actions and statistics.
type client struct {
c genl
c *genetlink.Conn
familyID uint16
familyVersion uint8
}
// genl is an interface over generic netlink, so netlink interactions can
// be stubbed in tests.
type genl interface {
Close() error
GetFamily(name string) (genetlink.Family, error)
Execute(m genetlink.Message, family uint16, flags netlink.HeaderFlags) ([]genetlink.Message, error)
}
// newClient dials a generic netlink connection and verifies that nl80211
// is available for use by this package.
func newClient() (*client, error) {
@ -51,12 +43,10 @@ func newClient() (*client, error) {
return nil, err
}
g := &sysGENL{Conn: c}
return initClient(g)
return initClient(c)
}
// initClient is the internal constructor for a client, used in tests.
func initClient(c genl) (*client, error) {
func initClient(c *genetlink.Conn) (*client, error) {
family, err := c.GetFamily(nl80211.GenlName)
if err != nil {
// Ensure the genl socket is closed on error to avoid leaking file
@ -479,15 +469,3 @@ func decodeSSID(b []byte) string {
return buf.String()
}
var _ genl = &sysGENL{}
// sysGENL is the system implementation of genl, using generic netlink.
type sysGENL struct {
*genetlink.Conn
}
// GetFamily is a small adapter to make *genetlink.Conn implement genl.
func (g *sysGENL) GetFamily(name string) (genetlink.Family, error) {
return g.Conn.Family.Get(name)
}

View file

@ -345,6 +345,11 @@ func Fatalf(format string, args ...interface{}) {
baseLogger.sourced().Fatalf(format, args...)
}
// AddHook adds hook to Prometheus' original logger.
func AddHook(hook logrus.Hook) {
origLogger.Hooks.Add(hook)
}
type errorLogWriter struct{}
func (errorLogWriter) Write(b []byte) (int, error) {

View file

@ -13,46 +13,46 @@ import (
// http://man7.org/linux/man-pages/man2/getrlimit.2.html.
type ProcLimits struct {
// CPU time limit in seconds.
CPUTime int
CPUTime int64
// Maximum size of files that the process may create.
FileSize int
FileSize int64
// Maximum size of the process's data segment (initialized data,
// uninitialized data, and heap).
DataSize int
DataSize int64
// Maximum size of the process stack in bytes.
StackSize int
StackSize int64
// Maximum size of a core file.
CoreFileSize int
CoreFileSize int64
// Limit of the process's resident set in pages.
ResidentSet int
ResidentSet int64
// Maximum number of processes that can be created for the real user ID of
// the calling process.
Processes int
Processes int64
// Value one greater than the maximum file descriptor number that can be
// opened by this process.
OpenFiles int
OpenFiles int64
// Maximum number of bytes of memory that may be locked into RAM.
LockedMemory int
LockedMemory int64
// Maximum size of the process's virtual memory address space in bytes.
AddressSpace int
AddressSpace int64
// Limit on the combined number of flock(2) locks and fcntl(2) leases that
// this process may establish.
FileLocks int
FileLocks int64
// Limit of signals that may be queued for the real user ID of the calling
// process.
PendingSignals int
PendingSignals int64
// Limit on the number of bytes that can be allocated for POSIX message
// queues for the real user ID of the calling process.
MsqqueueSize int
MsqqueueSize int64
// Limit of the nice priority set using setpriority(2) or nice(2).
NicePriority int
NicePriority int64
// Limit of the real-time priority set using sched_setscheduler(2) or
// sched_setparam(2).
RealtimePriority int
RealtimePriority int64
// Limit (in microseconds) on the amount of CPU time that a process
// scheduled under a real-time scheduling policy may consume without making
// a blocking system call.
RealtimeTimeout int
RealtimeTimeout int64
}
const (
@ -125,13 +125,13 @@ func (p Proc) NewLimits() (ProcLimits, error) {
return l, s.Err()
}
func parseInt(s string) (int, error) {
func parseInt(s string) (int64, error) {
if s == limitsUnlimited {
return -1, nil
}
i, err := strconv.ParseInt(s, 10, 32)
i, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return 0, fmt.Errorf("couldn't parse value %s: %s", s, err)
}
return int(i), nil
return i, nil
}

View file

@ -116,7 +116,7 @@ func (p *Proc) Addr() uintptr {
//go:uintptrescapes
// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
// are supplied.
//
// The returned error is always non-nil, constructed from the result of GetLastError.
@ -289,6 +289,7 @@ func (p *LazyProc) mustFind() {
// Addr returns the address of the procedure represented by p.
// The return value can be passed to Syscall to run the procedure.
// It will panic if the procedure cannot be found.
func (p *LazyProc) Addr() uintptr {
p.mustFind()
return p.proc.Addr()
@ -296,8 +297,8 @@ func (p *LazyProc) Addr() uintptr {
//go:uintptrescapes
// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
// are supplied.
// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
// are supplied. It will also panic if the procedure cannot be found.
//
// The returned error is always non-nil, constructed from the result of GetLastError.
// Callers must inspect the primary return value to decide whether an error occurred

View file

@ -202,6 +202,21 @@ func NewCallbackCDecl(fn interface{}) uintptr {
// syscall interface implementation for other packages
// GetProcAddressByOrdinal retrieves the address of the exported
// function from module by ordinal.
func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err error) {
r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0)
proc = uintptr(r0)
if proc == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func Exit(code int) { ExitProcess(uint32(code)) }
func makeInheritSa() *SecurityAttributes {

92
vendor/vendor.json vendored
View file

@ -21,12 +21,12 @@
"revisionTime": "2015-10-22T06:55:26Z"
},
{
"checksumSHA1": "OXcULIfKv/Xcsa4o1By1lY0s+AI=",
"checksumSHA1": "Gofi5dpQ/jevSfySSRDaoNpHMq8=",
"path": "github.com/beevik/ntp",
"revision": "802074b1b037c59dbdbee7e196ad91b51d0ec844",
"revisionTime": "2017-10-03T23:10:51Z",
"version": "v0.1.1",
"versionExact": "v0.1.1"
"revision": "62c80a04de2086884d8296004b6d74ee1846c582",
"revisionTime": "2017-10-20T00:02:52Z",
"version": "v0.2.0",
"versionExact": "v0.2.0"
},
{
"checksumSHA1": "spyv5/YFBjYyZLZa1U2LBfDR8PM=",
@ -81,10 +81,16 @@
"versionExact": "v1.0.0"
},
{
"checksumSHA1": "r3t+HDvOEQVCaLjuMT8rl6opbNQ=",
"checksumSHA1": "VZIJG8dML/XqZbL9bpeDNgkazcg=",
"path": "github.com/mdlayher/genetlink",
"revision": "76fecce4c787fb8eaa21a8755f722d67c53038e1",
"revisionTime": "2017-09-01T18:19:24Z"
},
{
"checksumSHA1": "LUVR92VPf7w6G90RtLHJU5C7p/k=",
"path": "github.com/mdlayher/netlink",
"revision": "343c07bd16ebbc714f19c528a6deb6723ace06f3",
"revisionTime": "2017-03-10T17:31:27Z"
"revision": "82077d593cd599c082317ceb5cfb22ee3fbc75ea",
"revisionTime": "2017-09-15T04:07:23Z"
},
{
"checksumSHA1": "+2roeIWCAjCC58tZcs12Vqgf1Io=",
@ -93,22 +99,22 @@
"revisionTime": "2017-01-04T04:59:06Z"
},
{
"checksumSHA1": "9udZUcU9bmkXtnkyLNqJ8jKRt0c=",
"checksumSHA1": "9nig0WuuiTICStI/8S+pIGqYksc=",
"path": "github.com/mdlayher/netlink/nlenc",
"revision": "1291b75abe0cc0cb335f110466bf1f02590c916d",
"revisionTime": "2017-01-04T04:59:06Z"
"revision": "82077d593cd599c082317ceb5cfb22ee3fbc75ea",
"revisionTime": "2017-09-15T04:07:23Z"
},
{
"checksumSHA1": "FdmT9kyPtsLxk+sgxJmKqcbOCR4=",
"checksumSHA1": "VrGOd/bos90JqbKuu/cTFdyWoWk=",
"path": "github.com/mdlayher/wifi",
"revision": "567082929344b0af8eb8a2ad6fe4725c0b3c8702",
"revisionTime": "2017-03-17T19:22:46Z"
"revision": "17fb8383f38adbf6a7f12e6cbd1d461760aabf5c",
"revisionTime": "2017-09-01T18:29:50Z"
},
{
"checksumSHA1": "VzutdH69PUqRqhrDVv6F91ebQd4=",
"path": "github.com/mdlayher/wifi/internal/nl80211",
"revision": "88fd1c0ec178645c1b7d300090b5a9d4b226b8e1",
"revisionTime": "2017-01-07T15:17:58Z"
"revision": "17fb8383f38adbf6a7f12e6cbd1d461760aabf5c",
"revisionTime": "2017-09-01T18:29:50Z"
},
{
"checksumSHA1": "N8DZCxgnkiFM2cdn0/jB6jRu1TM=",
@ -135,56 +141,56 @@
{
"checksumSHA1": "xfnn0THnqNwjwimeTClsxahYrIo=",
"path": "github.com/prometheus/common/expfmt",
"revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
"revisionTime": "2017-09-08T16:18:22Z"
"revision": "1bab55dd05dbff384524a6a1c99006d9eb5f139b",
"revisionTime": "2017-10-06T14:14:18Z"
},
{
"checksumSHA1": "GWlM3d2vPYyNATtTFgftS10/A9w=",
"path": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
"revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
"revisionTime": "2017-09-08T16:18:22Z"
"revision": "1bab55dd05dbff384524a6a1c99006d9eb5f139b",
"revisionTime": "2017-10-06T14:14:18Z"
},
{
"checksumSHA1": "jYpLEs+wZ5LZubvOJEDSQ8I14MI=",
"checksumSHA1": "urKbLgaVUBz64iwZ6z4fHijDfXE=",
"path": "github.com/prometheus/common/log",
"revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
"revisionTime": "2017-09-08T16:18:22Z"
"revision": "1bab55dd05dbff384524a6a1c99006d9eb5f139b",
"revisionTime": "2017-10-06T14:14:18Z"
},
{
"checksumSHA1": "3VoqH7TFfzA6Ds0zFzIbKCUvBmw=",
"path": "github.com/prometheus/common/model",
"revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
"revisionTime": "2017-09-08T16:18:22Z"
"revision": "1bab55dd05dbff384524a6a1c99006d9eb5f139b",
"revisionTime": "2017-10-06T14:14:18Z"
},
{
"checksumSHA1": "91KYK0SpvkaMJJA2+BcxbVnyRO0=",
"path": "github.com/prometheus/common/version",
"revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
"revisionTime": "2017-09-08T16:18:22Z"
"revision": "1bab55dd05dbff384524a6a1c99006d9eb5f139b",
"revisionTime": "2017-10-06T14:14:18Z"
},
{
"checksumSHA1": "ihxJIjxtbEYdQKwA0D0nRipj95I=",
"checksumSHA1": "pW1yt1G1J9jnQMCxr1TDI7LQr3s=",
"path": "github.com/prometheus/procfs",
"revision": "e645f4e5aaa8506fc71d6edbc5c4ff02c04c46f2",
"revisionTime": "2017-07-03T10:12:42Z"
"revision": "a6e9df898b1336106c743392c48ee0b71f5c4efa",
"revisionTime": "2017-10-17T21:40:25Z"
},
{
"checksumSHA1": "RAb14ZPZ6Y+AD0TnMBqLHaIw/I8=",
"path": "github.com/prometheus/procfs/bcache",
"revision": "e645f4e5aaa8506fc71d6edbc5c4ff02c04c46f2",
"revisionTime": "2017-07-03T10:12:42Z"
"revision": "a6e9df898b1336106c743392c48ee0b71f5c4efa",
"revisionTime": "2017-10-17T21:40:25Z"
},
{
"checksumSHA1": "wMhQkA/xQw3Q8eI+PIAjFmS94Qo=",
"path": "github.com/prometheus/procfs/sysfs",
"revision": "e645f4e5aaa8506fc71d6edbc5c4ff02c04c46f2",
"revisionTime": "2017-07-03T10:12:42Z"
"revision": "a6e9df898b1336106c743392c48ee0b71f5c4efa",
"revisionTime": "2017-10-17T21:40:25Z"
},
{
"checksumSHA1": "xCiFAAwVTrjsfZT1BIJQ3DgeNCY=",
"path": "github.com/prometheus/procfs/xfs",
"revision": "e645f4e5aaa8506fc71d6edbc5c4ff02c04c46f2",
"revisionTime": "2017-07-03T10:12:42Z"
"revision": "a6e9df898b1336106c743392c48ee0b71f5c4efa",
"revisionTime": "2017-10-17T21:40:25Z"
},
{
"checksumSHA1": "5+eS1Ticg5wkpsdNoPiST3OQcIg=",
@ -237,22 +243,22 @@
"revisionTime": "2017-10-30T10:08:44Z"
},
{
"checksumSHA1": "pBPFzDGt3AVSRffB7ffiUnruFUk=",
"checksumSHA1": "8BcMOi8XTSigDtV2npDc8vMrS60=",
"path": "golang.org/x/sys/windows",
"revision": "314a259e304ff91bd6985da2a7149bbf91237993",
"revisionTime": "2017-07-19T03:44:26Z"
"revision": "95c6576299259db960f6c5b9b69ea52422860fce",
"revisionTime": "2017-10-30T10:08:44Z"
},
{
"checksumSHA1": "ZdFZFaXmCgEEaEhVPkyXrnhKhsg=",
"path": "golang.org/x/sys/windows/registry",
"revision": "314a259e304ff91bd6985da2a7149bbf91237993",
"revisionTime": "2017-07-19T03:44:26Z"
"revision": "95c6576299259db960f6c5b9b69ea52422860fce",
"revisionTime": "2017-10-30T10:08:44Z"
},
{
"checksumSHA1": "uVlUSSKplihZG7N+QJ6fzDZ4Kh8=",
"path": "golang.org/x/sys/windows/svc/eventlog",
"revision": "314a259e304ff91bd6985da2a7149bbf91237993",
"revisionTime": "2017-07-19T03:44:26Z"
"revision": "95c6576299259db960f6c5b9b69ea52422860fce",
"revisionTime": "2017-10-30T10:08:44Z"
},
{
"checksumSHA1": "3SZTatHIy9OTKc95YlVfXKnoySg=",