From 4a3be6086ed6fd5393d7081144ee147a8cc1fd36 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Thu, 5 Jul 2018 15:44:04 +0200 Subject: [PATCH] Update deps --- Gopkg.lock | 4 +- vendor/golang.org/x/net/http2/flow.go | 10 +- vendor/golang.org/x/net/http2/flow_test.go | 34 +++++++ vendor/golang.org/x/net/http2/server.go | 13 +++ vendor/golang.org/x/net/http2/server_test.go | 63 ++++++++++++ vendor/golang.org/x/net/ipv4/batch.go | 9 +- vendor/golang.org/x/net/ipv4/dgramopt.go | 31 +++--- vendor/golang.org/x/net/ipv4/doc.go | 2 +- vendor/golang.org/x/net/ipv4/endpoint.go | 21 ++-- vendor/golang.org/x/net/ipv4/genericopt.go | 10 +- vendor/golang.org/x/net/ipv4/header.go | 3 +- vendor/golang.org/x/net/ipv4/helper.go | 1 + .../golang.org/x/net/ipv4/multicast_test.go | 4 +- .../x/net/ipv4/multicastlistener_test.go | 10 +- .../x/net/ipv4/multicastsockopt_test.go | 4 +- vendor/golang.org/x/net/ipv4/packet.go | 5 +- vendor/golang.org/x/net/ipv4/payload_cmsg.go | 9 +- .../golang.org/x/net/ipv4/payload_nocmsg.go | 9 +- .../x/net/ipv4/readwrite_go1_8_test.go | 4 +- .../x/net/ipv4/readwrite_go1_9_test.go | 4 +- .../golang.org/x/net/ipv4/readwrite_test.go | 2 +- vendor/golang.org/x/net/ipv4/unicast_test.go | 6 +- .../x/net/ipv4/unicastsockopt_test.go | 6 +- vendor/golang.org/x/net/ipv6/batch.go | 5 +- vendor/golang.org/x/net/ipv6/dgramopt.go | 35 ++++--- vendor/golang.org/x/net/ipv6/doc.go | 2 +- vendor/golang.org/x/net/ipv6/endpoint.go | 13 ++- vendor/golang.org/x/net/ipv6/genericopt.go | 10 +- vendor/golang.org/x/net/ipv6/helper.go | 1 + vendor/golang.org/x/net/ipv6/icmp_test.go | 4 +- .../golang.org/x/net/ipv6/multicast_test.go | 4 +- .../x/net/ipv6/multicastlistener_test.go | 10 +- .../x/net/ipv6/multicastsockopt_test.go | 2 +- vendor/golang.org/x/net/ipv6/payload_cmsg.go | 9 +- .../golang.org/x/net/ipv6/payload_nocmsg.go | 9 +- .../x/net/ipv6/readwrite_go1_8_test.go | 4 +- .../x/net/ipv6/readwrite_go1_9_test.go | 4 +- .../golang.org/x/net/ipv6/readwrite_test.go | 2 +- vendor/golang.org/x/net/ipv6/sockopt_test.go | 6 +- vendor/golang.org/x/net/ipv6/unicast_test.go | 4 +- .../x/net/ipv6/unicastsockopt_test.go | 4 +- vendor/golang.org/x/sys/windows/service.go | 18 ++++ .../x/sys/windows/svc/mgr/config.go | 38 ++++---- .../x/sys/windows/svc/mgr/mgr_test.go | 81 ++++++++++++++++ .../x/sys/windows/svc/mgr/recovery.go | 96 +++++++++++++++++++ 45 files changed, 457 insertions(+), 168 deletions(-) create mode 100644 vendor/golang.org/x/sys/windows/svc/mgr/recovery.go diff --git a/Gopkg.lock b/Gopkg.lock index 6e00dd71..437e0087 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -167,7 +167,7 @@ "ipv6", "proxy" ] - revision = "afe8f62b1d6bbd81f31868121a50b06d8188e1f9" + revision = "ed29d75add3d7c4bf7ca65aac0c6df3d1420216f" [[projects]] branch = "master" @@ -180,7 +180,7 @@ "windows/svc/eventlog", "windows/svc/mgr" ] - revision = "a200a19cb90b19de298170992778b1fda7217bd6" + revision = "151529c776cdc58ddbe7963ba9af779f3577b419" [[projects]] name = "golang.org/x/text" diff --git a/vendor/golang.org/x/net/http2/flow.go b/vendor/golang.org/x/net/http2/flow.go index 957de254..cea601fc 100644 --- a/vendor/golang.org/x/net/http2/flow.go +++ b/vendor/golang.org/x/net/http2/flow.go @@ -41,10 +41,10 @@ func (f *flow) take(n int32) { // add adds n bytes (positive or negative) to the flow control window. // It returns false if the sum would exceed 2^31-1. func (f *flow) add(n int32) bool { - remain := (1<<31 - 1) - f.n - if n > remain { - return false + sum := f.n + n + if (sum > n) == (f.n > 0) { + f.n = sum + return true } - f.n += n - return true + return false } diff --git a/vendor/golang.org/x/net/http2/flow_test.go b/vendor/golang.org/x/net/http2/flow_test.go index 859adf5d..7ae82c78 100644 --- a/vendor/golang.org/x/net/http2/flow_test.go +++ b/vendor/golang.org/x/net/http2/flow_test.go @@ -49,5 +49,39 @@ func TestFlowAdd(t *testing.T) { if f.add(1) { t.Fatal("adding 1 to max shouldn't be allowed") } +} + +func TestFlowAddOverflow(t *testing.T) { + var f flow + if !f.add(0) { + t.Fatal("failed to add 0") + } + if !f.add(-1) { + t.Fatal("failed to add -1") + } + if !f.add(0) { + t.Fatal("failed to add 0") + } + if !f.add(1) { + t.Fatal("failed to add 1") + } + if !f.add(1) { + t.Fatal("failed to add 1") + } + if !f.add(0) { + t.Fatal("failed to add 0") + } + if !f.add(-3) { + t.Fatal("failed to add -3") + } + if got, want := f.available(), int32(-2); got != want { + t.Fatalf("size = %d; want %d", got, want) + } + if !f.add(1<<31 - 1) { + t.Fatal("failed to add 2^31-1") + } + if got, want := f.available(), int32(1+-3+(1<<31-1)); got != want { + t.Fatalf("size = %d; want %d", got, want) + } } diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 769c0fe5..79389916 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -2347,6 +2347,19 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { foreachHeaderElement(v, rws.declareTrailer) } + // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2), + // but respect "Connection" == "close" to mean sending a GOAWAY and tearing + // down the TCP connection when idle, like we do for HTTP/1. + // TODO: remove more Connection-specific header fields here, in addition + // to "Connection". + if _, ok := rws.snapHeader["Connection"]; ok { + v := rws.snapHeader.Get("Connection") + delete(rws.snapHeader, "Connection") + if v == "close" { + rws.conn.startGracefulShutdown() + } + } + endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ streamID: rws.stream.id, diff --git a/vendor/golang.org/x/net/http2/server_test.go b/vendor/golang.org/x/net/http2/server_test.go index baab0f14..02eb0dcc 100644 --- a/vendor/golang.org/x/net/http2/server_test.go +++ b/vendor/golang.org/x/net/http2/server_test.go @@ -3762,6 +3762,7 @@ func TestIssue20704Race(t *testing.T) { func TestServer_Rejects_TooSmall(t *testing.T) { testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + ioutil.ReadAll(r.Body) return nil }, func(st *serverTester) { st.writeHeaders(HeadersFrameParam{ @@ -3778,3 +3779,65 @@ func TestServer_Rejects_TooSmall(t *testing.T) { st.wantRSTStream(1, ErrCodeProtocol) }) } + +// Tests that a handler setting "Connection: close" results in a GOAWAY being sent, +// and the connection still completing. +func TestServerHandlerConnectionClose(t *testing.T) { + unblockHandler := make(chan bool, 1) + defer close(unblockHandler) // backup; in case of errors + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.Header().Set("Connection", "close") + w.Header().Set("Foo", "bar") + w.(http.Flusher).Flush() + <-unblockHandler + return nil + }, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(), + EndStream: true, + EndHeaders: true, + }) + var sawGoAway bool + var sawRes bool + for { + f, err := st.readFrame() + if err == io.EOF { + break + } + if err != nil { + t.Fatal(err) + } + switch f := f.(type) { + case *GoAwayFrame: + sawGoAway = true + unblockHandler <- true + if f.LastStreamID != 1 || f.ErrCode != ErrCodeNo { + t.Errorf("unexpected GOAWAY frame: %v", summarizeFrame(f)) + } + case *HeadersFrame: + goth := st.decodeHeader(f.HeaderBlockFragment()) + if !sawGoAway { + t.Fatalf("unexpected Headers frame before GOAWAY: %s, %v", summarizeFrame(f), goth) + } + wanth := [][2]string{ + {":status", "200"}, + {"foo", "bar"}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("got headers %v; want %v", goth, wanth) + } + sawRes = true + case *DataFrame: + if f.StreamID != 1 || !f.StreamEnded() || len(f.Data()) != 0 { + t.Errorf("unexpected DATA frame: %v", summarizeFrame(f)) + } + default: + t.Logf("unexpected frame: %v", summarizeFrame(f)) + } + } + if !sawRes { + t.Errorf("didn't see response") + } + }) +} diff --git a/vendor/golang.org/x/net/ipv4/batch.go b/vendor/golang.org/x/net/ipv4/batch.go index b4454992..5ce9b358 100644 --- a/vendor/golang.org/x/net/ipv4/batch.go +++ b/vendor/golang.org/x/net/ipv4/batch.go @@ -9,7 +9,6 @@ package ipv4 import ( "net" "runtime" - "syscall" "golang.org/x/net/internal/socket" ) @@ -76,7 +75,7 @@ type Message = socket.Message // headers. func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": @@ -107,7 +106,7 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { // On other platforms, this method will write only a single message. func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": @@ -139,7 +138,7 @@ func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) { // On other platforms, this method will read only a single message. func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": @@ -170,7 +169,7 @@ func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) { // On other platforms, this method will write only a single message. func (c *packetHandler) WriteBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": diff --git a/vendor/golang.org/x/net/ipv4/dgramopt.go b/vendor/golang.org/x/net/ipv4/dgramopt.go index 54d77d5f..36764492 100644 --- a/vendor/golang.org/x/net/ipv4/dgramopt.go +++ b/vendor/golang.org/x/net/ipv4/dgramopt.go @@ -6,7 +6,6 @@ package ipv4 import ( "net" - "syscall" "golang.org/x/net/bpf" ) @@ -15,7 +14,7 @@ import ( // multicast packets. func (c *dgramOpt) MulticastTTL() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoMulticastTTL] if !ok { @@ -28,7 +27,7 @@ func (c *dgramOpt) MulticastTTL() (int, error) { // outgoing multicast packets. func (c *dgramOpt) SetMulticastTTL(ttl int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastTTL] if !ok { @@ -41,7 +40,7 @@ func (c *dgramOpt) SetMulticastTTL(ttl int) error { // packet transmissions. func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { if !c.ok() { - return nil, syscall.EINVAL + return nil, errInvalidConn } so, ok := sockOpts[ssoMulticastInterface] if !ok { @@ -54,7 +53,7 @@ func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { // multicast packet transmissions. func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastInterface] if !ok { @@ -67,7 +66,7 @@ func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { // should be copied and send back to the originator. func (c *dgramOpt) MulticastLoopback() (bool, error) { if !c.ok() { - return false, syscall.EINVAL + return false, errInvalidConn } so, ok := sockOpts[ssoMulticastLoopback] if !ok { @@ -84,7 +83,7 @@ func (c *dgramOpt) MulticastLoopback() (bool, error) { // should be copied and send back to the originator. func (c *dgramOpt) SetMulticastLoopback(on bool) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastLoopback] if !ok { @@ -104,7 +103,7 @@ func (c *dgramOpt) SetMulticastLoopback(on bool) error { // configuration. func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoJoinGroup] if !ok { @@ -122,7 +121,7 @@ func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { // source-specific group. func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoLeaveGroup] if !ok { @@ -143,7 +142,7 @@ func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { // routing configuration. func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoJoinSourceGroup] if !ok { @@ -164,7 +163,7 @@ func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net // interface ifi. func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoLeaveSourceGroup] if !ok { @@ -186,7 +185,7 @@ func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source ne // ifi. func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoBlockSourceGroup] if !ok { @@ -207,7 +206,7 @@ func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source // group by ExcludeSourceSpecificGroup again on the interface ifi. func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoUnblockSourceGroup] if !ok { @@ -228,7 +227,7 @@ func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source // Currently only Linux supports this. func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { if !c.ok() { - return nil, syscall.EINVAL + return nil, errInvalidConn } so, ok := sockOpts[ssoICMPFilter] if !ok { @@ -241,7 +240,7 @@ func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { // Currently only Linux supports this. func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoICMPFilter] if !ok { @@ -255,7 +254,7 @@ func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { // Only supported on Linux. func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoAttachFilter] if !ok { diff --git a/vendor/golang.org/x/net/ipv4/doc.go b/vendor/golang.org/x/net/ipv4/doc.go index b43935a5..d1245554 100644 --- a/vendor/golang.org/x/net/ipv4/doc.go +++ b/vendor/golang.org/x/net/ipv4/doc.go @@ -241,4 +241,4 @@ // IncludeSourceSpecificGroup may return an error. package ipv4 // import "golang.org/x/net/ipv4" -// BUG(mikio): This package is not implemented on NaCl and Plan 9. +// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9. diff --git a/vendor/golang.org/x/net/ipv4/endpoint.go b/vendor/golang.org/x/net/ipv4/endpoint.go index 2ab87736..50094637 100644 --- a/vendor/golang.org/x/net/ipv4/endpoint.go +++ b/vendor/golang.org/x/net/ipv4/endpoint.go @@ -6,7 +6,6 @@ package ipv4 import ( "net" - "syscall" "time" "golang.org/x/net/internal/socket" @@ -58,7 +57,7 @@ func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil } // SetControlMessage sets the per packet IP-level socket options. func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on) } @@ -67,7 +66,7 @@ func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { // endpoint. func (c *PacketConn) SetDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.PacketConn.SetDeadline(t) } @@ -76,7 +75,7 @@ func (c *PacketConn) SetDeadline(t time.Time) error { // endpoint. func (c *PacketConn) SetReadDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.PacketConn.SetReadDeadline(t) } @@ -85,7 +84,7 @@ func (c *PacketConn) SetReadDeadline(t time.Time) error { // endpoint. func (c *PacketConn) SetWriteDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.PacketConn.SetWriteDeadline(t) } @@ -93,7 +92,7 @@ func (c *PacketConn) SetWriteDeadline(t time.Time) error { // Close closes the endpoint. func (c *PacketConn) Close() error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.PacketConn.Close() } @@ -124,7 +123,7 @@ type RawConn struct { // SetControlMessage sets the per packet IP-level socket options. func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on) } @@ -133,7 +132,7 @@ func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error { // endpoint. func (c *RawConn) SetDeadline(t time.Time) error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.packetHandler.IPConn.SetDeadline(t) } @@ -142,7 +141,7 @@ func (c *RawConn) SetDeadline(t time.Time) error { // endpoint. func (c *RawConn) SetReadDeadline(t time.Time) error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.packetHandler.IPConn.SetReadDeadline(t) } @@ -151,7 +150,7 @@ func (c *RawConn) SetReadDeadline(t time.Time) error { // endpoint. func (c *RawConn) SetWriteDeadline(t time.Time) error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.packetHandler.IPConn.SetWriteDeadline(t) } @@ -159,7 +158,7 @@ func (c *RawConn) SetWriteDeadline(t time.Time) error { // Close closes the endpoint. func (c *RawConn) Close() error { if !c.packetHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.packetHandler.IPConn.Close() } diff --git a/vendor/golang.org/x/net/ipv4/genericopt.go b/vendor/golang.org/x/net/ipv4/genericopt.go index 119bf841..587ae4a1 100644 --- a/vendor/golang.org/x/net/ipv4/genericopt.go +++ b/vendor/golang.org/x/net/ipv4/genericopt.go @@ -4,12 +4,10 @@ package ipv4 -import "syscall" - // TOS returns the type-of-service field value for outgoing packets. func (c *genericOpt) TOS() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoTOS] if !ok { @@ -22,7 +20,7 @@ func (c *genericOpt) TOS() (int, error) { // packets. func (c *genericOpt) SetTOS(tos int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoTOS] if !ok { @@ -34,7 +32,7 @@ func (c *genericOpt) SetTOS(tos int) error { // TTL returns the time-to-live field value for outgoing packets. func (c *genericOpt) TTL() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoTTL] if !ok { @@ -47,7 +45,7 @@ func (c *genericOpt) TTL() (int, error) { // packets. func (c *genericOpt) SetTTL(ttl int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoTTL] if !ok { diff --git a/vendor/golang.org/x/net/ipv4/header.go b/vendor/golang.org/x/net/ipv4/header.go index c8822a6a..358afe2f 100644 --- a/vendor/golang.org/x/net/ipv4/header.go +++ b/vendor/golang.org/x/net/ipv4/header.go @@ -9,7 +9,6 @@ import ( "fmt" "net" "runtime" - "syscall" "golang.org/x/net/internal/socket" ) @@ -54,7 +53,7 @@ func (h *Header) String() string { // Marshal returns the binary encoding of h. func (h *Header) Marshal() ([]byte, error) { if h == nil { - return nil, syscall.EINVAL + return nil, errInvalidConn } if h.Len < HeaderLen { return nil, errHeaderTooShort diff --git a/vendor/golang.org/x/net/ipv4/helper.go b/vendor/golang.org/x/net/ipv4/helper.go index a5052e32..8d8ff98e 100644 --- a/vendor/golang.org/x/net/ipv4/helper.go +++ b/vendor/golang.org/x/net/ipv4/helper.go @@ -10,6 +10,7 @@ import ( ) var ( + errInvalidConn = errors.New("invalid connection") errMissingAddress = errors.New("missing address") errMissingHeader = errors.New("missing header") errHeaderTooShort = errors.New("header too short") diff --git a/vendor/golang.org/x/net/ipv4/multicast_test.go b/vendor/golang.org/x/net/ipv4/multicast_test.go index bcf49736..2136a3c6 100644 --- a/vendor/golang.org/x/net/ipv4/multicast_test.go +++ b/vendor/golang.org/x/net/ipv4/multicast_test.go @@ -29,7 +29,7 @@ var packetConnReadWriteMulticastUDPTests = []struct { func TestPacketConnReadWriteMulticastUDP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "solaris", "windows": + case "js", "nacl", "plan9", "solaris", "windows": t.Skipf("not supported on %s", runtime.GOOS) } ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) @@ -117,7 +117,7 @@ var packetConnReadWriteMulticastICMPTests = []struct { func TestPacketConnReadWriteMulticastICMP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "solaris", "windows": + case "js", "nacl", "plan9", "solaris", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if m, ok := nettest.SupportsRawIPSocket(); !ok { diff --git a/vendor/golang.org/x/net/ipv4/multicastlistener_test.go b/vendor/golang.org/x/net/ipv4/multicastlistener_test.go index e43fbbe0..ba2480e4 100644 --- a/vendor/golang.org/x/net/ipv4/multicastlistener_test.go +++ b/vendor/golang.org/x/net/ipv4/multicastlistener_test.go @@ -21,7 +21,7 @@ var udpMultipleGroupListenerTests = []net.Addr{ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if testing.Short() { @@ -61,7 +61,7 @@ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if testing.Short() { @@ -116,7 +116,7 @@ func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if testing.Short() { @@ -172,7 +172,7 @@ func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if testing.Short() { @@ -217,7 +217,7 @@ func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) { func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if testing.Short() { diff --git a/vendor/golang.org/x/net/ipv4/multicastsockopt_test.go b/vendor/golang.org/x/net/ipv4/multicastsockopt_test.go index f7efac24..c0a26800 100644 --- a/vendor/golang.org/x/net/ipv4/multicastsockopt_test.go +++ b/vendor/golang.org/x/net/ipv4/multicastsockopt_test.go @@ -26,7 +26,7 @@ var packetConnMulticastSocketOptionTests = []struct { func TestPacketConnMulticastSocketOptions(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "js", "nacl", "plan9": t.Skipf("not supported on %s", runtime.GOOS) } ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) @@ -66,7 +66,7 @@ var rawConnMulticastSocketOptionTests = []struct { func TestRawConnMulticastSocketOptions(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "js", "nacl", "plan9": t.Skipf("not supported on %s", runtime.GOOS) } if m, ok := nettest.SupportsRawIPSocket(); !ok { diff --git a/vendor/golang.org/x/net/ipv4/packet.go b/vendor/golang.org/x/net/ipv4/packet.go index f00f5b05..966bb776 100644 --- a/vendor/golang.org/x/net/ipv4/packet.go +++ b/vendor/golang.org/x/net/ipv4/packet.go @@ -6,7 +6,6 @@ package ipv4 import ( "net" - "syscall" "golang.org/x/net/internal/socket" ) @@ -28,7 +27,7 @@ func (c *packetHandler) ok() bool { return c != nil && c.IPConn != nil && c.Conn // header h, the payload p and the control message cm. func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) { if !c.ok() { - return nil, nil, nil, syscall.EINVAL + return nil, nil, nil, errInvalidConn } return c.readFrom(b) } @@ -63,7 +62,7 @@ func slicePacket(b []byte) (h, p []byte, err error) { // Options = optional func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } return c.writeTo(h, p, cm) } diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg.go b/vendor/golang.org/x/net/ipv4/payload_cmsg.go index 3f06d760..eec520c4 100644 --- a/vendor/golang.org/x/net/ipv4/payload_cmsg.go +++ b/vendor/golang.org/x/net/ipv4/payload_cmsg.go @@ -6,10 +6,7 @@ package ipv4 -import ( - "net" - "syscall" -) +import "net" // ReadFrom reads a payload of the received IPv4 datagram, from the // endpoint c, copying the payload into b. It returns the number of @@ -17,7 +14,7 @@ import ( // src of the received datagram. func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { if !c.ok() { - return 0, nil, nil, syscall.EINVAL + return 0, nil, nil, errInvalidConn } return c.readFrom(b) } @@ -30,7 +27,7 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net. // control of the outgoing datagram is not required. func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } return c.writeTo(b, cm, dst) } diff --git a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go index 3926de70..8cb21b39 100644 --- a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go +++ b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go @@ -6,10 +6,7 @@ package ipv4 -import ( - "net" - "syscall" -) +import "net" // ReadFrom reads a payload of the received IPv4 datagram, from the // endpoint c, copying the payload into b. It returns the number of @@ -17,7 +14,7 @@ import ( // src of the received datagram. func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { if !c.ok() { - return 0, nil, nil, syscall.EINVAL + return 0, nil, nil, errInvalidConn } if n, src, err = c.PacketConn.ReadFrom(b); err != nil { return 0, nil, nil, err @@ -33,7 +30,7 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net. // control of the outgoing datagram is not required. func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } if dst == nil { return 0, errMissingAddress diff --git a/vendor/golang.org/x/net/ipv4/readwrite_go1_8_test.go b/vendor/golang.org/x/net/ipv4/readwrite_go1_8_test.go index 1cd926e7..83bf927e 100644 --- a/vendor/golang.org/x/net/ipv4/readwrite_go1_8_test.go +++ b/vendor/golang.org/x/net/ipv4/readwrite_go1_8_test.go @@ -22,7 +22,7 @@ import ( func BenchmarkPacketConnReadWriteUnicast(b *testing.B) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": b.Skipf("not supported on %s", runtime.GOOS) } @@ -126,7 +126,7 @@ func BenchmarkPacketConnReadWriteUnicast(b *testing.B) { func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } diff --git a/vendor/golang.org/x/net/ipv4/readwrite_go1_9_test.go b/vendor/golang.org/x/net/ipv4/readwrite_go1_9_test.go index 365de022..ef76c8a7 100644 --- a/vendor/golang.org/x/net/ipv4/readwrite_go1_9_test.go +++ b/vendor/golang.org/x/net/ipv4/readwrite_go1_9_test.go @@ -22,7 +22,7 @@ import ( func BenchmarkPacketConnReadWriteUnicast(b *testing.B) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": b.Skipf("not supported on %s", runtime.GOOS) } @@ -172,7 +172,7 @@ func BenchmarkPacketConnReadWriteUnicast(b *testing.B) { func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } diff --git a/vendor/golang.org/x/net/ipv4/readwrite_test.go b/vendor/golang.org/x/net/ipv4/readwrite_test.go index 3896a8ae..1b7f7488 100644 --- a/vendor/golang.org/x/net/ipv4/readwrite_test.go +++ b/vendor/golang.org/x/net/ipv4/readwrite_test.go @@ -61,7 +61,7 @@ func BenchmarkReadWriteUnicast(b *testing.B) { func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } diff --git a/vendor/golang.org/x/net/ipv4/unicast_test.go b/vendor/golang.org/x/net/ipv4/unicast_test.go index 02c089f0..274a558c 100644 --- a/vendor/golang.org/x/net/ipv4/unicast_test.go +++ b/vendor/golang.org/x/net/ipv4/unicast_test.go @@ -20,7 +20,7 @@ import ( func TestPacketConnReadWriteUnicastUDP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) @@ -71,7 +71,7 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) { func TestPacketConnReadWriteUnicastICMP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if m, ok := nettest.SupportsRawIPSocket(); !ok { @@ -157,7 +157,7 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) { func TestRawConnReadWriteUnicastICMP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if m, ok := nettest.SupportsRawIPSocket(); !ok { diff --git a/vendor/golang.org/x/net/ipv4/unicastsockopt_test.go b/vendor/golang.org/x/net/ipv4/unicastsockopt_test.go index db5213b9..2bfda7ff 100644 --- a/vendor/golang.org/x/net/ipv4/unicastsockopt_test.go +++ b/vendor/golang.org/x/net/ipv4/unicastsockopt_test.go @@ -16,7 +16,7 @@ import ( func TestConnUnicastSocketOptions(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) @@ -62,7 +62,7 @@ var packetConnUnicastSocketOptionTests = []struct { func TestPacketConnUnicastSocketOptions(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) @@ -88,7 +88,7 @@ func TestPacketConnUnicastSocketOptions(t *testing.T) { func TestRawConnUnicastSocketOptions(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if m, ok := nettest.SupportsRawIPSocket(); !ok { diff --git a/vendor/golang.org/x/net/ipv6/batch.go b/vendor/golang.org/x/net/ipv6/batch.go index 4f5fe683..10d64924 100644 --- a/vendor/golang.org/x/net/ipv6/batch.go +++ b/vendor/golang.org/x/net/ipv6/batch.go @@ -9,7 +9,6 @@ package ipv6 import ( "net" "runtime" - "syscall" "golang.org/x/net/internal/socket" ) @@ -67,7 +66,7 @@ type Message = socket.Message // On other platforms, this method will read only a single message. func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": @@ -98,7 +97,7 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { // On other platforms, this method will write only a single message. func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } switch runtime.GOOS { case "linux": diff --git a/vendor/golang.org/x/net/ipv6/dgramopt.go b/vendor/golang.org/x/net/ipv6/dgramopt.go index 703dafe8..eea4fde2 100644 --- a/vendor/golang.org/x/net/ipv6/dgramopt.go +++ b/vendor/golang.org/x/net/ipv6/dgramopt.go @@ -6,7 +6,6 @@ package ipv6 import ( "net" - "syscall" "golang.org/x/net/bpf" ) @@ -15,7 +14,7 @@ import ( // multicast packets. func (c *dgramOpt) MulticastHopLimit() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoMulticastHopLimit] if !ok { @@ -28,7 +27,7 @@ func (c *dgramOpt) MulticastHopLimit() (int, error) { // outgoing multicast packets. func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastHopLimit] if !ok { @@ -41,7 +40,7 @@ func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error { // packet transmissions. func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { if !c.ok() { - return nil, syscall.EINVAL + return nil, errInvalidConn } so, ok := sockOpts[ssoMulticastInterface] if !ok { @@ -54,7 +53,7 @@ func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { // multicast packet transmissions. func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastInterface] if !ok { @@ -67,7 +66,7 @@ func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { // should be copied and send back to the originator. func (c *dgramOpt) MulticastLoopback() (bool, error) { if !c.ok() { - return false, syscall.EINVAL + return false, errInvalidConn } so, ok := sockOpts[ssoMulticastLoopback] if !ok { @@ -84,7 +83,7 @@ func (c *dgramOpt) MulticastLoopback() (bool, error) { // should be copied and send back to the originator. func (c *dgramOpt) SetMulticastLoopback(on bool) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoMulticastLoopback] if !ok { @@ -104,7 +103,7 @@ func (c *dgramOpt) SetMulticastLoopback(on bool) error { // configuration. func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoJoinGroup] if !ok { @@ -122,7 +121,7 @@ func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { // source-specific group. func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoLeaveGroup] if !ok { @@ -143,7 +142,7 @@ func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { // routing configuration. func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoJoinSourceGroup] if !ok { @@ -164,7 +163,7 @@ func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net // interface ifi. func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoLeaveSourceGroup] if !ok { @@ -186,7 +185,7 @@ func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source ne // ifi. func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoBlockSourceGroup] if !ok { @@ -207,7 +206,7 @@ func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source // group by ExcludeSourceSpecificGroup again on the interface ifi. func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoUnblockSourceGroup] if !ok { @@ -230,7 +229,7 @@ func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source // field is located. func (c *dgramOpt) Checksum() (on bool, offset int, err error) { if !c.ok() { - return false, 0, syscall.EINVAL + return false, 0, errInvalidConn } so, ok := sockOpts[ssoChecksum] if !ok { @@ -251,7 +250,7 @@ func (c *dgramOpt) Checksum() (on bool, offset int, err error) { // checksum field is located. func (c *dgramOpt) SetChecksum(on bool, offset int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoChecksum] if !ok { @@ -266,7 +265,7 @@ func (c *dgramOpt) SetChecksum(on bool, offset int) error { // ICMPFilter returns an ICMP filter. func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { if !c.ok() { - return nil, syscall.EINVAL + return nil, errInvalidConn } so, ok := sockOpts[ssoICMPFilter] if !ok { @@ -278,7 +277,7 @@ func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { // SetICMPFilter deploys the ICMP filter. func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoICMPFilter] if !ok { @@ -292,7 +291,7 @@ func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { // Only supported on Linux. func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoAttachFilter] if !ok { diff --git a/vendor/golang.org/x/net/ipv6/doc.go b/vendor/golang.org/x/net/ipv6/doc.go index 664a97de..cb400062 100644 --- a/vendor/golang.org/x/net/ipv6/doc.go +++ b/vendor/golang.org/x/net/ipv6/doc.go @@ -240,4 +240,4 @@ // IncludeSourceSpecificGroup may return an error. package ipv6 // import "golang.org/x/net/ipv6" -// BUG(mikio): This package is not implemented on NaCl and Plan 9. +// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9. diff --git a/vendor/golang.org/x/net/ipv6/endpoint.go b/vendor/golang.org/x/net/ipv6/endpoint.go index 0624c174..93257563 100644 --- a/vendor/golang.org/x/net/ipv6/endpoint.go +++ b/vendor/golang.org/x/net/ipv6/endpoint.go @@ -6,7 +6,6 @@ package ipv6 import ( "net" - "syscall" "time" "golang.org/x/net/internal/socket" @@ -34,7 +33,7 @@ func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil } // with the endpoint. func (c *Conn) PathMTU() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoPathMTU] if !ok { @@ -76,7 +75,7 @@ func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil } // socket options. func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on) } @@ -85,7 +84,7 @@ func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { // endpoint. func (c *PacketConn) SetDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.SetDeadline(t) } @@ -94,7 +93,7 @@ func (c *PacketConn) SetDeadline(t time.Time) error { // endpoint. func (c *PacketConn) SetReadDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.SetReadDeadline(t) } @@ -103,7 +102,7 @@ func (c *PacketConn) SetReadDeadline(t time.Time) error { // endpoint. func (c *PacketConn) SetWriteDeadline(t time.Time) error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.SetWriteDeadline(t) } @@ -111,7 +110,7 @@ func (c *PacketConn) SetWriteDeadline(t time.Time) error { // Close closes the endpoint. func (c *PacketConn) Close() error { if !c.payloadHandler.ok() { - return syscall.EINVAL + return errInvalidConn } return c.payloadHandler.Close() } diff --git a/vendor/golang.org/x/net/ipv6/genericopt.go b/vendor/golang.org/x/net/ipv6/genericopt.go index e9dbc2e1..1a18f754 100644 --- a/vendor/golang.org/x/net/ipv6/genericopt.go +++ b/vendor/golang.org/x/net/ipv6/genericopt.go @@ -4,13 +4,11 @@ package ipv6 -import "syscall" - // TrafficClass returns the traffic class field value for outgoing // packets. func (c *genericOpt) TrafficClass() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoTrafficClass] if !ok { @@ -23,7 +21,7 @@ func (c *genericOpt) TrafficClass() (int, error) { // outgoing packets. func (c *genericOpt) SetTrafficClass(tclass int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoTrafficClass] if !ok { @@ -35,7 +33,7 @@ func (c *genericOpt) SetTrafficClass(tclass int) error { // HopLimit returns the hop limit field value for outgoing packets. func (c *genericOpt) HopLimit() (int, error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } so, ok := sockOpts[ssoHopLimit] if !ok { @@ -48,7 +46,7 @@ func (c *genericOpt) HopLimit() (int, error) { // packets. func (c *genericOpt) SetHopLimit(hoplim int) error { if !c.ok() { - return syscall.EINVAL + return errInvalidConn } so, ok := sockOpts[ssoHopLimit] if !ok { diff --git a/vendor/golang.org/x/net/ipv6/helper.go b/vendor/golang.org/x/net/ipv6/helper.go index 25974013..7ac53522 100644 --- a/vendor/golang.org/x/net/ipv6/helper.go +++ b/vendor/golang.org/x/net/ipv6/helper.go @@ -10,6 +10,7 @@ import ( ) var ( + errInvalidConn = errors.New("invalid connection") errMissingAddress = errors.New("missing address") errHeaderTooShort = errors.New("header too short") errInvalidConnType = errors.New("invalid conn type") diff --git a/vendor/golang.org/x/net/ipv6/icmp_test.go b/vendor/golang.org/x/net/ipv6/icmp_test.go index d8e9675d..bdde2fdb 100644 --- a/vendor/golang.org/x/net/ipv6/icmp_test.go +++ b/vendor/golang.org/x/net/ipv6/icmp_test.go @@ -34,7 +34,7 @@ func TestICMPString(t *testing.T) { func TestICMPFilter(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } @@ -61,7 +61,7 @@ func TestICMPFilter(t *testing.T) { func TestSetICMPFilter(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { diff --git a/vendor/golang.org/x/net/ipv6/multicast_test.go b/vendor/golang.org/x/net/ipv6/multicast_test.go index 69a21cd3..50442c36 100644 --- a/vendor/golang.org/x/net/ipv6/multicast_test.go +++ b/vendor/golang.org/x/net/ipv6/multicast_test.go @@ -29,7 +29,7 @@ var packetConnReadWriteMulticastUDPTests = []struct { func TestPacketConnReadWriteMulticastUDP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { @@ -129,7 +129,7 @@ var packetConnReadWriteMulticastICMPTests = []struct { func TestPacketConnReadWriteMulticastICMP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { diff --git a/vendor/golang.org/x/net/ipv6/multicastlistener_test.go b/vendor/golang.org/x/net/ipv6/multicastlistener_test.go index b27713e2..1ee0549d 100644 --- a/vendor/golang.org/x/net/ipv6/multicastlistener_test.go +++ b/vendor/golang.org/x/net/ipv6/multicastlistener_test.go @@ -21,7 +21,7 @@ var udpMultipleGroupListenerTests = []net.Addr{ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { @@ -61,7 +61,7 @@ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { @@ -116,7 +116,7 @@ func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { @@ -172,7 +172,7 @@ func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { @@ -216,7 +216,7 @@ func TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { switch runtime.GOOS { case "darwin", "dragonfly", "openbsd": // platforms that return fe80::1%lo0: bind: can't assign requested address t.Skipf("not supported on %s", runtime.GOOS) - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { diff --git a/vendor/golang.org/x/net/ipv6/multicastsockopt_test.go b/vendor/golang.org/x/net/ipv6/multicastsockopt_test.go index 9e6b902d..9906e876 100644 --- a/vendor/golang.org/x/net/ipv6/multicastsockopt_test.go +++ b/vendor/golang.org/x/net/ipv6/multicastsockopt_test.go @@ -26,7 +26,7 @@ var packetConnMulticastSocketOptionTests = []struct { func TestPacketConnMulticastSocketOptions(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg.go b/vendor/golang.org/x/net/ipv6/payload_cmsg.go index 4ee4b062..b7ccdbda 100644 --- a/vendor/golang.org/x/net/ipv6/payload_cmsg.go +++ b/vendor/golang.org/x/net/ipv6/payload_cmsg.go @@ -6,10 +6,7 @@ package ipv6 -import ( - "net" - "syscall" -) +import "net" // ReadFrom reads a payload of the received IPv6 datagram, from the // endpoint c, copying the payload into b. It returns the number of @@ -17,7 +14,7 @@ import ( // src of the received datagram. func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { if !c.ok() { - return 0, nil, nil, syscall.EINVAL + return 0, nil, nil, errInvalidConn } return c.readFrom(b) } @@ -29,7 +26,7 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net. // cm may be nil if control of the outgoing datagram is not required. func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } return c.writeTo(b, cm, dst) } diff --git a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go index 99a43542..83585072 100644 --- a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go +++ b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go @@ -6,10 +6,7 @@ package ipv6 -import ( - "net" - "syscall" -) +import "net" // ReadFrom reads a payload of the received IPv6 datagram, from the // endpoint c, copying the payload into b. It returns the number of @@ -17,7 +14,7 @@ import ( // src of the received datagram. func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { if !c.ok() { - return 0, nil, nil, syscall.EINVAL + return 0, nil, nil, errInvalidConn } if n, src, err = c.PacketConn.ReadFrom(b); err != nil { return 0, nil, nil, err @@ -32,7 +29,7 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net. // cm may be nil if control of the outgoing datagram is not required. func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { if !c.ok() { - return 0, syscall.EINVAL + return 0, errInvalidConn } if dst == nil { return 0, errMissingAddress diff --git a/vendor/golang.org/x/net/ipv6/readwrite_go1_8_test.go b/vendor/golang.org/x/net/ipv6/readwrite_go1_8_test.go index c11d92ae..b3fbda13 100644 --- a/vendor/golang.org/x/net/ipv6/readwrite_go1_8_test.go +++ b/vendor/golang.org/x/net/ipv6/readwrite_go1_8_test.go @@ -22,7 +22,7 @@ import ( func BenchmarkPacketConnReadWriteUnicast(b *testing.B) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": b.Skipf("not supported on %s", runtime.GOOS) } @@ -123,7 +123,7 @@ func BenchmarkPacketConnReadWriteUnicast(b *testing.B) { func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } diff --git a/vendor/golang.org/x/net/ipv6/readwrite_go1_9_test.go b/vendor/golang.org/x/net/ipv6/readwrite_go1_9_test.go index e2fd7337..7110619b 100644 --- a/vendor/golang.org/x/net/ipv6/readwrite_go1_9_test.go +++ b/vendor/golang.org/x/net/ipv6/readwrite_go1_9_test.go @@ -22,7 +22,7 @@ import ( func BenchmarkPacketConnReadWriteUnicast(b *testing.B) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": b.Skipf("not supported on %s", runtime.GOOS) } @@ -169,7 +169,7 @@ func BenchmarkPacketConnReadWriteUnicast(b *testing.B) { func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } diff --git a/vendor/golang.org/x/net/ipv6/readwrite_test.go b/vendor/golang.org/x/net/ipv6/readwrite_test.go index 206b915c..668208f2 100644 --- a/vendor/golang.org/x/net/ipv6/readwrite_test.go +++ b/vendor/golang.org/x/net/ipv6/readwrite_test.go @@ -65,7 +65,7 @@ func BenchmarkReadWriteUnicast(b *testing.B) { func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { diff --git a/vendor/golang.org/x/net/ipv6/sockopt_test.go b/vendor/golang.org/x/net/ipv6/sockopt_test.go index 774338db..add045e3 100644 --- a/vendor/golang.org/x/net/ipv6/sockopt_test.go +++ b/vendor/golang.org/x/net/ipv6/sockopt_test.go @@ -19,7 +19,7 @@ var supportsIPv6 bool = nettest.SupportsIPv6() func TestConnInitiatorPathMTU(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { @@ -57,7 +57,7 @@ func TestConnInitiatorPathMTU(t *testing.T) { func TestConnResponderPathMTU(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { @@ -95,7 +95,7 @@ func TestConnResponderPathMTU(t *testing.T) { func TestPacketConnChecksum(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { diff --git a/vendor/golang.org/x/net/ipv6/unicast_test.go b/vendor/golang.org/x/net/ipv6/unicast_test.go index a0b7d955..159bb39b 100644 --- a/vendor/golang.org/x/net/ipv6/unicast_test.go +++ b/vendor/golang.org/x/net/ipv6/unicast_test.go @@ -20,7 +20,7 @@ import ( func TestPacketConnReadWriteUnicastUDP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { @@ -78,7 +78,7 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) { func TestPacketConnReadWriteUnicastICMP(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { diff --git a/vendor/golang.org/x/net/ipv6/unicastsockopt_test.go b/vendor/golang.org/x/net/ipv6/unicastsockopt_test.go index e175dccf..69adefe8 100644 --- a/vendor/golang.org/x/net/ipv6/unicastsockopt_test.go +++ b/vendor/golang.org/x/net/ipv6/unicastsockopt_test.go @@ -16,7 +16,7 @@ import ( func TestConnUnicastSocketOptions(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { @@ -61,7 +61,7 @@ var packetConnUnicastSocketOptionTests = []struct { func TestPacketConnUnicastSocketOptions(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv6 { diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go index 24aa90bb..62fc31b4 100644 --- a/vendor/golang.org/x/sys/windows/service.go +++ b/vendor/golang.org/x/sys/windows/service.go @@ -43,6 +43,11 @@ const ( SC_STATUS_PROCESS_INFO = 0 + SC_ACTION_NONE = 0 + SC_ACTION_RESTART = 1 + SC_ACTION_REBOOT = 2 + SC_ACTION_RUN_COMMAND = 3 + SERVICE_STOPPED = 1 SERVICE_START_PENDING = 2 SERVICE_STOP_PENDING = 3 @@ -148,6 +153,19 @@ type ENUM_SERVICE_STATUS_PROCESS struct { ServiceStatusProcess SERVICE_STATUS_PROCESS } +type SERVICE_FAILURE_ACTIONS struct { + ResetPeriod uint32 + RebootMsg *uint16 + Command *uint16 + ActionsCount uint32 + Actions *SC_ACTION +} + +type SC_ACTION struct { + Type uint32 + Delay uint32 +} + //sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle //sys CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW //sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/config.go b/vendor/golang.org/x/sys/windows/svc/mgr/config.go index 03bf41f5..d804e31f 100644 --- a/vendor/golang.org/x/sys/windows/svc/mgr/config.go +++ b/vendor/golang.org/x/sys/windows/svc/mgr/config.go @@ -88,23 +88,11 @@ func (s *Service) Config() (Config, error) { } } - var p2 *windows.SERVICE_DESCRIPTION - n = uint32(1024) - for { - b := make([]byte, n) - p2 = (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0])) - err := windows.QueryServiceConfig2(s.Handle, - windows.SERVICE_CONFIG_DESCRIPTION, &b[0], n, &n) - if err == nil { - break - } - if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER { - return Config{}, err - } - if n <= uint32(len(b)) { - return Config{}, err - } + b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_DESCRIPTION) + if err != nil { + return Config{}, err } + p2 := (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0])) return Config{ ServiceType: p.ServiceType, @@ -137,3 +125,21 @@ func (s *Service) UpdateConfig(c Config) error { } return updateDescription(s.Handle, c.Description) } + +// queryServiceConfig2 calls Windows QueryServiceConfig2 with infoLevel parameter and returns retrieved service configuration information. +func (s *Service) queryServiceConfig2(infoLevel uint32) ([]byte, error) { + n := uint32(1024) + for { + b := make([]byte, n) + err := windows.QueryServiceConfig2(s.Handle, infoLevel, &b[0], n, &n) + if err == nil { + return b, nil + } + if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER { + return nil, err + } + if n <= uint32(len(b)) { + return nil, err + } + } +} diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go b/vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go index 1569a221..13f1f381 100644 --- a/vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go +++ b/vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go @@ -95,6 +95,85 @@ func testConfig(t *testing.T, s *mgr.Service, should mgr.Config) mgr.Config { return is } +func testRecoveryActions(t *testing.T, s *mgr.Service, should []mgr.RecoveryAction) { + is, err := s.RecoveryActions() + if err != nil { + t.Fatalf("RecoveryActions failed: %s", err) + } + if len(should) != len(is) { + t.Errorf("recovery action mismatch: contains %v actions, but should have %v", len(is), len(should)) + } + for i, _ := range is { + if should[i].Type != is[i].Type { + t.Errorf("recovery action mismatch: Type is %v, but should have %v", is[i].Type, should[i].Type) + } + if should[i].Delay != is[i].Delay { + t.Errorf("recovery action mismatch: Delay is %v, but should have %v", is[i].Delay, should[i].Delay) + } + } +} + +func testResetPeriod(t *testing.T, s *mgr.Service, should uint32) { + is, err := s.ResetPeriod() + if err != nil { + t.Fatalf("ResetPeriod failed: %s", err) + } + if should != is { + t.Errorf("reset period mismatch: reset period is %v, but should have %v", is, should) + } +} + +func testSetRecoveryActions(t *testing.T, s *mgr.Service) { + r := []mgr.RecoveryAction{ + mgr.RecoveryAction{ + Type: mgr.NoAction, + Delay: 60000 * time.Millisecond, + }, + mgr.RecoveryAction{ + Type: mgr.ServiceRestart, + Delay: 4 * time.Minute, + }, + mgr.RecoveryAction{ + Type: mgr.ServiceRestart, + Delay: time.Minute, + }, + mgr.RecoveryAction{ + Type: mgr.RunCommand, + Delay: 4000 * time.Millisecond, + }, + } + + // 4 recovery actions with reset period + err := s.SetRecoveryActions(r, uint32(10000)) + if err != nil { + t.Fatalf("SetRecoveryActions failed: %v", err) + } + testRecoveryActions(t, s, r) + testResetPeriod(t, s, uint32(10000)) + + // Infinite reset period + err = s.SetRecoveryActions(r, syscall.INFINITE) + if err != nil { + t.Fatalf("SetRecoveryActions failed: %v", err) + } + testRecoveryActions(t, s, r) + testResetPeriod(t, s, syscall.INFINITE) + + // nil recovery actions + err = s.SetRecoveryActions(nil, 0) + if err.Error() != "recoveryActions cannot be nil" { + t.Fatalf("SetRecoveryActions failed with unexpected error message of %q", err) + } + + // Delete all recovery actions and reset period + err = s.ResetRecoveryActions() + if err != nil { + t.Fatalf("ResetRecoveryActions failed: %v", err) + } + testRecoveryActions(t, s, nil) + testResetPeriod(t, s, 0) +} + func remove(t *testing.T, s *mgr.Service) { err := s.Delete() if err != nil { @@ -165,5 +244,7 @@ func TestMyService(t *testing.T) { t.Errorf("ListServices failed to find %q service", name) } + testSetRecoveryActions(t, s) + remove(t, s) } diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/recovery.go b/vendor/golang.org/x/sys/windows/svc/mgr/recovery.go new file mode 100644 index 00000000..9243dca2 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/svc/mgr/recovery.go @@ -0,0 +1,96 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package mgr + +import ( + "errors" + "time" + "unsafe" + + "golang.org/x/sys/windows" +) + +const ( + // Possible recovery actions that the service control manager can perform. + NoAction = windows.SC_ACTION_NONE // no action + ComputerReboot = windows.SC_ACTION_REBOOT // reboot the computer + ServiceRestart = windows.SC_ACTION_RESTART // restart the service + RunCommand = windows.SC_ACTION_RUN_COMMAND // run a command +) + +// RecoveryAction represents an action that the service control manager can perform when service fails. +// A service is considered failed when it terminates without reporting a status of SERVICE_STOPPED to the service controller. +type RecoveryAction struct { + Type int // one of NoAction, ComputerReboot, ServiceRestart or RunCommand + Delay time.Duration // the time to wait before performing the specified action +} + +// SetRecoveryActions sets actions that service controller performs when service fails and +// the time after which to reset the service failure count to zero if there are no failures, in seconds. +// Specify INFINITE to indicate that service failure count should never be reset. +func (s *Service) SetRecoveryActions(recoveryActions []RecoveryAction, resetPeriod uint32) error { + if recoveryActions == nil { + return errors.New("recoveryActions cannot be nil") + } + actions := []windows.SC_ACTION{} + for _, a := range recoveryActions { + action := windows.SC_ACTION{ + Type: uint32(a.Type), + Delay: uint32(a.Delay.Nanoseconds() / 1000000), + } + actions = append(actions, action) + } + rActions := windows.SERVICE_FAILURE_ACTIONS{ + ActionsCount: uint32(len(actions)), + Actions: &actions[0], + ResetPeriod: resetPeriod, + } + return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions))) +} + +// RecoveryActions returns actions that service controller performs when service fails. +// The service control manager counts the number of times service s has failed since the system booted. +// The count is reset to 0 if the service has not failed for ResetPeriod seconds. +// When the service fails for the Nth time, the service controller performs the action specified in element [N-1] of returned slice. +// If N is greater than slice length, the service controller repeats the last action in the slice. +func (s *Service) RecoveryActions() ([]RecoveryAction, error) { + b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_FAILURE_ACTIONS) + if err != nil { + return nil, err + } + p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0])) + if p.Actions == nil { + return nil, err + } + + var recoveryActions []RecoveryAction + actions := (*[1024]windows.SC_ACTION)(unsafe.Pointer(p.Actions))[:p.ActionsCount] + for _, action := range actions { + recoveryActions = append(recoveryActions, RecoveryAction{Type: int(action.Type), Delay: time.Duration(action.Delay) * time.Millisecond}) + } + return recoveryActions, nil +} + +// ResetRecoveryActions deletes both reset period and array of failure actions. +func (s *Service) ResetRecoveryActions() error { + actions := make([]windows.SC_ACTION, 1) + rActions := windows.SERVICE_FAILURE_ACTIONS{ + Actions: &actions[0], + } + return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions))) +} + +// ResetPeriod is the time after which to reset the service failure +// count to zero if there are no failures, in seconds. +func (s *Service) ResetPeriod() (uint32, error) { + b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_FAILURE_ACTIONS) + if err != nil { + return 0, err + } + p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0])) + return p.ResetPeriod, nil +}